Implement Multi-Sample Anti Aliasin (MSAA)
This commit is contained in:
parent
e9a9b8a2cf
commit
37b46bc584
97
src/main.cc
97
src/main.cc
@ -50,8 +50,13 @@
|
||||
|
||||
#define WIREFRAME 0
|
||||
#define NORMALS 0
|
||||
#define MSAA 1
|
||||
#define POINT_LIGHTS 1
|
||||
|
||||
#if MSAA
|
||||
#define MSAA_SAMPLE_COUNT 4
|
||||
#endif
|
||||
|
||||
enum exit_codes : int {
|
||||
EXIT_CODE_SUCCESS,
|
||||
EXIT_CODE_SDL_INIT_FAILED,
|
||||
@ -149,9 +154,15 @@ struct FrameBuffer {
|
||||
GLuint fbo;
|
||||
GLuint color;
|
||||
GLuint depth_stencil;
|
||||
GLuint width;
|
||||
GLuint height;
|
||||
};
|
||||
|
||||
FrameBuffer create_frame_buffer(unsigned int width, unsigned int height);
|
||||
FrameBuffer create_normal_frame_buffer(unsigned int width, unsigned int height);
|
||||
#if MSAA
|
||||
FrameBuffer create_multisample_frame_buffer(unsigned int width, unsigned int height);
|
||||
void blit_multisample_frame_buffer(const FrameBuffer &multisample_buffer, const FrameBuffer &normal_buffer);
|
||||
#endif
|
||||
void delete_frame_buffer(FrameBuffer &buffer);
|
||||
GLuint load_cubemap(std::vector<std::string> textures);
|
||||
|
||||
@ -166,6 +177,11 @@ int main() {
|
||||
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 3);
|
||||
SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE);
|
||||
|
||||
#if MSAA
|
||||
SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS, 1);
|
||||
SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, MSAA_SAMPLE_COUNT);
|
||||
#endif
|
||||
|
||||
SDL_Window *window = SDL_CreateWindow("Window", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED,
|
||||
WINDOW_WIDTH, WINDOW_HEIGHT, SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE);
|
||||
if (!window) {
|
||||
@ -181,12 +197,21 @@ int main() {
|
||||
return EXIT_CODE_GLAD_LOADER_FAILED;
|
||||
}
|
||||
|
||||
#if MSAA
|
||||
glEnable(GL_MULTISAMPLE);
|
||||
#endif
|
||||
|
||||
SDL_SetRelativeMouseMode(SDL_TRUE);
|
||||
SDL_WarpMouseInWindow(window, WINDOW_HALF_WIDTH, WINDOW_HALF_HEIGHT);
|
||||
|
||||
glViewport(0, 0, WINDOW_WIDTH, WINDOW_HEIGHT);
|
||||
|
||||
FrameBuffer offscreen_buffer = create_frame_buffer(WINDOW_WIDTH, WINDOW_HEIGHT);
|
||||
#if MSAA
|
||||
FrameBuffer multisample_buffer = create_multisample_frame_buffer(WINDOW_WIDTH, WINDOW_HEIGHT);
|
||||
FrameBuffer offscreen_buffer = create_normal_frame_buffer(WINDOW_WIDTH, WINDOW_HEIGHT);
|
||||
#else
|
||||
FrameBuffer offscreen_buffer = create_normal_frame_buffer(WINDOW_WIDTH, WINDOW_HEIGHT);
|
||||
#endif
|
||||
|
||||
std::vector<Vertex> vertices = {
|
||||
// positions // normals // texture coords
|
||||
@ -497,7 +522,11 @@ int main() {
|
||||
|
||||
// Recreate offscreen frame buffer
|
||||
delete_frame_buffer(offscreen_buffer);
|
||||
offscreen_buffer = create_frame_buffer(w, h);
|
||||
offscreen_buffer = create_normal_frame_buffer(w, h);
|
||||
#if MSAA
|
||||
delete_frame_buffer(multisample_buffer);
|
||||
multisample_buffer = create_multisample_frame_buffer(w, h);
|
||||
#endif
|
||||
}
|
||||
break;
|
||||
}
|
||||
@ -523,7 +552,11 @@ int main() {
|
||||
skybox_shader.set_mat4("sb_view", glm::mat4(glm::mat3(view)));
|
||||
|
||||
// Main render pass
|
||||
#if MSAA
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, multisample_buffer.fbo);
|
||||
#else
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, offscreen_buffer.fbo);
|
||||
#endif
|
||||
|
||||
glClearColor(0.04f, 0.08f, 0.08f, 1.0f);
|
||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||
@ -578,6 +611,10 @@ int main() {
|
||||
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
|
||||
#endif
|
||||
|
||||
#if MSAA
|
||||
blit_multisample_frame_buffer(multisample_buffer, offscreen_buffer);
|
||||
#endif
|
||||
|
||||
// Post processing pass
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
||||
|
||||
@ -959,7 +996,7 @@ std::vector<Texture2D> Model::load_material_textures(aiMaterial *material, aiTex
|
||||
return textures;
|
||||
}
|
||||
|
||||
FrameBuffer create_frame_buffer(unsigned int width, unsigned int height) {
|
||||
FrameBuffer create_normal_frame_buffer(unsigned int width, unsigned int height) {
|
||||
FrameBuffer buffer = {};
|
||||
|
||||
glGenFramebuffers(1, &buffer.fbo);
|
||||
@ -990,9 +1027,61 @@ FrameBuffer create_frame_buffer(unsigned int width, unsigned int height) {
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
glBindRenderbuffer(GL_RENDERBUFFER, 0);
|
||||
|
||||
buffer.width = width;
|
||||
buffer.height = height;
|
||||
|
||||
return buffer;
|
||||
}
|
||||
|
||||
#if MSAA
|
||||
FrameBuffer create_multisample_frame_buffer(unsigned int width, unsigned int height) {
|
||||
FrameBuffer buffer = {};
|
||||
|
||||
glGenFramebuffers(1, &buffer.fbo);
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, buffer.fbo);
|
||||
|
||||
// Create color texture
|
||||
glGenTextures(1, &buffer.color);
|
||||
glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, buffer.color);
|
||||
glTexImage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, MSAA_SAMPLE_COUNT, GL_RGB, width, height, GL_TRUE);
|
||||
glTexParameteri(GL_TEXTURE_2D_MULTISAMPLE, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D_MULTISAMPLE, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
|
||||
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D_MULTISAMPLE, buffer.color, 0);
|
||||
|
||||
// Create depth and stencil buffers
|
||||
glGenRenderbuffers(1, &buffer.depth_stencil);
|
||||
glBindRenderbuffer(GL_RENDERBUFFER, buffer.depth_stencil);
|
||||
glRenderbufferStorageMultisample(GL_RENDERBUFFER, MSAA_SAMPLE_COUNT, GL_DEPTH24_STENCIL8, width, height);
|
||||
|
||||
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER, buffer.depth_stencil);
|
||||
|
||||
if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) {
|
||||
printf("Incomplete frame buffer\n");
|
||||
exit(EXIT_CODE_INCOMPLETE_FRAME_BUFFER);
|
||||
}
|
||||
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
||||
glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, 0);
|
||||
glBindRenderbuffer(GL_RENDERBUFFER, 0);
|
||||
|
||||
buffer.width = width;
|
||||
buffer.height = height;
|
||||
|
||||
return buffer;
|
||||
}
|
||||
|
||||
void blit_multisample_frame_buffer(const FrameBuffer &multisample_buffer, const FrameBuffer &normal_buffer) {
|
||||
glBindFramebuffer(GL_READ_FRAMEBUFFER, multisample_buffer.fbo);
|
||||
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, normal_buffer.fbo);
|
||||
glBlitFramebuffer(
|
||||
0, 0, multisample_buffer.width, multisample_buffer.height,
|
||||
0, 0, normal_buffer.width, normal_buffer.height,
|
||||
GL_COLOR_BUFFER_BIT, GL_NEAREST
|
||||
);
|
||||
}
|
||||
#endif
|
||||
|
||||
void delete_frame_buffer(FrameBuffer &buffer) {
|
||||
glDeleteFramebuffers(1, &buffer.fbo);
|
||||
glDeleteTextures(1, &buffer.color);
|
||||
|
Loading…
Reference in New Issue
Block a user