Compare commits
	
		
			4 Commits
		
	
	
		
			main
			...
			02-model-l
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| c5f13d7c37 | |||
| db3116453b | |||
| 0db5c5d81a | |||
| d8d2c73438 | 
							
								
								
									
										4
									
								
								compile
									
									
									
									
									
								
							
							
						
						
									
										4
									
								
								compile
									
									
									
									
									
								
							| @@ -1,9 +1,9 @@ | |||||||
| #!/bin/bash | #!/bin/bash | ||||||
|  |  | ||||||
| CC=clang | CC=clang | ||||||
| CFLAGS="-g -c -Wall -Isrc/glad/include" | CFLAGS="-O3 -c -Wall -Isrc/glad/include" | ||||||
| CXX=clang++ | CXX=clang++ | ||||||
| CXXFLAGS="-g -Wall -std=c++20 $(pkg-config --cflags sdl2) -Isrc/glad/include -Isrc/glm -Isrc/assimp/include -Isrc/assimp/build/include" | CXXFLAGS="-O3 -Wall -std=c++20 $(pkg-config --cflags sdl2) -Isrc/glad/include -Isrc/glm -Isrc/assimp/include -Isrc/assimp/build/include" | ||||||
| LIBS="$(pkg-config --libs sdl2) -ldl -lz -lminizip -Lsrc/assimp/build/lib/ -lassimp" | LIBS="$(pkg-config --libs sdl2) -ldl -lz -lminizip -Lsrc/assimp/build/lib/ -lassimp" | ||||||
| GLAD_SRC="src/glad/src/glad.c" | GLAD_SRC="src/glad/src/glad.c" | ||||||
| GLAD_OBJ="glad.o" | GLAD_OBJ="glad.o" | ||||||
|   | |||||||
										
											Binary file not shown.
										
									
								
							| Before Width: | Height: | Size: 723 KiB | 
										
											Binary file not shown.
										
									
								
							| Before Width: | Height: | Size: 274 KiB | 
										
											Binary file not shown.
										
									
								
							| Before Width: | Height: | Size: 462 KiB | 
										
											Binary file not shown.
										
									
								
							| Before Width: | Height: | Size: 588 KiB | 
										
											Binary file not shown.
										
									
								
							| Before Width: | Height: | Size: 525 KiB | 
										
											Binary file not shown.
										
									
								
							| Before Width: | Height: | Size: 338 KiB | 
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							| @@ -35,40 +35,33 @@ struct SpotLight { | |||||||
|   float outer_cutoff; |   float outer_cutoff; | ||||||
| }; | }; | ||||||
|  |  | ||||||
| in VS_OUT { | in vec3 vert_normal; | ||||||
|   vec3 vert_normal; | in vec3 frag_position; | ||||||
|   vec3 frag_position; | in vec2 uv_coords; | ||||||
|   vec2 uv_coords; |  | ||||||
| } fs_in; | out vec4 color; | ||||||
|  |  | ||||||
| uniform Material material; | uniform Material material; | ||||||
| uniform DirLight directional_light; | uniform DirLight directional_light; | ||||||
| uniform PointLight point_lights[POINT_LIGHT_COUNT]; | uniform PointLight point_lights[POINT_LIGHT_COUNT]; | ||||||
| uniform SpotLight spot_light; | 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_dir_light(DirLight light, vec3 normal, vec3 view_direction); | ||||||
| vec3 calc_point_light(PointLight light, vec3 normal, vec3 frag_position, vec3 view_direction); | vec3 calc_point_light(PointLight light, vec3 normal, vec3 frag_position, vec3 view_direction); | ||||||
| vec3 calc_spot_light(SpotLight light, vec3 normal, vec3 frag_position, vec3 view_direction); | vec3 calc_spot_light(SpotLight light, vec3 normal, vec3 frag_position, vec3 view_direction); | ||||||
|  |  | ||||||
| out vec4 color; |  | ||||||
|  |  | ||||||
| void main() { | void main() { | ||||||
|   vec3  normal         = normalize(fs_in.vert_normal); |   vec3  normal         = normalize(vert_normal); | ||||||
|   vec3  view_direction = normalize(fs_in.frag_position - camera_position); |   vec3  view_direction = normalize(camera_position - frag_position); | ||||||
|  |  | ||||||
|   vec3 result = calc_dir_light(directional_light, normal, view_direction); |   vec3 result = calc_dir_light(directional_light, normal, view_direction); | ||||||
|  |  | ||||||
|   for (int i = 0; i < POINT_LIGHT_COUNT; ++i) { |   for (int i = 0; i < POINT_LIGHT_COUNT; ++i) { | ||||||
|     result += calc_point_light(point_lights[i], normal, fs_in.frag_position, view_direction); |     result += calc_point_light(point_lights[i], normal, frag_position, view_direction); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   result += calc_spot_light(spot_light, normal, fs_in.frag_position, view_direction); |   result += calc_spot_light(spot_light, normal, frag_position, view_direction); | ||||||
|  |  | ||||||
|   color = vec4(result, 1.0); |   color = vec4(result, 1.0); | ||||||
| }; | }; | ||||||
| @@ -77,11 +70,11 @@ vec3 calc_dir_light(DirLight light, vec3 normal, vec3 view_direction) { | |||||||
|   vec3 light_direction     = normalize(-light.direction); |   vec3 light_direction     = normalize(-light.direction); | ||||||
|   vec3  reflect_direction  = reflect(-light_direction, normal); |   vec3  reflect_direction  = reflect(-light_direction, normal); | ||||||
|   float diff               = max(dot(normal, light_direction), 0.0); |   float diff               = max(dot(normal, light_direction), 0.0); | ||||||
|   vec3  diff_tex           = vec3(texture(material.diffuse1, fs_in.uv_coords)); |   vec3  diff_tex           = vec3(texture(material.diffuse1, uv_coords)); | ||||||
|   float spec               = pow(max(dot(reflect_direction, view_direction), 0.0), material.shininess); |   float spec               = pow(max(dot(reflect_direction, view_direction), 0.0), material.shininess); | ||||||
|   vec3  ambient            = light.ambient * diff_tex; |   vec3  ambient            = light.ambient * diff_tex; | ||||||
|   vec3  diffuse            = light.diffuse * (diff * diff_tex); |   vec3  diffuse            = light.diffuse * (diff * diff_tex); | ||||||
|   vec3  specular           = light.specular * (spec * vec3(texture(material.specular1, fs_in.uv_coords))); |   vec3  specular           = light.specular * (spec * vec3(texture(material.specular1, uv_coords))); | ||||||
|  |  | ||||||
|   return ambient + diffuse + specular; |   return ambient + diffuse + specular; | ||||||
| } | } | ||||||
| @@ -92,11 +85,11 @@ vec3 calc_point_light(PointLight light, vec3 normal, vec3 frag_position, vec3 vi | |||||||
|   float distance           = length(light.position - frag_position); |   float distance           = length(light.position - frag_position); | ||||||
|   float attenuation        = 1.0 / (light.constant + light.linear * distance + light.quadratic * (distance * distance)); |   float attenuation        = 1.0 / (light.constant + light.linear * distance + light.quadratic * (distance * distance)); | ||||||
|   float diff               = max(dot(normal, light_direction), 0.0); |   float diff               = max(dot(normal, light_direction), 0.0); | ||||||
|   vec3  diff_tex           = vec3(texture(material.diffuse1, fs_in.uv_coords)); |   vec3  diff_tex           = vec3(texture(material.diffuse1, uv_coords)); | ||||||
|   float spec               = pow(max(dot(reflect_direction, view_direction), 0.0), material.shininess); |   float spec               = pow(max(dot(reflect_direction, view_direction), 0.0), material.shininess); | ||||||
|   vec3  ambient            = light.ambient * diff_tex * attenuation; |   vec3  ambient            = light.ambient * diff_tex * attenuation; | ||||||
|   vec3  diffuse            = light.diffuse * (diff * diff_tex) * attenuation; |   vec3  diffuse            = light.diffuse * (diff * diff_tex) * attenuation; | ||||||
|   vec3  specular           = light.specular * (spec * vec3(texture(material.specular1, fs_in.uv_coords))) * attenuation; |   vec3  specular           = light.specular * (spec * vec3(texture(material.specular1, uv_coords))) * attenuation; | ||||||
|  |  | ||||||
|   return ambient + diffuse + specular; |   return ambient + diffuse + specular; | ||||||
| } | } | ||||||
| @@ -109,10 +102,10 @@ vec3 calc_spot_light(SpotLight light, vec3 normal, vec3 frag_position, vec3 view | |||||||
|   float intensity          = clamp((theta - light.outer_cutoff) / epsilon, 0.0, 1.0); |   float intensity          = clamp((theta - light.outer_cutoff) / epsilon, 0.0, 1.0); | ||||||
|   float diff               = max(dot(normal, light_direction), 0.0); |   float diff               = max(dot(normal, light_direction), 0.0); | ||||||
|   float spec               = pow(max(dot(reflect_direction, view_direction), 0.0), material.shininess); |   float spec               = pow(max(dot(reflect_direction, view_direction), 0.0), material.shininess); | ||||||
|   vec3  diff_tex           = vec3(texture(material.diffuse1, fs_in.uv_coords)); |   vec3  diff_tex           = vec3(texture(material.diffuse1, uv_coords)); | ||||||
|   vec3  ambient            = light.ambient * diff_tex; |   vec3  ambient            = light.ambient * diff_tex; | ||||||
|   vec3  diffuse            = light.diffuse * (diff * diff_tex) * intensity; |   vec3  diffuse            = light.diffuse * (diff * diff_tex) * intensity; | ||||||
|   vec3  specular           = light.specular * (spec * vec3(texture(material.specular1, fs_in.uv_coords))) * intensity; |   vec3  specular           = light.specular * (spec * vec3(texture(material.specular1, uv_coords))) * intensity; | ||||||
|  |  | ||||||
|   return ambient + diffuse + specular; |   return ambient + diffuse + specular; | ||||||
| } | } | ||||||
|   | |||||||
| @@ -1,18 +0,0 @@ | |||||||
| #version 330 core |  | ||||||
|  |  | ||||||
| #define POINT_LIGHT_COUNT 4 |  | ||||||
|  |  | ||||||
| layout(location=0) in vec3 position; |  | ||||||
| layout(location=1) in vec3 normal; |  | ||||||
| layout(location=2) in vec2 uv; |  | ||||||
| layout(location=3) in mat4 model; |  | ||||||
|  |  | ||||||
| layout (std140) uniform Common { |  | ||||||
|   mat4 projection; |  | ||||||
|   mat4 view; |  | ||||||
|   vec3 camera_position; |  | ||||||
| }; |  | ||||||
|  |  | ||||||
| void main() { |  | ||||||
|   gl_Position = projection * view * model * vec4(position, 1.0); |  | ||||||
| }; |  | ||||||
| @@ -1,7 +0,0 @@ | |||||||
| #version 330 core |  | ||||||
|  |  | ||||||
| out vec4 color; |  | ||||||
|  |  | ||||||
| void main() { |  | ||||||
|   color = vec4(1.0, 1.0, 0.0, 1.0); |  | ||||||
| } |  | ||||||
| @@ -1,34 +0,0 @@ | |||||||
| #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); |  | ||||||
|   } |  | ||||||
| } |  | ||||||
| @@ -1,25 +0,0 @@ | |||||||
| #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); |  | ||||||
| }; |  | ||||||
| @@ -1,17 +0,0 @@ | |||||||
| #version 330 core |  | ||||||
|  |  | ||||||
| struct Material { |  | ||||||
|   sampler2D diffuse1; |  | ||||||
|   sampler2D specular1; |  | ||||||
|   float shininess; |  | ||||||
| }; |  | ||||||
|  |  | ||||||
| in vec2 uv_coords; |  | ||||||
|  |  | ||||||
| uniform Material material; |  | ||||||
|  |  | ||||||
| out vec4 color; |  | ||||||
|  |  | ||||||
| void main() { |  | ||||||
|   color = vec4(vec3(texture(material.diffuse1, uv_coords)), 1.0); |  | ||||||
| } |  | ||||||
| @@ -1,12 +0,0 @@ | |||||||
| #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; |  | ||||||
| } |  | ||||||
| @@ -1,24 +0,0 @@ | |||||||
| #version 330 core |  | ||||||
|  |  | ||||||
| in VS_OUT { |  | ||||||
|   vec3 vert_normal; |  | ||||||
|   vec3 frag_position; |  | ||||||
|   vec2 uv_coords; |  | ||||||
| } fs_in; |  | ||||||
|  |  | ||||||
| uniform samplerCube cubemap; |  | ||||||
|  |  | ||||||
| layout (std140) uniform Common { |  | ||||||
|   mat4 projection; |  | ||||||
|   mat4 view; |  | ||||||
|   vec3 camera_position; |  | ||||||
| }; |  | ||||||
|  |  | ||||||
| out vec4 color; |  | ||||||
|  |  | ||||||
| void main() { |  | ||||||
|   vec3 view_direction    = normalize(fs_in.frag_position - camera_position); |  | ||||||
|   vec3 reflect_direction = reflect(view_direction, normalize(fs_in.vert_normal)); |  | ||||||
|  |  | ||||||
|   color = vec4(texture(cubemap, reflect_direction).rgb, 1.0); |  | ||||||
| } |  | ||||||
| @@ -1,27 +0,0 @@ | |||||||
| #version 330 core |  | ||||||
|  |  | ||||||
| #define AIR_IOR 1.0 |  | ||||||
| #define GLASS_IOR 1.52 |  | ||||||
|  |  | ||||||
| in VS_OUT { |  | ||||||
|   vec3 vert_normal; |  | ||||||
|   vec3 frag_position; |  | ||||||
|   vec2 uv_coords; |  | ||||||
| } fs_in; |  | ||||||
|  |  | ||||||
| uniform samplerCube cubemap; |  | ||||||
|  |  | ||||||
| layout (std140) uniform Common { |  | ||||||
|   mat4 projection; |  | ||||||
|   mat4 view; |  | ||||||
|   vec3 camera_position; |  | ||||||
| }; |  | ||||||
|  |  | ||||||
| out vec4 color; |  | ||||||
|  |  | ||||||
| void main() { |  | ||||||
|   vec3 view_direction    = normalize(fs_in.frag_position - camera_position); |  | ||||||
|   vec3 refract_direction = refract(view_direction, normalize(fs_in.vert_normal), AIR_IOR / GLASS_IOR); |  | ||||||
|  |  | ||||||
|   color = vec4(texture(cubemap, refract_direction).rgb, 1.0); |  | ||||||
| } |  | ||||||
| @@ -1,11 +0,0 @@ | |||||||
| #version 330 core |  | ||||||
|  |  | ||||||
| in vec3 uv_coords; |  | ||||||
|  |  | ||||||
| uniform samplerCube cubemap; |  | ||||||
|  |  | ||||||
| out vec4 color; |  | ||||||
|  |  | ||||||
| void main() { |  | ||||||
|   color = texture(cubemap, uv_coords); |  | ||||||
| } |  | ||||||
| @@ -1,21 +0,0 @@ | |||||||
| #version 330 core |  | ||||||
|  |  | ||||||
| layout(location=0) in vec3 position; |  | ||||||
| layout(location=1) in vec3 normal; |  | ||||||
| layout(location=2) in vec2 uv; |  | ||||||
|  |  | ||||||
| uniform mat4 sb_view; |  | ||||||
|  |  | ||||||
| layout (std140) uniform Common { |  | ||||||
|   mat4 projection; |  | ||||||
|   mat4 view; |  | ||||||
|   vec3 camera_position; |  | ||||||
| }; |  | ||||||
|  |  | ||||||
| out vec3 uv_coords; |  | ||||||
|  |  | ||||||
| void main() { |  | ||||||
|   vec4 pos    = projection * sb_view * vec4(position, 1.0); |  | ||||||
|   gl_Position = pos.xyww; |  | ||||||
|   uv_coords   = position; |  | ||||||
| } |  | ||||||
| @@ -4,26 +4,18 @@ layout(location=0) in vec3 position; | |||||||
| layout(location=1) in vec3 normal; | layout(location=1) in vec3 normal; | ||||||
| layout(location=2) in vec2 uv; | layout(location=2) in vec2 uv; | ||||||
|  |  | ||||||
|  | out vec3 vert_normal; | ||||||
|  | out vec3 frag_position; | ||||||
|  | out vec2 uv_coords; | ||||||
|  |  | ||||||
| uniform mat3 normal_mat; | uniform mat3 normal_mat; | ||||||
| uniform mat4 model; | uniform mat4 model; | ||||||
|  | uniform mat4 view; | ||||||
| layout (std140) uniform Common { | uniform mat4 projection; | ||||||
|   mat4 projection; |  | ||||||
|   mat4 view; |  | ||||||
|   vec3 camera_position; |  | ||||||
| }; |  | ||||||
|  |  | ||||||
| // interface block |  | ||||||
| out VS_OUT { |  | ||||||
|   vec3 vert_normal; |  | ||||||
|   vec3 frag_position; |  | ||||||
|   vec2 uv_coords; |  | ||||||
| } vs_out; |  | ||||||
|  |  | ||||||
| void main() { | void main() { | ||||||
|   vs_out.frag_position = vec3(model * vec4(position, 1.0)); |   vert_normal   = normal_mat * normal; | ||||||
|   vs_out.vert_normal   = normal_mat * normal; |   frag_position = vec3(model * vec4(position, 1.0)); | ||||||
|   vs_out.uv_coords     = uv; |   uv_coords     = uv; | ||||||
|  |   gl_Position   = projection * view * model * vec4(position, 1.0); | ||||||
|   gl_Position = projection * view * model * vec4(position, 1.0); |  | ||||||
| }; | }; | ||||||
|   | |||||||
 Submodule src/assimp updated: 258cdfd2bc...c35200e38e
									
								
							
							
								
								
									
										460
									
								
								src/main.cc
									
									
									
									
									
								
							
							
						
						
									
										460
									
								
								src/main.cc
									
									
									
									
									
								
							| @@ -48,27 +48,17 @@ | |||||||
| #define max(a, b) (a > b ? a : b) | #define max(a, b) (a > b ? a : b) | ||||||
| #define clamp(v, a, b) (min(max(v, a), b)) | #define clamp(v, a, b) (min(max(v, a), b)) | ||||||
|  |  | ||||||
| #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 { | enum exit_codes : int { | ||||||
|   EXIT_CODE_SUCCESS, |   EXIT_CODE_SUCCESS, | ||||||
|   EXIT_CODE_SDL_INIT_FAILED, |   EXIT_CODE_SDL_INIT_FAILED, | ||||||
|   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 { | ||||||
|   public: |   public: | ||||||
|     Shader(const std::string &vert_file, const std::string &frag_file, const std::string &geo_file = ""); |     Shader(const std::string &vert_file, const std::string &frag_file); | ||||||
|     ~Shader(); |     ~Shader(); | ||||||
|     void activate(); |     void activate(); | ||||||
|     void set_int(const char *name, int value); |     void set_int(const char *name, int value); | ||||||
| @@ -77,10 +67,9 @@ class Shader { | |||||||
|     void set_vec4(const char *name, glm::vec4 vector); |     void set_vec4(const char *name, glm::vec4 vector); | ||||||
|     void set_mat3(const char *name, glm::mat3 matrix); |     void set_mat3(const char *name, glm::mat3 matrix); | ||||||
|     void set_mat4(const char *name, glm::mat4 matrix); |     void set_mat4(const char *name, glm::mat4 matrix); | ||||||
|     void set_uniform_block_binding_point(const char *block_name, GLuint binding_point); |  | ||||||
|     GLuint program; |     GLuint program; | ||||||
|   private: |   private: | ||||||
|     void link_program(GLuint vert, GLuint frag, GLuint geo); |     void link_program(GLuint vert, GLuint frag); | ||||||
|     GLuint load_and_compile_shader(const std::string &filepath, GLenum shader_type); |     GLuint load_and_compile_shader(const std::string &filepath, GLenum shader_type); | ||||||
|     std::string load_shader_from_file(const std::string &filepath); |     std::string load_shader_from_file(const std::string &filepath); | ||||||
|     static const char *get_shader_type_string(GLenum shader_type); |     static const char *get_shader_type_string(GLenum shader_type); | ||||||
| @@ -121,14 +110,10 @@ class Mesh { | |||||||
|     std::vector<Texture2D> textures; |     std::vector<Texture2D> textures; | ||||||
|  |  | ||||||
|     Mesh(std::vector<Vertex> vertices, std::vector<GLuint> indices, std::vector<Texture2D> textures); |     Mesh(std::vector<Vertex> vertices, std::vector<GLuint> indices, std::vector<Texture2D> textures); | ||||||
|     void activate(); |  | ||||||
|     void deactivate(); |  | ||||||
|     void draw(Shader &Shader); |     void draw(Shader &Shader); | ||||||
|     void draw_instanced(Shader &Shader, unsigned int count = 1); |  | ||||||
|   private: |   private: | ||||||
|     GLuint vao, vbo, ebo; |     GLuint vao, vbo, ebo; | ||||||
|     void setup_mesh(); |     void setup_mesh(); | ||||||
|     void set_mesh_textures_for_drawing(Shader &shader); |  | ||||||
| }; | }; | ||||||
|  |  | ||||||
| class Model { | class Model { | ||||||
| @@ -150,22 +135,6 @@ 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; |  | ||||||
|   GLuint width; |  | ||||||
|   GLuint 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); |  | ||||||
|  |  | ||||||
| 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; | ||||||
| @@ -177,11 +146,6 @@ 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) { | ||||||
| @@ -197,21 +161,12 @@ 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); | ||||||
|  |  | ||||||
| #if MSAA |   glEnable(GL_DEPTH_TEST); | ||||||
|   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 | ||||||
| @@ -256,74 +211,21 @@ int main() { | |||||||
|     13, 15, 16 |     13, 15, 16 | ||||||
|   }; |   }; | ||||||
|  |  | ||||||
|   Model suzanne = {"models/suzanne/suzanne.obj"}; |   Model backpack = {"models/suzanne/suzanne.obj"}; | ||||||
|   Mesh light    = {vertices, indices, {}}; |   Mesh light     = {vertices, indices, {}}; | ||||||
|  |  | ||||||
|   std::vector<Vertex> skybox_vertices = { |   Shader main_shader  {"shaders/vert.glsl", "shaders/frag.glsl"}; | ||||||
|     Vertex{glm::vec3(-1.0f,  1.0f, -1.0f), glm::vec3(1.0f, 1.0f, 1.0f), glm::vec2(1.0f, 1.0f)}, |   Shader light_shader {"shaders/vert.glsl", "shaders/light_frag.glsl"}; | ||||||
|     Vertex{glm::vec3(-1.0f, -1.0f, -1.0f), glm::vec3(1.0f, 1.0f, 1.0f), glm::vec2(1.0f, 1.0f)}, |  | ||||||
|     Vertex{glm::vec3( 1.0f, -1.0f, -1.0f), glm::vec3(1.0f, 1.0f, 1.0f), glm::vec2(1.0f, 1.0f)}, |  | ||||||
|     Vertex{glm::vec3( 1.0f,  1.0f, -1.0f), glm::vec3(1.0f, 1.0f, 1.0f), glm::vec2(1.0f, 1.0f)}, |  | ||||||
|     Vertex{glm::vec3(-1.0f, -1.0f,  1.0f), glm::vec3(1.0f, 1.0f, 1.0f), glm::vec2(1.0f, 1.0f)}, |  | ||||||
|     Vertex{glm::vec3(-1.0f,  1.0f,  1.0f), glm::vec3(1.0f, 1.0f, 1.0f), glm::vec2(1.0f, 1.0f)}, |  | ||||||
|     Vertex{glm::vec3( 1.0f, -1.0f,  1.0f), glm::vec3(1.0f, 1.0f, 1.0f), glm::vec2(1.0f, 1.0f)}, |  | ||||||
|     Vertex{glm::vec3( 1.0f,  1.0f,  1.0f), glm::vec3(1.0f, 1.0f, 1.0f), glm::vec2(1.0f, 1.0f)}, |  | ||||||
|   }; |  | ||||||
|  |  | ||||||
|   std::vector<GLuint> skybox_indices = { |   const float camera_speed   = 25.0f; | ||||||
|     0, 1, 2, |   glm::vec3 camera_position  = glm::vec3(-2.0f, 0.0f, 6.0f); | ||||||
|     2, 3, 0, |   glm::vec3 camera_forward   = glm::vec3(0.0f); | ||||||
|     4, 1, 0, |   glm::vec3 world_up         = glm::vec3(0.0f, 1.0f, 0.0f); | ||||||
|     0, 5, 4, |   glm::vec3 light_ambient    = glm::vec3(0.2f, 0.2f, 0.2f); | ||||||
|     2, 6, 7, |   glm::vec3 light_diffuse    = glm::vec3(0.75f, 0.75f, 0.75f); | ||||||
|     7, 3, 2, |   glm::vec3 light_specular   = glm::vec3(1.0f, 1.0f, 1.0f); | ||||||
|     4, 5, 7, |  | ||||||
|     7, 6, 4, |  | ||||||
|     0, 3, 7, |  | ||||||
|     7, 5, 0, |  | ||||||
|     1, 4, 2, |  | ||||||
|     2, 4, 6, |  | ||||||
|   }; |  | ||||||
|  |  | ||||||
|   Mesh skybox = {skybox_vertices, skybox_indices, {}}; |   float yaw   = -70.0f; | ||||||
|  |  | ||||||
|   std::vector<Vertex> screen_vertices = { |  | ||||||
|     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 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"}; |  | ||||||
| #if NORMALS |  | ||||||
|   Shader normal_vis_shader {"shaders/normal_vert.glsl", "shaders/normal_frag.glsl", "shaders/normal_geo.glsl"}; |  | ||||||
| #endif |  | ||||||
|  |  | ||||||
| #if POINT_LIGHTS |  | ||||||
|   Shader light_shader      {"shaders/light_vert.glsl",  "shaders/light_frag.glsl"}; |  | ||||||
|   std::vector<glm::mat4> light_shader_model_mats; |  | ||||||
| #endif |  | ||||||
|  |  | ||||||
|   const float camera_speed  = 25.0f; |  | ||||||
|   glm::vec3 camera_position = glm::vec3(-2.5f, 0.0f, 8.0f); |  | ||||||
|   glm::vec3 camera_forward  = glm::vec3(0.0f); |  | ||||||
|   glm::vec3 world_up        = glm::vec3(0.0f, 1.0f, 0.0f); |  | ||||||
|   glm::vec3 light_ambient   = glm::vec3(0.2f, 0.2f, 0.2f); |  | ||||||
|   glm::vec3 light_diffuse   = glm::vec3(0.75f, 0.75f, 0.75f); |  | ||||||
|   glm::vec3 light_specular  = glm::vec3(1.0f, 1.0f, 1.0f); |  | ||||||
|  |  | ||||||
|   float yaw   = -75.0f; |  | ||||||
|   float pitch =   0.0f; |   float pitch =   0.0f; | ||||||
|  |  | ||||||
|   glm::mat4 model      = glm::mat4(1.0f); |   glm::mat4 model      = glm::mat4(1.0f); | ||||||
| @@ -331,6 +233,11 @@ int main() { | |||||||
|   glm::mat4 projection = glm::perspective(glm::radians(45.0f), (float)WINDOW_WIDTH / (float)WINDOW_HEIGHT, 0.1f, 100.0f); |   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); |   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); | ||||||
|  |  | ||||||
|   std::vector<glm::vec3> point_light_positions = { |   std::vector<glm::vec3> point_light_positions = { | ||||||
|     glm::vec3( 0.7f,  0.2f,  2.0f), |     glm::vec3( 0.7f,  0.2f,  2.0f), | ||||||
|     glm::vec3( 2.3f, -3.3f, -4.0f), |     glm::vec3( 2.3f, -3.3f, -4.0f), | ||||||
| @@ -338,9 +245,6 @@ int main() { | |||||||
|     glm::vec3( 1.0f,  0.0f, -18.0f) |     glm::vec3( 1.0f,  0.0f, -18.0f) | ||||||
|   }; |   }; | ||||||
|  |  | ||||||
|   // Setup material |  | ||||||
|   main_shader.set_float("material.shininess", 32.0f); |  | ||||||
|  |  | ||||||
|   // Setup lights |   // Setup lights | ||||||
|   main_shader.set_vec3("directional_light.direction", glm::vec3(-0.2f, -1.0f, -0.3f)); |   main_shader.set_vec3("directional_light.direction", glm::vec3(-0.2f, -1.0f, -0.3f)); | ||||||
|   main_shader.set_vec3("directional_light.ambient", light_ambient); |   main_shader.set_vec3("directional_light.ambient", light_ambient); | ||||||
| @@ -386,76 +290,8 @@ int main() { | |||||||
|     memset(constant,  0, sizeof(constant)); |     memset(constant,  0, sizeof(constant)); | ||||||
|     memset(linear,    0, sizeof(linear)); |     memset(linear,    0, sizeof(linear)); | ||||||
|     memset(quadratic, 0, sizeof(quadratic)); |     memset(quadratic, 0, sizeof(quadratic)); | ||||||
|  |  | ||||||
| #if POINT_LIGHTS |  | ||||||
|     glm::mat4 light_shader_model_mat = glm::translate(glm::mat4(1.0f), point_light_positions[i]); |  | ||||||
|     light_shader_model_mat = glm::scale(light_shader_model_mat, glm::vec3(0.2f)); |  | ||||||
|     light_shader_model_mats.push_back(light_shader_model_mat); |  | ||||||
| #endif |  | ||||||
|   } |   } | ||||||
|  |  | ||||||
| #if POINT_LIGHTS |  | ||||||
|   std::size_t vec4_size = sizeof(glm::vec4); |  | ||||||
|  |  | ||||||
|   light.activate(); |  | ||||||
|  |  | ||||||
|   GLuint instanceVBO; |  | ||||||
|   glGenBuffers(1, &instanceVBO); |  | ||||||
|   glBindBuffer(GL_ARRAY_BUFFER, instanceVBO); |  | ||||||
|   glBufferData(GL_ARRAY_BUFFER, sizeof(glm::mat4) * light_shader_model_mats.size(), glm::value_ptr(light_shader_model_mats[0]), GL_STATIC_DRAW); |  | ||||||
|  |  | ||||||
|   // Set up attribute pointers for each column of the matrix |  | ||||||
|   for (unsigned int i = 3; i < 7; ++i) { |  | ||||||
|     glVertexAttribPointer(i, 4, GL_FLOAT, GL_FALSE, 4 * vec4_size, (void *)((i - 3) * vec4_size)); |  | ||||||
|     glEnableVertexAttribArray(i); |  | ||||||
|     glVertexAttribDivisor(i, 1); |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   light.deactivate(); |  | ||||||
|  |  | ||||||
|   glBindBuffer(GL_ARRAY_BUFFER, 0); |  | ||||||
| #endif |  | ||||||
|  |  | ||||||
|   // Load cube map |  | ||||||
|   std::vector<std::string> cube_map_textures = { |  | ||||||
|     "images/skybox/right.jpg", |  | ||||||
|     "images/skybox/left.jpg", |  | ||||||
|     "images/skybox/top.jpg", |  | ||||||
|     "images/skybox/bottom.jpg", |  | ||||||
|     "images/skybox/front.jpg", |  | ||||||
|     "images/skybox/back.jpg", |  | ||||||
|   }; |  | ||||||
|  |  | ||||||
|   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 |  | ||||||
|   main_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); |  | ||||||
|   refractive_shader.set_uniform_block_binding_point("Common", ubo_binding_point); |  | ||||||
|  |  | ||||||
| #if NORMALS |  | ||||||
|   normal_vis_shader.set_uniform_block_binding_point("Common", ubo_binding_point); |  | ||||||
| #endif |  | ||||||
|  |  | ||||||
| #if POINT_LIGHTS |  | ||||||
|   light_shader.set_uniform_block_binding_point     ("Common", ubo_binding_point); |  | ||||||
| #endif |  | ||||||
|  |  | ||||||
|   // 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; |   const float sensitivity   = 0.1f; | ||||||
|   int last_mouse_x          = WINDOW_HALF_WIDTH; |   int last_mouse_x          = WINDOW_HALF_WIDTH; | ||||||
|   int last_mouse_y          = WINDOW_HALF_HEIGHT; |   int last_mouse_y          = WINDOW_HALF_HEIGHT; | ||||||
| @@ -519,14 +355,6 @@ 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_normal_frame_buffer(w, h); |  | ||||||
| #if MSAA |  | ||||||
|             delete_frame_buffer(multisample_buffer); |  | ||||||
|             multisample_buffer = create_multisample_frame_buffer(w, h); |  | ||||||
| #endif |  | ||||||
|           } |           } | ||||||
|           break; |           break; | ||||||
|       } |       } | ||||||
| @@ -538,96 +366,33 @@ int main() { | |||||||
|     camera_forward   = glm::normalize(camera_forward); |     camera_forward   = glm::normalize(camera_forward); | ||||||
|  |  | ||||||
|     view = glm::lookAt(camera_position, camera_position + camera_forward, world_up); |     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.position", camera_position); | ||||||
|     main_shader.set_vec3("spot_light.direction", camera_forward); |     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.cutoff", glm::cos(glm::radians(12.5))); | ||||||
|     main_shader.set_float("spot_light.outer_cutoff", glm::cos(glm::radians(17.5))); |     main_shader.set_float("spot_light.outer_cutoff", glm::cos(glm::radians(17.5))); | ||||||
|     skybox_shader.set_mat4("sb_view", glm::mat4(glm::mat3(view))); |     main_shader.set_mat4("view", view); | ||||||
|  |     light_shader.set_mat4("view", 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); |     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); |     model = glm::translate(glm::mat4(1.0f), glm::vec3(0.0f, 0.0f, 0.0f)); | ||||||
|     glDepthFunc(GL_LEQUAL); |  | ||||||
|     glEnable(GL_CULL_FACE); |  | ||||||
|  |  | ||||||
|     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)); | ||||||
|     main_shader.activate(); |     main_shader.activate(); | ||||||
|     main_shader.set_mat4("model", model); |     main_shader.set_mat4("model", model); | ||||||
|     main_shader.set_mat3("normal_mat", normal_mat); |     main_shader.set_mat3("normal_mat", normal_mat); | ||||||
|     suzanne.draw(main_shader); |     backpack.draw(main_shader); | ||||||
|  |  | ||||||
| #if NORMALS |     // Draw light source | ||||||
|     normal_mat = glm::transpose(glm::inverse(view * model)); |     for (int i = 0; i < point_light_positions.size(); ++i) { | ||||||
|     normal_vis_shader.activate(); |       model = glm::translate(glm::mat4(1.0f), point_light_positions[i]); | ||||||
|     normal_vis_shader.set_mat4("model", model); |       model = glm::scale(model, glm::vec3(0.2f)); | ||||||
|     normal_vis_shader.set_mat3("normal_mat", normal_mat); |       light_shader.activate(); | ||||||
|     suzanne.draw(normal_vis_shader); |       light_shader.set_mat4("model", model); | ||||||
| #endif |       light_shader.set_vec3("light_diffuse", light_diffuse); | ||||||
|  |       light.draw(light_shader); | ||||||
|     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)); |  | ||||||
|     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); |  | ||||||
|  |  | ||||||
| #if POINT_LIGHTS |  | ||||||
|     // Draw point lights |  | ||||||
|     light_shader.set_vec3("light_diffuse", light_diffuse); |  | ||||||
|     light.draw_instanced(light_shader, point_light_positions.size()); |  | ||||||
| #endif |  | ||||||
|  |  | ||||||
|     // Draw skybox |  | ||||||
|     skybox_shader.activate(); |  | ||||||
|     glActiveTexture(GL_TEXTURE0); |  | ||||||
|     glBindTexture(GL_TEXTURE_CUBE_MAP, cubemap); |  | ||||||
|     skybox_shader.set_int("cubemap", 0); |  | ||||||
|     skybox.draw(skybox_shader); |  | ||||||
|  |  | ||||||
| #if WIREFRAME |  | ||||||
|     // wireframe mode |  | ||||||
|     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); |  | ||||||
|  |  | ||||||
|     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); | ||||||
|   } |   } | ||||||
| @@ -640,19 +405,12 @@ int main() { | |||||||
| } | } | ||||||
|  |  | ||||||
|  |  | ||||||
| Shader::Shader(const std::string &vert_file, const std::string &frag_file, const std::string &geo_file) { | Shader::Shader(const std::string &vert_file, const std::string &frag_file) { | ||||||
|   GLuint vert = load_and_compile_shader(vert_file, GL_VERTEX_SHADER); |   GLuint vert = load_and_compile_shader(vert_file, GL_VERTEX_SHADER); | ||||||
|   GLuint frag = load_and_compile_shader(frag_file, GL_FRAGMENT_SHADER); |   GLuint frag = load_and_compile_shader(frag_file, GL_FRAGMENT_SHADER); | ||||||
|   GLuint geo  = 0; |   link_program(vert, frag); | ||||||
|   if (geo_file.size() > 0) { |  | ||||||
|     geo = load_and_compile_shader(geo_file, GL_GEOMETRY_SHADER); |  | ||||||
|   } |  | ||||||
|   link_program(vert, frag, geo); |  | ||||||
|   glDeleteShader(vert); |   glDeleteShader(vert); | ||||||
|   glDeleteShader(frag); |   glDeleteShader(frag); | ||||||
|   if (geo > 0) { |  | ||||||
|     glDeleteShader(geo); |  | ||||||
|   } |  | ||||||
| } | } | ||||||
|  |  | ||||||
| Shader::~Shader() { | Shader::~Shader() { | ||||||
| @@ -697,18 +455,10 @@ void Shader::set_mat4(const char *name, glm::mat4 matrix) { | |||||||
|   glUniformMatrix4fv(glGetUniformLocation(program, name), 1, GL_FALSE, glm::value_ptr(matrix)); |   glUniformMatrix4fv(glGetUniformLocation(program, name), 1, GL_FALSE, glm::value_ptr(matrix)); | ||||||
| } | } | ||||||
|  |  | ||||||
| void Shader::set_uniform_block_binding_point(const char *block_name, GLuint binding_point) { | void Shader::link_program(GLuint vert, GLuint frag) { | ||||||
|   GLuint block_index = glGetUniformBlockIndex(program, block_name); |  | ||||||
|   glUniformBlockBinding(program, block_index, binding_point); |  | ||||||
| } |  | ||||||
|  |  | ||||||
| void Shader::link_program(GLuint vert, GLuint frag, GLuint geo) { |  | ||||||
|   program = glCreateProgram(); |   program = glCreateProgram(); | ||||||
|   glAttachShader(program, vert); |   glAttachShader(program, vert); | ||||||
|   glAttachShader(program, frag); |   glAttachShader(program, frag); | ||||||
|   if (geo > 0) { |  | ||||||
|     glAttachShader(program, geo); |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   glLinkProgram(program); |   glLinkProgram(program); | ||||||
|   GLint program_linked; |   GLint program_linked; | ||||||
| @@ -865,7 +615,7 @@ void Mesh::setup_mesh() { | |||||||
|   glEnableVertexAttribArray(2); |   glEnableVertexAttribArray(2); | ||||||
| } | } | ||||||
|  |  | ||||||
| void Mesh::set_mesh_textures_for_drawing(Shader &shader) { | void Mesh::draw(Shader &shader) { | ||||||
|   unsigned int diffuse = 1; |   unsigned int diffuse = 1; | ||||||
|   unsigned int specular = 1; |   unsigned int specular = 1; | ||||||
|   unsigned int index; |   unsigned int index; | ||||||
| @@ -876,33 +626,13 @@ void Mesh::set_mesh_textures_for_drawing(Shader &shader) { | |||||||
|     shader.set_int(texture.name(index).c_str(), texture.texture_unit - GL_TEXTURE0); |     shader.set_int(texture.name(index).c_str(), texture.texture_unit - GL_TEXTURE0); | ||||||
|     texture.activate(); |     texture.activate(); | ||||||
|   } |   } | ||||||
| } |  | ||||||
|  |  | ||||||
| void Mesh::activate() { |  | ||||||
|   glBindVertexArray(vao); |   glBindVertexArray(vao); | ||||||
| } |  | ||||||
|  |  | ||||||
| void Mesh::deactivate() { |  | ||||||
|   glBindVertexArray(0); |  | ||||||
| } |  | ||||||
|  |  | ||||||
| void Mesh::draw(Shader &shader) { |  | ||||||
|   set_mesh_textures_for_drawing(shader); |  | ||||||
|   activate(); |  | ||||||
|   glDrawElements(GL_TRIANGLES, indices.size(), GL_UNSIGNED_INT, (void *)0); |   glDrawElements(GL_TRIANGLES, indices.size(), GL_UNSIGNED_INT, (void *)0); | ||||||
|   deactivate(); |  | ||||||
| } |  | ||||||
|  |  | ||||||
| void Mesh::draw_instanced(Shader &shader, unsigned int count) { |  | ||||||
|   set_mesh_textures_for_drawing(shader); |  | ||||||
|   glBindVertexArray(vao); |  | ||||||
|   glDrawElementsInstanced(GL_TRIANGLES, indices.size(), GL_UNSIGNED_INT, (void *)0, count); |  | ||||||
|   glBindVertexArray(0); |   glBindVertexArray(0); | ||||||
| } | } | ||||||
|  |  | ||||||
| void Model::draw(Shader &shader) { | void Model::draw(Shader &shader) { | ||||||
|   shader.activate(); |  | ||||||
|  |  | ||||||
|   for (int i = 0; i < meshes.size(); ++i) { |   for (int i = 0; i < meshes.size(); ++i) { | ||||||
|     meshes[i].draw(shader); |     meshes[i].draw(shader); | ||||||
|   } |   } | ||||||
| @@ -995,117 +725,3 @@ std::vector<Texture2D> Model::load_material_textures(aiMaterial *material, aiTex | |||||||
|  |  | ||||||
|   return textures; |   return textures; | ||||||
| } | } | ||||||
|  |  | ||||||
| FrameBuffer create_normal_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); |  | ||||||
|  |  | ||||||
|   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); |  | ||||||
|   glDeleteRenderbuffers(1, &buffer.depth_stencil); |  | ||||||
| } |  | ||||||
|  |  | ||||||
| GLuint load_cubemap(std::vector<std::string> textures) { |  | ||||||
|   GLuint cubemap; |  | ||||||
|   glGenTextures(1, &cubemap); |  | ||||||
|   glBindTexture(GL_TEXTURE_CUBE_MAP, cubemap); |  | ||||||
|  |  | ||||||
|   int width, height, channels; |  | ||||||
|   uint8_t *tex; |  | ||||||
|   for (unsigned int i = 0; i < textures.size(); ++i) { |  | ||||||
|     tex = stbi_load(textures[i].c_str(), &width, &height, &channels, 0); |  | ||||||
|     glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, tex); |  | ||||||
|     stbi_image_free(tex); |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR); |  | ||||||
|   glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR); |  | ||||||
|   glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); |  | ||||||
|   glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); |  | ||||||
|   glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE); |  | ||||||
|  |  | ||||||
|   return cubemap; |  | ||||||
| } |  | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user