66#include " shader.h"
77#include " vertex_buffer.h"
88#include " index_buffer.h"
9+ #include " libs/stb_image.h"
910
10- struct Material {
11+ struct BMFMaterial {
1112 glm::vec3 diffuse;
1213 glm::vec3 specular;
1314 glm::vec3 emissive;
1415 float shininess;
1516};
1617
18+ struct Material {
19+ BMFMaterial material;
20+ GLuint diffuseMap;
21+ GLuint normalMap;
22+ };
23+
1724class Mesh {
1825public:
1926 Mesh (std::vector<Vertex>& vertices, uint64 numVertices, std::vector<uint32>& indices, uint64 numIndices, Material material, Shader* shader) {
@@ -28,6 +35,7 @@ class Mesh {
2835 specularLocation = GLCALL (glGetUniformLocation (shader->getShaderId (), " u_material.specular" ));
2936 emissiveLocation = GLCALL (glGetUniformLocation (shader->getShaderId (), " u_material.emissive" ));
3037 shininessLocation = GLCALL (glGetUniformLocation (shader->getShaderId (), " u_material.shininess" ));
38+ diffuseMapLocation = GLCALL (glGetUniformLocation (shader->getShaderId (), " u_diffuse_map" ));
3139 }
3240 ~Mesh () {
3341 delete vertexBuffer;
@@ -36,10 +44,12 @@ class Mesh {
3644 inline void render () {
3745 vertexBuffer->bind ();
3846 indexBuffer->bind ();
39- glUniform3fv (diffuseLocation, 1 , (float *)&material.diffuse .data );
40- glUniform3fv (specularLocation, 1 , (float *)&material.specular .data );
41- glUniform3fv (emissiveLocation, 1 , (float *)&material.emissive .data );
42- glUniform1f (shininessLocation, material.shininess );
47+ glUniform3fv (diffuseLocation, 1 , (float *)&material.material .diffuse .data );
48+ glUniform3fv (specularLocation, 1 , (float *)&material.material .specular .data );
49+ glUniform3fv (emissiveLocation, 1 , (float *)&material.material .emissive .data );
50+ glUniform1f (shininessLocation, material.material .shininess );
51+ GLCALL (glBindTexture (GL_TEXTURE_2D, material.diffuseMap ));
52+ GLCALL (glUniform1i (diffuseMapLocation, 0 ));
4353 GLCALL (glDrawElements (GL_TRIANGLES, numIndices, GL_UNSIGNED_INT, 0 ));
4454 }
4555private:
@@ -52,28 +62,97 @@ class Mesh {
5262 int specularLocation;
5363 int emissiveLocation;
5464 int shininessLocation;
65+ int diffuseMapLocation;
5566};
5667
5768class Model {
5869public:
5970 void init (const char * filename, Shader* shader) {
6071 uint64 numMeshes = 0 ;
72+ uint64 numMaterials = 0 ;
6173 std::ifstream input = std::ifstream (filename, std::ios::in | std::ios::binary);
6274 if (!input.is_open ()) {
6375 std::cout << " File not found" << std::endl;
6476 return ;
6577 }
6678
79+ // Materials
80+ input.read ((char *)&numMaterials, sizeof (uint64));
81+ for (uint64 i = 0 ; i < numMaterials; i++) {
82+ Material material = {};
83+ input.read ((char *)&material, sizeof (BMFMaterial));
84+
85+ uint64 diffuseMapNameLength = 0 ;
86+ input.read ((char *)&diffuseMapNameLength, sizeof (uint64));
87+ std::string diffuseMapName (diffuseMapNameLength, ' \0 ' );
88+ input.read ((char *)&diffuseMapName[0 ], diffuseMapNameLength);
89+
90+ uint64 normalMapNameLength = 0 ;
91+ input.read ((char *)&normalMapNameLength, sizeof (uint64));
92+ std::string normalMapName (normalMapNameLength, ' \0 ' );
93+ input.read ((char *)&normalMapName[0 ], normalMapNameLength);
94+
95+ assert (diffuseMapNameLength > 0 );
96+ assert (normalMapNameLength > 0 );
97+
98+ int32 textureWidth = 0 ;
99+ int32 textureHeight = 0 ;
100+ int32 bitsPerPixel = 0 ;
101+ GLCALL (glGenTextures (2 , &material.diffuseMap ));
102+ stbi_set_flip_vertically_on_load (true );
103+ {
104+ auto textureBuffer = stbi_load (diffuseMapName.c_str (), &textureWidth, &textureHeight, &bitsPerPixel, 4 );
105+ assert (textureBuffer);
106+ assert (material.diffuseMap );
107+
108+ GLCALL (glBindTexture (GL_TEXTURE_2D, material.diffuseMap ));
109+
110+ GLCALL (glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR));
111+ GLCALL (glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR));
112+ GLCALL (glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE));
113+ GLCALL (glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE));
114+
115+ GLCALL (glTexImage2D (GL_TEXTURE_2D, 0 , GL_RGBA8, textureWidth, textureHeight, 0 , GL_RGBA, GL_UNSIGNED_BYTE, textureBuffer));
116+
117+ if (textureBuffer) {
118+ stbi_image_free (textureBuffer);
119+ }
120+ }
121+
122+ {
123+ auto textureBuffer = stbi_load (normalMapName.c_str (), &textureWidth, &textureHeight, &bitsPerPixel, 4 );
124+ assert (textureBuffer);
125+ assert (material.normalMap );
126+
127+ GLCALL (glBindTexture (GL_TEXTURE_2D, material.normalMap ));
128+
129+ GLCALL (glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR));
130+ GLCALL (glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR));
131+ GLCALL (glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE));
132+ GLCALL (glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE));
133+
134+ GLCALL (glTexImage2D (GL_TEXTURE_2D, 0 , GL_RGBA8, textureWidth, textureHeight, 0 , GL_RGBA, GL_UNSIGNED_BYTE, textureBuffer));
135+
136+ if (textureBuffer) {
137+ stbi_image_free (textureBuffer);
138+ }
139+ }
140+
141+ GLCALL (glBindTexture (GL_TEXTURE_2D, 0 ));
142+ materials.push_back (material);
143+ }
144+
145+ // Meshes
67146 input.read ((char *)&numMeshes, sizeof (uint64));
68147
69148 for (uint64 i = 0 ; i < numMeshes; i++) {
70- Material material;
71149 std::vector<Vertex> vertices;
72150 uint64 numVertices = 0 ;
73151 std::vector<uint32> indices;
74152 uint64 numIndices = 0 ;
153+ uint64 materialIndex = 0 ;
75154
76- input.read ((char *)&material , sizeof (Material ));
155+ input.read ((char *)&materialIndex , sizeof (uint64 ));
77156 input.read ((char *)&numVertices, sizeof (uint64));
78157 input.read ((char *)&numIndices, sizeof (uint64));
79158
@@ -85,6 +164,8 @@ class Model {
85164 input.read ((char *)&vertex.normal .x , sizeof (float ));
86165 input.read ((char *)&vertex.normal .y , sizeof (float ));
87166 input.read ((char *)&vertex.normal .z , sizeof (float ));
167+ input.read ((char *)&vertex.textureCoord .x , sizeof (float ));
168+ input.read ((char *)&vertex.textureCoord .y , sizeof (float ));
88169 vertices.push_back (vertex);
89170 }
90171 for (uint64 i = 0 ; i < numIndices; i++) {
@@ -93,7 +174,7 @@ class Model {
93174 indices.push_back (index);
94175 }
95176
96- Mesh* mesh = new Mesh (vertices, numVertices, indices, numIndices, material , shader);
177+ Mesh* mesh = new Mesh (vertices, numVertices, indices, numIndices, materials[materialIndex] , shader);
97178 meshes.push_back (mesh);
98179 }
99180 }
@@ -111,4 +192,5 @@ class Model {
111192 }
112193private:
113194 std::vector<Mesh*> meshes;
195+ std::vector<Material> materials;
114196};
0 commit comments