summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorchai <chaifix@163.com>2021-10-28 00:47:35 +0800
committerchai <chaifix@163.com>2021-10-28 00:47:35 +0800
commit1b6f71b2777bdc74d63f988346a8cfee766718b0 (patch)
treeae710ba057f4841e7d0911eb4d3e0c346f79a524
parent305ca0a09d4e750186b5190432de47f3493e806a (diff)
+DefaultVertexLayout
-rw-r--r--Projects/VisualStudio/Editor/Editor.vcxproj7
-rw-r--r--Projects/VisualStudio/Editor/Editor.vcxproj.filters21
-rw-r--r--Runtime/Graphics/CustomVertexLayout.cpp0
-rw-r--r--Runtime/Graphics/CustomVertexLayout.h15
-rw-r--r--Runtime/Graphics/DefaultVertexLayout.cpp119
-rw-r--r--Runtime/Graphics/DefaultVertexLayout.h52
-rw-r--r--Runtime/Graphics/SharedVertexBuffer.cpp190
-rw-r--r--Runtime/Graphics/VertexAttribute.cpp19
-rw-r--r--Runtime/Graphics/VertexAttribute.h35
-rw-r--r--Runtime/Graphics/VertexBuffer.cpp311
-rw-r--r--Runtime/Graphics/VertexBuffer.h36
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();