1
0
forked from 0ad/0ad

Removes duplication of backend format in VertexArray usages, optimizes vertex color attribute of quad overlay.

This was SVN commit r26609.
This commit is contained in:
Vladislav Belov 2022-03-08 23:28:31 +00:00
parent 6a09087225
commit 12c304e494
9 changed files with 112 additions and 136 deletions

View File

@ -159,12 +159,10 @@ CMiniMapTexture::CMiniMapTexture(CSimulation2& simulation)
} }
m_HalfBlinkDuration = blinkDuration / 2.0; m_HalfBlinkDuration = blinkDuration / 2.0;
m_AttributePos.type = GL_FLOAT; m_AttributePos.format = Renderer::Backend::Format::R32G32_SFLOAT;
m_AttributePos.elems = 2;
m_VertexArray.AddAttribute(&m_AttributePos); m_VertexArray.AddAttribute(&m_AttributePos);
m_AttributeColor.type = GL_UNSIGNED_BYTE; m_AttributeColor.format = Renderer::Backend::Format::R8G8B8A8_UNORM;
m_AttributeColor.elems = 4;
m_VertexArray.AddAttribute(&m_AttributeColor); m_VertexArray.AddAttribute(&m_AttributeColor);
m_VertexArray.SetNumberOfVertices(MAX_ENTITIES_DRAWN * 4); m_VertexArray.SetNumberOfVertices(MAX_ENTITIES_DRAWN * 4);
@ -569,9 +567,9 @@ void CMiniMapTexture::RenderFinalTexture(
const GLsizei stride = (GLsizei)m_VertexArray.GetStride(); const GLsizei stride = (GLsizei)m_VertexArray.GetStride();
shader->VertexPointer( shader->VertexPointer(
Renderer::Backend::Format::R32G32_SFLOAT, stride, base + m_AttributePos.offset); m_AttributePos.format, stride, base + m_AttributePos.offset);
shader->ColorPointer( shader->ColorPointer(
Renderer::Backend::Format::R8G8B8A8_UNORM, stride, base + m_AttributeColor.offset); m_AttributeColor.format, stride, base + m_AttributeColor.offset);
shader->AssertPointersBound(); shader->AssertPointersBound();
deviceCommandContext->SetIndexBuffer(m_IndexArray.GetBuffer()); deviceCommandContext->SetIndexBuffer(m_IndexArray.GetBuffer());

View File

@ -48,20 +48,16 @@ CParticleEmitter::CParticleEmitter(const CParticleEmitterTypePtr& type) :
m_Particles.reserve(m_Type->m_MaxParticles); m_Particles.reserve(m_Type->m_MaxParticles);
m_AttributePos.type = GL_FLOAT; m_AttributePos.format = Renderer::Backend::Format::R32G32B32_SFLOAT;
m_AttributePos.elems = 3;
m_VertexArray.AddAttribute(&m_AttributePos); m_VertexArray.AddAttribute(&m_AttributePos);
m_AttributeAxis.type = GL_FLOAT; m_AttributeAxis.format = Renderer::Backend::Format::R32G32_SFLOAT;
m_AttributeAxis.elems = 2;
m_VertexArray.AddAttribute(&m_AttributeAxis); m_VertexArray.AddAttribute(&m_AttributeAxis);
m_AttributeUV.type = GL_FLOAT; m_AttributeUV.format = Renderer::Backend::Format::R32G32_SFLOAT;
m_AttributeUV.elems = 2;
m_VertexArray.AddAttribute(&m_AttributeUV); m_VertexArray.AddAttribute(&m_AttributeUV);
m_AttributeColor.type = GL_UNSIGNED_BYTE; m_AttributeColor.format = Renderer::Backend::Format::R8G8B8A8_UNORM;
m_AttributeColor.elems = 4;
m_VertexArray.AddAttribute(&m_AttributeColor); m_VertexArray.AddAttribute(&m_AttributeColor);
m_VertexArray.SetNumberOfVertices(m_Type->m_MaxParticles * 4); m_VertexArray.SetNumberOfVertices(m_Type->m_MaxParticles * 4);
@ -209,17 +205,17 @@ void CParticleEmitter::RenderArray(
GLsizei stride = (GLsizei)m_VertexArray.GetStride(); GLsizei stride = (GLsizei)m_VertexArray.GetStride();
shader->VertexPointer( shader->VertexPointer(
Renderer::Backend::Format::R32G32B32_SFLOAT, stride, base + m_AttributePos.offset); m_AttributePos.format, stride, base + m_AttributePos.offset);
// Pass the sin/cos axis components as texcoords for no particular reason // Pass the sin/cos axis components as texcoords for no particular reason
// other than that they fit. (Maybe this should be glVertexAttrib* instead?) // other than that they fit. (Maybe this should be glVertexAttrib* instead?)
shader->TexCoordPointer( shader->TexCoordPointer(
GL_TEXTURE0, Renderer::Backend::Format::R32G32_SFLOAT, stride, base + m_AttributeUV.offset); GL_TEXTURE0, m_AttributeUV.format, stride, base + m_AttributeUV.offset);
shader->TexCoordPointer( shader->TexCoordPointer(
GL_TEXTURE1, Renderer::Backend::Format::R32G32_SFLOAT, stride, base + m_AttributeAxis.offset); GL_TEXTURE1, m_AttributeAxis.format, stride, base + m_AttributeAxis.offset);
shader->ColorPointer( shader->ColorPointer(
Renderer::Backend::Format::R8G8B8A8_UNORM, stride, base + m_AttributeColor.offset); m_AttributeColor.format, stride, base + m_AttributeColor.offset);
shader->AssertPointersBound(); shader->AssertPointersBound();

View File

@ -57,8 +57,7 @@ ShaderModelDef::ShaderModelDef(const CModelDefPtr& mdef)
m_UVs.resize(mdef->GetNumUVsPerVertex()); m_UVs.resize(mdef->GetNumUVsPerVertex());
for (size_t i = 0; i < mdef->GetNumUVsPerVertex(); ++i) for (size_t i = 0; i < mdef->GetNumUVsPerVertex(); ++i)
{ {
m_UVs[i].type = GL_FLOAT; m_UVs[i].format = Renderer::Backend::Format::R32G32_SFLOAT;
m_UVs[i].elems = 2;
m_Array.AddAttribute(&m_UVs[i]); m_Array.AddAttribute(&m_UVs[i]);
} }
@ -135,12 +134,10 @@ CModelRData* ShaderModelVertexRenderer::CreateModelData(const void* key, CModel*
// Positions and normals must be 16-byte aligned for SSE writes. // Positions and normals must be 16-byte aligned for SSE writes.
shadermodel->m_Position.type = GL_FLOAT; shadermodel->m_Position.format = Renderer::Backend::Format::R32G32B32A32_SFLOAT;
shadermodel->m_Position.elems = 4;
shadermodel->m_Array.AddAttribute(&shadermodel->m_Position); shadermodel->m_Array.AddAttribute(&shadermodel->m_Position);
shadermodel->m_Normal.type = GL_FLOAT; shadermodel->m_Normal.format = Renderer::Backend::Format::R32G32B32A32_SFLOAT;
shadermodel->m_Normal.elems = 4;
shadermodel->m_Array.AddAttribute(&shadermodel->m_Normal); shadermodel->m_Array.AddAttribute(&shadermodel->m_Normal);
shadermodel->m_Array.SetNumberOfVertices(mdef->GetNumVertices()); shadermodel->m_Array.SetNumberOfVertices(mdef->GetNumVertices());
@ -205,14 +202,14 @@ void ShaderModelVertexRenderer::PrepareModelDef(
if (streamflags & STREAM_UV0) if (streamflags & STREAM_UV0)
{ {
shader->TexCoordPointer( shader->TexCoordPointer(
GL_TEXTURE0, Renderer::Backend::Format::R32G32_SFLOAT, stride, GL_TEXTURE0, m->shadermodeldef->m_UVs[0].format, stride,
base + m->shadermodeldef->m_UVs[0].offset); base + m->shadermodeldef->m_UVs[0].offset);
} }
if ((streamflags & STREAM_UV1) && def.GetNumUVsPerVertex() >= 2) if ((streamflags & STREAM_UV1) && def.GetNumUVsPerVertex() >= 2)
{ {
shader->TexCoordPointer( shader->TexCoordPointer(
GL_TEXTURE1, Renderer::Backend::Format::R32G32_SFLOAT, stride, GL_TEXTURE1, m->shadermodeldef->m_UVs[1].format, stride,
base + m->shadermodeldef->m_UVs[1].offset); base + m->shadermodeldef->m_UVs[1].offset);
} }
} }

View File

@ -60,19 +60,16 @@ IModelDef::IModelDef(const CModelDefPtr& mdef, bool gpuSkinning, bool calculateT
{ {
size_t numVertices = mdef->GetNumVertices(); size_t numVertices = mdef->GetNumVertices();
m_Position.type = GL_FLOAT; m_Position.format = Renderer::Backend::Format::R32G32B32_SFLOAT;
m_Position.elems = 3;
m_Array.AddAttribute(&m_Position); m_Array.AddAttribute(&m_Position);
m_Normal.type = GL_FLOAT; m_Normal.format = Renderer::Backend::Format::R32G32B32_SFLOAT;
m_Normal.elems = 3;
m_Array.AddAttribute(&m_Normal); m_Array.AddAttribute(&m_Normal);
m_UVs.resize(mdef->GetNumUVsPerVertex()); m_UVs.resize(mdef->GetNumUVsPerVertex());
for (size_t i = 0; i < mdef->GetNumUVsPerVertex(); i++) for (size_t i = 0; i < mdef->GetNumUVsPerVertex(); i++)
{ {
m_UVs[i].type = GL_FLOAT; m_UVs[i].format = Renderer::Backend::Format::R32G32_SFLOAT;
m_UVs[i].elems = 2;
m_Array.AddAttribute(&m_UVs[i]); m_Array.AddAttribute(&m_UVs[i]);
} }
@ -85,12 +82,10 @@ IModelDef::IModelDef(const CModelDefPtr& mdef, bool gpuSkinning, bool calculateT
LOGERROR("Model '%s' has too many bones %zu/64", mdef->GetName().string8().c_str(), mdef->GetNumBones() + 1); LOGERROR("Model '%s' has too many bones %zu/64", mdef->GetName().string8().c_str(), mdef->GetNumBones() + 1);
ENSURE(mdef->GetNumBones() + 1 <= 64); ENSURE(mdef->GetNumBones() + 1 <= 64);
m_BlendJoints.type = GL_UNSIGNED_BYTE; m_BlendJoints.format = Renderer::Backend::Format::R8G8B8A8_UINT;
m_BlendJoints.elems = 4;
m_Array.AddAttribute(&m_BlendJoints); m_Array.AddAttribute(&m_BlendJoints);
m_BlendWeights.type = GL_UNSIGNED_BYTE; m_BlendWeights.format = Renderer::Backend::Format::R8G8B8A8_UNORM;
m_BlendWeights.elems = 4;
m_Array.AddAttribute(&m_BlendWeights); m_Array.AddAttribute(&m_BlendWeights);
} }
@ -98,8 +93,7 @@ IModelDef::IModelDef(const CModelDefPtr& mdef, bool gpuSkinning, bool calculateT
{ {
// Generate tangents for the geometry:- // Generate tangents for the geometry:-
m_Tangent.type = GL_FLOAT; m_Tangent.format = Renderer::Backend::Format::R32G32B32A32_SFLOAT;
m_Tangent.elems = 4;
m_Array.AddAttribute(&m_Tangent); m_Array.AddAttribute(&m_Tangent);
// floats per vertex; position + normal + tangent + UV*sets [+ GPUskinning] // floats per vertex; position + normal + tangent + UV*sets [+ GPUskinning]
@ -333,21 +327,21 @@ void InstancingModelRenderer::PrepareModelDef(
if (streamflags & STREAM_POS) if (streamflags & STREAM_POS)
{ {
shader->VertexPointer( shader->VertexPointer(
Renderer::Backend::Format::R32G32B32_SFLOAT, stride, m->imodeldef->m_Position.format, stride,
base + m->imodeldef->m_Position.offset); base + m->imodeldef->m_Position.offset);
} }
if (streamflags & STREAM_NORMAL) if (streamflags & STREAM_NORMAL)
{ {
shader->NormalPointer( shader->NormalPointer(
Renderer::Backend::Format::R32G32B32_SFLOAT, stride, m->imodeldef->m_Normal.format, stride,
base + m->imodeldef->m_Normal.offset); base + m->imodeldef->m_Normal.offset);
} }
if (m->calculateTangents) if (m->calculateTangents)
{ {
shader->VertexAttribPointer( shader->VertexAttribPointer(
str_a_tangent, Renderer::Backend::Format::R32G32B32A32_SFLOAT, str_a_tangent, m->imodeldef->m_Tangent.format,
GL_FALSE, stride, base + m->imodeldef->m_Tangent.offset); GL_FALSE, stride, base + m->imodeldef->m_Tangent.offset);
} }
@ -358,7 +352,7 @@ void InstancingModelRenderer::PrepareModelDef(
if (def.GetNumUVsPerVertex() >= uv + 1) if (def.GetNumUVsPerVertex() >= uv + 1)
{ {
shader->TexCoordPointer( shader->TexCoordPointer(
GL_TEXTURE0 + uv, Renderer::Backend::Format::R32G32_SFLOAT, stride, GL_TEXTURE0 + uv, m->imodeldef->m_UVs[uv].format, stride,
base + m->imodeldef->m_UVs[uv].offset); base + m->imodeldef->m_UVs[uv].offset);
} }
else else
@ -369,10 +363,10 @@ void InstancingModelRenderer::PrepareModelDef(
if (m->gpuSkinning) if (m->gpuSkinning)
{ {
shader->VertexAttribPointer( shader->VertexAttribPointer(
str_a_skinJoints, Renderer::Backend::Format::R8G8B8A8_UINT, GL_FALSE, str_a_skinJoints, m->imodeldef->m_BlendJoints.format, GL_FALSE,
stride, base + m->imodeldef->m_BlendJoints.offset); stride, base + m->imodeldef->m_BlendJoints.offset);
shader->VertexAttribPointer( shader->VertexAttribPointer(
str_a_skinWeights, Renderer::Backend::Format::R8G8B8A8_UNORM, GL_TRUE, str_a_skinWeights, m->imodeldef->m_BlendWeights.format, GL_TRUE,
stride, base + m->imodeldef->m_BlendWeights.offset); stride, base + m->imodeldef->m_BlendWeights.offset);
} }

View File

@ -157,16 +157,13 @@ OverlayRendererInternals::OverlayRendererInternals()
: quadVertices(Renderer::Backend::GL::CBuffer::Type::VERTEX, true), : quadVertices(Renderer::Backend::GL::CBuffer::Type::VERTEX, true),
quadIndices(false) quadIndices(false)
{ {
quadAttributePos.elems = 3; quadAttributePos.format = Renderer::Backend::Format::R32G32B32_SFLOAT;
quadAttributePos.type = GL_FLOAT;
quadVertices.AddAttribute(&quadAttributePos); quadVertices.AddAttribute(&quadAttributePos);
quadAttributeColor.elems = 4; quadAttributeColor.format = Renderer::Backend::Format::R8G8B8A8_UNORM;
quadAttributeColor.type = GL_FLOAT;
quadVertices.AddAttribute(&quadAttributeColor); quadVertices.AddAttribute(&quadAttributeColor);
quadAttributeUV.elems = 2; quadAttributeUV.format = Renderer::Backend::Format::R16G16_SINT;
quadAttributeUV.type = GL_SHORT; // don't use GL_UNSIGNED_SHORT here, TexCoordPointer won't accept it
quadVertices.AddAttribute(&quadAttributeUV); quadVertices.AddAttribute(&quadAttributeUV);
// Note that we're reusing the textured overlay line shader for the quad overlay rendering. This // Note that we're reusing the textured overlay line shader for the quad overlay rendering. This
@ -310,7 +307,7 @@ void OverlayRenderer::PrepareForRendering()
// Write quad overlay vertices/indices to VA backing store // Write quad overlay vertices/indices to VA backing store
VertexArrayIterator<CVector3D> vertexPos = m->quadAttributePos.GetIterator<CVector3D>(); VertexArrayIterator<CVector3D> vertexPos = m->quadAttributePos.GetIterator<CVector3D>();
VertexArrayIterator<CVector4D> vertexColor = m->quadAttributeColor.GetIterator<CVector4D>(); VertexArrayIterator<SColor4ub> vertexColor = m->quadAttributeColor.GetIterator<SColor4ub>();
VertexArrayIterator<short[2]> vertexUV = m->quadAttributeUV.GetIterator<short[2]>(); VertexArrayIterator<short[2]> vertexUV = m->quadAttributeUV.GetIterator<short[2]>();
size_t indicesIdx = 0; size_t indicesIdx = 0;
@ -332,9 +329,7 @@ void OverlayRenderer::PrepareForRendering()
{ {
const SOverlayQuad* quad = batchRenderData.m_Quads[i]; const SOverlayQuad* quad = batchRenderData.m_Quads[i];
// TODO: this is kind of ugly, the iterator should use a type that can have quad->m_Color assigned const SColor4ub quadColor = quad->m_Color.AsSColor4ub();
// to it directly
const CVector4D quadColor(quad->m_Color.r, quad->m_Color.g, quad->m_Color.b, quad->m_Color.a);
*vertexPos++ = quad->m_Corners[0] + vOffset; *vertexPos++ = quad->m_Corners[0] + vOffset;
*vertexPos++ = quad->m_Corners[1] + vOffset; *vertexPos++ = quad->m_Corners[1] + vOffset;
@ -573,16 +568,16 @@ void OverlayRenderer::RenderQuadOverlays(
int streamflags = shader->GetStreamFlags(); int streamflags = shader->GetStreamFlags();
if (streamflags & STREAM_POS) if (streamflags & STREAM_POS)
shader->VertexPointer(Renderer::Backend::Format::R32G32B32_SFLOAT, vertexStride, vertexBase + m->quadAttributePos.offset); shader->VertexPointer(m->quadAttributePos.format, vertexStride, vertexBase + m->quadAttributePos.offset);
if (streamflags & STREAM_UV0) if (streamflags & STREAM_UV0)
shader->TexCoordPointer(GL_TEXTURE0, Renderer::Backend::Format::R16G16_SINT, vertexStride, vertexBase + m->quadAttributeUV.offset); shader->TexCoordPointer(GL_TEXTURE0, m->quadAttributeUV.format, vertexStride, vertexBase + m->quadAttributeUV.offset);
if (streamflags & STREAM_UV1) if (streamflags & STREAM_UV1)
shader->TexCoordPointer(GL_TEXTURE1, Renderer::Backend::Format::R16G16_SINT, vertexStride, vertexBase + m->quadAttributeUV.offset); shader->TexCoordPointer(GL_TEXTURE1, m->quadAttributeUV.format, vertexStride, vertexBase + m->quadAttributeUV.offset);
if (streamflags & STREAM_COLOR) if (streamflags & STREAM_COLOR)
shader->ColorPointer(Renderer::Backend::Format::R32G32B32A32_SFLOAT, vertexStride, vertexBase + m->quadAttributeColor.offset); shader->ColorPointer(m->quadAttributeColor.format, vertexStride, vertexBase + m->quadAttributeColor.offset);
shader->AssertPointersBound(); shader->AssertPointersBound();
deviceCommandContext->DrawIndexed(m->quadIndices.GetOffset() + batchRenderData.m_IndicesBase, batchNumQuads * 6, 0); deviceCommandContext->DrawIndexed(m->quadIndices.GetOffset() + batchRenderData.m_IndicesBase, batchNumQuads * 6, 0);

View File

@ -243,9 +243,9 @@ void SkyManager::RenderSky(
const GLsizei stride = static_cast<GLsizei>(m_VertexArray.GetStride()); const GLsizei stride = static_cast<GLsizei>(m_VertexArray.GetStride());
shader->VertexPointer( shader->VertexPointer(
Renderer::Backend::Format::R32G32B32_SFLOAT, stride, base + m_AttributePosition.offset); m_AttributePosition.format, stride, base + m_AttributePosition.offset);
shader->TexCoordPointer( shader->TexCoordPointer(
GL_TEXTURE0, Renderer::Backend::Format::R32G32B32_SFLOAT, stride, base + m_AttributeUV.offset); GL_TEXTURE0, m_AttributeUV.format, stride, base + m_AttributeUV.offset);
shader->AssertPointersBound(); shader->AssertPointersBound();
deviceCommandContext->Draw(0, m_VertexArray.GetNumberOfVertices()); deviceCommandContext->Draw(0, m_VertexArray.GetNumberOfVertices());
@ -256,12 +256,10 @@ void SkyManager::RenderSky(
void SkyManager::CreateSkyCube() void SkyManager::CreateSkyCube()
{ {
m_AttributePosition.type = GL_FLOAT; m_AttributePosition.format = Renderer::Backend::Format::R32G32B32_SFLOAT;
m_AttributePosition.elems = 3;
m_VertexArray.AddAttribute(&m_AttributePosition); m_VertexArray.AddAttribute(&m_AttributePosition);
m_AttributeUV.type = GL_FLOAT; m_AttributeUV.format = Renderer::Backend::Format::R32G32B32_SFLOAT;
m_AttributeUV.elems = 3;
m_VertexArray.AddAttribute(&m_AttributeUV); m_VertexArray.AddAttribute(&m_AttributeUV);
// 6 sides of cube with 6 vertices. // 6 sides of cube with 6 vertices.

View File

@ -18,7 +18,6 @@
#include "precompiled.h" #include "precompiled.h"
#include "lib/alignment.h" #include "lib/alignment.h"
#include "lib/ogl.h"
#include "lib/sysdep/rtl.h" #include "lib/sysdep/rtl.h"
#include "maths/Vector3D.h" #include "maths/Vector3D.h"
#include "maths/Vector4D.h" #include "maths/Vector4D.h"
@ -29,6 +28,41 @@
#include "renderer/VertexBuffer.h" #include "renderer/VertexBuffer.h"
#include "renderer/VertexBufferManager.h" #include "renderer/VertexBufferManager.h"
namespace
{
size_t GetAttributeSize(const Renderer::Backend::Format format)
{
switch (format)
{
case Renderer::Backend::Format::R8G8B8A8_UNORM: FALLTHROUGH;
case Renderer::Backend::Format::R8G8B8A8_UINT:
return sizeof(u8) * 4;
case Renderer::Backend::Format::A8_UNORM: FALLTHROUGH;
return sizeof(u8);
case Renderer::Backend::Format::R16_UNORM: FALLTHROUGH;
case Renderer::Backend::Format::R16_UINT: FALLTHROUGH;
case Renderer::Backend::Format::R16_SINT:
return sizeof(u16);
case Renderer::Backend::Format::R16G16_UNORM: FALLTHROUGH;
case Renderer::Backend::Format::R16G16_UINT: FALLTHROUGH;
case Renderer::Backend::Format::R16G16_SINT:
return sizeof(u16) * 2;
case Renderer::Backend::Format::R32_SFLOAT:
return sizeof(float);
case Renderer::Backend::Format::R32G32_SFLOAT:
return sizeof(float) * 2;
case Renderer::Backend::Format::R32G32B32_SFLOAT:
return sizeof(float) * 3;
case Renderer::Backend::Format::R32G32B32A32_SFLOAT:
return sizeof(float) * 4;
default:
break;
};
return 0;
}
} // anonymous namespace
VertexArray::VertexArray( VertexArray::VertexArray(
const Renderer::Backend::GL::CBuffer::Type type, const bool dynamic) const Renderer::Backend::GL::CBuffer::Type type, const bool dynamic)
@ -67,11 +101,8 @@ void VertexArray::SetNumberOfVertices(const size_t numberOfVertices)
// Add vertex attributes like Position, Normal, UV // Add vertex attributes like Position, Normal, UV
void VertexArray::AddAttribute(Attribute* attr) void VertexArray::AddAttribute(Attribute* attr)
{ {
ENSURE( // Attribute is supported is its size is greater than zero.
(attr->type == GL_FLOAT || attr->type == GL_SHORT || attr->type == GL_UNSIGNED_SHORT || attr->type == GL_UNSIGNED_BYTE) ENSURE(GetAttributeSize(attr->format) > 0 && "Unsupported attribute.");
&& "Unsupported attribute type"
);
ENSURE(attr->elems >= 1 && attr->elems <= 4);
attr->vertexArray = this; attr->vertexArray = this;
m_Attributes.push_back(attr); m_Attributes.push_back(attr);
@ -86,8 +117,9 @@ template<>
VertexArrayIterator<CVector3D> VertexArray::Attribute::GetIterator<CVector3D>() const VertexArrayIterator<CVector3D> VertexArray::Attribute::GetIterator<CVector3D>() const
{ {
ENSURE(vertexArray); ENSURE(vertexArray);
ENSURE(type == GL_FLOAT); ENSURE(
ENSURE(elems >= 3); format == Renderer::Backend::Format::R32G32B32_SFLOAT ||
format == Renderer::Backend::Format::R32G32B32A32_SFLOAT);
return vertexArray->MakeIterator<CVector3D>(this); return vertexArray->MakeIterator<CVector3D>(this);
} }
@ -96,8 +128,7 @@ template<>
VertexArrayIterator<CVector4D> VertexArray::Attribute::GetIterator<CVector4D>() const VertexArrayIterator<CVector4D> VertexArray::Attribute::GetIterator<CVector4D>() const
{ {
ENSURE(vertexArray); ENSURE(vertexArray);
ENSURE(type == GL_FLOAT); ENSURE(format == Renderer::Backend::Format::R32G32B32A32_SFLOAT);
ENSURE(elems >= 4);
return vertexArray->MakeIterator<CVector4D>(this); return vertexArray->MakeIterator<CVector4D>(this);
} }
@ -106,28 +137,18 @@ template<>
VertexArrayIterator<float[2]> VertexArray::Attribute::GetIterator<float[2]>() const VertexArrayIterator<float[2]> VertexArray::Attribute::GetIterator<float[2]>() const
{ {
ENSURE(vertexArray); ENSURE(vertexArray);
ENSURE(type == GL_FLOAT); ENSURE(format == Renderer::Backend::Format::R32G32_SFLOAT);
ENSURE(elems >= 2);
return vertexArray->MakeIterator<float[2]>(this); return vertexArray->MakeIterator<float[2]>(this);
} }
template<>
VertexArrayIterator<SColor3ub> VertexArray::Attribute::GetIterator<SColor3ub>() const
{
ENSURE(vertexArray);
ENSURE(type == GL_UNSIGNED_BYTE);
ENSURE(elems >= 3);
return vertexArray->MakeIterator<SColor3ub>(this);
}
template<> template<>
VertexArrayIterator<SColor4ub> VertexArray::Attribute::GetIterator<SColor4ub>() const VertexArrayIterator<SColor4ub> VertexArray::Attribute::GetIterator<SColor4ub>() const
{ {
ENSURE(vertexArray); ENSURE(vertexArray);
ENSURE(type == GL_UNSIGNED_BYTE); ENSURE(
ENSURE(elems >= 4); format == Renderer::Backend::Format::R8G8B8A8_UNORM ||
format == Renderer::Backend::Format::R8G8B8A8_UINT);
return vertexArray->MakeIterator<SColor4ub>(this); return vertexArray->MakeIterator<SColor4ub>(this);
} }
@ -136,8 +157,7 @@ template<>
VertexArrayIterator<u16> VertexArray::Attribute::GetIterator<u16>() const VertexArrayIterator<u16> VertexArray::Attribute::GetIterator<u16>() const
{ {
ENSURE(vertexArray); ENSURE(vertexArray);
ENSURE(type == GL_UNSIGNED_SHORT); ENSURE(format == Renderer::Backend::Format::R16_UINT);
ENSURE(elems >= 1);
return vertexArray->MakeIterator<u16>(this); return vertexArray->MakeIterator<u16>(this);
} }
@ -146,8 +166,7 @@ template<>
VertexArrayIterator<u16[2]> VertexArray::Attribute::GetIterator<u16[2]>() const VertexArrayIterator<u16[2]> VertexArray::Attribute::GetIterator<u16[2]>() const
{ {
ENSURE(vertexArray); ENSURE(vertexArray);
ENSURE(type == GL_UNSIGNED_SHORT); ENSURE(format == Renderer::Backend::Format::R16G16_UINT);
ENSURE(elems >= 2);
return vertexArray->MakeIterator<u16[2]>(this); return vertexArray->MakeIterator<u16[2]>(this);
} }
@ -156,8 +175,7 @@ template<>
VertexArrayIterator<u8> VertexArray::Attribute::GetIterator<u8>() const VertexArrayIterator<u8> VertexArray::Attribute::GetIterator<u8>() const
{ {
ENSURE(vertexArray); ENSURE(vertexArray);
ENSURE(type == GL_UNSIGNED_BYTE); ENSURE(format == Renderer::Backend::Format::A8_UNORM);
ENSURE(elems >= 1);
return vertexArray->MakeIterator<u8>(this); return vertexArray->MakeIterator<u8>(this);
} }
@ -166,8 +184,9 @@ template<>
VertexArrayIterator<u8[4]> VertexArray::Attribute::GetIterator<u8[4]>() const VertexArrayIterator<u8[4]> VertexArray::Attribute::GetIterator<u8[4]>() const
{ {
ENSURE(vertexArray); ENSURE(vertexArray);
ENSURE(type == GL_UNSIGNED_BYTE); ENSURE(
ENSURE(elems >= 4); format == Renderer::Backend::Format::R8G8B8A8_UNORM ||
format == Renderer::Backend::Format::R8G8B8A8_UINT);
return vertexArray->MakeIterator<u8[4]>(this); return vertexArray->MakeIterator<u8[4]>(this);
} }
@ -176,8 +195,7 @@ template<>
VertexArrayIterator<short> VertexArray::Attribute::GetIterator<short>() const VertexArrayIterator<short> VertexArray::Attribute::GetIterator<short>() const
{ {
ENSURE(vertexArray); ENSURE(vertexArray);
ENSURE(type == GL_SHORT); ENSURE(format == Renderer::Backend::Format::R16_SINT);
ENSURE(elems >= 1);
return vertexArray->MakeIterator<short>(this); return vertexArray->MakeIterator<short>(this);
} }
@ -186,8 +204,7 @@ template<>
VertexArrayIterator<short[2]> VertexArray::Attribute::GetIterator<short[2]>() const VertexArrayIterator<short[2]> VertexArray::Attribute::GetIterator<short[2]>() const
{ {
ENSURE(vertexArray); ENSURE(vertexArray);
ENSURE(type == GL_SHORT); ENSURE(format == Renderer::Backend::Format::R16G16_SINT);
ENSURE(elems >= 2);
return vertexArray->MakeIterator<short[2]>(this); return vertexArray->MakeIterator<short[2]>(this);
} }
@ -218,31 +235,11 @@ void VertexArray::Layout()
for (ssize_t idx = m_Attributes.size()-1; idx >= 0; --idx) for (ssize_t idx = m_Attributes.size()-1; idx >= 0; --idx)
{ {
Attribute* attr = m_Attributes[idx]; Attribute* attr = m_Attributes[idx];
if (attr->format == Renderer::Backend::Format::UNDEFINED)
if (!attr->type || !attr->elems)
continue; continue;
size_t attrSize = 0; const size_t attrSize = GetAttributeSize(attr->format);
switch(attr->type) ENSURE(attrSize > 0);
{
case GL_UNSIGNED_BYTE:
attrSize = sizeof(GLubyte);
break;
case GL_SHORT:
attrSize = sizeof(GLshort);
break;
case GL_UNSIGNED_SHORT:
attrSize = sizeof(GLushort);
break;
case GL_FLOAT:
attrSize = sizeof(GLfloat);
break;
default:
attrSize = 0;
debug_warn(L"Bad Attribute::type"); break;
}
attrSize *= attr->elems;
attr->offset = m_Stride; attr->offset = m_Stride;
@ -319,8 +316,7 @@ void VertexArray::FreeBackingStore()
VertexIndexArray::VertexIndexArray(const bool dynamic) : VertexIndexArray::VertexIndexArray(const bool dynamic) :
VertexArray(Renderer::Backend::GL::CBuffer::Type::INDEX, dynamic) VertexArray(Renderer::Backend::GL::CBuffer::Type::INDEX, dynamic)
{ {
m_Attr.type = GL_UNSIGNED_SHORT; m_Attr.format = Renderer::Backend::Format::R16_UINT;
m_Attr.elems = 1;
AddAttribute(&m_Attr); AddAttribute(&m_Attr);
} }

View File

@ -18,6 +18,7 @@
#ifndef INCLUDED_VERTEXARRAY #ifndef INCLUDED_VERTEXARRAY
#define INCLUDED_VERTEXARRAY #define INCLUDED_VERTEXARRAY
#include "renderer/backend/Format.h"
#include "renderer/backend/gl/Buffer.h" #include "renderer/backend/gl/Buffer.h"
#include "renderer/backend/gl/DeviceCommandContext.h" #include "renderer/backend/gl/DeviceCommandContext.h"
#include "renderer/VertexBufferManager.h" #include "renderer/VertexBufferManager.h"
@ -131,29 +132,26 @@ private:
// This class chooses the vertex layout at runtime, based on the attributes // This class chooses the vertex layout at runtime, based on the attributes
// that are actually needed. // that are actually needed.
// //
// Note that this class will not allocate any OpenGL resources until one // Note that this class will not allocate any backend resources until one
// of the Upload functions is called. // of the Upload functions is called.
class VertexArray class VertexArray
{ {
public: public:
struct Attribute struct Attribute
{ {
// Data type. Currently supported: GL_FLOAT, GL_SHORT, GL_UNSIGNED_SHORT, GL_UNSIGNED_BYTE. Renderer::Backend::Format format = Renderer::Backend::Format::UNDEFINED;
GLenum type;
// How many elements per vertex (e.g. 3 for RGB, 2 for UV)
GLuint elems;
// Offset (in bytes) into a vertex structure (filled in by Layout()) // Offset (in bytes) into a vertex structure (filled in by Layout())
size_t offset; size_t offset = 0;
VertexArray* vertexArray; VertexArray* vertexArray = nullptr;
Attribute() : type(0), elems(0), offset(0), vertexArray(0) { } Attribute() {}
// Get an iterator over the backing store for the given attribute that // Get an iterator over the backing store for the given attribute that
// initially points at the first vertex. // initially points at the first vertex.
// Supported types T: CVector3D, CVector4D, float[2], SColor3ub, SColor4ub, // Supported types T: CVector3D, CVector4D, float[2], SColor4ub,
// u16, u16[2], u8, u8[4], short, short[2]. // u16, u16[2], u8[4], short, short[2].
// This function verifies at runtime that the requested type T matches // This function verifies at runtime that the requested type T matches
// the attribute definition passed to AddAttribute(). // the attribute definition passed to AddAttribute().
template<typename T> template<typename T>
@ -201,7 +199,7 @@ private:
template<typename T> template<typename T>
VertexArrayIterator<T> MakeIterator(const Attribute* attr) VertexArrayIterator<T> MakeIterator(const Attribute* attr)
{ {
ENSURE(attr->type && attr->elems); ENSURE(attr->format != Renderer::Backend::Format::UNDEFINED);
return VertexArrayIterator<T>(m_BackingStore + attr->offset, m_Stride); return VertexArrayIterator<T>(m_BackingStore + attr->offset, m_Stride);
} }

View File

@ -36,7 +36,11 @@ enum class Format
A8_UNORM, A8_UNORM,
L8_UNORM, L8_UNORM,
R16_UNORM,
R16_UINT,
R16_SINT, R16_SINT,
R16G16_UNORM,
R16G16_UINT,
R16G16_SINT, R16G16_SINT,
R32_SFLOAT, R32_SFLOAT,