以下是对该问题的描述:
1.我想渲染一些VBO形状(矩形,圆形等)到一个屏幕外的帧缓冲对象。这可以是任何形状。
1.然后我想在一个简单的sprite表面上绘制结果作为纹理,而不是在整个屏幕本身上。
我似乎无法使它正常工作。
当我运行代码时,我看到图形被绘制在整个屏幕上,但中间的sprite中没有。它仍然是空白的。尽管看起来我用1个颜色纹理设置了FBO,但它仍然只呈现在屏幕上,即使我在上下文中选择了FBO对象。
我想要实现的是将这些形状绘制到屏幕外的纹理上(显然是使用FBO),然后将其渲染到屏幕上某个位置绘制的sprite(或立方体,或我们)的表面上。然而,无论我绘制什么,看起来都是在屏幕上绘制的。
tex(tex_对象_ID);函数只是OpenGL标准纹理绑定的一个简单的 Package 器。它选择一个纹理到当前的渲染环境中。
无论我怎么尝试我都得到这样的结果:sprite是空白的,但是所有这些形状应该出现在那里,而不是在主屏幕上。(我没有绑定渲染到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/texture对象没有被正确地传递给一些东西。但是我花了一整天的时间,希望比我更有经验的人能看到这个错误。
1条答案
按热度按时间qeeaahzv1#
GL_COLOR
不是glDrawBuffer
的可接受值请参阅OpenGL 4.6 API Compatibility Profile Specification, 17.4.1 Selecting Buffers for Writing, Table 17.4 and Table 17.5, page 628
第一个月第二个月第一个月,第一个月第三个月,第一个月第四个月,第一个月第五个月,第一个月第六个月,第一个月第七个月,第一个月第八个月,第一个月第九个月,第一个月第十个月,第一个月第十一个月,第一个月第十二个月。
DrawBuffer
的参数(当上下文绑定到默认帧缓冲区时),以及它们所指示的缓冲区。相同的参数对ReadBuffer
有效,但只选择了一个缓冲区,如第节所述。COLOR_ATTACHMENTi
当上下文绑定到帧缓冲区对象时,DrawBuffer(s)和ReadBuffer的参数,以及它们指示的缓冲区。
COLOR_ATTACHMENTi
中的 i 的范围可以从零到MAX_COLOR_ATTACHMENTS
的值减一。这意味着
glDrawBuffer(GL_COLOR);
和glReadBuffer(GL_COLOR);
将生成GL_INVALID_ENUM
错误。请尝试改用COLOR_ATTACHMENT0
。此外,
glCheckFramebufferStatus(GL_FRAMEBUFFER)
检查绑定到 target 的帧缓冲区对象的完整性。这就意味着
必须在之前
或者您必须用途: