Added RenderTextures (And many others things)
-Added Forward, left and up vector (Vector3) -Added Matrix4::ConcatenateAffine shortcut -Added Quaternion::GetInverse() and Quaternion::Inverse() -Added Resource listeners -Added Depth and stencil pixel formats -All enums now have an ending "max" entry -Animation/Mesh::Add[Sequence/Skin/SubMesh] now returns a boolean -Contexts are now resources -Enhanced AnimatedMesh demo -Fixed MD2 facing -Fixed Vector3::CrossProduct -Made Resource thread-safe -Made OpenGL translation table global -Many bugfixes -MLT will now write malloc failure to the log -Most of the strcpy were replaced with faster memcpy -Occlusion queries availability is now always tested -OpenGL-related includes now requires NAZARA_RENDERER_OPENGL to be defined to have any effect -Pixel formats now have a type -Renamed RenderTarget::IsValid to IsRenderable -Renamed Quaternion::GetNormalized() to GetNormal() -Renamed Texture::Bind() to Prepare() -Renamed VectorX::Make[Ceil|Floor] to Maximize/Minimize -Removed MATH_MATRIX_COLUMN_MAJOR option (all matrices are column-major) -Removed RENDERER_ACTIVATE_RENDERWINDOW_ON_CREATION option (Render windows are active upon their creation) Former-commit-id: 0d1da1e32c156a958221edf04a5315c75b354450
This commit is contained in:
@@ -1,337 +1,339 @@
|
||||
// Copyright (C) 2012 Jérôme Leclercq
|
||||
// This file is part of the "Nazara Engine - Utility module"
|
||||
// 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_storage = storage;
|
||||
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 == 0) ? m_length-offset : 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 == 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()
|
||||
{
|
||||
#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};
|
||||
// Copyright (C) 2012 Jérôme Leclercq
|
||||
// This file is part of the "Nazara Engine - Utility module"
|
||||
// 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_storage = storage;
|
||||
m_usage = usage;
|
||||
|
||||
NotifyCreated();
|
||||
return true; // Si on arrive ici c'est que tout s'est bien passé.
|
||||
}
|
||||
|
||||
void NzBuffer::Destroy()
|
||||
{
|
||||
if (m_impl)
|
||||
{
|
||||
NotifyDestroy();
|
||||
|
||||
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 == 0) ? m_length-offset : 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 == 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()
|
||||
{
|
||||
#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};
|
||||
|
||||
Reference in New Issue
Block a user