我正在制作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;
}
答案 0 :(得分:2)
在着色器中执行以下操作时:
gl_FragColor.x -=1-color.x;
gl_FragColor.y -=1-color.y;
gl_FragColor.z -=1-color.z;
您假设当您输入main()
gl_FragColor
时,包含当前帧缓冲区的当前像素颜色。
但事实并非如此! gl_FragColor
是您需要在着色器中设置的颜色,直到您设置它,其值将是未定义的(在您的情况下,它似乎设置为黑色),它将永远不会包含"当前帧缓冲区色" (查看规格,这适用于所有版本的OpenGL / OpenGLES,没有例外)。
要获得当前的帧缓冲颜色,您需要为移动GPU使用EXT_shader_framebuffer_fetch等OpenGL扩展,遗憾的是桌面GPU不存在此类扩展(但您可以将Image Load Store与OpenGL4一起使用)。
但在这里我离题了,因为我认为你不需要任何这些扩展,你需要的只是在渲染你的掩码时启用blending并正确配置混合公式以达到你的效果。