Implement Multi-Sample Anti Aliasing (MSAA)
This commit is contained in:
		
							
								
								
									
										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); | ||||
|   | ||||
		Reference in New Issue
	
	Block a user