Implement double frame buffering
This commit is contained in:
parent
9de54d016d
commit
68cc990650
18
shaders/pp_frag.glsl
Normal file
18
shaders/pp_frag.glsl
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
#version 330 core
|
||||||
|
|
||||||
|
struct Material {
|
||||||
|
sampler2D diffuse1;
|
||||||
|
sampler2D specular1;
|
||||||
|
float shininess;
|
||||||
|
};
|
||||||
|
|
||||||
|
in vec2 uv_coords;
|
||||||
|
|
||||||
|
uniform Material material;
|
||||||
|
// uniform sampler2D image_texture;
|
||||||
|
|
||||||
|
out vec4 color;
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
color = vec4(vec3(texture(material.diffuse1, uv_coords)), 1.0);
|
||||||
|
}
|
12
shaders/pp_vert.glsl
Normal file
12
shaders/pp_vert.glsl
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
#version 330 core
|
||||||
|
|
||||||
|
layout(location=0) in vec3 position;
|
||||||
|
layout(location=1) in vec3 normal;
|
||||||
|
layout(location=2) in vec2 uv;
|
||||||
|
|
||||||
|
out vec2 uv_coords;
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
gl_Position = vec4(position.x, position.y, 0.0, 1.0);
|
||||||
|
uv_coords = uv;
|
||||||
|
}
|
98
src/main.cc
98
src/main.cc
@ -54,6 +54,7 @@ enum exit_codes : int {
|
|||||||
EXIT_CODE_WINDOW_CREATION_FAILED,
|
EXIT_CODE_WINDOW_CREATION_FAILED,
|
||||||
EXIT_CODE_OPENGL_CONTEXT_FAILED,
|
EXIT_CODE_OPENGL_CONTEXT_FAILED,
|
||||||
EXIT_CODE_GLAD_LOADER_FAILED,
|
EXIT_CODE_GLAD_LOADER_FAILED,
|
||||||
|
EXIT_CODE_INCOMPLETE_FRAME_BUFFER,
|
||||||
};
|
};
|
||||||
|
|
||||||
class Shader {
|
class Shader {
|
||||||
@ -135,6 +136,15 @@ class Model {
|
|||||||
std::vector<Texture2D> load_material_textures(aiMaterial *mat, aiTextureType type);
|
std::vector<Texture2D> load_material_textures(aiMaterial *mat, aiTextureType type);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct FrameBuffer {
|
||||||
|
GLuint fbo;
|
||||||
|
GLuint color;
|
||||||
|
GLuint depth_stencil;
|
||||||
|
};
|
||||||
|
|
||||||
|
FrameBuffer create_frame_buffer(unsigned int width, unsigned int height);
|
||||||
|
void delete_frame_buffer(FrameBuffer &buffer);
|
||||||
|
|
||||||
int main() {
|
int main() {
|
||||||
if (SDL_Init(SDL_INIT_EVERYTHING) != 0) {
|
if (SDL_Init(SDL_INIT_EVERYTHING) != 0) {
|
||||||
return EXIT_CODE_SDL_INIT_FAILED;
|
return EXIT_CODE_SDL_INIT_FAILED;
|
||||||
@ -166,8 +176,7 @@ int main() {
|
|||||||
|
|
||||||
glViewport(0, 0, WINDOW_WIDTH, WINDOW_HEIGHT);
|
glViewport(0, 0, WINDOW_WIDTH, WINDOW_HEIGHT);
|
||||||
|
|
||||||
glEnable(GL_DEPTH_TEST);
|
FrameBuffer offscreen_buffer = create_frame_buffer(WINDOW_WIDTH, WINDOW_HEIGHT);
|
||||||
glEnable(GL_CULL_FACE);
|
|
||||||
|
|
||||||
std::vector<Vertex> vertices = {
|
std::vector<Vertex> vertices = {
|
||||||
// positions // normals // texture coords
|
// positions // normals // texture coords
|
||||||
@ -215,8 +224,23 @@ int main() {
|
|||||||
Model backpack = {"models/suzanne/suzanne.obj"};
|
Model backpack = {"models/suzanne/suzanne.obj"};
|
||||||
Mesh light = {vertices, indices, {}};
|
Mesh light = {vertices, indices, {}};
|
||||||
|
|
||||||
Shader main_shader {"shaders/vert.glsl", "shaders/frag.glsl"};
|
std::vector<Vertex> screen_vertices = {
|
||||||
Shader light_shader {"shaders/vert.glsl", "shaders/light_frag.glsl"};
|
Vertex{glm::vec3(-1.0f, -1.0f, 0.0f), glm::vec3(1.0f, 1.0f, 1.0f), glm::vec2(0.0f, 0.0f)},
|
||||||
|
Vertex{glm::vec3( 1.0f, -1.0f, 0.0f), glm::vec3(1.0f, 1.0f, 1.0f), glm::vec2(1.0f, 0.0f)},
|
||||||
|
Vertex{glm::vec3(-1.0f, 1.0f, 0.0f), glm::vec3(1.0f, 1.0f, 1.0f), glm::vec2(0.0f, 1.0f)},
|
||||||
|
Vertex{glm::vec3( 1.0f, 1.0f, 0.0f), glm::vec3(1.0f, 1.0f, 1.0f), glm::vec2(1.0f, 1.0f)},
|
||||||
|
};
|
||||||
|
|
||||||
|
std::vector<GLuint> screen_indices = {
|
||||||
|
0, 1, 2,
|
||||||
|
2, 1, 3,
|
||||||
|
};
|
||||||
|
|
||||||
|
Mesh screen = {screen_vertices, screen_indices, {}};
|
||||||
|
|
||||||
|
Shader main_shader {"shaders/vert.glsl", "shaders/frag.glsl"};
|
||||||
|
Shader light_shader {"shaders/vert.glsl", "shaders/light_frag.glsl"};
|
||||||
|
Shader post_processing {"shaders/pp_vert.glsl", "shaders/pp_frag.glsl"};
|
||||||
|
|
||||||
const float camera_speed = 25.0f;
|
const float camera_speed = 25.0f;
|
||||||
glm::vec3 camera_position = glm::vec3(-2.0f, 0.0f, 6.0f);
|
glm::vec3 camera_position = glm::vec3(-2.0f, 0.0f, 6.0f);
|
||||||
@ -356,6 +380,10 @@ int main() {
|
|||||||
SDL_GL_GetDrawableSize(wnd, &w, &h);
|
SDL_GL_GetDrawableSize(wnd, &w, &h);
|
||||||
glViewport(0, 0, w, h);
|
glViewport(0, 0, w, h);
|
||||||
SDL_WarpMouseInWindow(wnd, (int)(w * 0.5f), (int)(h * 0.5f));
|
SDL_WarpMouseInWindow(wnd, (int)(w * 0.5f), (int)(h * 0.5f));
|
||||||
|
|
||||||
|
// Recreate offscreen frame buffer
|
||||||
|
delete_frame_buffer(offscreen_buffer);
|
||||||
|
offscreen_buffer = create_frame_buffer(w, h);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -375,8 +403,13 @@ int main() {
|
|||||||
main_shader.set_mat4("view", view);
|
main_shader.set_mat4("view", view);
|
||||||
light_shader.set_mat4("view", view);
|
light_shader.set_mat4("view", view);
|
||||||
|
|
||||||
|
// Main render pass
|
||||||
|
glBindFramebuffer(GL_FRAMEBUFFER, offscreen_buffer.fbo);
|
||||||
|
|
||||||
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);
|
||||||
|
glEnable(GL_DEPTH_TEST);
|
||||||
|
glEnable(GL_CULL_FACE);
|
||||||
|
|
||||||
model = glm::translate(glm::mat4(1.0f), glm::vec3(0.0f, 0.0f, 0.0f));
|
model = glm::translate(glm::mat4(1.0f), glm::vec3(0.0f, 0.0f, 0.0f));
|
||||||
normal_mat = glm::transpose(glm::inverse(model));
|
normal_mat = glm::transpose(glm::inverse(model));
|
||||||
@ -395,6 +428,23 @@ int main() {
|
|||||||
light.draw(light_shader);
|
light.draw(light_shader);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// wireframe mode
|
||||||
|
// glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
|
||||||
|
|
||||||
|
// Post processing pass
|
||||||
|
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
||||||
|
|
||||||
|
glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
|
||||||
|
glClear(GL_COLOR_BUFFER_BIT);
|
||||||
|
glDisable(GL_DEPTH_TEST);
|
||||||
|
glDisable(GL_CULL_FACE);
|
||||||
|
|
||||||
|
post_processing.activate();
|
||||||
|
glActiveTexture(GL_TEXTURE0);
|
||||||
|
glBindTexture(GL_TEXTURE_2D, offscreen_buffer.color);
|
||||||
|
post_processing.set_int("image_texture", 0);
|
||||||
|
screen.draw(post_processing);
|
||||||
|
|
||||||
SDL_GL_SwapWindow(window);
|
SDL_GL_SwapWindow(window);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -726,3 +776,43 @@ 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 buffer = {};
|
||||||
|
|
||||||
|
glGenFramebuffers(1, &buffer.fbo);
|
||||||
|
glBindFramebuffer(GL_FRAMEBUFFER, buffer.fbo);
|
||||||
|
|
||||||
|
// Create color texture
|
||||||
|
glGenTextures(1, &buffer.color);
|
||||||
|
glBindTexture(GL_TEXTURE_2D, buffer.color);
|
||||||
|
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, NULL);
|
||||||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||||
|
|
||||||
|
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, buffer.color, 0);
|
||||||
|
|
||||||
|
// Create depth and stencil buffers
|
||||||
|
glGenRenderbuffers(1, &buffer.depth_stencil);
|
||||||
|
glBindRenderbuffer(GL_RENDERBUFFER, buffer.depth_stencil);
|
||||||
|
glRenderbufferStorage(GL_RENDERBUFFER, 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, 0);
|
||||||
|
glBindRenderbuffer(GL_RENDERBUFFER, 0);
|
||||||
|
|
||||||
|
return buffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
void delete_frame_buffer(FrameBuffer &buffer) {
|
||||||
|
glDeleteFramebuffers(1, &buffer.fbo);
|
||||||
|
glDeleteTextures(1, &buffer.color);
|
||||||
|
glDeleteRenderbuffers(1, &buffer.depth_stencil);
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user