diff --git a/src/mesh.cpp b/src/mesh.cpp index a12086a..48d59f2 100644 --- a/src/mesh.cpp +++ b/src/mesh.cpp @@ -38,22 +38,31 @@ meLoadFromFile(const char* filename) } meMeshInfo* mesh = (meMeshInfo*) std::calloc(1, sizeof(meMeshInfo)); - // TODO: using hard model transform for now + // TODO: using hard coded model transform for now mesh->model_transform = glm::scale(glm::mat4(1), glm::vec3(100, 100, 100)); // allocate buffers for vertex and index data from mesh mesh->num_vertices = scene->mMeshes[0]->mNumVertices; mesh->vertices = (glm::vec3 *) std::calloc(mesh->num_vertices, sizeof(glm::vec3)); + mesh->normals = (glm::vec3 *) std::calloc(mesh->num_vertices, sizeof(glm::vec3)); mesh->num_indices = scene->mMeshes[0]->mNumFaces * 3; // NOTE: assume 3 vertices per face mesh->indices = (uint *) std::calloc(mesh->num_indices, sizeof(uint)); - // copy vertices + // copy vertices and normals for (uint i = 0; i < mesh->num_vertices; i++) { aiVector3D v_in = scene->mMeshes[0]->mVertices[i]; glm::vec3& v_out = mesh->vertices[i]; v_out.x = v_in.x; v_out.y = v_in.y; v_out.z = v_in.z; + + if (scene->mMeshes[0]->HasNormals()) { + aiVector3D n_in = scene->mMeshes[0]->mNormals[i]; + glm::vec3& n_out = mesh->normals[i]; + n_out.x = n_in.x; + n_out.y = n_in.y; + n_out.z = n_in.z; + } } // copy indices @@ -61,7 +70,6 @@ meLoadFromFile(const char* filename) for (uint j = 0; j < 3; j++) mesh->indices[i * 3 + j] = scene->mMeshes[0]->mFaces[i].mIndices[j]; -#if 1 // material aiMaterial* mat = scene->mMaterials[0]; aiColor3D color(0.f, 0.f, 0.f); @@ -72,7 +80,6 @@ meLoadFromFile(const char* filename) mesh->diffuse_color.g = color.g; mesh->diffuse_color.b = color.b; } -#endif // free memeory from assimp aiReleaseImport(scene); @@ -84,6 +91,8 @@ meFreeMesh(meMeshInfo* mesh) { std::free(mesh->vertices); mesh->vertices = nullptr; + std::free(mesh->normals); + mesh->normals = nullptr; std::free(mesh->indices); mesh->indices = nullptr; std::free(mesh); diff --git a/src/mesh.h b/src/mesh.h index 4741f39..78aa1b0 100644 --- a/src/mesh.h +++ b/src/mesh.h @@ -11,6 +11,7 @@ struct meMeshInfo glm::mat4 model_transform; uint num_vertices = 0; glm::vec3* vertices = nullptr; + glm::vec3* normals = nullptr; uint num_indices = 0; uint* indices = nullptr; glm::vec3 diffuse_color; diff --git a/src/render_group.cpp b/src/render_group.cpp index d64337a..d08cef6 100644 --- a/src/render_group.cpp +++ b/src/render_group.cpp @@ -122,25 +122,38 @@ bool rgInitEntity(gl_render_group* rg, Entity* e) { bool retVal = true; + bool useNormals = rg->use_normals = (e->mesh->normals != nullptr); - uint entity_buf_len = e->mesh->num_vertices * 3; - GLfloat* entity_buf = (GLfloat*) std::calloc(entity_buf_len, sizeof(GLfloat)); - GLfloat* entity_color_buf = (GLfloat*) std::calloc(entity_buf_len, sizeof(GLfloat)); + uint vertex_buf_len = e->mesh->num_vertices * 3; + GLfloat* vertex_buf = (GLfloat*) std::calloc(vertex_buf_len, sizeof(GLfloat)); + GLfloat* color_buf = (GLfloat*) std::calloc(vertex_buf_len, sizeof(GLfloat)); + GLfloat* normal_buf; + if (useNormals) + normal_buf = (GLfloat*) std::calloc(vertex_buf_len, sizeof(GLfloat)); - // dump vertices into temporary buffer + // dump vertices, colors, and normals into temporary buffers uint vertex_index = 0; uint vertex_prop_index = 0; - for (uint i = 0; i < entity_buf_len; i++) { + for (uint i = 0; i < vertex_buf_len; i++) { const glm::vec3& vertex = e->mesh->vertices[vertex_index]; + const glm::vec3& normal = e->mesh->normals[vertex_index]; switch (vertex_prop_index) { - case 0: entity_buf[i] = vertex.x; break; - case 1: entity_buf[i] = vertex.y; break; - case 2: entity_buf[i] = vertex.z; break; + case 0: vertex_buf[i] = vertex.x; break; + case 1: vertex_buf[i] = vertex.y; break; + case 2: vertex_buf[i] = vertex.z; break; } - entity_color_buf[i] = e->mesh->diffuse_color[vertex_prop_index]; + if (useNormals) { + switch (vertex_prop_index) { + case 0: normal_buf[i] = normal.x; break; + case 1: normal_buf[i] = normal.y; break; + case 2: normal_buf[i] = normal.z; break; + } + } + + color_buf[i] = e->mesh->diffuse_color[vertex_prop_index]; vertex_prop_index++; if (vertex_prop_index == 3) { @@ -149,12 +162,19 @@ rgInitEntity(gl_render_group* rg, Entity* e) } } - rgInitGLBufferObject(&rg->vertex_buffer, entity_buf_len, - GL_DYNAMIC_DRAW, GL_ARRAY_BUFFER, entity_buf); + // send vertex and color data to OpenGL + rgInitGLBufferObject(&rg->vertex_buffer, vertex_buf_len, + GL_DYNAMIC_DRAW, GL_ARRAY_BUFFER, vertex_buf); + + rgInitGLBufferObject(&rg->color_buffer, vertex_buf_len, + GL_STATIC_DRAW, GL_ARRAY_BUFFER, color_buf); - rgInitGLBufferObject(&rg->color_buffer, entity_buf_len, - GL_STATIC_DRAW, GL_ARRAY_BUFFER, entity_color_buf); + if (useNormals) { + rgInitGLBufferObject(&rg->vertex_normals, vertex_buf_len, + GL_STATIC_DRAW, GL_ARRAY_BUFFER, normal_buf); + } + // TODO: combine this somehow with rgInitGLBufferObject() // dump indices into temp buffer gl_index_buffer index_buffer; index_buffer.buffer_len = e->mesh->num_indices; @@ -170,9 +190,11 @@ rgInitEntity(gl_render_group* rg, Entity* e) glBufferData(GL_ELEMENT_ARRAY_BUFFER, e->mesh->num_indices * sizeof(uint), rg->index_buffer.indices, GL_STATIC_DRAW); - std::free(entity_buf); - std::free(entity_color_buf); - entity_buf = entity_color_buf = nullptr; + // free temp buffers + std::free(vertex_buf); + if (useNormals) std::free(normal_buf); + std::free(color_buf); + vertex_buf = normal_buf = color_buf = nullptr; return retVal; } @@ -240,6 +262,13 @@ rgDrawIndexed(gl_render_group* rg, GLenum draw_mode, glm::mat4 model_matrix, glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 0, (void*) 0); } + // 3rd attribe buffer : normals + if (rg->use_normals) { + glEnableVertexAttribArray(2); + glBindBuffer(GL_ARRAY_BUFFER, rg->vertex_normals.buffer_id); + glVertexAttribPointer(2, 3, GL_FLOAT, GL_FALSE, 0, (void*) 0); + } + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, rg->index_buffer.buffer_id); // draw @@ -250,6 +279,8 @@ rgDrawIndexed(gl_render_group* rg, GLenum draw_mode, glm::mat4 model_matrix, glDisableVertexAttribArray(0); if (rg->color_buffer.buffer) glDisableVertexAttribArray(1); + if (rg->use_normals) + glDisableVertexAttribArray(2); } void diff --git a/src/render_group.h b/src/render_group.h index 0d18bd6..a91562f 100644 --- a/src/render_group.h +++ b/src/render_group.h @@ -20,8 +20,8 @@ struct gl_index_buffer struct gl_render_group { - // NOTE: For now the renderFrame function will assume these are the same size gl_buffer vertex_buffer; + gl_buffer vertex_normals; gl_buffer color_buffer; gl_index_buffer index_buffer; GLuint program_id = 0; @@ -29,6 +29,7 @@ struct gl_render_group GLuint view_matrix_id = 0; GLuint projection_matrix_id = 0; GLuint vertex_array_id = 0; + bool use_normals = false; }; typedef struct gl_buffer gl_buffer; diff --git a/src/renderer.cpp b/src/renderer.cpp index 9b02a5a..2718fff 100644 --- a/src/renderer.cpp +++ b/src/renderer.cpp @@ -426,7 +426,6 @@ createScene(std::vector* hexes, Entity* entities, uint32 entity_count) GL_STATIC_DRAW, GL_ARRAY_BUFFER, line_buf); // free temporary buffers - // TODO: temp buffers won't be freed if exit early is hit std::free(vbuf); std::free(cbuf); std::free(line_buf); @@ -437,6 +436,8 @@ createScene(std::vector* hexes, Entity* entities, uint32 entity_count) rgInitGLBufferObject(&g_debug_render_group->vertex_buffer, len, GL_DYNAMIC_DRAW, GL_ARRAY_BUFFER, 0); + // entities + for (uint i = 0; i < entity_count; i++) rgInitEntity(g_entity_render_group, &entities[i]);