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(); | 
