Compare commits
	
		
			4 Commits
		
	
	
		
			main
			...
			02-model-l
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| c5f13d7c37 | |||
| db3116453b | |||
| 0db5c5d81a | |||
| d8d2c73438 | 
							
								
								
									
										3
									
								
								.gitmodules
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								.gitmodules
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,3 @@ | ||||
| [submodule "src/assimp"] | ||||
| 	path = src/assimp | ||||
| 	url = git@github.com:assimp/assimp | ||||
							
								
								
									
										4
									
								
								compile
									
									
									
									
									
								
							
							
						
						
									
										4
									
								
								compile
									
									
									
									
									
								
							| @@ -1,9 +1,9 @@ | ||||
| #!/bin/bash | ||||
|  | ||||
| CC=clang | ||||
| CFLAGS="-g -c -Wall -Isrc/glad/include" | ||||
| CFLAGS="-O3 -c -Wall -Isrc/glad/include" | ||||
| 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" | ||||
| GLAD_SRC="src/glad/src/glad.c" | ||||
| GLAD_OBJ="glad.o" | ||||
|   | ||||
							
								
								
									
										
											BIN
										
									
								
								models/suzanne/diffuse.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								models/suzanne/diffuse.png
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							| After Width: | Height: | Size: 67 KiB | 
							
								
								
									
										
											BIN
										
									
								
								models/suzanne/specular.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								models/suzanne/specular.png
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							| After Width: | Height: | Size: 526 KiB | 
							
								
								
									
										12
									
								
								models/suzanne/suzanne.mtl
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										12
									
								
								models/suzanne/suzanne.mtl
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,12 @@ | ||||
| # Blender 4.3.2 MTL File: 'None' | ||||
| # www.blender.org | ||||
|  | ||||
| newmtl Material | ||||
| Ka 1.000000 1.000000 1.000000 | ||||
| Ks 0.500000 0.500000 0.500000 | ||||
| Ke 0.000000 0.000000 0.000000 | ||||
| Ni 1.450000 | ||||
| d 1.000000 | ||||
| illum 2 | ||||
| map_Kd diffuse.png | ||||
| map_Ks specular.png | ||||
							
								
								
									
										2977
									
								
								models/suzanne/suzanne.obj
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										2977
									
								
								models/suzanne/suzanne.obj
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							| @@ -3,8 +3,8 @@ | ||||
| #define POINT_LIGHT_COUNT 4 | ||||
|  | ||||
| struct Material { | ||||
|   sampler2D diffuse; | ||||
|   sampler2D specular; | ||||
|   sampler2D diffuse1; | ||||
|   sampler2D specular1; | ||||
|   float shininess; | ||||
| }; | ||||
|  | ||||
| @@ -70,11 +70,11 @@ vec3 calc_dir_light(DirLight light, vec3 normal, vec3 view_direction) { | ||||
|   vec3 light_direction     = normalize(-light.direction); | ||||
|   vec3  reflect_direction  = reflect(-light_direction, normal); | ||||
|   float diff               = max(dot(normal, light_direction), 0.0); | ||||
|   vec3  diff_tex           = vec3(texture(material.diffuse, uv_coords)); | ||||
|   vec3  diff_tex           = vec3(texture(material.diffuse1, uv_coords)); | ||||
|   float spec               = pow(max(dot(reflect_direction, view_direction), 0.0), material.shininess); | ||||
|   vec3  ambient            = light.ambient * diff_tex; | ||||
|   vec3  diffuse            = light.diffuse * (diff * diff_tex); | ||||
|   vec3  specular           = light.specular * (spec * vec3(texture(material.specular, uv_coords))); | ||||
|   vec3  specular           = light.specular * (spec * vec3(texture(material.specular1, uv_coords))); | ||||
|  | ||||
|   return ambient + diffuse + specular; | ||||
| } | ||||
| @@ -85,11 +85,11 @@ vec3 calc_point_light(PointLight light, vec3 normal, vec3 frag_position, vec3 vi | ||||
|   float distance           = length(light.position - frag_position); | ||||
|   float attenuation        = 1.0 / (light.constant + light.linear * distance + light.quadratic * (distance * distance)); | ||||
|   float diff               = max(dot(normal, light_direction), 0.0); | ||||
|   vec3  diff_tex           = vec3(texture(material.diffuse, uv_coords)); | ||||
|   vec3  diff_tex           = vec3(texture(material.diffuse1, uv_coords)); | ||||
|   float spec               = pow(max(dot(reflect_direction, view_direction), 0.0), material.shininess); | ||||
|   vec3  ambient            = light.ambient * diff_tex * attenuation; | ||||
|   vec3  diffuse            = light.diffuse * (diff * diff_tex) * attenuation; | ||||
|   vec3  specular           = light.specular * (spec * vec3(texture(material.specular, uv_coords))) * attenuation; | ||||
|   vec3  specular           = light.specular * (spec * vec3(texture(material.specular1, uv_coords))) * attenuation; | ||||
|  | ||||
|   return ambient + diffuse + specular; | ||||
| } | ||||
| @@ -102,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 diff               = max(dot(normal, light_direction), 0.0); | ||||
|   float spec               = pow(max(dot(reflect_direction, view_direction), 0.0), material.shininess); | ||||
|   vec3  diff_tex           = vec3(texture(material.diffuse, uv_coords)); | ||||
|   vec3  diff_tex           = vec3(texture(material.diffuse1, uv_coords)); | ||||
|   vec3  ambient            = light.ambient * diff_tex; | ||||
|   vec3  diffuse            = light.diffuse * (diff * diff_tex) * intensity; | ||||
|   vec3  specular           = light.specular * (spec * vec3(texture(material.specular, uv_coords))) * intensity; | ||||
|   vec3  specular           = light.specular * (spec * vec3(texture(material.specular1, uv_coords))) * intensity; | ||||
|  | ||||
|   return ambient + diffuse + specular; | ||||
| } | ||||
|   | ||||
 Submodule src/assimp updated: 258cdfd2bc...c35200e38e
									
								
							
							
								
								
									
										200
									
								
								src/main.cc
									
									
									
									
									
								
							
							
						
						
									
										200
									
								
								src/main.cc
									
									
									
									
									
								
							| @@ -14,6 +14,14 @@ | ||||
| #include "glm/gtx/rotate_vector.hpp" | ||||
| #include "glm/gtx/string_cast.hpp" | ||||
|  | ||||
| // Assimp | ||||
| #include "assimp/Importer.hpp" | ||||
| #include "assimp/postprocess.h" | ||||
| #include "assimp/scene.h" | ||||
| #include "assimp/mesh.h" | ||||
| #include "assimp/material.h" | ||||
| #include "assimp/types.h" | ||||
|  | ||||
| // SDL | ||||
| #include <SDL2/SDL.h> | ||||
| #include <SDL2/SDL_timer.h> | ||||
| @@ -67,16 +75,23 @@ class Shader { | ||||
|     static const char *get_shader_type_string(GLenum shader_type); | ||||
| }; | ||||
|  | ||||
| enum TextureType : unsigned char { | ||||
|   TEXTURE_TYPE_DIFFUSE, | ||||
|   TEXTURE_TYPE_SPECULAR, | ||||
| }; | ||||
|  | ||||
| class Texture2D { | ||||
|   public: | ||||
|     Texture2D(const char *filename, GLint texture_unit, const char *name); | ||||
|     Texture2D(const char *filename, GLint texture_unit, TextureType type); | ||||
|     ~Texture2D(); | ||||
|     void activate() const; | ||||
|     std::string name(unsigned int index) const; | ||||
|     int width; | ||||
|     int height; | ||||
|     int channels; | ||||
|     const char *filename; | ||||
|     GLint texture_unit; | ||||
|     std::string name; | ||||
|     TextureType type; | ||||
|   private: | ||||
|     GLuint texture; | ||||
|     GLint format; | ||||
| @@ -101,6 +116,25 @@ class Mesh { | ||||
|     void setup_mesh(); | ||||
| }; | ||||
|  | ||||
| class Model { | ||||
|   public: | ||||
|     Model(const char *path) { | ||||
|       load_model(path); | ||||
|     } | ||||
|  | ||||
|     void draw(Shader &shader); | ||||
|   private: | ||||
|     std::vector<Texture2D> loaded_textures; | ||||
|     std::vector<Mesh> meshes; | ||||
|     std::string directory; | ||||
|     GLint texture_unit = GL_TEXTURE0; | ||||
|  | ||||
|     void load_model(std::string path); | ||||
|     void process_node(aiNode *node, const aiScene *scene); | ||||
|     Mesh process_mesh(aiMesh *mesh, const aiScene *scene); | ||||
|     std::vector<Texture2D> load_material_textures(aiMaterial *mat, aiTextureType type); | ||||
| }; | ||||
|  | ||||
| int main() { | ||||
|   if (SDL_Init(SDL_INIT_EVERYTHING) != 0) { | ||||
|     return EXIT_CODE_SDL_INIT_FAILED; | ||||
| @@ -130,8 +164,6 @@ int main() { | ||||
|   SDL_SetRelativeMouseMode(SDL_TRUE); | ||||
|   SDL_WarpMouseInWindow(window, WINDOW_HALF_WIDTH, WINDOW_HALF_HEIGHT); | ||||
|  | ||||
|   stbi_set_flip_vertically_on_load(true); | ||||
|  | ||||
|   glViewport(0, 0, WINDOW_WIDTH, WINDOW_HEIGHT); | ||||
|  | ||||
|   glEnable(GL_DEPTH_TEST); | ||||
| @@ -179,12 +211,7 @@ int main() { | ||||
|     13, 15, 16 | ||||
|   }; | ||||
|  | ||||
|   std::vector<Texture2D> textures = { | ||||
|     Texture2D("images/container2.png", GL_TEXTURE0, "material.diffuse"), | ||||
|     Texture2D("images/container2_specular.png", GL_TEXTURE1, "material.specular"), | ||||
|   }; | ||||
|  | ||||
|   Mesh container = {vertices, indices, textures}; | ||||
|   Model backpack = {"models/suzanne/suzanne.obj"}; | ||||
|   Mesh light     = {vertices, indices, {}}; | ||||
|  | ||||
|   Shader main_shader  {"shaders/vert.glsl", "shaders/frag.glsl"}; | ||||
| @@ -207,40 +234,26 @@ int main() { | ||||
|   glm::mat3 normal_mat = glm::mat3(1.0f); | ||||
|  | ||||
|   main_shader.set_mat4 ("projection", projection); | ||||
|   main_shader.set_vec3 ("material.specular", glm::vec3(0.5f, 0.5f, 0.5f)); | ||||
|   main_shader.set_float("material.shininess", 32.0f); | ||||
|  | ||||
|   light_shader.set_mat4("projection", projection); | ||||
|  | ||||
|   std::vector<glm::vec3> cube_positions = { | ||||
|       glm::vec3( 0.0f,  0.0f,  0.0f), | ||||
|       glm::vec3( 4.0f,  6.0f, -15.0f), | ||||
|       glm::vec3(-3.5f, -3.2f, -2.5f), | ||||
|       glm::vec3(-5.8f, -3.0f, -12.3f), | ||||
|       glm::vec3( 4.4f, -1.4f, -3.5f), | ||||
|       glm::vec3(-3.7f,  4.0f, -7.5f), | ||||
|       glm::vec3( 3.3f, -3.0f, -2.5f), | ||||
|       glm::vec3( 3.5f,  3.0f, -2.5f), | ||||
|       glm::vec3( 3.5f,  1.2f, -1.5f), | ||||
|       glm::vec3(-3.3f,  2.0f, -1.5f) | ||||
|   }; | ||||
|  | ||||
|   std::vector<glm::vec3> point_light_positions = { | ||||
|     glm::vec3( 0.7f,  0.2f,  2.0f), | ||||
|     glm::vec3( 2.3f, -3.3f, -4.0f), | ||||
|     glm::vec3(-4.0f,  2.0f, -12.0f), | ||||
|     glm::vec3( 0.0f,  0.0f, -3.0f) | ||||
|     glm::vec3( 1.0f,  0.0f, -18.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); | ||||
|   main_shader.set_vec3("directional_light.diffuse", light_diffuse); | ||||
|   main_shader.set_vec3("directional_light.diffuse", light_diffuse * 0.25f); | ||||
|   main_shader.set_vec3("directional_light.specular", light_specular); | ||||
|  | ||||
|   main_shader.set_vec3("spot_light.ambient", light_ambient); | ||||
|   main_shader.set_vec3("spot_light.diffuse", light_diffuse); | ||||
|   main_shader.set_vec3("spot_light.specular", light_specular); | ||||
|   main_shader.set_vec3("spot_light.diffuse", light_diffuse * 0.5f); | ||||
|   main_shader.set_vec3("spot_light.specular", light_specular * 0.25f); | ||||
|  | ||||
|   for (int i = 0; i < point_light_positions.size(); ++i) { | ||||
|     char base[256]      = {0}; | ||||
| @@ -263,8 +276,8 @@ int main() { | ||||
|  | ||||
|     main_shader.set_vec3(position, point_light_positions[i]); | ||||
|     main_shader.set_vec3(ambient, light_ambient); | ||||
|     main_shader.set_vec3(diffuse, light_diffuse); | ||||
|     main_shader.set_vec3(specular, light_specular); | ||||
|     main_shader.set_vec3(diffuse, light_diffuse * 0.25f); | ||||
|     main_shader.set_vec3(specular, light_specular * 0.5f); | ||||
|     main_shader.set_float(constant, 1.0f); | ||||
|     main_shader.set_float(linear, 0.09f); | ||||
|     main_shader.set_float(quadratic, 0.032f); | ||||
| @@ -364,15 +377,12 @@ int main() { | ||||
|     glClearColor(0.04f, 0.08f, 0.08f, 1.0f); | ||||
|     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); | ||||
|  | ||||
|     for (int i = 0; i < cube_positions.size(); ++i) { | ||||
|       model = glm::translate(glm::mat4(1.0f), cube_positions[i]); | ||||
|       model = glm::rotate(model, glm::radians(10.0f * i), glm::vec3(1.0f, 0.3f, 0.5f)); | ||||
|     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); | ||||
|       container.draw(main_shader); | ||||
|     } | ||||
|     backpack.draw(main_shader); | ||||
|  | ||||
|     // Draw light source | ||||
|     for (int i = 0; i < point_light_positions.size(); ++i) { | ||||
| @@ -531,7 +541,7 @@ const char *Shader::get_shader_type_string(GLenum shader_type) { | ||||
|   return output; | ||||
| } | ||||
|  | ||||
| Texture2D::Texture2D(const char *filename, GLint texture_unit, const char *name) : texture_unit(texture_unit), name(name) { | ||||
| Texture2D::Texture2D(const char *filename, GLint texture_unit, TextureType type) : filename(filename), texture_unit(texture_unit), type(type) { | ||||
|   uint8_t *image = stbi_load(filename, &width, &height, &channels, 0); | ||||
|   if (!image) { | ||||
|     return; | ||||
| @@ -562,6 +572,23 @@ void Texture2D::activate() const { | ||||
|   glBindTexture(GL_TEXTURE_2D, texture); | ||||
| } | ||||
|  | ||||
| std::string Texture2D::name(unsigned int index) const { | ||||
|   std::string output = "material."; | ||||
|  | ||||
|   switch (type) { | ||||
|     case TEXTURE_TYPE_DIFFUSE: | ||||
|       output += "diffuse"; | ||||
|       break; | ||||
|     case TEXTURE_TYPE_SPECULAR: | ||||
|       output += "specular"; | ||||
|       break; | ||||
|   } | ||||
|  | ||||
|   output += std::to_string(index); | ||||
|  | ||||
|   return output.c_str(); | ||||
| } | ||||
|  | ||||
| Mesh::Mesh(std::vector<Vertex> vertices, std::vector<GLuint> indices, std::vector<Texture2D> textures) | ||||
|   : vertices(vertices), indices(indices), textures(textures) { | ||||
|     setup_mesh(); | ||||
| @@ -589,9 +616,14 @@ void Mesh::setup_mesh() { | ||||
| } | ||||
|  | ||||
| void Mesh::draw(Shader &shader) { | ||||
|   unsigned int diffuse = 1; | ||||
|   unsigned int specular = 1; | ||||
|   unsigned int index; | ||||
|  | ||||
|   for (int i = 0; i < textures.size(); ++i) { | ||||
|     const Texture2D &texture = textures[i]; | ||||
|     shader.set_int(texture.name.c_str(), texture.texture_unit - GL_TEXTURE0); | ||||
|     index = texture.type == TEXTURE_TYPE_DIFFUSE ? diffuse++ : specular++; | ||||
|     shader.set_int(texture.name(index).c_str(), texture.texture_unit - GL_TEXTURE0); | ||||
|     texture.activate(); | ||||
|   } | ||||
|  | ||||
| @@ -599,3 +631,97 @@ void Mesh::draw(Shader &shader) { | ||||
|   glDrawElements(GL_TRIANGLES, indices.size(), GL_UNSIGNED_INT, (void *)0); | ||||
|   glBindVertexArray(0); | ||||
| } | ||||
|  | ||||
| void Model::draw(Shader &shader) { | ||||
|   for (int i = 0; i < meshes.size(); ++i) { | ||||
|     meshes[i].draw(shader); | ||||
|   } | ||||
| } | ||||
|  | ||||
| void Model::load_model(std::string path) { | ||||
|   Assimp::Importer importer; | ||||
|   const aiScene *scene = importer.ReadFile(path, aiProcess_Triangulate | aiProcess_FlipUVs); | ||||
|   if (!scene || scene->mFlags & AI_SCENE_FLAGS_INCOMPLETE || !scene->mRootNode) { | ||||
|     printf("Failed to load model: %s. Error: %s\n", path.c_str(), importer.GetErrorString()); | ||||
|     return; | ||||
|   } | ||||
|  | ||||
|   directory = path.substr(0, path.find_last_of('/')); | ||||
|   process_node(scene->mRootNode, scene); | ||||
| } | ||||
|  | ||||
| void Model::process_node(aiNode *node, const aiScene *scene) { | ||||
|   for (unsigned int i = 0; i < node->mNumMeshes; ++i) { | ||||
|     aiMesh *mesh = scene->mMeshes[node->mMeshes[i]]; | ||||
|     meshes.push_back(process_mesh(mesh, scene)); | ||||
|   } | ||||
|  | ||||
|   for (unsigned int i = 0; i < node->mNumChildren; ++i) { | ||||
|     process_node(node->mChildren[i], scene); | ||||
|   } | ||||
| } | ||||
|  | ||||
| Mesh Model::process_mesh(aiMesh *mesh, const aiScene *scene) { | ||||
|   std::vector<Vertex> vertices; | ||||
|   std::vector<GLuint> indices; | ||||
|   std::vector<Texture2D> textures; | ||||
|  | ||||
|   for (unsigned int i = 0; i < mesh->mNumVertices; ++i) { | ||||
|     Vertex vertex; | ||||
|  | ||||
|     vertex.position = glm::vec3(mesh->mVertices[i].x, mesh->mVertices[i].y, mesh->mVertices[i].z); | ||||
|     vertex.normal = glm::vec3(mesh->mNormals[i].x, mesh->mNormals[i].y, mesh->mNormals[i].z); | ||||
|     if (mesh->mTextureCoords[0]) { | ||||
|       vertex.tex_coord = glm::vec2(mesh->mTextureCoords[0][i].x, mesh->mTextureCoords[0][i].y); | ||||
|     } else { | ||||
|       vertex.tex_coord = glm::vec2(0.0f, 0.0f); | ||||
|     } | ||||
|  | ||||
|     vertices.push_back(vertex); | ||||
|   } | ||||
|  | ||||
|   for (unsigned int i = 0; i < mesh->mNumFaces; ++i) { | ||||
|     aiFace face = mesh->mFaces[i]; | ||||
|     for (unsigned int j = 0; j < face.mNumIndices; ++j) { | ||||
|       indices.push_back(face.mIndices[j]); | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   if (mesh->mMaterialIndex >= 0) { | ||||
|     aiMaterial *material = scene->mMaterials[mesh->mMaterialIndex]; | ||||
|  | ||||
|     std::vector<Texture2D> diffuse_maps = load_material_textures(material, aiTextureType_DIFFUSE); | ||||
|     textures.insert(textures.end(), diffuse_maps.begin(), diffuse_maps.end()); | ||||
|  | ||||
|     std::vector<Texture2D> specular_maps = load_material_textures(material, aiTextureType_SPECULAR); | ||||
|     textures.insert(textures.end(), specular_maps.begin(), specular_maps.end()); | ||||
|   } | ||||
|  | ||||
|   return Mesh(vertices, indices, textures); | ||||
| } | ||||
|  | ||||
| std::vector<Texture2D> Model::load_material_textures(aiMaterial *material, aiTextureType type) { | ||||
|   std::vector<Texture2D> textures; | ||||
|   for (unsigned int i = 0; i < material->GetTextureCount(type); ++i) { | ||||
|     aiString path; | ||||
|     material->GetTexture(type, i, &path); | ||||
|     std::string absolute_path = directory + '/' + path.C_Str(); | ||||
|  | ||||
|     bool skip = false; | ||||
|     for (unsigned int j = 0; j < loaded_textures.size(); ++j) { | ||||
|       if (std::strcmp(loaded_textures[j].filename, absolute_path.c_str()) == 0) { | ||||
|         textures.push_back(loaded_textures[j]); | ||||
|         skip = true; | ||||
|         break; | ||||
|       } | ||||
|     } | ||||
|  | ||||
|     if (!skip) { | ||||
|       TextureType tex_type = type == aiTextureType_DIFFUSE ? TEXTURE_TYPE_DIFFUSE : TEXTURE_TYPE_SPECULAR; | ||||
|       Texture2D texture = {absolute_path.c_str(), texture_unit++, tex_type}; | ||||
|       textures.push_back(texture); | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   return textures; | ||||
| } | ||||
|   | ||||
		Reference in New Issue
	
	Block a user