From e8f4f4ae12d1e736232b2fa0f8d7846cc8bc763c Mon Sep 17 00:00:00 2001 From: Abdelrahman Date: Sat, 28 Dec 2024 22:28:20 +0000 Subject: [PATCH] Move common shader data to uniform buffer --- shaders/frag.glsl | 7 ++++- shaders/reflective_frag.glsl | 7 ++++- shaders/refractive_frag.glsl | 7 ++++- shaders/sb_vert.glsl | 11 ++++++-- shaders/vert.glsl | 8 ++++-- src/main.cc | 53 +++++++++++++++++++++++++----------- 6 files changed, 69 insertions(+), 24 deletions(-) diff --git a/shaders/frag.glsl b/shaders/frag.glsl index b8e81af..fdaaa23 100644 --- a/shaders/frag.glsl +++ b/shaders/frag.glsl @@ -45,7 +45,12 @@ uniform Material material; uniform DirLight directional_light; uniform PointLight point_lights[POINT_LIGHT_COUNT]; uniform SpotLight spot_light; -uniform vec3 camera_position; + +layout (std140) uniform Common { + mat4 projection; + mat4 view; + vec3 camera_position; +}; vec3 calc_dir_light(DirLight light, vec3 normal, vec3 view_direction); vec3 calc_point_light(PointLight light, vec3 normal, vec3 frag_position, vec3 view_direction); diff --git a/shaders/reflective_frag.glsl b/shaders/reflective_frag.glsl index 589fc3f..e75439d 100644 --- a/shaders/reflective_frag.glsl +++ b/shaders/reflective_frag.glsl @@ -6,9 +6,14 @@ in VS_OUT { vec2 uv_coords; } fs_in; -uniform vec3 camera_position; uniform samplerCube cubemap; +layout (std140) uniform Common { + mat4 projection; + mat4 view; + vec3 camera_position; +}; + out vec4 color; void main() { diff --git a/shaders/refractive_frag.glsl b/shaders/refractive_frag.glsl index 9aaab80..9362ddb 100644 --- a/shaders/refractive_frag.glsl +++ b/shaders/refractive_frag.glsl @@ -9,9 +9,14 @@ in VS_OUT { vec2 uv_coords; } fs_in; -uniform vec3 camera_position; uniform samplerCube cubemap; +layout (std140) uniform Common { + mat4 projection; + mat4 view; + vec3 camera_position; +}; + out vec4 color; void main() { diff --git a/shaders/sb_vert.glsl b/shaders/sb_vert.glsl index a59433d..4675721 100644 --- a/shaders/sb_vert.glsl +++ b/shaders/sb_vert.glsl @@ -4,13 +4,18 @@ layout(location=0) in vec3 position; layout(location=1) in vec3 normal; layout(location=2) in vec2 uv; -uniform mat4 view; -uniform mat4 projection; +uniform mat4 sb_view; + +layout (std140) uniform Common { + mat4 projection; + mat4 view; + vec3 camera_position; +}; out vec3 uv_coords; void main() { - vec4 pos = projection * view * vec4(position, 1.0); + vec4 pos = projection * sb_view * vec4(position, 1.0); gl_Position = pos.xyww; uv_coords = position; } diff --git a/shaders/vert.glsl b/shaders/vert.glsl index 48cb808..a4fa499 100644 --- a/shaders/vert.glsl +++ b/shaders/vert.glsl @@ -6,8 +6,12 @@ layout(location=2) in vec2 uv; uniform mat3 normal_mat; uniform mat4 model; -uniform mat4 view; -uniform mat4 projection; + +layout (std140) uniform Common { + mat4 projection; + mat4 view; + vec3 camera_position; +}; // interface block out VS_OUT { diff --git a/src/main.cc b/src/main.cc index 8c4e728..01c888c 100644 --- a/src/main.cc +++ b/src/main.cc @@ -290,14 +290,6 @@ int main() { glm::mat4 projection = glm::perspective(glm::radians(45.0f), (float)WINDOW_WIDTH / (float)WINDOW_HEIGHT, 0.1f, 100.0f); glm::mat3 normal_mat = glm::mat3(1.0f); - main_shader.set_mat4 ("projection", projection); - main_shader.set_float("material.shininess", 32.0f); - - light_shader.set_mat4("projection", projection); - skybox_shader.set_mat4("projection", projection); - reflective_shader.set_mat4("projection", projection); - refractive_shader.set_mat4("projection", projection); - std::vector point_light_positions = { glm::vec3( 0.7f, 0.2f, 2.0f), glm::vec3( 2.3f, -3.3f, -4.0f), @@ -305,6 +297,9 @@ int main() { glm::vec3( 1.0f, 0.0f, -18.0f) }; + // Setup material + main_shader.set_float("material.shininess", 32.0f); + // Setup lights main_shader.set_vec3("directional_light.direction", glm::vec3(-0.2f, -1.0f, -0.3f)); main_shader.set_vec3("directional_light.ambient", light_ambient); @@ -364,6 +359,32 @@ int main() { GLuint cubemap = load_cubemap(cube_map_textures); + // Generate and bind uniform buffer + GLuint ubo; + GLuint ubo_binding_point = 0; + glGenBuffers(1, &ubo); + glBindBuffer(GL_UNIFORM_BUFFER, ubo); + glBufferData(GL_UNIFORM_BUFFER, 144, NULL, GL_STATIC_DRAW); + // Bind the uniform buffer object to a binding point + // Can also be done using glBindBufferRange instead of glBindBufferBase + glBindBufferBase(GL_UNIFORM_BUFFER, ubo_binding_point, ubo); + + // Set the shaders binding points + GLuint main_shader_common_block_index = glGetUniformBlockIndex(main_shader.program, "Common"); + GLuint light_shader_common_block_index = glGetUniformBlockIndex(light_shader.program, "Common"); + GLuint skybox_shader_common_block_index = glGetUniformBlockIndex(skybox_shader.program, "Common"); + GLuint reflective_shader_common_block_index = glGetUniformBlockIndex(reflective_shader.program, "Common"); + GLuint refractive_shader_common_block_index = glGetUniformBlockIndex(refractive_shader.program, "Common"); + glUniformBlockBinding(main_shader.program, main_shader_common_block_index, ubo_binding_point); + glUniformBlockBinding(light_shader.program, light_shader_common_block_index, ubo_binding_point); + glUniformBlockBinding(skybox_shader.program, skybox_shader_common_block_index, ubo_binding_point); + glUniformBlockBinding(reflective_shader.program, reflective_shader_common_block_index, ubo_binding_point); + glUniformBlockBinding(refractive_shader.program, refractive_shader_common_block_index, ubo_binding_point); + + // Add projection matrix to uniform buffer + glBufferSubData(GL_UNIFORM_BUFFER, 0, sizeof(glm::mat4), glm::value_ptr(projection)); + glBindBuffer(GL_UNIFORM_BUFFER, 0); + const float sensitivity = 0.1f; int last_mouse_x = WINDOW_HALF_WIDTH; int last_mouse_y = WINDOW_HALF_HEIGHT; @@ -442,18 +463,18 @@ int main() { camera_forward = glm::normalize(camera_forward); view = glm::lookAt(camera_position, camera_position + camera_forward, world_up); - main_shader.set_vec3("camera_position", camera_position); + + // Add view matrix and camera_position to uniform buffer + glBindBuffer(GL_UNIFORM_BUFFER, ubo); + glBufferSubData(GL_UNIFORM_BUFFER, sizeof(glm::mat4), sizeof(glm::mat4), glm::value_ptr(view)); + glBufferSubData(GL_UNIFORM_BUFFER, 2 * sizeof(glm::mat4), sizeof(glm::vec3), glm::value_ptr(camera_position)); + glBindBuffer(GL_UNIFORM_BUFFER, 0); + main_shader.set_vec3("spot_light.position", camera_position); main_shader.set_vec3("spot_light.direction", camera_forward); main_shader.set_float("spot_light.cutoff", glm::cos(glm::radians(12.5))); main_shader.set_float("spot_light.outer_cutoff", glm::cos(glm::radians(17.5))); - main_shader.set_mat4("view", view); - light_shader.set_mat4("view", view); - reflective_shader.set_vec3("camera_position", camera_position); - reflective_shader.set_mat4("view", view); - refractive_shader.set_vec3("camera_position", camera_position); - refractive_shader.set_mat4("view", view); - skybox_shader.set_mat4("view", glm::mat4(glm::mat3(view))); + skybox_shader.set_mat4("sb_view", glm::mat4(glm::mat3(view))); // Main render pass glBindFramebuffer(GL_FRAMEBUFFER, offscreen_buffer.fbo);