diff options
author | chai <chaifix@163.com> | 2021-10-28 00:47:35 +0800 |
---|---|---|
committer | chai <chaifix@163.com> | 2021-10-28 00:47:35 +0800 |
commit | 1b6f71b2777bdc74d63f988346a8cfee766718b0 (patch) | |
tree | ae710ba057f4841e7d0911eb4d3e0c346f79a524 | |
parent | 305ca0a09d4e750186b5190432de47f3493e806a (diff) |
+DefaultVertexLayout
-rw-r--r-- | Projects/VisualStudio/Editor/Editor.vcxproj | 7 | ||||
-rw-r--r-- | Projects/VisualStudio/Editor/Editor.vcxproj.filters | 21 | ||||
-rw-r--r-- | Runtime/Graphics/CustomVertexLayout.cpp | 0 | ||||
-rw-r--r-- | Runtime/Graphics/CustomVertexLayout.h | 15 | ||||
-rw-r--r-- | Runtime/Graphics/DefaultVertexLayout.cpp | 119 | ||||
-rw-r--r-- | Runtime/Graphics/DefaultVertexLayout.h | 52 | ||||
-rw-r--r-- | Runtime/Graphics/SharedVertexBuffer.cpp | 190 | ||||
-rw-r--r-- | Runtime/Graphics/VertexAttribute.cpp | 19 | ||||
-rw-r--r-- | Runtime/Graphics/VertexAttribute.h | 35 | ||||
-rw-r--r-- | Runtime/Graphics/VertexBuffer.cpp | 311 | ||||
-rw-r--r-- | Runtime/Graphics/VertexBuffer.h | 36 |
11 files changed, 461 insertions, 344 deletions
diff --git a/Projects/VisualStudio/Editor/Editor.vcxproj b/Projects/VisualStudio/Editor/Editor.vcxproj index de5e835..e2fbda7 100644 --- a/Projects/VisualStudio/Editor/Editor.vcxproj +++ b/Projects/VisualStudio/Editor/Editor.vcxproj @@ -177,6 +177,8 @@ <ClCompile Include="..\..\..\Runtime\FileSystem\ImageJobs.cpp" />
<ClCompile Include="..\..\..\Runtime\FileSystem\Path.cpp" />
<ClCompile Include="..\..\..\Runtime\FileSystem\Unzip.cpp" />
+ <ClCompile Include="..\..\..\Runtime\Graphics\CustomVertexLayout.cpp" />
+ <ClCompile Include="..\..\..\Runtime\Graphics\DefaultVertexLayout.cpp" />
<ClCompile Include="..\..\..\Runtime\Graphics\GfxDevice.cpp" />
<ClCompile Include="..\..\..\Runtime\Graphics\FrameBuffer.cpp" />
<ClCompile Include="..\..\..\Runtime\Graphics\GlyphAtlas.cpp" />
@@ -189,7 +191,9 @@ <ClCompile Include="..\..\..\Runtime\Graphics\RenderTexture.cpp" />
<ClCompile Include="..\..\..\Runtime\Graphics\Shader.cpp" />
<ClCompile Include="..\..\..\Runtime\Graphics\ShaderCompiler.cpp" />
+ <ClCompile Include="..\..\..\Runtime\Graphics\SharedVertexBuffer.cpp" />
<ClCompile Include="..\..\..\Runtime\Graphics\Texture.cpp" />
+ <ClCompile Include="..\..\..\Runtime\Graphics\VertexAttribute.cpp" />
<ClCompile Include="..\..\..\Runtime\Graphics\VertexBuffer.cpp" />
<ClCompile Include="..\..\..\Runtime\Lua\LuaBind\LuaBindCFunctions.cpp" />
<ClCompile Include="..\..\..\Runtime\Lua\LuaBind\LuaBindClass.cpp" />
@@ -249,6 +253,8 @@ <ClInclude Include="..\..\..\Runtime\FileSystem\Path.h" />
<ClInclude Include="..\..\..\Runtime\FileSystem\Unzip.h" />
<ClInclude Include="..\..\..\Runtime\Graphics\Color.h" />
+ <ClInclude Include="..\..\..\Runtime\Graphics\CustomVertexLayout.h" />
+ <ClInclude Include="..\..\..\Runtime\Graphics\DefaultVertexLayout.h" />
<ClInclude Include="..\..\..\Runtime\Graphics\GfxDevice.h" />
<ClInclude Include="..\..\..\Runtime\Graphics\DeviceDefine.h" />
<ClInclude Include="..\..\..\Runtime\Graphics\FrameBuffer.h" />
@@ -263,6 +269,7 @@ <ClInclude Include="..\..\..\Runtime\Graphics\Shader.h" />
<ClInclude Include="..\..\..\Runtime\Graphics\ShaderCompiler.h" />
<ClInclude Include="..\..\..\Runtime\Graphics\Texture.h" />
+ <ClInclude Include="..\..\..\Runtime\Graphics\VertexAttribute.h" />
<ClInclude Include="..\..\..\Runtime\Graphics\VertexBuffer.h" />
<ClInclude Include="..\..\..\Runtime\Lua\LuaBind\LuaBind.h" />
<ClInclude Include="..\..\..\Runtime\Lua\LuaBind\LuaBindCFunctions.h" />
diff --git a/Projects/VisualStudio/Editor/Editor.vcxproj.filters b/Projects/VisualStudio/Editor/Editor.vcxproj.filters index 9bda8cd..1b419c4 100644 --- a/Projects/VisualStudio/Editor/Editor.vcxproj.filters +++ b/Projects/VisualStudio/Editor/Editor.vcxproj.filters @@ -357,6 +357,18 @@ <ClCompile Include="..\..\..\Runtime\Graphics\GPUDataBuffer.cpp">
<Filter>Runtime\Graphics</Filter>
</ClCompile>
+ <ClCompile Include="..\..\..\Runtime\Graphics\CustomVertexLayout.cpp">
+ <Filter>Runtime\FileSystem</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Runtime\Graphics\DefaultVertexLayout.cpp">
+ <Filter>Runtime\FileSystem</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Runtime\Graphics\SharedVertexBuffer.cpp">
+ <Filter>Runtime\Graphics</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Runtime\Graphics\VertexAttribute.cpp">
+ <Filter>Runtime\Graphics</Filter>
+ </ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\..\..\Editor\GUI\Dock.h">
@@ -593,6 +605,15 @@ <ClInclude Include="..\..\..\Runtime\Graphics\GPUDataBuffer.h">
<Filter>Runtime\Graphics</Filter>
</ClInclude>
+ <ClInclude Include="..\..\..\Runtime\Graphics\DefaultVertexLayout.h">
+ <Filter>Runtime\Graphics</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\Runtime\Graphics\CustomVertexLayout.h">
+ <Filter>Runtime\Graphics</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\Runtime\Graphics\VertexAttribute.h">
+ <Filter>Runtime\Graphics</Filter>
+ </ClInclude>
</ItemGroup>
<ItemGroup>
<None Include="..\..\..\Runtime\Lua\LuaBind\LuaBindClass.inc">
diff --git a/Runtime/Graphics/CustomVertexLayout.cpp b/Runtime/Graphics/CustomVertexLayout.cpp new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/Runtime/Graphics/CustomVertexLayout.cpp diff --git a/Runtime/Graphics/CustomVertexLayout.h b/Runtime/Graphics/CustomVertexLayout.h new file mode 100644 index 0000000..402e663 --- /dev/null +++ b/Runtime/Graphics/CustomVertexLayout.h @@ -0,0 +1,15 @@ +#pragma once + +#include <vector> +#include "../Utilities/UtilMacros.h" +#include "../Shaders/ShaderChannel.h" +#include "OpenGL.h" +#include "GPUDataBuffer.h" +#include "VertexAttribute.h" + +struct CustomVertexLayout +{ + GLuint buffer; + std::vector<VertexAttributeDescriptor> attributes; +}; + diff --git a/Runtime/Graphics/DefaultVertexLayout.cpp b/Runtime/Graphics/DefaultVertexLayout.cpp new file mode 100644 index 0000000..0781c2e --- /dev/null +++ b/Runtime/Graphics/DefaultVertexLayout.cpp @@ -0,0 +1,119 @@ +#include "DefaultVertexLayout.h" + +namespace VertexLayout +{ + // 默认vertex layout + static const int kVertexAttrSize[VertexAttr_Count] = { + 3 * sizeof(float), // position + 3 * sizeof(float), // normal + 4 * sizeof(float), // tangent + 4 * sizeof(byte), // color + 2 * sizeof(float), // uv + 2 * sizeof(float), // uv2 + 2 * sizeof(float), // uv3 + 2 * sizeof(float), // uv4 + }; + + static const int kVertexAttrDimension[VertexAttr_Count] = { + 3, // position + 3, // normal + 4, // tangent + 4, // color + 2, // uv + 2, // uv2 + 2, // uv3 + 2, // uv4 + }; + + bool IsGLVertexAttrNeedNormalized(uint attr/*, uint format*/) + { + if (attr == VertexAttr_Color) + return true; + /* + if (format == VertexAttrFormat_Color || format == VertexAttrFormat_Byte) + return true; + */ + return false; + } + + uint GetDefaultShaderChannelFormat(uint attr) + { + return attr == VertexAttr_Color ? VertexAttrFormat_Color : VertexAttrFormat_Float; + } + + uint32 GetDefaultVertexAttrSize(int attr) + { + return kVertexAttrSize[attr]; + } + + uint GetDefaultVertexAttrDimension(uint attr) + { + return kVertexAttrDimension[attr]; + } + + uint GetDefaultShaderChannelDimension(uint attr) + { + return attr == VertexAttr_Color ? 4 : GetDefaultVertexAttrDimension(attr); + } + + GLenum GetDefaultVertexAttrcomponentFormat(uint attr) + { + uint componentFormat = GetDefaultShaderChannelFormat(attr); + return VertexAttribute::ConvertAttrFormatToGLFormat(componentFormat); + } + + uint32 GetDynamicChunkStride(uint32 vertexAttrMask) + { + uint32 stride = 0; + for (int i = 0; i < vertexAttrMask; ++i) + { + if (vertexAttrMask & Mask(i)) + stride += VertexLayout::GetDefaultVertexAttrSize(i); + } + return stride; + } + + static uint32 sEnabledArrays = 0; + + void SetupDefaultVertexLayout(const DefaultVertexLayout& info) + { + glBindBuffer(GL_ARRAY_BUFFER, info.buffer); + + for (int attrIdx = 0; attrIdx < VertexAttr_Count; ++attrIdx) + { + if (info.enableMask & Mask(attrIdx)) + { + if (!sEnabledArrays & Mask(attrIdx)) + glEnableVertexAttribArray(attrIdx); + int numCompo = info.attributes[attrIdx].componentNum; + GLenum compoType = VertexLayout::GetDefaultVertexAttrcomponentFormat(attrIdx); + bool normalized = VertexLayout::IsGLVertexAttrNeedNormalized(attrIdx); + uint stride = info.attributes[attrIdx].stride; + const void* pointer = info.attributes[attrIdx].pointer; + + glVertexAttribPointer(attrIdx, numCompo, compoType, normalized ? GL_TRUE : GL_FALSE, stride, pointer); + } + else if (sEnabledArrays & Mask(attrIdx)) + glDisableVertexAttribArray(attrIdx); + } + sEnabledArrays = info.enableMask; + } + + void InvalidateVertexInputCache() + { + sEnabledArrays = 0; + for (int attrIdx = 0; attrIdx < VertexAttr_Count; ++attrIdx) + glDisableVertexAttribArray(attrIdx); + } + + // 索引保存为 unsgined short (GL_UNSIGNED_SHORT) + uint GetDefaultIndexSize() + { + return sizeof(uint16); + } + GLenum GetDefaultIndexFormat() + { + return GL_UNSIGNED_SHORT; + } + +} diff --git a/Runtime/Graphics/DefaultVertexLayout.h b/Runtime/Graphics/DefaultVertexLayout.h new file mode 100644 index 0000000..2d78518 --- /dev/null +++ b/Runtime/Graphics/DefaultVertexLayout.h @@ -0,0 +1,52 @@ +#pragma once + +#include <vector> +#include "../Utilities/UtilMacros.h" +#include "../Shaders/ShaderChannel.h" +#include "OpenGL.h" +#include "GPUDataBuffer.h" +#include "VertexAttribute.h" + +// 默认的顶点布局,适用于Mesh导入的结果,保持shader的一致性 +// 如果需要修改布局,比如编辑器UI中,用CustomVertexLayout + +// 默认的顶点属性以及顺序 +enum EVertexAttr +{ + VertexAttr_Position = 0, + VertexAttr_Normal, + VertexAttr_Tangent, + VertexAttr_Color, + VertexAttr_UV, + VertexAttr_UV2, + VertexAttr_UV3, + VertexAttr_UV4, + + VertexAttr_Count +}; + +// GPU侧的默认顶点属性 +struct DefaultVertexLayout +{ + uint32 enableMask; + GLuint buffer; // vbo或者0(pinned memory) + VertexAttributeDescriptor attributes[VertexAttr_Count]; +}; + +namespace VertexLayout +{ + extern uint GetDefaultIndexSize(); + extern GLenum GetDefaultIndexFormat(); + + extern uint32 GetDynamicChunkStride(uint32 vertexAttrMask); + extern bool IsGLVertexAttrNeedNormalized(uint attr); + extern uint GetDefaultShaderChannelFormat(uint attr); + extern uint32 GetDefaultVertexAttrSize(int attr); + extern uint GetDefaultVertexAttrDimension(uint attr); + extern uint GetDefaultShaderChannelDimension(uint attr); + extern GLenum GetDefaultVertexAttrComponentType(uint attr); + + void SetupDefaultVertexLayout(const DefaultVertexLayout& info); + void InvalidateVertexInputCache(); + +} diff --git a/Runtime/Graphics/SharedVertexBuffer.cpp b/Runtime/Graphics/SharedVertexBuffer.cpp new file mode 100644 index 0000000..d547b3c --- /dev/null +++ b/Runtime/Graphics/SharedVertexBuffer.cpp @@ -0,0 +1,190 @@ +#include "VertexBuffer.h" +#include "../Profiling/FrameStats.h" + +SharedVertexBuffer::SharedVertexBuffer() +{ +} + +SharedVertexBuffer::~SharedVertexBuffer() +{ +} + +//GetChunk +//-> ReleaseChunk +//-> DrawChunk + +void SharedVertexBuffer::GetChunk(uint attrsMask, int maxVerts, int maxIndices, EPrimitive primitive, void **out_vb, void **out_ib) +{ + 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; + + const bool mapVertexBuffer = vbufferSize >= DataBufferThreshold; + const bool mapIndexBuffer = ibufferSize >= DataBufferThreshold; + + GPU::DataBuffer* vertexBuffer = mapVertexBuffer ? GPU::ClaimBuffer(vbufferSize, usage) : 0; + GPU::DataBuffer* indexBuffer = mapIndexBuffer ? GPU::ClaimBuffer(ibufferSize, usage) : 0; + + if (vertexBuffer && vertexBuffer->GetSize() < vbufferSize) + vertexBuffer->Restore(vbufferSize, usage); + + if (indexBuffer && indexBuffer->GetSize() < ibufferSize) + indexBuffer->Restore(ibufferSize, usage); + + if (!mapVertexBuffer && m_CurVBData.size() < vbufferSize) + m_CurVBData.resize(vbufferSize); + + if (!mapIndexBuffer && m_CurIBData.size() < ibufferSize) + m_CurIBData.resize(ibufferSize); + + const GLenum access = GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_BUFFER_BIT | GL_MAP_FLUSH_EXPLICIT_BIT; + + if (vertexBuffer) + *out_vb = vertexBuffer->MapRange(0, vbufferSize, access); + else + *out_vb = &m_CurVBData[0]; + + if (indexBuffer) + *out_ib = indexBuffer->MapRange(0, ibufferSize, access); + else + *out_ib = &m_CurIBData[0]; + + m_CurVB = vertexBuffer; + m_CurIB = indexBuffer; + m_CurPrimitive = primitive; + m_CurAttrMask = attrsMask; + m_CurStride = stride; +} + +void SharedVertexBuffer::ReleaseChunk(int actualVerts, int actualIndices) +{ + int actualVBufferSize = m_CurStride * actualVerts; + int actualIBufferSize = VertexLayout::GetDefaultIndexSize() * actualIndices; + + const GLenum usage = GL_STREAM_DRAW; + + 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]); + } + + 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::DrawChunk() +{ + DefaultVertexLayout vertexArray; + FillVertexDataInfo(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::FillVertexDataInfo(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); + } + } +} + +void SharedVertexBuffer::Clean() +{ + if (m_CurVB) + { + GPU::ReleaseBuffer(m_CurVB); + m_CurVB = 0; + } + + if (m_CurIB) + { + GPU::ReleaseBuffer(m_CurIB); + m_CurIB = 0; + } + + m_CurPrimitive = Primitive_Triangle; + m_CurAttrMask = 0; + m_CurStride = 0; + m_CurVertexCount = 0; + m_CurIndexCount = 0; + + m_CurVBData.clear(); + m_CurIBData.clear(); +} diff --git a/Runtime/Graphics/VertexAttribute.cpp b/Runtime/Graphics/VertexAttribute.cpp new file mode 100644 index 0000000..0b0e8e4 --- /dev/null +++ b/Runtime/Graphics/VertexAttribute.cpp @@ -0,0 +1,19 @@ +#include "VertexAttribute.h" + +namespace VertexAttribute +{ + + // map VertexAttrFormat to OpenGL type + static GLenum kGLVertexAttrFormat[VertexAttrFormat_Count] = { + GL_FLOAT, // VertexAttrFormat_Float + GL_HALF_FLOAT, // VertexAttrFormat_Float16 + GL_UNSIGNED_BYTE, // VertexAttrFormat_Color + GL_BYTE // VertexAttrFormat_Byte + }; + + GLenum ConvertAttrFormatToGLFormat(uint fmt) + { + return kGLVertexAttrFormat[fmt]; + } + +}
\ No newline at end of file diff --git a/Runtime/Graphics/VertexAttribute.h b/Runtime/Graphics/VertexAttribute.h new file mode 100644 index 0000000..2e6e59f --- /dev/null +++ b/Runtime/Graphics/VertexAttribute.h @@ -0,0 +1,35 @@ +#pragma once + +#include <vector> + +#include "../Utilities/UtilMacros.h" +#include "../Shaders/ShaderChannel.h" + +#include "OpenGL.h" +#include "GPUDataBuffer.h" + +// component format +enum VertexAttrFormat +{ + VertexAttrFormat_Float = 0, // position\normal\tangent\uv\uv2\uv3\uv4 + VertexAttrFormat_Float16 = 1, + VertexAttrFormat_Color = 2, // color + VertexAttrFormat_Byte = 3, + + VertexAttrFormat_Count = 4 +}; + +struct VertexAttributeDescriptor +{ + const void* pointer; // 内存地址或显存中相对VBO的偏移值 + uint componentNum; // 向量维度1,2,3,4 + uint componentFormat; // 每个分量的类型 + uint16 stride; // 间隔 +}; + +namespace VertexAttribute +{ + + extern GLenum ConvertAttrFormatToGLFormat(uint fmt); + +} diff --git a/Runtime/Graphics/VertexBuffer.cpp b/Runtime/Graphics/VertexBuffer.cpp index 7ea3acd..8423c2b 100644 --- a/Runtime/Graphics/VertexBuffer.cpp +++ b/Runtime/Graphics/VertexBuffer.cpp @@ -1,95 +1,6 @@ #include "VertexBuffer.h" #include "../Profiling/FrameStats.h" -void SetupDefaultVertexArray(const VertexDataInfo& info); -void InvalidateVertexInputCache(); - -// LUTs of vertex attributes -static const int kVertexAttrSize[VertexAttr_Count] = { - 3 * sizeof(float), // position - 3 * sizeof(float), // normal - 4 * sizeof(float), // tangent - 1 * sizeof(uint32), // color - 2 * sizeof(float), // uv - 2 * sizeof(float), // uv2 - 2 * sizeof(float), // uv3 - 2 * sizeof(float), // uv4 -}; - -static const int kVertexAttrDimension[VertexAttr_Count] = { - 3, // position - 3, // normal - 4, // tangent - 1, // color - 2, // uv - 2, // uv2 - 2, // uv3 - 2, // uv4 -}; - -enum VertexAttrFormat -{ - VertexAttrFormat_Float = 0, // position \ normal \ tangent \ uv0 \ uv1 - VertexAttrFormat_Float16 = 1, - VertexAttrFormat_Color = 2, // color - VertexAttrFormat_Byte = 3, - - VertexAttrFormat_Count = 4 -}; - -// map VertexAttrFormat to OpenGL type -static GLenum kGLVertexAttrFormat[VertexAttrFormat_Count] = { - GL_FLOAT, // VertexAttrFormat_Float - GL_HALF_FLOAT, // VertexAttrFormat_Float16 - GL_UNSIGNED_BYTE, // VertexAttrFormat_Color - GL_BYTE // VertexAttrFormat_Byte -}; - -static bool IsGLVertexAttrNeedNormalized(uint attr, uint format) -{ - if(attr == VertexAttr_Position) - return false; - else // color and byte need to be normalized - return format != VertexAttrFormat_Float && format != VertexAttrFormat_Float16; -} - -static uint GetDefaultShaderChannelFormat(uint attr) -{ -// besides color, other attributes are all composite of float values - return attr == VertexAttr_Color ? VertexAttrFormat_Color : VertexAttrFormat_Float; -} - -static uint32 GetDefaultVertexAttrSize(/*VertexAttr*/ int attr) -{ - return kVertexAttrSize[attr]; -} - -static uint GetDefaultVertexAttrDimension(uint attr) -{ - return kVertexAttrDimension[attr]; -} - -static uint GetDefaultShaderChannelDimension(uint attr) -{ - return attr == VertexAttr_Color ? 4 : GetDefaultVertexAttrDimension(attr); -} - -// index is stored in unsgined short (GL_UNSIGNED_SHORT) -static const int kIndexSize = sizeof(uint16); -static GLenum kGLIndexFormat = GL_UNSIGNED_SHORT; - -// Get size used for vertexAttrMask -static uint32 GetDynamicChunkStride(uint32 vertexAttrMask) -{ - uint32 stride = 0; - for (int i = 0; i < vertexAttrMask; ++i) - { - if (vertexAttrMask & Mask(i)) - stride += GetDefaultVertexAttrSize(i); - } - return stride; -} - VertexBuffer::VertexBuffer(VertexBufferType type) { } @@ -97,225 +8,3 @@ VertexBuffer::VertexBuffer(VertexBufferType type) VertexBuffer::~VertexBuffer() { } - -//------------------------------------------------------------------------------------------------------------ - -SharedVertexBuffer::SharedVertexBuffer() -{ -} - -SharedVertexBuffer::~SharedVertexBuffer() -{ -} - -//GetChunk -//-> ReleaseChunk -//-> DrawChunk - -void SharedVertexBuffer::GetChunk(uint attrsMask, int maxVerts, int maxIndices, EPrimitive primitive, void **out_vb, void **out_ib) -{ - Assert(out_vb && out_ib); - - uint stride = GetDynamicChunkStride(attrsMask); // data size of single vertex - GLenum usage = GL_STREAM_DRAW; - uint vbufferSize = stride * maxVerts; - uint ibufferSize = kIndexSize * maxIndices; - - const bool mapVertexBuffer = vbufferSize >= DataBufferThreshold; - const bool mapIndexBuffer = ibufferSize >= DataBufferThreshold; - - GPU::DataBuffer* vertexBuffer = mapVertexBuffer ? GPU::ClaimBuffer(vbufferSize, usage) : 0; - GPU::DataBuffer* indexBuffer = mapIndexBuffer ? GPU::ClaimBuffer(ibufferSize, usage) : 0; - - if(vertexBuffer && vertexBuffer->GetSize() < vbufferSize) - vertexBuffer->Restore(vbufferSize, usage); - - if(indexBuffer && indexBuffer->GetSize() < ibufferSize) - indexBuffer->Restore(ibufferSize, usage); - - if(!mapVertexBuffer && m_CurVBData.size() < vbufferSize) - m_CurVBData.resize(vbufferSize); - - if(!mapIndexBuffer && m_CurIBData.size() < ibufferSize) - m_CurIBData.resize(ibufferSize); - - const GLenum access = GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_BUFFER_BIT | GL_MAP_FLUSH_EXPLICIT_BIT; - - if (vertexBuffer) - *out_vb = vertexBuffer->MapRange(0, vbufferSize, access); - else - *out_vb = &m_CurVBData[0]; - - if(indexBuffer) - *out_ib = indexBuffer->MapRange(0, ibufferSize, access); - else - *out_ib = &m_CurIBData[0]; - - m_CurVB = vertexBuffer; - m_CurIB = indexBuffer; - m_CurPrimitive = primitive; - m_CurAttrMask = attrsMask; - m_CurStride = stride; -} - -void SharedVertexBuffer::ReleaseChunk(int actualVerts, int actualIndices) -{ - int actualVBufferSize = m_CurStride * actualVerts; - int actualIBufferSize = kIndexSize * actualIndices; - - const GLenum usage = GL_STREAM_DRAW; - - 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]); - } - - 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::DrawChunk() -{ - VertexDataInfo vertexArray; - FillVertexArrayInfo(vertexArray); - - // bind vertex attributes data - SetupDefaultVertexArray(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()); - - switch (m_CurPrimitive) - { - case Primitive_Triangle: - glDrawElements(GL_TRIANGLES, m_CurIndexCount, kGLIndexFormat, indexPtr); - g_FrameStats.AddDrawCall(); - g_FrameStats.AddTrianglesCount(m_CurIndexCount / 3); - break; - case Primitive_Line: - glDrawElements(GL_LINE, m_CurIndexCount, kGLIndexFormat, indexPtr); - g_FrameStats.AddDrawCall(); - break; - case Primitive_Point: - glDrawElements(GL_POINT, m_CurIndexCount, kGLIndexFormat, indexPtr); - g_FrameStats.AddDrawCall(); - break; - } - - if(m_CurIB) - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); - - // End draw - Clean(); -} - -void SharedVertexBuffer::FillVertexArrayInfo(VertexDataInfo& 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 += 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].componentType = GetDefaultShaderChannelFormat(attrIdx); - dst.attributes[attrIdx].componentNum = GetDefaultShaderChannelDimension(attrIdx); - dst.attributes[attrIdx].stride = m_CurStride; - - dst.enableMask |= Mask(attrIdx); - } - } -} - -void SharedVertexBuffer::Clean() -{ - if (m_CurVB) - { - GPU::ReleaseBuffer(m_CurVB); - m_CurVB = 0; - } - - if (m_CurIB) - { - GPU::ReleaseBuffer(m_CurIB); - m_CurIB = 0; - } - - m_CurPrimitive = Primitive_Triangle; - m_CurAttrMask = 0; - m_CurStride = 0; - m_CurVertexCount = 0; - m_CurIndexCount = 0; - - m_CurVBData.clear(); - m_CurIBData.clear(); -} - -static uint32 sEnabledArrays = 0; - -void SetupDefaultVertexArray(const VertexDataInfo& info) -{ - glBindBuffer(GL_ARRAY_BUFFER, info.buffer); - - for (int attrIdx = 0; attrIdx < VertexAttr_Count; ++attrIdx) - { - if (info.enableMask & Mask(attrIdx)) - { - if (!sEnabledArrays & Mask(attrIdx)) - glEnableVertexAttribArray(attrIdx); - int numCompo = info.attributes[attrIdx].componentNum; - GLenum compoType = kGLVertexAttrFormat[info.attributes[attrIdx].componentType]; - bool normalized = IsGLVertexAttrNeedNormalized(attrIdx, compoType); - uint stride = info.attributes[attrIdx].stride; - const void* pointer = info.attributes[attrIdx].pointer; - - glVertexAttribPointer(attrIdx, numCompo, compoType, normalized ? GL_TRUE : GL_FALSE, stride, pointer); - } - else if(sEnabledArrays & Mask(attrIdx)) - glDisableVertexAttribArray(attrIdx); - } - sEnabledArrays = info.enableMask; -} - -void InvalidateVertexInputCache() -{ - sEnabledArrays = 0; - for(int attrIdx = 0; attrIdx < VertexAttr_Count; ++attrIdx) - glDisableVertexAttribArray(attrIdx); -}
\ No newline at end of file diff --git a/Runtime/Graphics/VertexBuffer.h b/Runtime/Graphics/VertexBuffer.h index b38b0b6..05aa16c 100644 --- a/Runtime/Graphics/VertexBuffer.h +++ b/Runtime/Graphics/VertexBuffer.h @@ -8,21 +8,8 @@ #include "OpenGL.h" #include "GPUDataBuffer.h" - -// 默认的顶点属性,够用了 -enum EVertexAttr -{ - VertexAttr_Position = 0, - VertexAttr_Normal, - VertexAttr_Tangent, - VertexAttr_Color, - VertexAttr_UV, - VertexAttr_UV2, - VertexAttr_UV3, - VertexAttr_UV4, - - VertexAttr_Count -}; +#include "DefaultVertexLayout.h" +#include "CustomVertexLayout.h" enum EPrimitive { @@ -31,22 +18,6 @@ enum EPrimitive Primitive_Point = 3, }; -struct VertexAttributeDescriptor -{ - const void* pointer; // 内存或显存 - uint componentType; - uint componentNum; - uint16 stride; -}; - -// GPU侧的顶点属性 -struct VertexDataInfo -{ - uint32 enableMask; - GLuint buffer; - VertexAttributeDescriptor attributes[VertexAttr_Count]; -}; - class VertexBuffer { public: @@ -63,7 +34,6 @@ public: void Draw(); private: - VertexBufferType m_Type; GPU::DataBuffer *m_VB; GPU::DataBuffer *m_IB;// vertex buffer and index buffer @@ -83,7 +53,7 @@ public: private: - void FillVertexArrayInfo(VertexDataInfo& dst); + void FillVertexDataInfo(DefaultVertexLayout& dst); void Clean(); |