我使用了tutorial中的一些代码,并在个人项目中实现,但FrameBufferObject只显示一帧,然后再也没有显示任何内容。
以下是我使用的代码:(在glutDisplayFunc()
)
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_FBO);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
// Render out objects, using glsl shaders with MVPs
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
glClearColor(0.0, 0.0, 0.0, 1.0);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glUseProgram(m_Shader);
glBindTexture(GL_TEXTURE_2D, m_DiffuseTexture);
glUniform1i(uniform_fbo_texture, /*GL_TEXTURE*/0);
glEnableVertexAttribArray(attribute_v_coord_postproc);
glBindBuffer(GL_ARRAY_BUFFER, vbo_fbo_vertices);
glVertexAttribPointer(attribute_v_coord_postproc,2,GL_FLOAT,GL_FALSE,0,0);
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
glDisableVertexAttribArray(attribute_v_coord_postproc);
glutSwapBuffers();
您可以在上面看到的所有功能实际上都被抽象为函数和类,但这就是所有功能。 m_Shader是一个能够转换为gluint(其ID)的类。
这里是FBO类的构造函数:
/* Texture */
glActiveTexture(GL_TEXTURE0);
glGenTextures(1, &m_DiffuseTexture);
glBindTexture(GL_TEXTURE_2D, m_DiffuseTexture);
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_RGBA, a_Width, a_Height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
glBindTexture(GL_TEXTURE_2D, 0);
/* Depth buffer */
glGenRenderbuffers(1, &m_DepthBuffer);
glBindRenderbuffer(GL_RENDERBUFFER, m_DepthBuffer);
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT16, a_Width, a_Height);
glBindRenderbuffer(GL_RENDERBUFFER, 0);
/* Framebuffer to link everything together */
glGenFramebuffers(1, &m_FBO);
glBindFramebuffer(GL_FRAMEBUFFER, m_FBO);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, m_DiffuseTexture, 0);
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, m_DepthBuffer);
// check FBO status
GLenum status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT);
if (status != GL_FRAMEBUFFER_COMPLETE_EXT)
{
char tmps[256];
switch (status)
{
case GL_FRAMEBUFFER_COMPLETE_EXT:
strcpy_s(tmps, 256, "Frame buffer complete");
return;
case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT:
strcpy_s(tmps, 256, "Frame buffer incomplete: Attachment is NOT complete");
return;
case GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_EXT:
strcpy_s(tmps, 256, "Frame buffer incomplete: No image is attached to FBO");
return;
case GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT:
strcpy_s(tmps, 256, "Frame buffer incomplete: Attached images have different dimensions");
return;
case GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT:
strcpy_s(tmps, 256, "Frame buffer incomplete: Color attached images have different internal formats");
return;
case GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER_EXT:
strcpy_s(tmps, 256, "Frame buffer incomplete: Draw buffer");
return;
case GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER_EXT:
strcpy_s(tmps, 256, "Frame buffer incomplete: Read buffer");
return;
case GL_FRAMEBUFFER_UNSUPPORTED_EXT:
strcpy_s(tmps, 256, "Unsupported by FBO implementation");
return;
default:
strcpy_s(tmps, 256, "Unknown error");
return;
}
char tmps2[256];
sprintf_s(tmps2, 256, "FBO not setup OK: '%s'", tmps);
MessageBox(NULL, tmps2, "Error", MB_ICONSTOP);
}
glBindFramebuffer(GL_FRAMEBUFFER, 0);
GLfloat fbo_vertices[] =
{
-1, -1,
1, -1,
-1, 1,
1, 1,
};
glGenBuffers(1, &vbo_fbo_vertices);
glBindBuffer(GL_ARRAY_BUFFER, vbo_fbo_vertices);
glBufferData(GL_ARRAY_BUFFER, sizeof(fbo_vertices), fbo_vertices, GL_STATIC_DRAW);
glBindBuffer(GL_ARRAY_BUFFER, 0);
m_Shader.Add(GL_VERTEX_SHADER, "data/shaders/postProcess.vert");
m_Shader.Add(GL_FRAGMENT_SHADER, "data/shaders/postProcess.frag");
attribute_v_coord_postproc = glGetAttribLocation(m_Shader, "v_coord");
uniform_fbo_texture = glGetUniformLocation(m_Shader, "fbo_texture");