<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="ru">
		<id>http://www.jexp.ru/index.php?action=history&amp;feed=atom&amp;title=Java%2FAdvanced_Graphics%2FOpenGL</id>
		<title>Java/Advanced Graphics/OpenGL - История изменений</title>
		<link rel="self" type="application/atom+xml" href="http://www.jexp.ru/index.php?action=history&amp;feed=atom&amp;title=Java%2FAdvanced_Graphics%2FOpenGL"/>
		<link rel="alternate" type="text/html" href="http://www.jexp.ru/index.php?title=Java/Advanced_Graphics/OpenGL&amp;action=history"/>
		<updated>2026-04-21T14:22:44Z</updated>
		<subtitle>История изменений этой страницы в вики</subtitle>
		<generator>MediaWiki 1.30.0</generator>

	<entry>
		<id>http://www.jexp.ru/index.php?title=Java/Advanced_Graphics/OpenGL&amp;diff=7571&amp;oldid=prev</id>
		<title>Admin: 1 версия</title>
		<link rel="alternate" type="text/html" href="http://www.jexp.ru/index.php?title=Java/Advanced_Graphics/OpenGL&amp;diff=7571&amp;oldid=prev"/>
				<updated>2010-06-01T06:48:08Z</updated>
		
		<summary type="html">&lt;p&gt;1 версия&lt;/p&gt;
&lt;table class=&quot;diff diff-contentalign-left&quot; data-mw=&quot;interface&quot;&gt;
				&lt;tr style=&quot;vertical-align: top;&quot; lang=&quot;ru&quot;&gt;
				&lt;td colspan=&quot;1&quot; style=&quot;background-color: white; color:black; text-align: center;&quot;&gt;← Предыдущая&lt;/td&gt;
				&lt;td colspan=&quot;1&quot; style=&quot;background-color: white; color:black; text-align: center;&quot;&gt;Версия 06:48, 1 июня 2010&lt;/td&gt;
				&lt;/tr&gt;&lt;tr&gt;&lt;td colspan=&quot;2&quot; style=&quot;text-align: center;&quot; lang=&quot;ru&quot;&gt;&lt;div class=&quot;mw-diff-empty&quot;&gt;(нет различий)&lt;/div&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;</summary>
		<author><name>Admin</name></author>	</entry>

	<entry>
		<id>http://www.jexp.ru/index.php?title=Java/Advanced_Graphics/OpenGL&amp;diff=7570&amp;oldid=prev</id>
		<title> в 18:01, 31 мая 2010</title>
		<link rel="alternate" type="text/html" href="http://www.jexp.ru/index.php?title=Java/Advanced_Graphics/OpenGL&amp;diff=7570&amp;oldid=prev"/>
				<updated>2010-05-31T18:01:45Z</updated>
		
		<summary type="html">&lt;p&gt;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Новая страница&lt;/b&gt;&lt;/p&gt;&lt;div&gt;== Bloom OpenGL ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
  &amp;lt;!-- start source code --&amp;gt;&lt;br /&gt;
   &lt;br /&gt;
    &amp;lt;source lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
/*&lt;br /&gt;
 * Copyright (c) 2007, Romain Guy&lt;br /&gt;
 * All rights reserved.&lt;br /&gt;
 *&lt;br /&gt;
 * Redistribution and use in source and binary forms, with or without&lt;br /&gt;
 * modification, are permitted provided that the following conditions&lt;br /&gt;
 * are met:&lt;br /&gt;
 *&lt;br /&gt;
 *   * Redistributions of source code must retain the above copyright&lt;br /&gt;
 *     notice, this list of conditions and the following disclaimer.&lt;br /&gt;
 *   * Redistributions in binary form must reproduce the above&lt;br /&gt;
 *     copyright notice, this list of conditions and the following&lt;br /&gt;
 *     disclaimer in the documentation and/or other materials provided&lt;br /&gt;
 *     with the distribution.&lt;br /&gt;
 *   * Neither the name of the TimingFramework project nor the names of its&lt;br /&gt;
 *     contributors may be used to endorse or promote products derived&lt;br /&gt;
 *     from this software without specific prior written permission.&lt;br /&gt;
 *&lt;br /&gt;
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS&lt;br /&gt;
 * &amp;quot;AS IS&amp;quot; AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT&lt;br /&gt;
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR&lt;br /&gt;
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT&lt;br /&gt;
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,&lt;br /&gt;
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT&lt;br /&gt;
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,&lt;br /&gt;
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY&lt;br /&gt;
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT&lt;br /&gt;
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE&lt;br /&gt;
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.&lt;br /&gt;
 */&lt;br /&gt;
import java.awt.Dimension;&lt;br /&gt;
import java.awt.FlowLayout;&lt;br /&gt;
import java.awt.BorderLayout;&lt;br /&gt;
import java.awt.image.BufferedImage;&lt;br /&gt;
import java.io.IOException;&lt;br /&gt;
import javax.imageio.ImageIO;&lt;br /&gt;
import javax.media.opengl.GL;&lt;br /&gt;
import javax.media.opengl.GLAutoDrawable;&lt;br /&gt;
import javax.media.opengl.GLCapabilities;&lt;br /&gt;
import javax.media.opengl.GLEventListener;&lt;br /&gt;
import javax.media.opengl.GLJPanel;&lt;br /&gt;
import javax.media.opengl.glu.GLU;&lt;br /&gt;
import javax.swing.JFrame;&lt;br /&gt;
import javax.swing.SwingUtilities;&lt;br /&gt;
import javax.swing.JPanel;&lt;br /&gt;
import javax.swing.JLabel;&lt;br /&gt;
import javax.swing.JSlider;&lt;br /&gt;
import javax.swing.event.ChangeListener;&lt;br /&gt;
import javax.swing.event.ChangeEvent;&lt;br /&gt;
import com.sun.opengl.util.BufferUtil;&lt;br /&gt;
import com.sun.opengl.util.texture.Texture;&lt;br /&gt;
import com.sun.opengl.util.texture.TextureIO;&lt;br /&gt;
/**&lt;br /&gt;
 * THIS DEMO REQUIRES THE JOGL LIBRARY TO COMPILE AND EXECUTE !&lt;br /&gt;
 *&lt;br /&gt;
 * JOGL can be found at http://jogl.dev.java.net for your OS.&lt;br /&gt;
 *&lt;br /&gt;
 * /!\ The rendering happens in FBOs so that you can get the result back into&lt;br /&gt;
 *     a Java 2D image without displaying it on screen through a GLJPanel. This&lt;br /&gt;
 *     implementation does not offer the conversion from FBO to a BufferedImage&lt;br /&gt;
 *     but you can do it by reading the texture data from frameBufferTexture2.&lt;br /&gt;
 *&lt;br /&gt;
 * @author Romain Guy &amp;lt;romain.guy@mac.ru&amp;gt;&lt;br /&gt;
 */&lt;br /&gt;
public class BloomOpenGL extends GLJPanel implements GLEventListener {&lt;br /&gt;
    private int frameBufferObject1 = -1;&lt;br /&gt;
    private int frameBufferTexture1 = -1;&lt;br /&gt;
    private int frameBufferObject2 = -1;&lt;br /&gt;
    private int frameBufferTexture2 = -1;&lt;br /&gt;
    private Texture texture;&lt;br /&gt;
    private BufferedImage image;&lt;br /&gt;
    private GLU glu = new GLU();&lt;br /&gt;
    private String blurShaderSource =&lt;br /&gt;
        &amp;quot;const int MAX_KERNEL_SIZE = 25;&amp;quot; +&lt;br /&gt;
        &amp;quot;uniform sampler2D baseImage;&amp;quot; +&lt;br /&gt;
        &amp;quot;uniform vec2 offsets[MAX_KERNEL_SIZE];&amp;quot; +&lt;br /&gt;
        &amp;quot;uniform float kernelVals[MAX_KERNEL_SIZE];&amp;quot; +&lt;br /&gt;
        &amp;quot;&amp;quot; +&lt;br /&gt;
        &amp;quot;void main(void) {&amp;quot; +&lt;br /&gt;
        &amp;quot;    int i;&amp;quot; +&lt;br /&gt;
        &amp;quot;    vec4 sum = vec4(0.0);&amp;quot; +&lt;br /&gt;
        &amp;quot;&amp;quot; +&lt;br /&gt;
        &amp;quot;    for (i = 0; i &amp;lt; MAX_KERNEL_SIZE; i++) {&amp;quot; +&lt;br /&gt;
        &amp;quot;        vec4 tmp = texture2D(baseImage,&amp;quot; +&lt;br /&gt;
        &amp;quot;                             gl_TexCoord[0].st + offsets[i]);&amp;quot; +&lt;br /&gt;
        &amp;quot;        sum += tmp * kernelVals[i];&amp;quot; +&lt;br /&gt;
        &amp;quot;    }&amp;quot; +&lt;br /&gt;
        &amp;quot;&amp;quot; +&lt;br /&gt;
        &amp;quot;    gl_FragColor = sum;&amp;quot; +&lt;br /&gt;
        &amp;quot;}&amp;quot;;&lt;br /&gt;
    private int blurShader;&lt;br /&gt;
    private String brightPassShaderSource =&lt;br /&gt;
        &amp;quot;uniform sampler2D baseImage;&amp;quot; +&lt;br /&gt;
        &amp;quot;uniform float brightPassThreshold;&amp;quot; +&lt;br /&gt;
        &amp;quot;&amp;quot; +&lt;br /&gt;
        &amp;quot;void main(void) {&amp;quot; +&lt;br /&gt;
        &amp;quot;    vec3 luminanceVector = vec3(0.2125, 0.7154, 0.0721);&amp;quot; +&lt;br /&gt;
        &amp;quot;    vec4 sample = texture2D(baseImage, gl_TexCoord[0].st);&amp;quot; +&lt;br /&gt;
        &amp;quot;&amp;quot; +&lt;br /&gt;
        &amp;quot;    float luminance = dot(luminanceVector, sample.rgb);&amp;quot; +&lt;br /&gt;
      &amp;quot;    luminance = max(0.0, luminance - brightPassThreshold);&amp;quot; +&lt;br /&gt;
      &amp;quot;    sample.rgb *= sign(luminance);&amp;quot; +&lt;br /&gt;
      &amp;quot;    sample.a = 1.0;&amp;quot; +&lt;br /&gt;
        &amp;quot;&amp;quot; +&lt;br /&gt;
        &amp;quot;    gl_FragColor = sample;&amp;quot; +&lt;br /&gt;
        &amp;quot;}&amp;quot;;&lt;br /&gt;
    private int brightPassShader;&lt;br /&gt;
    private float threshold = 0.3f;&lt;br /&gt;
    public BloomOpenGL() {&lt;br /&gt;
        super(new GLCapabilities());&lt;br /&gt;
        addGLEventListener(this);&lt;br /&gt;
        try {&lt;br /&gt;
            image = ImageIO.read(getClass().getResource(&amp;quot;screen.png&amp;quot;));&lt;br /&gt;
        } catch (IOException e) {&lt;br /&gt;
            e.printStackTrace();&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    public void init(GLAutoDrawable glAutoDrawable) {&lt;br /&gt;
        GL gl = glAutoDrawable.getGL();&lt;br /&gt;
        if (texture == null) {&lt;br /&gt;
            texture = TextureIO.newTexture(image, false);&lt;br /&gt;
        }&lt;br /&gt;
        // create the blur shader&lt;br /&gt;
        blurShader = createFragmentProgram(gl, new String[] { blurShaderSource });&lt;br /&gt;
        gl.glUseProgramObjectARB(blurShader);&lt;br /&gt;
        int loc = gl.glGetUniformLocationARB(blurShader, &amp;quot;baseImage&amp;quot;);&lt;br /&gt;
        gl.glUniform1iARB(loc, 0);&lt;br /&gt;
        gl.glUseProgramObjectARB(0);&lt;br /&gt;
        // create the bright-pass shader&lt;br /&gt;
        brightPassShader = createFragmentProgram(gl, new String[] { brightPassShaderSource });&lt;br /&gt;
        gl.glUseProgramObjectARB(brightPassShader);&lt;br /&gt;
        loc = gl.glGetUniformLocationARB(brightPassShader, &amp;quot;baseImage&amp;quot;);&lt;br /&gt;
        gl.glUniform1iARB(loc, 0);&lt;br /&gt;
        gl.glUseProgramObjectARB(0);&lt;br /&gt;
        // create the FBOs&lt;br /&gt;
        if (gl.isExtensionAvailable(&amp;quot;GL_EXT_framebuffer_object&amp;quot;)) {&lt;br /&gt;
            int[] fboId = new int[1];&lt;br /&gt;
            int[] texId = new int[1];&lt;br /&gt;
            createFrameBufferObject(gl, fboId, texId,&lt;br /&gt;
                                    image.getWidth(), image.getHeight());&lt;br /&gt;
            frameBufferObject1 = fboId[0];&lt;br /&gt;
            frameBufferTexture1 = texId[0];&lt;br /&gt;
            createFrameBufferObject(gl, fboId, texId,&lt;br /&gt;
                                    image.getWidth(), image.getHeight());&lt;br /&gt;
            frameBufferObject2 = fboId[0];&lt;br /&gt;
            frameBufferTexture2 = texId[0];&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    private static void createFrameBufferObject(GL gl, int[] frameBuffer,&lt;br /&gt;
                                                int[] colorBuffer, int width,&lt;br /&gt;
                                                int height) {&lt;br /&gt;
        gl.glGenFramebuffersEXT(1, frameBuffer, 0);&lt;br /&gt;
        gl.glBindFramebufferEXT(GL.GL_FRAMEBUFFER_EXT, frameBuffer[0]);&lt;br /&gt;
        gl.glGenTextures(1, colorBuffer, 0);&lt;br /&gt;
        gl.glBindTexture(GL.GL_TEXTURE_2D, colorBuffer[0]);&lt;br /&gt;
        gl.glTexImage2D(GL.GL_TEXTURE_2D, 0, GL.GL_RGBA,&lt;br /&gt;
                        width, height,&lt;br /&gt;
                        0, GL.GL_RGBA, GL.GL_UNSIGNED_BYTE,&lt;br /&gt;
                        BufferUtil.newByteBuffer(width * height * 4));&lt;br /&gt;
        gl.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_MIN_FILTER, GL.GL_LINEAR);&lt;br /&gt;
        gl.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_MAG_FILTER, GL.GL_LINEAR);&lt;br /&gt;
        gl.glFramebufferTexture2DEXT(GL.GL_FRAMEBUFFER_EXT,&lt;br /&gt;
                                     GL.GL_COLOR_ATTACHMENT0_EXT,&lt;br /&gt;
                                     GL.GL_TEXTURE_2D, colorBuffer[0], 0);&lt;br /&gt;
        gl.glBindTexture(GL.GL_TEXTURE_2D, 0);&lt;br /&gt;
        int status = gl.glCheckFramebufferStatusEXT(GL.GL_FRAMEBUFFER_EXT);&lt;br /&gt;
        if (status == GL.GL_FRAMEBUFFER_COMPLETE_EXT) {&lt;br /&gt;
            gl.glBindFramebufferEXT(GL.GL_FRAMEBUFFER_EXT, 0);&lt;br /&gt;
        } else {&lt;br /&gt;
            throw new IllegalStateException(&amp;quot;Frame Buffer Oject not created.&amp;quot;);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    private static void viewOrtho(GL gl, int width, int height) {&lt;br /&gt;
        gl.glMatrixMode(GL.GL_PROJECTION);&lt;br /&gt;
        gl.glPushMatrix();&lt;br /&gt;
        gl.glLoadIdentity();&lt;br /&gt;
        gl.glOrtho(0, width, height, 0, -1, 1);&lt;br /&gt;
        gl.glMatrixMode(GL.GL_MODELVIEW);&lt;br /&gt;
        gl.glPushMatrix();&lt;br /&gt;
        gl.glLoadIdentity();&lt;br /&gt;
    }&lt;br /&gt;
    private static void renderTexturedQuad(GL gl, float width, float height,&lt;br /&gt;
                                           boolean flip) {&lt;br /&gt;
        gl.glBegin(GL.GL_QUADS);&lt;br /&gt;
            gl.glTexCoord2f(0.0f, flip ? 1.0f : 0.0f);&lt;br /&gt;
            gl.glVertex2f(0.0f, 0.0f);&lt;br /&gt;
            gl.glTexCoord2f(1.0f, flip ? 1.0f : 0.0f);&lt;br /&gt;
            gl.glVertex2f(width, 0.0f);&lt;br /&gt;
            gl.glTexCoord2f(1.0f, flip ? 0.0f : 1.0f);&lt;br /&gt;
            gl.glVertex2f(width, height);&lt;br /&gt;
            gl.glTexCoord2f(0.0f, flip ? 0.0f : 1.0f);&lt;br /&gt;
            gl.glVertex2f(0.0f, height);&lt;br /&gt;
        gl.glEnd();&lt;br /&gt;
    }&lt;br /&gt;
    private static int createFragmentProgram(GL gl, String[] fragmentShaderSource) {&lt;br /&gt;
        int fragmentShader, fragmentProgram;&lt;br /&gt;
        int[] success = new int[1];&lt;br /&gt;
        // create the shader object and compile the shader source code&lt;br /&gt;
        fragmentShader = gl.glCreateShaderObjectARB(GL.GL_FRAGMENT_SHADER_ARB);&lt;br /&gt;
        gl.glShaderSourceARB(fragmentShader, 1, fragmentShaderSource, null);&lt;br /&gt;
        gl.glCompileShaderARB(fragmentShader);&lt;br /&gt;
        gl.glGetObjectParameterivARB(fragmentShader,&lt;br /&gt;
                                      GL.GL_OBJECT_COMPILE_STATUS_ARB,&lt;br /&gt;
                                      success, 0);&lt;br /&gt;
        // print the compiler messages, if necessary&lt;br /&gt;
        int[] infoLogLength = new int[1];&lt;br /&gt;
        int[] length = new int[1];&lt;br /&gt;
        gl.glGetObjectParameterivARB(fragmentShader,&lt;br /&gt;
                                     GL.GL_OBJECT_INFO_LOG_LENGTH_ARB,&lt;br /&gt;
                                     infoLogLength, 0);&lt;br /&gt;
        if (infoLogLength[0] &amp;gt; 1) {&lt;br /&gt;
            byte[] b = new byte[1024];&lt;br /&gt;
            gl.glGetInfoLogARB(fragmentShader, 1024, length, 0, b, 0);&lt;br /&gt;
            System.out.println(&amp;quot;Fragment compile phase = &amp;quot; + new String(b, 0, length[0]));&lt;br /&gt;
        }&lt;br /&gt;
        if (success[0] == 0) {&lt;br /&gt;
            gl.glDeleteObjectARB(fragmentShader);&lt;br /&gt;
            return -1;&lt;br /&gt;
        }&lt;br /&gt;
        // create the program object and attach it to the shader&lt;br /&gt;
        fragmentProgram = gl.glCreateProgramObjectARB();&lt;br /&gt;
        gl.glAttachObjectARB(fragmentProgram, fragmentShader);&lt;br /&gt;
        // it is now safe to delete the shader object&lt;br /&gt;
        gl.glDeleteObjectARB(fragmentShader);&lt;br /&gt;
        // link the program&lt;br /&gt;
        gl.glLinkProgramARB(fragmentProgram);&lt;br /&gt;
        gl.glGetObjectParameterivARB(fragmentProgram,&lt;br /&gt;
                                     GL.GL_OBJECT_LINK_STATUS_ARB,&lt;br /&gt;
                                     success, 0);&lt;br /&gt;
        gl.glGetObjectParameterivARB(fragmentShader,&lt;br /&gt;
                                     GL.GL_OBJECT_INFO_LOG_LENGTH_ARB,&lt;br /&gt;
                                     infoLogLength, 0);&lt;br /&gt;
        if (infoLogLength[0] &amp;gt; 1) {&lt;br /&gt;
            byte[] b = new byte[1024];&lt;br /&gt;
            gl.glGetInfoLogARB(fragmentShader, 1024, length, 0, b, 0);&lt;br /&gt;
            System.out.println(&amp;quot;Fragment link phase = &amp;quot; + new String(b, 0, length[0]));&lt;br /&gt;
        }&lt;br /&gt;
        if (success[0] == 0) {&lt;br /&gt;
            gl.glDeleteObjectARB(fragmentProgram);&lt;br /&gt;
            return -1;&lt;br /&gt;
        }&lt;br /&gt;
        return fragmentProgram;&lt;br /&gt;
    }&lt;br /&gt;
    private static void enableBlurFragmentProgram(GL gl, int program,&lt;br /&gt;
                                                  float textureWidth,&lt;br /&gt;
                                                  float textureHeight) {&lt;br /&gt;
        gl.glUseProgramObjectARB(program);&lt;br /&gt;
        int kernelWidth = 5;&lt;br /&gt;
        int kernelHeight = 5;&lt;br /&gt;
        float xoff = 1.0f / textureWidth;&lt;br /&gt;
        float yoff = 1.0f / textureHeight;&lt;br /&gt;
        float[] offsets = new float[kernelWidth * kernelHeight * 2];&lt;br /&gt;
        int offsetIndex = 0;&lt;br /&gt;
        for (int i = -kernelHeight / 2; i &amp;lt; kernelHeight / 2 + 1; i++) {&lt;br /&gt;
            for (int j = -kernelWidth / 2; j &amp;lt; kernelWidth / 2 + 1; j++) {&lt;br /&gt;
                offsets[offsetIndex++] = j * xoff;&lt;br /&gt;
                offsets[offsetIndex++] = i * yoff;&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        int loc = gl.glGetUniformLocationARB(program, &amp;quot;offsets&amp;quot;);&lt;br /&gt;
        gl.glUniform2fv(loc, offsets.length, offsets, 0);&lt;br /&gt;
        float[] values = createGaussianBlurFilter(2);&lt;br /&gt;
        loc = gl.glGetUniformLocationARB(program, &amp;quot;kernelVals&amp;quot;);&lt;br /&gt;
        gl.glUniform1fvARB(loc, values.length, values, 0);&lt;br /&gt;
    }&lt;br /&gt;
    private static float[] createGaussianBlurFilter(int radius) {&lt;br /&gt;
        if (radius &amp;lt; 1) {&lt;br /&gt;
            throw new IllegalArgumentException(&amp;quot;Radius must be &amp;gt;= 1&amp;quot;);&lt;br /&gt;
        }&lt;br /&gt;
        int size = radius * 2 + 1;&lt;br /&gt;
        float[] data = new float[size * size];&lt;br /&gt;
        float sigma = radius / 3.0f;&lt;br /&gt;
        float twoSigmaSquare = 2.0f * sigma * sigma;&lt;br /&gt;
        float sigmaRoot = (float) Math.sqrt(twoSigmaSquare * Math.PI);&lt;br /&gt;
        float total = 0.0f;&lt;br /&gt;
        int index = 0;&lt;br /&gt;
        for (int y = -radius; y &amp;lt;= radius; y++) {&lt;br /&gt;
            for (int x = -radius; x &amp;lt;= radius; x++) {&lt;br /&gt;
                float distance = x * x + y * y;&lt;br /&gt;
                data[index] = (float) Math.exp(-distance / twoSigmaSquare) / sigmaRoot;&lt;br /&gt;
                total += data[index];&lt;br /&gt;
                index++;&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        for (int i = 0; i &amp;lt; data.length; i++) {&lt;br /&gt;
            data[i] /= total;&lt;br /&gt;
        }&lt;br /&gt;
        return data;&lt;br /&gt;
    }&lt;br /&gt;
    private static void enableBrightPassFragmentProgram(GL gl, int program,&lt;br /&gt;
                                                        float threshold) {&lt;br /&gt;
        gl.glUseProgramObjectARB(program);&lt;br /&gt;
        int loc = gl.glGetUniformLocationARB(program, &amp;quot;brightPassThreshold&amp;quot;);&lt;br /&gt;
        gl.glUniform1fARB(loc, threshold);&lt;br /&gt;
    }&lt;br /&gt;
    private static void disableFragmentProgram(GL gl) {&lt;br /&gt;
        gl.glUseProgramObjectARB(0);&lt;br /&gt;
    }&lt;br /&gt;
    public void display(GLAutoDrawable glAutoDrawable) {&lt;br /&gt;
        GL gl = glAutoDrawable.getGL();&lt;br /&gt;
        gl.glLoadIdentity(); &lt;br /&gt;
        gl.glClearColor(0.0f, 0.0f, 0.0f, 0.0f);&lt;br /&gt;
        gl.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT);&lt;br /&gt;
        viewOrtho(gl, image.getWidth(), image.getHeight());&lt;br /&gt;
        gl.glEnable(GL.GL_TEXTURE_2D);&lt;br /&gt;
        int width = image.getWidth();&lt;br /&gt;
        int height = image.getHeight();&lt;br /&gt;
        // Source Image/bright pass on FBO1&lt;br /&gt;
        renderBrightPass(gl, width, height);&lt;br /&gt;
        // Source image on FBO2&lt;br /&gt;
        renderImage(gl, width, height);&lt;br /&gt;
        // On screen&lt;br /&gt;
        renderTextureOnScreen(gl, width, height);&lt;br /&gt;
        //render5x5(gl, width, height);&lt;br /&gt;
        render11x11(gl, width, height);&lt;br /&gt;
        render21x21(gl, width, height);&lt;br /&gt;
        render41x41(gl, width, height);&lt;br /&gt;
        gl.glDisable(GL.GL_TEXTURE_2D);&lt;br /&gt;
        gl.glFlush();&lt;br /&gt;
    }&lt;br /&gt;
    private void render41x41(GL gl, int width, int height) {&lt;br /&gt;
        // FBO1/blur on FBO2&lt;br /&gt;
        renderBlur(gl, width / 8.0f, height / 8.0f);&lt;br /&gt;
        // Add on screen&lt;br /&gt;
        gl.glPushMatrix();&lt;br /&gt;
        gl.glTranslatef(0.0f, -height * 7.0f, 0.0f);&lt;br /&gt;
        renderAddTextureOnScreen(gl, width * 8.0f, height * 8.0f);&lt;br /&gt;
        gl.glPopMatrix();&lt;br /&gt;
    }&lt;br /&gt;
    private void render21x21(GL gl, int width, int height) {&lt;br /&gt;
        // FBO1/blur on FBO2&lt;br /&gt;
        renderBlur(gl, width / 4.0f, height / 4.0f);&lt;br /&gt;
        // Add on screen&lt;br /&gt;
        gl.glPushMatrix();&lt;br /&gt;
        gl.glTranslatef(0.0f, -height * 3.0f, 0.0f);&lt;br /&gt;
        renderAddTextureOnScreen(gl, width * 4.0f, height * 4.0f);&lt;br /&gt;
        gl.glPopMatrix();&lt;br /&gt;
    }&lt;br /&gt;
    private void render11x11(GL gl, int width, int height) {&lt;br /&gt;
        // FBO1/blur on FBO2&lt;br /&gt;
        renderBlur(gl, width / 2.0f, height / 2.0f);&lt;br /&gt;
        // Add on screen&lt;br /&gt;
        gl.glPushMatrix();&lt;br /&gt;
        gl.glTranslatef(0.0f, -height, 0.0f);&lt;br /&gt;
        renderAddTextureOnScreen(gl, width * 2.0f, height * 2.0f);&lt;br /&gt;
        gl.glPopMatrix();&lt;br /&gt;
    }&lt;br /&gt;
    private void render5x5(GL gl, int width, int height) {&lt;br /&gt;
        // FBO1/blur on FBO2&lt;br /&gt;
        renderBlur(gl, width, height);&lt;br /&gt;
        // Add on screen&lt;br /&gt;
        renderAddTextureOnScreen(gl, width, height);&lt;br /&gt;
    }&lt;br /&gt;
    private void renderAddTextureOnScreen(GL gl, float width, float height) {&lt;br /&gt;
        gl.glEnable(GL.GL_BLEND);&lt;br /&gt;
        gl.glBlendFunc(GL.GL_ONE, GL.GL_ONE);&lt;br /&gt;
        renderTextureOnScreen(gl, width, height);&lt;br /&gt;
        gl.glDisable(GL.GL_BLEND);&lt;br /&gt;
    }&lt;br /&gt;
    private void renderTextureOnScreen(GL gl, float width, float height) {&lt;br /&gt;
        // Draw the texture on a quad&lt;br /&gt;
        gl.glBindTexture(GL.GL_TEXTURE_2D, frameBufferTexture2);&lt;br /&gt;
        renderTexturedQuad(gl, width, height, false);&lt;br /&gt;
        gl.glBindTexture(GL.GL_TEXTURE_2D, 0);&lt;br /&gt;
    }&lt;br /&gt;
    private void renderBrightPass(GL gl, float width, float height) {&lt;br /&gt;
        // Draw into the FBO&lt;br /&gt;
        gl.glBindFramebufferEXT(GL.GL_FRAMEBUFFER_EXT, frameBufferObject1);&lt;br /&gt;
        gl.glClearColor(0.0f, 0.0f, 0.0f, 0.0f);&lt;br /&gt;
        gl.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT);&lt;br /&gt;
        enableBrightPassFragmentProgram(gl, brightPassShader, threshold);&lt;br /&gt;
        gl.glBindTexture(GL.GL_TEXTURE_2D, texture.getTextureObject());&lt;br /&gt;
        renderTexturedQuad(gl, width, height, texture.getMustFlipVertically());&lt;br /&gt;
        gl.glBindTexture(GL.GL_TEXTURE_2D, 0);&lt;br /&gt;
        disableFragmentProgram(gl);&lt;br /&gt;
        gl.glBindFramebufferEXT(GL.GL_FRAMEBUFFER_EXT, 0);&lt;br /&gt;
    }&lt;br /&gt;
    private void renderImage(GL gl, float width, float height) {&lt;br /&gt;
        // Draw into the FBO&lt;br /&gt;
        gl.glBindFramebufferEXT(GL.GL_FRAMEBUFFER_EXT, frameBufferObject2);&lt;br /&gt;
        gl.glClearColor(0.0f, 0.0f, 0.0f, 0.0f);&lt;br /&gt;
        gl.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT);&lt;br /&gt;
        gl.glBindTexture(GL.GL_TEXTURE_2D, texture.getTextureObject());&lt;br /&gt;
        renderTexturedQuad(gl, width, height, texture.getMustFlipVertically());&lt;br /&gt;
        gl.glBindTexture(GL.GL_TEXTURE_2D, 0);&lt;br /&gt;
        gl.glBindFramebufferEXT(GL.GL_FRAMEBUFFER_EXT, 0);&lt;br /&gt;
    }&lt;br /&gt;
    private void renderBlur(GL gl, float width, float height) {&lt;br /&gt;
        // Draw into the FBO&lt;br /&gt;
        gl.glBindFramebufferEXT(GL.GL_FRAMEBUFFER_EXT, frameBufferObject2);&lt;br /&gt;
        gl.glClearColor(0.0f, 0.0f, 0.0f, 0.0f);&lt;br /&gt;
        gl.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT);&lt;br /&gt;
        enableBlurFragmentProgram(gl, blurShader, width, height);&lt;br /&gt;
        gl.glBindTexture(GL.GL_TEXTURE_2D, frameBufferTexture1);&lt;br /&gt;
        renderTexturedQuad(gl, width, height, texture.getMustFlipVertically());&lt;br /&gt;
        gl.glBindTexture(GL.GL_TEXTURE_2D, 0);&lt;br /&gt;
        disableFragmentProgram(gl);&lt;br /&gt;
        gl.glBindFramebufferEXT(GL.GL_FRAMEBUFFER_EXT, 0);&lt;br /&gt;
    }&lt;br /&gt;
    @Override&lt;br /&gt;
    public Dimension getPreferredSize() {&lt;br /&gt;
        return new Dimension(image.getWidth(), image.getHeight());&lt;br /&gt;
    }&lt;br /&gt;
    public void reshape(GLAutoDrawable glAutoDrawable, int x, int y,&lt;br /&gt;
                        int width, int height) {&lt;br /&gt;
        GL gl = glAutoDrawable.getGL();&lt;br /&gt;
        gl.glViewport(0, 0, width, height);&lt;br /&gt;
        gl.glMatrixMode(GL.GL_PROJECTION);&lt;br /&gt;
        gl.glLoadIdentity();&lt;br /&gt;
        glu.gluPerspective(50, (float) width / height, 5, 2000);&lt;br /&gt;
        gl.glMatrixMode(GL.GL_MODELVIEW);&lt;br /&gt;
        gl.glLoadIdentity();&lt;br /&gt;
    }&lt;br /&gt;
    public void displayChanged(GLAutoDrawable glAutoDrawable, boolean modeChanged,&lt;br /&gt;
                               boolean deviceChanged) {&lt;br /&gt;
    }&lt;br /&gt;
    public float getThreshold() {&lt;br /&gt;
        return threshold;&lt;br /&gt;
    }&lt;br /&gt;
    public void setThreshold(float threshold) {&lt;br /&gt;
        this.threshold = threshold;&lt;br /&gt;
        repaint();&lt;br /&gt;
    }&lt;br /&gt;
    public static void main(String[] args) {&lt;br /&gt;
        SwingUtilities.invokeLater(new Runnable() {&lt;br /&gt;
            public void run() {&lt;br /&gt;
                final BloomOpenGL bloom;&lt;br /&gt;
                final JSlider slider;&lt;br /&gt;
                JFrame f = new JFrame(&amp;quot;Bloom OpenGL&amp;quot;);&lt;br /&gt;
                f.add(bloom = new BloomOpenGL());&lt;br /&gt;
                JPanel controls = new JPanel(new FlowLayout(FlowLayout.LEADING));&lt;br /&gt;
                controls.add(new JLabel(&amp;quot;Bloom: 0.0&amp;quot;));&lt;br /&gt;
                controls.add(slider = new JSlider(0, 100, 30));&lt;br /&gt;
                slider.addChangeListener(new ChangeListener() {&lt;br /&gt;
                    public void stateChanged(ChangeEvent e) {&lt;br /&gt;
                        JSlider slider = (JSlider) e.getSource();&lt;br /&gt;
                        float threshold = slider.getValue() / 100.0f;&lt;br /&gt;
                        bloom.setThreshold(threshold);&lt;br /&gt;
                    }&lt;br /&gt;
                });&lt;br /&gt;
                controls.add(new JLabel(&amp;quot;1.0&amp;quot;));&lt;br /&gt;
                f.add(controls, BorderLayout.SOUTH);&lt;br /&gt;
                f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);&lt;br /&gt;
                f.pack();&lt;br /&gt;
                f.setLocationRelativeTo(null);&lt;br /&gt;
                f.setResizable(false);&lt;br /&gt;
                f.setVisible(true);&lt;br /&gt;
            }&lt;br /&gt;
        });&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
 &amp;lt;/source&amp;gt;&lt;br /&gt;
    &lt;br /&gt;
   &lt;br /&gt;
  &amp;lt;!-- end source code --&amp;gt;&lt;/div&gt;</summary>
			</entry>

	</feed>