(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,134 +1760,124 @@ 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
glBindBuffer(NzOpenGL::BufferTarget[nzBufferType_Vertex], vertexBufferImpl->GetOpenGLID()); for (unsigned int i = 0; i < (s_instancing ? 2 : 1); ++i)
bufferOffset = s_vertexBuffer->GetStartOffset();
vertexDeclaration = s_vertexBuffer->GetVertexDeclaration();
stride = vertexDeclaration->GetStride();
for (unsigned int i = nzVertexComponent_FirstVertexData; i <= nzVertexComponent_LastVertexData; ++i)
{ {
nzComponentType type; // Selon l'itération nous choisissons un buffer différent
bool enabled; const NzVertexBuffer* vertexBuffer = (i == 0) ? s_vertexBuffer : &s_instanceBuffer;
unsigned int offset;
vertexDeclaration->GetComponent(static_cast<nzVertexComponent>(i), &enabled, &type, &offset);
if (!IsComponentTypeSupported(type)) NzHardwareBuffer* vertexBufferImpl = static_cast<NzHardwareBuffer*>(vertexBuffer->GetBuffer()->GetImpl());
glBindBuffer(NzOpenGL::BufferTarget[nzBufferType_Vertex], vertexBufferImpl->GetOpenGLID());
bufferOffset = vertexBuffer->GetStartOffset();
vertexDeclaration = vertexBuffer->GetVertexDeclaration();
stride = vertexDeclaration->GetStride();
// 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)
{ {
NazaraError("Invalid declaration: Vertex component 0x" + NzString::Number(i, 16) + " (type: 0x" + NzString::Number(type, 16) + ") is not supported"); nzComponentType type;
updateFailed = true; bool enabled;
break; unsigned int offset;
} vertexDeclaration->GetComponent(static_cast<nzVertexComponent>(j), &enabled, &type, &offset);
if (enabled) if (!IsComponentTypeSupported(type))
{
glEnableVertexAttribArray(NzOpenGL::VertexComponentIndex[i]);
if (type <= nzComponentType_Double1 && type >= nzComponentType_Double4)
{ {
glVertexAttribLPointer(NzOpenGL::VertexComponentIndex[i], NazaraError("Invalid vertex declaration " + NzString::Pointer(vertexDeclaration) + ": Vertex component 0x" + NzString::Number(j, 16) + " (type: 0x" + NzString::Number(type, 16) + ") is not supported");
NzUtility::ComponentCount[type], updateFailed = true;
NzOpenGL::ComponentType[type], break;
stride,
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 (enabled)
{
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; glEnableVertexAttribArray(NzOpenGL::VertexComponentIndex[j]);
bool enabled;
unsigned int offset;
vertexDeclaration->GetComponent(static_cast<nzVertexComponent>(i), &enabled, &type, &offset);
if (!IsComponentTypeSupported(type)) switch (type)
{ {
NazaraError("Invalid declaration: Vertex component 0x" + NzString::Number(i, 16) + " (type: 0x" + NzString::Number(type, 16) + ") is not supported"); case nzComponentType_Color:
updateFailed = true;
break;
}
if (enabled)
{
glEnableVertexAttribArray(NzOpenGL::VertexComponentIndex[i]);
if (type <= nzComponentType_Double1 && type >= nzComponentType_Double4)
{ {
glVertexAttribLPointer(NzOpenGL::VertexComponentIndex[i], glVertexAttribPointer(NzOpenGL::VertexComponentIndex[j],
NzUtility::ComponentCount[type], NzUtility::ComponentCount[type],
NzOpenGL::ComponentType[type], NzOpenGL::ComponentType[type],
stride, GL_TRUE,
reinterpret_cast<void*>(bufferOffset + offset)); stride,
reinterpret_cast<void*>(bufferOffset + offset));
break;
} }
else if (type <= nzComponentType_Int1 && type >= nzComponentType_Int4)
case nzComponentType_Double1:
case nzComponentType_Double2:
case nzComponentType_Double3:
case nzComponentType_Double4:
{ {
glVertexAttribIPointer(NzOpenGL::VertexComponentIndex[i], glVertexAttribLPointer(NzOpenGL::VertexComponentIndex[j],
NzUtility::ComponentCount[type], NzUtility::ComponentCount[type],
NzOpenGL::ComponentType[type], NzOpenGL::ComponentType[type],
stride, stride,
reinterpret_cast<void*>(bufferOffset + offset)); reinterpret_cast<void*>(bufferOffset + offset));
break;
} }
else
case nzComponentType_Float1:
case nzComponentType_Float2:
case nzComponentType_Float3:
case nzComponentType_Float4:
{ {
glVertexAttribPointer(NzOpenGL::VertexComponentIndex[i], glVertexAttribPointer(NzOpenGL::VertexComponentIndex[j],
NzUtility::ComponentCount[type], NzUtility::ComponentCount[type],
NzOpenGL::ComponentType[type], NzOpenGL::ComponentType[type],
(type == nzComponentType_Color) ? GL_TRUE : GL_FALSE, GL_FALSE,
stride, stride,
reinterpret_cast<void*>(bufferOffset + offset)); reinterpret_cast<void*>(bufferOffset + offset));
break;
} }
glVertexAttribDivisor(NzOpenGL::VertexComponentIndex[i], 1); case nzComponentType_Int1:
} case nzComponentType_Int2:
else case nzComponentType_Int3:
glDisableVertexAttribArray(NzOpenGL::VertexComponentIndex[i]); case nzComponentType_Int4:
} {
} glVertexAttribIPointer(NzOpenGL::VertexComponentIndex[j],
else NzUtility::ComponentCount[type],
{ NzOpenGL::ComponentType[type],
for (unsigned int i = nzVertexComponent_FirstInstanceData; i <= nzVertexComponent_LastInstanceData; ++i) stride,
glDisableVertexAttribArray(NzOpenGL::VertexComponentIndex[i]); reinterpret_cast<void*>(bufferOffset + offset));
}
// Et on active l'index buffer (Un seul index buffer par VAO) break;
if (s_indexBuffer) }
{
NzHardwareBuffer* indexBufferImpl = static_cast<NzHardwareBuffer*>(s_indexBuffer->GetBuffer()->GetImpl()); }
glBindBuffer(NzOpenGL::BufferTarget[nzBufferType_Index], indexBufferImpl->GetOpenGLID()); // 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]);
} }
else
glBindBuffer(NzOpenGL::BufferTarget[nzBufferType_Index], 0);
} }
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)
glDisableVertexAttribArray(NzOpenGL::VertexComponentIndex[i]);
}
// Et on active l'index buffer (Un seul index buffer par VAO)
if (s_indexBuffer)
{
NzHardwareBuffer* indexBufferImpl = static_cast<NzHardwareBuffer*>(s_indexBuffer->GetBuffer()->GetImpl());
glBindBuffer(NzOpenGL::BufferTarget[nzBufferType_Index], indexBufferImpl->GetOpenGLID());
}
else
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);
NzOpenGL::SetBuffer(nzBufferType_Vertex, 0); NzOpenGL::SetBuffer(nzBufferType_Vertex, 0);