diff --git a/src/Core/OpenGL/CVertexBuffer.cpp b/src/Core/OpenGL/CVertexBuffer.cpp index 25b9ad60..1bc4e14f 100644 --- a/src/Core/OpenGL/CVertexBuffer.cpp +++ b/src/Core/OpenGL/CVertexBuffer.cpp @@ -21,32 +21,45 @@ CVertexBuffer::~CVertexBuffer() CVertexArrayManager::DeleteAllArraysForVBO(this); if (mBuffered) - glDeleteBuffers(14, mAttribBuffers); + glDeleteBuffers(static_cast(mAttribBuffers.size()), mAttribBuffers.data()); } uint16 CVertexBuffer::AddVertex(const CVertex& rkVtx) { - if (mPositions.size() == 0xFFFF) throw std::overflow_error("VBO contains too many vertices"); + if (mPositions.size() == 0xFFFF) + throw std::overflow_error("VBO contains too many vertices"); - if (mVtxDesc & EVertexAttribute::Position) mPositions.push_back(rkVtx.Position); - if (mVtxDesc & EVertexAttribute::Normal) mNormals.push_back(rkVtx.Normal); - if (mVtxDesc & EVertexAttribute::Color0) mColors[0].push_back(rkVtx.Color[0]); - if (mVtxDesc & EVertexAttribute::Color1) mColors[1].push_back(rkVtx.Color[1]); + if (mVtxDesc & EVertexAttribute::Position) + mPositions.push_back(rkVtx.Position); + if (mVtxDesc & EVertexAttribute::Normal) + mNormals.push_back(rkVtx.Normal); + if (mVtxDesc & EVertexAttribute::Color0) + mColors[0].push_back(rkVtx.Color[0]); + if (mVtxDesc & EVertexAttribute::Color1) + mColors[1].push_back(rkVtx.Color[1]); - for (uint32 iTex = 0; iTex < 8; iTex++) - if (mVtxDesc & (EVertexAttribute::Tex0 << iTex)) mTexCoords[iTex].push_back(rkVtx.Tex[iTex]); + for (size_t iTex = 0; iTex < mTexCoords.size(); iTex++) + { + if (mVtxDesc & (EVertexAttribute::Tex0 << iTex)) + mTexCoords[iTex].push_back(rkVtx.Tex[iTex]); + } - for (uint32 iMtx = 0; iMtx < 8; iMtx++) - if (mVtxDesc & (EVertexAttribute::PosMtx << iMtx)) mTexCoords[iMtx].push_back(rkVtx.MatrixIndices[iMtx]); + for (size_t iMtx = 0; iMtx < mTexCoords.size(); iMtx++) + { + if (mVtxDesc & (EVertexAttribute::PosMtx << iMtx)) + mTexCoords[iMtx].push_back(rkVtx.MatrixIndices[iMtx]); + } if (mVtxDesc.HasAnyFlags(EVertexAttribute::BoneIndices | EVertexAttribute::BoneWeights) && mpSkin) { const SVertexWeights& rkWeights = mpSkin->WeightsForVertex(rkVtx.ArrayPosition); - if (mVtxDesc & EVertexAttribute::BoneIndices) mBoneIndices.push_back(rkWeights.Indices); - if (mVtxDesc & EVertexAttribute::BoneWeights) mBoneWeights.push_back(rkWeights.Weights); + if (mVtxDesc & EVertexAttribute::BoneIndices) + mBoneIndices.push_back(rkWeights.Indices); + if (mVtxDesc & EVertexAttribute::BoneWeights) + mBoneWeights.push_back(rkWeights.Weights); } - return (mPositions.size() - 1); + return mPositions.size() - 1; } uint16 CVertexBuffer::AddIfUnique(const CVertex& rkVtx, uint16 Start) @@ -59,25 +72,43 @@ uint16 CVertexBuffer::AddIfUnique(const CVertex& rkVtx, uint16 Start) bool Unique = false; if (mVtxDesc & EVertexAttribute::Position) - if (rkVtx.Position != mPositions[iVert]) Unique = true; + { + if (rkVtx.Position != mPositions[iVert]) + Unique = true; + } if (!Unique && (mVtxDesc & EVertexAttribute::Normal)) - if (rkVtx.Normal != mNormals[iVert]) Unique = true; + { + if (rkVtx.Normal != mNormals[iVert]) + Unique = true; + } if (!Unique && (mVtxDesc & EVertexAttribute::Color0)) - if (rkVtx.Color[0] != mColors[0][iVert]) Unique = true; + { + if (rkVtx.Color[0] != mColors[0][iVert]) + Unique = true; + } if (!Unique && (mVtxDesc & EVertexAttribute::Color1)) - if (rkVtx.Color[1] != mColors[1][iVert]) Unique = true; + { + if (rkVtx.Color[1] != mColors[1][iVert]) + Unique = true; + } if (!Unique) - for (uint32 iTex = 0; iTex < 8; iTex++) - if ((mVtxDesc & (EVertexAttribute::Tex0 << iTex))) + { + for (size_t iTex = 0; iTex < mTexCoords.size(); iTex++) + { + if (mVtxDesc & (EVertexAttribute::Tex0 << iTex)) + { if (rkVtx.Tex[iTex] != mTexCoords[iTex][iVert]) { Unique = true; break; } + } + } + } if (!Unique && mpSkin && (mVtxDesc.HasAnyFlags(EVertexAttribute::BoneIndices | EVertexAttribute::BoneWeights))) { @@ -85,8 +116,8 @@ uint16 CVertexBuffer::AddIfUnique(const CVertex& rkVtx, uint16 Start) for (uint32 iWgt = 0; iWgt < 4; iWgt++) { - if ( ((mVtxDesc & EVertexAttribute::BoneIndices) && (rkWeights.Indices[iWgt] != mBoneIndices[iVert][iWgt])) || - ((mVtxDesc & EVertexAttribute::BoneWeights) && (rkWeights.Weights[iWgt] != mBoneWeights[iVert][iWgt])) ) + if (((mVtxDesc & EVertexAttribute::BoneIndices) && (rkWeights.Indices[iWgt] != mBoneIndices[iVert][iWgt])) || + ((mVtxDesc & EVertexAttribute::BoneWeights) && (rkWeights.Weights[iWgt] != mBoneWeights[iVert][iWgt]))) { Unique = true; break; @@ -94,7 +125,8 @@ uint16 CVertexBuffer::AddIfUnique(const CVertex& rkVtx, uint16 Start) } } - if (!Unique) return iVert; + if (!Unique) + return iVert; } } @@ -103,7 +135,7 @@ uint16 CVertexBuffer::AddIfUnique(const CVertex& rkVtx, uint16 Start) void CVertexBuffer::Reserve(uint16 Size) { - uint32 ReserveSize = mPositions.size() + Size; + const size_t ReserveSize = mPositions.size() + Size; if (mVtxDesc & EVertexAttribute::Position) mPositions.reserve(ReserveSize); @@ -117,9 +149,11 @@ void CVertexBuffer::Reserve(uint16 Size) if (mVtxDesc & EVertexAttribute::Color1) mColors[1].reserve(ReserveSize); - for (uint32 iTex = 0; iTex < 8; iTex++) + for (size_t iTex = 0; iTex < mTexCoords.size(); iTex++) + { if (mVtxDesc & (EVertexAttribute::Tex0 << iTex)) mTexCoords[iTex].reserve(ReserveSize); + } if (mVtxDesc & EVertexAttribute::BoneIndices) mBoneIndices.reserve(ReserveSize); @@ -131,7 +165,7 @@ void CVertexBuffer::Reserve(uint16 Size) void CVertexBuffer::Clear() { if (mBuffered) - glDeleteBuffers(14, mAttribBuffers); + glDeleteBuffers(static_cast(mAttribBuffers.size()), mAttribBuffers.data()); mBuffered = false; mPositions.clear(); @@ -139,8 +173,8 @@ void CVertexBuffer::Clear() mColors[0].clear(); mColors[1].clear(); - for (uint32 iTex = 0; iTex < 8; iTex++) - mTexCoords[iTex].clear(); + for (auto& coord : mTexCoords) + coord.clear(); mBoneIndices.clear(); mBoneWeights.clear(); @@ -151,49 +185,46 @@ void CVertexBuffer::Buffer() // Make sure we don't end up with two buffers for the same data... if (mBuffered) { - glDeleteBuffers(14, mAttribBuffers); + glDeleteBuffers(static_cast(mAttribBuffers.size()), mAttribBuffers.data()); mBuffered = false; } // Generate buffers - glGenBuffers(14, mAttribBuffers); + glGenBuffers(static_cast(mAttribBuffers.size()), mAttribBuffers.data()); - for (uint32 iAttrib = 0; iAttrib < 14; iAttrib++) + for (size_t iAttrib = 0; iAttrib < mAttribBuffers.size(); iAttrib++) { - int Attrib = (EVertexAttribute::Position << iAttrib); - bool HasAttrib = ((mVtxDesc & Attrib) != 0); - if (!HasAttrib) continue; + const auto Attrib = static_cast(EVertexAttribute::Position << iAttrib); + const bool HasAttrib = (mVtxDesc & Attrib) != 0; + if (!HasAttrib) + continue; if (iAttrib < 2) { - std::vector *pBuffer = (iAttrib == 0) ? &mPositions : &mNormals; + const std::vector& pBuffer = iAttrib == 0 ? mPositions : mNormals; glBindBuffer(GL_ARRAY_BUFFER, mAttribBuffers[iAttrib]); - glBufferData(GL_ARRAY_BUFFER, pBuffer->size() * sizeof(CVector3f), pBuffer->data(), GL_STATIC_DRAW); + glBufferData(GL_ARRAY_BUFFER, pBuffer.size() * sizeof(CVector3f), pBuffer.data(), GL_STATIC_DRAW); } - else if (iAttrib < 4) { - uint8 Index = (uint8) (iAttrib - 2); + const auto Index = static_cast(iAttrib - 2); glBindBuffer(GL_ARRAY_BUFFER, mAttribBuffers[iAttrib]); glBufferData(GL_ARRAY_BUFFER, mColors[Index].size() * sizeof(CColor), mColors[Index].data(), GL_STATIC_DRAW); } - else if (iAttrib < 12) { - uint8 Index = (uint8) (iAttrib - 4); + const auto Index = static_cast(iAttrib - 4); glBindBuffer(GL_ARRAY_BUFFER, mAttribBuffers[iAttrib]); glBufferData(GL_ARRAY_BUFFER, mTexCoords[Index].size() * sizeof(CVector2f), mTexCoords[Index].data(), GL_STATIC_DRAW); } - else if (iAttrib == 12) { glBindBuffer(GL_ARRAY_BUFFER, mAttribBuffers[iAttrib]); glBufferData(GL_ARRAY_BUFFER, mBoneIndices.size() * sizeof(TBoneIndices), mBoneIndices.data(), GL_STATIC_DRAW); } - else if (iAttrib == 13) { glBindBuffer(GL_ARRAY_BUFFER, mAttribBuffers[iAttrib]); @@ -206,7 +237,9 @@ void CVertexBuffer::Buffer() void CVertexBuffer::Bind() { - if (!mBuffered) Buffer(); + if (!mBuffered) + Buffer(); + CVertexArrayManager::Current()->BindVAO(this); } @@ -248,44 +281,40 @@ GLuint CVertexBuffer::CreateVAO() glGenVertexArrays(1, &VertexArray); glBindVertexArray(VertexArray); - for (uint32 iAttrib = 0; iAttrib < 14; iAttrib++) + for (size_t iAttrib = 0; iAttrib < mAttribBuffers.size(); iAttrib++) { - int Attrib = (EVertexAttribute::Position << iAttrib); - bool HasAttrib = ((mVtxDesc & Attrib) != 0); + const auto Attrib = static_cast(EVertexAttribute::Position << iAttrib); + const bool HasAttrib = (mVtxDesc & Attrib) != 0; if (!HasAttrib) continue; if (iAttrib < 2) { glBindBuffer(GL_ARRAY_BUFFER, mAttribBuffers[iAttrib]); - glVertexAttribPointer(iAttrib, 3, GL_FLOAT, GL_FALSE, sizeof(CVector3f), (void*) 0); + glVertexAttribPointer(iAttrib, 3, GL_FLOAT, GL_FALSE, sizeof(CVector3f), nullptr); glEnableVertexAttribArray(iAttrib); } - else if (iAttrib < 4) { glBindBuffer(GL_ARRAY_BUFFER, mAttribBuffers[iAttrib]); - glVertexAttribPointer(iAttrib, 1, GL_UNSIGNED_INT, GL_FALSE, sizeof(CColor), (void*) 0); + glVertexAttribPointer(iAttrib, 1, GL_UNSIGNED_INT, GL_FALSE, sizeof(CColor), nullptr); glEnableVertexAttribArray(iAttrib); } - else if (iAttrib < 12) { glBindBuffer(GL_ARRAY_BUFFER, mAttribBuffers[iAttrib]); - glVertexAttribPointer(iAttrib, 2, GL_FLOAT, GL_FALSE, sizeof(CVector2f), (void*) 0); + glVertexAttribPointer(iAttrib, 2, GL_FLOAT, GL_FALSE, sizeof(CVector2f), nullptr); glEnableVertexAttribArray(iAttrib); } - else if (iAttrib == 12) { glBindBuffer(GL_ARRAY_BUFFER, mAttribBuffers[iAttrib]); - glVertexAttribIPointer(iAttrib, 1, GL_UNSIGNED_INT, sizeof(TBoneIndices), (void*) 0); + glVertexAttribIPointer(iAttrib, 1, GL_UNSIGNED_INT, sizeof(TBoneIndices), nullptr); glEnableVertexAttribArray(iAttrib); } - else if (iAttrib == 13) { glBindBuffer(GL_ARRAY_BUFFER, mAttribBuffers[iAttrib]); - glVertexAttribPointer(iAttrib, 4, GL_FLOAT, GL_FALSE, sizeof(TBoneWeights), (void*) 0); + glVertexAttribPointer(iAttrib, 4, GL_FLOAT, GL_FALSE, sizeof(TBoneWeights), nullptr); glEnableVertexAttribArray(iAttrib); } } diff --git a/src/Core/OpenGL/CVertexBuffer.h b/src/Core/OpenGL/CVertexBuffer.h index 9836dc56..cef82df8 100644 --- a/src/Core/OpenGL/CVertexBuffer.h +++ b/src/Core/OpenGL/CVertexBuffer.h @@ -5,21 +5,22 @@ #include "Core/Resource/Animation/CSkin.h" #include "Core/Resource/Model/CVertex.h" #include "Core/Resource/Model/EVertexAttribute.h" +#include #include #include class CVertexBuffer { - FVertexDescription mVtxDesc; // Flags that indicate what vertex attributes are enabled on this vertex buffer - GLuint mAttribBuffers[14]; // Separate GL buffer for each attribute to allow not tracking unused attribs. No support for matrix indices currently. - TResPtr mpSkin; // Skin for skinned models. Null on unskinned models; - std::vector mPositions; // Vector of vertex positions - std::vector mNormals; // Vector of vertex normals - std::vector mColors[2]; // Vectors of vertex colors - std::vector mTexCoords[8]; // Vectors of texture coordinates - std::vector mBoneIndices; // Vectors of bone indices - std::vector mBoneWeights; // Vectors of bone weights - bool mBuffered = false; // Bool value that indicates whether the attributes have been buffered. + FVertexDescription mVtxDesc; // Flags that indicate what vertex attributes are enabled on this vertex buffer + std::array mAttribBuffers{}; // Separate GL buffer for each attribute to allow not tracking unused attribs. No support for matrix indices currently. + TResPtr mpSkin; // Skin for skinned models. Null on unskinned models; + std::vector mPositions; // Vector of vertex positions + std::vector mNormals; // Vector of vertex normals + std::array, 2> mColors; // Vectors of vertex colors + std::array, 8> mTexCoords; // Vectors of texture coordinates + std::vector mBoneIndices; // Vectors of bone indices + std::vector mBoneWeights; // Vectors of bone weights + bool mBuffered = false; // Bool value that indicates whether the attributes have been buffered. public: CVertexBuffer();