From 2f0c5794d26604619a2f661ada8a8ab18a32a3d9 Mon Sep 17 00:00:00 2001 From: Antoine Pilote Date: Sun, 13 Aug 2023 01:07:18 -0400 Subject: [PATCH] Started rendering --- .../resources/Shaders/gbuffer_skinned.shader | 9 +++-- .../Rendering/Buffers/VertexBufferLayout.h | 7 ++++ Nuake/src/Rendering/Mesh/SkinnedMesh.cpp | 11 +++-- .../Rendering/Platforms/OGLRendererAPI.cpp | 9 ++++- Nuake/src/Rendering/SceneRenderer.cpp | 17 ++++++-- Nuake/src/Rendering/Vertex.h | 3 +- Nuake/src/Resource/ModelLoader.cpp | 40 +++++++++++++------ Nuake/src/Resource/ModelLoader.h | 11 +++++ 8 files changed, 81 insertions(+), 26 deletions(-) diff --git a/Editor/resources/Shaders/gbuffer_skinned.shader b/Editor/resources/Shaders/gbuffer_skinned.shader index 37462682..5adc13b9 100644 --- a/Editor/resources/Shaders/gbuffer_skinned.shader +++ b/Editor/resources/Shaders/gbuffer_skinned.shader @@ -33,22 +33,23 @@ void main() vec4 totalPosition = vec4(0.0f); for (int i = 0; i < MAX_BONES_INFLUENCE; i++) { - if (BonesIDs[i] == -1) + if (BoneIDs[i] == -1) { continue; } - if (BonesIDs[i] >= MAX_BONES) + if (BoneIDs[i] >= MAX_BONES) { totalPosition = vec4(VertexPosition, 1.0f); + break; } - vec4 localPositon = u_FinalBonesMatrice[BoneIDs[i]] * vec4(VertexPosition, 1.0f); + vec4 localPosition = vec4(VertexPosition, 1.0f); totalPosition += localPosition * Weights[i]; // vec3 localNormal = mat3(u_FinalBonesMatrice[BoneIDs[i]]) * Normal; } - gl_Position = u_Projection * u_View * u_Model * vec4(totalPosition, 1.0f); + gl_Position = u_Projection * u_View * u_Model * vec4(VertexPosition, 1.0f); } #shader fragment diff --git a/Nuake/src/Rendering/Buffers/VertexBufferLayout.h b/Nuake/src/Rendering/Buffers/VertexBufferLayout.h index 9287d188..4418d517 100644 --- a/Nuake/src/Rendering/Buffers/VertexBufferLayout.h +++ b/Nuake/src/Rendering/Buffers/VertexBufferLayout.h @@ -50,6 +50,13 @@ namespace Nuake { m_Stride += VertexBufferElement::GetSizeOfType(RendererEnum::UINT) * count; } + template<> + void Push(unsigned int count) + { + m_Elements.push_back({ RendererEnum::INT, count, false }); + m_Stride += VertexBufferElement::GetSizeOfType(RendererEnum::INT) * count; + } + template<> void Push(unsigned int count) { diff --git a/Nuake/src/Rendering/Mesh/SkinnedMesh.cpp b/Nuake/src/Rendering/Mesh/SkinnedMesh.cpp index 3874e67c..a3871e5b 100644 --- a/Nuake/src/Rendering/Mesh/SkinnedMesh.cpp +++ b/Nuake/src/Rendering/Mesh/SkinnedMesh.cpp @@ -40,6 +40,11 @@ namespace Nuake return m_Indices; } + std::vector& SkinnedMesh::GetBones() + { + return m_Bones; + } + Ref SkinnedMesh::GetMaterial() inline const { return m_Material; @@ -77,7 +82,7 @@ namespace Nuake { m_VertexArray = CreateScope(); m_VertexArray->Bind(); - m_VertexBuffer = CreateScope(m_Vertices.data(), m_Vertices.size() * sizeof(Vertex)); + m_VertexBuffer = CreateScope(m_Vertices.data(), m_Vertices.size() * sizeof(SkinnedVertex)); m_ElementBuffer = CreateScope(m_Indices.data(), m_Indices.size() * sizeof(unsigned int), RendererEnum::ELEMENT_ARRAY_BUFFER); VertexBufferLayout bufferLayout = VertexBufferLayout(); @@ -86,8 +91,8 @@ namespace Nuake bufferLayout.Push(3); // Normal bufferLayout.Push(3); // Tangent bufferLayout.Push(3); // Bitangent - bufferLayout.Push(4); // BoneIds - bufferLayout.Push(4); // Weights + bufferLayout.Push(1); // BoneIds + bufferLayout.Push(1); // Weights m_VertexArray->AddBuffer(*m_VertexBuffer, bufferLayout); m_VertexArray->Unbind(); diff --git a/Nuake/src/Rendering/Platforms/OGLRendererAPI.cpp b/Nuake/src/Rendering/Platforms/OGLRendererAPI.cpp index abf92dc0..cf04dae0 100644 --- a/Nuake/src/Rendering/Platforms/OGLRendererAPI.cpp +++ b/Nuake/src/Rendering/Platforms/OGLRendererAPI.cpp @@ -70,7 +70,14 @@ namespace Nuake { void OGLRendererAPI::VertexAttribPointer(const unsigned int index, const int size, const RendererEnum type, bool normalized, int stride, const void* pointer) { GLenum glType = GetType(type); - glVertexAttribPointer(index, size, glType, normalized, stride, pointer); + if (glType == GL_INT) + { + glVertexAttribIPointer(index, size, glType, stride, pointer); + } + else + { + glVertexAttribPointer(index, size, glType, normalized, stride, pointer); + } } void OGLRendererAPI::DrawMultiElements(const RendererEnum mode, const int count, const RendererEnum type, const void* const* indices, unsigned int drawCount) diff --git a/Nuake/src/Rendering/SceneRenderer.cpp b/Nuake/src/Rendering/SceneRenderer.cpp index c2623d7c..87f61caa 100644 --- a/Nuake/src/Rendering/SceneRenderer.cpp +++ b/Nuake/src/Rendering/SceneRenderer.cpp @@ -360,6 +360,9 @@ namespace Nuake gBufferSkinnedMeshShader->SetUniformMat4f("u_View", mView); // Skinned Models + const uint32_t entityIdUniformLocation = gBufferSkinnedMeshShader->FindUniformLocation("u_EntityID"); + const uint32_t modelMatrixUniformLocation = gBufferSkinnedMeshShader->FindUniformLocation("u_Model"); + auto skinnedModelView = scene.m_Registry.view(); for (auto e : skinnedModelView) { @@ -369,13 +372,19 @@ namespace Nuake { for (auto& m : mesh.ModelResource->GetMeshes()) { - const uint32_t entityIdUniformLocation = gBufferSkinnedMeshShader->FindUniformLocation("u_EntityID"); - const uint32_t modelMatrixUniformLocation = gBufferSkinnedMeshShader->FindUniformLocation("u_Model"); m->GetMaterial()->Bind(gBufferSkinnedMeshShader); - + + uint32_t boneId = 0; + for (auto& b : m->GetBones()) + { + const std::string boneMatrixUniformName = "u_FinalBonesMatrice[" + std::to_string(boneId) + "]"; + gBufferSkinnedMeshShader->SetUniformMat4f(boneMatrixUniformName, b.Offset); + boneId++; + } + gBufferSkinnedMeshShader->SetUniformMat4f(modelMatrixUniformLocation, transform.GetGlobalTransform()); gBufferSkinnedMeshShader->SetUniform1i(entityIdUniformLocation, (uint32_t)e + 1); - m->Draw(gBufferSkinnedMeshShader, false); + m->Draw(gBufferSkinnedMeshShader, true); } } } diff --git a/Nuake/src/Rendering/Vertex.h b/Nuake/src/Rendering/Vertex.h index ef5aca9a..4e1d39ff 100644 --- a/Nuake/src/Rendering/Vertex.h +++ b/Nuake/src/Rendering/Vertex.h @@ -12,7 +12,7 @@ namespace Nuake Vector3 bitangent; }; - const uint32_t MAX_BONE_INFLUENCE = 4; + const uint32_t MAX_BONE_INFLUENCE = 1; struct SkinnedVertex { Vector3 position; @@ -22,7 +22,6 @@ namespace Nuake Vector3 bitangent; int boneIDs[MAX_BONE_INFLUENCE]; - //weights from each bone float weights[MAX_BONE_INFLUENCE]; }; diff --git a/Nuake/src/Resource/ModelLoader.cpp b/Nuake/src/Resource/ModelLoader.cpp index a61e71ea..3f53e986 100644 --- a/Nuake/src/Resource/ModelLoader.cpp +++ b/Nuake/src/Resource/ModelLoader.cpp @@ -116,10 +116,10 @@ namespace Nuake Ref ModelLoader::ProcessSkinnedMesh(aiMesh* node, const aiScene* scene) { - auto vertices = ProcessSkinnedVertices(node); - auto indices = ProcessIndices(node); - auto material = ProcessMaterials(scene, node); - auto bones = std::vector(); + auto& vertices = ProcessSkinnedVertices(node); + auto& indices = ProcessIndices(node); + auto& material = ProcessMaterials(scene, node); + auto& bones = std::vector(); if (node->HasBones()) { for (uint32_t i = 0; i < node->mNumBones; i++) @@ -128,15 +128,28 @@ namespace Nuake const std::string& boneName = bone->mName.C_Str(); const auto& boneMatrix = bone->mOffsetMatrix; - for (uint32_t j = 0; j < bone->mNumWeights; j++) + Bone newBone; + newBone.Name = boneName; + newBone.Offset = ConvertMatrixToGLMFormat(bone->mOffsetMatrix); + + const uint32_t numWeight = bone->mNumWeights; + newBone.VertexWeights.reserve(numWeight); + for (uint32_t j = 0; j < numWeight; j++) { aiVertexWeight vertexWeight = bone->mWeights[j]; + const uint32_t vertexWeightVertexId = vertexWeight.mVertexId; + vertices[vertexWeightVertexId].boneIDs[j] = i; + vertices[vertexWeightVertexId].weights[j] = vertexWeight.mWeight; + BoneVertexWeight boneVertexWeight + { + vertexWeightVertexId, + vertexWeight.mWeight + }; - const float weigth = vertexWeight.mWeight; - uint32_t vertexId = vertexWeight.mVertexId; - - vertices[vertexId].boneIDs[j] = i; + newBone.VertexWeights.push_back(std::move(boneVertexWeight)); } + + bones.push_back(std::move(newBone)); } } else @@ -145,8 +158,6 @@ namespace Nuake } // Fill in the bones in the vertices - - Ref mesh = CreateRef(); mesh->AddSurface(vertices, indices, bones); mesh->SetMaterial(material); @@ -245,7 +256,12 @@ namespace Nuake for (uint32_t i = 0; i < mesh->mNumVertices; i++) { SkinnedVertex vertex; - + for (int w = 0; w < MAX_BONE_INFLUENCE; w++) + { + vertex.boneIDs[w] = -1; + vertex.weights[w] = 0.0f; + } + Vector3 current; // Position diff --git a/Nuake/src/Resource/ModelLoader.h b/Nuake/src/Resource/ModelLoader.h index 888c63f7..a80adf61 100644 --- a/Nuake/src/Resource/ModelLoader.h +++ b/Nuake/src/Resource/ModelLoader.h @@ -45,5 +45,16 @@ namespace Nuake void ProcessSkinnedNode(aiNode* node, const aiScene* scene); Ref ProcessSkinnedMesh(aiMesh* node, const aiScene* scene); std::vector ProcessSkinnedVertices(aiMesh* mesh); + + static inline Matrix4 ConvertMatrixToGLMFormat(const aiMatrix4x4& from) + { + Matrix4 to; + //the a,b,c,d in assimp is the row ; the 1,2,3,4 is the column + to[0][0] = from.a1; to[1][0] = from.a2; to[2][0] = from.a3; to[3][0] = from.a4; + to[0][1] = from.b1; to[1][1] = from.b2; to[2][1] = from.b3; to[3][1] = from.b4; + to[0][2] = from.c1; to[1][2] = from.c2; to[2][2] = from.c3; to[3][2] = from.c4; + to[0][3] = from.d1; to[1][3] = from.d2; to[2][3] = from.d3; to[3][3] = from.d4; + return to; + } }; } \ No newline at end of file