如何使用着色器绘制FBO lwjgl

How to use shader for drawing FBO lwjgl

我正在制作一个 2D 游戏,我想制作一个光罩。到目前为止,我制作了一个帧缓冲区,我在其中放置了我的蒙版,但我无法在其上应用着色器。当我不使用着色器时,光照贴图被正确绘制(没有场景,所以对于这段代码,我绘制了一个带有一个白色矩形的黑屏)但是当我尝试将它与场景混合时,它只是绘制黑屏。这就是我绘制帧缓冲区和应用着色器的方式。

//draw scene

glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_frameBufferObject);//enable frame buffer
            glPushAttrib(GL_VIEWPORT_BIT);
            glViewport(0, 0, 1920, 1080);
            glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);  

            //fill with black
            glColor3f(0.0f, 0.0f, 0.0f);
            glBegin(GL_QUADS);
                glVertex2f(0, 0);
                glVertex2f(1920, 0);
                glVertex2f(1920, 1080);
                glVertex2f(0, 1080);
            glEnd();

            //example light, a rectangle trough which i should see the scene
            glColor3f(1.0f,1.0f,1.0f);
            glBegin(GL_QUADS);
                glVertex2f(100, 100);
                glVertex2f(300, 100);
                glVertex2f(300, 300);
                glVertex2f(100, 300);
            glEnd();

            //Deactivate the framebuffer object
            glPopAttrib();
            glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);

            glUseProgram(shaderProgram3);//this is the shader program
            //Render the framebuffer object to the screen

            glEnable(GL_TEXTURE_2D);
            glBindTexture(GL_TEXTURE_2D, m_frameBufferTexture);
                glBegin(GL_QUADS);
                    glTexCoord2f(0f, 0f);
                    glVertex2f(0, 0);
                    glTexCoord2f(1f, 0f);
                    glVertex2f(1920, 0); 
                    glTexCoord2f(1f, 1f);
                    glVertex2f(1920, 1080);
                    glTexCoord2f(0f, 1f);
                    glVertex2f(0, 1080);
                glEnd();
            glDisable(GL_TEXTURE_2D);
            glUseProgram(0);

    Display.update();
    Display.sync(60);

这是着色器

uniform sampler2D backbuffer;

void main( void ) {    
    vec2 position;
    position.x = gl_FragCoord.x/1920;
    position.y = gl_FragCoord.y/1080;
    vec4 color = texture2D(backbuffer, position);
    gl_FragColor.x -=1-color.x;
    gl_FragColor.y -=1-color.y;
    gl_FragColor.z -=1-color.z;
}

当您在着色器中执行以下操作时:

gl_FragColor.x -=1-color.x;
gl_FragColor.y -=1-color.y;
gl_FragColor.z -=1-color.z;

您假设当您输入 main()gl_FragColor 包含当前帧缓冲区的当前像素颜色。

但事实并非如此! gl_FragColor 是您需要在着色器中设置的颜色,在您设置它之前,它的值将是未定义的(在您的情况下它似乎设置为黑色),它永远不会包含 "current framebuffer color" (检查规范,这适用于所有版本的 OpenGL / OpenGLES,没有例外)。

要获得当前的帧缓冲区颜色,您需要使用 OpenGL 扩展,例如 EXT_shader_framebuffer_fetch for mobile GPUs and sadly this kind of extension does not exist for desktop GPUs (but you can use Image Load Store with OpenGL4)。

但在这里我离题了,因为我认为您不需要任何这些扩展,您需要的只是在渲染遮罩时启用 blending 并正确配置混合公式以实现您的效果。