Implement Multi-Sample Anti Aliasing (MSAA)
This commit is contained in:
parent
e9a9b8a2cf
commit
71f6d03635
97
src/main.cc
97
src/main.cc
@ -50,8 +50,13 @@
|
|||||||
|
|
||||||
#define WIREFRAME 0
|
#define WIREFRAME 0
|
||||||
#define NORMALS 0
|
#define NORMALS 0
|
||||||
|
#define MSAA 1
|
||||||
#define POINT_LIGHTS 1
|
#define POINT_LIGHTS 1
|
||||||
|
|
||||||
|
#if MSAA
|
||||||
|
#define MSAA_SAMPLE_COUNT 4
|
||||||
|
#endif
|
||||||
|
|
||||||
enum exit_codes : int {
|
enum exit_codes : int {
|
||||||
EXIT_CODE_SUCCESS,
|
EXIT_CODE_SUCCESS,
|
||||||
EXIT_CODE_SDL_INIT_FAILED,
|
EXIT_CODE_SDL_INIT_FAILED,
|
||||||
@ -149,9 +154,15 @@ struct FrameBuffer {
|
|||||||
GLuint fbo;
|
GLuint fbo;
|
||||||
GLuint color;
|
GLuint color;
|
||||||
GLuint depth_stencil;
|
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);
|
void delete_frame_buffer(FrameBuffer &buffer);
|
||||||
GLuint load_cubemap(std::vector<std::string> textures);
|
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_MINOR_VERSION, 3);
|
||||||
SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE);
|
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,
|
SDL_Window *window = SDL_CreateWindow("Window", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED,
|
||||||
WINDOW_WIDTH, WINDOW_HEIGHT, SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE);
|
WINDOW_WIDTH, WINDOW_HEIGHT, SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE);
|
||||||
if (!window) {
|
if (!window) {
|
||||||
@ -181,12 +197,21 @@ int main() {
|
|||||||
return EXIT_CODE_GLAD_LOADER_FAILED;
|
return EXIT_CODE_GLAD_LOADER_FAILED;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if MSAA
|
||||||
|
glEnable(GL_MULTISAMPLE);
|
||||||
|
#endif
|
||||||
|
|
||||||
SDL_SetRelativeMouseMode(SDL_TRUE);
|
SDL_SetRelativeMouseMode(SDL_TRUE);
|
||||||
SDL_WarpMouseInWindow(window, WINDOW_HALF_WIDTH, WINDOW_HALF_HEIGHT);
|
SDL_WarpMouseInWindow(window, WINDOW_HALF_WIDTH, WINDOW_HALF_HEIGHT);
|
||||||
|
|
||||||
glViewport(0, 0, WINDOW_WIDTH, WINDOW_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 = {
|
std::vector<Vertex> vertices = {
|
||||||
// positions // normals // texture coords
|
// positions // normals // texture coords
|
||||||
@ -497,7 +522,11 @@ int main() {
|
|||||||
|
|
||||||
// Recreate offscreen frame buffer
|
// Recreate offscreen frame buffer
|
||||||
delete_frame_buffer(offscreen_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;
|
break;
|
||||||
}
|
}
|
||||||
@ -523,7 +552,11 @@ int main() {
|
|||||||
skybox_shader.set_mat4("sb_view", glm::mat4(glm::mat3(view)));
|
skybox_shader.set_mat4("sb_view", glm::mat4(glm::mat3(view)));
|
||||||
|
|
||||||
// Main render pass
|
// Main render pass
|
||||||
|
#if MSAA
|
||||||
|
glBindFramebuffer(GL_FRAMEBUFFER, multisample_buffer.fbo);
|
||||||
|
#else
|
||||||
glBindFramebuffer(GL_FRAMEBUFFER, offscreen_buffer.fbo);
|
glBindFramebuffer(GL_FRAMEBUFFER, offscreen_buffer.fbo);
|
||||||
|
#endif
|
||||||
|
|
||||||
glClearColor(0.04f, 0.08f, 0.08f, 1.0f);
|
glClearColor(0.04f, 0.08f, 0.08f, 1.0f);
|
||||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||||
@ -578,6 +611,10 @@ int main() {
|
|||||||
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
|
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if MSAA
|
||||||
|
blit_multisample_frame_buffer(multisample_buffer, offscreen_buffer);
|
||||||
|
#endif
|
||||||
|
|
||||||
// Post processing pass
|
// Post processing pass
|
||||||
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
||||||
|
|
||||||
@ -959,7 +996,7 @@ std::vector<Texture2D> Model::load_material_textures(aiMaterial *material, aiTex
|
|||||||
return textures;
|
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 = {};
|
FrameBuffer buffer = {};
|
||||||
|
|
||||||
glGenFramebuffers(1, &buffer.fbo);
|
glGenFramebuffers(1, &buffer.fbo);
|
||||||
@ -990,9 +1027,61 @@ FrameBuffer create_frame_buffer(unsigned int width, unsigned int height) {
|
|||||||
glBindTexture(GL_TEXTURE_2D, 0);
|
glBindTexture(GL_TEXTURE_2D, 0);
|
||||||
glBindRenderbuffer(GL_RENDERBUFFER, 0);
|
glBindRenderbuffer(GL_RENDERBUFFER, 0);
|
||||||
|
|
||||||
|
buffer.width = width;
|
||||||
|
buffer.height = height;
|
||||||
|
|
||||||
return buffer;
|
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) {
|
void delete_frame_buffer(FrameBuffer &buffer) {
|
||||||
glDeleteFramebuffers(1, &buffer.fbo);
|
glDeleteFramebuffers(1, &buffer.fbo);
|
||||||
glDeleteTextures(1, &buffer.color);
|
glDeleteTextures(1, &buffer.color);
|
||||||
|
Loading…
Reference in New Issue
Block a user