Add ability to draw normals
This commit is contained in:
		
							
								
								
									
										7
									
								
								shaders/normal_frag.glsl
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										7
									
								
								shaders/normal_frag.glsl
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,7 @@ | ||||
| #version 330 core | ||||
|  | ||||
| out vec4 color; | ||||
|  | ||||
| void main() { | ||||
|   color = vec4(1.0, 1.0, 0.0, 1.0); | ||||
| } | ||||
							
								
								
									
										34
									
								
								shaders/normal_geo.glsl
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										34
									
								
								shaders/normal_geo.glsl
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,34 @@ | ||||
| #version 330 core | ||||
|  | ||||
| #define MAGNITUDE 0.1 | ||||
|  | ||||
| layout (triangles) in; | ||||
| layout (line_strip, max_vertices = 6) out; | ||||
|  | ||||
| uniform float time; | ||||
|  | ||||
| in VS_OUT { | ||||
|   vec3 vert_normal; | ||||
| } gs_in[]; | ||||
|  | ||||
| layout (std140) uniform Common { | ||||
|   mat4 projection; | ||||
|   mat4 view; | ||||
|   vec3 camera_position; | ||||
| }; | ||||
|  | ||||
| void generate_line(int index) { | ||||
|   gl_Position = projection * gl_in[index].gl_Position; | ||||
|   EmitVertex(); | ||||
|  | ||||
|   gl_Position = projection * (gl_in[index].gl_Position + vec4(gs_in[index].vert_normal, 1.0) * MAGNITUDE); | ||||
|   EmitVertex(); | ||||
|  | ||||
|   EndPrimitive(); | ||||
| } | ||||
|  | ||||
| void main() { | ||||
|   for (int i = 0; i < 3; ++i) { | ||||
|     generate_line(i); | ||||
|   } | ||||
| } | ||||
							
								
								
									
										25
									
								
								shaders/normal_vert.glsl
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										25
									
								
								shaders/normal_vert.glsl
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,25 @@ | ||||
| #version 330 core | ||||
|  | ||||
| layout(location=0) in vec3 position; | ||||
| layout(location=1) in vec3 normal; | ||||
| layout(location=2) in vec2 uv; | ||||
|  | ||||
| uniform mat3 normal_mat; | ||||
| uniform mat4 model; | ||||
|  | ||||
| layout (std140) uniform Common { | ||||
|   mat4 projection; | ||||
|   mat4 view; | ||||
|   vec3 camera_position; | ||||
| }; | ||||
|  | ||||
| // interface block | ||||
| out VS_OUT { | ||||
|   vec3 vert_normal; | ||||
| } vs_out; | ||||
|  | ||||
| void main() { | ||||
|   vs_out.vert_normal = normal_mat * normal; | ||||
|  | ||||
|   gl_Position = view * model * vec4(position, 1.0); | ||||
| }; | ||||
							
								
								
									
										74
									
								
								src/main.cc
									
									
									
									
									
								
							
							
						
						
									
										74
									
								
								src/main.cc
									
									
									
									
									
								
							| @@ -48,6 +48,10 @@ | ||||
| #define max(a, b) (a > b ? a : b) | ||||
| #define clamp(v, a, b) (min(max(v, a), b)) | ||||
|  | ||||
| #define WIREFRAME 0 | ||||
| #define NORMALS 0 | ||||
| #define POINT_LIGHTS 0 | ||||
|  | ||||
| enum exit_codes : int { | ||||
|   EXIT_CODE_SUCCESS, | ||||
|   EXIT_CODE_SDL_INIT_FAILED, | ||||
| @@ -59,7 +63,7 @@ enum exit_codes : int { | ||||
|  | ||||
| class Shader { | ||||
|   public: | ||||
|     Shader(const std::string &vert_file, const std::string &frag_file); | ||||
|     Shader(const std::string &vert_file, const std::string &frag_file, const std::string &geo_file = ""); | ||||
|     ~Shader(); | ||||
|     void activate(); | ||||
|     void set_int(const char *name, int value); | ||||
| @@ -71,7 +75,7 @@ class Shader { | ||||
|     void set_uniform_block_binding_point(const char *block_name, GLuint binding_point); | ||||
|     GLuint program; | ||||
|   private: | ||||
|     void link_program(GLuint vert, GLuint frag); | ||||
|     void link_program(GLuint vert, GLuint frag, GLuint geo); | ||||
|     GLuint load_and_compile_shader(const std::string &filepath, GLenum shader_type); | ||||
|     std::string load_shader_from_file(const std::string &filepath); | ||||
|     static const char *get_shader_type_string(GLenum shader_type); | ||||
| @@ -268,12 +272,13 @@ int main() { | ||||
|  | ||||
|   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 skybox_shader     {"shaders/sb_vert.glsl", "shaders/sb_frag.glsl"}; | ||||
|   Shader reflective_shader {"shaders/vert.glsl",    "shaders/reflective_frag.glsl"}; | ||||
|   Shader refractive_shader {"shaders/vert.glsl",    "shaders/refractive_frag.glsl"}; | ||||
|   Shader post_processing   {"shaders/pp_vert.glsl", "shaders/pp_frag.glsl"}; | ||||
|   Shader main_shader       {"shaders/vert.glsl",        "shaders/frag.glsl"}; | ||||
|   Shader normal_vis_shader {"shaders/normal_vert.glsl", "shaders/normal_frag.glsl", "shaders/normal_geo.glsl"}; | ||||
|   Shader light_shader      {"shaders/vert.glsl",        "shaders/light_frag.glsl"}; | ||||
|   Shader skybox_shader     {"shaders/sb_vert.glsl",     "shaders/sb_frag.glsl"}; | ||||
|   Shader reflective_shader {"shaders/vert.glsl",        "shaders/reflective_frag.glsl"}; | ||||
|   Shader refractive_shader {"shaders/vert.glsl",        "shaders/refractive_frag.glsl"}; | ||||
|   Shader post_processing   {"shaders/pp_vert.glsl",     "shaders/pp_frag.glsl"}; | ||||
|  | ||||
|   const float camera_speed  = 25.0f; | ||||
|   glm::vec3 camera_position = glm::vec3(-2.5f, 0.0f, 8.0f); | ||||
| @@ -372,6 +377,7 @@ int main() { | ||||
|  | ||||
|   // Set the shaders binding points | ||||
|   main_shader.set_uniform_block_binding_point      ("Common", ubo_binding_point); | ||||
|   normal_vis_shader.set_uniform_block_binding_point("Common", ubo_binding_point); | ||||
|   light_shader.set_uniform_block_binding_point     ("Common", ubo_binding_point); | ||||
|   skybox_shader.set_uniform_block_binding_point    ("Common", ubo_binding_point); | ||||
|   reflective_shader.set_uniform_block_binding_point("Common", ubo_binding_point); | ||||
| @@ -482,36 +488,46 @@ int main() { | ||||
|     glDepthFunc(GL_LEQUAL); | ||||
|     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)); | ||||
|     main_shader.activate(); | ||||
|     main_shader.set_mat4("model", model); | ||||
|     main_shader.set_mat3("normal_mat", normal_mat); | ||||
|     suzanne.draw(main_shader); | ||||
|  | ||||
|     model = glm::translate(glm::mat4(1.0f), glm::vec3(3.0f, 0.0f, 0.0f)); | ||||
| #if NORMALS | ||||
|     normal_mat = glm::transpose(glm::inverse(view * model)); | ||||
|     normal_vis_shader.activate(); | ||||
|     normal_vis_shader.set_mat4("model", model); | ||||
|     normal_vis_shader.set_mat3("normal_mat", normal_mat); | ||||
|     suzanne.draw(normal_vis_shader); | ||||
| #endif | ||||
|  | ||||
|     model      = glm::translate(glm::mat4(1.0f), glm::vec3(3.0f, 0.0f, 0.0f)); | ||||
|     normal_mat = glm::transpose(glm::inverse(model)); | ||||
|     reflective_shader.set_mat4("model", model); | ||||
|     reflective_shader.set_mat3("normal_mat", normal_mat); | ||||
|     suzanne.draw(reflective_shader); | ||||
|  | ||||
|     glDisable(GL_CULL_FACE); | ||||
|     model = glm::translate(glm::mat4(1.0f), glm::vec3(-3.0f, 0.0f, 0.0f)); | ||||
|     model      = glm::translate(glm::mat4(1.0f), glm::vec3(-3.0f, 0.0f, 0.0f)); | ||||
|     normal_mat = glm::transpose(glm::inverse(model)); | ||||
|     refractive_shader.set_mat4("model", model); | ||||
|     refractive_shader.set_mat3("normal_mat", normal_mat); | ||||
|     suzanne.draw(refractive_shader); | ||||
|     glEnable(GL_CULL_FACE); | ||||
|  | ||||
| #if POINT_LIGHTS | ||||
|     // Draw point lights | ||||
|     // for (int i = 0; i < point_light_positions.size(); ++i) { | ||||
|     //   model = glm::translate(glm::mat4(1.0f), point_light_positions[i]); | ||||
|     //   model = glm::scale(model, glm::vec3(0.2f)); | ||||
|     //   light_shader.activate(); | ||||
|     //   light_shader.set_mat4("model", model); | ||||
|     //   light_shader.set_vec3("light_diffuse", light_diffuse); | ||||
|     //   light.draw(light_shader); | ||||
|     // } | ||||
|     for (int i = 0; i < point_light_positions.size(); ++i) { | ||||
|       model = glm::translate(glm::mat4(1.0f), point_light_positions[i]); | ||||
|       model = glm::scale(model, glm::vec3(0.2f)); | ||||
|       light_shader.activate(); | ||||
|       light_shader.set_mat4("model", model); | ||||
|       light_shader.set_vec3("light_diffuse", light_diffuse); | ||||
|       light.draw(light_shader); | ||||
|     } | ||||
| #endif | ||||
|  | ||||
|     // Draw skybox | ||||
|     glDisable(GL_CULL_FACE); | ||||
| @@ -521,8 +537,10 @@ int main() { | ||||
|     skybox_shader.set_int("cubemap", 0); | ||||
|     skybox.draw(skybox_shader); | ||||
|  | ||||
| #if WIREFRAME | ||||
|     // wireframe mode | ||||
|     // glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); | ||||
|     glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); | ||||
| #endif | ||||
|  | ||||
|     // Post processing pass | ||||
|     glBindFramebuffer(GL_FRAMEBUFFER, 0); | ||||
| @@ -549,12 +567,19 @@ int main() { | ||||
| } | ||||
|  | ||||
|  | ||||
| Shader::Shader(const std::string &vert_file, const std::string &frag_file) { | ||||
| Shader::Shader(const std::string &vert_file, const std::string &frag_file, const std::string &geo_file) { | ||||
|   GLuint vert = load_and_compile_shader(vert_file, GL_VERTEX_SHADER); | ||||
|   GLuint frag = load_and_compile_shader(frag_file, GL_FRAGMENT_SHADER); | ||||
|   link_program(vert, frag); | ||||
|   GLuint geo  = 0; | ||||
|   if (geo_file.size() > 0) { | ||||
|     geo = load_and_compile_shader(geo_file, GL_GEOMETRY_SHADER); | ||||
|   } | ||||
|   link_program(vert, frag, geo); | ||||
|   glDeleteShader(vert); | ||||
|   glDeleteShader(frag); | ||||
|   if (geo > 0) { | ||||
|     glDeleteShader(geo); | ||||
|   } | ||||
| } | ||||
|  | ||||
| Shader::~Shader() { | ||||
| @@ -604,10 +629,13 @@ void Shader::set_uniform_block_binding_point(const char *block_name, GLuint bind | ||||
|   glUniformBlockBinding(program, block_index, binding_point); | ||||
| } | ||||
|  | ||||
| void Shader::link_program(GLuint vert, GLuint frag) { | ||||
| void Shader::link_program(GLuint vert, GLuint frag, GLuint geo) { | ||||
|   program = glCreateProgram(); | ||||
|   glAttachShader(program, vert); | ||||
|   glAttachShader(program, frag); | ||||
|   if (geo > 0) { | ||||
|     glAttachShader(program, geo); | ||||
|   } | ||||
|  | ||||
|   glLinkProgram(program); | ||||
|   GLint program_linked; | ||||
|   | ||||
		Reference in New Issue
	
	Block a user