Moved buffers to Utility

Fixed NzVector4::operator/
Replaced enumName_Count by enumName_Max
Renamed (Index/Vertex)Buffer::GetBufferPtr by GetPointer
This commit is contained in:
Lynix
2012-06-21 09:49:47 +02:00
parent be0a5d2819
commit ec9470ceb6
31 changed files with 291 additions and 258 deletions

View File

@@ -0,0 +1,273 @@
// Copyright (C) 2012 Jérôme Leclercq
// This file is part of the "Nazara Engine".
// For conditions of distribution and use, see copyright notice in Config.hpp
#include <Nazara/Utility/Buffer.hpp>
#include <Nazara/Core/Error.hpp>
#include <Nazara/Utility/BufferImpl.hpp>
#include <Nazara/Utility/Config.hpp>
#include <Nazara/Utility/SoftwareBuffer.hpp>
#include <cstring>
#include <stdexcept>
#include <Nazara/Utility/Debug.hpp>
namespace
{
NzBufferImpl* SoftwareBufferFunction(NzBuffer* parent, nzBufferType type)
{
return new NzSoftwareBuffer(parent, type);
}
}
NzBuffer::NzBuffer(nzBufferType type) :
m_type(type),
m_typeSize(0),
m_impl(nullptr),
m_length(0)
{
}
NzBuffer::NzBuffer(nzBufferType type, unsigned int length, nzUInt8 typeSize, nzBufferStorage storage, nzBufferUsage usage) :
m_type(type),
m_impl(nullptr)
{
Create(length, typeSize, storage, usage);
#ifdef NAZARA_DEBUG
if (!m_impl)
{
NazaraError("Failed to create buffer");
throw std::runtime_error("Constructor failed");
}
#endif
}
NzBuffer::~NzBuffer()
{
Destroy();
}
bool NzBuffer::CopyContent(NzBuffer& buffer)
{
#if NAZARA_UTILITY_SAFE
if (!m_impl)
{
NazaraError("Buffer must be valid");
return false;
}
if (!buffer.IsValid())
{
NazaraError("Source buffer must be valid");
return false;
}
if (!buffer.GetTypeSize() != m_typeSize)
{
NazaraError("Source buffer type size does not match buffer type size");
return false;
}
#endif
void* ptr = buffer.Map(nzBufferAccess_ReadOnly);
if (!ptr)
{
NazaraError("Failed to map source buffer");
return false;
}
bool r = Fill(ptr, 0, buffer.GetLength());
if (!buffer.Unmap())
NazaraWarning("Failed to unmap source buffer");
return r;
}
bool NzBuffer::Create(unsigned int length, nzUInt8 typeSize, nzBufferStorage storage, nzBufferUsage usage)
{
Destroy();
// On tente d'abord de faire un buffer hardware, si supporté
if (s_bufferFunctions[storage])
{
NzBufferImpl* impl = s_bufferFunctions[storage](this, m_type);
if (!impl->Create(length*typeSize, usage))
{
NazaraError("Failed to create buffer");
delete impl;
return false;
}
m_impl = impl;
}
else
{
NazaraError("Buffer storage not supported");
return false;
}
m_length = length;
m_typeSize = typeSize;
m_usage = usage;
// Si on arrive ici c'est que tout s'est bien passé.
return true;
}
void NzBuffer::Destroy()
{
if (m_impl)
{
m_impl->Destroy();
delete m_impl;
m_impl = nullptr;
}
}
bool NzBuffer::Fill(const void* data, unsigned int offset, unsigned int length)
{
#if NAZARA_UTILITY_SAFE
if (!m_impl)
{
NazaraError("Buffer not valid");
return false;
}
if (offset+length > m_length)
{
NazaraError("Exceeding buffer size");
return false;
}
#endif
return m_impl->Fill(data, offset*m_typeSize, length*m_typeSize);
}
NzBufferImpl* NzBuffer::GetImpl() const
{
return m_impl;
}
unsigned int NzBuffer::GetLength() const
{
return m_length;
}
void* NzBuffer::GetPointer()
{
#if NAZARA_UTILITY_SAFE
if (!m_impl)
{
NazaraError("Buffer not valid");
return nullptr;
}
#endif
return m_impl->GetPointer();
}
const void* NzBuffer::GetPointer() const
{
#if NAZARA_UTILITY_SAFE
if (!m_impl)
{
NazaraError("Buffer not valid");
return nullptr;
}
#endif
return m_impl->GetPointer();
}
unsigned int NzBuffer::GetSize() const
{
return m_length*m_typeSize;
}
nzBufferStorage NzBuffer::GetStorage() const
{
return m_storage;
}
nzBufferType NzBuffer::GetType() const
{
return m_type;
}
nzUInt8 NzBuffer::GetTypeSize() const
{
return m_typeSize;
}
nzBufferUsage NzBuffer::GetUsage() const
{
return m_usage;
}
bool NzBuffer::IsHardware() const
{
return m_storage == nzBufferStorage_Hardware;
}
bool NzBuffer::IsValid() const
{
return m_impl != nullptr;
}
void* NzBuffer::Map(nzBufferAccess access, unsigned int offset, unsigned int length)
{
#if NAZARA_UTILITY_SAFE
if (!m_impl)
{
NazaraError("Buffer not valid");
return nullptr;
}
if (offset+length > m_length)
{
NazaraError("Exceeding buffer size");
return nullptr;
}
#endif
return m_impl->Map(access, offset*m_typeSize, length*m_typeSize);
}
bool NzBuffer::Unmap()
{
#if NAZARA_UTILITY_SAFE
if (!m_impl)
{
NazaraError("Buffer not valid");
return false;
}
#endif
return m_impl->Unmap();
}
bool NzBuffer::IsSupported(nzBufferStorage storage)
{
return s_bufferFunctions[storage] != nullptr;
}
void NzBuffer::SetBufferFunction(nzBufferStorage storage, BufferFunction func)
{
s_bufferFunctions[storage] = func;
}
bool NzBuffer::Initialize()
{
s_bufferFunctions[nzBufferStorage_Software] = SoftwareBufferFunction;
return true;
}
void NzBuffer::Uninitialize()
{
std::memset(s_bufferFunctions, 0, (nzBufferStorage_Max+1)*sizeof(NzBuffer::BufferFunction));
}
NzBuffer::BufferFunction NzBuffer::s_bufferFunctions[nzBufferStorage_Max+1] = {0};

View File

@@ -0,0 +1,8 @@
// Copyright (C) 2012 Jérôme Leclercq
// This file is part of the "Nazara Engine".
// For conditions of distribution and use, see copyright notice in Config.hpp
#include <Nazara/Utility/BufferImpl.hpp>
#include <Nazara/Utility/Debug.hpp>
NzBufferImpl::~NzBufferImpl() = default;

View File

@@ -0,0 +1,206 @@
// Copyright (C) 2012 Jérôme Leclercq
// This file is part of the "Nazara Engine".
// For conditions of distribution and use, see copyright notice in Config.hpp
#include <Nazara/Utility/IndexBuffer.hpp>
#include <Nazara/Core/Error.hpp>
#include <Nazara/Utility/Config.hpp>
#include <stdexcept>
#include <Nazara/Utility/Debug.hpp>
NzIndexBuffer::NzIndexBuffer(NzBuffer* buffer, unsigned int startIndex, unsigned int indexCount) :
m_buffer(buffer),
m_ownsBuffer(false),
m_indexCount(indexCount),
m_startIndex(startIndex)
{
if (m_buffer)
{
#ifdef NAZARA_DEBUG
nzUInt8 indexSize = m_buffer->GetSize();
if (indexSize != 1 && indexSize != 2 && indexSize != 4)
{
NazaraError("Invalid index size (" + NzString::Number(indexSize) + ')');
m_buffer = nullptr;
throw std::runtime_error("Constructor failed");
}
#endif
m_buffer->AddResourceReference();
}
}
NzIndexBuffer::NzIndexBuffer(unsigned int length, nzUInt8 indexSize, nzBufferStorage storage, nzBufferUsage usage) :
m_ownsBuffer(true),
m_indexCount(length),
m_startIndex(0)
{
#ifdef NAZARA_DEBUG
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->SetPersistent(false);
}
NzIndexBuffer::NzIndexBuffer(const NzIndexBuffer& indexBuffer) :
m_buffer(indexBuffer.m_buffer),
m_ownsBuffer(indexBuffer.m_ownsBuffer),
m_indexCount(indexBuffer.m_indexCount),
m_startIndex(indexBuffer.m_startIndex)
{
if (m_buffer)
{
if (m_ownsBuffer)
{
NzBuffer* buffer = indexBuffer.m_buffer;
m_buffer = new NzBuffer(nzBufferType_Index, buffer->GetLength(), buffer->GetSize(), buffer->GetStorage(), buffer->GetUsage());
m_buffer->AddResourceReference();
m_buffer->SetPersistent(false);
m_buffer->CopyContent(*indexBuffer.m_buffer);
}
else
{
m_buffer = indexBuffer.m_buffer;
m_buffer->AddResourceReference();
}
}
}
NzIndexBuffer::~NzIndexBuffer()
{
if (m_buffer)
m_buffer->RemoveResourceReference();
}
bool NzIndexBuffer::Fill(const void* data, unsigned int offset, unsigned int length)
{
#if NAZARA_UTILITY_SAFE
if (!m_buffer)
{
NazaraError("Impossible to fill sequential buffer");
return false;
}
if (offset+length > m_indexCount)
{
NazaraError("Exceeding virtual buffer size");
return false;
}
#endif
return m_buffer->Fill(data, m_startIndex+offset, length);
}
NzBuffer* NzIndexBuffer::GetBuffer() const
{
return m_buffer;
}
nzUInt8 NzIndexBuffer::GetIndexSize() const
{
#if NAZARA_UTILITY_SAFE
if (!m_buffer)
{
NazaraError("Sequential index buffer has no index size");
return 0;
}
#endif
return m_buffer->GetTypeSize();
}
void* NzIndexBuffer::GetPointer()
{
#if NAZARA_UTILITY_SAFE
if (!m_buffer)
{
NazaraError("Sequential index buffer: Buffer has no pointer");
return nullptr;
}
#endif
return reinterpret_cast<nzUInt8*>(m_buffer->GetPointer()) + m_startIndex*m_buffer->GetTypeSize();
}
const void* NzIndexBuffer::GetPointer() const
{
#if NAZARA_UTILITY_SAFE
if (!m_buffer)
{
NazaraError("Sequential index buffer has no pointer");
return nullptr;
}
#endif
return reinterpret_cast<const nzUInt8*>(m_buffer->GetPointer()) + m_startIndex*m_buffer->GetTypeSize();
}
unsigned int NzIndexBuffer::GetIndexCount() const
{
return m_indexCount;
}
unsigned int NzIndexBuffer::GetStartIndex() const
{
return m_startIndex;
}
bool NzIndexBuffer::IsHardware() const
{
#if NAZARA_UTILITY_SAFE
if (!m_buffer)
{
NazaraWarning("Sequential index buffers are neither hardware or software");
return false;
}
#endif
return m_buffer->IsHardware();
}
bool NzIndexBuffer::IsSequential() const
{
return m_buffer == nullptr;
}
void* NzIndexBuffer::Map(nzBufferAccess access, unsigned int offset, unsigned int length)
{
#if NAZARA_UTILITY_SAFE
if (!m_buffer)
{
NazaraError("Impossible to map sequential index buffer");
return nullptr;
}
if (offset+length > m_indexCount)
{
NazaraError("Exceeding virtual buffer size");
return nullptr;
}
#endif
return m_buffer->Map(access, m_startIndex+offset, (length) ? length : m_indexCount-offset);
}
bool NzIndexBuffer::Unmap()
{
#if NAZARA_UTILITY_SAFE
if (!m_buffer)
{
NazaraError("Impossible to unlock sequential index buffer");
return false;
}
#endif
return m_buffer->Unmap();
}

View File

@@ -1314,7 +1314,7 @@ bool NzPixelFormat::Initialize()
void NzPixelFormat::Uninitialize()
{
std::memset(s_convertFunctions, 0, nzPixelFormat_Count*nzPixelFormat_Count*sizeof(NzPixelFormat::ConvertFunction));
std::memset(s_convertFunctions, 0, (nzPixelFormat_Max+1)*(nzPixelFormat_Max+1)*sizeof(NzPixelFormat::ConvertFunction));
}
NzPixelFormat::ConvertFunction NzPixelFormat::s_convertFunctions[nzPixelFormat_Count][nzPixelFormat_Count] = {{0}}; ///FIXME: Fonctionne correctement ?
NzPixelFormat::ConvertFunction NzPixelFormat::s_convertFunctions[nzPixelFormat_Max+1][nzPixelFormat_Max+1] = {{0}}; ///FIXME: Fonctionne correctement ?

View File

@@ -0,0 +1,103 @@
// Copyright (C) 2012 Jérôme Leclercq
// This file is part of the "Nazara Engine".
// For conditions of distribution and use, see copyright notice in Config.hpp
#include <Nazara/Utility/SoftwareBuffer.hpp>
#include <Nazara/Core/Error.hpp>
#include <Nazara/Utility/Config.hpp>
#include <cstring>
#include <stdexcept>
#include <Nazara/Utility/Debug.hpp>
NzSoftwareBuffer::NzSoftwareBuffer(NzBuffer* parent, nzBufferType type) :
m_type(type)
{
NazaraUnused(parent);
}
NzSoftwareBuffer::~NzSoftwareBuffer()
{
}
bool NzSoftwareBuffer::Create(unsigned int size, nzBufferUsage usage)
{
NazaraUnused(usage);
// Cette allocation est protégée car sa taille dépend directement de paramètres utilisateurs
try
{
m_buffer = new nzUInt8[size];
}
catch (const std::exception& e)
{
NazaraError("Failed to allocate software buffer (" + NzString(e.what()) + ')');
return false;
}
m_mapped = false;
return true;
}
void NzSoftwareBuffer::Destroy()
{
delete[] m_buffer;
}
bool NzSoftwareBuffer::Fill(const void* data, unsigned int offset, unsigned int size)
{
#if NAZARA_UTILITY_SAFE
if (m_mapped)
{
NazaraError("Buffer already mapped");
return false;
}
#endif
std::memcpy(&m_buffer[offset], data, size);
return true;
}
void* NzSoftwareBuffer::GetPointer()
{
return m_buffer;
}
bool NzSoftwareBuffer::IsHardware() const
{
return false;
}
void* NzSoftwareBuffer::Map(nzBufferAccess access, unsigned int offset, unsigned int size)
{
NazaraUnused(access);
NazaraUnused(size);
#if NAZARA_UTILITY_SAFE
if (m_mapped)
{
NazaraError("Buffer already mapped");
return nullptr;
}
#endif
m_mapped = true;
return &m_buffer[offset];
}
bool NzSoftwareBuffer::Unmap()
{
#if NAZARA_UTILITY_SAFE
if (!m_mapped)
{
NazaraError("Buffer not mapped");
return true;
}
#endif
m_mapped = false;
return true;
}

View File

@@ -0,0 +1,37 @@
// Copyright (C) 2012 Jérôme Leclercq
// This file is part of the "Nazara Engine".
// For conditions of distribution and use, see copyright notice in Config.hpp
#pragma once
#ifndef NAZARA_SOFTWAREBUFFER_HPP
#define NAZARA_SOFTWAREBUFFER_HPP
#include <Nazara/Prerequesites.hpp>
#include <Nazara/Utility/BufferImpl.hpp>
class NzSoftwareBuffer : public NzBufferImpl
{
public:
NzSoftwareBuffer(NzBuffer* parent, nzBufferType type);
~NzSoftwareBuffer();
bool Create(unsigned int size, nzBufferUsage usage = nzBufferUsage_Static);
void Destroy();
bool Fill(const void* data, unsigned int offset, unsigned int length);
void* GetPointer();
bool IsHardware() const;
void* Map(nzBufferAccess access, unsigned int offset = 0, unsigned int length = 0);
bool Unmap();
private:
nzBufferType m_type;
nzUInt8* m_buffer;
bool m_mapped;
};
#endif // NAZARA_SOFTWAREBUFFER_HPP

View File

@@ -4,6 +4,7 @@
#include <Nazara/Utility/Utility.hpp>
#include <Nazara/Core/Error.hpp>
#include <Nazara/Utility/Buffer.hpp>
#include <Nazara/Utility/Config.hpp>
#include <Nazara/Utility/Loaders/PCX.hpp>
#include <Nazara/Utility/Loaders/STB.hpp>
@@ -31,9 +32,15 @@ bool NzUtility::Initialize()
}
#endif
if (!NzBuffer::Initialize())
{
NazaraError("Failed to initialize buffers");
return false;
}
if (!NzPixelFormat::Initialize())
{
NazaraError("Failed to initialize pixel format");
NazaraError("Failed to initialize pixel formats");
return false;
}
@@ -45,10 +52,10 @@ bool NzUtility::Initialize()
return false;
}
// Loaders spécialisés
/// Loaders spécialisés
NzLoaders_PCX_Register(); // Loader de fichiers .PCX (1, 4, 8, 24)
// Loaders génériques (En dernier pour donner la priorité aux loaders spécialisés)
/// Loaders génériques (En dernier pour donner la priorité aux loaders spécialisés)
NzLoaders_STB_Register(); // Loader générique (STB)
s_initialized = true;
@@ -70,8 +77,8 @@ void NzUtility::Uninitialize()
NzLoaders_PCX_Unregister();
NzWindow::Uninitialize();
NzPixelFormat::Uninitialize();
NzBuffer::Uninitialize();
s_initialized = false;
}

View File

@@ -0,0 +1,126 @@
// Copyright (C) 2012 Jérôme Leclercq
// This file is part of the "Nazara Engine".
// For conditions of distribution and use, see copyright notice in Config.hpp
#include <Nazara/Utility/VertexBuffer.hpp>
#include <Nazara/Core/Error.hpp>
#include <Nazara/Utility/Debug.hpp>
NzVertexBuffer::NzVertexBuffer(NzBuffer* buffer, unsigned int startVertex, unsigned int vertexCount) :
m_buffer(buffer),
m_ownsBuffer(false),
m_startVertex(startVertex),
m_vertexCount(vertexCount)
{
#ifdef NAZARA_DEBUG
if (!m_buffer)
{
NazaraError("Passed buffer is null");
return;
}
#endif
m_buffer->AddResourceReference();
}
NzVertexBuffer::NzVertexBuffer(unsigned int length, nzUInt8 typeSize, nzBufferStorage storage, nzBufferUsage usage) :
m_ownsBuffer(true),
m_startVertex(0),
m_vertexCount(length)
{
m_buffer = new NzBuffer(nzBufferType_Vertex, length, typeSize, storage, usage);
m_buffer->AddResourceReference();
m_buffer->SetPersistent(false);
}
NzVertexBuffer::NzVertexBuffer(const NzVertexBuffer& vertexBuffer) :
m_ownsBuffer(vertexBuffer.m_ownsBuffer),
m_startVertex(vertexBuffer.m_startVertex),
m_vertexCount(vertexBuffer.m_vertexCount)
{
if (m_ownsBuffer)
{
NzBuffer* buffer = vertexBuffer.m_buffer;
m_buffer = new NzBuffer(nzBufferType_Vertex, buffer->GetLength(), buffer->GetSize(), buffer->GetStorage(), buffer->GetUsage());
m_buffer->AddResourceReference();
m_buffer->SetPersistent(false);
m_buffer->CopyContent(*vertexBuffer.m_buffer);
}
else
{
m_buffer = vertexBuffer.m_buffer;
m_buffer->AddResourceReference();
}
}
NzVertexBuffer::~NzVertexBuffer()
{
m_buffer->RemoveResourceReference();
}
bool NzVertexBuffer::Fill(const void* data, unsigned int offset, unsigned int length)
{
#if NAZARA_UTILITY_SAFE
if (offset+length > m_vertexCount)
{
NazaraError("Exceeding virtual buffer size");
return false;
}
#endif
return m_buffer->Fill(data, m_startVertex+offset, length);
}
NzBuffer* NzVertexBuffer::GetBuffer() const
{
return m_buffer;
}
void* NzVertexBuffer::GetPointer()
{
return reinterpret_cast<nzUInt8*>(m_buffer->GetPointer()) + m_startVertex*m_buffer->GetTypeSize();
}
const void* NzVertexBuffer::GetPointer() const
{
return reinterpret_cast<const nzUInt8*>(m_buffer->GetPointer()) + m_startVertex*m_buffer->GetTypeSize();
}
unsigned int NzVertexBuffer::GetStartVertex() const
{
return m_startVertex;
}
nzUInt8 NzVertexBuffer::GetTypeSize() const
{
return m_buffer->GetTypeSize();
}
unsigned int NzVertexBuffer::GetVertexCount() const
{
return m_vertexCount;
}
bool NzVertexBuffer::IsHardware() const
{
return m_buffer->IsHardware();
}
void* NzVertexBuffer::Map(nzBufferAccess access, unsigned int offset, unsigned int length)
{
#if NAZARA_UTILITY_SAFE
if (offset+length > m_vertexCount)
{
NazaraError("Exceeding virtual buffer size");
return nullptr;
}
#endif
return m_buffer->Map(access, m_startVertex+offset, (length) ? length : m_vertexCount-offset);
}
bool NzVertexBuffer::Unmap()
{
return m_buffer->Unmap();
}

View File

@@ -0,0 +1,119 @@
// Copyright (C) 2012 Jérôme Leclercq
// This file is part of the "Nazara Engine".
// 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 <Nazara/Utility/Debug.hpp>
namespace
{
const unsigned int size[] =
{
4, // nzElementType_Color
8, // nzElementType_Double1
16, // nzElementType_Double2
24, // nzElementType_Double3
32, // nzElementType_Double4
4, // nzElementType_Float1
8, // nzElementType_Float2
12, // nzElementType_Float3
16 // nzElementType_Float4
};
}
bool NzVertexDeclaration::Create(const NzVertexElement* elements, unsigned int elementCount)
{
for (unsigned int i = 0; i < elementCount; ++i)
{
unsigned int stream = elements[i].stream;
if (stream >= m_streams.size())
m_streams.resize(stream+1);
#if NAZARA_UTILITY_SAFE
else // Seulement si le stream ne vient pas d'être créé (Autrement c'est inutile)
{
for (unsigned int j = 0; j < i; ++j)
{
if (elements[j].stream == stream && elements[j].usage == elements[i].usage && elements[j].usageIndex == elements[i].usageIndex)
{
NazaraError("Element usage (" + NzString::Number(elements[j].usage, 16) + ") collision on stream " + NzString::Number(stream) + " with usage index " + NzString::Number(elements[j].usageIndex));
return false;
}
}
}
#endif
Element element;
element.offset = elements[i].offset;
element.type = elements[i].type;
element.usage = elements[i].usage;
element.usageIndex = elements[i].usageIndex;
m_streams[stream].elements.push_back(element);
}
for (Stream& stream : m_streams)
{
stream.stride = 0;
for (const Element& element : stream.elements)
stream.stride += size[element.type];
#if NAZARA_RENDERER_FORCE_DECLARATION_STRIDE_MULTIPLE_OF_32
stream.stride = ((static_cast<int>(stream.stride)-1)/32+1)*32;
#endif
}
return true;
}
const NzVertexDeclaration::Element* NzVertexDeclaration::GetElement(unsigned int i, unsigned int stream) const
{
#if NAZARA_UTILITY_SAFE
if (stream >= m_streams.size())
{
NazaraError("Stream out of range");
return nullptr;
}
if (i >= m_streams[stream].elements.size())
{
NazaraError("Index out of range");
return nullptr;
}
#endif
return &m_streams[stream].elements[i];
}
unsigned int NzVertexDeclaration::GetElementCount(unsigned int stream) const
{
#if NAZARA_UTILITY_SAFE
if (stream >= m_streams.size())
{
NazaraError("Stream out of range");
return 0;
}
#endif
return m_streams[stream].elements.size();
}
unsigned int NzVertexDeclaration::GetStreamCount() const
{
return m_streams.size();
}
unsigned int NzVertexDeclaration::GetStride(unsigned int stream) const
{
#if NAZARA_UTILITY_SAFE
if (stream >= m_streams.size())
{
NazaraError("Stream out of range");
return 0;
}
#endif
return m_streams[stream].stride;
}