diff options
author | chai <chaifix@163.com> | 2021-10-28 01:52:12 +0800 |
---|---|---|
committer | chai <chaifix@163.com> | 2021-10-28 01:52:12 +0800 |
commit | 80dca084b568e4e77d2a4031ce8625cdabc660ab (patch) | |
tree | d8c0172aeddca648ec89cbbbda72a938f3ef7433 /Runtime/Graphics/SharedVertexBuffer.cpp | |
parent | 1b6f71b2777bdc74d63f988346a8cfee766718b0 (diff) |
+ custom vertex buffer
Diffstat (limited to 'Runtime/Graphics/SharedVertexBuffer.cpp')
-rw-r--r-- | Runtime/Graphics/SharedVertexBuffer.cpp | 199 |
1 files changed, 137 insertions, 62 deletions
diff --git a/Runtime/Graphics/SharedVertexBuffer.cpp b/Runtime/Graphics/SharedVertexBuffer.cpp index d547b3c..464a919 100644 --- a/Runtime/Graphics/SharedVertexBuffer.cpp +++ b/Runtime/Graphics/SharedVertexBuffer.cpp @@ -1,4 +1,4 @@ -#include "VertexBuffer.h" +#include "SharedVertexBuffer.h" #include "../Profiling/FrameStats.h" SharedVertexBuffer::SharedVertexBuffer() @@ -9,6 +9,9 @@ SharedVertexBuffer::~SharedVertexBuffer() { } +//------------------------------------------------------------------------------------------------------------ +// Defualt Vertex Layout + //GetChunk //-> ReleaseChunk //-> DrawChunk @@ -18,13 +21,102 @@ void SharedVertexBuffer::GetChunk(uint attrsMask, int maxVerts, int maxIndices, Assert(out_vb && out_ib); uint stride = VertexLayout::GetDynamicChunkStride(attrsMask); // data size of single vertex - GLenum usage = GL_STREAM_DRAW; - uint vbufferSize = stride * maxVerts; - uint ibufferSize = VertexLayout::GetDefaultIndexSize() * maxIndices; + GetChunk(stride, maxVerts, VertexLayout::GetDefaultIndexSize(), maxIndices, primitive, out_vb, out_ib); + + // default layout + m_CurAttrMask = attrsMask; + m_CurStride = stride; +} + +void SharedVertexBuffer::DrawChunk() +{ + DefaultVertexLayout vertexArray; + FillDefaultVertexLayout(vertexArray); + + // bind vertex attributes data + VertexLayout::SetupDefaultVertexLayout(vertexArray); + + const void* indexPtr = m_CurIB ? 0 : (m_CurIBData.empty() ? 0 : &m_CurIBData[0]); + + if (m_CurIB) + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_CurIB->GetHandle()); + + GLenum indexFormat = VertexLayout::GetDefaultIndexFormat(); + + switch (m_CurPrimitive) + { + case Primitive_Triangle: + glDrawElements(GL_TRIANGLES, m_CurIndexCount, indexFormat, indexPtr); + g_FrameStats.AddDrawCall(); + g_FrameStats.AddTrianglesCount(m_CurIndexCount / 3); + break; + case Primitive_Line: + glDrawElements(GL_LINE, m_CurIndexCount, indexFormat, indexPtr); + g_FrameStats.AddDrawCall(); + break; + case Primitive_Point: + glDrawElements(GL_POINT, m_CurIndexCount, indexFormat, indexPtr); + g_FrameStats.AddDrawCall(); + break; + } + + if (m_CurIB) + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); + + // End draw + Clean(); +} + +void SharedVertexBuffer::FillDefaultVertexLayout(DefaultVertexLayout& dst) +{ + const byte* basepointer = m_CurVB ? 0 : &m_CurVBData[0]; + const GLuint buffer = m_CurVB ? m_CurVB->GetHandle() : 0; + + int attrOffsets[VertexAttr_Count] = { 0 }; + { + uint32 curOffset = 0; + for (uint idx = 0; idx < VertexAttr_Count; ++idx) + { + if (m_CurAttrMask & Mask(idx)) + { + attrOffsets[idx] = curOffset; + curOffset += VertexLayout::GetDefaultVertexAttrSize(idx); + } + } + } + + dst.buffer = buffer; + + for (uint32 attrIdx = 0; attrIdx < VertexAttr_Count; ++attrIdx) + { + if (m_CurAttrMask & Mask(attrIdx)) + { + dst.attributes[attrIdx].pointer = basepointer + attrOffsets[attrIdx]; + dst.attributes[attrIdx].componentFormat = VertexLayout::GetDefaultShaderChannelFormat(attrIdx); + dst.attributes[attrIdx].componentNum = VertexLayout::GetDefaultShaderChannelDimension(attrIdx); + dst.attributes[attrIdx].stride = m_CurStride; + + dst.enableMask |= Mask(attrIdx); + } + } +} + +//------------------------------------------------------------------------------------------------------------ +// Custom Vertex Layout + +// 用buffersize为依据决定用vbo或者pinned memory +void SharedVertexBuffer::GetChunk(uint sizePerVert, uint sizePerIndex, int maxVerts, int maxIndices, EPrimitive primitive, void **out_vb, void **out_ib) +{ + Assert(out_vb && out_ib); + + uint vbufferSize = sizePerVert * maxVerts; + uint ibufferSize = sizePerIndex * maxIndices; const bool mapVertexBuffer = vbufferSize >= DataBufferThreshold; const bool mapIndexBuffer = ibufferSize >= DataBufferThreshold; + GLenum usage = GL_STREAM_DRAW; + GPU::DataBuffer* vertexBuffer = mapVertexBuffer ? GPU::ClaimBuffer(vbufferSize, usage) : 0; GPU::DataBuffer* indexBuffer = mapIndexBuffer ? GPU::ClaimBuffer(ibufferSize, usage) : 0; @@ -54,51 +146,32 @@ void SharedVertexBuffer::GetChunk(uint attrsMask, int maxVerts, int maxIndices, m_CurVB = vertexBuffer; m_CurIB = indexBuffer; + m_CurPrimitive = primitive; - m_CurAttrMask = attrsMask; - m_CurStride = stride; } -void SharedVertexBuffer::ReleaseChunk(int actualVerts, int actualIndices) +void SharedVertexBuffer::FillCustomVertexLayout(CustomVertexLayout& dst) { - int actualVBufferSize = m_CurStride * actualVerts; - int actualIBufferSize = VertexLayout::GetDefaultIndexSize() * actualIndices; - - const GLenum usage = GL_STREAM_DRAW; + const byte* basepointer = m_CurVB ? 0 : &m_CurVBData[0]; + const GLuint buffer = m_CurVB ? m_CurVB->GetHandle() : 0; - if (m_CurVB) - { - m_CurVB->FlushMapedRange(0, actualVBufferSize); - m_CurVB->UnMap(); - } - else if (actualVBufferSize >= DataBufferThreshold) - { - m_CurVB = GPU::ClaimBuffer(actualVBufferSize, usage); - m_CurVB->RestoreWithData(actualVBufferSize, usage, &m_CurVBData[0]); - } + dst.buffer = buffer; - if (m_CurIB) + for (int i = 0; i < dst.attributes.size(); ++i) { - m_CurIB->FlushMapedRange(0, actualIBufferSize); - m_CurIB->UnMap(); + int offset = dst.attributes[i].startOffset; + dst.attributes[i].pointer = basepointer + offset; } - else if (actualIBufferSize >= DataBufferThreshold) - { - m_CurIB = GPU::ClaimBuffer(0, usage); - m_CurIB->RestoreWithData(0, usage, &m_CurIBData[0]); - } - - m_CurVertexCount = actualVerts; - m_CurIndexCount = actualIndices; } -void SharedVertexBuffer::DrawChunk() +void SharedVertexBuffer::DrawChunk(CustomVertexLayout& layout) { - DefaultVertexLayout vertexArray; - FillVertexDataInfo(vertexArray); + const byte* basepointer = m_CurVB ? 0 : &m_CurVBData[0]; + const GLuint buffer = m_CurVB ? m_CurVB->GetHandle() : 0; - // bind vertex attributes data - VertexLayout::SetupDefaultVertexLayout(vertexArray); + FillCustomVertexLayout(layout); + + VertexLayout::SetupCustomVertexLayout(layout); const void* indexPtr = m_CurIB ? 0 : (m_CurIBData.empty() ? 0 : &m_CurIBData[0]); @@ -131,38 +204,40 @@ void SharedVertexBuffer::DrawChunk() Clean(); } -void SharedVertexBuffer::FillVertexDataInfo(DefaultVertexLayout& dst) +//------------------------------------------------------------------------------------------------------------ +// Both Default and Custom Vertex Layout + +void SharedVertexBuffer::ReleaseChunk(int actualVerts, int actualIndices) { - const byte* basepointer = m_CurVB ? 0 : &m_CurVBData[0]; - const GLuint buffer = m_CurVB ? m_CurVB->GetHandle() : 0; + int actualVBufferSize = m_CurStride * actualVerts; + int actualIBufferSize = VertexLayout::GetDefaultIndexSize() * actualIndices; - int attrOffsets[VertexAttr_Count] = { 0 }; + const GLenum usage = GL_STREAM_DRAW; + + if (m_CurVB) { - uint32 curOffset = 0; - for (uint idx = 0; idx < VertexAttr_Count; ++idx) - { - if (m_CurAttrMask & Mask(idx)) - { - attrOffsets[idx] = curOffset; - curOffset += VertexLayout::GetDefaultVertexAttrSize(idx); - } - } + m_CurVB->FlushMapedRange(0, actualVBufferSize); + m_CurVB->UnMap(); } - - dst.buffer = buffer; - - for (uint32 attrIdx = 0; attrIdx < VertexAttr_Count; ++attrIdx) + else if (actualVBufferSize >= DataBufferThreshold) { - if (m_CurAttrMask & Mask(attrIdx)) - { - dst.attributes[attrIdx].pointer = basepointer + attrOffsets[attrIdx]; - dst.attributes[attrIdx].componentFormat = VertexLayout::GetDefaultShaderChannelFormat(attrIdx); - dst.attributes[attrIdx].componentNum = VertexLayout::GetDefaultShaderChannelDimension(attrIdx); - dst.attributes[attrIdx].stride = m_CurStride; + m_CurVB = GPU::ClaimBuffer(actualVBufferSize, usage); + m_CurVB->RestoreWithData(actualVBufferSize, usage, &m_CurVBData[0]); + } - dst.enableMask |= Mask(attrIdx); - } + if (m_CurIB) + { + m_CurIB->FlushMapedRange(0, actualIBufferSize); + m_CurIB->UnMap(); + } + else if (actualIBufferSize >= DataBufferThreshold) + { + m_CurIB = GPU::ClaimBuffer(0, usage); + m_CurIB->RestoreWithData(0, usage, &m_CurIBData[0]); } + + m_CurVertexCount = actualVerts; + m_CurIndexCount = actualIndices; } void SharedVertexBuffer::Clean() |