如何使用着色器绘制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 并正确配置混合公式以实现您的效果。
我正在制作一个 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 并正确配置混合公式以实现您的效果。