以下是对问题的描述:
我似乎无法使其正常工作。
当我运行代码时,我看到整个屏幕上绘制的形状,但不是中间的精灵。它仍然是空白的。尽管看起来我设置了具有1种颜色纹理的FBO,但即使我将FBO对象选择到上下文中,它仍然只会呈现屏幕。
我想要实现的是将这些形状绘制到屏幕外纹理(显然使用FBO),然后将其渲染到屏幕上某处绘制的精灵(或立方体或我们)的表面上。然而,无论我绘制什么,似乎都是在屏幕上绘制的。
tex(tex_object_ID);函数只是OpenGL标准纹理绑定的简写包装器。它将纹理选择到当前渲染上下文中。
无论我尝试什么,我都会得到这样的结果:精灵是空白的,但所有这些形状都应该出现在那里,而不是在主屏幕上。 (我没有将渲染绑定到FBO吗?为什么它仍然在屏幕上渲染?)
我认为这只是我缺少正确顺序设置FBO的后勤工作。任何人都可以告诉我的代码有什么问题吗?
我不知道为什么背景是红色的,因为我在选择FBO后将其清除。这是精灵应该得到红色背景&在它上面绘制的形状。
/*-- Initialization -- */
GLuint texture = 0;
GLuint Framebuffer = 0;
GLuint GenerateFrameBuffer(int dimension)
{
glEnable(GL_TEXTURE_2D);
glGenTextures(1, &texture);
glBindTexture(GL_TEXTURE_2D, texture);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, dimension, dimension, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
glGenFramebuffers(1, &Framebuffer);
glBindFramebuffer(GL_FRAMEBUFFER, Framebuffer);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0);
glDrawBuffer(GL_COLOR);
glReadBuffer(GL_COLOR);
glBindFramebuffer(GL_FRAMEBUFFER, 0);
if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
console_log("GL_FRAMEBUFFER != GL_FRAMEBUFFER_COMPLETE\n");
return texture;
}
// Store framebuffer texture (should I store texture here or Framebuffer object?)
GLuint FramebufferHandle = GenerateFrameBuffer( 256 );
遵循标准OpenGL初始化代码,分配内存,创建和绑定VBO等。这正常工作,初始化时没有错误。我可以在标准双缓冲区上成功渲染VBO,多边形,纹理多边形,线条等。
接下来,在我的渲染循环中,我执行以下操作:
// Possible problem?
// Should FramebufferHandle be passed here?
// I tried "texture" and "Framebuffer " as well, to no effect:
glBindFramebuffer(GL_FRAMEBUFFER, FramebufferHandle);
// Correct projection, just calculates the view based on current zoom
Projection = setOrthoFrustum(-config.zoomed_width/2, config.zoomed_width/2, -config.zoomed_height/2, config.zoomed_height/2, 0, 100);
View.identity();
Model.identity();
// Mini shader, 100% *guaranteed* to work, there are no errors in it (works normally on the screen)
shaderProgramMini.use();
//Clear frame buffer with blue color
glClearColor(0.0f, 0.0f, 1.0f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);// | GL_DEPTH_BUFFER_BIT);
// Set yellow to draw different shapes on the framebuffer
color = {1.0f,1.0f,0.0f};
// Draw several shapes (already correctly stored in VBO objects)
Memory.select(VBO_RECTANGLES); // updates uniforms
glDrawArrays(GL_QUADS, 0, Memory.renderable[VBO_RECTANGLES].indexIndex);
Memory.select(VBO_CIRCLES); // updates uniforms
glDrawArrays(GL_LINES, 0, Memory.renderable[VBO_CIRCLES].indexIndex);
Memory.select(VBO_2D_LIGHT); // updates uniforms
glDrawArrays(GL_LINES, 0, Memory.renderable[VBO_2D_LIGHT].indexIndex);
// Done writing to framebuffer
glBindFramebuffer(GL_FRAMEBUFFER, 0);
// Correct projection, just calculates the view based on current zoom
Projection = setOrthoFrustum(-config.zoomed_width/2, config.zoomed_width/2, -config.zoomed_height/2, config.zoomed_height/2, 0, 100);
View.identity();
Model.identity();
Model.scale(10.0);
// Select texture shader to draw what was drawn on offscreen Framebuffer / texture
// Standard texture shader, 100% *guaranteed* to work, there are no errors in it (works normally on the screen)
shaderProgramTexture.use();
// This is a wrapper for bind texture to ID, just shorthand function name
tex(texture); // FramebufferHandle; // ? // maybe the mistake in binding to the wrong target object?
color = {0.5f,0.2f,0.0f};
Memory.select(VBO_SPRITE); Select a square VBO for rendering sprites (works if any other texture is assigned to it)
// finally draw the sprite with Framebuffer's texture:
glDrawArrays(GL_TRIANGLES, 0, Memory.renderable[VBO_SPRITE].indexIndex);
我可能已经完全错了。或FramebufferHandle / Framebuffer /纹理对象未正确传递给某些东西。但是我整天都在度过,希望比我更有经验的人能看出错误。
答案 0 :(得分:4)
GL_COLOR
不是glDrawBuffer
NONE
,FRONT_LEFT
,FRONT_RIGHT
,BACK_LEFT
,BACK_RIGHT
,FRONT
,BACK
,LEFT
,RIGHT
,FRONT_AND_BACK
,AUXi
。当上下文绑定到默认帧缓冲区时,
DrawBuffer
的参数,以及它们指示的缓冲区。相同的参数对ReadBuffer
有效,但只选择了一个缓冲区,如章节中所述。
COLOR_ATTACHMENTi
当上下文绑定到帧缓冲区对象时,DrawBuffer和ReadBuffer的参数,以及它们指示的缓冲区。
COLOR_ATTACHMENTi
中 i 的范围可以从零到MAX_COLOR_ATTACHMENTS
的值减一。
Thsi表示glDrawBuffer(GL_COLOR);
和glReadBuffer(GL_COLOR);
会产生GL_INVALID_ENUM
错误。
请尝试使用COLOR_ATTACHMENT0
。
此外,glCheckFramebufferStatus(GL_FRAMEBUFFER)
检查绑定到目标的帧缓冲对象的完整性。
这意味着
glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE
必须在
之前完成glBindFramebuffer(GL_FRAMEBUFFER, 0);
或者您必须使用:
glNamedFramebufferReadBuffer(Framebuffer, GL_FRAMEBUFFER);