201 lines
6.3 KiB
C++
201 lines
6.3 KiB
C++
// Copyright (C) 2013 Jérôme Leclercq
|
|
// This file is part of the "Nazara Engine - Utility module"
|
|
// For conditions of distribution and use, see copyright notice in Config.hpp
|
|
|
|
#include <Nazara/Utility/VertexDeclaration.hpp>
|
|
#include <Nazara/Core/Error.hpp>
|
|
#include <Nazara/Utility/Config.hpp>
|
|
#include <cstring>
|
|
#include <Nazara/Utility/Debug.hpp>
|
|
|
|
namespace
|
|
{
|
|
unsigned int attributeSize[nzAttributeType_Max+1] =
|
|
{
|
|
4, // nzAttributeType_Color
|
|
1, // nzAttributeType_Double1
|
|
2, // nzAttributeType_Double2
|
|
3, // nzAttributeType_Double3
|
|
4, // nzAttributeType_Double4
|
|
1, // nzAttributeType_Float1
|
|
2, // nzAttributeType_Float2
|
|
3, // nzAttributeType_Float3
|
|
4 // nzAttributeType_Float4
|
|
};
|
|
|
|
static_assert(sizeof(attributeSize)/sizeof(unsigned int) == nzAttributeType_Max+1, "Attribute size array is incomplete");
|
|
|
|
unsigned int attributeStride[nzAttributeType_Max+1] =
|
|
{
|
|
4*sizeof(nzUInt8), // nzAttributeType_Color
|
|
1*sizeof(double), // nzAttributeType_Double1
|
|
2*sizeof(double), // nzAttributeType_Double2
|
|
3*sizeof(double), // nzAttributeType_Double3
|
|
4*sizeof(double), // nzAttributeType_Double4
|
|
1*sizeof(float), // nzAttributeType_Float1
|
|
2*sizeof(float), // nzAttributeType_Float2
|
|
3*sizeof(float), // nzAttributeType_Float3
|
|
4*sizeof(float) // nzAttributeType_Float4
|
|
};
|
|
|
|
static_assert(sizeof(attributeStride)/sizeof(unsigned int) == nzAttributeType_Max+1, "Attribute stride array is incomplete");
|
|
}
|
|
|
|
NzVertexDeclaration::NzVertexDeclaration() :
|
|
m_stride(0)
|
|
{
|
|
}
|
|
|
|
NzVertexDeclaration::NzVertexDeclaration(NzVertexDeclaration& declaration) :
|
|
NzResource(),
|
|
m_stride(declaration.m_stride)
|
|
{
|
|
std::memcpy(m_attributes, declaration.m_attributes, sizeof(Attribute)*(nzAttributeUsage_Max+1));
|
|
}
|
|
|
|
void NzVertexDeclaration::DisableAttribute(nzAttributeUsage usage)
|
|
{
|
|
#ifdef NAZARA_DEBUG
|
|
if (usage > nzAttributeUsage_Max)
|
|
{
|
|
NazaraError("Attribute usage out of enum");
|
|
return;
|
|
}
|
|
#endif
|
|
|
|
Attribute& attribute = m_attributes[usage];
|
|
|
|
if (attribute.enabled)
|
|
{
|
|
attribute.enabled = false;
|
|
m_stride -= attributeStride[attribute.type];
|
|
}
|
|
}
|
|
|
|
void NzVertexDeclaration::EnableAttribute(nzAttributeUsage usage, nzAttributeType type, unsigned int offset)
|
|
{
|
|
#ifdef NAZARA_DEBUG
|
|
if (usage > nzAttributeUsage_Max)
|
|
{
|
|
NazaraError("Attribute usage out of enum");
|
|
return;
|
|
}
|
|
#endif
|
|
|
|
Attribute& attribute = m_attributes[usage];
|
|
|
|
if (attribute.enabled)
|
|
m_stride -= attributeStride[attribute.type];
|
|
else
|
|
attribute.enabled = true;
|
|
|
|
attribute.offset = offset;
|
|
attribute.type = type;
|
|
|
|
m_stride += attributeStride[type];
|
|
}
|
|
|
|
void NzVertexDeclaration::GetAttribute(nzAttributeUsage usage, bool* enabled, nzAttributeType* type, unsigned int* offset) const
|
|
{
|
|
#ifdef NAZARA_DEBUG
|
|
if (usage > nzAttributeUsage_Max)
|
|
{
|
|
NazaraError("Attribute usage out of enum");
|
|
return;
|
|
}
|
|
#endif
|
|
|
|
const Attribute& attribute = m_attributes[usage];
|
|
|
|
if (enabled)
|
|
*enabled = attribute.enabled;
|
|
|
|
if (type)
|
|
*type = attribute.type;
|
|
|
|
if (offset)
|
|
*offset = attribute.offset;
|
|
}
|
|
|
|
unsigned int NzVertexDeclaration::GetStride() const
|
|
{
|
|
return m_stride;
|
|
}
|
|
|
|
void NzVertexDeclaration::SetStride(unsigned int stride)
|
|
{
|
|
m_stride = stride;
|
|
}
|
|
|
|
NzVertexDeclaration& NzVertexDeclaration::operator=(const NzVertexDeclaration& declaration)
|
|
{
|
|
std::memcpy(m_attributes, declaration.m_attributes, sizeof(Attribute)*(nzAttributeUsage_Max+1));
|
|
m_stride = declaration.m_stride;
|
|
|
|
return *this;
|
|
}
|
|
|
|
NzVertexDeclaration* NzVertexDeclaration::Get(nzVertexLayout layout)
|
|
{
|
|
#ifdef NAZARA_DEBUG
|
|
if (layout > nzVertexLayout_Max)
|
|
{
|
|
NazaraError("Vertex layout out of enum");
|
|
return nullptr;
|
|
}
|
|
#endif
|
|
|
|
return &s_declarations[layout];
|
|
}
|
|
|
|
unsigned int NzVertexDeclaration::GetAttributeSize(nzAttributeType type)
|
|
{
|
|
#ifdef NAZARA_DEBUG
|
|
if (type > nzAttributeType_Max)
|
|
{
|
|
NazaraError("Attribute type out of enum");
|
|
return 0;
|
|
}
|
|
#endif
|
|
|
|
return attributeSize[type];
|
|
}
|
|
|
|
bool NzVertexDeclaration::Initialize()
|
|
{
|
|
s_declarations[nzVertexLayout_XY].EnableAttribute(nzAttributeUsage_Position, nzAttributeType_Float2, 0);
|
|
|
|
s_declarations[nzVertexLayout_XY_UV].EnableAttribute(nzAttributeUsage_Position, nzAttributeType_Float2, 0);
|
|
s_declarations[nzVertexLayout_XY_UV].EnableAttribute(nzAttributeUsage_TexCoord, nzAttributeType_Float2, 2*sizeof(float));
|
|
|
|
s_declarations[nzVertexLayout_XYZ].EnableAttribute(nzAttributeUsage_Position, nzAttributeType_Float3, 0);
|
|
|
|
s_declarations[nzVertexLayout_XYZ_Normal].EnableAttribute(nzAttributeUsage_Position, nzAttributeType_Float3, 0);
|
|
s_declarations[nzVertexLayout_XYZ_Normal].EnableAttribute(nzAttributeUsage_Normal, nzAttributeType_Float3, 3*sizeof(float));
|
|
|
|
s_declarations[nzVertexLayout_XYZ_Normal_UV].EnableAttribute(nzAttributeUsage_Position, nzAttributeType_Float3, 0);
|
|
s_declarations[nzVertexLayout_XYZ_Normal_UV].EnableAttribute(nzAttributeUsage_Normal, nzAttributeType_Float3, 3*sizeof(float));
|
|
s_declarations[nzVertexLayout_XYZ_Normal_UV].EnableAttribute(nzAttributeUsage_TexCoord, nzAttributeType_Float2, (3+3)*sizeof(float));
|
|
|
|
s_declarations[nzVertexLayout_XYZ_Normal_UV_Tangent].EnableAttribute(nzAttributeUsage_Position, nzAttributeType_Float3, 0);
|
|
s_declarations[nzVertexLayout_XYZ_Normal_UV_Tangent].EnableAttribute(nzAttributeUsage_Normal, nzAttributeType_Float3, 3*sizeof(float));
|
|
s_declarations[nzVertexLayout_XYZ_Normal_UV_Tangent].EnableAttribute(nzAttributeUsage_TexCoord, nzAttributeType_Float2, (3+3)*sizeof(float));
|
|
s_declarations[nzVertexLayout_XYZ_Normal_UV_Tangent].EnableAttribute(nzAttributeUsage_Tangent, nzAttributeType_Float3, (3+3+2)*sizeof(float));
|
|
|
|
s_declarations[nzVertexLayout_XYZ_UV].EnableAttribute(nzAttributeUsage_Position, nzAttributeType_Float3, 0);
|
|
s_declarations[nzVertexLayout_XYZ_UV].EnableAttribute(nzAttributeUsage_TexCoord, nzAttributeType_Float2, 3*sizeof(float));
|
|
|
|
s_declarations[nzVertexLayout_Matrix4].EnableAttribute(nzAttributeUsage_InstanceData0, nzAttributeType_Float4, 0*4*sizeof(float));
|
|
s_declarations[nzVertexLayout_Matrix4].EnableAttribute(nzAttributeUsage_InstanceData1, nzAttributeType_Float4, 1*4*sizeof(float));
|
|
s_declarations[nzVertexLayout_Matrix4].EnableAttribute(nzAttributeUsage_InstanceData2, nzAttributeType_Float4, 2*4*sizeof(float));
|
|
s_declarations[nzVertexLayout_Matrix4].EnableAttribute(nzAttributeUsage_InstanceData3, nzAttributeType_Float4, 3*4*sizeof(float));
|
|
|
|
return true;
|
|
}
|
|
|
|
void NzVertexDeclaration::Uninitialize()
|
|
{
|
|
}
|
|
|
|
NzVertexDeclaration NzVertexDeclaration::s_declarations[nzVertexLayout_Max+1];
|