diff --git a/include/Render/RenderMisc.h b/include/Render/RenderMisc.h index 402672b..e74a8ec 100644 --- a/include/Render/RenderMisc.h +++ b/include/Render/RenderMisc.h @@ -55,12 +55,18 @@ namespace SE std::vector PositionData; std::vector TexCoordData; std::vector NormalData; + std::vector TangentData; + std::vector BitangentData; std::shared_ptr vao; std::shared_ptr positionVBO; std::shared_ptr texCoordVBO; std::shared_ptr normalVBO; + std::shared_ptr tangentVBO; + std::shared_ptr bitangentVBO; void RefreshVBO(); + + void CalcTangentBitangent(); }; struct T2DQuad diff --git a/src/ModelManager/ModelManager.cpp b/src/ModelManager/ModelManager.cpp index df605cd..53dbf12 100644 --- a/src/ModelManager/ModelManager.cpp +++ b/src/ModelManager/ModelManager.cpp @@ -121,6 +121,8 @@ bool TLiteModel::LoadModel(const std::string& s) vertexDataStruct.TexCoordData = res.TexCoordArr; vertexDataStruct.NormalData = res.NormalArr; + vertexDataStruct.CalcTangentBitangent(); + vertexDataStruct.RefreshVBO(); /* TriangleList.Data.Vec3CoordArr[CONST_STRING_POSITION_ATTRIB] = res.VertexArr; @@ -239,11 +241,14 @@ void TLiteModel::DrawVBO() EnableVertexAttribArray("vPosition"); EnableVertexAttribArray("vTexCoord"); EnableVertexAttribArray("vNormal"); - + EnableVertexAttribArray("vTangent"); + EnableVertexAttribArray("vBitangent"); //Renderer->DrawTriangleList(TriangleList); DrawVertexDataStruct(vertexDataStruct); + DisableVertexAttribArray("vBitangent"); + DisableVertexAttribArray("vTangent"); DisableVertexAttribArray("vNormal"); DisableVertexAttribArray("vTexCoord"); DisableVertexAttribArray("vPosition"); @@ -256,8 +261,6 @@ void TLiteModel::DrawVBO() } - - void TLiteModel::MoveModel(const vec3& v) { for (cardinal i = 0; i < TriangleCount * 3; i++) @@ -274,6 +277,8 @@ void TLiteModel::RotateModel(const mat3& r) { vertexDataStruct.PositionData[i] = r * vertexDataStruct.PositionData[i]; vertexDataStruct.NormalData[i] = r * vertexDataStruct.NormalData[i]; + vertexDataStruct.TangentData[i] = r * vertexDataStruct.TangentData[i]; + vertexDataStruct.BitangentData[i] = r * vertexDataStruct.BitangentData[i]; //TriangleList.Data.Vec3CoordArr[CONST_STRING_POSITION_ATTRIB][i] = r * TriangleList.Data.Vec3CoordArr[CONST_STRING_POSITION_ATTRIB][i]; //TriangleList.Data.Vec3CoordArr[CONST_STRING_NORMAL_ATTRIB][i] = r * TriangleList.Data.Vec3CoordArr[CONST_STRING_NORMAL_ATTRIB][i]; //TriangleList.Data.Vec3CoordArr[CONST_STRING_TANGENT_ATTRIB][i] = r * TriangleList.Data.Vec3CoordArr[CONST_STRING_TANGENT_ATTRIB][i]; diff --git a/src/Render/RenderMisc.cpp b/src/Render/RenderMisc.cpp index cfda087..9758cca 100644 --- a/src/Render/RenderMisc.cpp +++ b/src/Render/RenderMisc.cpp @@ -79,6 +79,70 @@ namespace SE } + if (TangentData.size() > 0) + { + if (!tangentVBO) + { + tangentVBO = std::make_shared(); + } + + glBindBuffer(GL_ARRAY_BUFFER, tangentVBO->getBuffer()); + + glBufferData(GL_ARRAY_BUFFER, TangentData.size() * 12, &TangentData[0], GL_STATIC_DRAW); + + } + + if (BitangentData.size() > 0) + { + if (!bitangentVBO) + { + bitangentVBO = std::make_shared(); + } + + glBindBuffer(GL_ARRAY_BUFFER, bitangentVBO->getBuffer()); + + glBufferData(GL_ARRAY_BUFFER, BitangentData.size() * 12, &BitangentData[0], GL_STATIC_DRAW); + + } + + } + + void VertexDataStruct::CalcTangentBitangent() + { + TangentData.clear(); + BitangentData.clear(); + + for (int i = 0; i < PositionData.size() / 3; i++) + { + vec3 v0 = PositionData[i * 3]; + vec3 v1 = PositionData[i * 3 + 1]; + vec3 v2 = PositionData[i * 3 + 2]; + + vec2 t0 = TexCoordData[i * 3]; + vec2 t1 = TexCoordData[i * 3 + 1]; + vec2 t2 = TexCoordData[i * 3 + 2]; + + vec3 deltaPos1 = v1 - v0; + vec3 deltaPos2 = v2 - v0; + vec2 deltaUV1 = t1 - t0; + vec2 deltaUV2 = t2 - t0; + + float r = 1.0f / (deltaUV1.v[0] * deltaUV2.v[1] - deltaUV1.v[1] * deltaUV2.v[0]); + + vec3 tangent = (deltaPos1 * deltaUV2.v[1] - deltaPos2 * deltaUV1.v[1]) * r; + vec3 bitangent = (deltaPos2 * deltaUV1.v[0] - deltaPos1 * deltaUV2.v[0]) * r; + + TangentData.push_back(tangent); + TangentData.push_back(tangent); + TangentData.push_back(tangent); + + BitangentData.push_back(bitangent); + BitangentData.push_back(bitangent); + BitangentData.push_back(bitangent); + + } + + RefreshVBO(); } void DrawVertexDataStruct(const VertexDataStruct& vertexDataStruct) @@ -86,6 +150,8 @@ namespace SE static const std::string vTexCoord("vTexCoord"); static const std::string vPosition("vPosition"); static const std::string vNormal("vNormal"); + static const std::string vTangent("vTangent"); + static const std::string vBitangent("vBitangent"); //Check if main thread, check if data is not empty... glBindBuffer(GL_ARRAY_BUFFER, vertexDataStruct.texCoordVBO->getBuffer()); @@ -97,6 +163,18 @@ namespace SE VertexAttribPointer3fv(vNormal, 0, NULL); } + if (vertexDataStruct.tangentVBO) + { + glBindBuffer(GL_ARRAY_BUFFER, vertexDataStruct.tangentVBO->getBuffer()); + VertexAttribPointer3fv(vTangent, 0, NULL); + } + + if (vertexDataStruct.bitangentVBO) + { + glBindBuffer(GL_ARRAY_BUFFER, vertexDataStruct.bitangentVBO->getBuffer()); + VertexAttribPointer3fv(vBitangent, 0, NULL); + } + glBindBuffer(GL_ARRAY_BUFFER, vertexDataStruct.positionVBO->getBuffer()); VertexAttribPointer3fv(vPosition, 0, NULL);