Merge remote-tracking branch 'upstream/master'
This commit is contained in:
@@ -13,8 +13,6 @@
|
||||
#error OS not handled
|
||||
#endif
|
||||
|
||||
#define NAZARA_CLASS_CLOCK
|
||||
#include <Nazara/Core/ThreadSafety.hpp>
|
||||
#include <Nazara/Core/Debug.hpp>
|
||||
|
||||
NzClock::NzClock() :
|
||||
|
||||
@@ -16,8 +16,6 @@
|
||||
#error OS not handled
|
||||
#endif
|
||||
|
||||
#define NAZARA_CLASS_DIRECTORY
|
||||
#include <Nazara/Core/ThreadSafety.hpp>
|
||||
#include <Nazara/Core/Debug.hpp>
|
||||
|
||||
namespace
|
||||
|
||||
@@ -14,8 +14,6 @@
|
||||
#error No implementation for this platform
|
||||
#endif
|
||||
|
||||
#define NAZARA_CLASS_DYNLIB
|
||||
#include <Nazara/Core/ThreadSafety.hpp>
|
||||
#include <Nazara/Core/Debug.hpp>
|
||||
|
||||
NzDynLib::NzDynLib(const NzString& libraryPath) :
|
||||
|
||||
@@ -19,8 +19,6 @@
|
||||
#error OS not handled
|
||||
#endif
|
||||
|
||||
#define NAZARA_CLASS_FILE
|
||||
#include <Nazara/Core/ThreadSafety.hpp>
|
||||
#include <Nazara/Core/Debug.hpp>
|
||||
|
||||
NzFile::NzFile() :
|
||||
@@ -295,6 +293,7 @@ std::size_t NzFile::Read(void* buffer, std::size_t size)
|
||||
return m_impl->Read(buffer, size);
|
||||
else
|
||||
{
|
||||
// Si nous ne devons rien lire, nous avançons simplement
|
||||
nzUInt64 currentPos = m_impl->GetCursorPos();
|
||||
|
||||
m_impl->SetCursorPos(NzFile::AtCurrent, size);
|
||||
|
||||
@@ -13,8 +13,6 @@
|
||||
#include <cstdio>
|
||||
#endif
|
||||
|
||||
#define NAZARA_CLASS_LOG
|
||||
#include <Nazara/Core/ThreadSafety.hpp>
|
||||
#include <Nazara/Core/Debug.hpp>
|
||||
|
||||
namespace
|
||||
|
||||
@@ -13,15 +13,13 @@
|
||||
#include <cstring>
|
||||
#include <sstream>
|
||||
#include <Utfcpp/utf8.h>
|
||||
|
||||
#define NAZARA_CLASS_STRING
|
||||
#include <Nazara/Core/ThreadSafety.hpp>
|
||||
#include <Nazara/Core/Debug.hpp>
|
||||
|
||||
inline unsigned int nzPow2(unsigned int n)
|
||||
{
|
||||
unsigned int x = 1;
|
||||
|
||||
// Tant que x est plus petit que n, on décale ses bits vers la gauche, ce qui revient à multiplier par deux
|
||||
while(x <= n)
|
||||
x <<= 1;
|
||||
|
||||
@@ -265,9 +263,15 @@ NzString& NzString::Append(const NzString& string)
|
||||
return *this;
|
||||
}
|
||||
|
||||
void NzString::Clear()
|
||||
void NzString::Clear(bool keepBuffer)
|
||||
{
|
||||
ReleaseString();
|
||||
if (keepBuffer)
|
||||
{
|
||||
EnsureOwnership();
|
||||
m_sharedString->size = 0;
|
||||
}
|
||||
else
|
||||
ReleaseString();
|
||||
}
|
||||
|
||||
bool NzString::Contains(char character, int start, nzUInt32 flags) const
|
||||
@@ -2843,7 +2847,7 @@ unsigned int NzString::Replace(const char* oldString, const char* replaceString,
|
||||
else ///TODO: Algorithme de remplacement sans changement de buffer (si rSize < oSize)
|
||||
{
|
||||
unsigned int newSize = m_sharedString->size + Count(oldString)*(rSize - oSize);
|
||||
if (newSize == m_sharedString->size) // Count(oldString) == 0
|
||||
if (newSize == m_sharedString->size) // Alors c'est que Count(oldString) == 0
|
||||
return 0;
|
||||
|
||||
char* newString = new char[newSize+1];
|
||||
@@ -2913,7 +2917,7 @@ unsigned int NzString::Replace(const NzString& oldString, const NzString& replac
|
||||
else
|
||||
{
|
||||
unsigned int newSize = m_sharedString->size + Count(oldString)*(replaceString.m_sharedString->size - oldString.m_sharedString->size);
|
||||
if (newSize == m_sharedString->size) // Count(oldString) == 0
|
||||
if (newSize == m_sharedString->size) // Alors c'est que Count(oldString) == 0
|
||||
return 0;
|
||||
|
||||
char* newString = new char[newSize+1];
|
||||
@@ -3198,6 +3202,9 @@ void NzString::Reserve(unsigned int bufferSize)
|
||||
|
||||
NzString& NzString::Resize(int size, char character)
|
||||
{
|
||||
if (size == 0)
|
||||
Clear(true);
|
||||
|
||||
if (size < 0)
|
||||
size = std::max(static_cast<int>(m_sharedString->size + size), 0);
|
||||
|
||||
@@ -3242,6 +3249,9 @@ NzString& NzString::Resize(int size, char character)
|
||||
|
||||
NzString NzString::Resized(int size, char character) const
|
||||
{
|
||||
if (size == 0)
|
||||
return NzString();
|
||||
|
||||
if (size < 0)
|
||||
size = m_sharedString->size + size;
|
||||
|
||||
@@ -3492,8 +3502,9 @@ unsigned int NzString::SplitAny(std::vector<NzString>& result, const char* separ
|
||||
if (m_sharedString->size == 0)
|
||||
return 0;
|
||||
|
||||
unsigned int lastSep = FindAny(separations, start, flags);
|
||||
unsigned int oldSize = result.size();
|
||||
|
||||
unsigned int lastSep = FindAny(separations, start, flags);
|
||||
if (lastSep == npos)
|
||||
{
|
||||
result.push_back(*this);
|
||||
@@ -3842,7 +3853,7 @@ bool NzString::ToBool(bool* value, nzUInt32 flags) const
|
||||
|
||||
bool NzString::ToDouble(double* value) const
|
||||
{
|
||||
if (m_sharedString->size)
|
||||
if (m_sharedString->size == 0)
|
||||
return false;
|
||||
|
||||
if (value)
|
||||
@@ -3853,13 +3864,15 @@ bool NzString::ToDouble(double* value) const
|
||||
|
||||
bool NzString::ToInteger(long long* value, nzUInt8 base) const
|
||||
{
|
||||
if (!IsNumber(base))
|
||||
return false;
|
||||
|
||||
if (value)
|
||||
*value = NzStringToNumber(*this, base);
|
||||
{
|
||||
bool ok;
|
||||
*value = NzStringToNumber(*this, base, &ok);
|
||||
|
||||
return true;
|
||||
return ok;
|
||||
}
|
||||
else
|
||||
return IsNumber(base);
|
||||
}
|
||||
|
||||
NzString NzString::ToLower(nzUInt32 flags) const
|
||||
@@ -5089,11 +5102,12 @@ void NzString::ReleaseString()
|
||||
return;
|
||||
|
||||
NazaraMutexLock(m_sharedString->mutex);
|
||||
m_sharedString->refCount--;
|
||||
bool freeSharedString = (--m_sharedString->refCount == 0);
|
||||
NazaraMutexUnlock(m_sharedString->mutex);
|
||||
|
||||
if (m_sharedString->refCount == 0)
|
||||
if (freeSharedString)
|
||||
{
|
||||
NazaraMutexUnlock(m_sharedString->mutex);
|
||||
delete[] m_sharedString->string;
|
||||
delete m_sharedString;
|
||||
}
|
||||
|
||||
@@ -6,49 +6,46 @@
|
||||
#include <Nazara/Core/Config.hpp>
|
||||
#include <Nazara/Core/Debug.hpp>
|
||||
|
||||
namespace NzUnicode
|
||||
#if NAZARA_CORE_INCLUDE_UNICODEDATA
|
||||
struct Character
|
||||
{
|
||||
#if NAZARA_CORE_INCLUDE_UNICODEDATA
|
||||
struct Character
|
||||
{
|
||||
nzUInt16 category; // Le type du caractère
|
||||
nzUInt8 direction; // Le sens de lecure du caractère
|
||||
nzUInt32 lowerCase; // Le caractère correspondant en minuscule
|
||||
nzUInt32 titleCase; // Le caractère correspondant en titre
|
||||
nzUInt32 upperCase; // Le caractère correspondant en majuscule
|
||||
};
|
||||
nzUInt16 category; // Le type du caractère
|
||||
nzUInt8 direction; // Le sens de lecure du caractère
|
||||
nzUInt32 lowerCase; // Le caractère correspondant en minuscule
|
||||
nzUInt32 titleCase; // Le caractère correspondant en titre
|
||||
nzUInt32 upperCase; // Le caractère correspondant en majuscule
|
||||
};
|
||||
|
||||
#include <Nazara/Core/UnicodeData.hpp>
|
||||
#include <Nazara/Core/UnicodeData.hpp>
|
||||
|
||||
#else // Implémentation bidon
|
||||
#else // Implémentation bidon
|
||||
|
||||
Category GetCategory(char32_t character)
|
||||
{
|
||||
NazaraUnused(character);
|
||||
NzUnicode::Category NzUnicode::GetCategory(char32_t character)
|
||||
{
|
||||
NazaraUnused(character);
|
||||
|
||||
return Category_NoCategory;
|
||||
}
|
||||
|
||||
Direction GetDirection(char32_t character)
|
||||
{
|
||||
NazaraUnused(character);
|
||||
|
||||
return Direction_Boundary_Neutral;
|
||||
}
|
||||
|
||||
char32_t GetLowercase(char32_t character)
|
||||
{
|
||||
return character;
|
||||
}
|
||||
|
||||
char32_t GetTitlecase(char32_t character)
|
||||
{
|
||||
return character;
|
||||
}
|
||||
|
||||
char32_t GetUppercase(char32_t character)
|
||||
{
|
||||
return character;
|
||||
}
|
||||
#endif
|
||||
return Category_NoCategory;
|
||||
}
|
||||
|
||||
NzUnicode::Direction NzUnicode::GetDirection(char32_t character)
|
||||
{
|
||||
NazaraUnused(character);
|
||||
|
||||
return Direction_Boundary_Neutral;
|
||||
}
|
||||
|
||||
char32_t NzUnicode::GetLowercase(char32_t character)
|
||||
{
|
||||
return character;
|
||||
}
|
||||
|
||||
char32_t NzUnicode::GetTitlecase(char32_t character)
|
||||
{
|
||||
return character;
|
||||
}
|
||||
|
||||
char32_t NzUnicode::GetUppercase(char32_t character)
|
||||
{
|
||||
return character;
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -2,13 +2,13 @@
|
||||
// This file is part of the "Nazara Engine".
|
||||
// For conditions of distribution and use, see copyright notice in Config.hpp
|
||||
|
||||
// http://www.cs.wustl.edu/~schmidt/win32-cv-1.html
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef NAZARA_THREADCONDITIONIMPL_HPP
|
||||
#define NAZARA_THREADCONDITIONIMPL_HPP
|
||||
|
||||
// http://www.cs.wustl.edu/~schmidt/win32-cv-1.html
|
||||
|
||||
#include <Nazara/Prerequesites.hpp>
|
||||
#include <windows.h>
|
||||
|
||||
|
||||
@@ -1,243 +0,0 @@
|
||||
// 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/Renderer/OpenGL.hpp>
|
||||
#include <Nazara/Renderer/Buffer.hpp>
|
||||
#include <Nazara/Core/Error.hpp>
|
||||
#include <Nazara/Renderer/Config.hpp>
|
||||
#include <Nazara/Renderer/HardwareBuffer.hpp>
|
||||
#include <Nazara/Renderer/Renderer.hpp>
|
||||
#include <Nazara/Renderer/SoftwareBuffer.hpp>
|
||||
#include <stdexcept>
|
||||
#include <Nazara/Renderer/Debug.hpp>
|
||||
|
||||
namespace
|
||||
{
|
||||
nzRendererCap storageToCapability[] = {
|
||||
nzRendererCap_HardwareBuffer, // nzBufferStorage_Hardware
|
||||
nzRendererCap_SoftwareBuffer, // nzBufferStorage_Software
|
||||
};
|
||||
}
|
||||
|
||||
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, nzBufferUsage usage) :
|
||||
m_type(type),
|
||||
m_impl(nullptr)
|
||||
{
|
||||
Create(length, typeSize, 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)
|
||||
{
|
||||
void* ptr = buffer.Map(nzBufferAccess_ReadOnly);
|
||||
if (!ptr)
|
||||
{
|
||||
NazaraError("Failed to map source buffer");
|
||||
return false;
|
||||
}
|
||||
|
||||
bool r = Fill(ptr, 0, m_length);
|
||||
|
||||
if (!buffer.Unmap())
|
||||
NazaraWarning("Failed to unmap source buffer");
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
bool NzBuffer::Create(unsigned int length, nzUInt8 typeSize, nzBufferUsage usage)
|
||||
{
|
||||
Destroy();
|
||||
|
||||
// On tente d'abord de faire un buffer hardware, si supporté
|
||||
if (NazaraRenderer->HasCapability(nzRendererCap_HardwareBuffer))
|
||||
{
|
||||
m_impl = new NzHardwareBuffer(this, m_type);
|
||||
if (!m_impl->Create(length*typeSize, usage))
|
||||
{
|
||||
NazaraWarning("Failed to create hardware buffer, trying to create software buffer...");
|
||||
|
||||
delete m_impl;
|
||||
m_impl = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
if (!m_impl)
|
||||
{
|
||||
if (!NazaraRenderer->HasCapability(nzRendererCap_SoftwareBuffer))
|
||||
{
|
||||
// Ne devrait jamais arriver
|
||||
NazaraError("Software buffer not supported");
|
||||
return false;
|
||||
}
|
||||
|
||||
m_impl = new NzSoftwareBuffer(this, m_type);
|
||||
if (!m_impl->Create(length*typeSize, usage))
|
||||
{
|
||||
NazaraError("Failed to create software buffer");
|
||||
delete m_impl;
|
||||
m_impl = nullptr;
|
||||
|
||||
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_RENDERER_SAFE
|
||||
if (!m_impl)
|
||||
{
|
||||
NazaraError("Buffer not created");
|
||||
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);
|
||||
}
|
||||
|
||||
void* NzBuffer::GetBufferPtr()
|
||||
{
|
||||
#if NAZARA_RENDERER_SAFE
|
||||
if (!m_impl)
|
||||
{
|
||||
NazaraError("Buffer not created");
|
||||
return nullptr;
|
||||
}
|
||||
#endif
|
||||
|
||||
return m_impl->GetBufferPtr();
|
||||
}
|
||||
|
||||
const void* NzBuffer::GetBufferPtr() const
|
||||
{
|
||||
#if NAZARA_RENDERER_SAFE
|
||||
if (!m_impl)
|
||||
{
|
||||
NazaraError("Buffer not created");
|
||||
return nullptr;
|
||||
}
|
||||
#endif
|
||||
|
||||
return m_impl->GetBufferPtr();
|
||||
}
|
||||
|
||||
NzBufferImpl* NzBuffer::GetImpl() const
|
||||
{
|
||||
return m_impl;
|
||||
}
|
||||
|
||||
unsigned int NzBuffer::GetLength() const
|
||||
{
|
||||
return m_length;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
void* NzBuffer::Map(nzBufferAccess access, unsigned int offset, unsigned int length)
|
||||
{
|
||||
#if NAZARA_RENDERER_SAFE
|
||||
if (!m_impl)
|
||||
{
|
||||
NazaraError("Buffer not created");
|
||||
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_RENDERER_SAFE
|
||||
if (!m_impl)
|
||||
{
|
||||
NazaraError("Buffer not created");
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
return m_impl->Unmap();
|
||||
}
|
||||
|
||||
bool NzBuffer::IsSupported(nzBufferStorage storage)
|
||||
{
|
||||
return NazaraRenderer->HasCapability(storageToCapability[storage]);
|
||||
}
|
||||
@@ -1,33 +0,0 @@
|
||||
// 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_BUFFERIMPL_HPP
|
||||
#define NAZARA_BUFFERIMPL_HPP
|
||||
|
||||
#include <Nazara/Renderer/Buffer.hpp>
|
||||
|
||||
class NzBufferImpl
|
||||
{
|
||||
public:
|
||||
NzBufferImpl() = default;
|
||||
virtual ~NzBufferImpl();
|
||||
|
||||
virtual void Bind() = 0;
|
||||
|
||||
virtual bool Create(unsigned int size, nzBufferUsage usage = nzBufferUsage_Static) = 0;
|
||||
virtual void Destroy() = 0;
|
||||
|
||||
virtual bool Fill(const void* data, unsigned int offset, unsigned int size) = 0;
|
||||
|
||||
virtual void* GetBufferPtr() = 0;
|
||||
|
||||
virtual bool IsHardware() const = 0;
|
||||
|
||||
virtual void* Map(nzBufferAccess access, unsigned int offset = 0, unsigned int size = 0) = 0;
|
||||
virtual bool Unmap() = 0;
|
||||
};
|
||||
|
||||
#endif // NAZARA_BUFFERIMPL_INCLUDED
|
||||
@@ -290,7 +290,8 @@ bool NzContext::EnsureContext()
|
||||
|
||||
threadContext = context;
|
||||
}
|
||||
else if (!threadContext->SetActive(true))
|
||||
|
||||
if (!threadContext->SetActive(true))
|
||||
{
|
||||
NazaraError("Failed to active thread context");
|
||||
return false;
|
||||
|
||||
@@ -6,15 +6,27 @@
|
||||
#include <Nazara/Renderer/Config.hpp>
|
||||
#include <Nazara/Renderer/Debug.hpp>
|
||||
|
||||
nzUInt8 NzContextParameters::defaultMajorVersion; // Initialisé par NzOpenGL
|
||||
nzUInt8 NzContextParameters::defaultMinorVersion; // Initialisé par NzOpenGL
|
||||
// Version majeure d'OpenGL, initialisé par NzOpenGL::Initialize()
|
||||
nzUInt8 NzContextParameters::defaultMajorVersion;
|
||||
|
||||
// Version majeure d'OpenGL, initialisé par NzOpenGL::Initialize()
|
||||
nzUInt8 NzContextParameters::defaultMinorVersion;
|
||||
|
||||
// Contexte de partage par défaut, initialisé par NzOpenGL::Initialize()
|
||||
const NzContext* NzContextParameters::defaultShareContext = nullptr;
|
||||
NzWindowHandle NzContextParameters::defaultWindow = 0;
|
||||
|
||||
// Si possible, garder la compatibilité avec les fonctionnalités dépréciées
|
||||
bool NzContextParameters::defaultCompatibilityProfile = false;
|
||||
|
||||
// Mode debug d'OpenGL par défaut
|
||||
#if NAZARA_RENDERER_OPENGL_DEBUG || defined(NAZARA_DEBUG)
|
||||
bool NzContextParameters::defaultDebugMode = true;
|
||||
#else
|
||||
bool NzContextParameters::defaultDebugMode = false;
|
||||
#endif
|
||||
|
||||
// Active le double-buffering sur les contextes
|
||||
bool NzContextParameters::defaultDoubleBuffered = false;
|
||||
|
||||
// Active le partage des ressources entre contextes (Via le defaultShareContext)
|
||||
bool NzContextParameters::defaultShared = true;
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
#include <Nazara/Renderer/Context.hpp>
|
||||
#include <Nazara/Renderer/Renderer.hpp>
|
||||
#include <Nazara/Renderer/Texture.hpp>
|
||||
#include <Nazara/Renderer/VertexDeclaration.hpp>
|
||||
#include <Nazara/Utility/VertexDeclaration.hpp>
|
||||
#include <Nazara/Renderer/Debug.hpp>
|
||||
|
||||
namespace
|
||||
@@ -24,7 +24,7 @@ namespace
|
||||
4 // nzElementUsage_TexCoord
|
||||
};
|
||||
|
||||
const GLenum shaderType[nzShaderType_Count] = {
|
||||
const GLenum shaderType[nzShaderType_Max+1] = {
|
||||
GL_FRAGMENT_SHADER, // nzShaderType_Fragment
|
||||
GL_GEOMETRY_SHADER, // nzShaderType_Geometry
|
||||
GL_VERTEX_SHADER // nzShaderType_Vertex
|
||||
@@ -98,6 +98,7 @@ bool NzGLSLShader::Compile()
|
||||
glGetProgramiv(m_program, GL_INFO_LOG_LENGTH, &length);
|
||||
if (length > 1)
|
||||
{
|
||||
m_log.Clear(true);
|
||||
m_log.Reserve(length+19-1); // La taille retournée est celle du buffer (Avec caractère de fin)
|
||||
m_log.Prepend("Linkage error: ");
|
||||
m_log.Resize(length+19-1); // Extension du buffer d'écriture pour ajouter le log
|
||||
@@ -129,14 +130,15 @@ bool NzGLSLShader::Create()
|
||||
glBindAttribLocation(m_program, attribIndex[nzElementUsage_Diffuse], "Diffuse");
|
||||
glBindAttribLocation(m_program, attribIndex[nzElementUsage_Tangent], "Tangent");
|
||||
|
||||
NzString uniformName = "TexCoordi";
|
||||
for (unsigned int i = 0; i < 8; ++i)
|
||||
NzString uniform = "TexCoord";
|
||||
unsigned int maxTexCoords = NazaraRenderer->GetMaxTextureUnits();
|
||||
for (unsigned int i = 0; i < maxTexCoords; ++i)
|
||||
{
|
||||
uniformName[8] = '0'+i;
|
||||
NzString uniformName = uniform + NzString::Number(i);
|
||||
glBindAttribLocation(m_program, attribIndex[nzElementUsage_TexCoord]+i, uniformName.GetConstBuffer());
|
||||
}
|
||||
|
||||
for (int i = 0; i < nzShaderType_Count; ++i)
|
||||
for (int i = 0; i <= nzShaderType_Max; ++i)
|
||||
m_shaders[i] = 0;
|
||||
|
||||
return true;
|
||||
@@ -242,6 +244,7 @@ bool NzGLSLShader::Load(nzShaderType type, const NzString& source)
|
||||
glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &length);
|
||||
if (length > 1)
|
||||
{
|
||||
m_log.Clear(true);
|
||||
m_log.Reserve(length+19-1); // La taille retournée est celle du buffer (Avec caractère de fin)
|
||||
m_log.Prepend("Compilation error: ");
|
||||
m_log.Resize(length+19-1); // Extension du buffer d'écriture pour ajouter le log
|
||||
|
||||
@@ -63,7 +63,7 @@ class NzGLSLShader : public NzShaderImpl
|
||||
mutable std::map<NzString, GLint> m_idCache;
|
||||
std::map<GLint, TextureSlot> m_textures;
|
||||
GLuint m_program;
|
||||
GLuint m_shaders[nzShaderType_Count];
|
||||
GLuint m_shaders[nzShaderType_Max+1];
|
||||
NzShader* m_parent;
|
||||
NzString m_log;
|
||||
};
|
||||
|
||||
@@ -52,14 +52,14 @@ namespace
|
||||
|
||||
if (access == nzBufferAccess_DiscardAndWrite)
|
||||
{
|
||||
GLint size;
|
||||
glGetBufferParameteriv(bufferTargetBinding[type], GL_BUFFER_SIZE, &size);
|
||||
GLint bufferSize;
|
||||
glGetBufferParameteriv(bufferTargetBinding[type], GL_BUFFER_SIZE, &bufferSize);
|
||||
|
||||
GLint usage;
|
||||
glGetBufferParameteriv(bufferTargetBinding[type], GL_BUFFER_USAGE, &usage);
|
||||
GLint bufferUsage;
|
||||
glGetBufferParameteriv(bufferTargetBinding[type], GL_BUFFER_USAGE, &bufferUsage);
|
||||
|
||||
// On discard le buffer
|
||||
glBufferData(bufferTargetBinding[type], size, nullptr, usage);
|
||||
glBufferData(bufferTargetBinding[type], bufferSize, nullptr, bufferUsage);
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
// http://www.opengl.org/wiki/Vertex_Specification_Best_Practices
|
||||
if (size == m_parent->GetLength())
|
||||
glBufferData(bufferTarget[m_type], m_parent->GetSize(), nullptr, bufferUsage[m_parent->GetStorage()]); // Discard
|
||||
if (size == m_parent->GetSize())
|
||||
glBufferData(bufferTarget[m_type], m_parent->GetSize(), nullptr, bufferUsage[m_parent->GetUsage()]); // Discard
|
||||
|
||||
glBufferSubData(bufferTarget[m_type], offset, size, data);
|
||||
}
|
||||
@@ -188,7 +188,7 @@ bool NzHardwareBuffer::Fill(const void* data, unsigned int offset, unsigned int
|
||||
return true;
|
||||
}
|
||||
|
||||
void* NzHardwareBuffer::GetBufferPtr()
|
||||
void* NzHardwareBuffer::GetPointer()
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
@@ -198,7 +198,7 @@ bool NzHardwareBuffer::IsHardware() const
|
||||
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();
|
||||
|
||||
@@ -209,7 +209,7 @@ void* NzHardwareBuffer::Map(nzBufferAccess access, unsigned int offset, unsigned
|
||||
if (previous != 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)
|
||||
if (previous != m_buffer && previous != 0)
|
||||
@@ -235,14 +235,14 @@ bool NzHardwareBuffer::Unmap()
|
||||
|
||||
glBufferData(bufferTarget[m_type], m_parent->GetSize(), nullptr, bufferUsage[m_parent->GetStorage()]);
|
||||
|
||||
// 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érations chaînées)
|
||||
if (previous != m_buffer && previous != 0)
|
||||
glBindBuffer(bufferTarget[m_type], previous);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// 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érations chaînées)
|
||||
if (previous != m_buffer && previous != 0)
|
||||
glBindBuffer(bufferTarget[m_type], previous);
|
||||
|
||||
|
||||
@@ -8,8 +8,8 @@
|
||||
#define NAZARA_HARDWAREBUFFER_HPP
|
||||
|
||||
#include <Nazara/Prerequesites.hpp>
|
||||
#include <Nazara/Renderer/BufferImpl.hpp>
|
||||
#include <Nazara/Renderer/OpenGL.hpp>
|
||||
#include <Nazara/Utility/BufferImpl.hpp>
|
||||
|
||||
class NzHardwareBuffer : public NzBufferImpl
|
||||
{
|
||||
@@ -22,13 +22,13 @@ class NzHardwareBuffer : public NzBufferImpl
|
||||
bool Create(unsigned int size, nzBufferUsage usage = nzBufferUsage_Static);
|
||||
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* GetBufferPtr();
|
||||
void* GetPointer();
|
||||
|
||||
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();
|
||||
|
||||
private:
|
||||
|
||||
@@ -298,7 +298,8 @@ bool NzOpenGL::Initialize()
|
||||
return false;
|
||||
}
|
||||
|
||||
// Fonctions optionnelles
|
||||
/****************************************Extensions****************************************/
|
||||
|
||||
glGetStringi = reinterpret_cast<PFNGLGETSTRINGIPROC>(LoadEntry("glGetStringi", false));
|
||||
glMapBufferRange = reinterpret_cast<PFNGLMAPBUFFERRANGEPROC>(LoadEntry("glMapBufferRange", false));
|
||||
|
||||
@@ -310,8 +311,6 @@ bool NzOpenGL::Initialize()
|
||||
glXSwapInterval = reinterpret_cast<PFNGLXSWAPINTERVALSGIPROC>(LoadEntry("glXSwapIntervalSGI", false));
|
||||
#endif
|
||||
|
||||
/****************************************Extensions****************************************/
|
||||
|
||||
if (!glGetStringi || !LoadExtensions3())
|
||||
{
|
||||
if (openGLversion >= 300) // Dans le cas contraire c'est normal
|
||||
@@ -353,7 +352,7 @@ bool NzOpenGL::Initialize()
|
||||
}
|
||||
catch (const std::exception& e)
|
||||
{
|
||||
NazaraError("Failed to load GL_ARB_debug_output: " + NzString(e.what()));
|
||||
NazaraWarning("Failed to load GL_ARB_debug_output: " + NzString(e.what()));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -371,7 +370,7 @@ bool NzOpenGL::Initialize()
|
||||
}
|
||||
catch (const std::exception& e)
|
||||
{
|
||||
NazaraError("Failed to load ARB_gpu_shader_fp64: " + NzString(e.what()));
|
||||
NazaraWarning("Failed to load ARB_gpu_shader_fp64: " + NzString(e.what()));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -396,10 +395,13 @@ bool NzOpenGL::Initialize()
|
||||
}
|
||||
catch (const std::exception& e)
|
||||
{
|
||||
NazaraError("Failed to load ARB_framebuffer_object: (" + NzString(e.what()) + ")");
|
||||
NazaraWarning("Failed to load ARB_framebuffer_object: (" + NzString(e.what()) + ")");
|
||||
}
|
||||
}
|
||||
|
||||
// PixelBufferObject
|
||||
openGLextensions[NzOpenGL::PixelBufferObject] = (openGLversion >= 210 || IsSupported("GL_ARB_pixel_buffer_object"));
|
||||
|
||||
// SeparateShaderObjects
|
||||
if (openGLversion >= 400 || IsSupported("GL_ARB_gpu_shader_fp64"))
|
||||
{
|
||||
@@ -449,7 +451,7 @@ bool NzOpenGL::Initialize()
|
||||
}
|
||||
catch (const std::exception& e)
|
||||
{
|
||||
NazaraError("Failed to load EXT_texture3D: " + NzString(e.what()));
|
||||
NazaraWarning("Failed to load EXT_texture3D: " + NzString(e.what()));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -470,7 +472,7 @@ bool NzOpenGL::Initialize()
|
||||
}
|
||||
catch (const std::exception& e)
|
||||
{
|
||||
NazaraError("Failed to load ARB_texture_storage: " + NzString(e.what()));
|
||||
NazaraWarning("Failed to load ARB_texture_storage: " + NzString(e.what()));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -487,10 +489,14 @@ bool NzOpenGL::Initialize()
|
||||
}
|
||||
catch (const std::exception& e)
|
||||
{
|
||||
NazaraError("Failed to load ARB_vertex_array_object: " + NzString(e.what()));
|
||||
NazaraWarning("Failed to load ARB_vertex_array_object: " + NzString(e.what()));
|
||||
}
|
||||
}
|
||||
|
||||
// Fonctions de substitut
|
||||
if (!glGenerateMipmap)
|
||||
glGenerateMipmap = reinterpret_cast<PFNGLGENERATEMIPMAPEXTPROC>(LoadEntry("glGenerateMipmapEXT", false));
|
||||
|
||||
/****************************************Contexte de référence****************************************/
|
||||
|
||||
///FIXME: Utiliser le contexte de chargement comme référence ? (Vérifier mode debug)
|
||||
@@ -502,6 +508,8 @@ bool NzOpenGL::Initialize()
|
||||
return false;
|
||||
}
|
||||
|
||||
NzContextParameters::defaultShareContext = NzContext::GetReference();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -6,16 +6,17 @@
|
||||
#include <Nazara/Renderer/Renderer.hpp>
|
||||
#include <Nazara/Core/Color.hpp>
|
||||
#include <Nazara/Core/Error.hpp>
|
||||
#include <Nazara/Renderer/BufferImpl.hpp>
|
||||
#include <Nazara/Renderer/Config.hpp>
|
||||
#include <Nazara/Renderer/Context.hpp>
|
||||
#include <Nazara/Renderer/IndexBuffer.hpp>
|
||||
#include <Nazara/Renderer/HardwareBuffer.hpp>
|
||||
#include <Nazara/Renderer/RenderTarget.hpp>
|
||||
#include <Nazara/Renderer/Shader.hpp>
|
||||
#include <Nazara/Renderer/ShaderImpl.hpp>
|
||||
#include <Nazara/Renderer/VertexBuffer.hpp>
|
||||
#include <Nazara/Renderer/VertexDeclaration.hpp>
|
||||
#include <Nazara/Utility/BufferImpl.hpp>
|
||||
#include <Nazara/Utility/IndexBuffer.hpp>
|
||||
#include <Nazara/Utility/Utility.hpp>
|
||||
#include <Nazara/Utility/VertexBuffer.hpp>
|
||||
#include <Nazara/Utility/VertexDeclaration.hpp>
|
||||
#include <stdexcept>
|
||||
#include <Nazara/Renderer/Debug.hpp>
|
||||
|
||||
@@ -27,7 +28,8 @@ namespace
|
||||
1, // nzElementUsage_Normal
|
||||
0, // nzElementUsage_Position
|
||||
3, // nzElementUsage_Tangent
|
||||
4 // nzElementUsage_TexCoord
|
||||
|
||||
4 // nzElementUsage_TexCoord (Doit être le dernier de la liste car extensible)
|
||||
};
|
||||
|
||||
|
||||
@@ -128,6 +130,11 @@ namespace
|
||||
GL_REPLACE, // nzStencilOperation_Replace
|
||||
GL_ZERO // nzStencilOperation_Zero
|
||||
};
|
||||
|
||||
NzBufferImpl* HardwareBufferFunction(NzBuffer* parent, nzBufferType type)
|
||||
{
|
||||
return new NzHardwareBuffer(parent, type);
|
||||
}
|
||||
}
|
||||
|
||||
NzRenderer::NzRenderer()
|
||||
@@ -197,29 +204,34 @@ void NzRenderer::DrawIndexedPrimitives(nzPrimitiveType primitive, unsigned int f
|
||||
return;
|
||||
}
|
||||
|
||||
nzUInt8 indexSize = m_indexBuffer->GetIndexSize();
|
||||
|
||||
GLenum type;
|
||||
switch (indexSize)
|
||||
if (m_indexBuffer->IsSequential())
|
||||
glDrawArrays(openglPrimitive[primitive], m_indexBuffer->GetStartIndex(), m_indexBuffer->GetIndexCount());
|
||||
else
|
||||
{
|
||||
case 1:
|
||||
type = GL_UNSIGNED_BYTE;
|
||||
break;
|
||||
nzUInt8 indexSize = m_indexBuffer->GetIndexSize();
|
||||
|
||||
case 2:
|
||||
type = GL_UNSIGNED_SHORT;
|
||||
break;
|
||||
GLenum type;
|
||||
switch (indexSize)
|
||||
{
|
||||
case 1:
|
||||
type = GL_UNSIGNED_BYTE;
|
||||
break;
|
||||
|
||||
case 4:
|
||||
type = GL_UNSIGNED_INT;
|
||||
break;
|
||||
case 2:
|
||||
type = GL_UNSIGNED_SHORT;
|
||||
break;
|
||||
|
||||
default:
|
||||
NazaraError("Invalid index size (" + NzString::Number(indexSize) + ')');
|
||||
return;
|
||||
case 4:
|
||||
type = GL_UNSIGNED_INT;
|
||||
break;
|
||||
|
||||
default:
|
||||
NazaraError("Invalid index size (" + NzString::Number(indexSize) + ')');
|
||||
return;
|
||||
}
|
||||
|
||||
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->GetBufferPtr()) + firstIndex*indexSize);
|
||||
}
|
||||
|
||||
void NzRenderer::DrawPrimitives(nzPrimitiveType primitive, unsigned int firstVertex, unsigned int vertexCount)
|
||||
@@ -333,15 +345,13 @@ bool NzRenderer::Initialize()
|
||||
m_utilityModule = new NzUtility;
|
||||
m_utilityModule->Initialize();
|
||||
}
|
||||
else
|
||||
m_utilityModule = nullptr;
|
||||
|
||||
if (NzOpenGL::Initialize())
|
||||
{
|
||||
NzContext::EnsureContext();
|
||||
|
||||
const NzContext* context = NzContext::GetReference();
|
||||
bool compatibility = context->GetParameters().compatibilityProfile;
|
||||
|
||||
m_vaoUpdated = false;
|
||||
m_indexBuffer = nullptr;
|
||||
m_shader = nullptr;
|
||||
m_stencilCompare = nzRendererComparison_Always;
|
||||
@@ -353,6 +363,7 @@ bool NzRenderer::Initialize()
|
||||
m_stencilReference = 0;
|
||||
m_stencilZFail = nzStencilOperation_Keep;
|
||||
m_target = nullptr;
|
||||
m_vaoUpdated = false;
|
||||
m_vertexBuffer = nullptr;
|
||||
m_vertexDeclaration = nullptr;
|
||||
|
||||
@@ -362,7 +373,7 @@ bool NzRenderer::Initialize()
|
||||
m_capabilities[nzRendererCap_HardwareBuffer] = true; // Natif depuis OpenGL 1.5
|
||||
m_capabilities[nzRendererCap_MultipleRenderTargets] = true; // Natif depuis OpenGL 2.0
|
||||
m_capabilities[nzRendererCap_OcclusionQuery] = true; // Natif depuis OpenGL 1.5
|
||||
m_capabilities[nzRendererCap_SoftwareBuffer] = compatibility || NzOpenGL::GetVersion() <= 300; // Déprécié en OpenGL 3
|
||||
m_capabilities[nzRendererCap_PixelBufferObject] = NzOpenGL::IsSupported(NzOpenGL::PixelBufferObject);
|
||||
m_capabilities[nzRendererCap_Texture3D] = NzOpenGL::IsSupported(NzOpenGL::Texture3D);
|
||||
m_capabilities[nzRendererCap_TextureCubemap] = true; // Natif depuis OpenGL 1.3
|
||||
m_capabilities[nzRendererCap_TextureMulti] = true; // Natif depuis OpenGL 1.3
|
||||
@@ -393,11 +404,17 @@ bool NzRenderer::Initialize()
|
||||
GLint maxTextureUnits;
|
||||
glGetIntegerv(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, &maxTextureUnits);
|
||||
|
||||
m_maxTextureUnit = static_cast<unsigned int>(maxTextureUnits);
|
||||
GLint maxVertexAttribs;
|
||||
glGetIntegerv(GL_MAX_VERTEX_ATTRIBS, &maxVertexAttribs);
|
||||
|
||||
// Impossible de binder plus de texcoords que d'attributes (en sachant qu'un certain nombre est déjà pris par les autres attributs)
|
||||
m_maxTextureUnit = static_cast<unsigned int>(std::min(maxTextureUnits, maxVertexAttribs-attribIndex[nzElementUsage_TexCoord]));
|
||||
}
|
||||
else
|
||||
m_maxTextureUnit = 1;
|
||||
|
||||
NzBuffer::SetBufferFunction(nzBufferStorage_Hardware, HardwareBufferFunction);
|
||||
|
||||
s_initialized = true;
|
||||
|
||||
return true;
|
||||
@@ -497,9 +514,16 @@ void NzRenderer::SetFaceFilling(nzFaceFilling fillingMode)
|
||||
glPolygonMode(GL_FRONT_AND_BACK, faceFillingMode[fillingMode]);
|
||||
}
|
||||
|
||||
|
||||
bool NzRenderer::SetIndexBuffer(const NzIndexBuffer* indexBuffer)
|
||||
{
|
||||
#if NAZARA_RENDERER_SAFE
|
||||
if (indexBuffer && !indexBuffer->IsHardware() && !indexBuffer->IsSequential())
|
||||
{
|
||||
NazaraError("Buffer must be hardware");
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (indexBuffer != m_indexBuffer)
|
||||
{
|
||||
m_indexBuffer = indexBuffer;
|
||||
@@ -537,8 +561,6 @@ bool NzRenderer::SetShader(NzShader* shader)
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else
|
||||
m_shader = nullptr;
|
||||
|
||||
m_shader = shader;
|
||||
|
||||
@@ -635,6 +657,14 @@ bool NzRenderer::SetTarget(NzRenderTarget* target)
|
||||
|
||||
bool NzRenderer::SetVertexBuffer(const NzVertexBuffer* vertexBuffer)
|
||||
{
|
||||
#if NAZARA_RENDERER_SAFE
|
||||
if (vertexBuffer && !vertexBuffer->IsHardware())
|
||||
{
|
||||
NazaraError("Buffer must be hardware");
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (m_vertexBuffer != vertexBuffer)
|
||||
{
|
||||
m_vertexBuffer = vertexBuffer;
|
||||
@@ -675,13 +705,7 @@ void NzRenderer::SetViewport(const NzRectui& viewport)
|
||||
}
|
||||
|
||||
unsigned int width = m_target->GetWidth();
|
||||
if (viewport.x+viewport.width >= width)
|
||||
{
|
||||
NazaraError("Rectangle dimensions are out of bounds");
|
||||
return;
|
||||
}
|
||||
|
||||
if (viewport.y+viewport.height >= height)
|
||||
if (viewport.x+viewport.width > width || viewport.y+viewport.height > height)
|
||||
{
|
||||
NazaraError("Rectangle dimensions are out of bounds");
|
||||
return;
|
||||
@@ -812,31 +836,35 @@ bool NzRenderer::EnsureStateUpdate()
|
||||
|
||||
if (update)
|
||||
{
|
||||
m_vertexBuffer->GetBuffer()->GetImpl()->Bind();
|
||||
NzHardwareBuffer* vertexBuffer = static_cast<NzHardwareBuffer*>(m_vertexBuffer->GetBuffer()->GetImpl());
|
||||
vertexBuffer->Bind();
|
||||
|
||||
const nzUInt8* buffer = reinterpret_cast<const nzUInt8*>(m_vertexBuffer->GetBufferPtr());
|
||||
const nzUInt8* buffer = reinterpret_cast<const nzUInt8*>(m_vertexBuffer->GetPointer());
|
||||
|
||||
///FIXME: Améliorer les déclarations pour permettre de faire ça plus simplement
|
||||
for (int i = 0; i < 12; ++i) // Solution temporaire, à virer
|
||||
glDisableVertexAttribArray(i); // Chaque itération tue un chaton :(
|
||||
|
||||
unsigned int stride = m_vertexDeclaration->GetStride();
|
||||
unsigned int elementCount = m_vertexDeclaration->GetElementCount();
|
||||
for (unsigned int i = 0; i < elementCount; ++i)
|
||||
unsigned int stride = m_vertexDeclaration->GetStride(nzElementStream_VertexData);
|
||||
for (unsigned int i = 0; i <= nzElementUsage_Max; ++i)
|
||||
{
|
||||
const NzVertexDeclaration::Element* element = m_vertexDeclaration->GetElement(i);
|
||||
const NzVertexElement* element = m_vertexDeclaration->GetElement(nzElementStream_VertexData, static_cast<nzElementUsage>(i));
|
||||
|
||||
glEnableVertexAttribArray(attribIndex[element->usage]+element->usageIndex);
|
||||
glVertexAttribPointer(attribIndex[element->usage]+element->usageIndex,
|
||||
openglSize[element->type],
|
||||
openglType[element->type],
|
||||
(element->type == nzElementType_Color) ? GL_TRUE : GL_FALSE,
|
||||
stride,
|
||||
&buffer[element->offset]);
|
||||
if (element)
|
||||
{
|
||||
glEnableVertexAttribArray(attribIndex[i]);
|
||||
glVertexAttribPointer(attribIndex[i],
|
||||
openglSize[element->type],
|
||||
openglType[element->type],
|
||||
(element->type == nzElementType_Color) ? GL_TRUE : GL_FALSE,
|
||||
stride,
|
||||
&buffer[element->offset]);
|
||||
}
|
||||
else
|
||||
glDisableVertexAttribArray(attribIndex[i]);
|
||||
}
|
||||
|
||||
if (m_indexBuffer)
|
||||
m_indexBuffer->GetBuffer()->GetImpl()->Bind();
|
||||
{
|
||||
NzHardwareBuffer* indexBuffer = static_cast<NzHardwareBuffer*>(m_indexBuffer->GetBuffer()->GetImpl());
|
||||
indexBuffer->Bind();
|
||||
}
|
||||
}
|
||||
|
||||
if (vaoSupported)
|
||||
|
||||
@@ -124,7 +124,6 @@ namespace
|
||||
return true;
|
||||
|
||||
case nzPixelFormat_Undefined:
|
||||
case nzPixelFormat_Count:
|
||||
NazaraInternalError("Invalid pixel format");
|
||||
return false;
|
||||
}
|
||||
@@ -252,8 +251,8 @@ namespace
|
||||
return true;
|
||||
}
|
||||
|
||||
static unsigned short lockedLevel[nzImageType_Count] = {0};
|
||||
static GLuint lockedPrevious[nzImageType_Count] = {0};
|
||||
static unsigned short lockedLevel[nzImageType_Max+1] = {0};
|
||||
static GLuint lockedPrevious[nzImageType_Max+1] = {0};
|
||||
|
||||
void LockTexture(NzTextureImpl* impl)
|
||||
{
|
||||
@@ -342,7 +341,7 @@ bool NzTexture::Bind() const
|
||||
|
||||
glBindTexture(openglTarget[m_impl->type], m_impl->id);
|
||||
|
||||
if (!m_impl->mipmapsUpdated)
|
||||
if (m_impl->mipmapping && !m_impl->mipmapsUpdated)
|
||||
{
|
||||
glGenerateMipmap(openglTarget[m_impl->type]);
|
||||
m_impl->mipmapsUpdated = true;
|
||||
@@ -434,7 +433,13 @@ bool NzTexture::Create(nzImageType type, nzPixelFormat format, unsigned int widt
|
||||
|
||||
NzContext::EnsureContext();
|
||||
|
||||
levelCount = std::min(levelCount, NzImage::GetMaxLevel(width, height, depth));
|
||||
if (IsMipmappingSupported())
|
||||
levelCount = std::min(levelCount, NzImage::GetMaxLevel(width, height, depth));
|
||||
else if (levelCount > 1)
|
||||
{
|
||||
NazaraWarning("Mipmapping not supported, reducing level count to 1");
|
||||
levelCount = 1;
|
||||
}
|
||||
|
||||
NzTextureImpl* impl = new NzTextureImpl;
|
||||
glGenTextures(1, &impl->id);
|
||||
@@ -478,10 +483,7 @@ bool NzTexture::Create(nzImageType type, nzPixelFormat format, unsigned int widt
|
||||
SetWrapMode(nzTextureWrap_Repeat);
|
||||
|
||||
if (m_impl->levelCount > 1U)
|
||||
{
|
||||
m_impl->mipmapping = true;
|
||||
m_impl->mipmapsUpdated = false;
|
||||
}
|
||||
EnableMipmapping(true);
|
||||
|
||||
if (!lock)
|
||||
UnlockTexture(impl);
|
||||
@@ -578,25 +580,17 @@ bool NzTexture::EnableMipmapping(bool enable)
|
||||
}
|
||||
#endif
|
||||
|
||||
if (!glGenerateMipmap)
|
||||
if (m_impl->levelCount == 1)
|
||||
return true;
|
||||
|
||||
if (!IsMipmappingSupported())
|
||||
{
|
||||
NazaraError("Mipmapping not supported");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!m_impl->mipmapping && enable)
|
||||
{
|
||||
GLint tex;
|
||||
glGetIntegerv(openglTargetBinding[m_impl->type], &tex);
|
||||
|
||||
if (m_impl->id == static_cast<GLuint>(tex))
|
||||
{
|
||||
glGenerateMipmap(openglTarget[m_impl->type]);
|
||||
m_impl->mipmapsUpdated = true;
|
||||
}
|
||||
else
|
||||
m_impl->mipmapsUpdated = false;
|
||||
}
|
||||
m_impl->mipmapsUpdated = false;
|
||||
|
||||
m_impl->mipmapping = enable;
|
||||
|
||||
@@ -849,7 +843,6 @@ bool NzTexture::LoadFromImage(const NzImage& image)
|
||||
if (!IsFormatSupported(format))
|
||||
{
|
||||
nzPixelFormat newFormat = (NzPixelFormat::HasAlpha(format)) ? nzPixelFormat_BGRA8 : nzPixelFormat_BGR8;
|
||||
|
||||
NazaraWarning("Format not supported, trying to convert it to " + NzPixelFormat::ToString(newFormat) + "...");
|
||||
|
||||
if (NzPixelFormat::IsConversionSupported(format, newFormat))
|
||||
@@ -873,14 +866,13 @@ bool NzTexture::LoadFromImage(const NzImage& image)
|
||||
}
|
||||
|
||||
nzImageType type = newImage.GetType();
|
||||
nzUInt8 levelCount = newImage.GetLevelCount();
|
||||
if (!Create(type, format, newImage.GetWidth(), newImage.GetHeight(), newImage.GetDepth(), levelCount, true))
|
||||
if (!Create(type, format, newImage.GetWidth(), newImage.GetHeight(), newImage.GetDepth(), newImage.GetLevelCount(), true))
|
||||
{
|
||||
NazaraError("Failed to create texture");
|
||||
return false;
|
||||
}
|
||||
|
||||
for (nzUInt8 level = 0; level < levelCount; ++level)
|
||||
for (nzUInt8 level = 0; level < m_impl->levelCount; ++level)
|
||||
{
|
||||
if (!Update(newImage.GetConstPixels(level), level))
|
||||
{
|
||||
@@ -943,13 +935,13 @@ bool NzTexture::SetAnisotropyLevel(unsigned int anistropyLevel)
|
||||
NazaraError("Texture must be valid");
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (!NzOpenGL::IsSupported(NzOpenGL::AnisotropicFilter))
|
||||
{
|
||||
NazaraError("Anisotropic filter not supported");
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
LockTexture(m_impl);
|
||||
|
||||
@@ -982,7 +974,7 @@ bool NzTexture::SetFilterMode(nzTextureFilter filter)
|
||||
switch (filter)
|
||||
{
|
||||
case nzTextureFilter_Bilinear:
|
||||
if (m_impl->levelCount > 1)
|
||||
if (m_impl->mipmapping > 1)
|
||||
glTexParameteri(target, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST);
|
||||
else
|
||||
glTexParameteri(target, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
@@ -991,7 +983,7 @@ bool NzTexture::SetFilterMode(nzTextureFilter filter)
|
||||
break;
|
||||
|
||||
case nzTextureFilter_Nearest:
|
||||
if (m_impl->levelCount > 1)
|
||||
if (m_impl->mipmapping > 1)
|
||||
glTexParameteri(target, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST);
|
||||
else
|
||||
glTexParameteri(target, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||
@@ -1354,12 +1346,13 @@ bool NzTexture::Update(const nzUInt8* pixels, const NzCubeui& cube, nzUInt8 leve
|
||||
nzUInt8 bpp = NzPixelFormat::GetBPP(m_impl->format);
|
||||
|
||||
// Inversion de la texture pour le repère d'OpenGL
|
||||
NzImage mirrored;
|
||||
mirrored.Create(m_impl->type, m_impl->format, cube.width, cube.height, cube.depth);
|
||||
mirrored.Update(pixels);
|
||||
|
||||
if (!mirrored.FlipVertically())
|
||||
unsigned int size = cube.width*cube.height*cube.depth*bpp;
|
||||
nzUInt8* mirrored = new nzUInt8[size];
|
||||
if (!NzPixelFormat::Flip(nzPixelFlipping_Vertically, m_impl->format, cube.width, cube.height, cube.depth, pixels, mirrored))
|
||||
{
|
||||
NazaraWarning("Failed to flip image");
|
||||
std::memcpy(mirrored, pixels, size);
|
||||
}
|
||||
|
||||
SetUnpackAlignement(bpp);
|
||||
|
||||
@@ -1367,15 +1360,15 @@ bool NzTexture::Update(const nzUInt8* pixels, const NzCubeui& cube, nzUInt8 leve
|
||||
switch (m_impl->type)
|
||||
{
|
||||
case nzImageType_1D:
|
||||
glTexSubImage1D(GL_TEXTURE_1D, level, cube.x, cube.width, format.dataFormat, format.dataType, mirrored.GetConstPixels());
|
||||
glTexSubImage1D(GL_TEXTURE_1D, level, cube.x, cube.width, format.dataFormat, format.dataType, mirrored);
|
||||
break;
|
||||
|
||||
case nzImageType_2D:
|
||||
glTexSubImage2D(GL_TEXTURE_2D, level, cube.x, height-cube.height-cube.y, cube.width, cube.height, format.dataFormat, format.dataType, mirrored.GetConstPixels());
|
||||
glTexSubImage2D(GL_TEXTURE_2D, level, cube.x, height-cube.height-cube.y, cube.width, cube.height, format.dataFormat, format.dataType, mirrored);
|
||||
break;
|
||||
|
||||
case nzImageType_3D:
|
||||
glTexSubImage3D(GL_TEXTURE_3D, level, cube.x, height-cube.height-cube.y, cube.z, cube.width, cube.height, cube.depth, format.dataFormat, format.dataType, mirrored.GetConstPixels());
|
||||
glTexSubImage3D(GL_TEXTURE_3D, level, cube.x, height-cube.height-cube.y, cube.z, cube.width, cube.height, cube.depth, format.dataFormat, format.dataType, mirrored);
|
||||
break;
|
||||
|
||||
default:
|
||||
@@ -1383,6 +1376,8 @@ bool NzTexture::Update(const nzUInt8* pixels, const NzCubeui& cube, nzUInt8 leve
|
||||
}
|
||||
UnlockTexture(m_impl);
|
||||
|
||||
delete[] mirrored;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -1503,19 +1498,21 @@ bool NzTexture::UpdateFace(nzCubemapFace face, const nzUInt8* pixels, const NzRe
|
||||
nzUInt8 bpp = NzPixelFormat::GetBPP(m_impl->format);
|
||||
|
||||
// Inversion de la texture pour le repère d'OpenGL
|
||||
NzImage mirrored;
|
||||
mirrored.Create(m_impl->type, m_impl->format, rect.width, rect.height);
|
||||
mirrored.Update(pixels);
|
||||
|
||||
if (!mirrored.FlipVertically())
|
||||
unsigned int size = rect.width*rect.height*bpp;
|
||||
nzUInt8* mirrored = new nzUInt8[size];
|
||||
if (!NzPixelFormat::Flip(nzPixelFlipping_Vertically, m_impl->format, rect.width, rect.height, 1, pixels, mirrored))
|
||||
{
|
||||
NazaraWarning("Failed to flip image");
|
||||
std::memcpy(mirrored, pixels, size);
|
||||
}
|
||||
|
||||
SetUnpackAlignement(bpp);
|
||||
|
||||
LockTexture(m_impl);
|
||||
glTexSubImage2D(cubemapFace[face], level, rect.x, height-rect.height-rect.y, rect.width, rect.height, format.dataFormat, format.dataType, mirrored.GetConstPixels());
|
||||
glTexSubImage2D(cubemapFace[face], level, rect.x, height-rect.height-rect.y, rect.width, rect.height, format.dataFormat, format.dataType, mirrored);
|
||||
UnlockTexture(m_impl);
|
||||
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -1576,7 +1573,6 @@ bool NzTexture::IsFormatSupported(nzPixelFormat format)
|
||||
}
|
||||
|
||||
case nzPixelFormat_Undefined:
|
||||
case nzPixelFormat_Count:
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -1585,6 +1581,11 @@ bool NzTexture::IsFormatSupported(nzPixelFormat format)
|
||||
return false;
|
||||
}
|
||||
|
||||
bool NzTexture::IsMipmappingSupported()
|
||||
{
|
||||
return glGenerateMipmap != nullptr;
|
||||
}
|
||||
|
||||
bool NzTexture::IsTypeSupported(nzImageType type)
|
||||
{
|
||||
switch (type)
|
||||
|
||||
@@ -1,127 +0,0 @@
|
||||
// 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/Renderer/VertexDeclaration.hpp>
|
||||
#include <Nazara/Core/Error.hpp>
|
||||
#include <Nazara/Renderer/Config.hpp>
|
||||
#include <Nazara/Renderer/Renderer.hpp>
|
||||
#include <Nazara/Renderer/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_RENDERER_SAFE
|
||||
else // Seulement si le stream ne vient pas d'être créé (Autrement c'est inutile)
|
||||
{
|
||||
bool fp64 = NazaraRenderer->HasCapability(nzRendererCap_FP64);
|
||||
|
||||
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;
|
||||
}
|
||||
else if (!fp64 && elements[j].type >= nzElementType_Double1 && elements[j].type <= nzElementType_Double4)
|
||||
{
|
||||
NazaraError("FP64 not supported");
|
||||
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_RENDERER_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_RENDERER_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_RENDERER_SAFE
|
||||
if (stream >= m_streams.size())
|
||||
{
|
||||
NazaraError("Stream out of range");
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
return m_streams[stream].stride;
|
||||
}
|
||||
318
src/Nazara/Utility/Animation.cpp
Normal file
318
src/Nazara/Utility/Animation.cpp
Normal file
@@ -0,0 +1,318 @@
|
||||
// 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/Animation.hpp>
|
||||
#include <Nazara/Core/Error.hpp>
|
||||
#include <Nazara/Utility/Config.hpp>
|
||||
#include <vector>
|
||||
#include <Nazara/Utility/Debug.hpp>
|
||||
|
||||
struct NzAnimationImpl
|
||||
{
|
||||
std::map<NzString, unsigned int> sequenceMap;
|
||||
std::vector<NzSequence> sequences;
|
||||
nzAnimationType type;
|
||||
unsigned int frameCount;
|
||||
};
|
||||
|
||||
bool NzAnimationParams::IsValid() const
|
||||
{
|
||||
if (startFrame > endFrame)
|
||||
{
|
||||
NazaraError("Start frame must be lower than end frame");
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
NzAnimation::~NzAnimation()
|
||||
{
|
||||
Destroy();
|
||||
}
|
||||
|
||||
unsigned int NzAnimation::AddSequence(const NzSequence& sequence)
|
||||
{
|
||||
#if NAZARA_UTILITY_SAFE
|
||||
if (!m_impl)
|
||||
{
|
||||
NazaraError("Animation not created");
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
unsigned int index = m_impl->sequences.size();
|
||||
|
||||
if (!sequence.name.IsEmpty())
|
||||
{
|
||||
#if NAZARA_UTILITY_SAFE
|
||||
auto it = m_impl->sequenceMap.find(sequence.name);
|
||||
if (it != m_impl->sequenceMap.end())
|
||||
{
|
||||
NazaraError("Sequence name \"" + sequence.name + "\" is already used");
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
m_impl->sequenceMap[sequence.name] = index;
|
||||
}
|
||||
|
||||
m_impl->sequences.push_back(sequence);
|
||||
|
||||
return index;
|
||||
}
|
||||
|
||||
bool NzAnimation::Create(nzAnimationType type, unsigned int frameCount)
|
||||
{
|
||||
Destroy();
|
||||
|
||||
#if NAZARA_UTILITY_SAFE
|
||||
if (type == nzAnimationType_Static)
|
||||
{
|
||||
NazaraError("Invalid type");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (frameCount == 0)
|
||||
{
|
||||
NazaraError("Frame count must be over zero");
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
m_impl = new NzAnimationImpl;
|
||||
m_impl->frameCount = frameCount;
|
||||
m_impl->type = type;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void NzAnimation::Destroy()
|
||||
{
|
||||
if (m_impl)
|
||||
{
|
||||
delete m_impl;
|
||||
m_impl = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
unsigned int NzAnimation::GetFrameCount() const
|
||||
{
|
||||
#if NAZARA_UTILITY_SAFE
|
||||
if (!m_impl)
|
||||
{
|
||||
NazaraError("Animation not created");
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
return m_impl->frameCount;
|
||||
}
|
||||
|
||||
NzSequence* NzAnimation::GetSequence(const NzString& sequenceName)
|
||||
{
|
||||
#if NAZARA_UTILITY_SAFE
|
||||
if (!m_impl)
|
||||
{
|
||||
NazaraError("Animation not created");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
auto it = m_impl->sequenceMap.find(sequenceName);
|
||||
if (it == m_impl->sequenceMap.end())
|
||||
{
|
||||
NazaraError("Sequence not found");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return &m_impl->sequences[it->second];
|
||||
#else
|
||||
return &m_impl->sequences[m_impl->sequenceMap[sequenceName]];
|
||||
#endif
|
||||
}
|
||||
|
||||
NzSequence* NzAnimation::GetSequence(unsigned int index)
|
||||
{
|
||||
#if NAZARA_UTILITY_SAFE
|
||||
if (!m_impl)
|
||||
{
|
||||
NazaraError("Animation not created");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (index >= m_impl->sequences.size())
|
||||
{
|
||||
NazaraError("Sequence index out of range (" + NzString::Number(index) + " >= " + NzString::Number(m_impl->sequences.size()) + ')');
|
||||
return nullptr;
|
||||
}
|
||||
#endif
|
||||
|
||||
return &m_impl->sequences[index];
|
||||
}
|
||||
|
||||
const NzSequence* NzAnimation::GetSequence(const NzString& sequenceName) const
|
||||
{
|
||||
#if NAZARA_UTILITY_SAFE
|
||||
if (!m_impl)
|
||||
{
|
||||
NazaraError("Animation not created");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
auto it = m_impl->sequenceMap.find(sequenceName);
|
||||
if (it == m_impl->sequenceMap.end())
|
||||
{
|
||||
NazaraError("Sequence not found");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return &m_impl->sequences[it->second];
|
||||
#else
|
||||
return &m_impl->sequences[m_impl->sequenceMap[sequenceName]];
|
||||
#endif
|
||||
}
|
||||
|
||||
const NzSequence* NzAnimation::GetSequence(unsigned int index) const
|
||||
{
|
||||
#if NAZARA_UTILITY_SAFE
|
||||
if (!m_impl)
|
||||
{
|
||||
NazaraError("Animation not created");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (index >= m_impl->sequences.size())
|
||||
{
|
||||
NazaraError("Sequence index out of range (" + NzString::Number(index) + " >= " + NzString::Number(m_impl->sequences.size()) + ')');
|
||||
return nullptr;
|
||||
}
|
||||
#endif
|
||||
|
||||
return &m_impl->sequences[index];
|
||||
}
|
||||
|
||||
unsigned int NzAnimation::GetSequenceCount() const
|
||||
{
|
||||
#if NAZARA_UTILITY_SAFE
|
||||
if (!m_impl)
|
||||
{
|
||||
NazaraError("Animation not created");
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
return m_impl->sequences.size();
|
||||
}
|
||||
|
||||
nzAnimationType NzAnimation::GetType() const
|
||||
{
|
||||
#if NAZARA_UTILITY_SAFE
|
||||
if (!m_impl)
|
||||
{
|
||||
NazaraError("Animation not created");
|
||||
return nzAnimationType_Static; // Ce qui est une valeur invalide pour NzAnimation
|
||||
}
|
||||
#endif
|
||||
|
||||
return m_impl->type;
|
||||
}
|
||||
|
||||
bool NzAnimation::HasSequence(const NzString& sequenceName) const
|
||||
{
|
||||
#if NAZARA_UTILITY_SAFE
|
||||
if (!m_impl)
|
||||
{
|
||||
NazaraError("Animation not created");
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
return m_impl->sequenceMap.find(sequenceName) != m_impl->sequenceMap.end();
|
||||
}
|
||||
|
||||
bool NzAnimation::HasSequence(unsigned int index) const
|
||||
{
|
||||
#if NAZARA_UTILITY_SAFE
|
||||
if (!m_impl)
|
||||
{
|
||||
NazaraError("Animation not created");
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
return index >= m_impl->sequences.size();
|
||||
}
|
||||
|
||||
bool NzAnimation::IsValid() const
|
||||
{
|
||||
return m_impl != nullptr;
|
||||
}
|
||||
|
||||
bool NzAnimation::LoadFromFile(const NzString& filePath, const NzAnimationParams& params)
|
||||
{
|
||||
return NzAnimationLoader::LoadFromFile(this, filePath, params);
|
||||
}
|
||||
|
||||
bool NzAnimation::LoadFromMemory(const void* data, std::size_t size, const NzAnimationParams& params)
|
||||
{
|
||||
return NzAnimationLoader::LoadFromMemory(this, data, size, params);
|
||||
}
|
||||
|
||||
bool NzAnimation::LoadFromStream(NzInputStream& stream, const NzAnimationParams& params)
|
||||
{
|
||||
return NzAnimationLoader::LoadFromStream(this, stream, params);
|
||||
}
|
||||
|
||||
void NzAnimation::RemoveSequence(const NzString& identifier)
|
||||
{
|
||||
#if NAZARA_UTILITY_SAFE
|
||||
if (!m_impl)
|
||||
{
|
||||
NazaraError("Animation not created");
|
||||
return;
|
||||
}
|
||||
|
||||
auto it = m_impl->sequenceMap.find(identifier);
|
||||
if (it == m_impl->sequenceMap.end())
|
||||
{
|
||||
NazaraError("SubMesh not found");
|
||||
return;
|
||||
}
|
||||
|
||||
unsigned int index = it->second;
|
||||
#else
|
||||
unsigned int index = m_impl->sequenceMap[identifier];
|
||||
#endif
|
||||
|
||||
auto it2 = m_impl->sequences.begin();
|
||||
std::advance(it2, index);
|
||||
|
||||
m_impl->sequences.erase(it2);
|
||||
}
|
||||
|
||||
void NzAnimation::RemoveSequence(unsigned int index)
|
||||
{
|
||||
#if NAZARA_UTILITY_SAFE
|
||||
if (!m_impl)
|
||||
{
|
||||
NazaraError("Animation not created");
|
||||
return;
|
||||
}
|
||||
|
||||
if (index >= m_impl->sequences.size())
|
||||
{
|
||||
NazaraError("Sequence index out of range (" + NzString::Number(index) + " >= " + NzString::Number(m_impl->sequences.size()) + ')');
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
auto it = m_impl->sequences.begin();
|
||||
std::advance(it, index);
|
||||
|
||||
m_impl->sequences.erase(it);
|
||||
}
|
||||
|
||||
std::list<NzAnimationLoader::MemoryLoader> NzAnimation::s_memoryLoaders;
|
||||
std::list<NzAnimationLoader::StreamLoader> NzAnimation::s_streamLoaders;
|
||||
std::multimap<NzString, NzAnimationLoader::LoadFileFunction> NzAnimation::s_fileLoaders;
|
||||
336
src/Nazara/Utility/Buffer.cpp
Normal file
336
src/Nazara/Utility/Buffer.cpp
Normal file
@@ -0,0 +1,336 @@
|
||||
// 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_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};
|
||||
@@ -2,7 +2,7 @@
|
||||
// This file is part of the "Nazara Engine".
|
||||
// For conditions of distribution and use, see copyright notice in Config.hpp
|
||||
|
||||
#include <Nazara/Renderer/BufferImpl.hpp>
|
||||
#include <Nazara/Renderer/Debug.hpp>
|
||||
#include <Nazara/Utility/BufferImpl.hpp>
|
||||
#include <Nazara/Utility/Debug.hpp>
|
||||
|
||||
NzBufferImpl::~NzBufferImpl() = default;
|
||||
61
src/Nazara/Utility/Cursor.cpp
Normal file
61
src/Nazara/Utility/Cursor.cpp
Normal file
@@ -0,0 +1,61 @@
|
||||
// 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/Cursor.hpp>
|
||||
|
||||
#if defined(NAZARA_PLATFORM_WINDOWS)
|
||||
#include <Nazara/Utility/Win32/CursorImpl.hpp>
|
||||
#elif defined(NAZARA_PLATFORM_LINUX)
|
||||
#include <Nazara/Utility/Linux/CursorImpl.hpp>
|
||||
#else
|
||||
#error Lack of implementation: Cursor
|
||||
#endif
|
||||
|
||||
#include <Nazara/Utility/Debug.hpp>
|
||||
|
||||
NzCursor::NzCursor() :
|
||||
m_impl(nullptr)
|
||||
{
|
||||
}
|
||||
|
||||
NzCursor::~NzCursor()
|
||||
{
|
||||
Destroy();
|
||||
}
|
||||
|
||||
bool NzCursor::Create(const NzImage& cursor, int hotSpotX, int hotSpotY)
|
||||
{
|
||||
Destroy();
|
||||
|
||||
m_impl = new NzCursorImpl;
|
||||
if (!m_impl->Create(cursor, hotSpotX, hotSpotY))
|
||||
{
|
||||
NazaraError("Failed to create cursor implementation");
|
||||
delete m_impl;
|
||||
m_impl = nullptr;
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool NzCursor::Create(const NzImage& cursor, const NzVector2i& hotSpot)
|
||||
{
|
||||
return Create(cursor, hotSpot.x, hotSpot.y);
|
||||
}
|
||||
|
||||
void NzCursor::Destroy()
|
||||
{
|
||||
if (m_impl)
|
||||
{
|
||||
m_impl->Destroy();
|
||||
delete m_impl;
|
||||
m_impl = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
bool NzCursor::IsValid() const
|
||||
{
|
||||
return m_impl != nullptr;
|
||||
}
|
||||
56
src/Nazara/Utility/Icon.cpp
Normal file
56
src/Nazara/Utility/Icon.cpp
Normal file
@@ -0,0 +1,56 @@
|
||||
// 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/Icon.hpp>
|
||||
|
||||
#if defined(NAZARA_PLATFORM_WINDOWS)
|
||||
#include <Nazara/Utility/Win32/IconImpl.hpp>
|
||||
#elif defined(NAZARA_PLATFORM_LINUX)
|
||||
#include <Nazara/Utility/Linux/IconImpl.hpp>
|
||||
#else
|
||||
#error Lack of implementation: Icon
|
||||
#endif
|
||||
|
||||
#include <Nazara/Utility/Debug.hpp>
|
||||
|
||||
NzIcon::NzIcon() :
|
||||
m_impl(nullptr)
|
||||
{
|
||||
}
|
||||
|
||||
NzIcon::~NzIcon()
|
||||
{
|
||||
Destroy();
|
||||
}
|
||||
|
||||
bool NzIcon::Create(const NzImage& icon)
|
||||
{
|
||||
Destroy();
|
||||
|
||||
m_impl = new NzIconImpl;
|
||||
if (!m_impl->Create(icon))
|
||||
{
|
||||
NazaraError("Failed to create icon implementation");
|
||||
delete m_impl;
|
||||
m_impl = nullptr;
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void NzIcon::Destroy()
|
||||
{
|
||||
if (m_impl)
|
||||
{
|
||||
m_impl->Destroy();
|
||||
delete m_impl;
|
||||
m_impl = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
bool NzIcon::IsValid() const
|
||||
{
|
||||
return m_impl != nullptr;
|
||||
}
|
||||
@@ -5,7 +5,6 @@
|
||||
#include <Nazara/Utility/Image.hpp>
|
||||
#include <Nazara/Core/Error.hpp>
|
||||
#include <Nazara/Utility/Config.hpp>
|
||||
#include <Nazara/Utility/ResourceLoader.hpp>
|
||||
#include <cmath>
|
||||
#include <Nazara/Utility/Debug.hpp>
|
||||
|
||||
@@ -22,6 +21,11 @@ namespace
|
||||
}
|
||||
}
|
||||
|
||||
bool NzImageParams::IsValid() const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
NzImage::NzImage() :
|
||||
m_sharedImage(&emptyImage)
|
||||
{
|
||||
@@ -494,24 +498,12 @@ bool NzImage::FlipHorizontally()
|
||||
|
||||
EnsureOwnership();
|
||||
|
||||
nzUInt8 bpp = NzPixelFormat::GetBPP(m_sharedImage->format);
|
||||
unsigned int width = m_sharedImage->width;
|
||||
unsigned int height = m_sharedImage->height;
|
||||
unsigned int depth = (m_sharedImage->type == nzImageType_Cubemap) ? 6 : m_sharedImage->depth;
|
||||
for (unsigned int level = 0; level < m_sharedImage->levelCount; ++level)
|
||||
{
|
||||
for (unsigned int z = 0; z < depth; ++z)
|
||||
{
|
||||
nzUInt8* ptr = &m_sharedImage->pixels[level][width*height*z];
|
||||
unsigned int lineStride = width*bpp;
|
||||
for (unsigned int y = 0; y < height; ++y)
|
||||
{
|
||||
for (unsigned int x = 0; x < width/2; ++x)
|
||||
std::swap_ranges(&ptr[x*bpp], &ptr[(x+1)*bpp], &ptr[(width-x)*bpp]);
|
||||
|
||||
ptr += lineStride;
|
||||
}
|
||||
}
|
||||
NzPixelFormat::Flip(nzPixelFlipping_Horizontally, m_sharedImage->format, width, height, depth, m_sharedImage->pixels[level], m_sharedImage->pixels[level]);
|
||||
|
||||
if (width > 1U)
|
||||
width >>= 1;
|
||||
@@ -545,19 +537,12 @@ bool NzImage::FlipVertically()
|
||||
|
||||
EnsureOwnership();
|
||||
|
||||
nzUInt8 bpp = NzPixelFormat::GetBPP(m_sharedImage->format);
|
||||
unsigned int width = m_sharedImage->width;
|
||||
unsigned int height = m_sharedImage->height;
|
||||
unsigned int depth = (m_sharedImage->type == nzImageType_Cubemap) ? 6 : m_sharedImage->depth;
|
||||
for (unsigned int level = 0; level < m_sharedImage->levelCount; ++level)
|
||||
{
|
||||
for (unsigned int z = 0; z < depth; ++z)
|
||||
{
|
||||
nzUInt8* ptr = &m_sharedImage->pixels[level][width*height*z];
|
||||
unsigned int lineStride = width*bpp;
|
||||
for (unsigned int y = 0; y < height/2; ++y)
|
||||
std::swap_ranges(&ptr[y*lineStride], &ptr[(y+1)*lineStride-1], &ptr[(height-y-1)*lineStride]);
|
||||
}
|
||||
NzPixelFormat::Flip(nzPixelFlipping_Vertically, m_sharedImage->format, width, height, depth, m_sharedImage->pixels[level], m_sharedImage->pixels[level]);
|
||||
|
||||
if (width > 1U)
|
||||
width >>= 1;
|
||||
@@ -818,17 +803,17 @@ bool NzImage::IsValid() const
|
||||
|
||||
bool NzImage::LoadFromFile(const NzString& filePath, const NzImageParams& params)
|
||||
{
|
||||
return NzResourceLoader<NzImage, NzImageParams>::LoadResourceFromFile(this, filePath, params);
|
||||
return NzImageLoader::LoadFromFile(this, filePath, params);
|
||||
}
|
||||
|
||||
bool NzImage::LoadFromMemory(const void* data, std::size_t size, const NzImageParams& params)
|
||||
{
|
||||
return NzResourceLoader<NzImage, NzImageParams>::LoadResourceFromMemory(this, data, size, params);
|
||||
return NzImageLoader::LoadFromMemory(this, data, size, params);
|
||||
}
|
||||
|
||||
bool NzImage::LoadFromStream(NzInputStream& stream, const NzImageParams& params)
|
||||
{
|
||||
return NzResourceLoader<NzImage, NzImageParams>::LoadResourceFromStream(this, stream, params);
|
||||
return NzImageLoader::LoadFromStream(this, stream, params);
|
||||
}
|
||||
|
||||
bool NzImage::SetLevelCount(nzUInt8 levelCount)
|
||||
@@ -1110,36 +1095,6 @@ nzUInt8 NzImage::GetMaxLevel(unsigned int width, unsigned int height, unsigned i
|
||||
return std::max(std::max(std::max(widthLevel, heightLevel), depthLevel), 1U);
|
||||
}
|
||||
|
||||
void NzImage::RegisterFileLoader(const NzString& extensions, LoadFileFunction loadFile)
|
||||
{
|
||||
return RegisterResourceFileLoader(extensions, loadFile);
|
||||
}
|
||||
|
||||
void NzImage::RegisterMemoryLoader(IsMemoryLoadingSupportedFunction isLoadingSupported, LoadMemoryFunction loadMemory)
|
||||
{
|
||||
return RegisterResourceMemoryLoader(isLoadingSupported, loadMemory);
|
||||
}
|
||||
|
||||
void NzImage::RegisterStreamLoader(IsStreamLoadingSupportedFunction isLoadingSupported, LoadStreamFunction loadStream)
|
||||
{
|
||||
return RegisterResourceStreamLoader(isLoadingSupported, loadStream);
|
||||
}
|
||||
|
||||
void NzImage::UnregisterFileLoader(const NzString& extensions, LoadFileFunction loadFile)
|
||||
{
|
||||
UnregisterResourceFileLoader(extensions, loadFile);
|
||||
}
|
||||
|
||||
void NzImage::UnregisterMemoryLoader(IsMemoryLoadingSupportedFunction isLoadingSupported, LoadMemoryFunction loadMemory)
|
||||
{
|
||||
UnregisterResourceMemoryLoader(isLoadingSupported, loadMemory);
|
||||
}
|
||||
|
||||
void NzImage::UnregisterStreamLoader(IsStreamLoadingSupportedFunction isLoadingSupported, LoadStreamFunction loadStream)
|
||||
{
|
||||
UnregisterResourceStreamLoader(isLoadingSupported, loadStream);
|
||||
}
|
||||
|
||||
void NzImage::EnsureOwnership()
|
||||
{
|
||||
if (m_sharedImage == &emptyImage)
|
||||
@@ -1168,10 +1123,10 @@ void NzImage::ReleaseImage()
|
||||
return;
|
||||
|
||||
NazaraMutexLock(m_sharedImage->mutex);
|
||||
m_sharedImage->refCount--;
|
||||
bool freeSharedImage = (--m_sharedImage->refCount == 0);
|
||||
NazaraMutexUnlock(m_sharedImage->mutex);
|
||||
|
||||
if (m_sharedImage->refCount == 0)
|
||||
if (freeSharedImage)
|
||||
{
|
||||
for (unsigned int i = 0; i < m_sharedImage->levelCount; ++i)
|
||||
delete[] m_sharedImage->pixels[i];
|
||||
@@ -1184,3 +1139,6 @@ void NzImage::ReleaseImage()
|
||||
}
|
||||
|
||||
NzImage::SharedImage NzImage::emptyImage(0, nzImageType_2D, nzPixelFormat_Undefined, 1, nullptr, 0, 0, 0);
|
||||
std::list<NzImageLoader::MemoryLoader> NzImage::s_memoryLoaders;
|
||||
std::list<NzImageLoader::StreamLoader> NzImage::s_streamLoaders;
|
||||
std::multimap<NzString, NzImageLoader::LoadFileFunction> NzImage::s_fileLoaders;
|
||||
|
||||
@@ -2,11 +2,11 @@
|
||||
// This file is part of the "Nazara Engine".
|
||||
// For conditions of distribution and use, see copyright notice in Config.hpp
|
||||
|
||||
#include <Nazara/Renderer/IndexBuffer.hpp>
|
||||
#include <Nazara/Utility/IndexBuffer.hpp>
|
||||
#include <Nazara/Core/Error.hpp>
|
||||
#include <Nazara/Renderer/Config.hpp>
|
||||
#include <Nazara/Utility/Config.hpp>
|
||||
#include <stdexcept>
|
||||
#include <Nazara/Renderer/Debug.hpp>
|
||||
#include <Nazara/Utility/Debug.hpp>
|
||||
|
||||
NzIndexBuffer::NzIndexBuffer(NzBuffer* buffer, unsigned int startIndex, unsigned int indexCount) :
|
||||
m_buffer(buffer),
|
||||
@@ -31,7 +31,7 @@ m_startIndex(startIndex)
|
||||
}
|
||||
}
|
||||
|
||||
NzIndexBuffer::NzIndexBuffer(unsigned int length, nzUInt8 indexSize, nzBufferUsage usage) :
|
||||
NzIndexBuffer::NzIndexBuffer(unsigned int length, nzUInt8 indexSize, nzBufferStorage storage, nzBufferUsage usage) :
|
||||
m_ownsBuffer(true),
|
||||
m_indexCount(length),
|
||||
m_startIndex(0)
|
||||
@@ -46,13 +46,15 @@ m_startIndex(0)
|
||||
}
|
||||
#endif
|
||||
|
||||
m_buffer = new NzBuffer(nzBufferType_Index, length, indexSize, usage);
|
||||
m_buffer = new NzBuffer(nzBufferType_Index, length, indexSize, storage, usage);
|
||||
m_buffer->AddResourceReference();
|
||||
m_buffer->SetPersistent(false);
|
||||
}
|
||||
|
||||
NzIndexBuffer::NzIndexBuffer(const NzIndexBuffer& indexBuffer) :
|
||||
NzResource(true),
|
||||
m_buffer(indexBuffer.m_buffer),
|
||||
m_ownsBuffer(indexBuffer.m_ownsBuffer),
|
||||
m_indexCount(indexBuffer.m_indexCount),
|
||||
m_startIndex(indexBuffer.m_startIndex)
|
||||
{
|
||||
@@ -60,7 +62,9 @@ m_startIndex(indexBuffer.m_startIndex)
|
||||
{
|
||||
if (m_ownsBuffer)
|
||||
{
|
||||
m_buffer = new NzBuffer(nzBufferType_Index, indexBuffer.m_buffer->GetLength(), indexBuffer.m_buffer->GetSize(), indexBuffer.m_buffer->GetUsage());
|
||||
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);
|
||||
@@ -71,8 +75,6 @@ m_startIndex(indexBuffer.m_startIndex)
|
||||
m_buffer->AddResourceReference();
|
||||
}
|
||||
}
|
||||
else
|
||||
m_buffer = nullptr;
|
||||
}
|
||||
|
||||
NzIndexBuffer::~NzIndexBuffer()
|
||||
@@ -83,10 +85,10 @@ NzIndexBuffer::~NzIndexBuffer()
|
||||
|
||||
bool NzIndexBuffer::Fill(const void* data, unsigned int offset, unsigned int length)
|
||||
{
|
||||
#if NAZARA_RENDERER_SAFE
|
||||
#if NAZARA_UTILITY_SAFE
|
||||
if (!m_buffer)
|
||||
{
|
||||
NazaraError("Impossible to fill sequential buffer");
|
||||
NazaraError("Impossible to fill sequential buffers");
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -105,38 +107,12 @@ NzBuffer* NzIndexBuffer::GetBuffer() const
|
||||
return m_buffer;
|
||||
}
|
||||
|
||||
void* NzIndexBuffer::GetBufferPtr()
|
||||
{
|
||||
#if NAZARA_RENDERER_SAFE
|
||||
if (!m_buffer)
|
||||
{
|
||||
NazaraError("Sequential index buffer: Buffer has no pointer");
|
||||
return nullptr;
|
||||
}
|
||||
#endif
|
||||
|
||||
return reinterpret_cast<nzUInt8*>(m_buffer->GetBufferPtr()) + m_startIndex*m_buffer->GetTypeSize();
|
||||
}
|
||||
|
||||
const void* NzIndexBuffer::GetBufferPtr() const
|
||||
{
|
||||
#if NAZARA_RENDERER_SAFE
|
||||
if (!m_buffer)
|
||||
{
|
||||
NazaraError("Sequential index buffer: Buffer has no pointer");
|
||||
return nullptr;
|
||||
}
|
||||
#endif
|
||||
|
||||
return reinterpret_cast<const nzUInt8*>(m_buffer->GetBufferPtr()) + m_startIndex*m_buffer->GetTypeSize();
|
||||
}
|
||||
|
||||
nzUInt8 NzIndexBuffer::GetIndexSize() const
|
||||
{
|
||||
#if NAZARA_RENDERER_SAFE
|
||||
#if NAZARA_UTILITY_SAFE
|
||||
if (!m_buffer)
|
||||
{
|
||||
NazaraError("Sequential index buffer: Buffer has no index size");
|
||||
NazaraError("Sequential buffers have no index size");
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
@@ -144,6 +120,32 @@ nzUInt8 NzIndexBuffer::GetIndexSize() const
|
||||
return m_buffer->GetTypeSize();
|
||||
}
|
||||
|
||||
void* NzIndexBuffer::GetPointer()
|
||||
{
|
||||
#if NAZARA_UTILITY_SAFE
|
||||
if (!m_buffer)
|
||||
{
|
||||
NazaraError("Sequential buffers have 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 buffers have 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;
|
||||
@@ -156,10 +158,10 @@ unsigned int NzIndexBuffer::GetStartIndex() const
|
||||
|
||||
bool NzIndexBuffer::IsHardware() const
|
||||
{
|
||||
#if NAZARA_RENDERER_SAFE
|
||||
#if NAZARA_UTILITY_SAFE
|
||||
if (!m_buffer)
|
||||
{
|
||||
NazaraError("Sequential index buffer is neither hardware or software");
|
||||
NazaraWarning("Sequential index buffers are neither hardware or software");
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
@@ -174,10 +176,10 @@ bool NzIndexBuffer::IsSequential() const
|
||||
|
||||
void* NzIndexBuffer::Map(nzBufferAccess access, unsigned int offset, unsigned int length)
|
||||
{
|
||||
#if NAZARA_RENDERER_SAFE
|
||||
#if NAZARA_UTILITY_SAFE
|
||||
if (!m_buffer)
|
||||
{
|
||||
NazaraError("Impossible to map sequential index buffer");
|
||||
NazaraError("Impossible to map sequential buffers");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
@@ -191,12 +193,25 @@ void* NzIndexBuffer::Map(nzBufferAccess access, unsigned int offset, unsigned in
|
||||
return m_buffer->Map(access, m_startIndex+offset, (length) ? length : m_indexCount-offset);
|
||||
}
|
||||
|
||||
bool NzIndexBuffer::Unmap()
|
||||
bool NzIndexBuffer::SetStorage(nzBufferStorage storage)
|
||||
{
|
||||
#if NAZARA_RENDERER_SAFE
|
||||
#if NAZARA_UTILITY_SAFE
|
||||
if (!m_buffer)
|
||||
{
|
||||
NazaraError("Impossible to unlock sequential index buffer");
|
||||
NazaraWarning("Sequential buffers have no storage");
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
||||
return m_buffer->SetStorage(storage);
|
||||
}
|
||||
|
||||
bool NzIndexBuffer::Unmap()
|
||||
{
|
||||
#if NAZARA_UTILITY_SAFE
|
||||
if (!m_buffer)
|
||||
{
|
||||
NazaraError("Impossible to unlock sequential buffers");
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
13
src/Nazara/Utility/KeyframeMesh.cpp
Normal file
13
src/Nazara/Utility/KeyframeMesh.cpp
Normal file
@@ -0,0 +1,13 @@
|
||||
// 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/KeyframeMesh.hpp>
|
||||
#include <Nazara/Utility/Debug.hpp>
|
||||
|
||||
NzKeyframeMesh::NzKeyframeMesh(const NzMesh* parent) :
|
||||
NzSubMesh(parent)
|
||||
{
|
||||
}
|
||||
|
||||
NzKeyframeMesh::~NzKeyframeMesh() = default;
|
||||
15
src/Nazara/Utility/Loaders/MD2.hpp
Normal file
15
src/Nazara/Utility/Loaders/MD2.hpp
Normal file
@@ -0,0 +1,15 @@
|
||||
// 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_LOADERS_MD2_HPP
|
||||
#define NAZARA_LOADERS_MD2_HPP
|
||||
|
||||
#include <Nazara/Prerequesites.hpp>
|
||||
|
||||
void NzLoaders_MD2_Register();
|
||||
void NzLoaders_MD2_Unregister();
|
||||
|
||||
#endif // NAZARA_LOADERS_MD2_HPP
|
||||
173
src/Nazara/Utility/Loaders/MD2/Constants.cpp
Normal file
173
src/Nazara/Utility/Loaders/MD2/Constants.cpp
Normal file
@@ -0,0 +1,173 @@
|
||||
// Copyright (C) 2011 Jérôme Leclercq
|
||||
// This file is part of the "Ungine".
|
||||
// For conditions of distribution and use, see copyright notice in Core.h
|
||||
|
||||
#include <Nazara/Utility/Loaders/MD2/Constants.hpp>
|
||||
|
||||
const nzUInt32 md2Ident = 'I' + ('D'<<8) + ('P'<<16) + ('2'<<24);
|
||||
|
||||
const NzVector3f md2Normals[162] =
|
||||
{
|
||||
NzVector3f(-0.525731f, 0.000000f, 0.850651f),
|
||||
NzVector3f(-0.442863f, 0.238856f, 0.864188f),
|
||||
NzVector3f(-0.295242f, 0.000000f, 0.955423f),
|
||||
NzVector3f(-0.309017f, 0.500000f, 0.809017f),
|
||||
NzVector3f(-0.162460f, 0.262866f, 0.951056f),
|
||||
NzVector3f(0.000000f, 0.000000f, 1.000000f),
|
||||
NzVector3f(0.000000f, 0.850651f, 0.525731f),
|
||||
NzVector3f(-0.147621f, 0.716567f, 0.681718f),
|
||||
NzVector3f(0.147621f, 0.716567f, 0.681718f),
|
||||
NzVector3f(0.000000f, 0.525731f, 0.850651f),
|
||||
NzVector3f(0.309017f, 0.500000f, 0.809017f),
|
||||
NzVector3f(0.525731f, 0.000000f, 0.850651f),
|
||||
NzVector3f(0.295242f, 0.000000f, 0.955423f),
|
||||
NzVector3f(0.442863f, 0.238856f, 0.864188f),
|
||||
NzVector3f(0.162460f, 0.262866f, 0.951056f),
|
||||
NzVector3f(-0.681718f, 0.147621f, 0.716567f),
|
||||
NzVector3f(-0.809017f, 0.309017f, 0.500000f),
|
||||
NzVector3f(-0.587785f, 0.425325f, 0.688191f),
|
||||
NzVector3f(-0.850651f, 0.525731f, 0.000000f),
|
||||
NzVector3f(-0.864188f, 0.442863f, 0.238856f),
|
||||
NzVector3f(-0.716567f, 0.681718f, 0.147621f),
|
||||
NzVector3f(-0.688191f, 0.587785f, 0.425325f),
|
||||
NzVector3f(-0.500000f, 0.809017f, 0.309017f),
|
||||
NzVector3f(-0.238856f, 0.864188f, 0.442863f),
|
||||
NzVector3f(-0.425325f, 0.688191f, 0.587785f),
|
||||
NzVector3f(-0.716567f, 0.681718f, -0.147621f),
|
||||
NzVector3f(-0.500000f, 0.809017f, -0.309017f),
|
||||
NzVector3f(-0.525731f, 0.850651f, 0.000000f),
|
||||
NzVector3f(0.000000f, 0.850651f, -0.525731f),
|
||||
NzVector3f(-0.238856f, 0.864188f, -0.442863f),
|
||||
NzVector3f(0.000000f, 0.955423f, -0.295242f),
|
||||
NzVector3f(-0.262866f, 0.951056f, -0.162460f),
|
||||
NzVector3f(0.000000f, 1.000000f, 0.000000f),
|
||||
NzVector3f(0.000000f, 0.955423f, 0.295242f),
|
||||
NzVector3f(-0.262866f, 0.951056f, 0.162460f),
|
||||
NzVector3f(0.238856f, 0.864188f, 0.442863f),
|
||||
NzVector3f(0.262866f, 0.951056f, 0.162460f),
|
||||
NzVector3f(0.500000f, 0.809017f, 0.309017f),
|
||||
NzVector3f(0.238856f, 0.864188f, -0.442863f),
|
||||
NzVector3f(0.262866f, 0.951056f, -0.162460f),
|
||||
NzVector3f(0.500000f, 0.809017f, -0.309017f),
|
||||
NzVector3f(0.850651f, 0.525731f, 0.000000f),
|
||||
NzVector3f(0.716567f, 0.681718f, 0.147621f),
|
||||
NzVector3f(0.716567f, 0.681718f, -0.147621f),
|
||||
NzVector3f(0.525731f, 0.850651f, 0.000000f),
|
||||
NzVector3f(0.425325f, 0.688191f, 0.587785f),
|
||||
NzVector3f(0.864188f, 0.442863f, 0.238856f),
|
||||
NzVector3f(0.688191f, 0.587785f, 0.425325f),
|
||||
NzVector3f(0.809017f, 0.309017f, 0.500000f),
|
||||
NzVector3f(0.681718f, 0.147621f, 0.716567f),
|
||||
NzVector3f(0.587785f, 0.425325f, 0.688191f),
|
||||
NzVector3f(0.955423f, 0.295242f, 0.000000f),
|
||||
NzVector3f(1.000000f, 0.000000f, 0.000000f),
|
||||
NzVector3f(0.951056f, 0.162460f, 0.262866f),
|
||||
NzVector3f(0.850651f, -0.525731f, 0.000000f),
|
||||
NzVector3f(0.955423f, -0.295242f, 0.000000f),
|
||||
NzVector3f(0.864188f, -0.442863f, 0.238856f),
|
||||
NzVector3f(0.951056f, -0.162460f, 0.262866f),
|
||||
NzVector3f(0.809017f, -0.309017f, 0.500000f),
|
||||
NzVector3f(0.681718f, -0.147621f, 0.716567f),
|
||||
NzVector3f(0.850651f, 0.000000f, 0.525731f),
|
||||
NzVector3f(0.864188f, 0.442863f, -0.238856f),
|
||||
NzVector3f(0.809017f, 0.309017f, -0.500000f),
|
||||
NzVector3f(0.951056f, 0.162460f, -0.262866f),
|
||||
NzVector3f(0.525731f, 0.000000f, -0.850651f),
|
||||
NzVector3f(0.681718f, 0.147621f, -0.716567f),
|
||||
NzVector3f(0.681718f, -0.147621f, -0.716567f),
|
||||
NzVector3f(0.850651f, 0.000000f, -0.525731f),
|
||||
NzVector3f(0.809017f, -0.309017f, -0.500000f),
|
||||
NzVector3f(0.864188f, -0.442863f, -0.238856f),
|
||||
NzVector3f(0.951056f, -0.162460f, -0.262866f),
|
||||
NzVector3f(0.147621f, 0.716567f, -0.681718f),
|
||||
NzVector3f(0.309017f, 0.500000f, -0.809017f),
|
||||
NzVector3f(0.425325f, 0.688191f, -0.587785f),
|
||||
NzVector3f(0.442863f, 0.238856f, -0.864188f),
|
||||
NzVector3f(0.587785f, 0.425325f, -0.688191f),
|
||||
NzVector3f(0.688191f, 0.587785f, -0.425325f),
|
||||
NzVector3f(-0.147621f, 0.716567f, -0.681718f),
|
||||
NzVector3f(-0.309017f, 0.500000f, -0.809017f),
|
||||
NzVector3f(0.000000f, 0.525731f, -0.850651f),
|
||||
NzVector3f(-0.525731f, 0.000000f, -0.850651f),
|
||||
NzVector3f(-0.442863f, 0.238856f, -0.864188f),
|
||||
NzVector3f(-0.295242f, 0.000000f, -0.955423f),
|
||||
NzVector3f(-0.162460f, 0.262866f, -0.951056f),
|
||||
NzVector3f(0.000000f, 0.000000f, -1.000000f),
|
||||
NzVector3f(0.295242f, 0.000000f, -0.955423f),
|
||||
NzVector3f(0.162460f, 0.262866f, -0.951056f),
|
||||
NzVector3f(-0.442863f, -0.238856f, -0.864188f),
|
||||
NzVector3f(-0.309017f, -0.500000f, -0.809017f),
|
||||
NzVector3f(-0.162460f, -0.262866f, -0.951056f),
|
||||
NzVector3f(0.000000f, -0.850651f, -0.525731f),
|
||||
NzVector3f(-0.147621f, -0.716567f, -0.681718f),
|
||||
NzVector3f(0.147621f, -0.716567f, -0.681718f),
|
||||
NzVector3f(0.000000f, -0.525731f, -0.850651f),
|
||||
NzVector3f(0.309017f, -0.500000f, -0.809017f),
|
||||
NzVector3f(0.442863f, -0.238856f, -0.864188f),
|
||||
NzVector3f(0.162460f, -0.262866f, -0.951056f),
|
||||
NzVector3f(0.238856f, -0.864188f, -0.442863f),
|
||||
NzVector3f(0.500000f, -0.809017f, -0.309017f),
|
||||
NzVector3f(0.425325f, -0.688191f, -0.587785f),
|
||||
NzVector3f(0.716567f, -0.681718f, -0.147621f),
|
||||
NzVector3f(0.688191f, -0.587785f, -0.425325f),
|
||||
NzVector3f(0.587785f, -0.425325f, -0.688191f),
|
||||
NzVector3f(0.000000f, -0.955423f, -0.295242f),
|
||||
NzVector3f(0.000000f, -1.000000f, 0.000000f),
|
||||
NzVector3f(0.262866f, -0.951056f, -0.162460f),
|
||||
NzVector3f(0.000000f, -0.850651f, 0.525731f),
|
||||
NzVector3f(0.000000f, -0.955423f, 0.295242f),
|
||||
NzVector3f(0.238856f, -0.864188f, 0.442863f),
|
||||
NzVector3f(0.262866f, -0.951056f, 0.162460f),
|
||||
NzVector3f(0.500000f, -0.809017f, 0.309017f),
|
||||
NzVector3f(0.716567f, -0.681718f, 0.147621f),
|
||||
NzVector3f(0.525731f, -0.850651f, 0.000000f),
|
||||
NzVector3f(-0.238856f, -0.864188f, -0.442863f),
|
||||
NzVector3f(-0.500000f, -0.809017f, -0.309017f),
|
||||
NzVector3f(-0.262866f, -0.951056f, -0.162460f),
|
||||
NzVector3f(-0.850651f, -0.525731f, 0.000000f),
|
||||
NzVector3f(-0.716567f, -0.681718f, -0.147621f),
|
||||
NzVector3f(-0.716567f, -0.681718f, 0.147621f),
|
||||
NzVector3f(-0.525731f, -0.850651f, 0.000000f),
|
||||
NzVector3f(-0.500000f, -0.809017f, 0.309017f),
|
||||
NzVector3f(-0.238856f, -0.864188f, 0.442863f),
|
||||
NzVector3f(-0.262866f, -0.951056f, 0.162460f),
|
||||
NzVector3f(-0.864188f, -0.442863f, 0.238856f),
|
||||
NzVector3f(-0.809017f, -0.309017f, 0.500000f),
|
||||
NzVector3f(-0.688191f, -0.587785f, 0.425325f),
|
||||
NzVector3f(-0.681718f, -0.147621f, 0.716567f),
|
||||
NzVector3f(-0.442863f, -0.238856f, 0.864188f),
|
||||
NzVector3f(-0.587785f, -0.425325f, 0.688191f),
|
||||
NzVector3f(-0.309017f, -0.500000f, 0.809017f),
|
||||
NzVector3f(-0.147621f, -0.716567f, 0.681718f),
|
||||
NzVector3f(-0.425325f, -0.688191f, 0.587785f),
|
||||
NzVector3f(-0.162460f, -0.262866f, 0.951056f),
|
||||
NzVector3f(0.442863f, -0.238856f, 0.864188f),
|
||||
NzVector3f(0.162460f, -0.262866f, 0.951056f),
|
||||
NzVector3f(0.309017f, -0.500000f, 0.809017f),
|
||||
NzVector3f(0.147621f, -0.716567f, 0.681718f),
|
||||
NzVector3f(0.000000f, -0.525731f, 0.850651f),
|
||||
NzVector3f(0.425325f, -0.688191f, 0.587785f),
|
||||
NzVector3f(0.587785f, -0.425325f, 0.688191f),
|
||||
NzVector3f(0.688191f, -0.587785f, 0.425325f),
|
||||
NzVector3f(-0.955423f, 0.295242f, 0.000000f),
|
||||
NzVector3f(-0.951056f, 0.162460f, 0.262866f),
|
||||
NzVector3f(-1.000000f, 0.000000f, 0.000000f),
|
||||
NzVector3f(-0.850651f, 0.000000f, 0.525731f),
|
||||
NzVector3f(-0.955423f, -0.295242f, 0.000000f),
|
||||
NzVector3f(-0.951056f, -0.162460f, 0.262866f),
|
||||
NzVector3f(-0.864188f, 0.442863f, -0.238856f),
|
||||
NzVector3f(-0.951056f, 0.162460f, -0.262866f),
|
||||
NzVector3f(-0.809017f, 0.309017f, -0.500000f),
|
||||
NzVector3f(-0.864188f, -0.442863f, -0.238856f),
|
||||
NzVector3f(-0.951056f, -0.162460f, -0.262866f),
|
||||
NzVector3f(-0.809017f, -0.309017f, -0.500000f),
|
||||
NzVector3f(-0.681718f, 0.147621f, -0.716567f),
|
||||
NzVector3f(-0.681718f, -0.147621f, -0.716567f),
|
||||
NzVector3f(-0.850651f, 0.000000f, -0.525731f),
|
||||
NzVector3f(-0.688191f, 0.587785f, -0.425325f),
|
||||
NzVector3f(-0.587785f, 0.425325f, -0.688191f),
|
||||
NzVector3f(-0.425325f, 0.688191f, -0.587785f),
|
||||
NzVector3f(-0.425325f, -0.688191f, -0.587785f),
|
||||
NzVector3f(-0.587785f, -0.425325f, -0.688191f),
|
||||
NzVector3f(-0.688191f, -0.587785f, -0.425325f)
|
||||
};
|
||||
65
src/Nazara/Utility/Loaders/MD2/Constants.hpp
Normal file
65
src/Nazara/Utility/Loaders/MD2/Constants.hpp
Normal file
@@ -0,0 +1,65 @@
|
||||
// Copyright (C) 2011 Jérôme Leclercq
|
||||
// This file is part of the "Ungine".
|
||||
// For conditions of distribution and use, see copyright notice in Core.h
|
||||
|
||||
#ifndef NAZARA_LOADERS_MD2_CONSTANTS_HPP
|
||||
#define NAZARA_LOADERS_MD2_CONSTANTS_HPP
|
||||
|
||||
#include <Nazara/Prerequesites.hpp>
|
||||
#include <Nazara/Math/Vector3.hpp>
|
||||
#include <vector>
|
||||
|
||||
struct md2_header
|
||||
{
|
||||
nzUInt32 ident; // nombre magique : "IDP2"
|
||||
nzUInt32 version; // version du format : 8
|
||||
|
||||
nzUInt32 skinwidth; // largeur texture
|
||||
nzUInt32 skinheight; // hauteur texture
|
||||
|
||||
nzUInt32 framesize; // taille d'une frame en octets
|
||||
|
||||
nzUInt32 num_skins; // nombre de skins
|
||||
nzUInt32 num_vertices; // nombre de vertices par frame
|
||||
nzUInt32 num_st; // nombre de coordonnées de texture
|
||||
nzUInt32 num_tris; // nombre de triangles
|
||||
nzUInt32 num_glcmds; // nombre de commandes opengl
|
||||
nzUInt32 num_frames; // nombre de frames
|
||||
|
||||
nzUInt32 offset_skins; // offset données skins
|
||||
nzUInt32 offset_st; // offset données coordonnées de texture
|
||||
nzUInt32 offset_tris; // offset données triangles
|
||||
nzUInt32 offset_frames; // offset données frames
|
||||
nzUInt32 offset_glcmds; // offset données commandes OpenGL
|
||||
nzUInt32 offset_end; // offset fin de fichier
|
||||
};
|
||||
|
||||
struct md2_vertex
|
||||
{
|
||||
nzUInt8 x, y, z;
|
||||
nzUInt8 n;
|
||||
};
|
||||
|
||||
struct md2_texCoord
|
||||
{
|
||||
nzInt16 u, v;
|
||||
};
|
||||
|
||||
struct md2_triangle
|
||||
{
|
||||
nzUInt16 vertices[3];
|
||||
nzUInt16 texCoords[3];
|
||||
};
|
||||
|
||||
struct md2_frame
|
||||
{
|
||||
NzVector3f scale;
|
||||
NzVector3f translate;
|
||||
char name[16];
|
||||
std::vector<md2_vertex> vertices;
|
||||
};
|
||||
|
||||
extern const nzUInt32 md2Ident;
|
||||
extern const NzVector3f md2Normals[162];
|
||||
|
||||
#endif // NAZARA_LOADERS_MD2_CONSTANTS_HPP
|
||||
266
src/Nazara/Utility/Loaders/MD2/Loader.cpp
Normal file
266
src/Nazara/Utility/Loaders/MD2/Loader.cpp
Normal file
@@ -0,0 +1,266 @@
|
||||
// Copyright (C) 2011 Jérôme Leclercq
|
||||
// This file is part of the "Ungine".
|
||||
// For conditions of distribution and use, see copyright notice in Core.h
|
||||
|
||||
#include <Nazara/Utility/Loaders/MD2.hpp>
|
||||
#include <Nazara/Core/Endianness.hpp>
|
||||
#include <Nazara/Core/Error.hpp>
|
||||
#include <Nazara/Core/File.hpp>
|
||||
#include <Nazara/Core/InputStream.hpp>
|
||||
#include <Nazara/Core/MemoryStream.hpp>
|
||||
#include <Nazara/Math/Basic.hpp>
|
||||
#include <Nazara/Utility/Mesh.hpp>
|
||||
#include <Nazara/Utility/Loaders/MD2/Constants.hpp>
|
||||
#include <Nazara/Utility/Loaders/MD2/Mesh.hpp>
|
||||
#include <cstddef>
|
||||
#include <cstring>
|
||||
#include <Nazara/Utility/Debug.hpp>
|
||||
|
||||
namespace
|
||||
{
|
||||
bool NzLoader_MD2_LoadStream(NzMesh* mesh, NzInputStream& stream, const NzMeshParams& parameters);
|
||||
|
||||
bool NzLoader_MD2_LoadFile(NzMesh* mesh, const NzString& filePath, const NzMeshParams& parameters)
|
||||
{
|
||||
NzFile file(filePath);
|
||||
if (!file.Open(NzFile::ReadOnly))
|
||||
{
|
||||
NazaraError("Failed to open file");
|
||||
return false;
|
||||
}
|
||||
|
||||
return NzLoader_MD2_LoadStream(mesh, file, parameters);
|
||||
}
|
||||
|
||||
bool NzLoader_MD2_LoadMemory(NzMesh* mesh, const void* data, unsigned int size, const NzMeshParams& parameters)
|
||||
{
|
||||
NzMemoryStream stream(data, size);
|
||||
return NzLoader_MD2_LoadStream(mesh, stream, parameters);
|
||||
}
|
||||
|
||||
bool NzLoader_MD2_LoadStream(NzMesh* mesh, NzInputStream& stream, const NzMeshParams& parameters)
|
||||
{
|
||||
md2_header header;
|
||||
if (stream.Read(&header, sizeof(md2_header)) != sizeof(md2_header))
|
||||
{
|
||||
NazaraError("Failed to read header");
|
||||
return false;
|
||||
}
|
||||
|
||||
// Les fichiers MD2 sont en little endian
|
||||
#if NAZARA_BIG_ENDIAN
|
||||
NzByteSwap(&header.ident, sizeof(nzUInt32));
|
||||
#endif
|
||||
|
||||
if (header.ident != md2Ident)
|
||||
{
|
||||
NazaraError("Invalid MD2 file");
|
||||
return false;
|
||||
}
|
||||
|
||||
#if NAZARA_BIG_ENDIAN
|
||||
NzByteSwap(&header.version, sizeof(nzUInt32));
|
||||
#endif
|
||||
|
||||
if (header.version != 8)
|
||||
{
|
||||
NazaraError("Bad version number (" + NzString::Number(header.version) + ')');
|
||||
return false;
|
||||
}
|
||||
|
||||
#if NAZARA_BIG_ENDIAN
|
||||
NzByteSwap(&header.skinwidth, sizeof(nzUInt32));
|
||||
NzByteSwap(&header.skinheight, sizeof(nzUInt32));
|
||||
NzByteSwap(&header.framesize, sizeof(nzUInt32));
|
||||
NzByteSwap(&header.num_skins, sizeof(nzUInt32));
|
||||
NzByteSwap(&header.num_vertices, sizeof(nzUInt32));
|
||||
NzByteSwap(&header.num_st, sizeof(nzUInt32));
|
||||
NzByteSwap(&header.num_tris, sizeof(nzUInt32));
|
||||
NzByteSwap(&header.num_glcmds, sizeof(nzUInt32));
|
||||
NzByteSwap(&header.num_frames, sizeof(nzUInt32));
|
||||
NzByteSwap(&header.offset_skins, sizeof(nzUInt32));
|
||||
NzByteSwap(&header.offset_st, sizeof(nzUInt32));
|
||||
NzByteSwap(&header.offset_tris, sizeof(nzUInt32));
|
||||
NzByteSwap(&header.offset_frames, sizeof(nzUInt32));
|
||||
NzByteSwap(&header.offset_glcmds, sizeof(nzUInt32));
|
||||
NzByteSwap(&header.offset_end, sizeof(nzUInt32));
|
||||
#endif
|
||||
|
||||
if (stream.GetSize() < header.offset_end)
|
||||
{
|
||||
NazaraError("Incomplete MD2 file");
|
||||
return false;
|
||||
}
|
||||
|
||||
/// Création du mesh
|
||||
// Animé ou statique, c'est la question
|
||||
bool animated;
|
||||
unsigned int startFrame = NzClamp(parameters.animation.startFrame, 0U, static_cast<unsigned int>(header.num_frames-1));
|
||||
unsigned int endFrame = NzClamp(parameters.animation.endFrame, 0U, static_cast<unsigned int>(header.num_frames-1));
|
||||
|
||||
if (parameters.loadAnimations && startFrame != endFrame)
|
||||
animated = true;
|
||||
else
|
||||
animated = false;
|
||||
|
||||
if (!mesh->Create((animated) ? nzAnimationType_Keyframe : nzAnimationType_Static)) // Ne devrait pas échouer
|
||||
{
|
||||
NazaraInternalError("Failed to create mesh");
|
||||
return false;
|
||||
}
|
||||
|
||||
/// Chargement des skins
|
||||
if (header.num_skins > 0)
|
||||
{
|
||||
stream.SetCursorPos(header.offset_skins);
|
||||
{
|
||||
char skin[68];
|
||||
for (unsigned int i = 0; i < header.num_skins; ++i)
|
||||
{
|
||||
stream.Read(skin, 68*sizeof(char));
|
||||
mesh->AddSkin(skin);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Chargement des animmations
|
||||
if (animated)
|
||||
{
|
||||
NzAnimation* animation = new NzAnimation;
|
||||
if (animation->Create(nzAnimationType_Keyframe, endFrame-startFrame+1))
|
||||
{
|
||||
NzString frameName;
|
||||
|
||||
NzSequence sequence;
|
||||
sequence.framePerSecond = 10; // Par défaut pour les animations MD2
|
||||
|
||||
char name[16], last[16];
|
||||
stream.SetCursorPos(header.offset_frames + startFrame*header.framesize + offsetof(md2_frame, name));
|
||||
stream.Read(last, 16*sizeof(char));
|
||||
|
||||
int pos = std::strlen(last)-1;
|
||||
for (unsigned int j = 0; j < 2; ++j)
|
||||
{
|
||||
if (!std::isdigit(last[pos]))
|
||||
break;
|
||||
|
||||
pos--;
|
||||
}
|
||||
last[pos+1] = '\0';
|
||||
|
||||
unsigned int numFrames = 0;
|
||||
for (unsigned int i = startFrame; i <= endFrame; ++i)
|
||||
{
|
||||
stream.SetCursorPos(header.offset_frames + i*header.framesize + offsetof(md2_frame, name));
|
||||
stream.Read(name, 16*sizeof(char));
|
||||
|
||||
int pos = std::strlen(name)-1;
|
||||
for (unsigned int j = 0; j < 2; ++j)
|
||||
{
|
||||
if (!std::isdigit(name[pos]))
|
||||
break;
|
||||
|
||||
pos--;
|
||||
}
|
||||
name[pos+1] = '\0';
|
||||
|
||||
if (std::strcmp(name, last) != 0) // Si les deux frames n'ont pas le même nom
|
||||
{
|
||||
// Alors on enregistre la séquence
|
||||
sequence.firstFrame = i-numFrames;
|
||||
sequence.lastFrame = i-1;
|
||||
sequence.name = last;
|
||||
animation->AddSequence(sequence);
|
||||
|
||||
std::strcpy(last, name);
|
||||
|
||||
numFrames = 0;
|
||||
}
|
||||
|
||||
numFrames++;
|
||||
}
|
||||
|
||||
// On ajoute la dernière frame (Qui n'a pas été traitée par la boucle)
|
||||
sequence.firstFrame = endFrame-numFrames;
|
||||
sequence.lastFrame = endFrame;
|
||||
sequence.name = last;
|
||||
animation->AddSequence(sequence);
|
||||
|
||||
mesh->SetAnimation(animation);
|
||||
animation->SetPersistent(false);
|
||||
}
|
||||
else
|
||||
NazaraInternalError("Failed to create animaton");
|
||||
}
|
||||
|
||||
/// Chargement des submesh
|
||||
// Actuellement le loader ne charge qu'un submesh
|
||||
// TODO: Utiliser les commandes OpenGL pour accélérer le rendu
|
||||
NzMD2Mesh* subMesh = new NzMD2Mesh(mesh);
|
||||
if (!subMesh->Create(header, stream, parameters))
|
||||
{
|
||||
NazaraError("Failed to create MD2 mesh");
|
||||
return false;
|
||||
}
|
||||
|
||||
mesh->AddSubMesh(subMesh);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool NzLoader_MD2_IdentifyMemory(const void* data, unsigned int size, const NzMeshParams& parameters)
|
||||
{
|
||||
NazaraUnused(parameters);
|
||||
|
||||
if (size < sizeof(md2_header))
|
||||
return false;
|
||||
|
||||
const md2_header* header = reinterpret_cast<const md2_header*>(data);
|
||||
|
||||
#if NAZARA_BIG_ENDIAN
|
||||
nzUInt32 ident = header->ident;
|
||||
nzUInt32 version = header->version;
|
||||
|
||||
NzByteSwap(&ident, sizeof(nzUInt32));
|
||||
NzByteSwap(&version, sizeof(nzUInt32));
|
||||
|
||||
return ident == md2Ident && version == 8;
|
||||
#else
|
||||
return header->ident == md2Ident && header->version == 8;
|
||||
#endif
|
||||
}
|
||||
|
||||
bool NzLoader_MD2_IdentifyStream(NzInputStream& stream, const NzMeshParams& parameters)
|
||||
{
|
||||
NazaraUnused(parameters);
|
||||
|
||||
nzUInt32 magic[2];
|
||||
if (stream.Read(&magic[0], 2*sizeof(nzUInt32)) != 2*sizeof(nzUInt32))
|
||||
return false;
|
||||
|
||||
#if NAZARA_BIG_ENDIAN
|
||||
NzByteSwap(&magic[0], sizeof(nzUInt32));
|
||||
NzByteSwap(&magic[1], sizeof(nzUInt32));
|
||||
#endif
|
||||
|
||||
return magic[0] == md2Ident && magic[1] == 8;
|
||||
}
|
||||
}
|
||||
|
||||
void NzLoaders_MD2_Register()
|
||||
{
|
||||
NzMD2Mesh::Initialize();
|
||||
|
||||
NzMeshLoader::RegisterFileLoader("md2", NzLoader_MD2_LoadFile);
|
||||
NzMeshLoader::RegisterMemoryLoader(NzLoader_MD2_IdentifyMemory, NzLoader_MD2_LoadMemory);
|
||||
NzMeshLoader::RegisterStreamLoader(NzLoader_MD2_IdentifyStream, NzLoader_MD2_LoadStream);
|
||||
}
|
||||
|
||||
void NzLoaders_MD2_Unregister()
|
||||
{
|
||||
NzMeshLoader::UnregisterStreamLoader(NzLoader_MD2_IdentifyStream, NzLoader_MD2_LoadStream);
|
||||
NzMeshLoader::UnregisterMemoryLoader(NzLoader_MD2_IdentifyMemory, NzLoader_MD2_LoadMemory);
|
||||
NzMeshLoader::UnregisterFileLoader("md2", NzLoader_MD2_LoadFile);
|
||||
|
||||
NzMD2Mesh::Uninitialize();
|
||||
}
|
||||
275
src/Nazara/Utility/Loaders/MD2/Mesh.cpp
Normal file
275
src/Nazara/Utility/Loaders/MD2/Mesh.cpp
Normal file
@@ -0,0 +1,275 @@
|
||||
// Copyright (C) 2011 Jérôme Leclercq
|
||||
// This file is part of the "Ungine".
|
||||
// For conditions of distribution and use, see copyright notice in Core.h
|
||||
|
||||
#include <Nazara/Utility/Loaders/MD2/Mesh.hpp>
|
||||
#include <Nazara/Core/InputStream.hpp>
|
||||
#include <Nazara/Math/Matrix4.hpp>
|
||||
#include <Nazara/Utility/IndexBuffer.hpp>
|
||||
#include <Nazara/Utility/Mesh.hpp>
|
||||
#include <Nazara/Utility/VertexBuffer.hpp>
|
||||
#include <Nazara/Utility/Debug.hpp>
|
||||
|
||||
NzMD2Mesh::NzMD2Mesh(const NzMesh* parent) :
|
||||
NzKeyframeMesh(parent),
|
||||
m_frames(nullptr),
|
||||
m_indexBuffer(nullptr),
|
||||
m_vertexBuffer(nullptr)
|
||||
{
|
||||
}
|
||||
|
||||
NzMD2Mesh::~NzMD2Mesh()
|
||||
{
|
||||
Destroy();
|
||||
}
|
||||
|
||||
bool NzMD2Mesh::Create(const md2_header& header, NzInputStream& stream, const NzMeshParams& parameters)
|
||||
{
|
||||
Destroy();
|
||||
|
||||
unsigned int startFrame = NzClamp(parameters.animation.startFrame, 0U, static_cast<unsigned int>(header.num_frames-1));
|
||||
unsigned int endFrame = NzClamp(parameters.animation.endFrame, 0U, static_cast<unsigned int>(header.num_frames-1));
|
||||
|
||||
m_frameCount = endFrame - startFrame + 1;
|
||||
m_vertexCount = header.num_tris*3;
|
||||
|
||||
/// Chargement des vertices
|
||||
std::vector<md2_texCoord> texCoords(header.num_st);
|
||||
std::vector<md2_triangle> triangles(header.num_tris);
|
||||
|
||||
// Lecture des coordonnées de texture
|
||||
stream.SetCursorPos(header.offset_st);
|
||||
stream.Read(&texCoords[0], header.num_st*sizeof(md2_texCoord));
|
||||
|
||||
#if NAZARA_BIG_ENDIAN
|
||||
for (unsigned int i = 0; i < header.num_st; ++i)
|
||||
{
|
||||
NzByteSwap(&texCoords[i].u, sizeof(nzInt16));
|
||||
NzByteSwap(&texCoords[i].v, sizeof(nzInt16));
|
||||
}
|
||||
#endif
|
||||
|
||||
stream.SetCursorPos(header.offset_tris);
|
||||
stream.Read(&triangles[0], header.num_tris*sizeof(md2_triangle));
|
||||
|
||||
#if NAZARA_BIG_ENDIAN
|
||||
for (unsigned int i = 0; i < header.num_tris; ++i)
|
||||
{
|
||||
NzByteSwap(&triangles[i].vertices[0], sizeof(nzUInt16));
|
||||
NzByteSwap(&texCoords[i].texCoords[0], sizeof(nzUInt16));
|
||||
|
||||
NzByteSwap(&triangles[i].vertices[1], sizeof(nzUInt16));
|
||||
NzByteSwap(&texCoords[i].texCoords[1], sizeof(nzUInt16));
|
||||
|
||||
NzByteSwap(&triangles[i].vertices[2], sizeof(nzUInt16));
|
||||
NzByteSwap(&texCoords[i].texCoords[2], sizeof(nzUInt16));
|
||||
}
|
||||
#endif
|
||||
|
||||
stream.SetCursorPos(header.offset_frames + header.framesize*startFrame);
|
||||
|
||||
md2_frame frame;
|
||||
frame.vertices.resize(header.num_vertices);
|
||||
|
||||
// Pour que le modèle soit correctement aligné, on génère une matrice de rotation que nous appliquerons à chacune des vertices
|
||||
NzMatrix4f rotationMatrix = NzMatrix4f::Rotate(NzEulerAnglesf(-90.f, 0.f, -90.f));
|
||||
//NzMatrix4f rotationMatrix;
|
||||
//rotationMatrix.SetIdentity();
|
||||
|
||||
unsigned int stride = s_declaration.GetStride(nzElementStream_VertexData);
|
||||
|
||||
m_frames = new Frame[m_frameCount];
|
||||
for (unsigned int i = 0; i < m_frameCount; ++i)
|
||||
{
|
||||
stream.Read(&frame.scale, sizeof(NzVector3f));
|
||||
stream.Read(&frame.translate, sizeof(NzVector3f));
|
||||
stream.Read(&frame.name, 16*sizeof(char));
|
||||
stream.Read(&frame.vertices[0], header.num_vertices*sizeof(md2_vertex));
|
||||
|
||||
#if NAZARA_BIG_ENDIAN
|
||||
NzByteSwap(&frame.scale.x, sizeof(float));
|
||||
NzByteSwap(&frame.scale.y, sizeof(float));
|
||||
NzByteSwap(&frame.scale.z, sizeof(float));
|
||||
|
||||
NzByteSwap(&frame.translate.x, sizeof(float));
|
||||
NzByteSwap(&frame.translate.y, sizeof(float));
|
||||
NzByteSwap(&frame.translate.z, sizeof(float));
|
||||
#endif
|
||||
|
||||
m_frames[i].normal = new nzUInt8[m_vertexCount]; // Nous stockons l'indice de la normale plutôt que la normale (gain d'espace)
|
||||
m_frames[i].vertices = new NzVector3f[m_vertexCount];
|
||||
for (unsigned int t = 0; t < header.num_tris; ++t)
|
||||
{
|
||||
for (unsigned int v = 0; v < 3; ++v)
|
||||
{
|
||||
const md2_vertex& vert = frame.vertices[triangles[t].vertices[v]];
|
||||
|
||||
NzVector3f vertex = rotationMatrix * NzVector3f(vert.x * frame.scale.x + frame.translate.x, vert.y * frame.scale.y + frame.translate.y, vert.z * frame.scale.z + frame.translate.z);
|
||||
|
||||
m_frames[i].normal[t*3+v] = vert.n;
|
||||
m_frames[i].vertices[t*3+v] = vertex;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
nzBufferStorage storage = (NzBuffer::IsSupported(nzBufferStorage_Hardware) && !parameters.forceSoftware) ? nzBufferStorage_Hardware : nzBufferStorage_Software;
|
||||
|
||||
m_indexBuffer = nullptr; // Pas d'indexbuffer pour l'instant
|
||||
m_vertexBuffer = new NzVertexBuffer(m_vertexCount, (3+3+2)*sizeof(float), storage, nzBufferUsage_Dynamic);
|
||||
|
||||
nzUInt8* ptr = reinterpret_cast<nzUInt8*>(m_vertexBuffer->Map(nzBufferAccess_WriteOnly));
|
||||
if (!ptr)
|
||||
{
|
||||
NazaraError("Failed to map vertex buffer");
|
||||
Destroy();
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// On avance jusqu'aux premières coordonnées de texture
|
||||
ptr += s_declaration.GetElement(nzElementStream_VertexData, nzElementUsage_TexCoord)->offset;
|
||||
for (unsigned int t = 0; t < header.num_tris; ++t)
|
||||
{
|
||||
for (unsigned int v = 0; v < 3; ++v)
|
||||
{
|
||||
const md2_texCoord& texC = texCoords[triangles[t].texCoords[v]];
|
||||
|
||||
NzVector2f* coords = reinterpret_cast<NzVector2f*>(ptr);
|
||||
coords->x = texC.u / static_cast<float>(header.skinwidth);
|
||||
coords->y = 1.f - texC.v / static_cast<float>(header.skinheight);
|
||||
|
||||
ptr += stride;
|
||||
}
|
||||
}
|
||||
|
||||
if (!m_vertexBuffer->Unmap())
|
||||
{
|
||||
NazaraError("Failed to unmap buffer");
|
||||
Destroy();
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
m_vertexBuffer->AddResourceReference();
|
||||
m_vertexBuffer->SetPersistent(false);
|
||||
|
||||
AnimateImpl(0, 0, 0.f);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void NzMD2Mesh::Destroy()
|
||||
{
|
||||
if (m_frames)
|
||||
{
|
||||
for (unsigned int i = 0; i < m_frameCount; ++i)
|
||||
{
|
||||
delete[] m_frames[i].normal;
|
||||
delete[] m_frames[i].vertices;
|
||||
}
|
||||
|
||||
delete[] m_frames;
|
||||
m_frames = nullptr;
|
||||
}
|
||||
|
||||
if (m_indexBuffer)
|
||||
{
|
||||
m_indexBuffer->RemoveResourceReference();
|
||||
m_indexBuffer = nullptr;
|
||||
}
|
||||
|
||||
if (m_vertexBuffer)
|
||||
{
|
||||
m_vertexBuffer->RemoveResourceReference();
|
||||
m_vertexBuffer = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
nzAnimationType NzMD2Mesh::GetAnimationType() const
|
||||
{
|
||||
if (m_frameCount > 1)
|
||||
return nzAnimationType_Keyframe;
|
||||
else
|
||||
return nzAnimationType_Static;
|
||||
}
|
||||
|
||||
unsigned int NzMD2Mesh::GetFrameCount() const
|
||||
{
|
||||
return m_frameCount;
|
||||
}
|
||||
|
||||
const NzIndexBuffer* NzMD2Mesh::GetIndexBuffer() const
|
||||
{
|
||||
return nullptr;
|
||||
//return m_indexBuffer;
|
||||
}
|
||||
|
||||
nzPrimitiveType NzMD2Mesh::GetPrimitiveType() const
|
||||
{
|
||||
return nzPrimitiveType_TriangleList;
|
||||
}
|
||||
|
||||
const NzVertexBuffer* NzMD2Mesh::GetVertexBuffer() const
|
||||
{
|
||||
return m_vertexBuffer;
|
||||
}
|
||||
|
||||
const NzVertexDeclaration* NzMD2Mesh::GetVertexDeclaration() const
|
||||
{
|
||||
return &s_declaration;
|
||||
}
|
||||
|
||||
void NzMD2Mesh::Initialize()
|
||||
{
|
||||
NzVertexElement elements[3];
|
||||
elements[0].offset = 0;
|
||||
elements[0].type = nzElementType_Float3;
|
||||
elements[0].usage = nzElementUsage_Position;
|
||||
|
||||
elements[1].offset = 3*sizeof(float);
|
||||
elements[1].type = nzElementType_Float3;
|
||||
elements[1].usage = nzElementUsage_Normal;
|
||||
|
||||
elements[2].offset = 3*sizeof(float) + 3*sizeof(float);
|
||||
elements[2].type = nzElementType_Float2;
|
||||
elements[2].usage = nzElementUsage_TexCoord;
|
||||
|
||||
s_declaration.Create(elements, 3);
|
||||
}
|
||||
|
||||
void NzMD2Mesh::Uninitialize()
|
||||
{
|
||||
s_declaration.Destroy();
|
||||
}
|
||||
|
||||
void NzMD2Mesh::AnimateImpl(unsigned int frameA, unsigned int frameB, float interpolation)
|
||||
{
|
||||
nzUInt8* ptr = reinterpret_cast<nzUInt8*>(m_vertexBuffer->Map(nzBufferAccess_WriteOnly));
|
||||
if (!ptr)
|
||||
{
|
||||
NazaraError("Failed to map vertex buffer");
|
||||
return;
|
||||
}
|
||||
|
||||
unsigned int stride = s_declaration.GetStride(nzElementStream_VertexData);
|
||||
unsigned int positionOffset = s_declaration.GetElement(nzElementStream_VertexData, nzElementUsage_Position)->offset;
|
||||
unsigned int normalOffset = s_declaration.GetElement(nzElementStream_VertexData, nzElementUsage_Normal)->offset;
|
||||
|
||||
Frame* fA = &m_frames[frameA];
|
||||
Frame* fB = &m_frames[frameB];
|
||||
for (unsigned int i = 0; i < m_vertexCount; ++i)
|
||||
{
|
||||
NzVector3f* position = reinterpret_cast<NzVector3f*>(ptr + positionOffset);
|
||||
NzVector3f* normal = reinterpret_cast<NzVector3f*>(ptr + normalOffset);
|
||||
|
||||
*position = fA->vertices[i] + interpolation * (fB->vertices[i] - fA->vertices[i]);
|
||||
*normal = md2Normals[fA->normal[i]] + interpolation * (md2Normals[fB->normal[i]] - md2Normals[fA->normal[i]]);
|
||||
|
||||
ptr += stride;
|
||||
}
|
||||
|
||||
if (!m_vertexBuffer->Unmap())
|
||||
NazaraWarning("Failed to unmap vertex buffer, expect mesh corruption");
|
||||
}
|
||||
|
||||
NzVertexDeclaration NzMD2Mesh::s_declaration;
|
||||
64
src/Nazara/Utility/Loaders/MD2/Mesh.hpp
Normal file
64
src/Nazara/Utility/Loaders/MD2/Mesh.hpp
Normal file
@@ -0,0 +1,64 @@
|
||||
// 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_LOADERS_MD2_MESH_HPP
|
||||
#define NAZARA_LOADERS_MD2_MESH_HPP
|
||||
|
||||
#include <Nazara/Prerequesites.hpp>
|
||||
#include <Nazara/Math/Vector3.hpp>
|
||||
#include <Nazara/Utility/KeyframeMesh.hpp>
|
||||
#include <Nazara/Utility/VertexDeclaration.hpp>
|
||||
#include <Nazara/Utility/Loaders/MD2/Constants.hpp>
|
||||
|
||||
class NzIndexBuffer;
|
||||
class NzInputStream;
|
||||
class NzVertexBuffer;
|
||||
struct NzMeshParams;
|
||||
|
||||
class NAZARA_API NzMD2Mesh : public NzKeyframeMesh
|
||||
{
|
||||
public:
|
||||
NzMD2Mesh(const NzMesh* parent);
|
||||
~NzMD2Mesh();
|
||||
|
||||
bool Create(const md2_header& header, NzInputStream& stream, const NzMeshParams& parameters);
|
||||
void Destroy();
|
||||
|
||||
nzAnimationType GetAnimationType() const;
|
||||
unsigned int GetFrameCount() const;
|
||||
const NzIndexBuffer* GetIndexBuffer() const;
|
||||
nzPrimitiveType GetPrimitiveType() const;
|
||||
const NzVertexBuffer* GetVertexBuffer() const;
|
||||
const NzVertexDeclaration* GetVertexDeclaration() const;
|
||||
|
||||
bool IsAnimated() const;
|
||||
|
||||
static void Initialize();
|
||||
static void Uninitialize();
|
||||
|
||||
private:
|
||||
void AnimateImpl(unsigned int frameA, unsigned int frameB, float interpolation);
|
||||
|
||||
struct Frame
|
||||
{
|
||||
//AxisAlignedBox aabb;
|
||||
nzUInt8* normal;
|
||||
NzVector3f* tangents;
|
||||
NzVector3f* vertices;
|
||||
char name[16];
|
||||
};
|
||||
|
||||
//AxisAlignedBox m_aabb;
|
||||
Frame* m_frames;
|
||||
NzIndexBuffer* m_indexBuffer;
|
||||
NzVertexBuffer* m_vertexBuffer;
|
||||
unsigned int m_frameCount;
|
||||
unsigned int m_vertexCount;
|
||||
|
||||
static NzVertexDeclaration s_declaration;
|
||||
};
|
||||
|
||||
#endif // NAZARA_LOADERS_MD2_MESH_HPP
|
||||
@@ -37,9 +37,9 @@ namespace
|
||||
nzUInt8 padding[54];
|
||||
};
|
||||
|
||||
bool NzLoader_PCX_LoadStream(NzImage* resource, NzInputStream& stream, const NzImageParams& parameters);
|
||||
bool NzLoader_PCX_LoadStream(NzImage* image, NzInputStream& stream, const NzImageParams& parameters);
|
||||
|
||||
bool NzLoader_PCX_LoadFile(NzImage* resource, const NzString& filePath, const NzImageParams& parameters)
|
||||
bool NzLoader_PCX_LoadFile(NzImage* image, const NzString& filePath, const NzImageParams& parameters)
|
||||
{
|
||||
NzFile file(filePath);
|
||||
if (!file.Open(NzFile::ReadOnly))
|
||||
@@ -48,16 +48,16 @@ namespace
|
||||
return false;
|
||||
}
|
||||
|
||||
return NzLoader_PCX_LoadStream(resource, file, parameters);
|
||||
return NzLoader_PCX_LoadStream(image, file, parameters);
|
||||
}
|
||||
|
||||
bool NzLoader_PCX_LoadMemory(NzImage* resource, const void* data, unsigned int size, const NzImageParams& parameters)
|
||||
bool NzLoader_PCX_LoadMemory(NzImage* image, const void* data, unsigned int size, const NzImageParams& parameters)
|
||||
{
|
||||
NzMemoryStream stream(data, size);
|
||||
return NzLoader_PCX_LoadStream(resource, stream, parameters);
|
||||
return NzLoader_PCX_LoadStream(image, stream, parameters);
|
||||
}
|
||||
|
||||
bool NzLoader_PCX_LoadStream(NzImage* resource, NzInputStream& stream, const NzImageParams& parameters)
|
||||
bool NzLoader_PCX_LoadStream(NzImage* image, NzInputStream& stream, const NzImageParams& parameters)
|
||||
{
|
||||
NazaraUnused(parameters);
|
||||
|
||||
@@ -93,13 +93,13 @@ namespace
|
||||
unsigned int width = header.xmax - header.xmin+1;
|
||||
unsigned int height = header.ymax - header.ymin+1;
|
||||
|
||||
if (!resource->Create(nzImageType_2D, nzPixelFormat_RGB8, width, height, 1, (parameters.levelCount > 0) ? parameters.levelCount : 1))
|
||||
if (!image->Create(nzImageType_2D, nzPixelFormat_RGB8, width, height, 1, (parameters.levelCount > 0) ? parameters.levelCount : 1))
|
||||
{
|
||||
NazaraError("Failed to create image");
|
||||
return false;
|
||||
}
|
||||
|
||||
nzUInt8* pixels = resource->GetPixels();
|
||||
nzUInt8* pixels = image->GetPixels();
|
||||
|
||||
int rle_value = 0;
|
||||
unsigned int rle_count = 0;
|
||||
@@ -339,17 +339,17 @@ namespace
|
||||
}
|
||||
|
||||
default:
|
||||
NazaraError("Unknown " + NzString::Number(bitCount) + " bitcount pcx files");
|
||||
NazaraError("Unable to load " + NzString::Number(bitCount) + " bitcount pcx files");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (parameters.loadFormat != nzPixelFormat_Undefined)
|
||||
resource->Convert(parameters.loadFormat);
|
||||
image->Convert(parameters.loadFormat);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool NzLoader_PCX_IsMemoryLoadingSupported(const void* data, unsigned int size, const NzImageParams& parameters)
|
||||
bool NzLoader_PCX_IdentifyMemory(const void* data, unsigned int size, const NzImageParams& parameters)
|
||||
{
|
||||
NazaraUnused(parameters);
|
||||
|
||||
@@ -359,12 +359,13 @@ namespace
|
||||
return *reinterpret_cast<const nzUInt8*>(data) == 0x0a;
|
||||
}
|
||||
|
||||
bool NzLoader_PCX_IsStreamLoadingSupported(NzInputStream& stream, const NzImageParams& parameters)
|
||||
bool NzLoader_PCX_IdentifyStream(NzInputStream& stream, const NzImageParams& parameters)
|
||||
{
|
||||
NazaraUnused(parameters);
|
||||
|
||||
nzUInt8 manufacturer;
|
||||
stream.Read(&manufacturer, 1);
|
||||
if (stream.Read(&manufacturer, 1) != 1)
|
||||
return false;
|
||||
|
||||
return manufacturer == 0x0a;
|
||||
}
|
||||
@@ -372,14 +373,14 @@ namespace
|
||||
|
||||
void NzLoaders_PCX_Register()
|
||||
{
|
||||
NzImage::RegisterFileLoader("pcx", NzLoader_PCX_LoadFile);
|
||||
NzImage::RegisterMemoryLoader(NzLoader_PCX_IsMemoryLoadingSupported, NzLoader_PCX_LoadMemory);
|
||||
NzImage::RegisterStreamLoader(NzLoader_PCX_IsStreamLoadingSupported, NzLoader_PCX_LoadStream);
|
||||
NzImageLoader::RegisterFileLoader("pcx", NzLoader_PCX_LoadFile);
|
||||
NzImageLoader::RegisterMemoryLoader(NzLoader_PCX_IdentifyMemory, NzLoader_PCX_LoadMemory);
|
||||
NzImageLoader::RegisterStreamLoader(NzLoader_PCX_IdentifyStream, NzLoader_PCX_LoadStream);
|
||||
}
|
||||
|
||||
void NzLoaders_PCX_Unregister()
|
||||
{
|
||||
NzImage::UnregisterStreamLoader(NzLoader_PCX_IsStreamLoadingSupported, NzLoader_PCX_LoadStream);
|
||||
NzImage::UnregisterMemoryLoader(NzLoader_PCX_IsMemoryLoadingSupported, NzLoader_PCX_LoadMemory);
|
||||
NzImage::UnregisterFileLoader("pcx", NzLoader_PCX_LoadFile);
|
||||
NzImageLoader::UnregisterStreamLoader(NzLoader_PCX_IdentifyStream, NzLoader_PCX_LoadStream);
|
||||
NzImageLoader::UnregisterMemoryLoader(NzLoader_PCX_IdentifyMemory, NzLoader_PCX_LoadMemory);
|
||||
NzImageLoader::UnregisterFileLoader("pcx", NzLoader_PCX_LoadFile);
|
||||
}
|
||||
@@ -15,8 +15,6 @@
|
||||
|
||||
#include <Nazara/Utility/Debug.hpp>
|
||||
|
||||
// Auteur du loader original : David Henry
|
||||
|
||||
namespace
|
||||
{
|
||||
int Read(void* userdata, char* data, int size)
|
||||
@@ -39,9 +37,9 @@ namespace
|
||||
|
||||
static stbi_io_callbacks callbacks = {Read, Skip, Eof};
|
||||
|
||||
bool NzLoader_STB_LoadStream(NzImage* resource, NzInputStream& stream, const NzImageParams& parameters);
|
||||
bool NzLoader_STB_LoadStream(NzImage* image, NzInputStream& stream, const NzImageParams& parameters);
|
||||
|
||||
bool NzLoader_STB_LoadFile(NzImage* resource, const NzString& filePath, const NzImageParams& parameters)
|
||||
bool NzLoader_STB_LoadFile(NzImage* image, const NzString& filePath, const NzImageParams& parameters)
|
||||
{
|
||||
NzFile file(filePath);
|
||||
if (!file.Open(NzFile::ReadOnly))
|
||||
@@ -50,16 +48,16 @@ namespace
|
||||
return false;
|
||||
}
|
||||
|
||||
return NzLoader_STB_LoadStream(resource, file, parameters);
|
||||
return NzLoader_STB_LoadStream(image, file, parameters);
|
||||
}
|
||||
|
||||
bool NzLoader_STB_LoadMemory(NzImage* resource, const void* data, unsigned int size, const NzImageParams& parameters)
|
||||
bool NzLoader_STB_LoadMemory(NzImage* image, const void* data, unsigned int size, const NzImageParams& parameters)
|
||||
{
|
||||
NzMemoryStream stream(data, size);
|
||||
return NzLoader_STB_LoadStream(resource, stream, parameters);
|
||||
return NzLoader_STB_LoadStream(image, stream, parameters);
|
||||
}
|
||||
|
||||
bool NzLoader_STB_LoadStream(NzImage* resource, NzInputStream& stream, const NzImageParams& parameters)
|
||||
bool NzLoader_STB_LoadStream(NzImage* image, NzInputStream& stream, const NzImageParams& parameters)
|
||||
{
|
||||
NazaraUnused(parameters);
|
||||
|
||||
@@ -112,7 +110,7 @@ namespace
|
||||
if (format == nzPixelFormat_Undefined)
|
||||
format = formats[bpp-1];
|
||||
|
||||
if (!resource->Create(nzImageType_2D, format, width, height, 1, (parameters.levelCount > 0) ? parameters.levelCount : 1))
|
||||
if (!image->Create(nzImageType_2D, format, width, height, 1, (parameters.levelCount > 0) ? parameters.levelCount : 1))
|
||||
{
|
||||
NazaraError("Failed to create image");
|
||||
stbi_image_free(ptr);
|
||||
@@ -120,17 +118,17 @@ namespace
|
||||
return false;
|
||||
}
|
||||
|
||||
resource->Update(ptr);
|
||||
image->Update(ptr);
|
||||
|
||||
stbi_image_free(ptr);
|
||||
|
||||
if (stbiFormat == STBI_default && parameters.loadFormat != nzPixelFormat_Undefined)
|
||||
resource->Convert(parameters.loadFormat);
|
||||
image->Convert(parameters.loadFormat);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool NzLoader_STB_IsMemoryLoadingSupported(const void* data, unsigned int size, const NzImageParams& parameters)
|
||||
bool NzLoader_STB_IdentifyMemory(const void* data, unsigned int size, const NzImageParams& parameters)
|
||||
{
|
||||
NazaraUnused(parameters);
|
||||
|
||||
@@ -138,7 +136,7 @@ namespace
|
||||
return stbi_info_from_memory(reinterpret_cast<const stbi_uc*>(data), size, &width, &height, &bpp);
|
||||
}
|
||||
|
||||
bool NzLoader_STB_IsStreamLoadingSupported(NzInputStream& stream, const NzImageParams& parameters)
|
||||
bool NzLoader_STB_IdentifyStream(NzInputStream& stream, const NzImageParams& parameters)
|
||||
{
|
||||
NazaraUnused(parameters);
|
||||
|
||||
@@ -149,14 +147,14 @@ namespace
|
||||
|
||||
void NzLoaders_STB_Register()
|
||||
{
|
||||
NzImage::RegisterFileLoader("bmp, gif, hdr, jpg, jpeg, pic, png, psd, tga", NzLoader_STB_LoadFile);
|
||||
NzImage::RegisterMemoryLoader(NzLoader_STB_IsMemoryLoadingSupported, NzLoader_STB_LoadMemory);
|
||||
NzImage::RegisterStreamLoader(NzLoader_STB_IsStreamLoadingSupported, NzLoader_STB_LoadStream);
|
||||
NzImageLoader::RegisterFileLoader("bmp, gif, hdr, jpg, jpeg, pic, png, psd, tga", NzLoader_STB_LoadFile);
|
||||
NzImageLoader::RegisterMemoryLoader(NzLoader_STB_IdentifyMemory, NzLoader_STB_LoadMemory);
|
||||
NzImageLoader::RegisterStreamLoader(NzLoader_STB_IdentifyStream, NzLoader_STB_LoadStream);
|
||||
}
|
||||
|
||||
void NzLoaders_STB_Unregister()
|
||||
{
|
||||
NzImage::UnregisterStreamLoader(NzLoader_STB_IsStreamLoadingSupported, NzLoader_STB_LoadStream);
|
||||
NzImage::UnregisterMemoryLoader(NzLoader_STB_IsMemoryLoadingSupported, NzLoader_STB_LoadMemory);
|
||||
NzImage::UnregisterFileLoader("bmp, gif, hdr, jpg, jpeg, pic, png, psd, tga", NzLoader_STB_LoadFile);
|
||||
NzImageLoader::UnregisterStreamLoader(NzLoader_STB_IdentifyStream, NzLoader_STB_LoadStream);
|
||||
NzImageLoader::UnregisterMemoryLoader(NzLoader_STB_IdentifyMemory, NzLoader_STB_LoadMemory);
|
||||
NzImageLoader::UnregisterFileLoader("bmp, gif, hdr, jpg, jpeg, pic, png, psd, tga", NzLoader_STB_LoadFile);
|
||||
}
|
||||
575
src/Nazara/Utility/Mesh.cpp
Normal file
575
src/Nazara/Utility/Mesh.cpp
Normal file
@@ -0,0 +1,575 @@
|
||||
// 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/Mesh.hpp>
|
||||
#include <Nazara/Core/Error.hpp>
|
||||
#include <Nazara/Utility/Config.hpp>
|
||||
#include <Nazara/Utility/SubMesh.hpp>
|
||||
#include <cstring>
|
||||
#include <deque>
|
||||
#include <Nazara/Utility/Debug.hpp>
|
||||
|
||||
bool NzMeshParams::IsValid() const
|
||||
{
|
||||
if (!animation.IsValid())
|
||||
{
|
||||
NazaraError("Invalid animation parameters");
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
struct NzMeshImpl
|
||||
{
|
||||
std::map<NzString, nzUInt8> subMeshMap;
|
||||
std::deque<NzString> skins;
|
||||
std::vector<NzSubMesh*> subMeshes;
|
||||
nzAnimationType animationType;
|
||||
const NzAnimation* animation = nullptr;
|
||||
};
|
||||
|
||||
NzMesh::~NzMesh()
|
||||
{
|
||||
Destroy();
|
||||
}
|
||||
|
||||
unsigned int NzMesh::AddSkin(const NzString& skin, bool setDefault)
|
||||
{
|
||||
#if NAZARA_UTILITY_SAFE
|
||||
if (!m_impl)
|
||||
{
|
||||
NazaraError("Mesh not created");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (skin.IsEmpty())
|
||||
{
|
||||
NazaraError("Skin is empty");
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (setDefault)
|
||||
m_impl->skins.push_front(skin);
|
||||
else
|
||||
m_impl->skins.push_back(skin);
|
||||
|
||||
return m_impl->skins.size()-1;
|
||||
}
|
||||
|
||||
nzUInt8 NzMesh::AddSubMesh(NzSubMesh* subMesh)
|
||||
{
|
||||
#if NAZARA_UTILITY_SAFE
|
||||
if (!m_impl)
|
||||
{
|
||||
NazaraError("Mesh not created");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!subMesh)
|
||||
{
|
||||
NazaraError("Invalid submesh");
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
subMesh->AddResourceReference();
|
||||
m_impl->subMeshes.push_back(subMesh);
|
||||
|
||||
return m_impl->subMeshes.size()-1;
|
||||
}
|
||||
|
||||
nzUInt8 NzMesh::AddSubMesh(const NzString& identifier, NzSubMesh* subMesh)
|
||||
{
|
||||
#if NAZARA_UTILITY_SAFE
|
||||
if (!m_impl)
|
||||
{
|
||||
NazaraError("Mesh not created");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (identifier.IsEmpty())
|
||||
{
|
||||
NazaraError("Identifier is empty");
|
||||
return 0;
|
||||
}
|
||||
|
||||
auto it = m_impl->subMeshMap.find(identifier);
|
||||
if (it != m_impl->subMeshMap.end())
|
||||
{
|
||||
NazaraError("SubMesh identifier \"" + identifier + "\" is already used");
|
||||
return it->second;
|
||||
}
|
||||
|
||||
if (!subMesh)
|
||||
{
|
||||
NazaraError("Invalid submesh");
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
nzUInt8 index = m_impl->subMeshes.size();
|
||||
|
||||
subMesh->AddResourceReference();
|
||||
|
||||
m_impl->subMeshes.push_back(subMesh);
|
||||
m_impl->subMeshMap[identifier] = index;
|
||||
|
||||
return index;
|
||||
}
|
||||
|
||||
void NzMesh::Animate(unsigned int frameA, unsigned int frameB, float interpolation)
|
||||
{
|
||||
#if NAZARA_UTILITY_SAFE
|
||||
if (!m_impl)
|
||||
{
|
||||
NazaraError("Mesh not created");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!m_impl->animation)
|
||||
{
|
||||
NazaraError("Mesh has no animation");
|
||||
return;
|
||||
}
|
||||
|
||||
unsigned int frameCount = m_impl->animation->GetFrameCount();
|
||||
if (frameA >= frameCount)
|
||||
{
|
||||
NazaraError("Frame A is out of range (" + NzString::Number(frameA) + " >= " + NzString::Number(frameCount) + ')');
|
||||
return;
|
||||
}
|
||||
|
||||
if (frameB >= frameCount)
|
||||
{
|
||||
NazaraError("Frame B is out of range (" + NzString::Number(frameB) + " >= " + NzString::Number(frameCount) + ')');
|
||||
return;
|
||||
}
|
||||
|
||||
if (interpolation < 0.f || interpolation > 1.f)
|
||||
{
|
||||
NazaraError("Interpolation must be in range [0..1] (Got " + NzString::Number(interpolation) + ')');
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
for (NzSubMesh* subMesh : m_impl->subMeshes)
|
||||
subMesh->AnimateImpl(frameA, frameB, interpolation);
|
||||
}
|
||||
|
||||
bool NzMesh::Create(nzAnimationType type)
|
||||
{
|
||||
Destroy();
|
||||
|
||||
m_impl = new NzMeshImpl;
|
||||
m_impl->animationType = type;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void NzMesh::Destroy()
|
||||
{
|
||||
if (m_impl)
|
||||
{
|
||||
if (m_impl->animation)
|
||||
m_impl->animation->RemoveResourceReference();
|
||||
|
||||
for (NzSubMesh* subMesh : m_impl->subMeshes)
|
||||
subMesh->RemoveResourceReference();
|
||||
|
||||
delete m_impl;
|
||||
m_impl = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
const NzAnimation* NzMesh::GetAnimation() const
|
||||
{
|
||||
#if NAZARA_UTILITY_SAFE
|
||||
if (!m_impl)
|
||||
{
|
||||
NazaraError("Mesh not created");
|
||||
return nullptr;
|
||||
}
|
||||
#endif
|
||||
|
||||
return m_impl->animation;
|
||||
}
|
||||
|
||||
nzAnimationType NzMesh::GetAnimationType() const
|
||||
{
|
||||
#if NAZARA_UTILITY_SAFE
|
||||
if (!m_impl)
|
||||
{
|
||||
NazaraError("Mesh not created");
|
||||
return nzAnimationType_Static;
|
||||
}
|
||||
#endif
|
||||
|
||||
return m_impl->animationType;
|
||||
}
|
||||
|
||||
unsigned int NzMesh::GetFrameCount() const
|
||||
{
|
||||
#if NAZARA_UTILITY_SAFE
|
||||
if (!m_impl)
|
||||
{
|
||||
NazaraError("Mesh not created");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!m_impl->animation)
|
||||
{
|
||||
NazaraError("Mesh has no animation");
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
return m_impl->animation->GetFrameCount();
|
||||
}
|
||||
|
||||
NzString NzMesh::GetSkin(unsigned int index) const
|
||||
{
|
||||
#if NAZARA_UTILITY_SAFE
|
||||
if (!m_impl)
|
||||
{
|
||||
NazaraError("Mesh not created");
|
||||
return NzString();
|
||||
}
|
||||
|
||||
if (index >= m_impl->skins.size())
|
||||
{
|
||||
NazaraError("Skin index out of range (" + NzString::Number(index) + " >= " + NzString::Number(m_impl->skins.size()) + ')');
|
||||
return NzString();
|
||||
}
|
||||
#endif
|
||||
|
||||
return m_impl->skins[index];
|
||||
}
|
||||
|
||||
unsigned int NzMesh::GetSkinCount() const
|
||||
{
|
||||
#if NAZARA_UTILITY_SAFE
|
||||
if (!m_impl)
|
||||
{
|
||||
NazaraError("Mesh not created");
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
return m_impl->skins.size();
|
||||
}
|
||||
|
||||
NzSubMesh* NzMesh::GetSubMesh(const NzString& identifier)
|
||||
{
|
||||
#if NAZARA_UTILITY_SAFE
|
||||
if (!m_impl)
|
||||
{
|
||||
NazaraError("Mesh not created");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
auto it = m_impl->subMeshMap.find(identifier);
|
||||
if (it == m_impl->subMeshMap.end())
|
||||
{
|
||||
NazaraError("SubMesh not found");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return m_impl->subMeshes[it->second];
|
||||
#else
|
||||
return m_impl->subMeshes[m_impl->subMeshMap[identifier]];
|
||||
#endif
|
||||
}
|
||||
|
||||
NzSubMesh* NzMesh::GetSubMesh(nzUInt8 index)
|
||||
{
|
||||
#if NAZARA_UTILITY_SAFE
|
||||
if (!m_impl)
|
||||
{
|
||||
NazaraError("Mesh not created");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (index >= m_impl->subMeshes.size())
|
||||
{
|
||||
NazaraError("SubMesh index out of range (" + NzString::Number(index) + " >= " + NzString::Number(m_impl->subMeshes.size()) + ')');
|
||||
return nullptr;
|
||||
}
|
||||
#endif
|
||||
|
||||
return m_impl->subMeshes[index];
|
||||
}
|
||||
|
||||
const NzSubMesh* NzMesh::GetSubMesh(const NzString& identifier) const
|
||||
{
|
||||
#if NAZARA_UTILITY_SAFE
|
||||
if (!m_impl)
|
||||
{
|
||||
NazaraError("Mesh not created");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
auto it = m_impl->subMeshMap.find(identifier);
|
||||
if (it == m_impl->subMeshMap.end())
|
||||
{
|
||||
NazaraError("SubMesh not found");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return m_impl->subMeshes[it->second];
|
||||
#else
|
||||
return m_impl->subMeshes[m_impl->subMeshMap[identifier]];
|
||||
#endif
|
||||
}
|
||||
|
||||
const NzSubMesh* NzMesh::GetSubMesh(nzUInt8 index) const
|
||||
{
|
||||
#if NAZARA_UTILITY_SAFE
|
||||
if (!m_impl)
|
||||
{
|
||||
NazaraError("Mesh not created");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (index >= m_impl->subMeshes.size())
|
||||
{
|
||||
NazaraError("SubMesh index out of range (" + NzString::Number(index) + " >= " + NzString::Number(m_impl->subMeshes.size()) + ')');
|
||||
return nullptr;
|
||||
}
|
||||
#endif
|
||||
|
||||
return m_impl->subMeshes[index];
|
||||
}
|
||||
|
||||
nzUInt8 NzMesh::GetSubMeshCount() const
|
||||
{
|
||||
#if NAZARA_UTILITY_SAFE
|
||||
if (!m_impl)
|
||||
{
|
||||
NazaraError("Mesh not created");
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
return m_impl->subMeshes.size();
|
||||
}
|
||||
|
||||
unsigned int NzMesh::GetVertexCount() const
|
||||
{
|
||||
#if NAZARA_UTILITY_SAFE
|
||||
if (!m_impl)
|
||||
{
|
||||
NazaraError("Mesh not created");
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
unsigned int vertexCount = 0;
|
||||
for (NzSubMesh* subMesh : m_impl->subMeshes)
|
||||
vertexCount += subMesh->GetVertexCount();
|
||||
|
||||
return vertexCount;
|
||||
}
|
||||
|
||||
bool NzMesh::HasAnimation() const
|
||||
{
|
||||
#if NAZARA_UTILITY_SAFE
|
||||
if (!m_impl)
|
||||
{
|
||||
NazaraError("Mesh not created");
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
return m_impl->animation != nullptr;
|
||||
}
|
||||
|
||||
bool NzMesh::HasSkin(unsigned int index) const
|
||||
{
|
||||
#if NAZARA_UTILITY_SAFE
|
||||
if (!m_impl)
|
||||
{
|
||||
NazaraError("Mesh not created");
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
return m_impl->skins.size() > index;
|
||||
}
|
||||
|
||||
bool NzMesh::HasSubMesh(const NzString& identifier) const
|
||||
{
|
||||
#if NAZARA_UTILITY_SAFE
|
||||
if (!m_impl)
|
||||
{
|
||||
NazaraError("Mesh not created");
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
return m_impl->subMeshMap.find(identifier) != m_impl->subMeshMap.end();
|
||||
}
|
||||
|
||||
bool NzMesh::HasSubMesh(nzUInt8 index) const
|
||||
{
|
||||
#if NAZARA_UTILITY_SAFE
|
||||
if (!m_impl)
|
||||
{
|
||||
NazaraError("Mesh not created");
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
return index < m_impl->subMeshes.size();
|
||||
}
|
||||
|
||||
bool NzMesh::IsAnimable() const
|
||||
{
|
||||
#if NAZARA_UTILITY_SAFE
|
||||
if (!m_impl)
|
||||
{
|
||||
NazaraError("Mesh not created");
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
return m_impl->animationType != nzAnimationType_Static;
|
||||
}
|
||||
|
||||
bool NzMesh::IsValid() const
|
||||
{
|
||||
return m_impl != nullptr;
|
||||
}
|
||||
|
||||
bool NzMesh::LoadFromFile(const NzString& filePath, const NzMeshParams& params)
|
||||
{
|
||||
return NzMeshLoader::LoadFromFile(this, filePath, params);
|
||||
}
|
||||
|
||||
bool NzMesh::LoadFromMemory(const void* data, std::size_t size, const NzMeshParams& params)
|
||||
{
|
||||
return NzMeshLoader::LoadFromMemory(this, data, size, params);
|
||||
}
|
||||
|
||||
bool NzMesh::LoadFromStream(NzInputStream& stream, const NzMeshParams& params)
|
||||
{
|
||||
return NzMeshLoader::LoadFromStream(this, stream, params);
|
||||
}
|
||||
|
||||
void NzMesh::RemoveSkin(unsigned int index)
|
||||
{
|
||||
#if NAZARA_UTILITY_SAFE
|
||||
if (!m_impl)
|
||||
{
|
||||
NazaraError("Mesh not created");
|
||||
return;
|
||||
}
|
||||
|
||||
if (m_impl->skins.size() <= index)
|
||||
{
|
||||
NazaraError("Skin index out of range (" + NzString::Number(index) + " >= " + NzString::Number(m_impl->skins.size()) + ')');
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
auto it = m_impl->skins.begin();
|
||||
std::advance(it, index);
|
||||
|
||||
m_impl->skins.erase(it);
|
||||
}
|
||||
|
||||
void NzMesh::RemoveSubMesh(const NzString& identifier)
|
||||
{
|
||||
#if NAZARA_UTILITY_SAFE
|
||||
if (!m_impl)
|
||||
{
|
||||
NazaraError("Mesh not created");
|
||||
return;
|
||||
}
|
||||
|
||||
auto it = m_impl->subMeshMap.find(identifier);
|
||||
if (it == m_impl->subMeshMap.end())
|
||||
{
|
||||
NazaraError("SubMesh not found");
|
||||
return;
|
||||
}
|
||||
|
||||
unsigned int index = it->second;
|
||||
#else
|
||||
unsigned int index = m_impl->subMeshMap[identifier];
|
||||
#endif
|
||||
|
||||
auto it2 = m_impl->subMeshes.begin();
|
||||
std::advance(it2, index);
|
||||
|
||||
m_impl->subMeshes.erase(it2);
|
||||
}
|
||||
|
||||
void NzMesh::RemoveSubMesh(nzUInt8 index)
|
||||
{
|
||||
#if NAZARA_UTILITY_SAFE
|
||||
if (!m_impl)
|
||||
{
|
||||
NazaraError("Mesh not created");
|
||||
return;
|
||||
}
|
||||
|
||||
if (index >= m_impl->subMeshes.size())
|
||||
{
|
||||
NazaraError("SubMesh index out of range (" + NzString::Number(index) + " >= " + NzString::Number(m_impl->subMeshes.size()) + ')');
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
auto it = m_impl->subMeshes.begin();
|
||||
std::advance(it, index);
|
||||
|
||||
m_impl->subMeshes.erase(it);
|
||||
}
|
||||
|
||||
bool NzMesh::SetAnimation(const NzAnimation* animation)
|
||||
{
|
||||
#if NAZARA_UTILITY_SAFE
|
||||
if (!m_impl)
|
||||
{
|
||||
NazaraError("Mesh not created");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (m_impl->animationType == nzAnimationType_Static)
|
||||
{
|
||||
NazaraError("Static meshes cannot have animation");
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (animation == m_impl->animation)
|
||||
return true;
|
||||
|
||||
if (m_impl->animation)
|
||||
m_impl->animation->RemoveResourceReference();
|
||||
|
||||
if (animation)
|
||||
{
|
||||
#if NAZARA_UTILITY_SAFE
|
||||
if (animation->GetType() != m_impl->animationType)
|
||||
{
|
||||
NazaraError("Animation's type must match mesh animation type");
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
m_impl->animation = animation;
|
||||
m_impl->animation->AddResourceReference();
|
||||
}
|
||||
else
|
||||
m_impl->animation = nullptr;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
std::list<NzMeshLoader::MemoryLoader> NzMesh::s_memoryLoaders;
|
||||
std::list<NzMeshLoader::StreamLoader> NzMesh::s_streamLoaders;
|
||||
std::multimap<NzString, NzMeshLoader::LoadFileFunction> NzMesh::s_fileLoaders;
|
||||
@@ -1314,7 +1314,11 @@ 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));
|
||||
|
||||
for (unsigned int i = 0; i <= nzPixelFlipping_Max; ++i)
|
||||
s_flipFunctions[i].clear();
|
||||
}
|
||||
|
||||
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 ?
|
||||
std::map<nzPixelFormat, NzPixelFormat::FlipFunction> NzPixelFormat::s_flipFunctions[nzPixelFlipping_Max+1];
|
||||
|
||||
@@ -2,22 +2,12 @@
|
||||
// This file is part of the "Nazara Engine".
|
||||
// For conditions of distribution and use, see copyright notice in Config.hpp
|
||||
|
||||
#include <Nazara/Renderer/OpenGL.hpp>
|
||||
#include <Nazara/Renderer/SoftwareBuffer.hpp>
|
||||
#include <Nazara/Utility/SoftwareBuffer.hpp>
|
||||
#include <Nazara/Core/Error.hpp>
|
||||
#include <Nazara/Renderer/Config.hpp>
|
||||
#include <Nazara/Renderer/Context.hpp>
|
||||
#include <Nazara/Utility/Config.hpp>
|
||||
#include <cstring>
|
||||
#include <stdexcept>
|
||||
#include <Nazara/Renderer/Debug.hpp>
|
||||
|
||||
namespace
|
||||
{
|
||||
GLenum bufferTarget[] = {
|
||||
GL_ELEMENT_ARRAY_BUFFER, // nzBufferType_Index,
|
||||
GL_ARRAY_BUFFER, // nzBufferType_Vertex
|
||||
};
|
||||
}
|
||||
#include <Nazara/Utility/Debug.hpp>
|
||||
|
||||
NzSoftwareBuffer::NzSoftwareBuffer(NzBuffer* parent, nzBufferType type) :
|
||||
m_type(type)
|
||||
@@ -29,19 +19,6 @@ NzSoftwareBuffer::~NzSoftwareBuffer()
|
||||
{
|
||||
}
|
||||
|
||||
void NzSoftwareBuffer::Bind()
|
||||
{
|
||||
#ifdef NAZARA_DEBUG
|
||||
if (NzContext::GetCurrent() == nullptr)
|
||||
{
|
||||
NazaraError("No active context");
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
glBindBuffer(bufferTarget[m_type], 0);
|
||||
}
|
||||
|
||||
bool NzSoftwareBuffer::Create(unsigned int size, nzBufferUsage usage)
|
||||
{
|
||||
NazaraUnused(usage);
|
||||
@@ -69,7 +46,7 @@ void NzSoftwareBuffer::Destroy()
|
||||
|
||||
bool NzSoftwareBuffer::Fill(const void* data, unsigned int offset, unsigned int size)
|
||||
{
|
||||
#if NAZARA_RENDERER_SAFE
|
||||
#if NAZARA_UTILITY_SAFE
|
||||
if (m_mapped)
|
||||
{
|
||||
NazaraError("Buffer already mapped");
|
||||
@@ -82,7 +59,7 @@ bool NzSoftwareBuffer::Fill(const void* data, unsigned int offset, unsigned int
|
||||
return true;
|
||||
}
|
||||
|
||||
void* NzSoftwareBuffer::GetBufferPtr()
|
||||
void* NzSoftwareBuffer::GetPointer()
|
||||
{
|
||||
return m_buffer;
|
||||
}
|
||||
@@ -97,7 +74,7 @@ void* NzSoftwareBuffer::Map(nzBufferAccess access, unsigned int offset, unsigned
|
||||
NazaraUnused(access);
|
||||
NazaraUnused(size);
|
||||
|
||||
#if NAZARA_RENDERER_SAFE
|
||||
#if NAZARA_UTILITY_SAFE
|
||||
if (m_mapped)
|
||||
{
|
||||
NazaraError("Buffer already mapped");
|
||||
@@ -112,7 +89,7 @@ void* NzSoftwareBuffer::Map(nzBufferAccess access, unsigned int offset, unsigned
|
||||
|
||||
bool NzSoftwareBuffer::Unmap()
|
||||
{
|
||||
#if NAZARA_RENDERER_SAFE
|
||||
#if NAZARA_UTILITY_SAFE
|
||||
if (!m_mapped)
|
||||
{
|
||||
NazaraError("Buffer not mapped");
|
||||
@@ -8,7 +8,7 @@
|
||||
#define NAZARA_SOFTWAREBUFFER_HPP
|
||||
|
||||
#include <Nazara/Prerequesites.hpp>
|
||||
#include <Nazara/Renderer/BufferImpl.hpp>
|
||||
#include <Nazara/Utility/BufferImpl.hpp>
|
||||
|
||||
class NzSoftwareBuffer : public NzBufferImpl
|
||||
{
|
||||
@@ -16,18 +16,16 @@ class NzSoftwareBuffer : public NzBufferImpl
|
||||
NzSoftwareBuffer(NzBuffer* parent, nzBufferType type);
|
||||
~NzSoftwareBuffer();
|
||||
|
||||
void Bind();
|
||||
|
||||
bool Create(unsigned int size, nzBufferUsage usage = nzBufferUsage_Static);
|
||||
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* GetBufferPtr();
|
||||
void* GetPointer();
|
||||
|
||||
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();
|
||||
|
||||
private:
|
||||
141
src/Nazara/Utility/StaticMesh.cpp
Normal file
141
src/Nazara/Utility/StaticMesh.cpp
Normal file
@@ -0,0 +1,141 @@
|
||||
// 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/StaticMesh.hpp>
|
||||
#include <Nazara/Core/Error.hpp>
|
||||
#include <stdexcept>
|
||||
#include <Nazara/Utility/Debug.hpp>
|
||||
|
||||
NzStaticMesh::NzStaticMesh(const NzMesh* parent) :
|
||||
NzSubMesh(parent)
|
||||
{
|
||||
}
|
||||
|
||||
NzStaticMesh::NzStaticMesh(const NzMesh* parent, const NzVertexBuffer* vertexBuffer, const NzVertexDeclaration* vertexDeclaration, const NzIndexBuffer* indexBuffer) :
|
||||
NzSubMesh(parent)
|
||||
{
|
||||
#ifdef NAZARA_DEBUG
|
||||
if (!Create(vertexBuffer, vertexDeclaration, indexBuffer))
|
||||
{
|
||||
NazaraError("Failed to create mesh");
|
||||
throw std::runtime_error("Constructor failed");
|
||||
}
|
||||
#else
|
||||
Create(vertexBuffer, vertexDeclaration, indexBuffer);
|
||||
#endif
|
||||
}
|
||||
|
||||
NzStaticMesh::~NzStaticMesh()
|
||||
{
|
||||
Destroy();
|
||||
}
|
||||
|
||||
bool NzStaticMesh::Create(const NzVertexBuffer* vertexBuffer, const NzVertexDeclaration* vertexDeclaration, const NzIndexBuffer* indexBuffer)
|
||||
{
|
||||
Destroy();
|
||||
|
||||
#if NAZARA_UTILITY_SAFE
|
||||
if (!vertexBuffer)
|
||||
{
|
||||
NazaraError("Vertex buffer is null");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!vertexDeclaration)
|
||||
{
|
||||
NazaraError("Vertex declaration is null");
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (indexBuffer)
|
||||
{
|
||||
m_indexBuffer = indexBuffer;
|
||||
m_indexBuffer->AddResourceReference();
|
||||
}
|
||||
|
||||
m_vertexBuffer = vertexBuffer;
|
||||
m_vertexBuffer->AddResourceReference();
|
||||
|
||||
m_vertexDeclaration = vertexDeclaration;
|
||||
m_vertexDeclaration->AddResourceReference();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void NzStaticMesh::Destroy()
|
||||
{
|
||||
if (m_indexBuffer)
|
||||
{
|
||||
m_indexBuffer->RemoveResourceReference();
|
||||
m_indexBuffer = nullptr;
|
||||
}
|
||||
|
||||
if (m_vertexBuffer)
|
||||
{
|
||||
m_vertexBuffer->RemoveResourceReference();
|
||||
m_vertexBuffer = nullptr;
|
||||
}
|
||||
|
||||
if (m_vertexDeclaration)
|
||||
{
|
||||
m_vertexDeclaration->RemoveResourceReference();
|
||||
m_vertexDeclaration = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
nzAnimationType NzStaticMesh::GetAnimationType() const
|
||||
{
|
||||
return nzAnimationType_Static;
|
||||
}
|
||||
|
||||
unsigned int NzStaticMesh::GetFrameCount() const
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
const NzIndexBuffer* NzStaticMesh::GetIndexBuffer() const
|
||||
{
|
||||
return m_indexBuffer;
|
||||
}
|
||||
|
||||
nzPrimitiveType NzStaticMesh::GetPrimitiveType() const
|
||||
{
|
||||
return m_primitiveType;
|
||||
}
|
||||
|
||||
const NzVertexBuffer* NzStaticMesh::GetVertexBuffer() const
|
||||
{
|
||||
return m_vertexBuffer;
|
||||
}
|
||||
|
||||
const NzVertexDeclaration* NzStaticMesh::GetVertexDeclaration() const
|
||||
{
|
||||
return m_vertexDeclaration;
|
||||
}
|
||||
|
||||
bool NzStaticMesh::IsAnimated() const
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool NzStaticMesh::IsValid() const
|
||||
{
|
||||
return m_vertexBuffer != nullptr && m_vertexDeclaration != nullptr;
|
||||
}
|
||||
|
||||
void NzStaticMesh::SetPrimitiveType(nzPrimitiveType primitiveType)
|
||||
{
|
||||
m_primitiveType = primitiveType;
|
||||
}
|
||||
|
||||
void NzStaticMesh::AnimateImpl(unsigned int frameA, unsigned int frameB, float interpolation)
|
||||
{
|
||||
NazaraUnused(frameA);
|
||||
NazaraUnused(frameB);
|
||||
NazaraUnused(interpolation);
|
||||
|
||||
// Le safe mode est censé nous protéger de cet appel
|
||||
NazaraError("Static mesh have no animation, please enable safe mode");
|
||||
}
|
||||
68
src/Nazara/Utility/SubMesh.cpp
Normal file
68
src/Nazara/Utility/SubMesh.cpp
Normal file
@@ -0,0 +1,68 @@
|
||||
// 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/SubMesh.hpp>
|
||||
#include <Nazara/Core/Error.hpp>
|
||||
#include <Nazara/Core/String.hpp>
|
||||
#include <Nazara/Utility/Config.hpp>
|
||||
#include <Nazara/Utility/Mesh.hpp>
|
||||
#include <stdexcept>
|
||||
#include <Nazara/Utility/Debug.hpp>
|
||||
|
||||
NzSubMesh::NzSubMesh(const NzMesh* parent) :
|
||||
NzResource(false), // Un SubMesh n'est pas persistant par défaut
|
||||
m_parent(parent)
|
||||
{
|
||||
#if NAZARA_DEBUG
|
||||
if (!m_parent)
|
||||
{
|
||||
NazaraError("Parent mesh is null");
|
||||
throw std::invalid_argument("Parent mesh must be valid");
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
NzSubMesh::~NzSubMesh() = default;
|
||||
|
||||
void NzSubMesh::Animate(unsigned int frameA, unsigned int frameB, float interpolation)
|
||||
{
|
||||
#if NAZARA_UTILITY_SAFE
|
||||
if (!m_parent->HasAnimation())
|
||||
{
|
||||
NazaraError("SubMesh is not animated");
|
||||
return;
|
||||
}
|
||||
|
||||
unsigned int frameCount = m_parent->GetFrameCount();
|
||||
if (frameA >= frameCount)
|
||||
{
|
||||
NazaraError("Frame A is out of range (" + NzString::Number(frameA) + " >= " + NzString::Number(frameCount) + ')');
|
||||
return;
|
||||
}
|
||||
|
||||
if (frameB >= frameCount)
|
||||
{
|
||||
NazaraError("Frame B is out of range (" + NzString::Number(frameB) + " >= " + NzString::Number(frameCount) + ')');
|
||||
return;
|
||||
}
|
||||
|
||||
if (interpolation < 0.f || interpolation > 1.f)
|
||||
{
|
||||
NazaraError("Interpolation must be in range [0..1] (Got " + NzString::Number(interpolation) + ')');
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
AnimateImpl(frameA, frameB, interpolation);
|
||||
}
|
||||
|
||||
const NzMesh* NzSubMesh::GetParent() const
|
||||
{
|
||||
return m_parent;
|
||||
}
|
||||
|
||||
unsigned int NzSubMesh::GetVertexCount() const
|
||||
{
|
||||
return GetVertexBuffer()->GetVertexCount();
|
||||
}
|
||||
@@ -4,7 +4,9 @@
|
||||
|
||||
#include <Nazara/Utility/Utility.hpp>
|
||||
#include <Nazara/Core/Error.hpp>
|
||||
#include <Nazara/Utility/Buffer.hpp>
|
||||
#include <Nazara/Utility/Config.hpp>
|
||||
#include <Nazara/Utility/Loaders/MD2.hpp>
|
||||
#include <Nazara/Utility/Loaders/PCX.hpp>
|
||||
#include <Nazara/Utility/Loaders/STB.hpp>
|
||||
#include <Nazara/Utility/PixelFormat.hpp>
|
||||
@@ -31,9 +33,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 +53,15 @@ bool NzUtility::Initialize()
|
||||
return false;
|
||||
}
|
||||
|
||||
// Loaders spécialisés
|
||||
/// Loaders spécialisés
|
||||
// Mesh
|
||||
NzLoaders_MD2_Register(); // Loader de fichiers .MD2 (v8)
|
||||
|
||||
// Image
|
||||
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)
|
||||
// Image
|
||||
NzLoaders_STB_Register(); // Loader générique (STB)
|
||||
|
||||
s_initialized = true;
|
||||
@@ -66,12 +79,13 @@ void NzUtility::Uninitialize()
|
||||
}
|
||||
#endif
|
||||
|
||||
NzLoaders_STB_Unregister();
|
||||
NzLoaders_MD2_Unregister();
|
||||
NzLoaders_PCX_Unregister();
|
||||
NzLoaders_STB_Unregister();
|
||||
|
||||
NzWindow::Uninitialize();
|
||||
|
||||
NzPixelFormat::Uninitialize();
|
||||
NzBuffer::Uninitialize();
|
||||
|
||||
s_initialized = false;
|
||||
}
|
||||
|
||||
@@ -2,9 +2,10 @@
|
||||
// This file is part of the "Nazara Engine".
|
||||
// For conditions of distribution and use, see copyright notice in Config.hpp
|
||||
|
||||
#include <Nazara/Renderer/VertexBuffer.hpp>
|
||||
#include <Nazara/Utility/VertexBuffer.hpp>
|
||||
#include <Nazara/Core/Error.hpp>
|
||||
#include <Nazara/Renderer/Debug.hpp>
|
||||
#include <stdexcept>
|
||||
#include <Nazara/Utility/Debug.hpp>
|
||||
|
||||
NzVertexBuffer::NzVertexBuffer(NzBuffer* buffer, unsigned int startVertex, unsigned int vertexCount) :
|
||||
m_buffer(buffer),
|
||||
@@ -12,27 +13,38 @@ m_ownsBuffer(false),
|
||||
m_startVertex(startVertex),
|
||||
m_vertexCount(vertexCount)
|
||||
{
|
||||
#ifdef NAZARA_DEBUG
|
||||
if (!m_buffer)
|
||||
{
|
||||
NazaraError("Buffer is null");
|
||||
throw std::invalid_argument("Buffer must be valid");
|
||||
}
|
||||
#endif
|
||||
|
||||
m_buffer->AddResourceReference();
|
||||
}
|
||||
|
||||
NzVertexBuffer::NzVertexBuffer(unsigned int length, nzUInt8 typeSize, nzBufferUsage usage) :
|
||||
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, usage);
|
||||
m_buffer = new NzBuffer(nzBufferType_Vertex, length, typeSize, storage, usage);
|
||||
m_buffer->AddResourceReference();
|
||||
m_buffer->SetPersistent(false);
|
||||
}
|
||||
|
||||
NzVertexBuffer::NzVertexBuffer(const NzVertexBuffer& vertexBuffer) :
|
||||
NzResource(true),
|
||||
m_ownsBuffer(vertexBuffer.m_ownsBuffer),
|
||||
m_startVertex(vertexBuffer.m_startVertex),
|
||||
m_vertexCount(vertexBuffer.m_vertexCount)
|
||||
{
|
||||
if (m_ownsBuffer)
|
||||
{
|
||||
m_buffer = new NzBuffer(nzBufferType_Vertex, vertexBuffer.m_buffer->GetLength(), vertexBuffer.m_buffer->GetSize(), vertexBuffer.m_buffer->GetUsage());
|
||||
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);
|
||||
@@ -51,7 +63,7 @@ NzVertexBuffer::~NzVertexBuffer()
|
||||
|
||||
bool NzVertexBuffer::Fill(const void* data, unsigned int offset, unsigned int length)
|
||||
{
|
||||
#if NAZARA_RENDERER_SAFE
|
||||
#if NAZARA_UTILITY_SAFE
|
||||
if (offset+length > m_vertexCount)
|
||||
{
|
||||
NazaraError("Exceeding virtual buffer size");
|
||||
@@ -67,14 +79,14 @@ NzBuffer* NzVertexBuffer::GetBuffer() const
|
||||
return m_buffer;
|
||||
}
|
||||
|
||||
void* NzVertexBuffer::GetBufferPtr()
|
||||
void* NzVertexBuffer::GetPointer()
|
||||
{
|
||||
return reinterpret_cast<nzUInt8*>(m_buffer->GetBufferPtr()) + m_startVertex*m_buffer->GetTypeSize();
|
||||
return reinterpret_cast<nzUInt8*>(m_buffer->GetPointer()) + m_startVertex*m_buffer->GetTypeSize();
|
||||
}
|
||||
|
||||
const void* NzVertexBuffer::GetBufferPtr() const
|
||||
const void* NzVertexBuffer::GetPointer() const
|
||||
{
|
||||
return reinterpret_cast<const nzUInt8*>(m_buffer->GetBufferPtr()) + m_startVertex*m_buffer->GetTypeSize();
|
||||
return reinterpret_cast<const nzUInt8*>(m_buffer->GetPointer()) + m_startVertex*m_buffer->GetTypeSize();
|
||||
}
|
||||
|
||||
unsigned int NzVertexBuffer::GetStartVertex() const
|
||||
@@ -99,7 +111,7 @@ bool NzVertexBuffer::IsHardware() const
|
||||
|
||||
void* NzVertexBuffer::Map(nzBufferAccess access, unsigned int offset, unsigned int length)
|
||||
{
|
||||
#if NAZARA_RENDERER_SAFE
|
||||
#if NAZARA_UTILITY_SAFE
|
||||
if (offset+length > m_vertexCount)
|
||||
{
|
||||
NazaraError("Exceeding virtual buffer size");
|
||||
@@ -110,6 +122,11 @@ void* NzVertexBuffer::Map(nzBufferAccess access, unsigned int offset, unsigned i
|
||||
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()
|
||||
{
|
||||
return m_buffer->Unmap();
|
||||
346
src/Nazara/Utility/VertexDeclaration.cpp
Normal file
346
src/Nazara/Utility/VertexDeclaration.cpp
Normal file
@@ -0,0 +1,346 @@
|
||||
// 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 <algorithm>
|
||||
#include <cstring>
|
||||
#include <stdexcept>
|
||||
#include <vector>
|
||||
|
||||
#if NAZARA_THREADSAFETY_VERTEXDECLARATION
|
||||
#include <Nazara/Core/ThreadSafety.hpp>
|
||||
#else
|
||||
#include <Nazara/Core/ThreadSafetyOff.hpp>
|
||||
#endif
|
||||
|
||||
#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 VertexElementCompare(const NzVertexElement& elementA, const NzVertexElement& elementB)
|
||||
{
|
||||
// Nous classons d'abord par stream
|
||||
if (elementA.stream == elementB.stream)
|
||||
{
|
||||
// Ensuite par usage
|
||||
if (elementA.usage == elementB.usage)
|
||||
// Et finalement par usageIndex
|
||||
return elementA.usageIndex < elementB.usageIndex;
|
||||
else
|
||||
return elementA.usage < elementB.usage;
|
||||
}
|
||||
else
|
||||
return elementA.stream < elementB.stream;
|
||||
}
|
||||
}
|
||||
|
||||
struct NzVertexDeclarationImpl
|
||||
{
|
||||
std::vector<NzVertexElement> elements;
|
||||
int elementPos[nzElementStream_Max+1][nzElementUsage_Max+1];
|
||||
int streamPos[nzElementStream_Max+1];
|
||||
unsigned int stride[nzElementStream_Max+1] = {0};
|
||||
|
||||
unsigned short refCount;
|
||||
NazaraMutex(mutex)
|
||||
};
|
||||
|
||||
NzVertexDeclaration::NzVertexDeclaration(const NzVertexElement* elements, unsigned int elementCount)
|
||||
{
|
||||
#ifdef NAZARA_DEBUG
|
||||
if (!Create(elements, elementCount))
|
||||
{
|
||||
NazaraError("Failed to create declaration");
|
||||
throw std::runtime_error("Constructor failed");
|
||||
}
|
||||
#else
|
||||
Create(elements, elementCount);
|
||||
#endif
|
||||
}
|
||||
|
||||
NzVertexDeclaration::NzVertexDeclaration(const NzVertexDeclaration& declaration) :
|
||||
NzResource(),
|
||||
m_sharedImpl(declaration.m_sharedImpl)
|
||||
{
|
||||
if (m_sharedImpl)
|
||||
{
|
||||
NazaraMutexLock(m_sharedImpl->mutex);
|
||||
m_sharedImpl->refCount++;
|
||||
NazaraMutexUnlock(m_sharedImpl->mutex);
|
||||
}
|
||||
}
|
||||
|
||||
NzVertexDeclaration::NzVertexDeclaration(NzVertexDeclaration&& declaration) :
|
||||
m_sharedImpl(declaration.m_sharedImpl)
|
||||
{
|
||||
declaration.m_sharedImpl = nullptr;
|
||||
}
|
||||
|
||||
NzVertexDeclaration::~NzVertexDeclaration()
|
||||
{
|
||||
Destroy();
|
||||
}
|
||||
|
||||
bool NzVertexDeclaration::Create(const NzVertexElement* elements, unsigned int elementCount)
|
||||
{
|
||||
Destroy();
|
||||
|
||||
#if NAZARA_UTILITY_SAFE
|
||||
if (!elements || elementCount == 0)
|
||||
{
|
||||
NazaraError("No element");
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
NzVertexDeclarationImpl* impl = new NzVertexDeclarationImpl;
|
||||
std::memset(&impl->elementPos, -1, (nzElementStream_Max+1)*(nzElementUsage_Max+1)*sizeof(int));
|
||||
std::memset(&impl->streamPos, -1, (nzElementStream_Max+1)*sizeof(int));
|
||||
|
||||
// On copie et trie les éléments
|
||||
impl->elements.resize(elementCount);
|
||||
std::memcpy(&impl->elements[0], elements, elementCount*sizeof(NzVertexElement));
|
||||
std::sort(impl->elements.begin(), impl->elements.end(), VertexElementCompare);
|
||||
|
||||
for (unsigned int i = 0; i < elementCount; ++i)
|
||||
{
|
||||
NzVertexElement& current = impl->elements[i];
|
||||
#if NAZARA_UTILITY_SAFE
|
||||
// Notre tableau étant trié, s'il y a collision, les deux éléments identiques se suivent...
|
||||
if (i > 0)
|
||||
{
|
||||
NzVertexElement& previous = impl->elements[i-1]; // On accède à l'élément précédent
|
||||
if (previous.usage == current.usage && previous.usageIndex == current.usageIndex && previous.stream == current.stream)
|
||||
{
|
||||
// Les deux éléments sont identiques là où ils ne devraient pas, nous avons une collision...
|
||||
NazaraError("Element usage 0x" + NzString::Number(current.usage, 16) + " collision with usage index " + NzString::Number(current.usageIndex) + " on stream 0x" + NzString::Number(current.stream, 16));
|
||||
delete impl;
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if (current.usageIndex == 0)
|
||||
impl->elementPos[current.stream][current.usage] = i;
|
||||
|
||||
if (impl->streamPos[current.stream] == -1)
|
||||
impl->streamPos[current.stream] = i; // Premier élément du stream (via le triage)
|
||||
|
||||
impl->stride[current.stream] += size[current.type];
|
||||
}
|
||||
|
||||
#if NAZARA_RENDERER_FORCE_DECLARATION_STRIDE_MULTIPLE_OF_32
|
||||
for (unsigned int& stride : impl->stride)
|
||||
stride = ((static_cast<int>(stride)-1)/32+1)*32;
|
||||
#endif
|
||||
|
||||
m_sharedImpl = impl;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void NzVertexDeclaration::Destroy()
|
||||
{
|
||||
if (!m_sharedImpl)
|
||||
return;
|
||||
|
||||
NazaraMutexLock(m_sharedImpl->mutex);
|
||||
bool freeSharedImpl = (--m_sharedImpl->refCount == 0);
|
||||
NazaraMutexUnlock(m_sharedImpl->mutex);
|
||||
|
||||
if (freeSharedImpl)
|
||||
delete m_sharedImpl;
|
||||
|
||||
m_sharedImpl = nullptr;
|
||||
}
|
||||
|
||||
const NzVertexElement* NzVertexDeclaration::GetElement(unsigned int i) const
|
||||
{
|
||||
#if NAZARA_UTILITY_SAFE
|
||||
if (!m_sharedImpl)
|
||||
{
|
||||
NazaraError("Declaration not created");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (i >= m_sharedImpl->elements.size())
|
||||
{
|
||||
NazaraError("Element index out of range (" + NzString::Number(i) + " >= " + NzString::Number(m_sharedImpl->elements.size()) + ')');
|
||||
return nullptr;
|
||||
}
|
||||
#endif
|
||||
|
||||
return &m_sharedImpl->elements[i];
|
||||
}
|
||||
|
||||
const NzVertexElement* NzVertexDeclaration::GetElement(nzElementStream stream, unsigned int i) const
|
||||
{
|
||||
#if NAZARA_UTILITY_SAFE
|
||||
if (!m_sharedImpl)
|
||||
{
|
||||
NazaraError("Declaration not created");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
int streamPos = m_sharedImpl->streamPos[stream];
|
||||
if (streamPos == -1)
|
||||
{
|
||||
NazaraError("Declaration has no stream 0x" + NzString::Number(stream, 16));
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
unsigned int upperLimit = GetElementCount(stream);
|
||||
if (i >= upperLimit)
|
||||
{
|
||||
NazaraError("Element index out of range (" + NzString::Number(i) + " >= " + NzString::Number(upperLimit) + ')');
|
||||
return nullptr;
|
||||
}
|
||||
#endif
|
||||
|
||||
return &m_sharedImpl->elements[m_sharedImpl->streamPos[stream]+i];
|
||||
}
|
||||
|
||||
const NzVertexElement* NzVertexDeclaration::GetElement(nzElementStream stream, nzElementUsage usage, unsigned int usageIndex) const
|
||||
{
|
||||
#if NAZARA_UTILITY_SAFE
|
||||
if (!m_sharedImpl)
|
||||
{
|
||||
NazaraError("Declaration not created");
|
||||
return nullptr;
|
||||
}
|
||||
#endif
|
||||
|
||||
int elementPos = m_sharedImpl->elementPos[stream][usage];
|
||||
if (elementPos == -1)
|
||||
return nullptr;
|
||||
|
||||
elementPos += usageIndex;
|
||||
if (static_cast<unsigned int>(elementPos) >= m_sharedImpl->elements.size())
|
||||
return nullptr;
|
||||
|
||||
NzVertexElement& element = m_sharedImpl->elements[elementPos];
|
||||
if (element.stream != stream || element.usage != usage || element.usageIndex != usageIndex)
|
||||
return nullptr;
|
||||
|
||||
return &element;
|
||||
}
|
||||
|
||||
unsigned int NzVertexDeclaration::GetElementCount() const
|
||||
{
|
||||
#if NAZARA_UTILITY_SAFE
|
||||
if (!m_sharedImpl)
|
||||
{
|
||||
NazaraError("Declaration not created");
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
return m_sharedImpl->elements.size();
|
||||
}
|
||||
|
||||
unsigned int NzVertexDeclaration::GetElementCount(nzElementStream stream) const
|
||||
{
|
||||
#if NAZARA_UTILITY_SAFE
|
||||
if (!m_sharedImpl)
|
||||
{
|
||||
NazaraError("Declaration not created");
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
int streamPos = m_sharedImpl->streamPos[stream];
|
||||
if (streamPos == -1)
|
||||
return 0;
|
||||
|
||||
unsigned int upperLimit = 0;
|
||||
if (stream == nzElementStream_Max)
|
||||
upperLimit = m_sharedImpl->elements.size();
|
||||
else
|
||||
{
|
||||
for (unsigned int upperStream = stream+1; upperStream <= nzElementStream_Max; ++upperStream)
|
||||
{
|
||||
if (m_sharedImpl->streamPos[upperStream] != -1)
|
||||
{
|
||||
upperLimit = m_sharedImpl->streamPos[upperStream];
|
||||
break;
|
||||
}
|
||||
else if (upperStream == nzElementStream_Max) // Dernier stream, toujours pas de limite
|
||||
upperLimit = m_sharedImpl->elements.size();
|
||||
}
|
||||
}
|
||||
|
||||
return upperLimit-streamPos;
|
||||
}
|
||||
|
||||
unsigned int NzVertexDeclaration::GetStride(nzElementStream stream) const
|
||||
{
|
||||
#if NAZARA_UTILITY_SAFE
|
||||
if (!m_sharedImpl)
|
||||
{
|
||||
NazaraError("Declaration not created");
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
return m_sharedImpl->stride[stream];
|
||||
}
|
||||
|
||||
bool NzVertexDeclaration::HasStream(nzElementStream stream) const
|
||||
{
|
||||
#if NAZARA_UTILITY_SAFE
|
||||
if (!m_sharedImpl)
|
||||
{
|
||||
NazaraError("Declaration not created");
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
return m_sharedImpl->streamPos[stream] != -1;
|
||||
}
|
||||
|
||||
bool NzVertexDeclaration::IsValid() const
|
||||
{
|
||||
return m_sharedImpl != nullptr;
|
||||
}
|
||||
|
||||
NzVertexDeclaration& NzVertexDeclaration::operator=(const NzVertexDeclaration& declaration)
|
||||
{
|
||||
Destroy();
|
||||
|
||||
m_sharedImpl = declaration.m_sharedImpl;
|
||||
if (m_sharedImpl)
|
||||
{
|
||||
NazaraMutexLock(m_sharedImpl->mutex);
|
||||
m_sharedImpl->refCount++;
|
||||
NazaraMutexUnlock(m_sharedImpl->mutex);
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
NzVertexDeclaration& NzVertexDeclaration::operator=(NzVertexDeclaration&& declaration)
|
||||
{
|
||||
Destroy();
|
||||
|
||||
m_sharedImpl = declaration.m_sharedImpl;
|
||||
declaration.m_sharedImpl = nullptr;
|
||||
|
||||
return *this;
|
||||
}
|
||||
52
src/Nazara/Utility/Win32/CursorImpl.cpp
Normal file
52
src/Nazara/Utility/Win32/CursorImpl.cpp
Normal file
@@ -0,0 +1,52 @@
|
||||
// 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/Win32/CursorImpl.hpp>
|
||||
#include <Nazara/Core/Error.hpp>
|
||||
#include <Nazara/Utility/Image.hpp>
|
||||
#include <Nazara/Utility/Debug.hpp>
|
||||
|
||||
bool NzCursorImpl::Create(const NzImage& cursor, int hotSpotX, int hotSpotY)
|
||||
{
|
||||
NzImage windowsCursor(cursor);
|
||||
if (!windowsCursor.Convert(nzPixelFormat_BGRA8))
|
||||
{
|
||||
NazaraError("Failed to convert cursor to BGRA8");
|
||||
return false;
|
||||
}
|
||||
|
||||
HBITMAP bitmap = CreateBitmap(windowsCursor.GetWidth(), windowsCursor.GetHeight(), 1, 32, windowsCursor.GetConstPixels());
|
||||
HBITMAP monoBitmap = CreateBitmap(windowsCursor.GetWidth(), windowsCursor.GetHeight(), 1, 1, nullptr);
|
||||
|
||||
// http://msdn.microsoft.com/en-us/library/windows/desktop/ms648052(v=vs.85).aspx
|
||||
ICONINFO iconInfo;
|
||||
iconInfo.fIcon = FALSE;
|
||||
iconInfo.xHotspot = hotSpotX;
|
||||
iconInfo.yHotspot = hotSpotY;
|
||||
iconInfo.hbmMask = monoBitmap;
|
||||
iconInfo.hbmColor = bitmap;
|
||||
|
||||
m_cursor = CreateIconIndirect(&iconInfo);
|
||||
|
||||
DeleteObject(bitmap);
|
||||
DeleteObject(monoBitmap);
|
||||
|
||||
if (!m_cursor)
|
||||
{
|
||||
NazaraError("Failed to create cursor: " + NzGetLastSystemError());
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void NzCursorImpl::Destroy()
|
||||
{
|
||||
DestroyIcon(m_cursor);
|
||||
}
|
||||
|
||||
HCURSOR NzCursorImpl::GetCursor()
|
||||
{
|
||||
return m_cursor;
|
||||
}
|
||||
26
src/Nazara/Utility/Win32/CursorImpl.hpp
Normal file
26
src/Nazara/Utility/Win32/CursorImpl.hpp
Normal file
@@ -0,0 +1,26 @@
|
||||
// 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_CURSORIMPL_HPP
|
||||
#define NAZARA_CURSORIMPL_HPP
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
class NzImage;
|
||||
|
||||
class NzCursorImpl
|
||||
{
|
||||
public:
|
||||
bool Create(const NzImage& image, int hotSpotX, int hotSpotY);
|
||||
void Destroy();
|
||||
|
||||
HCURSOR GetCursor();
|
||||
|
||||
private:
|
||||
HICON m_cursor = nullptr;
|
||||
};
|
||||
|
||||
#endif // NAZARA_CURSORIMPL_HPP
|
||||
49
src/Nazara/Utility/Win32/IconImpl.cpp
Normal file
49
src/Nazara/Utility/Win32/IconImpl.cpp
Normal file
@@ -0,0 +1,49 @@
|
||||
// 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/Win32/IconImpl.hpp>
|
||||
#include <Nazara/Utility/Image.hpp>
|
||||
#include <Nazara/Utility/Debug.hpp>
|
||||
|
||||
bool NzIconImpl::Create(const NzImage& icon)
|
||||
{
|
||||
NzImage windowsIcon(icon);
|
||||
if (!windowsIcon.Convert(nzPixelFormat_BGRA8))
|
||||
{
|
||||
NazaraError("Failed to convert icon to BGRA8");
|
||||
return false;
|
||||
}
|
||||
|
||||
HBITMAP bitmap = CreateBitmap(windowsIcon.GetWidth(), windowsIcon.GetHeight(), 1, 32, windowsIcon.GetConstPixels());
|
||||
HBITMAP monoBitmap = CreateBitmap(windowsIcon.GetWidth(), windowsIcon.GetHeight(), 1, 1, nullptr);
|
||||
|
||||
// http://msdn.microsoft.com/en-us/library/windows/desktop/ms648052(v=vs.85).aspx
|
||||
ICONINFO iconInfo;
|
||||
iconInfo.fIcon = TRUE;
|
||||
iconInfo.hbmMask = monoBitmap;
|
||||
iconInfo.hbmColor = bitmap;
|
||||
|
||||
m_icon = CreateIconIndirect(&iconInfo);
|
||||
|
||||
DeleteObject(bitmap);
|
||||
DeleteObject(monoBitmap);
|
||||
|
||||
if (!m_icon)
|
||||
{
|
||||
NazaraError("Failed to create icon: " + NzGetLastSystemError());
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void NzIconImpl::Destroy()
|
||||
{
|
||||
DestroyIcon(m_icon);
|
||||
}
|
||||
|
||||
HICON NzIconImpl::GetIcon()
|
||||
{
|
||||
return m_icon;
|
||||
}
|
||||
26
src/Nazara/Utility/Win32/IconImpl.hpp
Normal file
26
src/Nazara/Utility/Win32/IconImpl.hpp
Normal file
@@ -0,0 +1,26 @@
|
||||
// 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_ICONIMPL_HPP
|
||||
#define NAZARA_ICONIMPL_HPP
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
class NzImage;
|
||||
|
||||
class NzIconImpl
|
||||
{
|
||||
public:
|
||||
bool Create(const NzImage& image);
|
||||
void Destroy();
|
||||
|
||||
HICON GetIcon();
|
||||
|
||||
private:
|
||||
HICON m_icon = nullptr;
|
||||
};
|
||||
|
||||
#endif // NAZARA_ICONIMPL_HPP
|
||||
@@ -12,13 +12,18 @@
|
||||
#include <Nazara/Core/Thread.hpp>
|
||||
#include <Nazara/Core/ThreadCondition.hpp>
|
||||
#include <Nazara/Utility/Config.hpp>
|
||||
#include <Nazara/Utility/Cursor.hpp>
|
||||
#include <Nazara/Utility/Image.hpp>
|
||||
#include <Nazara/Utility/Icon.hpp>
|
||||
#include <Nazara/Utility/Win32/CursorImpl.hpp>
|
||||
#include <Nazara/Utility/Win32/IconImpl.hpp>
|
||||
#include <cstdio>
|
||||
#include <windowsx.h>
|
||||
#include <Nazara/Utility/Debug.hpp>
|
||||
|
||||
#ifdef _WIN64
|
||||
#define GWL_USERDATA GWLP_USERDATA
|
||||
#define GCL_HCURSOR GCLP_HCURSOR
|
||||
#define GWL_USERDATA GWLP_USERDATA
|
||||
#endif
|
||||
|
||||
// N'est pas définit avec MinGW apparemment
|
||||
@@ -72,7 +77,7 @@ void NzWindowImpl::Close()
|
||||
|
||||
bool NzWindowImpl::Create(NzVideoMode mode, const NzString& title, nzUInt32 style)
|
||||
{
|
||||
bool fullscreen = (style & NzWindow::Fullscreen) != 0;
|
||||
bool fullscreen = (style & nzWindowStyle_Fullscreen) != 0;
|
||||
DWORD win32Style, win32StyleEx;
|
||||
unsigned int x, y;
|
||||
unsigned int width = mode.width;
|
||||
@@ -109,13 +114,13 @@ bool NzWindowImpl::Create(NzVideoMode mode, const NzString& title, nzUInt32 styl
|
||||
else
|
||||
{
|
||||
win32Style = WS_VISIBLE;
|
||||
if (style & NzWindow::Titlebar)
|
||||
if (style & nzWindowStyle_Titlebar)
|
||||
{
|
||||
win32Style |= WS_CAPTION | WS_MINIMIZEBOX;
|
||||
if (style & NzWindow::Closable)
|
||||
if (style & nzWindowStyle_Closable)
|
||||
win32Style |= WS_SYSMENU;
|
||||
|
||||
if (style & NzWindow::Resizable)
|
||||
if (style & nzWindowStyle_Resizable)
|
||||
win32Style |= WS_MAXIMIZEBOX | WS_SIZEBOX;
|
||||
}
|
||||
else
|
||||
@@ -272,6 +277,80 @@ bool NzWindowImpl::IsVisible() const
|
||||
return IsWindowVisible(m_handle);
|
||||
}
|
||||
|
||||
void NzWindowImpl::SetCursor(nzWindowCursor cursor)
|
||||
{
|
||||
switch (cursor)
|
||||
{
|
||||
case nzWindowCursor_Crosshair:
|
||||
m_cursor = reinterpret_cast<HCURSOR>(LoadImage(nullptr, IDC_CROSS, IMAGE_CURSOR, 0, 0, LR_SHARED));
|
||||
break;
|
||||
|
||||
case nzWindowCursor_Default:
|
||||
m_cursor = reinterpret_cast<HCURSOR>(LoadImage(nullptr, IDC_ARROW, IMAGE_CURSOR, 0, 0, LR_SHARED));
|
||||
break;
|
||||
|
||||
case nzWindowCursor_Hand:
|
||||
case nzWindowCursor_Pointer:
|
||||
m_cursor = reinterpret_cast<HCURSOR>(LoadImage(nullptr, IDC_HAND, IMAGE_CURSOR, 0, 0, LR_SHARED));
|
||||
break;
|
||||
|
||||
case nzWindowCursor_Help:
|
||||
m_cursor = reinterpret_cast<HCURSOR>(LoadImage(nullptr, IDC_HELP, IMAGE_CURSOR, 0, 0, LR_SHARED));
|
||||
break;
|
||||
|
||||
case nzWindowCursor_Move:
|
||||
m_cursor = reinterpret_cast<HCURSOR>(LoadImage(nullptr, IDC_SIZEALL, IMAGE_CURSOR, 0, 0, LR_SHARED));
|
||||
break;
|
||||
|
||||
case nzWindowCursor_None:
|
||||
m_cursor = nullptr;
|
||||
break;
|
||||
|
||||
case nzWindowCursor_Progress:
|
||||
m_cursor = reinterpret_cast<HCURSOR>(LoadImage(nullptr, IDC_APPSTARTING, IMAGE_CURSOR, 0, 0, LR_SHARED));
|
||||
break;
|
||||
|
||||
case nzWindowCursor_ResizeN:
|
||||
case nzWindowCursor_ResizeS:
|
||||
m_cursor = reinterpret_cast<HCURSOR>(LoadImage(nullptr, IDC_SIZENS, IMAGE_CURSOR, 0, 0, LR_SHARED));
|
||||
break;
|
||||
|
||||
case nzWindowCursor_ResizeNW:
|
||||
case nzWindowCursor_ResizeSE:
|
||||
m_cursor = reinterpret_cast<HCURSOR>(LoadImage(nullptr, IDC_SIZENESW, IMAGE_CURSOR, 0, 0, LR_SHARED));
|
||||
break;
|
||||
|
||||
case nzWindowCursor_ResizeNE:
|
||||
case nzWindowCursor_ResizeSW:
|
||||
m_cursor = reinterpret_cast<HCURSOR>(LoadImage(nullptr, IDC_SIZENWSE, IMAGE_CURSOR, 0, 0, LR_SHARED));
|
||||
break;
|
||||
|
||||
case nzWindowCursor_ResizeE:
|
||||
case nzWindowCursor_ResizeW:
|
||||
m_cursor = reinterpret_cast<HCURSOR>(LoadImage(nullptr, IDC_SIZEWE, IMAGE_CURSOR, 0, 0, LR_SHARED));
|
||||
break;
|
||||
|
||||
case nzWindowCursor_Text:
|
||||
m_cursor = reinterpret_cast<HCURSOR>(LoadImage(nullptr, IDC_IBEAM, IMAGE_CURSOR, 0, 0, LR_SHARED));
|
||||
break;
|
||||
|
||||
case nzWindowCursor_Wait:
|
||||
m_cursor = reinterpret_cast<HCURSOR>(LoadImage(nullptr, IDC_WAIT, IMAGE_CURSOR, 0, 0, LR_SHARED));
|
||||
break;
|
||||
}
|
||||
|
||||
// Pas besoin de libérer le curseur par la suite s'il est partagé
|
||||
// http://msdn.microsoft.com/en-us/library/windows/desktop/ms648045(v=vs.85).aspx
|
||||
::SetCursor(m_cursor);
|
||||
}
|
||||
|
||||
void NzWindowImpl::SetCursor(const NzCursor& cursor)
|
||||
{
|
||||
m_cursor = cursor.m_impl->GetCursor();
|
||||
|
||||
::SetCursor(m_cursor);
|
||||
}
|
||||
|
||||
void NzWindowImpl::SetEventListener(bool listener)
|
||||
{
|
||||
if (m_ownsWindow)
|
||||
@@ -297,6 +376,14 @@ void NzWindowImpl::SetFocus()
|
||||
SetForegroundWindow(m_handle);
|
||||
}
|
||||
|
||||
void NzWindowImpl::SetIcon(const NzIcon& icon)
|
||||
{
|
||||
HICON iconHandle = icon.m_impl->GetIcon();
|
||||
|
||||
SendMessage(m_handle, WM_SETICON, ICON_BIG, reinterpret_cast<LPARAM>(iconHandle));
|
||||
SendMessage(m_handle, WM_SETICON, ICON_SMALL, reinterpret_cast<LPARAM>(iconHandle));
|
||||
}
|
||||
|
||||
void NzWindowImpl::SetMaximumSize(int width, int height)
|
||||
{
|
||||
RECT rect = {0, 0, width, height};
|
||||
@@ -355,19 +442,6 @@ void NzWindowImpl::SetVisible(bool visible)
|
||||
ShowWindow(m_handle, (visible) ? SW_SHOW : SW_HIDE);
|
||||
}
|
||||
|
||||
void NzWindowImpl::ShowMouseCursor(bool show)
|
||||
{
|
||||
// Pas besoin de libérer le curseur par la suite s'il est partagé
|
||||
// http://msdn.microsoft.com/en-us/library/windows/desktop/ms648045(v=vs.85).aspx
|
||||
|
||||
if (show)
|
||||
m_cursor = reinterpret_cast<HCURSOR>(LoadImage(nullptr, MAKEINTRESOURCE(OCR_NORMAL), IMAGE_CURSOR, 0, 0, LR_SHARED));
|
||||
else
|
||||
m_cursor = nullptr;
|
||||
|
||||
SetCursor(m_cursor);
|
||||
}
|
||||
|
||||
void NzWindowImpl::StayOnTop(bool stayOnTop)
|
||||
{
|
||||
SetWindowPos(m_handle, (stayOnTop) ? HWND_TOPMOST : HWND_NOTOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_SHOWWINDOW);
|
||||
@@ -390,7 +464,7 @@ bool NzWindowImpl::HandleMessage(HWND window, UINT message, WPARAM wParam, LPARA
|
||||
case WM_SETCURSOR:
|
||||
// http://msdn.microsoft.com/en-us/library/windows/desktop/ms648382(v=vs.85).aspx
|
||||
if (LOWORD(lParam) == HTCLIENT)
|
||||
SetCursor(m_cursor);
|
||||
::SetCursor(m_cursor);
|
||||
|
||||
break;
|
||||
|
||||
|
||||
@@ -56,8 +56,11 @@ class NzWindowImpl : NzNonCopyable
|
||||
bool IsMinimized() const;
|
||||
bool IsVisible() const;
|
||||
|
||||
void SetCursor(nzWindowCursor cursor);
|
||||
void SetCursor(const NzCursor& cursor);
|
||||
void SetEventListener(bool listener);
|
||||
void SetFocus();
|
||||
void SetIcon(const NzIcon& icon);
|
||||
void SetMaximumSize(int width, int height);
|
||||
void SetMinimumSize(int width, int height);
|
||||
void SetPosition(int x, int y);
|
||||
@@ -65,7 +68,6 @@ class NzWindowImpl : NzNonCopyable
|
||||
void SetTitle(const NzString& title);
|
||||
void SetVisible(bool visible);
|
||||
|
||||
void ShowMouseCursor(bool show);
|
||||
void StayOnTop(bool stayOnTop);
|
||||
|
||||
static bool Initialize();
|
||||
|
||||
@@ -5,11 +5,18 @@
|
||||
#include <Nazara/Utility/Window.hpp>
|
||||
#include <Nazara/Core/Error.hpp>
|
||||
#include <Nazara/Core/LockGuard.hpp>
|
||||
#include <Nazara/Utility/Cursor.hpp>
|
||||
#include <Nazara/Utility/Image.hpp>
|
||||
#include <Nazara/Utility/Icon.hpp>
|
||||
#include <stdexcept>
|
||||
|
||||
#if defined(NAZARA_PLATFORM_WINDOWS)
|
||||
#include <Nazara/Utility/Win32/CursorImpl.hpp>
|
||||
#include <Nazara/Utility/Win32/IconImpl.hpp>
|
||||
#include <Nazara/Utility/Win32/WindowImpl.hpp>
|
||||
#elif defined(NAZARA_PLATFORM_LINUX)
|
||||
#include <Nazara/Utility/Linux/CursorImpl.hpp>
|
||||
#include <Nazara/Utility/Linux/IconImpl.hpp>
|
||||
#include <Nazara/Utility/Linux/WindowImpl.hpp>
|
||||
#else
|
||||
#error Lack of implementation: Window
|
||||
@@ -103,12 +110,12 @@ bool NzWindow::Create(NzVideoMode mode, const NzString& title, nzUInt32 style)
|
||||
Close();
|
||||
|
||||
// Inspiré du code de la SFML par Laurent Gomila
|
||||
if (style & Fullscreen)
|
||||
if (style & nzWindowStyle_Fullscreen)
|
||||
{
|
||||
if (fullscreenWindow)
|
||||
{
|
||||
NazaraError("Window (" + NzString::Pointer(fullscreenWindow) + ") already in fullscreen mode");
|
||||
style &= ~Fullscreen;
|
||||
style &= ~nzWindowStyle_Fullscreen;
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -121,8 +128,8 @@ bool NzWindow::Create(NzVideoMode mode, const NzString& title, nzUInt32 style)
|
||||
fullscreenWindow = this;
|
||||
}
|
||||
}
|
||||
else if (style & Closable || style & Resizable)
|
||||
style |= Titlebar;
|
||||
else if (style & nzWindowStyle_Closable || style & nzWindowStyle_Resizable)
|
||||
style |= nzWindowStyle_Titlebar;
|
||||
|
||||
m_impl = new NzWindowImpl(this);
|
||||
if (!m_impl->Create(mode, title, style))
|
||||
@@ -147,10 +154,10 @@ bool NzWindow::Create(NzVideoMode mode, const NzString& title, nzUInt32 style)
|
||||
|
||||
m_impl->EnableKeyRepeat(true);
|
||||
m_impl->EnableSmoothScrolling(false);
|
||||
m_impl->SetCursor(nzWindowCursor_Default);
|
||||
m_impl->SetMaximumSize(-1, -1);
|
||||
m_impl->SetMinimumSize(-1, -1);
|
||||
m_impl->SetVisible(true);
|
||||
m_impl->ShowMouseCursor(true);
|
||||
|
||||
if (opened)
|
||||
m_impl->SetPosition(position.x, position.y);
|
||||
@@ -299,6 +306,26 @@ bool NzWindow::PollEvent(NzEvent* event)
|
||||
return false;
|
||||
}
|
||||
|
||||
void NzWindow::SetCursor(nzWindowCursor cursor)
|
||||
{
|
||||
if (m_impl)
|
||||
m_impl->SetCursor(cursor);
|
||||
}
|
||||
|
||||
void NzWindow::SetCursor(const NzCursor& cursor)
|
||||
{
|
||||
#if NAZARA_UTILITY_SAFE
|
||||
if (!cursor.IsValid())
|
||||
{
|
||||
NazaraError("Cursor is not valid");
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (m_impl)
|
||||
m_impl->SetCursor(cursor);
|
||||
}
|
||||
|
||||
void NzWindow::SetEventListener(bool listener)
|
||||
{
|
||||
if (!m_impl)
|
||||
@@ -331,6 +358,20 @@ void NzWindow::SetFocus()
|
||||
m_impl->SetFocus();
|
||||
}
|
||||
|
||||
void NzWindow::SetIcon(const NzIcon& icon)
|
||||
{
|
||||
#if NAZARA_UTILITY_SAFE
|
||||
if (!icon.IsValid())
|
||||
{
|
||||
NazaraError("Icon is not valid");
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (m_impl)
|
||||
m_impl->SetIcon(icon);
|
||||
}
|
||||
|
||||
void NzWindow::SetMaximumSize(const NzVector2i& maxSize)
|
||||
{
|
||||
if (m_impl)
|
||||
@@ -391,12 +432,6 @@ void NzWindow::SetVisible(bool visible)
|
||||
m_impl->SetVisible(visible);
|
||||
}
|
||||
|
||||
void NzWindow::ShowMouseCursor(bool show)
|
||||
{
|
||||
if (m_impl)
|
||||
m_impl->ShowMouseCursor(show);
|
||||
}
|
||||
|
||||
void NzWindow::StayOnTop(bool stayOnTop)
|
||||
{
|
||||
if (m_impl)
|
||||
|
||||
Reference in New Issue
Block a user