void LoadVertices(const aiMesh &inMesh, std::vector<Vertex> &convertedVertices, BoundingSphere &inBoundingSphere) { for (unsigned int i = 0; i < inMesh.mNumVertices; ++i) { Vertex newVertex; float vertexLength = inMesh.mVertices[i].Length(); if (vertexLength > inBoundingSphere.mRadius) { inBoundingSphere.mRadius = vertexLength; } newVertex.LoadAiVector3D(newVertex.Pos, inMesh.mVertices[i]); if (inMesh.HasNormals()) { newVertex.LoadAiVector3D(newVertex.Normal, inMesh.mNormals[i]); } if (inMesh.HasTextureCoords(0)) { newVertex.LoadAiVector3D(newVertex.Tex0, inMesh.mTextureCoords[0][i]); newVertex.Tex0.y = 1.0 - newVertex.Tex0.y; } if (inMesh.HasTangentsAndBitangents()) { newVertex.LoadAiVector3D(newVertex.Tangent, inMesh.mTangents[i]); //newVertex.Tangent.z = -newVertex.Tangent.z; newVertex.LoadAiVector3D(newVertex.Bitangent, inMesh.mBitangents[i]); } convertedVertices.push_back(newVertex); } }
void Material::createVertexBuffer(const aiMesh& aiMesh, VertexBuffer& vertexBuffer) const { assert(aiMesh.HasPositions()); assert(aiMesh.HasNormals()); assert(aiMesh.HasTangentsAndBitangents()); assert(aiMesh.HasTextureCoords(0)); vertexBuffer.VertexCount = aiMesh.mNumVertices; const unsigned int vertexDataSize = vertexBuffer.VertexCount * 3; const unsigned int uvDataSize = vertexBuffer.VertexCount * aiMesh.mNumUVComponents[0]; float* const positionData = new float[vertexDataSize]; float* const normalData = new float[vertexDataSize]; float* const tangentData = new float[vertexDataSize]; float* const bitangentData = new float[vertexDataSize]; float* const uvData = new float[uvDataSize]; unsigned int index = 0, uvIndex = 0; for (unsigned int i=0; i < aiMesh.mNumVertices; ++i, index += 3, uvIndex += aiMesh.mNumUVComponents[0]) { positionData[index] = aiMesh.mVertices[i].x; positionData[index + 1] = aiMesh.mVertices[i].y; positionData[index + 2] = aiMesh.mVertices[i].z; normalData[index] = aiMesh.mNormals[i].x; normalData[index + 1] = aiMesh.mNormals[i].y; normalData[index + 2] = aiMesh.mNormals[i].z; tangentData[index] = aiMesh.mTangents[i].x; tangentData[index + 1] = aiMesh.mTangents[i].y; tangentData[index + 2] = aiMesh.mTangents[i].z; bitangentData[index] = aiMesh.mBitangents[i].x; bitangentData[index + 1] = aiMesh.mBitangents[i].y; bitangentData[index + 2] = aiMesh.mBitangents[i].z; uvData[uvIndex] = aiMesh.mTextureCoords[0][i].x; if (aiMesh.mNumUVComponents[0] > 1) { uvData[uvIndex + 1] = aiMesh.mTextureCoords[0][i].y; if (aiMesh.mNumUVComponents[0] > 2) { uvData[uvIndex + 2] = aiMesh.mTextureCoords[0][i].z; } } } vertexBuffer.VBOs.resize(5); glGenBuffers(5, &vertexBuffer.VBOs[0]); GLuint positionVBO = vertexBuffer.VBOs[0]; glBindBuffer(GL_ARRAY_BUFFER, positionVBO); glBufferData(GL_ARRAY_BUFFER, vertexDataSize * sizeof(positionData[0]), positionData, GL_STATIC_DRAW); GLuint normalVBO = vertexBuffer.VBOs[1]; glBindBuffer(GL_ARRAY_BUFFER, normalVBO); glBufferData(GL_ARRAY_BUFFER, vertexDataSize * sizeof(normalData[0]), normalData, GL_STATIC_DRAW); GLuint tangentVBO = vertexBuffer.VBOs[2]; glBindBuffer(GL_ARRAY_BUFFER, tangentVBO); glBufferData(GL_ARRAY_BUFFER, vertexDataSize * sizeof(tangentData[0]), tangentData, GL_STATIC_DRAW); GLuint bitangentVBO = vertexBuffer.VBOs[2]; glBindBuffer(GL_ARRAY_BUFFER, bitangentVBO); glBufferData(GL_ARRAY_BUFFER, vertexDataSize * sizeof(bitangentData[0]), bitangentData, GL_STATIC_DRAW); GLuint texCoordVBO = vertexBuffer.VBOs[3]; glBindBuffer(GL_ARRAY_BUFFER, texCoordVBO); glBufferData(GL_ARRAY_BUFFER, uvDataSize * sizeof(uvData[0]), uvData, GL_STATIC_DRAW); glGenVertexArrays(1, &vertexBuffer.VAO); glBindVertexArray(vertexBuffer.VAO); for (unsigned int i=0; i < vertexBuffer.VBOs.size(); ++i) { glEnableVertexAttribArray(i); } glBindBuffer(GL_ARRAY_BUFFER, positionVBO); glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, nullptr); glBindBuffer(GL_ARRAY_BUFFER, texCoordVBO); glVertexAttribPointer(1, aiMesh.mNumUVComponents[0], GL_FLOAT, GL_FALSE, 0, nullptr); glBindBuffer(GL_ARRAY_BUFFER, normalVBO); glVertexAttribPointer(2, 3, GL_FLOAT, GL_FALSE, 0, nullptr); glBindBuffer(GL_ARRAY_BUFFER, tangentVBO); glVertexAttribPointer(3, 3, GL_FLOAT, GL_FALSE, 0, nullptr); glBindBuffer(GL_ARRAY_BUFFER, bitangentVBO); glVertexAttribPointer(4, 3, GL_FLOAT, GL_FALSE, 0, nullptr); delete[] positionData; delete[] normalData; delete[] tangentData; delete[] bitangentData; delete[] uvData; }
void bc_mesh_loader::convert_aimesh(game::bc_render_system& p_render_system, core::bc_content_loading_context& p_context, const aiScene& p_aiscene, const aiNode& p_ainode, const aiMesh& p_aimesh, game::bc_mesh_part_data& p_mesh, game::bc_render_state_ptr& p_mesh_render_state) { auto& l_device = p_render_system.get_device(); core::bc_vector_movale< game::bc_vertex_pos_tex_nor_tan > l_vertices; core::bc_vector_movale< bcBYTE > l_indices; graphic::bc_graphic_resource_configure l_resource_configure; graphic::bc_buffer_ptr l_vertex_buffer; graphic::bc_buffer_ptr l_index_buffer; bcSIZE l_index_count = 0; graphic::bc_buffer_ptr l_cbuffer; game::bc_render_material_description l_material; bool l_need_32bit_indices = p_aimesh.mNumFaces * 3 > std::numeric_limits< bcUINT16 >::max(); bool l_has_texcoord = p_aimesh.HasTextureCoords(0); bool l_has_normal = p_aimesh.HasNormals(); bool l_has_tangent = p_aimesh.HasTangentsAndBitangents(); l_vertices.reserve(p_aimesh.mNumVertices); l_indices.reserve(p_aimesh.mNumFaces * 3 * (l_need_32bit_indices ? static_cast< bcINT >(game::bc_index_type::i32bit) : static_cast< bcINT >(game::bc_index_type::i16bit))); for (bcUINT l_vertex = 0; l_vertex < p_aimesh.mNumVertices; ++l_vertex) { game::bc_vertex_pos_tex_nor_tan l_vertex_layout; auto* l_aivertex = &p_aimesh.mVertices[l_vertex]; auto* l_aitexcoord = l_has_texcoord ? &p_aimesh.mTextureCoords[0][l_vertex] : nullptr; auto* l_ainoraml = l_has_normal ? &p_aimesh.mNormals[l_vertex] : nullptr; auto* l_aitangent = l_has_tangent ? &p_aimesh.mTangents[l_vertex] : nullptr; l_vertex_layout.m_position = core::bc_vector3f(l_aivertex->x, l_aivertex->y, l_aivertex->z); l_vertex_layout.m_texcoord = l_aitexcoord ? core::bc_vector2f(l_aitexcoord->x, l_aitexcoord->y) : core::bc_vector2f(); l_vertex_layout.m_normal = l_ainoraml ? core::bc_vector3f(l_ainoraml->x, l_ainoraml->y, l_ainoraml->z) : core::bc_vector3f(); l_vertex_layout.m_tangent = l_aitangent ? core::bc_vector3f(l_aitangent->x, l_aitangent->y, l_aitangent->z) : core::bc_vector3f(); l_vertices.push_back(l_vertex_layout); } bcUINT16* l_16bit_indices = reinterpret_cast< bcUINT16* >(l_indices.data()); bcUINT32* l_32bit_indices = reinterpret_cast< bcUINT32* >(l_indices.data()); for (bcUINT l_face_index = 0; l_face_index < p_aimesh.mNumFaces; ++l_face_index) { for (bcBYTE l_index = 0; l_index < 3; ++l_index) { if (l_need_32bit_indices) { *l_32bit_indices = static_cast< bcUINT32 >(p_aimesh.mFaces[l_face_index].mIndices[l_index]); ++l_32bit_indices; } else { *l_16bit_indices = static_cast< bcUINT16 >(p_aimesh.mFaces[l_face_index].mIndices[l_index]); ++l_16bit_indices; } ++l_index_count; } } auto l_vertex_buffer_config = l_resource_configure .as_resource() .as_buffer ( l_vertices.size(), sizeof(game::bc_vertex_pos_tex_nor_tan), graphic::bc_resource_usage::gpu_r, graphic::bc_resource_view_type::none, false ).as_vertex_buffer(); auto l_index_buffer_config = l_resource_configure .as_resource() .as_buffer ( l_index_count, l_need_32bit_indices ? static_cast< bcUINT32 >(game::bc_index_type::i32bit) : static_cast< bcUINT32 >(game::bc_index_type::i16bit), graphic::bc_resource_usage::gpu_r, graphic::bc_resource_view_type::none, false ).as_index_buffer(); auto l_vertex_buffer_data = graphic::bc_subresource_data(l_vertices.data(), 0, 0); auto l_index_buffer_data = graphic::bc_subresource_data(l_indices.data(), 0, 0); l_vertex_buffer = l_device.create_buffer(l_vertex_buffer_config, &l_vertex_buffer_data); l_index_buffer = l_device.create_buffer(l_index_buffer_config, &l_index_buffer_data); convert_aimaterial(p_context, *p_aiscene.mMaterials[p_aimesh.mMaterialIndex], l_material); auto l_material_name = core::bc_to_exclusive_string(core::bc_path(p_context.m_file->get_path().c_str()).get_filename()) + "." + p_aimesh.mName.C_Str(); auto l_material_ptr = p_render_system.get_material_manager().store_material ( p_context.get_allocator_alloc_type(), l_material_name.c_str(), std::move(l_material) ); p_mesh.m_name = p_aimesh.mName.C_Str(); p_mesh.m_material = std::move(l_material_ptr); p_mesh.m_vertices = std::move(l_vertices); p_mesh.m_indices = std::move(l_indices); p_mesh.m_vertex_buffer = std::move(l_vertex_buffer); p_mesh.m_index_buffer = std::move(l_index_buffer); p_mesh.m_bound_box = game::bc_extract_bound_box_from_points(physics::bc_bounded_strided_typed_data< core::bc_vector3f > ( &p_mesh.m_vertices[0].m_position, sizeof(game::bc_vertex_pos_tex_nor_tan), p_mesh.m_vertices.size() )); p_mesh_render_state = p_render_system.create_render_state ( graphic::bc_primitive::trianglelist, p_mesh.m_vertex_buffer.get(), sizeof(game::bc_vertex_pos_tex_nor_tan), 0, p_mesh.m_index_buffer.get(), l_need_32bit_indices ? game::bc_index_type::i32bit : game::bc_index_type::i16bit, l_index_count, 0, { graphic::bc_resource_view_parameter(0, graphic::bc_shader_type::pixel, p_mesh.m_material->get_diffuse_map_view()), graphic::bc_resource_view_parameter(0, graphic::bc_shader_type::pixel, p_mesh.m_material->get_normal_map_view()), graphic::bc_resource_view_parameter(0, graphic::bc_shader_type::pixel, p_mesh.m_material->get_specular_map_view()), }, { p_render_system.get_per_object_cbuffer(), graphic::bc_constant_buffer_parameter(1, graphic::bc_shader_type::pixel, p_mesh.m_material->get_parameters_cbuffer()) } ); }