我想尽办法在 OpenGL 和 C++ 中实现帧缓冲区对象。
基本上,我有一个处理帧缓冲区对象功能的类。然而,在渲染到帧缓冲区并使用帧缓冲区作为纹理之后,唯一绘制的是来自命令 glClearColor 的蓝色。
看看这段代码,我错过了什么吗?
void FrameBuffer::initFrameBufferDepthBuffer(void) {
glGenRenderbuffers(1, &fbo_depth); // Generate one render buffer and store the ID in fbo_depth
glBindRenderbuffer(GL_RENDERBUFFER, fbo_depth); // Bind the fbo_depth render buffer
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT, window_width, window_height); // Set the render buffer storage to be a depth component, with a width and height of the window
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, fbo_depth); // Set the render buffer of this buffer to the depth buffer
bool status = glCheckFramebufferStatus(GL_FRAMEBUFFER) == GL_FRAMEBUFFER_COMPLETE;
if(!status){
std::cout << "Error during depth buffer\n";
}
glBindRenderbuffer(GL_RENDERBUFFER, 0); // Unbind the render buffer
}
void FrameBuffer::initFrameBufferTexture(void) {
glGenTextures(1, &fbo_texture); // Generate one texture
glBindTexture(GL_TEXTURE_2D, fbo_texture); // Bind the texture fbo_texture
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, window_width, window_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); // Create a standard texture with the width and height of our window
// Setup the basic texture parameters
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,getTexture(), 0);
// Unbind the texture
glBindTexture(GL_TEXTURE_2D, 0);
bool status = glCheckFramebufferStatus(GL_FRAMEBUFFER) == GL_FRAMEBUFFER_COMPLETE;;
if(!status){
std::cout << "Error during texture buffer\n";
}
}
void FrameBuffer::create(void) {
glGenFramebuffers(1, &fbo); // Generate one frame buffer and store the ID in fbo
glBindFramebuffer(GL_FRAMEBUFFER, fbo); // Bind our frame buffer
initFrameBufferDepthBuffer(); // Initialize our frame buffer depth buffer
initFrameBufferTexture(); // Initialize our frame buffer texture
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, fbo_texture, 0); // Attach the texture fbo_texture to the color buffer in our frame buffer
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, fbo_depth); // Attach the depth buffer fbo_depth to our frame buffer
GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER); // Check that status of our generated frame buffer
if (status != GL_FRAMEBUFFER_COMPLETE) // If the frame buffer does not report back as complete
{
std::cout << "Couldn't create frame buffer" << std::endl; // Output an error to the console
exit(0); // Exit the application
}
glBindFramebuffer(GL_FRAMEBUFFER, 0); // Unbind our frame buffer
}
void FrameBuffer::bindTexture() {
glBindTexture(GL_TEXTURE_2D, fbo_texture); // Bind our frame buffer texture
}
void FrameBuffer::unbindTexture() {
glBindTexture(GL_TEXTURE_2D, 0); // Bind our frame buffer texture
}
void FrameBuffer::bind() {
glBindFramebuffer(GL_FRAMEBUFFER, fbo);
}
void FrameBuffer::unbind() {
glBindFramebuffer(GL_FRAMEBUFFER, 0);
}
void FrameBuffer::startUse() {
bind();
glPushAttrib(GL_VIEWPORT_BIT | GL_ENABLE_BIT); // Push our glEnable and glViewport states
glViewport(0, 0, window_width, window_height); // Set the size of the frame buffer view port
glMatrixMode( GL_PROJECTION ); //Switch to setting the camera perspective
float ratio = (GLfloat)window_width/(GLfloat)window_height; //Set the camera perspective
glLoadIdentity(); //reset the camera
gluPerspective( 60.0f, ratio, 0.1f, 100.0f );
glMatrixMode(GL_MODELVIEW);
glClearColor (0.0f, 0.0f, 1.0f, 1.0f); // Set the clear colour
glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Clear the depth and colour buffers
glLoadIdentity();
}
void FrameBuffer::stopUse() {
glPopAttrib(); // Restore our glEnable and glViewport states
unbind();
}
void FrameBuffer::destroy() {
glDeleteFramebuffers(1,&this->fbo);
glDeleteTextures(1,&fbo_texture);
glDeleteRenderbuffers(1,&fbo_depth);
}
unsigned int FrameBuffer::getTexture() {
return fbo_texture;
}