(Renderer) Improved vertex attribute code

Former-commit-id: eacb4df1848e7ae807ca607496a50a38451ea083
This commit is contained in:
Lynix 2014-07-12 14:59:14 +02:00
parent f2141f5756
commit 9137357725
1 changed files with 89 additions and 99 deletions

View File

@ -1760,120 +1760,111 @@ bool NzRenderer::EnsureStateUpdate()
unsigned int bufferOffset; unsigned int bufferOffset;
unsigned int stride; unsigned int stride;
NzHardwareBuffer* vertexBufferImpl = static_cast<NzHardwareBuffer*>(s_vertexBuffer->GetBuffer()->GetImpl()); // Pour éviter la duplication de code, on va utiliser une astuce via une boucle for
for (unsigned int i = 0; i < (s_instancing ? 2 : 1); ++i)
{
// Selon l'itération nous choisissons un buffer différent
const NzVertexBuffer* vertexBuffer = (i == 0) ? s_vertexBuffer : &s_instanceBuffer;
NzHardwareBuffer* vertexBufferImpl = static_cast<NzHardwareBuffer*>(vertexBuffer->GetBuffer()->GetImpl());
glBindBuffer(NzOpenGL::BufferTarget[nzBufferType_Vertex], vertexBufferImpl->GetOpenGLID()); glBindBuffer(NzOpenGL::BufferTarget[nzBufferType_Vertex], vertexBufferImpl->GetOpenGLID());
bufferOffset = s_vertexBuffer->GetStartOffset(); bufferOffset = vertexBuffer->GetStartOffset();
vertexDeclaration = s_vertexBuffer->GetVertexDeclaration(); vertexDeclaration = vertexBuffer->GetVertexDeclaration();
stride = vertexDeclaration->GetStride(); stride = vertexDeclaration->GetStride();
for (unsigned int i = nzVertexComponent_FirstVertexData; i <= nzVertexComponent_LastVertexData; ++i)
// On définit les bornes (une fois de plus selon l'itération)
unsigned int start = (i == 0) ? nzVertexComponent_FirstVertexData : nzVertexComponent_FirstInstanceData;
unsigned int end = (i == 0) ? nzVertexComponent_LastVertexData : nzVertexComponent_LastInstanceData;
for (unsigned int j = start; j <= end; ++j)
{ {
nzComponentType type; nzComponentType type;
bool enabled; bool enabled;
unsigned int offset; unsigned int offset;
vertexDeclaration->GetComponent(static_cast<nzVertexComponent>(i), &enabled, &type, &offset); vertexDeclaration->GetComponent(static_cast<nzVertexComponent>(j), &enabled, &type, &offset);
if (!IsComponentTypeSupported(type)) if (!IsComponentTypeSupported(type))
{ {
NazaraError("Invalid declaration: Vertex component 0x" + NzString::Number(i, 16) + " (type: 0x" + NzString::Number(type, 16) + ") is not supported"); NazaraError("Invalid vertex declaration " + NzString::Pointer(vertexDeclaration) + ": Vertex component 0x" + NzString::Number(j, 16) + " (type: 0x" + NzString::Number(type, 16) + ") is not supported");
updateFailed = true; updateFailed = true;
break; break;
} }
if (enabled) if (enabled)
{ {
glEnableVertexAttribArray(NzOpenGL::VertexComponentIndex[i]); glEnableVertexAttribArray(NzOpenGL::VertexComponentIndex[j]);
if (type <= nzComponentType_Double1 && type >= nzComponentType_Double4)
switch (type)
{ {
glVertexAttribLPointer(NzOpenGL::VertexComponentIndex[i], case nzComponentType_Color:
{
glVertexAttribPointer(NzOpenGL::VertexComponentIndex[j],
NzUtility::ComponentCount[type], NzUtility::ComponentCount[type],
NzOpenGL::ComponentType[type], NzOpenGL::ComponentType[type],
GL_TRUE,
stride, stride,
reinterpret_cast<void*>(bufferOffset + offset)); reinterpret_cast<void*>(bufferOffset + offset));
}
else if (type <= nzComponentType_Int1 && type >= nzComponentType_Int4)
{
glVertexAttribIPointer(NzOpenGL::VertexComponentIndex[i],
NzUtility::ComponentCount[type],
NzOpenGL::ComponentType[type],
stride,
reinterpret_cast<void*>(bufferOffset + offset));
}
else
{
glVertexAttribPointer(NzOpenGL::VertexComponentIndex[i],
NzUtility::ComponentCount[type],
NzOpenGL::ComponentType[type],
(type == nzComponentType_Color) ? GL_TRUE : GL_FALSE,
stride,
reinterpret_cast<void*>(bufferOffset + offset));
}
}
else
glDisableVertexAttribArray(NzOpenGL::VertexComponentIndex[i]);
}
if (!updateFailed)
{
if (s_instancing)
{
NzHardwareBuffer* instanceBufferImpl = static_cast<NzHardwareBuffer*>(s_instanceBuffer.GetBuffer()->GetImpl());
glBindBuffer(NzOpenGL::BufferTarget[nzBufferType_Vertex], instanceBufferImpl->GetOpenGLID());
bufferOffset = s_instanceBuffer.GetStartOffset();
vertexDeclaration = s_instanceBuffer.GetVertexDeclaration();
stride = vertexDeclaration->GetStride();
for (unsigned int i = nzVertexComponent_FirstInstanceData; i <= nzVertexComponent_LastInstanceData; ++i)
{
nzComponentType type;
bool enabled;
unsigned int offset;
vertexDeclaration->GetComponent(static_cast<nzVertexComponent>(i), &enabled, &type, &offset);
if (!IsComponentTypeSupported(type))
{
NazaraError("Invalid declaration: Vertex component 0x" + NzString::Number(i, 16) + " (type: 0x" + NzString::Number(type, 16) + ") is not supported");
updateFailed = true;
break; break;
} }
if (enabled) case nzComponentType_Double1:
case nzComponentType_Double2:
case nzComponentType_Double3:
case nzComponentType_Double4:
{ {
glEnableVertexAttribArray(NzOpenGL::VertexComponentIndex[i]); glVertexAttribLPointer(NzOpenGL::VertexComponentIndex[j],
if (type <= nzComponentType_Double1 && type >= nzComponentType_Double4)
{
glVertexAttribLPointer(NzOpenGL::VertexComponentIndex[i],
NzUtility::ComponentCount[type], NzUtility::ComponentCount[type],
NzOpenGL::ComponentType[type], NzOpenGL::ComponentType[type],
stride, stride,
reinterpret_cast<void*>(bufferOffset + offset)); reinterpret_cast<void*>(bufferOffset + offset));
}
else if (type <= nzComponentType_Int1 && type >= nzComponentType_Int4) break;
{
glVertexAttribIPointer(NzOpenGL::VertexComponentIndex[i],
NzUtility::ComponentCount[type],
NzOpenGL::ComponentType[type],
stride,
reinterpret_cast<void*>(bufferOffset + offset));
}
else
{
glVertexAttribPointer(NzOpenGL::VertexComponentIndex[i],
NzUtility::ComponentCount[type],
NzOpenGL::ComponentType[type],
(type == nzComponentType_Color) ? GL_TRUE : GL_FALSE,
stride,
reinterpret_cast<void*>(bufferOffset + offset));
} }
glVertexAttribDivisor(NzOpenGL::VertexComponentIndex[i], 1); case nzComponentType_Float1:
} case nzComponentType_Float2:
else case nzComponentType_Float3:
glDisableVertexAttribArray(NzOpenGL::VertexComponentIndex[i]); case nzComponentType_Float4:
}
}
else
{ {
glVertexAttribPointer(NzOpenGL::VertexComponentIndex[j],
NzUtility::ComponentCount[type],
NzOpenGL::ComponentType[type],
GL_FALSE,
stride,
reinterpret_cast<void*>(bufferOffset + offset));
break;
}
case nzComponentType_Int1:
case nzComponentType_Int2:
case nzComponentType_Int3:
case nzComponentType_Int4:
{
glVertexAttribIPointer(NzOpenGL::VertexComponentIndex[j],
NzUtility::ComponentCount[type],
NzOpenGL::ComponentType[type],
stride,
reinterpret_cast<void*>(bufferOffset + offset));
break;
}
}
// Les attributs d'instancing ont un diviseur spécifique (pour dépendre de l'instance en cours)
if (i == 1)
glVertexAttribDivisor(NzOpenGL::VertexComponentIndex[j], 1);
}
else
glDisableVertexAttribArray(NzOpenGL::VertexComponentIndex[j]);
}
}
if (!s_instancing)
{
// Je ne sais pas si c'est vraiment nécessaire de désactiver les attributs, sur mon ordinateur ça ne pose aucun problème
// mais dans le doute, je laisse ça comme ça.
for (unsigned int i = nzVertexComponent_FirstInstanceData; i <= nzVertexComponent_LastInstanceData; ++i) for (unsigned int i = nzVertexComponent_FirstInstanceData; i <= nzVertexComponent_LastInstanceData; ++i)
glDisableVertexAttribArray(NzOpenGL::VertexComponentIndex[i]); glDisableVertexAttribArray(NzOpenGL::VertexComponentIndex[i]);
} }
@ -1886,7 +1877,6 @@ bool NzRenderer::EnsureStateUpdate()
} }
else else
glBindBuffer(NzOpenGL::BufferTarget[nzBufferType_Index], 0); glBindBuffer(NzOpenGL::BufferTarget[nzBufferType_Index], 0);
}
// On invalide les bindings des buffers (car nous les avons défini manuellement) // On invalide les bindings des buffers (car nous les avons défini manuellement)
NzOpenGL::SetBuffer(nzBufferType_Index, 0); NzOpenGL::SetBuffer(nzBufferType_Index, 0);