⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 bloomopengl.java

📁 JAVA图形特效,详细介绍SWING等的效果开发
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
        }

        if (success[0] == 0) {
            gl.glDeleteObjectARB(fragmentProgram);
            return -1;
        }

        return fragmentProgram;
    }

    private static void enableBlurFragmentProgram(GL gl, int program,
                                                  float textureWidth,
                                                  float textureHeight) {
        gl.glUseProgramObjectARB(program);

        int kernelWidth = 5;
        int kernelHeight = 5;

        float xoff = 1.0f / textureWidth;
        float yoff = 1.0f / textureHeight;

        float[] offsets = new float[kernelWidth * kernelHeight * 2];
        int offsetIndex = 0;

        for (int i = -kernelHeight / 2; i < kernelHeight / 2 + 1; i++) {
            for (int j = -kernelWidth / 2; j < kernelWidth / 2 + 1; j++) {
                offsets[offsetIndex++] = j * xoff;
                offsets[offsetIndex++] = i * yoff;
            }
        }

        int loc = gl.glGetUniformLocationARB(program, "offsets");
        gl.glUniform2fv(loc, offsets.length, offsets, 0);

        float[] values = createGaussianBlurFilter(2);

        loc = gl.glGetUniformLocationARB(program, "kernelVals");
        gl.glUniform1fvARB(loc, values.length, values, 0);
    }

    private static float[] createGaussianBlurFilter(int radius) {
        if (radius < 1) {
            throw new IllegalArgumentException("Radius must be >= 1");
        }

        int size = radius * 2 + 1;
        float[] data = new float[size * size];

        float sigma = radius / 3.0f;
        float twoSigmaSquare = 2.0f * sigma * sigma;
        float sigmaRoot = (float) Math.sqrt(twoSigmaSquare * Math.PI);
        float total = 0.0f;

        int index = 0;
        for (int y = -radius; y <= radius; y++) {
            for (int x = -radius; x <= radius; x++) {
                float distance = x * x + y * y;
                data[index] = (float) Math.exp(-distance / twoSigmaSquare) / sigmaRoot;
                total += data[index];
                index++;
            }
        }

        for (int i = 0; i < data.length; i++) {
            data[i] /= total;
        }

        return data;
    }

    private static void enableBrightPassFragmentProgram(GL gl, int program,
                                                        float threshold) {
        gl.glUseProgramObjectARB(program);

        int loc = gl.glGetUniformLocationARB(program, "brightPassThreshold");
        gl.glUniform1fARB(loc, threshold);
    }

    private static void disableFragmentProgram(GL gl) {
        gl.glUseProgramObjectARB(0);
    }

    public void display(GLAutoDrawable glAutoDrawable) {
        GL gl = glAutoDrawable.getGL();
        gl.glLoadIdentity(); 
        gl.glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
        gl.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT);
        viewOrtho(gl, image.getWidth(), image.getHeight());
        gl.glEnable(GL.GL_TEXTURE_2D);

        int width = image.getWidth();
        int height = image.getHeight();

        // Source Image/bright pass on FBO1
        renderBrightPass(gl, width, height);
        // Source image on FBO2
        renderImage(gl, width, height);
        // On screen
        renderTextureOnScreen(gl, width, height);

        //render5x5(gl, width, height);
        render11x11(gl, width, height);
        render21x21(gl, width, height);
        render41x41(gl, width, height);

        gl.glDisable(GL.GL_TEXTURE_2D);
        gl.glFlush();
    }

    private void render41x41(GL gl, int width, int height) {
        // FBO1/blur on FBO2
        renderBlur(gl, width / 8.0f, height / 8.0f);
        // Add on screen
        gl.glPushMatrix();
        gl.glTranslatef(0.0f, -height * 7.0f, 0.0f);
        renderAddTextureOnScreen(gl, width * 8.0f, height * 8.0f);
        gl.glPopMatrix();
    }

    private void render21x21(GL gl, int width, int height) {
        // FBO1/blur on FBO2
        renderBlur(gl, width / 4.0f, height / 4.0f);
        // Add on screen
        gl.glPushMatrix();
        gl.glTranslatef(0.0f, -height * 3.0f, 0.0f);
        renderAddTextureOnScreen(gl, width * 4.0f, height * 4.0f);
        gl.glPopMatrix();
    }

    private void render11x11(GL gl, int width, int height) {
        // FBO1/blur on FBO2
        renderBlur(gl, width / 2.0f, height / 2.0f);
        // Add on screen
        gl.glPushMatrix();
        gl.glTranslatef(0.0f, -height, 0.0f);
        renderAddTextureOnScreen(gl, width * 2.0f, height * 2.0f);
        gl.glPopMatrix();
    }

    private void render5x5(GL gl, int width, int height) {
        // FBO1/blur on FBO2
        renderBlur(gl, width, height);
        // Add on screen
        renderAddTextureOnScreen(gl, width, height);
    }

    private void renderAddTextureOnScreen(GL gl, float width, float height) {
        gl.glEnable(GL.GL_BLEND);
        gl.glBlendFunc(GL.GL_ONE, GL.GL_ONE);
        renderTextureOnScreen(gl, width, height);
        gl.glDisable(GL.GL_BLEND);
    }

    private void renderTextureOnScreen(GL gl, float width, float height) {
        // Draw the texture on a quad
        gl.glBindTexture(GL.GL_TEXTURE_2D, frameBufferTexture2);
        renderTexturedQuad(gl, width, height, false);
        gl.glBindTexture(GL.GL_TEXTURE_2D, 0);
    }

    private void renderBrightPass(GL gl, float width, float height) {
        // Draw into the FBO
        gl.glBindFramebufferEXT(GL.GL_FRAMEBUFFER_EXT, frameBufferObject1);
        gl.glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
        gl.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT);
        enableBrightPassFragmentProgram(gl, brightPassShader, threshold);
        gl.glBindTexture(GL.GL_TEXTURE_2D, texture.getTextureObject());

        renderTexturedQuad(gl, width, height, texture.getMustFlipVertically());

        gl.glBindTexture(GL.GL_TEXTURE_2D, 0);
        disableFragmentProgram(gl);

        gl.glBindFramebufferEXT(GL.GL_FRAMEBUFFER_EXT, 0);
    }

    private void renderImage(GL gl, float width, float height) {
        // Draw into the FBO
        gl.glBindFramebufferEXT(GL.GL_FRAMEBUFFER_EXT, frameBufferObject2);
        gl.glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
        gl.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT);

        gl.glBindTexture(GL.GL_TEXTURE_2D, texture.getTextureObject());
        renderTexturedQuad(gl, width, height, texture.getMustFlipVertically());
        gl.glBindTexture(GL.GL_TEXTURE_2D, 0);

        gl.glBindFramebufferEXT(GL.GL_FRAMEBUFFER_EXT, 0);
    }

    private void renderBlur(GL gl, float width, float height) {
        // Draw into the FBO
        gl.glBindFramebufferEXT(GL.GL_FRAMEBUFFER_EXT, frameBufferObject2);
        gl.glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
        gl.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT);

        enableBlurFragmentProgram(gl, blurShader, width, height);
        gl.glBindTexture(GL.GL_TEXTURE_2D, frameBufferTexture1);

        renderTexturedQuad(gl, width, height, texture.getMustFlipVertically());

        gl.glBindTexture(GL.GL_TEXTURE_2D, 0);
        disableFragmentProgram(gl);

        gl.glBindFramebufferEXT(GL.GL_FRAMEBUFFER_EXT, 0);
    }

    @Override
    public Dimension getPreferredSize() {
        return new Dimension(image.getWidth(), image.getHeight());
    }

    public void reshape(GLAutoDrawable glAutoDrawable, int x, int y,
                        int width, int height) {
        GL gl = glAutoDrawable.getGL();

        gl.glViewport(0, 0, width, height);
        gl.glMatrixMode(GL.GL_PROJECTION);
        gl.glLoadIdentity();

        glu.gluPerspective(50, (float) width / height, 5, 2000);
        gl.glMatrixMode(GL.GL_MODELVIEW);
        gl.glLoadIdentity();
    }

    public void displayChanged(GLAutoDrawable glAutoDrawable, boolean modeChanged,
                               boolean deviceChanged) {
    }

    public float getThreshold() {
        return threshold;
    }

    public void setThreshold(float threshold) {
        this.threshold = threshold;
        repaint();
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                final BloomOpenGL bloom;
                final JSlider slider;

                JFrame f = new JFrame("Bloom OpenGL");
                f.add(bloom = new BloomOpenGL());

                JPanel controls = new JPanel(new FlowLayout(FlowLayout.LEADING));
                controls.add(new JLabel("Bloom: 0.0"));
                controls.add(slider = new JSlider(0, 100, 30));
                slider.addChangeListener(new ChangeListener() {
                    public void stateChanged(ChangeEvent e) {
                        JSlider slider = (JSlider) e.getSource();
                        float threshold = slider.getValue() / 100.0f;
                        bloom.setThreshold(threshold);
                    }
                });
                controls.add(new JLabel("1.0"));
                f.add(controls, BorderLayout.SOUTH);

                f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

                f.pack();
                f.setLocationRelativeTo(null);
                f.setResizable(false);
                f.setVisible(true);
            }
        });
    }
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -