所以我试图用C ++和GLFW / GLEW在OpenGL中创建一个帧缓冲对象。我已成功使用VAO和VBO来简单地使用OpenGL的glDrawArrays方法渲染顶点数组,以在屏幕上制作四边形。然后,我创建了一个多重采样的帧缓冲区对象,并创建了相应的颜色缓冲区和深度缓冲区,然后绑定它,然后渲染四边形,然后解除对帧缓冲区对象,然后尝试将FBO blit到屏幕。它没有那么好或根本没有效果。此外,如果它引起混淆,如果项目在visual studio中以发布模式运行,我做了一个名为“INRELEASE”的预处理器定义,这样在程序启动时就不会弹出控制台。 这是我的代码。
Fbo.h:
#pragma once
#include "Window.h"
class Fbo
{
public:
static const int NONE = 0;
static const int DEPTH_TEXTURE = 1;
static const int DEPTH_RENDER_BUFFER = 2;
private:
Window *window;
const int width;
const int height;
GLuint frameBuffer;
bool multisample;
GLuint colorTexture;
GLuint depthTexture;
GLuint depthBuffer;
GLuint colorBuffer;
void initializeFrameBuffer(int type);
void createFrameBuffer();
void createTextureAttachment();
void createDepthTextureAttachment();
void createMultisampledColorAttachment();
void createDepthBufferAttachment();
public:
Fbo(Window *window, int width, int height, int depthBufferType);
Fbo(Window *window, int width, int height);
void cleanUp() const;
void bindFrameBuffer() const;
void unbindFrameBuffer() const;
void bindToRead() const;
void resolveToFbo(Fbo *outputFbo) const;
void resolveToScreen() const;
inline int getColorTexture() const { return colorTexture; }
inline int getDepthTexture() const { return depthTexture; }
};
Fbo.cpp:
#include "Fbo.h"
#include <GLFW\glfw3.h>
#include <GL\glew.h>
#include <iostream>
Fbo::Fbo(Window *window, int width, int height, int depthBufferType) : width(width), height(height)
{
this->window = window;
multisample = false;
initializeFrameBuffer(depthBufferType);
}
Fbo::Fbo(Window *window, int width, int height) : width(width), height(height)
{
this->window = window;
multisample = true;
initializeFrameBuffer(DEPTH_RENDER_BUFFER);
}
void Fbo::cleanUp() const
{
glDeleteFramebuffers(1, &frameBuffer);
glDeleteTextures(1, &colorTexture);
glDeleteTextures(1, &depthTexture);
glDeleteRenderbuffers(1, &depthBuffer);
glDeleteRenderbuffers(1, &colorBuffer);
}
void Fbo::bindFrameBuffer() const
{
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, frameBuffer);
glViewport(0, 0, width, height);
}
void Fbo::unbindFrameBuffer() const
{
glBindFramebuffer(GL_FRAMEBUFFER, 0);
glViewport(0, 0, window->getWidth(), window->getHeight());
}
void Fbo::bindToRead() const
{
glBindTexture(GL_TEXTURE_2D, 0);
glBindFramebuffer(GL_READ_FRAMEBUFFER, frameBuffer);
glReadBuffer(GL_COLOR_ATTACHMENT0);
}
void Fbo::resolveToFbo(Fbo *outputFbo) const
{
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, outputFbo->frameBuffer);
glBindFramebuffer(GL_READ_FRAMEBUFFER, frameBuffer);
glBlitFramebuffer(0, 0, width, height, 0, 0, outputFbo->width, outputFbo->height, GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT, GL_NEAREST);
unbindFrameBuffer();
}
void Fbo::resolveToScreen() const
{
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
glBindFramebuffer(GL_READ_FRAMEBUFFER, frameBuffer);
glDrawBuffer(GL_BACK);
glBlitFramebuffer(0, 0, width, height, 0, 0, window->getWidth(), window->getHeight(), GL_COLOR_BUFFER_BIT, GL_NEAREST);
unbindFrameBuffer();
}
void Fbo::initializeFrameBuffer(int type)
{
createFrameBuffer();
if (multisample)
createMultisampledColorAttachment();
else
createTextureAttachment();
if (type == DEPTH_RENDER_BUFFER)
{
createDepthBufferAttachment();
}
else if (type == DEPTH_TEXTURE)
{
createDepthTextureAttachment();
}
unbindFrameBuffer();
}
void Fbo::createFrameBuffer()
{
glGenFramebuffers(1, &frameBuffer);
glBindFramebuffer(GL_FRAMEBUFFER, frameBuffer);
glDrawBuffer(GL_COLOR_ATTACHMENT0);
}
void Fbo::createTextureAttachment()
{
glGenTextures(1, &colorTexture);
glBindTexture(GL_TEXTURE_2D, colorTexture);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
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);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, colorTexture, 0);
}
void Fbo::createDepthTextureAttachment()
{
glGenTextures(1, &depthTexture);
glBindTexture(GL_TEXTURE_2D, depthTexture);
glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT24, width, height, 0, GL_DEPTH_COMPONENT, GL_FLOAT, NULL);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, depthTexture, 0);
}
void Fbo::createMultisampledColorAttachment()
{
glGenRenderbuffers(1, &colorBuffer);
glBindRenderbuffer(GL_RENDERBUFFER, colorBuffer);
glRenderbufferStorageMultisample(GL_RENDERBUFFER, 4, GL_RGBA8, width, height);
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, colorBuffer);
}
void Fbo::createDepthBufferAttachment()
{
glGenRenderbuffers(1, &depthBuffer);
glBindRenderbuffer(GL_RENDERBUFFER, depthBuffer);
if (!multisample)
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT24, width, height);
else
glRenderbufferStorageMultisample(GL_RENDERBUFFER, 4, GL_DEPTH_COMPONENT24, width, height);
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, depthBuffer);
}
Main.cpp的:
#include <iostream>
#include <GL\glew.h>
#include <GLFW\glfw3.h>
#include "Window.h"
#include "Fbo.h"
#include "Loader.h"
#include "Renderer.h"
#ifdef INRELEASE
int WinMain()
#else
int main()
#endif
{
Window window("3D Engine", 800, 600, true);
Loader loader;
Renderer renderer;
float vertices[] =
{
-0.5f, 0.5f, 0.0f,
-0.5f, -0.5f, 0.0f,
0.5f, -0.5f, 0.0f,
0.5f, -0.5f, 0.0f,
0.5f, 0.5f, 0.0f,
-0.5f, 0.5f, 0.0f
};
RawModel model = loader.loadToVao(vertices, sizeof(vertices));
Fbo fbo(&window, window.getWidth(), window.getHeight());
while (!window.isClosed())
{
window.clear();
fbo.bindFrameBuffer();
renderer.render(model);
fbo.unbindFrameBuffer();
fbo.resolveToScreen();
window.update();
}
fbo.cleanUp();
loader.cleanUp();
return 0;
}