Added NzBuffer::SetStorage

Fixed (Index/Vertex)Buffer::(Fill/Map) not filling/mapping the entire
buffer when the third argument was zero
Fixed Renderer not accepting sequential index buffer
This commit is contained in:
Lynix 2012-06-21 16:37:28 +02:00
parent ec9470ceb6
commit 445d6d236d
10 changed files with 135 additions and 42 deletions

View File

@ -76,6 +76,9 @@ class NAZARA_API NzBuffer : public NzResource, NzNonCopyable
bool IsValid() const; bool IsValid() const;
void* Map(nzBufferAccess access, unsigned int offset = 0, unsigned int length = 0); void* Map(nzBufferAccess access, unsigned int offset = 0, unsigned int length = 0);
bool SetStorage(nzBufferStorage storage);
bool Unmap(); bool Unmap();
static bool IsSupported(nzBufferStorage storage); static bool IsSupported(nzBufferStorage storage);

View File

@ -31,6 +31,9 @@ class NAZARA_API NzIndexBuffer
bool IsSequential() const; bool IsSequential() const;
void* Map(nzBufferAccess access, unsigned int offset = 0, unsigned int length = 0); void* Map(nzBufferAccess access, unsigned int offset = 0, unsigned int length = 0);
bool SetStorage(nzBufferStorage storage);
bool Unmap(); bool Unmap();
private: private:

View File

@ -30,6 +30,9 @@ class NAZARA_API NzVertexBuffer
bool IsHardware() const; bool IsHardware() const;
void* Map(nzBufferAccess access, unsigned int offset = 0, unsigned int length = 0); void* Map(nzBufferAccess access, unsigned int offset = 0, unsigned int length = 0);
bool SetStorage(nzBufferStorage storage);
bool Unmap(); bool Unmap();
private: private:

View File

@ -52,14 +52,14 @@ namespace
if (access == nzBufferAccess_DiscardAndWrite) if (access == nzBufferAccess_DiscardAndWrite)
{ {
GLint size; GLint bufferSize;
glGetBufferParameteriv(bufferTargetBinding[type], GL_BUFFER_SIZE, &size); glGetBufferParameteriv(bufferTargetBinding[type], GL_BUFFER_SIZE, &bufferSize);
GLint usage; GLint bufferUsage;
glGetBufferParameteriv(bufferTargetBinding[type], GL_BUFFER_USAGE, &usage); glGetBufferParameteriv(bufferTargetBinding[type], GL_BUFFER_USAGE, &bufferUsage);
// On discard le buffer // On discard le buffer
glBufferData(bufferTargetBinding[type], size, nullptr, usage); glBufferData(bufferTargetBinding[type], bufferSize, nullptr, bufferUsage);
} }
void* ptr = glMapBuffer(bufferTarget[type], bufferLock[access]); void* ptr = glMapBuffer(bufferTarget[type], bufferLock[access]);
@ -154,8 +154,8 @@ bool NzHardwareBuffer::Fill(const void* data, unsigned int offset, unsigned int
if (size < 32*1024) if (size < 32*1024)
{ {
// http://www.opengl.org/wiki/Vertex_Specification_Best_Practices // http://www.opengl.org/wiki/Vertex_Specification_Best_Practices
if (size == m_parent->GetLength()) if (size == m_parent->GetSize())
glBufferData(bufferTarget[m_type], m_parent->GetSize(), nullptr, bufferUsage[m_parent->GetStorage()]); // Discard glBufferData(bufferTarget[m_type], m_parent->GetSize(), nullptr, bufferUsage[m_parent->GetUsage()]); // Discard
glBufferSubData(bufferTarget[m_type], offset, size, data); glBufferSubData(bufferTarget[m_type], offset, size, data);
} }
@ -198,7 +198,7 @@ bool NzHardwareBuffer::IsHardware() const
return true; return true;
} }
void* NzHardwareBuffer::Map(nzBufferAccess access, unsigned int offset, unsigned int length) void* NzHardwareBuffer::Map(nzBufferAccess access, unsigned int offset, unsigned int size)
{ {
NzContext::EnsureContext(); NzContext::EnsureContext();
@ -209,7 +209,7 @@ void* NzHardwareBuffer::Map(nzBufferAccess access, unsigned int offset, unsigned
if (previous != m_buffer) if (previous != m_buffer)
glBindBuffer(bufferTarget[m_type], m_buffer); glBindBuffer(bufferTarget[m_type], m_buffer);
void* ptr = mapBuffer(m_type, access, offset, length); void* ptr = mapBuffer(m_type, access, offset, size);
// Inutile de rebinder s'il n'y avait aucun buffer (Optimise les opérrations chaînées) // Inutile de rebinder s'il n'y avait aucun buffer (Optimise les opérrations chaînées)
if (previous != m_buffer && previous != 0) if (previous != m_buffer && previous != 0)

View File

@ -22,13 +22,13 @@ class NzHardwareBuffer : public NzBufferImpl
bool Create(unsigned int size, nzBufferUsage usage = nzBufferUsage_Static); bool Create(unsigned int size, nzBufferUsage usage = nzBufferUsage_Static);
void Destroy(); void Destroy();
bool Fill(const void* data, unsigned int offset, unsigned int length); bool Fill(const void* data, unsigned int offset, unsigned int size);
void* GetPointer(); void* GetPointer();
bool IsHardware() const; bool IsHardware() const;
void* Map(nzBufferAccess access, unsigned int offset = 0, unsigned int length = 0); void* Map(nzBufferAccess access, unsigned int offset = 0, unsigned int size = 0);
bool Unmap(); bool Unmap();
private: private:

View File

@ -203,6 +203,10 @@ void NzRenderer::DrawIndexedPrimitives(nzPrimitiveType primitive, unsigned int f
return; return;
} }
if (m_indexBuffer->IsSequential())
glDrawArrays(openglPrimitive[primitive], m_indexBuffer->GetStartIndex(), m_indexBuffer->GetIndexCount());
else
{
nzUInt8 indexSize = m_indexBuffer->GetIndexSize(); nzUInt8 indexSize = m_indexBuffer->GetIndexSize();
GLenum type; GLenum type;
@ -226,6 +230,7 @@ void NzRenderer::DrawIndexedPrimitives(nzPrimitiveType primitive, unsigned int f
} }
glDrawElements(openglPrimitive[primitive], indexCount, type, reinterpret_cast<const nzUInt8*>(m_indexBuffer->GetPointer()) + firstIndex*indexSize); glDrawElements(openglPrimitive[primitive], indexCount, type, reinterpret_cast<const nzUInt8*>(m_indexBuffer->GetPointer()) + firstIndex*indexSize);
}
} }
void NzRenderer::DrawPrimitives(nzPrimitiveType primitive, unsigned int firstVertex, unsigned int vertexCount) void NzRenderer::DrawPrimitives(nzPrimitiveType primitive, unsigned int firstVertex, unsigned int vertexCount)
@ -507,7 +512,7 @@ void NzRenderer::SetFaceFilling(nzFaceFilling fillingMode)
bool NzRenderer::SetIndexBuffer(const NzIndexBuffer* indexBuffer) bool NzRenderer::SetIndexBuffer(const NzIndexBuffer* indexBuffer)
{ {
#if NAZARA_RENDERER_SAFE #if NAZARA_RENDERER_SAFE
if (indexBuffer && !indexBuffer->IsHardware()) if (indexBuffer && !indexBuffer->IsHardware() && !indexBuffer->IsSequential())
{ {
NazaraError("Buffer must be hardware"); NazaraError("Buffer must be hardware");
return false; return false;
@ -551,8 +556,6 @@ bool NzRenderer::SetShader(NzShader* shader)
return false; return false;
} }
} }
else
m_shader = nullptr;
m_shader = shader; m_shader = shader;

View File

@ -110,6 +110,7 @@ bool NzBuffer::Create(unsigned int length, nzUInt8 typeSize, nzBufferStorage sto
m_length = length; m_length = length;
m_typeSize = typeSize; m_typeSize = typeSize;
m_storage = storage;
m_usage = usage; m_usage = usage;
// Si on arrive ici c'est que tout s'est bien passé. // Si on arrive ici c'est que tout s'est bien passé.
@ -142,7 +143,7 @@ bool NzBuffer::Fill(const void* data, unsigned int offset, unsigned int length)
} }
#endif #endif
return m_impl->Fill(data, offset*m_typeSize, length*m_typeSize); return m_impl->Fill(data, offset*m_typeSize, ((length == 0) ? m_length-offset : length)*m_typeSize);
} }
NzBufferImpl* NzBuffer::GetImpl() const NzBufferImpl* NzBuffer::GetImpl() const
@ -232,7 +233,69 @@ void* NzBuffer::Map(nzBufferAccess access, unsigned int offset, unsigned int len
} }
#endif #endif
return m_impl->Map(access, offset*m_typeSize, length*m_typeSize); return m_impl->Map(access, offset*m_typeSize, ((length == 0) ? m_length-offset : length)*m_typeSize);
}
bool NzBuffer::SetStorage(nzBufferStorage storage)
{
#if NAZARA_UTILITY_SAFE
if (!m_impl)
{
NazaraError("Buffer not valid");
return false;
}
#endif
if (m_storage == storage)
return true;
#if NAZARA_UTILITY_SAFE
if (!IsSupported(storage))
{
NazaraError("Storage not supported");
return false;
}
#endif
void* ptr = m_impl->Map(nzBufferAccess_ReadOnly, 0, m_length*m_typeSize);
if (!ptr)
{
NazaraError("Failed to map buffer");
return false;
}
NzBufferImpl* impl = s_bufferFunctions[storage](this, m_type);
if (!impl->Create(m_length*m_typeSize, m_usage))
{
NazaraError("Failed to create buffer");
delete impl;
if (!m_impl->Unmap())
NazaraWarning("Failed to unmap buffer");
return false;
}
if (!impl->Fill(ptr, 0, m_length*m_typeSize))
{
NazaraError("Failed to fill buffer");
impl->Destroy();
delete impl;
if (!m_impl->Unmap())
NazaraWarning("Failed to unmap buffer");
return false;
}
m_impl->Unmap();
m_impl->Destroy();
delete m_impl;
m_impl = impl;
m_storage = storage;
return true;
} }
bool NzBuffer::Unmap() bool NzBuffer::Unmap()

View File

@ -87,7 +87,7 @@ bool NzIndexBuffer::Fill(const void* data, unsigned int offset, unsigned int len
#if NAZARA_UTILITY_SAFE #if NAZARA_UTILITY_SAFE
if (!m_buffer) if (!m_buffer)
{ {
NazaraError("Impossible to fill sequential buffer"); NazaraError("Impossible to fill sequential buffers");
return false; return false;
} }
@ -111,7 +111,7 @@ nzUInt8 NzIndexBuffer::GetIndexSize() const
#if NAZARA_UTILITY_SAFE #if NAZARA_UTILITY_SAFE
if (!m_buffer) if (!m_buffer)
{ {
NazaraError("Sequential index buffer has no index size"); NazaraError("Sequential buffers have no index size");
return 0; return 0;
} }
#endif #endif
@ -124,7 +124,7 @@ void* NzIndexBuffer::GetPointer()
#if NAZARA_UTILITY_SAFE #if NAZARA_UTILITY_SAFE
if (!m_buffer) if (!m_buffer)
{ {
NazaraError("Sequential index buffer: Buffer has no pointer"); NazaraError("Sequential buffers have no pointer");
return nullptr; return nullptr;
} }
#endif #endif
@ -137,7 +137,7 @@ const void* NzIndexBuffer::GetPointer() const
#if NAZARA_UTILITY_SAFE #if NAZARA_UTILITY_SAFE
if (!m_buffer) if (!m_buffer)
{ {
NazaraError("Sequential index buffer has no pointer"); NazaraError("Sequential buffers have no pointer");
return nullptr; return nullptr;
} }
#endif #endif
@ -178,7 +178,7 @@ void* NzIndexBuffer::Map(nzBufferAccess access, unsigned int offset, unsigned in
#if NAZARA_UTILITY_SAFE #if NAZARA_UTILITY_SAFE
if (!m_buffer) if (!m_buffer)
{ {
NazaraError("Impossible to map sequential index buffer"); NazaraError("Impossible to map sequential buffers");
return nullptr; return nullptr;
} }
@ -192,12 +192,25 @@ void* NzIndexBuffer::Map(nzBufferAccess access, unsigned int offset, unsigned in
return m_buffer->Map(access, m_startIndex+offset, (length) ? length : m_indexCount-offset); return m_buffer->Map(access, m_startIndex+offset, (length) ? length : m_indexCount-offset);
} }
bool NzIndexBuffer::SetStorage(nzBufferStorage storage)
{
#if NAZARA_UTILITY_SAFE
if (!m_buffer)
{
NazaraWarning("Sequential buffers have no storage");
return true;
}
#endif
return m_buffer->SetStorage(storage);
}
bool NzIndexBuffer::Unmap() bool NzIndexBuffer::Unmap()
{ {
#if NAZARA_UTILITY_SAFE #if NAZARA_UTILITY_SAFE
if (!m_buffer) if (!m_buffer)
{ {
NazaraError("Impossible to unlock sequential index buffer"); NazaraError("Impossible to unlock sequential buffers");
return false; return false;
} }
#endif #endif

View File

@ -19,13 +19,13 @@ class NzSoftwareBuffer : public NzBufferImpl
bool Create(unsigned int size, nzBufferUsage usage = nzBufferUsage_Static); bool Create(unsigned int size, nzBufferUsage usage = nzBufferUsage_Static);
void Destroy(); void Destroy();
bool Fill(const void* data, unsigned int offset, unsigned int length); bool Fill(const void* data, unsigned int offset, unsigned int size);
void* GetPointer(); void* GetPointer();
bool IsHardware() const; bool IsHardware() const;
void* Map(nzBufferAccess access, unsigned int offset = 0, unsigned int length = 0); void* Map(nzBufferAccess access, unsigned int offset = 0, unsigned int size = 0);
bool Unmap(); bool Unmap();
private: private:

View File

@ -120,6 +120,11 @@ void* NzVertexBuffer::Map(nzBufferAccess access, unsigned int offset, unsigned i
return m_buffer->Map(access, m_startVertex+offset, (length) ? length : m_vertexCount-offset); return m_buffer->Map(access, m_startVertex+offset, (length) ? length : m_vertexCount-offset);
} }
bool NzVertexBuffer::SetStorage(nzBufferStorage storage)
{
return m_buffer->SetStorage(storage);
}
bool NzVertexBuffer::Unmap() bool NzVertexBuffer::Unmap()
{ {
return m_buffer->Unmap(); return m_buffer->Unmap();