Index buffer no longer permit 8 bits index size
Modern graphics cards don't like 8 bits index size, so I introduced "Large indices" option, it means 32 bits indices when used otherwise the index size is 16 bits Former-commit-id: 213902de6704ceef16c6ea311ba0c6c5d2f6e665
This commit is contained in:
parent
437c7047c9
commit
b06acfcffd
|
|
@ -15,19 +15,20 @@ class NAZARA_API NzIndexBuffer : public NzResource
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
NzIndexBuffer(NzBuffer* buffer, unsigned int startIndex, unsigned int indexCount);
|
NzIndexBuffer(NzBuffer* buffer, unsigned int startIndex, unsigned int indexCount);
|
||||||
NzIndexBuffer(unsigned int length, nzUInt8 indexSize, nzBufferStorage storage = nzBufferStorage_Software, nzBufferUsage usage = nzBufferUsage_Static);
|
NzIndexBuffer(unsigned int length, bool largeIndices = false, nzBufferStorage storage = nzBufferStorage_Software, nzBufferUsage usage = nzBufferUsage_Static);
|
||||||
NzIndexBuffer(const NzIndexBuffer& indexBuffer);
|
NzIndexBuffer(const NzIndexBuffer& indexBuffer);
|
||||||
~NzIndexBuffer();
|
~NzIndexBuffer();
|
||||||
|
|
||||||
bool Fill(const void* data, unsigned int offset, unsigned int length);
|
bool Fill(const void* data, unsigned int offset, unsigned int length);
|
||||||
|
|
||||||
NzBuffer* GetBuffer() const;
|
NzBuffer* GetBuffer() const;
|
||||||
nzUInt8 GetIndexSize() const;
|
|
||||||
unsigned int GetIndexCount() const;
|
unsigned int GetIndexCount() const;
|
||||||
void* GetPointer();
|
void* GetPointer();
|
||||||
const void* GetPointer() const;
|
const void* GetPointer() const;
|
||||||
unsigned int GetStartIndex() const;
|
unsigned int GetStartIndex() const;
|
||||||
|
|
||||||
|
bool HasLargeIndices() const;
|
||||||
|
|
||||||
bool IsHardware() const;
|
bool IsHardware() const;
|
||||||
bool IsSequential() const;
|
bool IsSequential() const;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -187,29 +187,20 @@ void NzRenderer::DrawIndexedPrimitives(nzPrimitiveType primitive, unsigned int f
|
||||||
glDrawArrays(NzOpenGL::PrimitiveType[primitive], s_indexBuffer->GetStartIndex(), s_indexBuffer->GetIndexCount());
|
glDrawArrays(NzOpenGL::PrimitiveType[primitive], s_indexBuffer->GetStartIndex(), s_indexBuffer->GetIndexCount());
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
nzUInt8 indexSize = s_indexBuffer->GetIndexSize();
|
|
||||||
|
|
||||||
GLenum type;
|
GLenum type;
|
||||||
switch (indexSize)
|
const nzUInt8* ptr = reinterpret_cast<const nzUInt8*>(s_indexBuffer->GetPointer());
|
||||||
|
if (s_indexBuffer->HasLargeIndices())
|
||||||
{
|
{
|
||||||
case 1:
|
ptr += firstIndex*sizeof(nzUInt32);
|
||||||
type = GL_UNSIGNED_BYTE;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 2:
|
|
||||||
type = GL_UNSIGNED_SHORT;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 4:
|
|
||||||
type = GL_UNSIGNED_INT;
|
type = GL_UNSIGNED_INT;
|
||||||
break;
|
}
|
||||||
|
else
|
||||||
default:
|
{
|
||||||
NazaraError("Invalid index size (" + NzString::Number(indexSize) + ')');
|
ptr += firstIndex*sizeof(nzUInt16);
|
||||||
return;
|
type = GL_UNSIGNED_SHORT;
|
||||||
}
|
}
|
||||||
|
|
||||||
glDrawElements(NzOpenGL::PrimitiveType[primitive], indexCount, type, reinterpret_cast<const nzUInt8*>(s_indexBuffer->GetPointer()) + firstIndex*indexSize);
|
glDrawElements(NzOpenGL::PrimitiveType[primitive], indexCount, type, ptr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -20,7 +20,7 @@ m_startIndex(startIndex)
|
||||||
{
|
{
|
||||||
#ifdef NAZARA_DEBUG
|
#ifdef NAZARA_DEBUG
|
||||||
nzUInt8 indexSize = m_buffer->GetSize();
|
nzUInt8 indexSize = m_buffer->GetSize();
|
||||||
if (indexSize != 1 && indexSize != 2 && indexSize != 4)
|
if (indexSize != 2 && indexSize != 4)
|
||||||
{
|
{
|
||||||
NazaraError("Invalid index size (" + NzString::Number(indexSize) + ')');
|
NazaraError("Invalid index size (" + NzString::Number(indexSize) + ')');
|
||||||
m_buffer = nullptr;
|
m_buffer = nullptr;
|
||||||
|
|
@ -33,22 +33,12 @@ m_startIndex(startIndex)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
NzIndexBuffer::NzIndexBuffer(unsigned int length, nzUInt8 indexSize, nzBufferStorage storage, nzBufferUsage usage) :
|
NzIndexBuffer::NzIndexBuffer(unsigned int length, bool largeIndices, nzBufferStorage storage, nzBufferUsage usage) :
|
||||||
m_ownsBuffer(true),
|
m_ownsBuffer(true),
|
||||||
m_indexCount(length),
|
m_indexCount(length),
|
||||||
m_startIndex(0)
|
m_startIndex(0)
|
||||||
{
|
{
|
||||||
#ifdef NAZARA_DEBUG
|
m_buffer = new NzBuffer(nzBufferType_Index, length, (largeIndices) ? 4 : 2, storage, usage);
|
||||||
if (indexSize != 1 && indexSize != 2 && indexSize != 4)
|
|
||||||
{
|
|
||||||
NazaraError("Invalid index size");
|
|
||||||
m_buffer = nullptr;
|
|
||||||
|
|
||||||
throw std::runtime_error("Constructor failed");
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
m_buffer = new NzBuffer(nzBufferType_Index, length, indexSize, storage, usage);
|
|
||||||
m_buffer->AddResourceReference();
|
m_buffer->AddResourceReference();
|
||||||
m_buffer->SetPersistent(false);
|
m_buffer->SetPersistent(false);
|
||||||
}
|
}
|
||||||
|
|
@ -109,19 +99,6 @@ NzBuffer* NzIndexBuffer::GetBuffer() const
|
||||||
return m_buffer;
|
return m_buffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
nzUInt8 NzIndexBuffer::GetIndexSize() const
|
|
||||||
{
|
|
||||||
#if NAZARA_UTILITY_SAFE
|
|
||||||
if (!m_buffer)
|
|
||||||
{
|
|
||||||
NazaraError("Sequential buffers have no index size");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
return m_buffer->GetTypeSize();
|
|
||||||
}
|
|
||||||
|
|
||||||
void* NzIndexBuffer::GetPointer()
|
void* NzIndexBuffer::GetPointer()
|
||||||
{
|
{
|
||||||
#if NAZARA_UTILITY_SAFE
|
#if NAZARA_UTILITY_SAFE
|
||||||
|
|
@ -158,6 +135,19 @@ unsigned int NzIndexBuffer::GetStartIndex() const
|
||||||
return m_startIndex;
|
return m_startIndex;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool NzIndexBuffer::HasLargeIndices() const
|
||||||
|
{
|
||||||
|
#if NAZARA_UTILITY_SAFE
|
||||||
|
if (!m_buffer)
|
||||||
|
{
|
||||||
|
NazaraError("Sequential buffers have no index size");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return (m_buffer->GetTypeSize() == 4);
|
||||||
|
}
|
||||||
|
|
||||||
bool NzIndexBuffer::IsHardware() const
|
bool NzIndexBuffer::IsHardware() const
|
||||||
{
|
{
|
||||||
#if NAZARA_UTILITY_SAFE
|
#if NAZARA_UTILITY_SAFE
|
||||||
|
|
|
||||||
|
|
@ -186,15 +186,9 @@ bool NzMD5MeshParser::Parse(NzMesh* mesh)
|
||||||
unsigned int weightCount = md5Mesh.weights.size();
|
unsigned int weightCount = md5Mesh.weights.size();
|
||||||
|
|
||||||
// Index buffer
|
// Index buffer
|
||||||
nzUInt8 indexSize;
|
bool largeIndices = (vertexCount > std::numeric_limits<nzUInt16>::max());
|
||||||
if (vertexCount > std::numeric_limits<nzUInt16>::max())
|
|
||||||
indexSize = 4;
|
|
||||||
else if (vertexCount > std::numeric_limits<nzUInt8>::max())
|
|
||||||
indexSize = 2;
|
|
||||||
else
|
|
||||||
indexSize = 1;
|
|
||||||
|
|
||||||
std::unique_ptr<NzIndexBuffer> indexBuffer(new NzIndexBuffer(indexCount, indexSize, m_parameters.storage));
|
std::unique_ptr<NzIndexBuffer> indexBuffer(new NzIndexBuffer(indexCount, largeIndices, m_parameters.storage));
|
||||||
if (!indexBuffer->GetBuffer()->IsValid())
|
if (!indexBuffer->GetBuffer()->IsValid())
|
||||||
{
|
{
|
||||||
NazaraError("Failed to create index buffer");
|
NazaraError("Failed to create index buffer");
|
||||||
|
|
@ -208,37 +202,7 @@ bool NzMD5MeshParser::Parse(NzMesh* mesh)
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (indexSize)
|
if (largeIndices)
|
||||||
{
|
|
||||||
case 1:
|
|
||||||
{
|
|
||||||
nzUInt8* index = reinterpret_cast<nzUInt8*>(ptr);
|
|
||||||
|
|
||||||
for (const Mesh::Triangle& triangle : md5Mesh.triangles)
|
|
||||||
{
|
|
||||||
// On les respécifie dans le bon ordre
|
|
||||||
*index++ = triangle.x;
|
|
||||||
*index++ = triangle.z;
|
|
||||||
*index++ = triangle.y;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case 2:
|
|
||||||
{
|
|
||||||
nzUInt16* index = reinterpret_cast<nzUInt16*>(ptr);
|
|
||||||
|
|
||||||
for (const Mesh::Triangle& triangle : md5Mesh.triangles)
|
|
||||||
{
|
|
||||||
// On les respécifie dans le bon ordre
|
|
||||||
*index++ = triangle.x;
|
|
||||||
*index++ = triangle.z;
|
|
||||||
*index++ = triangle.y;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case 4:
|
|
||||||
{
|
{
|
||||||
nzUInt32* index = reinterpret_cast<nzUInt32*>(ptr);
|
nzUInt32* index = reinterpret_cast<nzUInt32*>(ptr);
|
||||||
|
|
||||||
|
|
@ -249,7 +213,17 @@ bool NzMD5MeshParser::Parse(NzMesh* mesh)
|
||||||
*index++ = triangle.z;
|
*index++ = triangle.z;
|
||||||
*index++ = triangle.y;
|
*index++ = triangle.y;
|
||||||
}
|
}
|
||||||
break;
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
nzUInt16* index = reinterpret_cast<nzUInt16*>(ptr);
|
||||||
|
|
||||||
|
for (const Mesh::Triangle& triangle : md5Mesh.triangles)
|
||||||
|
{
|
||||||
|
// On les respécifie dans le bon ordre
|
||||||
|
*index++ = triangle.x;
|
||||||
|
*index++ = triangle.z;
|
||||||
|
*index++ = triangle.y;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -342,15 +316,9 @@ bool NzMD5MeshParser::Parse(NzMesh* mesh)
|
||||||
unsigned int vertexCount = md5Mesh.vertices.size();
|
unsigned int vertexCount = md5Mesh.vertices.size();
|
||||||
|
|
||||||
// Index buffer
|
// Index buffer
|
||||||
nzUInt8 indexSize;
|
bool largeIndices = (vertexCount > std::numeric_limits<nzUInt16>::max());
|
||||||
if (vertexCount > std::numeric_limits<nzUInt16>::max())
|
|
||||||
indexSize = 4;
|
|
||||||
else if (vertexCount > std::numeric_limits<nzUInt8>::max())
|
|
||||||
indexSize = 2;
|
|
||||||
else
|
|
||||||
indexSize = 1;
|
|
||||||
|
|
||||||
std::unique_ptr<NzIndexBuffer> indexBuffer(new NzIndexBuffer(indexCount, indexSize, m_parameters.storage));
|
std::unique_ptr<NzIndexBuffer> indexBuffer(new NzIndexBuffer(indexCount, largeIndices, m_parameters.storage));
|
||||||
if (!indexBuffer->GetBuffer()->IsValid())
|
if (!indexBuffer->GetBuffer()->IsValid())
|
||||||
{
|
{
|
||||||
NazaraError("Failed to create index buffer");
|
NazaraError("Failed to create index buffer");
|
||||||
|
|
@ -364,11 +332,9 @@ bool NzMD5MeshParser::Parse(NzMesh* mesh)
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (indexSize)
|
if (largeIndices)
|
||||||
{
|
{
|
||||||
case 1:
|
nzUInt32* index = reinterpret_cast<nzUInt32*>(ptr);
|
||||||
{
|
|
||||||
nzUInt8* index = reinterpret_cast<nzUInt8*>(ptr);
|
|
||||||
|
|
||||||
for (const Mesh::Triangle& triangle : md5Mesh.triangles)
|
for (const Mesh::Triangle& triangle : md5Mesh.triangles)
|
||||||
{
|
{
|
||||||
|
|
@ -377,10 +343,8 @@ bool NzMD5MeshParser::Parse(NzMesh* mesh)
|
||||||
*index++ = triangle.z;
|
*index++ = triangle.z;
|
||||||
*index++ = triangle.y;
|
*index++ = triangle.y;
|
||||||
}
|
}
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
else
|
||||||
case 2:
|
|
||||||
{
|
{
|
||||||
nzUInt16* index = reinterpret_cast<nzUInt16*>(ptr);
|
nzUInt16* index = reinterpret_cast<nzUInt16*>(ptr);
|
||||||
|
|
||||||
|
|
@ -394,21 +358,6 @@ bool NzMD5MeshParser::Parse(NzMesh* mesh)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case 4:
|
|
||||||
{
|
|
||||||
nzUInt32* index = reinterpret_cast<nzUInt32*>(ptr);
|
|
||||||
|
|
||||||
for (const Mesh::Triangle& triangle : md5Mesh.triangles)
|
|
||||||
{
|
|
||||||
// On les respécifie dans le bon ordre
|
|
||||||
*index++ = triangle.x;
|
|
||||||
*index++ = triangle.z;
|
|
||||||
*index++ = triangle.y;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!indexBuffer->Unmap())
|
if (!indexBuffer->Unmap())
|
||||||
NazaraWarning("Failed to unmap index buffer");
|
NazaraWarning("Failed to unmap index buffer");
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue