summaryrefslogtreecommitdiff
path: root/Runtime/Graphics/SharedVertexBuffer.cpp
diff options
context:
space:
mode:
authorchai <chaifix@163.com>2021-10-28 01:52:12 +0800
committerchai <chaifix@163.com>2021-10-28 01:52:12 +0800
commit80dca084b568e4e77d2a4031ce8625cdabc660ab (patch)
treed8c0172aeddca648ec89cbbbda72a938f3ef7433 /Runtime/Graphics/SharedVertexBuffer.cpp
parent1b6f71b2777bdc74d63f988346a8cfee766718b0 (diff)
+ custom vertex buffer
Diffstat (limited to 'Runtime/Graphics/SharedVertexBuffer.cpp')
-rw-r--r--Runtime/Graphics/SharedVertexBuffer.cpp199
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()