Merge remote-tracking branch 'upstream/master'

This commit is contained in:
Remi Beges
2012-06-16 12:45:59 +02:00
114 changed files with 7524 additions and 1031 deletions

View File

@@ -7,22 +7,22 @@
#include <Nazara/Core/Debug/MemoryLeakTracker.hpp>
#include <new>
void* operator new(std::size_t size) throw(std::bad_alloc)
void* operator new(std::size_t size)
{
return NzMemoryManager::Allocate(size, false);
}
void* operator new[](std::size_t size) throw(std::bad_alloc)
void* operator new[](std::size_t size)
{
return NzMemoryManager::Allocate(size, true);
}
void operator delete(void* pointer) throw()
void operator delete(void* pointer) noexcept
{
NzMemoryManager::Free(pointer, false);
}
void operator delete[](void* pointer) throw()
void operator delete[](void* pointer) noexcept
{
NzMemoryManager::Free(pointer, true);
}

16
src/Nazara/Core/Color.cpp Normal file
View File

@@ -0,0 +1,16 @@
// 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/Core/Color.hpp>
#include <Nazara/Core/Debug.hpp>
const NzColor NzColor::Black(0, 0, 0);
const NzColor NzColor::Blue(0, 0, 255);
const NzColor NzColor::Cyan(0, 255, 255);
const NzColor NzColor::Green(0, 255, 0);
const NzColor NzColor::Magenta(255, 0, 255);
const NzColor NzColor::Orange(255, 165, 0);
const NzColor NzColor::Red(255, 0, 0);
const NzColor NzColor::Yellow(255, 255, 0);
const NzColor NzColor::White(255, 255, 255);

View File

@@ -7,22 +7,22 @@
#include <Nazara/Core/Debug/MemoryLeakTracker.hpp>
#include <new>
void* operator new(std::size_t size) throw(std::bad_alloc)
void* operator new(std::size_t size)
{
return NzMemoryManager::Allocate(size, false);
}
void* operator new[](std::size_t size) throw(std::bad_alloc)
void* operator new[](std::size_t size)
{
return NzMemoryManager::Allocate(size, true);
}
void operator delete(void* pointer) throw()
void operator delete(void* pointer) noexcept
{
NzMemoryManager::Free(pointer, false);
}
void operator delete[](void* pointer) throw()
void operator delete[](void* pointer) noexcept
{
NzMemoryManager::Free(pointer, true);
}

View File

@@ -73,7 +73,7 @@ void* NzMemoryManager::Allocate(std::size_t size, bool multi, const char* file,
Block* ptr = reinterpret_cast<Block*>(std::malloc(size+sizeof(Block)));
if (!ptr)
return nullptr;
return nullptr; // Impossible d'envoyer une exception car cela allouerait de la mémoire avec new (boucle infinie)
ptr->array = multi;
ptr->file = file;

View File

@@ -313,7 +313,7 @@ std::size_t NzFile::Read(void* buffer, std::size_t typeSize, unsigned int count)
{
unsigned int typeCount = byteRead/typeSize;
for (unsigned int i = 0; i < typeCount; ++i)
NzByteSwap(static_cast<char*>(buffer) + i*typeSize, typeSize);
NzByteSwap(reinterpret_cast<nzUInt8*>(buffer) + i*typeSize, typeSize);
}
return byteRead;

View File

@@ -111,8 +111,9 @@ NzHashDigest NzHashCRC32::End()
{
m_state->crc ^= 0xFFFFFFFF;
if (NazaraEndianness == nzEndianness_LittleEndian)
NzByteSwap(&m_state->crc, sizeof(nzUInt32));
#ifdef NAZARA_LITTLE_ENDIAN
NzByteSwap(&m_state->crc, sizeof(nzUInt32));
#endif
return NzHashDigest(GetHashName(), reinterpret_cast<nzUInt8*>(&m_state->crc), 4);
}

View File

@@ -52,8 +52,10 @@ NzHashDigest NzHashFletcher16::End()
m_state->sum2 = (m_state->sum2 & 0xff) + (m_state->sum2 >> 8);
nzUInt32 fletcher = (m_state->sum2 << 8) | m_state->sum1;
if (NazaraEndianness == nzEndianness_BigEndian)
NzByteSwap(&fletcher, sizeof(nzUInt32));
#ifdef NAZARA_BIG_ENDIAN
NzByteSwap(&fletcher, sizeof(nzUInt32));
#endif
return NzHashDigest(GetHashName(), reinterpret_cast<nzUInt8*>(&fletcher), 2);
}

View File

@@ -114,7 +114,7 @@ namespace
nzUInt32 d = state->abcd[3];
nzUInt32 t;
#ifdef NAZARA_ENDIANNESS_BIGENDIAN
#ifdef NAZARA_BIG_ENDIAN
/* Define storage only for big-endian CPUs. */
nzUInt32 X[16];

View File

@@ -42,7 +42,7 @@
#include <cstring>
/*** ENDIAN REVERSAL MACROS *******************************************/
#ifdef NAZARA_ENDIANNESS_LITTLEENDIAN
#ifdef NAZARA_LITTLE_ENDIAN
#define REVERSE32(w,x) { \
nzUInt32 tmp = (w); \
@@ -272,7 +272,7 @@ void SHA1_Init(SHA_CTX* context)
context->s1.bitcount = 0;
}
#ifdef NAZARA_ENDIANNESS_LITTLEENDIAN
#ifdef NAZARA_LITTLE_ENDIAN
#define ROUND1_0_TO_15(a,b,c,d,e) \
REVERSE32(*data++, W1[j]); \
@@ -281,7 +281,7 @@ void SHA1_Init(SHA_CTX* context)
(b) = ROTL32(30, (b)); \
j++;
#else // NAZARA_ENDIANNESS_LITTLEENDIAN
#else // NAZARA_LITTLE_ENDIAN
#define ROUND1_0_TO_15(a,b,c,d,e) \
(e) = ROTL32(5, (a)) + Ch((b), (c), (d)) + (e) + \
@@ -289,7 +289,7 @@ void SHA1_Init(SHA_CTX* context)
(b) = ROTL32(30, (b)); \
j++;
#endif // NAZARA_ENDIANNESS_LITTLEENDIAN
#endif // NAZARA_LITTLE_ENDIAN
#define ROUND1_16_TO_19(a,b,c,d,e) \
T1 = W1[(j+13)&0x0f] ^ W1[(j+8)&0x0f] ^ W1[(j+2)&0x0f] ^ W1[j&0x0f]; \
@@ -512,7 +512,7 @@ void SHA1_End(SHA_CTX* context, nzUInt8* digest)
}
}
/* Set the bit count: */
#ifdef NAZARA_ENDIANNESS_LITTLEENDIAN
#ifdef NAZARA_LITTLE_ENDIAN
/* Convert FROM host byte order */
REVERSE64(context->s1.bitcount,context->s1.bitcount);
#endif
@@ -523,7 +523,7 @@ void SHA1_End(SHA_CTX* context, nzUInt8* digest)
SHA1_Internal_Transform(context, reinterpret_cast<nzUInt32*>(context->s1.buffer));
/* Save the hash data for output: */
#ifdef NAZARA_ENDIANNESS_LITTLEENDIAN
#ifdef NAZARA_LITTLE_ENDIAN
{
/* Convert TO host byte order */
for (int j = 0; j < (SHA1_DIGEST_LENGTH >> 2); j++)
@@ -551,7 +551,7 @@ void SHA256_Init(SHA_CTX* context)
SHA256_Internal_Init(context, sha256_initial_hash_value);
}
#ifdef NAZARA_ENDIANNESS_LITTLEENDIAN
#ifdef NAZARA_LITTLE_ENDIAN
#define ROUND256_0_TO_15(a,b,c,d,e,f,g,h) \
REVERSE32(*data++, W256[j]); \
@@ -561,7 +561,7 @@ void SHA256_Init(SHA_CTX* context)
(h) = T1 + Sigma0_256(a) + Maj((a), (b), (c)); \
j++
#else // NAZARA_ENDIANNESS_LITTLEENDIAN
#else // NAZARA_LITTLE_ENDIAN
#define ROUND256_0_TO_15(a,b,c,d,e,f,g,h) \
T1 = (h) + Sigma1_256(e) + Ch((e), (f), (g)) + \
@@ -570,7 +570,7 @@ void SHA256_Init(SHA_CTX* context)
(h) = T1 + Sigma0_256(a) + Maj((a), (b), (c)); \
j++
#endif // NAZARA_ENDIANNESS_LITTLEENDIAN
#endif // NAZARA_LITTLE_ENDIAN
#define ROUND256(a,b,c,d,e,f,g,h) \
s0 = W256[(j+1)&0x0f]; \
@@ -693,7 +693,7 @@ void SHA256_Update(SHA_CTX* context, const nzUInt8 *data, std::size_t len)
void SHA256_Internal_Last(SHA_CTX* context)
{
unsigned int usedspace = (context->s256.bitcount >> 3) % 64;
#ifdef NAZARA_ENDIANNESS_LITTLEENDIAN
#ifdef NAZARA_LITTLE_ENDIAN
/* Convert FROM host byte order */
REVERSE64(context->s256.bitcount,context->s256.bitcount);
#endif
@@ -744,7 +744,7 @@ void SHA256_End(SHA_CTX* context, nzUInt8* digest)
SHA256_Internal_Last(context);
/* Save the hash data for output: */
#ifdef NAZARA_ENDIANNESS_LITTLEENDIAN
#ifdef NAZARA_LITTLE_ENDIAN
{
/* Convert TO host byte order */
for (int j = 0; j < (SHA256_DIGEST_LENGTH >> 2); j++)
@@ -786,7 +786,7 @@ void SHA224_End(SHA_CTX* context, nzUInt8* digest)
SHA256_Internal_Last(context);
/* Save the hash data for output: */
#ifdef NAZARA_ENDIANNESS_LITTLEENDIAN
#ifdef NAZARA_LITTLE_ENDIAN
{
/* Convert TO host byte order */
for (int j = 0; j < (SHA224_DIGEST_LENGTH >> 2); j++)
@@ -816,7 +816,7 @@ void SHA512_Init(SHA_CTX* context)
}
/* Unrolled SHA-512 round macros: */
#ifdef NAZARA_ENDIANNESS_LITTLEENDIAN
#ifdef NAZARA_LITTLE_ENDIAN
#define ROUND512_0_TO_15(a,b,c,d,e,f,g,h) \
REVERSE64(*data++, W512[j]); \
@@ -827,7 +827,7 @@ void SHA512_Init(SHA_CTX* context)
j++
#else // NAZARA_ENDIANNESS_LITTLEENDIAN
#else // NAZARA_LITTLE_ENDIAN
#define ROUND512_0_TO_15(a,b,c,d,e,f,g,h) \
T1 = (h) + Sigma1_512(e) + Ch((e), (f), (g)) + \
@@ -836,7 +836,7 @@ void SHA512_Init(SHA_CTX* context)
(h) = T1 + Sigma0_512(a) + Maj((a), (b), (c)); \
j++
#endif // NAZARA_ENDIANNESS_LITTLEENDIAN
#endif // NAZARA_LITTLE_ENDIAN
#define ROUND512(a,b,c,d,e,f,g,h) \
s0 = W512[(j+1)&0x0f]; \
@@ -958,7 +958,7 @@ void SHA512_Internal_Last(SHA_CTX* context)
unsigned int usedspace;
usedspace = (context->s512.bitcount[0] >> 3) % 128;
#ifdef NAZARA_ENDIANNESS_LITTLEENDIAN
#ifdef NAZARA_LITTLE_ENDIAN
/* Convert FROM host byte order */
REVERSE64(context->s512.bitcount[0],context->s512.bitcount[0]);
REVERSE64(context->s512.bitcount[1],context->s512.bitcount[1]);
@@ -1011,7 +1011,7 @@ void SHA512_End(SHA_CTX* context, nzUInt8* digest)
SHA512_Internal_Last(context);
/* Save the hash data for output: */
#ifdef NAZARA_ENDIANNESS_LITTLEENDIAN
#ifdef NAZARA_LITTLE_ENDIAN
{
/* Convert TO host byte order */
for (int j = 0; j < (SHA512_DIGEST_LENGTH >> 3); j++)
@@ -1051,7 +1051,7 @@ void SHA384_End(SHA_CTX* context, nzUInt8* digest)
SHA512_Internal_Last(context);
/* Save the hash data for output: */
#ifdef NAZARA_ENDIANNESS_LITTLEENDIAN
#ifdef NAZARA_LITTLE_ENDIAN
{
/* Convert TO host byte order */
for (int j = 0; j < (SHA384_DIGEST_LENGTH >> 3); j++)

View File

@@ -2,17 +2,17 @@
// This file is part of the "Nazara Engine".
// For conditions of distribution and use, see copyright notice in Config.hpp
#include <Nazara/Core/Lock.hpp>
#include <Nazara/Core/LockGuard.hpp>
#include <Nazara/Core/Mutex.hpp>
#include <Nazara/Core/Debug.hpp>
NzLock::NzLock(NzMutex& mutex) :
NzLockGuard::NzLockGuard(NzMutex& mutex) :
m_mutex(mutex)
{
m_mutex.Lock();
}
NzLock::~NzLock()
NzLockGuard::~NzLockGuard()
{
m_mutex.Unlock();
}

View File

@@ -8,7 +8,7 @@
#include <Nazara/Core/Debug.hpp>
NzMemoryStream::NzMemoryStream(const void* ptr, nzUInt64 size) :
m_ptr(static_cast<const nzUInt8*>(ptr)),
m_ptr(reinterpret_cast<const nzUInt8*>(ptr)),
m_pos(0),
m_size(size)
{

View File

@@ -3317,7 +3317,7 @@ NzString NzString::Simplified(nzUInt32 flags) const
utf8::unchecked::iterator<const char*> it(ptr);
do
{
if (NzUnicode::GetCategory(*it))
if (NzUnicode::GetCategory(*it) & NzUnicode::Category_Separator)
{
if (inword)
{
@@ -3941,39 +3941,59 @@ NzString NzString::Trimmed(nzUInt32 flags) const
if (m_sharedString->size == 0)
return *this;
unsigned int startPos = 0;
unsigned int endPos = m_sharedString->size-1;
unsigned int startPos;
unsigned int endPos;
if (flags & HandleUtf8)
{
utf8::unchecked::iterator<const char*> it(m_sharedString->string);
do
if ((flags & TrimOnlyRight) == 0)
{
if (NzUnicode::GetCategory(*it) & NzUnicode::Category_Separator)
break;
}
while (*++it);
startPos = it.base() - m_sharedString->string;
utf8::unchecked::iterator<const char*> it(m_sharedString->string);
do
{
if (NzUnicode::GetCategory(*it) & NzUnicode::Category_Separator)
break;
}
while (*++it);
utf8::unchecked::iterator<const char*> itR(&m_sharedString->string[m_sharedString->size]);
while ((itR--).base() != m_sharedString->string)
{
if (NzUnicode::GetCategory(*itR) & NzUnicode::Category_Separator)
break;
startPos = it.base() - m_sharedString->string;
}
endPos = itR.base() - m_sharedString->string;
else
startPos = 0;
if ((flags & TrimOnlyLeft) == 0)
{
utf8::unchecked::iterator<const char*> it(&m_sharedString->string[m_sharedString->size]);
while ((it--).base() != m_sharedString->string)
{
if (NzUnicode::GetCategory(*it) & NzUnicode::Category_Separator)
break;
}
endPos = it.base() - m_sharedString->string;
}
else
endPos = m_sharedString->size-1;
}
else
{
for (; startPos < m_sharedString->size; ++startPos)
startPos = 0;
if ((flags & TrimOnlyRight) == 0)
{
if (!std::isspace(m_sharedString->string[startPos]))
break;
for (; startPos < m_sharedString->size; ++startPos)
{
if (!std::isspace(m_sharedString->string[startPos]))
break;
}
}
for (; endPos > 0; --endPos)
endPos = m_sharedString->size-1;
if ((flags & TrimOnlyLeft) == 0)
{
if (!std::isspace(m_sharedString->string[endPos]))
break;
for (; endPos > 0; --endPos)
{
if (!std::isspace(m_sharedString->string[endPos]))
break;
}
}
}
@@ -3990,30 +4010,42 @@ NzString NzString::Trimmed(char character, nzUInt32 flags) const
if (flags & CaseInsensitive)
{
char ch = nzToLower(character);
for (; startPos < m_sharedString->size; ++startPos)
if ((flags & TrimOnlyRight) == 0)
{
if (nzToLower(m_sharedString->string[startPos]) != ch)
break;
for (; startPos < m_sharedString->size; ++startPos)
{
if (nzToLower(m_sharedString->string[startPos]) != ch)
break;
}
}
for (; endPos > 0; --endPos)
if ((flags & TrimOnlyLeft) == 0)
{
if (nzToLower(m_sharedString->string[startPos]) != ch)
break;
for (; endPos > 0; --endPos)
{
if (nzToLower(m_sharedString->string[startPos]) != ch)
break;
}
}
}
else
{
for (; startPos < m_sharedString->size; ++startPos)
if ((flags & TrimOnlyRight) == 0)
{
if (m_sharedString->string[startPos] != character)
break;
for (; startPos < m_sharedString->size; ++startPos)
{
if (m_sharedString->string[startPos] != character)
break;
}
}
for (; endPos > 0; --endPos)
if ((flags & TrimOnlyLeft) == 0)
{
if (m_sharedString->string[startPos] != character)
break;
for (; endPos > 0; --endPos)
{
if (m_sharedString->string[startPos] != character)
break;
}
}
}
@@ -4703,9 +4735,9 @@ NzString NzString::Number(unsigned long long number, nzUInt8 radix)
NzString NzString::Pointer(const void* ptr)
{
unsigned int size = sizeof(ptr)*2;
unsigned int size = sizeof(ptr)*2+2;
char* str = new char[size+1];
std::sprintf(str, "%p", ptr);
std::sprintf(str, "0x%p", ptr);
return NzString(new SharedString(1, size, size, str));
}

View File

@@ -8,7 +8,7 @@
#define NAZARA_DIRECTORYIMPL_HPP
#include <Nazara/Prerequesites.hpp>
#include <Nazara/Utility/NonCopyable.hpp>
#include <Nazara/Core/NonCopyable.hpp>
#include <windows.h>
class NzDirectory;

View File

@@ -8,7 +8,7 @@
#define NAZARA_DYNLIBIMPL_HPP
#include <Nazara/Core/DynLib.hpp>
#include <Nazara/Utility/NonCopyable.hpp>
#include <Nazara/Core/NonCopyable.hpp>
#include <windows.h>
class NzString;

View File

@@ -9,7 +9,7 @@
#include <Nazara/Prerequesites.hpp>
#include <Nazara/Core/File.hpp>
#include <Nazara/Utility/NonCopyable.hpp>
#include <Nazara/Core/NonCopyable.hpp>
#include <ctime>
#include <windows.h>

View File

@@ -6,7 +6,7 @@
#include <Nazara/Core/Win32/ThreadImpl.hpp>
#include <Nazara/Core/Error.hpp>
#include <Nazara/Utility/Functor.hpp>
#include <Nazara/Core/Functor.hpp>
#include <process.h>
#include <Nazara/Core/Debug.hpp>
@@ -65,9 +65,9 @@ void NzThreadImpl::Terminate()
TerminateThread(m_thread, 0);
}
unsigned int _stdcall NzThreadImpl::ThreadProc(void* userdata)
unsigned int __stdcall NzThreadImpl::ThreadProc(void* userdata)
{
NzThread* owner = static_cast<NzThread*>(userdata);
NzThread* owner = reinterpret_cast<NzThread*>(userdata);
NzFunctor* func = owner->m_func;
HANDLE myHandle = owner->m_impl->m_thread;
func->Run();

View File

@@ -29,7 +29,7 @@ class NzThreadImpl
void Terminate();
private:
static unsigned int _stdcall ThreadProc(void* userdata);
static unsigned int __stdcall ThreadProc(void* userdata);
HANDLE m_thread;
unsigned int m_threadId;

View File

@@ -7,22 +7,22 @@
#include <Nazara/Core/Debug/MemoryLeakTracker.hpp>
#include <new>
void* operator new(std::size_t size) throw(std::bad_alloc)
void* operator new(std::size_t size)
{
return NzMemoryManager::Allocate(size, false);
}
void* operator new[](std::size_t size) throw(std::bad_alloc)
void* operator new[](std::size_t size)
{
return NzMemoryManager::Allocate(size, true);
}
void operator delete(void* pointer) throw()
void operator delete(void* pointer) noexcept
{
NzMemoryManager::Free(pointer, false);
}
void operator delete[](void* pointer) throw()
void operator delete[](void* pointer) noexcept
{
NzMemoryManager::Free(pointer, true);
}

View File

@@ -7,22 +7,22 @@
#include <Nazara/Core/Debug/MemoryLeakTracker.hpp>
#include <new>
void* operator new(std::size_t size) throw(std::bad_alloc)
void* operator new(std::size_t size)
{
return NzMemoryManager::Allocate(size, false);
}
void* operator new[](std::size_t size) throw(std::bad_alloc)
void* operator new[](std::size_t size)
{
return NzMemoryManager::Allocate(size, true);
}
void operator delete(void* pointer) throw()
void operator delete(void* pointer) noexcept
{
NzMemoryManager::Free(pointer, false);
}
void operator delete[](void* pointer) throw()
void operator delete[](void* pointer) noexcept
{
NzMemoryManager::Free(pointer, true);
}

View File

@@ -50,17 +50,17 @@ NzBuffer::~NzBuffer()
bool NzBuffer::CopyContent(NzBuffer& buffer)
{
void* ptr = buffer.Lock(nzBufferLock_ReadOnly);
void* ptr = buffer.Map(nzBufferAccess_ReadOnly);
if (!ptr)
{
NazaraError("Unable to lock source buffer");
NazaraError("Failed to map source buffer");
return false;
}
bool r = Fill(ptr, 0, m_length);
if (!buffer.Unlock())
NazaraWarning("Unable to unlock source buffer");
if (!buffer.Unmap())
NazaraWarning("Failed to unmap source buffer");
return r;
}
@@ -145,7 +145,7 @@ void* NzBuffer::GetBufferPtr()
if (!m_impl)
{
NazaraError("Buffer not created");
return false;
return nullptr;
}
#endif
@@ -158,7 +158,7 @@ const void* NzBuffer::GetBufferPtr() const
if (!m_impl)
{
NazaraError("Buffer not created");
return false;
return nullptr;
}
#endif
@@ -205,7 +205,7 @@ bool NzBuffer::IsHardware() const
return m_storage == nzBufferStorage_Hardware;
}
void* NzBuffer::Lock(nzBufferLock lock, unsigned int offset, unsigned int length)
void* NzBuffer::Map(nzBufferAccess access, unsigned int offset, unsigned int length)
{
#if NAZARA_RENDERER_SAFE
if (!m_impl)
@@ -221,10 +221,10 @@ void* NzBuffer::Lock(nzBufferLock lock, unsigned int offset, unsigned int length
}
#endif
return m_impl->Lock(lock, offset*m_typeSize, length*m_typeSize);
return m_impl->Map(access, offset*m_typeSize, length*m_typeSize);
}
bool NzBuffer::Unlock()
bool NzBuffer::Unmap()
{
#if NAZARA_RENDERER_SAFE
if (!m_impl)
@@ -234,7 +234,7 @@ bool NzBuffer::Unlock()
}
#endif
return m_impl->Unlock();
return m_impl->Unmap();
}
bool NzBuffer::IsSupported(nzBufferStorage storage)

View File

@@ -26,8 +26,8 @@ class NzBufferImpl
virtual bool IsHardware() const = 0;
virtual void* Lock(nzBufferLock lock, unsigned int offset = 0, unsigned int size = 0) = 0;
virtual bool Unlock() = 0;
virtual void* Map(nzBufferAccess access, unsigned int offset = 0, unsigned int size = 0) = 0;
virtual bool Unmap() = 0;
};
#endif // NAZARA_BUFFERIMPL_INCLUDED

View File

@@ -5,7 +5,10 @@
#include <Nazara/Renderer/OpenGL.hpp>
#include <Nazara/Renderer/Context.hpp>
#include <Nazara/Core/Error.hpp>
#include <Nazara/Core/Log.hpp>
#include <Nazara/Core/StringStream.hpp>
#include <Nazara/Renderer/Config.hpp>
#include <vector>
#if defined(NAZARA_PLATFORM_WINDOWS)
#include <Nazara/Renderer/Win32/ContextImpl.hpp>
@@ -19,9 +22,112 @@
namespace
{
///TODO: Thread-local
NzContext* currentContext = nullptr;
NzContext* threadContext = nullptr;
NAZARA_THREADLOCAL NzContext* currentContext = nullptr;
NAZARA_THREADLOCAL NzContext* threadContext = nullptr;
std::vector<NzContext*> contexts;
void CALLBACK DebugCallback(unsigned int source, unsigned int type, unsigned int id, unsigned int severity, int length, const char* message, void* userParam)
{
NazaraUnused(length);
NzStringStream ss;
ss << "OpenGL debug message (ID: 0x" << NzString::Number(id, 16) << "):\n";
ss << "Sent by context: " << userParam;
ss << "\n-Source: ";
switch (source)
{
case GL_DEBUG_SOURCE_API_ARB:
ss << "OpenGL";
break;
case GL_DEBUG_SOURCE_WINDOW_SYSTEM_ARB:
ss << "Operating system";
break;
case GL_DEBUG_SOURCE_SHADER_COMPILER_ARB:
ss << "Shader compiler";
break;
case GL_DEBUG_SOURCE_THIRD_PARTY_ARB:
ss << "Shader compiler";
break;
case GL_DEBUG_SOURCE_APPLICATION_ARB:
ss << "Application";
break;
case GL_DEBUG_SOURCE_OTHER_ARB:
ss << "Other";
break;
default:
// Peut être rajouté par une extension
ss << "Unknown";
break;
}
ss << '\n';
ss << "-Type: ";
switch (type)
{
case GL_DEBUG_TYPE_ERROR_ARB:
ss << "Error";
break;
case GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR_ARB:
ss << "Deprecated behavior";
break;
case GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR_ARB:
ss << "Undefined behavior";
break;
case GL_DEBUG_TYPE_PORTABILITY_ARB:
ss << "Portability";
break;
case GL_DEBUG_TYPE_PERFORMANCE_ARB:
ss << "Performance";
break;
case GL_DEBUG_TYPE_OTHER_ARB:
ss << "Other";
break;
default:
// Peut être rajouté par une extension
ss << "Unknown";
break;
}
ss << '\n';
ss << "-Severity: ";
switch (severity)
{
case GL_DEBUG_SEVERITY_HIGH_ARB:
ss << "High";
break;
case GL_DEBUG_SEVERITY_MEDIUM_ARB:
ss << "Medium";
break;
case GL_DEBUG_SEVERITY_LOW_ARB:
ss << "Low";
break;
default:
// Peut être rajouté par une extension
ss << "Unknown";
break;
}
ss << '\n';
ss << "Message: " << message << '\n';
NazaraNotice(ss);
}
}
NzContext::NzContext() :
@@ -31,18 +137,13 @@ m_impl(nullptr)
NzContext::~NzContext()
{
if (m_impl)
{
if (currentContext == this)
NzContextImpl::Desactivate();
m_impl->Destroy();
delete m_impl;
}
Destroy();
}
bool NzContext::Create(const NzContextParameters& parameters)
{
Destroy();
m_parameters = parameters;
if (m_parameters.shared && !m_parameters.shareContext)
m_parameters.shareContext = s_reference;
@@ -71,9 +172,31 @@ bool NzContext::Create(const NzContextParameters& parameters)
if (m_parameters.antialiasingLevel > 0)
glEnable(GL_MULTISAMPLE);
if (NzOpenGL::IsSupported(NzOpenGL::DebugOutput) && m_parameters.debugMode)
{
glDebugMessageCallback(&DebugCallback, this);
#ifdef NAZARA_DEBUG
glEnable(GL_DEBUG_OUTPUT_SYNCHRONOUS_ARB);
#endif
}
return true;
}
void NzContext::Destroy()
{
if (m_impl)
{
if (currentContext == this)
NzContextImpl::Desactivate();
m_impl->Destroy();
delete m_impl;
m_impl = nullptr;
}
}
const NzContextParameters& NzContext::GetParameters() const
{
#ifdef NAZARA_RENDERER_SAFE
@@ -148,7 +271,36 @@ void NzContext::SwapBuffers()
m_impl->SwapBuffers();
}
const NzContext* NzContext::GetCurrent()
bool NzContext::EnsureContext()
{
if (!currentContext)
{
if (!threadContext)
{
NzContext* context = new NzContext;
if (!context->Create())
{
NazaraError("Failed to create context");
delete context;
return false;
}
contexts.push_back(context);
threadContext = context;
}
else if (!threadContext->SetActive(true))
{
NazaraError("Failed to active thread context");
return false;
}
}
return true;
}
NzContext* NzContext::GetCurrent()
{
return currentContext;
}
@@ -158,12 +310,14 @@ const NzContext* NzContext::GetReference()
return s_reference;
}
const NzContext* NzContext::GetThreadContext()
NzContext* NzContext::GetThreadContext()
{
EnsureContext();
return threadContext;
}
bool NzContext::InitializeReference()
bool NzContext::Initialize()
{
NzContextParameters parameters;
// parameters.compatibilityProfile = true;
@@ -178,11 +332,21 @@ bool NzContext::InitializeReference()
return false;
}
// Le contexte de référence doit rester désactivé pour le partage
s_reference->SetActive(false);
NzContextParameters::defaultShareContext = s_reference;
return true;
}
void NzContext::UninitializeReference()
void NzContext::Uninitialize()
{
for (NzContext* context : contexts)
delete context;
contexts.clear(); // On supprime tous les contextes créés
delete s_reference;
s_reference = nullptr;
}

View File

@@ -3,6 +3,7 @@
// For conditions of distribution and use, see copyright notice in Config.hpp
#include <Nazara/Renderer/ContextParameters.hpp>
#include <Nazara/Renderer/Config.hpp>
#include <Nazara/Renderer/Debug.hpp>
nzUInt8 NzContextParameters::defaultMajorVersion; // Initialisé par NzOpenGL
@@ -10,5 +11,10 @@ nzUInt8 NzContextParameters::defaultMinorVersion; // Initialis
const NzContext* NzContextParameters::defaultShareContext = nullptr;
NzWindowHandle NzContextParameters::defaultWindow = 0;
bool NzContextParameters::defaultCompatibilityProfile = false;
#if NAZARA_RENDERER_OPENGL_DEBUG || defined(NAZARA_DEBUG)
bool NzContextParameters::defaultDebugMode = true;
#else
bool NzContextParameters::defaultDebugMode = false;
#endif
bool NzContextParameters::defaultDoubleBuffered = false;
bool NzContextParameters::defaultShared = true;

View File

@@ -7,22 +7,22 @@
#include <Nazara/Core/Debug/MemoryLeakTracker.hpp>
#include <new>
void* operator new(std::size_t size) throw(std::bad_alloc)
void* operator new(std::size_t size)
{
return NzMemoryManager::Allocate(size, false);
}
void* operator new[](std::size_t size) throw(std::bad_alloc)
void* operator new[](std::size_t size)
{
return NzMemoryManager::Allocate(size, true);
}
void operator delete(void* pointer) throw()
void operator delete(void* pointer) noexcept
{
NzMemoryManager::Free(pointer, false);
}
void operator delete[](void* pointer) throw()
void operator delete[](void* pointer) noexcept
{
NzMemoryManager::Free(pointer, true);
}

View File

@@ -6,14 +6,16 @@
#include <Nazara/Renderer/GLSLShader.hpp>
#include <Nazara/Core/Error.hpp>
#include <Nazara/Core/String.hpp>
#include <Nazara/Renderer/BufferImpl.hpp>
#include <Nazara/Renderer/VertexBuffer.hpp>
#include <Nazara/Renderer/Context.hpp>
#include <Nazara/Renderer/Renderer.hpp>
#include <Nazara/Renderer/Texture.hpp>
#include <Nazara/Renderer/VertexDeclaration.hpp>
#include <Nazara/Renderer/Debug.hpp>
namespace
{
nzUInt8 attribIndex[] =
///FIXME: Déclaré deux fois (ici et dans Renderer.cpp)
const nzUInt8 attribIndex[] =
{
2, // nzElementUsage_Diffuse
1, // nzElementUsage_Normal
@@ -28,31 +30,8 @@ namespace
GL_VERTEX_SHADER // nzShaderType_Vertex
};
const nzUInt8 size[] =
{
4, // nzElementType_Color
1, // nzElementType_Double1
2, // nzElementType_Double2
3, // nzElementType_Double3
4, // nzElementType_Double4
1, // nzElementType_Float1
2, // nzElementType_Float2
3, // nzElementType_Float3
4 // nzElementType_Float4
};
const GLenum type[] =
{
GL_UNSIGNED_BYTE, // nzElementType_Color
GL_DOUBLE, // nzElementType_Double1
GL_DOUBLE, // nzElementType_Double2
GL_DOUBLE, // nzElementType_Double3
GL_DOUBLE, // nzElementType_Double4
GL_FLOAT, // nzElementType_Float1
GL_FLOAT, // nzElementType_Float2
GL_FLOAT, // nzElementType_Float3
GL_FLOAT // nzElementType_Float4
};
GLuint lockedPrevious = 0;
nzUInt8 lockedLevel = 0;
}
NzGLSLShader::NzGLSLShader(NzShader* parent) :
@@ -66,13 +45,38 @@ NzGLSLShader::~NzGLSLShader()
bool NzGLSLShader::Bind()
{
#if NAZARA_RENDERER_SAFE
if (lockedLevel > 0)
{
NazaraError("Cannot bind shader while a shader is locked");
return false;
}
#endif
#ifdef NAZARA_DEBUG
if (NzContext::GetCurrent() == nullptr)
{
NazaraError("No active context");
return false;
}
#endif
glUseProgram(m_program);
return true; ///FIXME: Comment détecter une erreur d'OpenGL sans ralentir le programme ?
for (auto it = m_textures.begin(); it != m_textures.end(); ++it)
{
glActiveTexture(GL_TEXTURE0 + it->second.unit);
if (!it->second.texture->Bind())
NazaraWarning("Failed to bind texture");
}
return true;
}
bool NzGLSLShader::Compile()
{
NzContext::EnsureContext();
m_idCache.clear();
glLinkProgram(m_program);
@@ -111,6 +115,8 @@ bool NzGLSLShader::Compile()
bool NzGLSLShader::Create()
{
NzContext::EnsureContext();
m_program = glCreateProgram();
if (!m_program)
{
@@ -123,7 +129,7 @@ bool NzGLSLShader::Create()
glBindAttribLocation(m_program, attribIndex[nzElementUsage_Diffuse], "Diffuse");
glBindAttribLocation(m_program, attribIndex[nzElementUsage_Tangent], "Tangent");
NzString uniformName = "TexCoord0";
NzString uniformName = "TexCoordi";
for (unsigned int i = 0; i < 8; ++i)
{
uniformName[8] = '0'+i;
@@ -138,6 +144,8 @@ bool NzGLSLShader::Create()
void NzGLSLShader::Destroy()
{
NzContext::EnsureContext();
for (GLuint shader : m_shaders)
if (shader)
glDeleteShader(shader);
@@ -158,6 +166,8 @@ nzShaderLanguage NzGLSLShader::GetLanguage() const
NzString NzGLSLShader::GetSourceCode(nzShaderType type) const
{
NzContext::EnsureContext();
NzString source;
GLint length;
@@ -177,6 +187,8 @@ GLint NzGLSLShader::GetUniformLocation(const NzString& name) const
GLint id;
if (it == m_idCache.end())
{
NzContext::EnsureContext();
id = glGetUniformLocation(m_program, name.GetConstBuffer());
m_idCache[name] = id;
}
@@ -193,6 +205,8 @@ bool NzGLSLShader::IsLoaded(nzShaderType type) const
bool NzGLSLShader::Load(nzShaderType type, const NzString& source)
{
NzContext::EnsureContext();
GLuint shader = glCreateShader(shaderType[type]);
if (!shader)
{
@@ -245,16 +259,18 @@ bool NzGLSLShader::Load(nzShaderType type, const NzString& source)
}
}
bool NzGLSLShader::Lock() const
bool NzGLSLShader::Lock()
{
if (m_lockedLevel++ == 0)
if (lockedLevel++ == 0)
{
NzContext::EnsureContext();
GLint previous;
glGetIntegerv(GL_CURRENT_PROGRAM, &previous);
m_lockedPrevious = previous;
lockedPrevious = previous;
if (m_lockedPrevious != m_program)
if (lockedPrevious != m_program)
glUseProgram(m_program);
}
@@ -263,97 +279,261 @@ bool NzGLSLShader::Lock() const
bool NzGLSLShader::SendBoolean(const NzString& name, bool value)
{
Lock();
glUniform1i(GetUniformLocation(name), value);
Unlock();
if (glProgramUniform1i)
glProgramUniform1i(m_program, GetUniformLocation(name), value);
else
{
Lock();
glUniform1i(GetUniformLocation(name), value);
Unlock();
}
return true;
}
bool NzGLSLShader::SendDouble(const NzString& name, double value)
{
Lock();
glUniform1d(GetUniformLocation(name), value);
Unlock();
if (glProgramUniform1d)
glProgramUniform1d(m_program, GetUniformLocation(name), value);
else
{
Lock();
glUniform1d(GetUniformLocation(name), value);
Unlock();
}
return true;
}
bool NzGLSLShader::SendFloat(const NzString& name, float value)
{
Lock();
glUniform1f(GetUniformLocation(name), value);
Unlock();
if (glProgramUniform1f)
glProgramUniform1f(m_program, GetUniformLocation(name), value);
else
{
Lock();
glUniform1f(GetUniformLocation(name), value);
Unlock();
}
return true;
}
bool NzGLSLShader::SendInteger(const NzString& name, int value)
{
Lock();
glUniform1i(GetUniformLocation(name), value);
Unlock();
if (glProgramUniform1i)
glProgramUniform1i(m_program, GetUniformLocation(name), value);
else
{
Lock();
glUniform1i(GetUniformLocation(name), value);
Unlock();
}
return true;
}
bool NzGLSLShader::SendMatrix(const NzString& name, const NzMatrix4d& matrix)
{
Lock();
glUniformMatrix4dv(GetUniformLocation(name), 1, GL_FALSE, matrix);
Unlock();
if (glProgramUniformMatrix4dv)
glProgramUniformMatrix4dv(m_program, GetUniformLocation(name), 1, GL_FALSE, matrix);
else
{
Lock();
glUniformMatrix4dv(GetUniformLocation(name), 1, GL_FALSE, matrix);
Unlock();
}
return true;
}
bool NzGLSLShader::SendMatrix(const NzString& name, const NzMatrix4f& matrix)
{
Lock();
glUniformMatrix4fv(GetUniformLocation(name), 1, GL_FALSE, matrix);
Unlock();
if (glProgramUniformMatrix4fv)
glProgramUniformMatrix4fv(m_program, GetUniformLocation(name), 1, GL_FALSE, matrix);
else
{
Lock();
glUniformMatrix4fv(GetUniformLocation(name), 1, GL_FALSE, matrix);
Unlock();
}
return true;
}
bool NzGLSLShader::SendVector(const NzString& name, const NzVector2d& vector)
{
if (glProgramUniform2dv)
glProgramUniform2dv(m_program, GetUniformLocation(name), 1, vector);
else
{
Lock();
glUniform2dv(GetUniformLocation(name), 1, vector);
Unlock();
}
return true;
}
bool NzGLSLShader::SendVector(const NzString& name, const NzVector2f& vector)
{
if (glProgramUniform2fv)
glProgramUniform2fv(m_program, GetUniformLocation(name), 1, vector);
else
{
Lock();
glUniform2fv(GetUniformLocation(name), 1, vector);
Unlock();
}
return true;
}
bool NzGLSLShader::SendVector(const NzString& name, const NzVector3d& vector)
{
if (glProgramUniform3dv)
glProgramUniform3dv(m_program, GetUniformLocation(name), 1, vector);
else
{
Lock();
glUniform3dv(GetUniformLocation(name), 1, vector);
Unlock();
}
return true;
}
bool NzGLSLShader::SendVector(const NzString& name, const NzVector3f& vector)
{
if (glProgramUniform3fv)
glProgramUniform3fv(m_program, GetUniformLocation(name), 1, vector);
else
{
Lock();
glUniform3fv(GetUniformLocation(name), 1, vector);
Unlock();
}
return true;
}
bool NzGLSLShader::SendVector(const NzString& name, const NzVector4d& vector)
{
if (glProgramUniform4dv)
glProgramUniform4dv(m_program, GetUniformLocation(name), 1, vector);
else
{
Lock();
glUniform4dv(GetUniformLocation(name), 1, vector);
Unlock();
}
return true;
}
bool NzGLSLShader::SendVector(const NzString& name, const NzVector4f& vector)
{
if (glProgramUniform4fv)
glProgramUniform4fv(m_program, GetUniformLocation(name), 1, vector);
else
{
Lock();
glUniform4fv(GetUniformLocation(name), 1, vector);
Unlock();
}
return true;
}
bool NzGLSLShader::SendTexture(const NzString& name, NzTexture* texture)
{
static const unsigned int maxUnits = NazaraRenderer->GetMaxTextureUnits();
unsigned int unitUsed = m_textures.size();
if (unitUsed >= maxUnits)
{
NazaraError("Unable to use texture \"" + name + "\" for shader: all available texture units are used");
return false;
}
// À partir d'ici nous savons qu'il y a au moins un identifiant de texture libre
GLint location = GetUniformLocation(name);
if (location == -1)
{
NazaraError("Parameter name \"" + name + "\" not found in shader");
return false;
}
nzUInt8 unit;
if (unitUsed == 0)
// Pas d'unité utilisée, la tâche est simple
unit = 0;
else
{
auto it = m_textures.rbegin(); // Itérateur vers la fin de la map
unit = it->second.unit;
if (unit == maxUnits-1)
{
// Il y a une place libre, mais pas à la fin
for (; it != m_textures.rend(); ++it)
{
if (unit - it->second.unit > 1) // Si l'espace entre les indices est supérieur à 1, alors il y a une place libre
{
unit--;
break;
}
}
}
else
// Il y a une place libre à la fin
unit++;
}
m_textures[location] = TextureSlot{unit, texture};
if (glProgramUniform1i)
glProgramUniform1i(m_program, location, unit);
else
{
Lock();
glUniform1i(location, unit);
Unlock();
}
return true;
}
void NzGLSLShader::Unbind()
{
#ifdef NAZARA_DEBUG
if (NzContext::GetCurrent() == nullptr)
{
NazaraError("No active context");
return;
}
#endif
glUseProgram(0);
}
void NzGLSLShader::Unlock() const
void NzGLSLShader::Unlock()
{
if (m_lockedLevel == 0)
#ifdef NAZARA_DEBUG
if (NzContext::GetCurrent() == nullptr)
{
NazaraError("No active context");
return;
}
#endif
#if NAZARA_RENDERER_SAFE
if (lockedLevel == 0)
{
NazaraWarning("Unlock called on non-locked texture");
return;
}
#endif
if (--m_lockedLevel == 0 && m_lockedPrevious != m_program)
glUseProgram(m_lockedPrevious);
}
bool NzGLSLShader::UpdateVertexBuffer(const NzVertexBuffer* vertexBuffer, const NzVertexDeclaration* vertexDeclaration)
{
vertexBuffer->GetBuffer()->GetImpl()->Bind();
const nzUInt8* buffer = reinterpret_cast<const nzUInt8*>(vertexBuffer->GetBufferPtr());
///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 = vertexDeclaration->GetStride();
unsigned int elementCount = vertexDeclaration->GetElementCount();
for (unsigned int i = 0; i < elementCount; ++i)
{
const NzVertexDeclaration::Element* element = vertexDeclaration->GetElement(i);
glEnableVertexAttribArray(attribIndex[element->usage]+element->usageIndex);
glVertexAttribPointer(attribIndex[element->usage]+element->usageIndex,
size[element->type],
type[element->type],
(element->type == nzElementType_Color) ? GL_TRUE : GL_FALSE,
stride,
&buffer[element->offset]);
}
return true;
if (--lockedLevel == 0 && lockedPrevious != m_program)
glUseProgram(lockedPrevious);
}

View File

@@ -34,7 +34,7 @@ class NzGLSLShader : public NzShaderImpl
bool IsLoaded(nzShaderType type) const;
bool Load(nzShaderType type, const NzString& source);
bool Lock() const;
bool Lock();
bool SendBoolean(const NzString& name, bool value);
bool SendDouble(const NzString& name, double value);
@@ -42,18 +42,28 @@ class NzGLSLShader : public NzShaderImpl
bool SendInteger(const NzString& name, int value);
bool SendMatrix(const NzString& name, const NzMatrix4d& matrix);
bool SendMatrix(const NzString& name, const NzMatrix4f& matrix);
bool SendVector(const NzString& name, const NzVector2d& vector);
bool SendVector(const NzString& name, const NzVector2f& vector);
bool SendVector(const NzString& name, const NzVector3d& vector);
bool SendVector(const NzString& name, const NzVector3f& vector);
bool SendVector(const NzString& name, const NzVector4d& vector);
bool SendVector(const NzString& name, const NzVector4f& vector);
bool SendTexture(const NzString& name, NzTexture* texture);
void Unbind();
void Unlock() const;
void Unlock();
private:
bool UpdateVertexBuffer(const NzVertexBuffer* vertexBuffer, const NzVertexDeclaration* vertexDeclaration);
struct TextureSlot
{
nzUInt8 unit;
NzTexture* texture;
};
mutable std::map<NzString, GLint> m_idCache;
mutable GLuint m_lockedPrevious;
std::map<GLint, TextureSlot> m_textures;
GLuint m_program;
GLuint m_shaders[nzShaderType_Count];
mutable nzUInt8 m_lockedLevel;
NzShader* m_parent;
NzString m_log;
};

View File

@@ -5,6 +5,7 @@
#include <Nazara/Renderer/OpenGL.hpp>
#include <Nazara/Renderer/HardwareBuffer.hpp>
#include <Nazara/Core/Error.hpp>
#include <Nazara/Renderer/Context.hpp>
#include <cstring>
#include <stdexcept>
#include <Nazara/Renderer/Debug.hpp>
@@ -12,17 +13,17 @@
namespace
{
GLenum bufferLock[] = {
GL_WRITE_ONLY, // nzBufferLock_DiscardAndWrite
GL_READ_ONLY, // nzBufferLock_ReadOnly
GL_READ_WRITE, // nzBufferLock_ReadWrite
GL_WRITE_ONLY // nzBufferLock_WriteOnly
GL_WRITE_ONLY, // nzBufferAccess_DiscardAndWrite
GL_READ_ONLY, // nzBufferAccess_ReadOnly
GL_READ_WRITE, // nzBufferAccess_ReadWrite
GL_WRITE_ONLY // nzBufferAccess_WriteOnly
};
GLenum bufferLockRange[] = {
GL_MAP_INVALIDATE_BUFFER_BIT | GL_MAP_WRITE_BIT, // nzBufferLock_DiscardAndWrite
GL_MAP_READ_BIT, // nzBufferLock_ReadOnly
GL_MAP_READ_BIT | GL_MAP_WRITE_BIT, // nzBufferLock_ReadWrite
GL_MAP_WRITE_BIT // nzBufferLock_WriteOnly
GL_MAP_INVALIDATE_BUFFER_BIT | GL_MAP_WRITE_BIT, // nzBufferAccess_DiscardAndWrite
GL_MAP_READ_BIT, // nzBufferAccess_ReadOnly
GL_MAP_READ_BIT | GL_MAP_WRITE_BIT, // nzBufferAccess_ReadWrite
GL_MAP_WRITE_BIT // nzBufferAccess_WriteOnly
};
GLenum bufferTarget[] = {
@@ -43,13 +44,13 @@ namespace
GL_STATIC_DRAW // nzBufferUsage_Static
};
typedef nzUInt8* (*LockRoutine)(nzBufferType type, nzBufferLock lock, unsigned int offset, unsigned int size);
typedef nzUInt8* (*LockRoutine)(nzBufferType type, nzBufferAccess access, unsigned int offset, unsigned int size);
nzUInt8* LockBuffer(nzBufferType type, nzBufferLock lock, unsigned int offset, unsigned int size)
nzUInt8* LockBuffer(nzBufferType type, nzBufferAccess access, unsigned int offset, unsigned int size)
{
NazaraUnused(size);
if (lock == nzBufferLock_DiscardAndWrite)
if (access == nzBufferAccess_DiscardAndWrite)
{
GLint size;
glGetBufferParameteriv(bufferTargetBinding[type], GL_BUFFER_SIZE, &size);
@@ -61,30 +62,30 @@ namespace
glBufferData(bufferTargetBinding[type], size, nullptr, usage);
}
void* ptr = glMapBuffer(bufferTarget[type], bufferLock[lock]);
void* ptr = glMapBuffer(bufferTarget[type], bufferLock[access]);
if (ptr)
return reinterpret_cast<nzUInt8*>(ptr) + offset;
else
return nullptr;
}
nzUInt8* LockBufferRange(nzBufferType type, nzBufferLock lock, unsigned int offset, unsigned int size)
nzUInt8* LockBufferRange(nzBufferType type, nzBufferAccess access, unsigned int offset, unsigned int size)
{
return reinterpret_cast<nzUInt8*>(glMapBufferRange(bufferTarget[type], offset, size, bufferLockRange[lock]));
return reinterpret_cast<nzUInt8*>(glMapBufferRange(bufferTarget[type], offset, size, bufferLockRange[access]));
}
nzUInt8* LockBufferFirstRun(nzBufferType type, nzBufferLock lock, unsigned int offset, unsigned int size);
nzUInt8* LockBufferFirstRun(nzBufferType type, nzBufferAccess access, unsigned int offset, unsigned int size);
LockRoutine lockBuffer = LockBufferFirstRun;
LockRoutine mapBuffer = LockBufferFirstRun;
nzUInt8* LockBufferFirstRun(nzBufferType type, nzBufferLock lock, unsigned int offset, unsigned int size)
nzUInt8* LockBufferFirstRun(nzBufferType type, nzBufferAccess access, unsigned int offset, unsigned int size)
{
if (glMapBufferRange)
lockBuffer = LockBufferRange;
mapBuffer = LockBufferRange;
else
lockBuffer = LockBuffer;
mapBuffer = LockBuffer;
return lockBuffer(type, lock, offset, size);
return mapBuffer(type, access, offset, size);
}
}
@@ -100,20 +101,24 @@ NzHardwareBuffer::~NzHardwareBuffer()
void NzHardwareBuffer::Bind()
{
#ifdef NAZARA_DEBUG
if (NzContext::GetCurrent() == nullptr)
{
NazaraError("No active context");
return;
}
#endif
glBindBuffer(bufferTarget[m_type], m_buffer);
}
bool NzHardwareBuffer::Create(unsigned int size, nzBufferUsage usage)
{
NzContext::EnsureContext();
m_buffer = 0;
glGenBuffers(1, &m_buffer);
if (!m_buffer)
{
NazaraError("Failed to create buffer");
return false;
}
GLint previous;
glGetIntegerv(bufferTargetBinding[m_type], &previous);
@@ -129,11 +134,15 @@ bool NzHardwareBuffer::Create(unsigned int size, nzBufferUsage usage)
void NzHardwareBuffer::Destroy()
{
NzContext::EnsureContext();
glDeleteBuffers(1, &m_buffer);
}
bool NzHardwareBuffer::Fill(const void* data, unsigned int offset, unsigned int size)
{
NzContext::EnsureContext();
GLuint previous;
glGetIntegerv(bufferTargetBinding[m_type], reinterpret_cast<GLint*>(&previous));
@@ -152,10 +161,10 @@ bool NzHardwareBuffer::Fill(const void* data, unsigned int offset, unsigned int
}
else
{
nzUInt8* ptr = lockBuffer(m_type, (size == m_parent->GetSize()) ? nzBufferLock_DiscardAndWrite : nzBufferLock_WriteOnly, offset, size);
nzUInt8* ptr = mapBuffer(m_type, (size == m_parent->GetSize()) ? nzBufferAccess_DiscardAndWrite : nzBufferAccess_WriteOnly, offset, size);
if (!ptr)
{
NazaraError("Failed to lock buffer");
NazaraError("Failed to map buffer");
return false;
}
@@ -164,7 +173,7 @@ bool NzHardwareBuffer::Fill(const void* data, unsigned int offset, unsigned int
if (glUnmapBuffer(bufferTarget[m_type]) != GL_TRUE)
{
// Une erreur rare est survenue, nous devons réinitialiser le buffer
NazaraError("Failed to unlock buffer, reinitialising content... (OpenGL error : 0x" + NzString::Number(glGetError(), 16) + ')');
NazaraError("Failed to unmap buffer, reinitialising content... (OpenGL error : 0x" + NzString::Number(glGetError(), 16) + ')');
glBufferData(bufferTarget[m_type], m_parent->GetSize(), nullptr, bufferUsage[m_parent->GetStorage()]);
@@ -189,8 +198,10 @@ bool NzHardwareBuffer::IsHardware() const
return true;
}
void* NzHardwareBuffer::Lock(nzBufferLock lock, unsigned int offset, unsigned int length)
void* NzHardwareBuffer::Map(nzBufferAccess access, unsigned int offset, unsigned int length)
{
NzContext::EnsureContext();
// Pour ne pas perturber le rendu, on interfère pas avec le binding déjà présent
GLuint previous;
glGetIntegerv(bufferTargetBinding[m_type], reinterpret_cast<GLint*>(&previous));
@@ -198,7 +209,7 @@ void* NzHardwareBuffer::Lock(nzBufferLock lock, unsigned int offset, unsigned in
if (previous != m_buffer)
glBindBuffer(bufferTarget[m_type], m_buffer);
void* ptr = lockBuffer(m_type, lock, offset, length);
void* ptr = mapBuffer(m_type, access, offset, length);
// Inutile de rebinder s'il n'y avait aucun buffer (Optimise les opérrations chaînées)
if (previous != m_buffer && previous != 0)
@@ -207,8 +218,10 @@ void* NzHardwareBuffer::Lock(nzBufferLock lock, unsigned int offset, unsigned in
return ptr;
}
bool NzHardwareBuffer::Unlock()
bool NzHardwareBuffer::Unmap()
{
NzContext::EnsureContext();
GLuint previous;
glGetIntegerv(bufferTargetBinding[m_type], reinterpret_cast<GLint*>(&previous));
@@ -218,7 +231,7 @@ bool NzHardwareBuffer::Unlock()
if (glUnmapBuffer(bufferTarget[m_type]) != GL_TRUE)
{
// Une erreur rare est survenue, nous devons réinitialiser le buffer
NazaraError("Failed to unlock buffer, reinitialising content... (OpenGL error : 0x" + NzString::Number(glGetError(), 16) + ')');
NazaraError("Failed to unmap buffer, reinitialising content... (OpenGL error : 0x" + NzString::Number(glGetError(), 16) + ')');
glBufferData(bufferTarget[m_type], m_parent->GetSize(), nullptr, bufferUsage[m_parent->GetStorage()]);

View File

@@ -28,8 +28,8 @@ class NzHardwareBuffer : public NzBufferImpl
bool IsHardware() const;
void* Lock(nzBufferLock lock, unsigned int offset = 0, unsigned int length = 0);
bool Unlock();
void* Map(nzBufferAccess access, unsigned int offset = 0, unsigned int length = 0);
bool Unmap();
private:
GLuint m_buffer;

View File

@@ -172,12 +172,12 @@ bool NzIndexBuffer::IsSequential() const
return m_buffer == nullptr;
}
void* NzIndexBuffer::Lock(nzBufferLock lock, unsigned int offset, unsigned int length)
void* NzIndexBuffer::Map(nzBufferAccess access, unsigned int offset, unsigned int length)
{
#if NAZARA_RENDERER_SAFE
if (!m_buffer)
{
NazaraError("Impossible to lock sequential index buffer");
NazaraError("Impossible to map sequential index buffer");
return nullptr;
}
@@ -188,10 +188,10 @@ void* NzIndexBuffer::Lock(nzBufferLock lock, unsigned int offset, unsigned int l
}
#endif
return m_buffer->Lock(lock, m_startIndex+offset, (length) ? length : m_indexCount-offset);
return m_buffer->Map(access, m_startIndex+offset, (length) ? length : m_indexCount-offset);
}
bool NzIndexBuffer::Unlock()
bool NzIndexBuffer::Unmap()
{
#if NAZARA_RENDERER_SAFE
if (!m_buffer)
@@ -201,5 +201,5 @@ bool NzIndexBuffer::Unlock()
}
#endif
return m_buffer->Unlock();
return m_buffer->Unmap();
}

View File

@@ -6,6 +6,7 @@
#include <Nazara/Renderer/OcclusionQuery.hpp>
#include <Nazara/Core/Error.hpp>
#include <Nazara/Renderer/Config.hpp>
#include <Nazara/Renderer/Context.hpp>
#include <Nazara/Renderer/Renderer.hpp>
#include <stdexcept>
#include <Nazara/Renderer/Debug.hpp>
@@ -15,9 +16,13 @@ m_id(0)
{
#if NAZARA_RENDERER_SAFE
if (IsSupported())
{
#endif
NzContext::EnsureContext();
glGenQueries(1, reinterpret_cast<GLuint*>(&m_id));
#if NAZARA_RENDERER_SAFE
}
else
{
NazaraError("Occlusion queries not supported");
@@ -37,21 +42,44 @@ m_id(0)
NzOcclusionQuery::~NzOcclusionQuery()
{
if (m_id)
glDeleteQueries(1, reinterpret_cast<GLuint*>(&m_id));
{
NzContext::EnsureContext();
GLuint query = static_cast<GLuint>(m_id);
glDeleteQueries(1, &query);
}
}
void NzOcclusionQuery::Begin()
{
#ifdef NAZARA_DEBUG
if (NzContext::GetCurrent() == nullptr)
{
NazaraError("No active context");
return;
}
#endif
glBeginQuery(GL_SAMPLES_PASSED, m_id);
}
void NzOcclusionQuery::End()
{
#ifdef NAZARA_DEBUG
if (NzContext::GetCurrent() == nullptr)
{
NazaraError("No active context");
return;
}
#endif
glEndQuery(GL_SAMPLES_PASSED);
}
unsigned int NzOcclusionQuery::GetResult() const
{
NzContext::EnsureContext();
GLuint result;
glGetQueryObjectuiv(m_id, GL_QUERY_RESULT, &result);
@@ -60,6 +88,8 @@ unsigned int NzOcclusionQuery::GetResult() const
bool NzOcclusionQuery::IsResultAvailable() const
{
NzContext::EnsureContext();
GLint available;
glGetQueryObjectiv(m_id, GL_QUERY_RESULT_AVAILABLE, &available);

View File

@@ -102,6 +102,11 @@ namespace
}
}
NzOpenGLFunc NzOpenGL::GetEntry(const NzString& entryPoint)
{
return LoadEntry(entryPoint.GetConstBuffer(), false);
}
unsigned int NzOpenGL::GetVersion()
{
return openGLversion;
@@ -116,16 +121,87 @@ bool NzOpenGL::Initialize()
}
// Le chargement des fonctions OpenGL nécessite un contexte OpenGL
// Le contexte de chargement ne peut pas être partagé car le contexte de référence n'existe pas encore
NzContextParameters parameters;
parameters.majorVersion = 2;
parameters.minorVersion = 0;
parameters.shared = false;
/*
Note: Même le contexte de chargement nécessite quelques fonctions de base pour correctement s'initialiser
Pour cette raison, deux contextes sont créés, le premier sert à récupérer les fonctions permetttant
de créer le second avec les bons paramètres.s
Non sérieusement si quelqu'un a une meilleure idée qu'il me le dise
*/
/****************************************Initialisation****************************************/
NzContext loadContext;
if (!loadContext.Create(parameters))
{
NazaraError("Failed to create load context");
Uninitialize();
return false;
}
#if defined(NAZARA_PLATFORM_WINDOWS)
wglCreateContextAttribs = reinterpret_cast<PFNWGLCREATECONTEXTATTRIBSARBPROC>(LoadEntry("wglCreateContextAttribsARB", false));
wglChoosePixelFormat = reinterpret_cast<PFNWGLCHOOSEPIXELFORMATARBPROC>(LoadEntry("wglChoosePixelFormatARB", false));
if (!wglChoosePixelFormat)
wglChoosePixelFormat = reinterpret_cast<PFNWGLCHOOSEPIXELFORMATEXTPROC>(LoadEntry("wglChoosePixelFormatEXT", false));
#elif defined(NAZARA_PLATFORM_LINUX)
glXCreateContextAttribs = reinterpret_cast<PFNGLXCREATECONTEXTATTRIBSARBPROC>(LoadEntry("glXCreateContextAttribsARB", false));
#endif
// Récupération de la version d'OpenGL
// Ce code se base sur le fait que la carte graphique renverra un contexte de compatibilité avec la plus haute version supportée
// Ce qui semble vrai au moins chez ATI/AMD et NVidia, mais si quelqu'un à une meilleure idée ...
glGetString = reinterpret_cast<PFNGLGETSTRINGPROC>(LoadEntry("glGetString"));
if (!glGetString)
{
NazaraError("Unable to load OpenGL: failed to load glGetString");
Uninitialize();
return false;
}
const GLubyte* version = glGetString(GL_VERSION);
if (!version)
{
NazaraError("Unable to retrieve OpenGL version");
Uninitialize();
return false;
}
unsigned int major = version[0] - '0';
unsigned int minor = version[2] - '0';
if (major == 0 || major > 9)
{
NazaraError("Unable to retrieve OpenGL major version");
return false;
}
if (minor > 9)
{
NazaraWarning("Unable to retrieve OpenGL minor version (using 0)");
minor = 0;
}
openGLversion = major*100 + minor*10;
parameters.debugMode = true; // Certaines extensions n'apparaissent qu'avec un contexte de debug (e.g. ARB_debug_output)
parameters.majorVersion = NzContextParameters::defaultMajorVersion = openGLversion/100;
parameters.minorVersion = NzContextParameters::defaultMinorVersion = (openGLversion%100)/10;
// Destruction implicite du premier contexte
if (!loadContext.Create(parameters))
{
NazaraError("Failed to create load context");
Uninitialize();
return false;
}
@@ -151,6 +227,7 @@ bool NzOpenGL::Initialize()
glColorMask = reinterpret_cast<PFNGLCOLORMASKPROC>(LoadEntry("glColorMask"));
glCullFace = reinterpret_cast<PFNGLCULLFACEPROC>(LoadEntry("glCullFace"));
glCompileShader = reinterpret_cast<PFNGLCOMPILESHADERPROC>(LoadEntry("glCompileShader"));
glCopyTexSubImage2D = reinterpret_cast<PFNGLCOPYTEXSUBIMAGE2DPROC>(LoadEntry("glCopyTexSubImage2D"));
glDeleteBuffers = reinterpret_cast<PFNGLDELETEBUFFERSPROC>(LoadEntry("glDeleteBuffers"));
glDeleteQueries = reinterpret_cast<PFNGLDELETEQUERIESPROC>(LoadEntry("glDeleteQueries"));
glDeleteProgram = reinterpret_cast<PFNGLDELETEPROGRAMPROC>(LoadEntry("glDeleteProgram"));
@@ -182,14 +259,17 @@ bool NzOpenGL::Initialize()
glGetShaderInfoLog = reinterpret_cast<PFNGLGETSHADERINFOLOGPROC>(LoadEntry("glGetShaderInfoLog"));
glGetShaderiv = reinterpret_cast<PFNGLGETSHADERIVPROC>(LoadEntry("glGetShaderiv"));
glGetShaderSource = reinterpret_cast<PFNGLGETSHADERSOURCEPROC>(LoadEntry("glGetShaderSource"));
glGetString = reinterpret_cast<PFNGLGETSTRINGPROC>(LoadEntry("glGetString"));
glGetTexImage = reinterpret_cast<PFNGLGETTEXIMAGEPROC>(LoadEntry("glGetTexImage"));
glGetTexLevelParameterfv = reinterpret_cast<PFNGLGETTEXLEVELPARAMETERFVPROC>(LoadEntry("glGetTexLevelParameterfv"));
glGetTexLevelParameteriv = reinterpret_cast<PFNGLGETTEXLEVELPARAMETERIVPROC>(LoadEntry("glGetTexLevelParameteriv"));
glGetTexParameterfv = reinterpret_cast<PFNGLGETTEXPARAMETERFVPROC>(LoadEntry("glGetTexParameterfv"));
glGetTexParameteriv = reinterpret_cast<PFNGLGETTEXPARAMETERIVPROC>(LoadEntry("glGetTexParameteriv"));
glGetUniformLocation = reinterpret_cast<PFNGLGETUNIFORMLOCATIONPROC>(LoadEntry("glGetUniformLocation"));
glLinkProgram = reinterpret_cast<PFNGLLINKPROGRAMPROC>(LoadEntry("glLinkProgram"));
glMapBuffer = reinterpret_cast<PFNGLMAPBUFFERPROC>(LoadEntry("glMapBuffer"));
glPixelStorei = reinterpret_cast<PFNGLPIXELSTOREIPROC>(LoadEntry("glPixelStorei"));
glPolygonMode = reinterpret_cast<PFNGLPOLYGONMODEPROC>(LoadEntry("glPolygonMode"));
glReadPixels = reinterpret_cast<PFNGLREADPIXELSPROC>(LoadEntry("glReadPixels"));
glScissor = reinterpret_cast<PFNGLSCISSORPROC>(LoadEntry("glScissor"));
glShaderSource = reinterpret_cast<PFNGLSHADERSOURCEPROC>(LoadEntry("glShaderSource"));
glStencilFunc = reinterpret_cast<PFNGLSTENCILFUNCPROC>(LoadEntry("glStencilFunc"));
@@ -223,50 +303,13 @@ bool NzOpenGL::Initialize()
glMapBufferRange = reinterpret_cast<PFNGLMAPBUFFERRANGEPROC>(LoadEntry("glMapBufferRange", false));
#if defined(NAZARA_PLATFORM_WINDOWS)
wglCreateContextAttribs = reinterpret_cast<PFNWGLCREATECONTEXTATTRIBSARBPROC>(LoadEntry("wglCreateContextAttribsARB", false));
wglChoosePixelFormat = reinterpret_cast<PFNWGLCHOOSEPIXELFORMATARBPROC>(LoadEntry("wglChoosePixelFormatARB", false));
if (!wglChoosePixelFormat)
wglChoosePixelFormat = reinterpret_cast<PFNWGLCHOOSEPIXELFORMATEXTPROC>(LoadEntry("wglChoosePixelFormatEXT", false));
wglGetExtensionsStringARB = reinterpret_cast<PFNWGLGETEXTENSIONSSTRINGARBPROC>(LoadEntry("wglGetExtensionsStringARB", false));
wglGetExtensionsStringEXT = reinterpret_cast<PFNWGLGETEXTENSIONSSTRINGEXTPROC>(LoadEntry("wglGetExtensionsStringEXT", false));
wglSwapInterval = reinterpret_cast<PFNWGLSWAPINTERVALEXTPROC>(LoadEntry("wglSwapIntervalEXT", false));
#elif defined(NAZARA_PLATFORM_LINUX)
glXCreateContextAttribs = reinterpret_cast<PFNGLXCREATECONTEXTATTRIBSARBPROC>(LoadEntry("glXCreateContextAttribsARB", false));
glXSwapInterval = reinterpret_cast<PFNGLXSWAPINTERVALSGIPROC>(LoadEntry("glXSwapIntervalSGI", false));
#endif
// Récupération de la version d'OpenGL
// Ce code se base sur le fait que la carte graphique renverra un contexte de compatibilité avec la plus haute version supportée
// Ce qui semble vrai au moins chez ATI/AMD et NVidia, mais si quelqu'un à une meilleure idée ...
const GLubyte* version = glGetString(GL_VERSION);
if (!version)
{
NazaraError("Unable to retrieve OpenGL version");
Uninitialize();
return false;
}
unsigned int major = version[0] - '0';
unsigned int minor = version[2] - '0';
if (major == 0 || major > 9)
{
NazaraError("Unable to retrieve OpenGL major version");
Uninitialize();
return false;
}
if (minor > 9)
{
NazaraWarning("Unable to retrieve OpenGL minor version (using 0)");
minor = 0;
}
openGLversion = major*100 + minor*10;
/****************************************Extensions****************************************/
if (!glGetStringi || !LoadExtensions3())
@@ -296,6 +339,24 @@ bool NzOpenGL::Initialize()
// AnisotropicFilter
openGLextensions[NzOpenGL::AnisotropicFilter] = IsSupported("GL_EXT_texture_filter_anisotropic");
// DebugOutput
if (IsSupported("GL_ARB_debug_output"))
{
try
{
glDebugMessageControl = reinterpret_cast<PFNGLDEBUGMESSAGECONTROLARBPROC>(LoadEntry("glDebugMessageControlARB"));
glDebugMessageInsert = reinterpret_cast<PFNGLDEBUGMESSAGEINSERTARBPROC>(LoadEntry("glDebugMessageInsertARB"));
glDebugMessageCallback = reinterpret_cast<PFNGLDEBUGMESSAGECALLBACKARBPROC>(LoadEntry("glDebugMessageCallbackARB"));
glGetDebugMessageLog = reinterpret_cast<PFNGLGETDEBUGMESSAGELOGARBPROC>(LoadEntry("glGetDebugMessageLogARB"));
openGLextensions[NzOpenGL::DebugOutput] = true;
}
catch (const std::exception& e)
{
NazaraError("Failed to load GL_ARB_debug_output: " + NzString(e.what()));
}
}
// FP64
if (openGLversion >= 400 || IsSupported("GL_ARB_gpu_shader_fp64"))
{
@@ -314,89 +375,133 @@ bool NzOpenGL::Initialize()
}
}
// Framebuffer_Object
try
{
glBindFramebuffer = reinterpret_cast<PFNGLBINDFRAMEBUFFERPROC>(LoadEntry("glBindFramebuffer"));
glBindRenderbuffer = reinterpret_cast<PFNGLBINDRENDERBUFFERPROC>(LoadEntry("glBindRenderbuffer"));
glCheckFramebufferStatus = reinterpret_cast<PFNGLCHECKFRAMEBUFFERSTATUSPROC>(LoadEntry("glCheckFramebufferStatus"));
glDeleteFramebuffers = reinterpret_cast<PFNGLDELETEFRAMEBUFFERSPROC>(LoadEntry("glDeleteFramebuffers"));
glDeleteRenderbuffers = reinterpret_cast<PFNGLDELETERENDERBUFFERSPROC>(LoadEntry("glDeleteRenderbuffers"));
glFramebufferRenderbuffer = reinterpret_cast<PFNGLFRAMEBUFFERRENDERBUFFERPROC>(LoadEntry("glFramebufferRenderbuffer"));
glFramebufferTexture2D = reinterpret_cast<PFNGLFRAMEBUFFERTEXTURE2DPROC>(LoadEntry("glFramebufferTexture2D"));
glGenerateMipmap = reinterpret_cast<PFNGLGENERATEMIPMAPPROC>(LoadEntry("glGenerateMipmap"));
glGenFramebuffers = reinterpret_cast<PFNGLGENFRAMEBUFFERSPROC>(LoadEntry("glGenFramebuffers"));
glGenRenderbuffers = reinterpret_cast<PFNGLGENRENDERBUFFERSPROC>(LoadEntry("glGenRenderbuffers"));
glRenderbufferStorage = reinterpret_cast<PFNGLRENDERBUFFERSTORAGEPROC>(LoadEntry("glRenderbufferStorage"));
openGLextensions[NzOpenGL::Framebuffer_Object] = true;
}
catch (const std::exception& e)
{
if (openGLversion >= 300)
NazaraWarning("Failed to load core FBOs (" + NzString(e.what()) + ")");
if (IsSupported("GL_EXT_framebuffer_object"))
{
try
{
glBindFramebuffer = reinterpret_cast<PFNGLBINDFRAMEBUFFEREXTPROC>(LoadEntry("glBindFramebufferEXT"));
glBindRenderbuffer = reinterpret_cast<PFNGLBINDRENDERBUFFEREXTPROC>(LoadEntry("glBindRenderbufferEXT"));
glCheckFramebufferStatus = reinterpret_cast<PFNGLCHECKFRAMEBUFFERSTATUSEXTPROC>(LoadEntry("glCheckFramebufferStatusEXT"));
glDeleteFramebuffers = reinterpret_cast<PFNGLDELETEFRAMEBUFFERSEXTPROC>(LoadEntry("glDeleteFramebuffersEXT"));
glDeleteRenderbuffers = reinterpret_cast<PFNGLDELETERENDERBUFFERSEXTPROC>(LoadEntry("glDeleteRenderbuffersEXT"));
glFramebufferRenderbuffer = reinterpret_cast<PFNGLFRAMEBUFFERRENDERBUFFEREXTPROC>(LoadEntry("glFramebufferRenderbufferEXT"));
glFramebufferTexture2D = reinterpret_cast<PFNGLFRAMEBUFFERTEXTURE2DEXTPROC>(LoadEntry("glFramebufferTexture2DEXT"));
glGenerateMipmap = reinterpret_cast<PFNGLGENERATEMIPMAPEXTPROC>(LoadEntry("glGenerateMipmapEXT"));
glGenFramebuffers = reinterpret_cast<PFNGLGENFRAMEBUFFERSEXTPROC>(LoadEntry("glGenFramebuffersEXT"));
glGenRenderbuffers = reinterpret_cast<PFNGLGENRENDERBUFFERSEXTPROC>(LoadEntry("glGenRenderbuffersEXT"));
glRenderbufferStorage = reinterpret_cast<PFNGLRENDERBUFFERSTORAGEEXTPROC>(LoadEntry("glRenderbufferStorageEXT"));
openGLextensions[NzOpenGL::Framebuffer_Object] = true;
}
catch (const std::exception& e)
{
NazaraError("Failed to load EXT_framebuffer_object: " + NzString(e.what()));
}
}
}
// Texture3D
if (IsSupported("GL_EXT_texture3D"))
// FrameBufferObject
if (openGLversion >= 300 || IsSupported("GL_ARB_framebuffer_object"))
{
try
{
glTexImage3D = reinterpret_cast<PFNGLTEXIMAGE3DEXTPROC>(LoadEntry("glTexImage3DEXT"));
glTexSubImage3D = reinterpret_cast<PFNGLTEXSUBIMAGE3DEXTPROC>(LoadEntry("glTexSubImage3DEXT"));
glBindFramebuffer = reinterpret_cast<PFNGLBINDFRAMEBUFFERPROC>(LoadEntry("glBindFramebuffer"));
glBindRenderbuffer = reinterpret_cast<PFNGLBINDRENDERBUFFERPROC>(LoadEntry("glBindRenderbuffer"));
glCheckFramebufferStatus = reinterpret_cast<PFNGLCHECKFRAMEBUFFERSTATUSPROC>(LoadEntry("glCheckFramebufferStatus"));
glDeleteFramebuffers = reinterpret_cast<PFNGLDELETEFRAMEBUFFERSPROC>(LoadEntry("glDeleteFramebuffers"));
glDeleteRenderbuffers = reinterpret_cast<PFNGLDELETERENDERBUFFERSPROC>(LoadEntry("glDeleteRenderbuffers"));
glFramebufferRenderbuffer = reinterpret_cast<PFNGLFRAMEBUFFERRENDERBUFFERPROC>(LoadEntry("glFramebufferRenderbuffer"));
glFramebufferTexture2D = reinterpret_cast<PFNGLFRAMEBUFFERTEXTURE2DPROC>(LoadEntry("glFramebufferTexture2D"));
glGenerateMipmap = reinterpret_cast<PFNGLGENERATEMIPMAPPROC>(LoadEntry("glGenerateMipmap"));
glGenFramebuffers = reinterpret_cast<PFNGLGENFRAMEBUFFERSPROC>(LoadEntry("glGenFramebuffers"));
glGenRenderbuffers = reinterpret_cast<PFNGLGENRENDERBUFFERSPROC>(LoadEntry("glGenRenderbuffers"));
glRenderbufferStorage = reinterpret_cast<PFNGLRENDERBUFFERSTORAGEPROC>(LoadEntry("glRenderbufferStorage"));
openGLextensions[NzOpenGL::Texture3D] = true;
openGLextensions[NzOpenGL::FrameBufferObject] = true;
}
catch (const std::exception& e)
{
NazaraError("Failed to load EXT_texture3D: " + NzString(e.what()));
NazaraError("Failed to load ARB_framebuffer_object: (" + NzString(e.what()) + ")");
}
}
/****************************************Contextes****************************************/
NzContextParameters::defaultMajorVersion = openGLversion/100;
NzContextParameters::defaultMinorVersion = (openGLversion%100)/10;
/*
NzContextParameters::defaultMajorVersion = std::min(openGLversion/100, 2U);
NzContextParameters::defaultMinorVersion = std::min((openGLversion%100)/10, 1U);
*/
if (!NzContext::InitializeReference())
// SeparateShaderObjects
if (openGLversion >= 400 || IsSupported("GL_ARB_gpu_shader_fp64"))
{
NazaraError("Failed to initialize reference context");
glProgramUniform1f = reinterpret_cast<PFNGLPROGRAMUNIFORM1FPROC>(LoadEntry("glProgramUniform1f"));
glProgramUniform1i = reinterpret_cast<PFNGLPROGRAMUNIFORM1IPROC>(LoadEntry("glProgramUniform1i"));
glProgramUniform2fv = reinterpret_cast<PFNGLPROGRAMUNIFORM2FVPROC>(LoadEntry("glProgramUniform2fv"));
glProgramUniform3fv = reinterpret_cast<PFNGLPROGRAMUNIFORM3FVPROC>(LoadEntry("glProgramUniform3fv"));
glProgramUniform4fv = reinterpret_cast<PFNGLPROGRAMUNIFORM4FVPROC>(LoadEntry("glProgramUniform4fv"));
glProgramUniformMatrix4fv = reinterpret_cast<PFNGLPROGRAMUNIFORMMATRIX4FVPROC>(LoadEntry("glProgramUniformMatrix4fv"));
if (openGLextensions[NzOpenGL::FP64])
{
glProgramUniform1d = reinterpret_cast<PFNGLPROGRAMUNIFORM1DPROC>(LoadEntry("glProgramUniform1d"));
glProgramUniform2dv = reinterpret_cast<PFNGLPROGRAMUNIFORM2DVPROC>(LoadEntry("glProgramUniform2dv"));
glProgramUniform3dv = reinterpret_cast<PFNGLPROGRAMUNIFORM3DVPROC>(LoadEntry("glProgramUniform3dv"));
glProgramUniform4dv = reinterpret_cast<PFNGLPROGRAMUNIFORM4DVPROC>(LoadEntry("glProgramUniform4dv"));
glProgramUniformMatrix4dv = reinterpret_cast<PFNGLPROGRAMUNIFORMMATRIX4DVPROC>(LoadEntry("glProgramUniformMatrix4dv"));
}
openGLextensions[NzOpenGL::SeparateShaderObjects] = true;
}
// Texture3D
try
{
glTexImage3D = reinterpret_cast<PFNGLTEXIMAGE3DPROC>(LoadEntry("glTexImage3D"));
glTexSubImage3D = reinterpret_cast<PFNGLTEXSUBIMAGE3DPROC>(LoadEntry("glTexSubImage3D"));
openGLextensions[NzOpenGL::Texture3D] = true;
}
catch (const std::exception& e)
{
if (openGLversion >= 120)
NazaraWarning("Failed to load core texture 3D (" + NzString(e.what()) + ")");
if (IsSupported("GL_EXT_texture3D"))
{
try
{
// Hacky: Normalement incompatible à cause du internalFormat, GLenum pour l'extension et GLint pour le noyau
// Mais la taille du type étant la même (GLenum est un typedef équivalent à GLint) et Nazara n'utilisant pas
// Ce qui cause l'incompatibilité (les paramètres 1,2,3,4), je prends cette liberté
glTexImage3D = reinterpret_cast<PFNGLTEXIMAGE3DPROC>(LoadEntry("glTexImage3DEXT"));
glTexSubImage3D = reinterpret_cast<PFNGLTEXSUBIMAGE3DEXTPROC>(LoadEntry("glTexSubImage3DEXT"));
openGLextensions[NzOpenGL::Texture3D] = true;
}
catch (const std::exception& e)
{
NazaraError("Failed to load EXT_texture3D: " + NzString(e.what()));
}
}
}
// TextureCompression_s3tc
openGLextensions[NzOpenGL::TextureCompression_s3tc] = IsSupported("GL_EXT_texture_compression_s3tc");
// TextureStorage
if (openGLversion >= 420 || IsSupported("GL_ARB_texture_storage"))
{
try
{
glTexStorage1D = reinterpret_cast<PFNGLTEXSTORAGE1DPROC>(LoadEntry("glTexStorage1D"));
glTexStorage2D = reinterpret_cast<PFNGLTEXSTORAGE2DPROC>(LoadEntry("glTexStorage2D"));
glTexStorage3D = reinterpret_cast<PFNGLTEXSTORAGE3DPROC>(LoadEntry("glTexStorage3D"));
openGLextensions[NzOpenGL::TextureStorage] = true;
}
catch (const std::exception& e)
{
NazaraError("Failed to load ARB_texture_storage: " + NzString(e.what()));
}
}
// VertexArrayObject
if (openGLversion >= 300 || IsSupported("GL_ARB_vertex_array_object"))
{
try
{
glBindVertexArray = reinterpret_cast<PFNGLBINDVERTEXARRAYPROC>(LoadEntry("glBindVertexArray"));
glDeleteVertexArrays = reinterpret_cast<PFNGLDELETEVERTEXARRAYSPROC>(LoadEntry("glDeleteVertexArrays"));
glGenVertexArrays = reinterpret_cast<PFNGLGENVERTEXARRAYSPROC>(LoadEntry("glGenVertexArrays"));
openGLextensions[NzOpenGL::VertexArrayObject] = true;
}
catch (const std::exception& e)
{
NazaraError("Failed to load ARB_vertex_array_object: " + NzString(e.what()));
}
}
/****************************************Contexte de référence****************************************/
///FIXME: Utiliser le contexte de chargement comme référence ? (Vérifier mode debug)
if (!NzContext::Initialize())
{
NazaraError("Failed to initialize contexts");
Uninitialize();
return false;
}
NzContextParameters::defaultShareContext = NzContext::GetReference();
return true;
}
@@ -412,7 +517,7 @@ bool NzOpenGL::IsSupported(const NzString& string)
void NzOpenGL::Uninitialize()
{
NzContext::UninitializeReference();
NzContext::Uninitialize();
for (bool& ext : openGLextensions)
ext = false;
@@ -431,6 +536,7 @@ PFNGLBINDBUFFERPROC glBindBuffer = nullptr;
PFNGLBINDFRAMEBUFFERPROC glBindFramebuffer = nullptr;
PFNGLBINDRENDERBUFFERPROC glBindRenderbuffer = nullptr;
PFNGLBINDTEXTUREPROC glBindTexture = nullptr;
PFNGLBINDVERTEXARRAYPROC glBindVertexArray = nullptr;
PFNGLBLENDFUNCPROC glBlendFunc = nullptr;
PFNGLBUFFERDATAPROC glBufferData = nullptr;
PFNGLBUFFERSUBDATAPROC glBufferSubData = nullptr;
@@ -444,6 +550,10 @@ PFNGLCHECKFRAMEBUFFERSTATUSPROC glCheckFramebufferStatus = nullptr;
PFNGLCOLORMASKPROC glColorMask = nullptr;
PFNGLCULLFACEPROC glCullFace = nullptr;
PFNGLCOMPILESHADERPROC glCompileShader = nullptr;
PFNGLCOPYTEXSUBIMAGE2DPROC glCopyTexSubImage2D = nullptr;
PFNGLDEBUGMESSAGECONTROLARBPROC glDebugMessageControl = nullptr;
PFNGLDEBUGMESSAGEINSERTARBPROC glDebugMessageInsert = nullptr;
PFNGLDEBUGMESSAGECALLBACKARBPROC glDebugMessageCallback = nullptr;
PFNGLDELETEBUFFERSPROC glDeleteBuffers = nullptr;
PFNGLDELETEFRAMEBUFFERSPROC glDeleteFramebuffers = nullptr;
PFNGLDELETEPROGRAMPROC glDeleteProgram = nullptr;
@@ -451,6 +561,7 @@ PFNGLDELETEQUERIESPROC glDeleteQueries = nullptr;
PFNGLDELETERENDERBUFFERSPROC glDeleteRenderbuffers = nullptr;
PFNGLDELETESHADERPROC glDeleteShader = nullptr;
PFNGLDELETETEXTURESPROC glDeleteTextures = nullptr;
PFNGLDELETEVERTEXARRAYSPROC glDeleteVertexArrays = nullptr;
PFNGLDEPTHFUNCPROC glDepthFunc = nullptr;
PFNGLDEPTHMASKPROC glDepthMask = nullptr;
PFNGLDISABLEPROC glDisable = nullptr;
@@ -471,7 +582,9 @@ PFNGLGENFRAMEBUFFERSPROC glGenFramebuffers = nullptr;
PFNGLGENRENDERBUFFERSPROC glGenRenderbuffers = nullptr;
PFNGLGENQUERIESPROC glGenQueries = nullptr;
PFNGLGENTEXTURESPROC glGenTextures = nullptr;
PFNGLGENVERTEXARRAYSPROC glGenVertexArrays = nullptr;
PFNGLGETBUFFERPARAMETERIVPROC glGetBufferParameteriv = nullptr;
PFNGLGETDEBUGMESSAGELOGARBPROC glGetDebugMessageLog = nullptr;
PFNGLGETERRORPROC glGetError = nullptr;
PFNGLGETINTEGERVPROC glGetIntegerv = nullptr;
PFNGLGETPROGRAMIVPROC glGetProgramiv = nullptr;
@@ -485,24 +598,44 @@ PFNGLGETSHADERSOURCEPROC glGetShaderSource = nullptr;
PFNGLGETSTRINGPROC glGetString = nullptr;
PFNGLGETSTRINGIPROC glGetStringi = nullptr;
PFNGLGETTEXIMAGEPROC glGetTexImage = nullptr;
PFNGLGETTEXLEVELPARAMETERFVPROC glGetTexLevelParameterfv = nullptr;
PFNGLGETTEXLEVELPARAMETERIVPROC glGetTexLevelParameteriv = nullptr;
PFNGLGETTEXPARAMETERFVPROC glGetTexParameterfv = nullptr;
PFNGLGETTEXPARAMETERIVPROC glGetTexParameteriv = nullptr;
PFNGLGETUNIFORMLOCATIONPROC glGetUniformLocation = nullptr;
PFNGLLINKPROGRAMPROC glLinkProgram = nullptr;
PFNGLMAPBUFFERPROC glMapBuffer = nullptr;
PFNGLMAPBUFFERRANGEPROC glMapBufferRange = nullptr;
PFNGLPIXELSTOREIPROC glPixelStorei = nullptr;
PFNGLPOLYGONMODEPROC glPolygonMode = nullptr;
PFNGLPROGRAMUNIFORM1DPROC glProgramUniform1d = nullptr;
PFNGLPROGRAMUNIFORM1FPROC glProgramUniform1f = nullptr;
PFNGLPROGRAMUNIFORM1IPROC glProgramUniform1i = nullptr;
PFNGLPROGRAMUNIFORM2DVPROC glProgramUniform2dv = nullptr;
PFNGLPROGRAMUNIFORM2FVPROC glProgramUniform2fv = nullptr;
PFNGLPROGRAMUNIFORM3DVPROC glProgramUniform3dv = nullptr;
PFNGLPROGRAMUNIFORM3FVPROC glProgramUniform3fv = nullptr;
PFNGLPROGRAMUNIFORM4DVPROC glProgramUniform4dv = nullptr;
PFNGLPROGRAMUNIFORM4FVPROC glProgramUniform4fv = nullptr;
PFNGLPROGRAMUNIFORMMATRIX4DVPROC glProgramUniformMatrix4dv = nullptr;
PFNGLPROGRAMUNIFORMMATRIX4FVPROC glProgramUniformMatrix4fv = nullptr;
PFNGLREADPIXELSPROC glReadPixels = nullptr;
PFNGLRENDERBUFFERSTORAGEPROC glRenderbufferStorage = nullptr;
PFNGLSCISSORPROC glScissor = nullptr;
PFNGLSHADERSOURCEPROC glShaderSource = nullptr;
PFNGLSTENCILFUNCPROC glStencilFunc = nullptr;
PFNGLSTENCILOPPROC glStencilOp = nullptr;
PFNGLTEXIMAGE1DPROC glTexImage1D = nullptr;
PFNGLTEXIMAGE2DPROC glTexImage2D = nullptr;
PFNGLTEXIMAGE3DEXTPROC glTexImage3D = nullptr;
PFNGLTEXIMAGE3DPROC glTexImage3D = nullptr;
PFNGLTEXPARAMETERFPROC glTexParameterf = nullptr;
PFNGLTEXPARAMETERIPROC glTexParameteri = nullptr;
PFNGLTEXSTORAGE1DPROC glTexStorage1D = nullptr;
PFNGLTEXSTORAGE2DPROC glTexStorage2D = nullptr;
PFNGLTEXSTORAGE3DPROC glTexStorage3D = nullptr;
PFNGLTEXSUBIMAGE1DPROC glTexSubImage1D = nullptr;
PFNGLTEXSUBIMAGE2DPROC glTexSubImage2D = nullptr;
PFNGLTEXSUBIMAGE3DEXTPROC glTexSubImage3D = nullptr;
PFNGLTEXSUBIMAGE3DPROC glTexSubImage3D = nullptr;
PFNGLUNIFORM1DPROC glUniform1d = nullptr;
PFNGLUNIFORM1FPROC glUniform1f = nullptr;
PFNGLUNIFORM1IPROC glUniform1i = nullptr;

View File

@@ -25,5 +25,5 @@ bool NzRenderTarget::SetActive(bool active)
void NzRenderTarget::Desactivate()
{
// Seuls les target sans contextes (ex: RenderTexture) nécessitent une désactivation
// Seuls les target sans contextes (ex: NzRenderTexture) nécessitent une désactivation
}

View File

@@ -5,17 +5,11 @@
#include <Nazara/Renderer/OpenGL.hpp>
#include <Nazara/Renderer/RenderWindow.hpp>
#include <Nazara/Core/Error.hpp>
#include <Nazara/Renderer/Config.hpp>
#include <Nazara/Renderer/Context.hpp>
#include <Nazara/Renderer/ContextParameters.hpp>
#include <Nazara/Renderer/Texture.hpp>
#include <stdexcept>
#include <Nazara/Renderer/Debug.hpp>
namespace
{
NzContextParameters invalidContextParameters;
NzRenderTargetParameters invalidRTParameters;
}
NzRenderWindow::NzRenderWindow() :
m_context(nullptr)
{
@@ -25,21 +19,107 @@ NzRenderWindow::NzRenderWindow(NzVideoMode mode, const NzString& title, nzUInt32
m_context(nullptr)
{
Create(mode, title, style, parameters);
#ifdef NAZARA_DEBUG
if (!m_impl)
{
NazaraError("Failed to create render window");
throw std::runtime_error("Constructor failed");
}
#endif
}
NzRenderWindow::NzRenderWindow(NzWindowHandle handle, const NzContextParameters& parameters) :
m_context(nullptr)
{
Create(handle, parameters);
#ifdef NAZARA_DEBUG
if (!m_impl)
{
NazaraError("Failed to create render window");
throw std::runtime_error("Constructor failed");
}
#endif
}
NzRenderWindow::~NzRenderWindow()
{
}
bool NzRenderWindow::CanActivate() const
bool NzRenderWindow::CopyToImage(NzImage* image)
{
return m_impl != nullptr && m_context != nullptr;
#if NAZARA_RENDERER_SAFE
if (!m_context)
{
NazaraError("Window has not been created");
return false;
}
if (!image)
{
NazaraError("Image must be valid");
return false;
}
#endif
if (!m_context->SetActive(true))
{
NazaraError("Failed to activate context");
return false;
}
NzVector2ui size = GetSize();
if (!image->Create(nzImageType_2D, nzPixelFormat_RGBA8, size.x, size.y, 1, 1))
{
NazaraError("Failed to create image");
return false;
}
nzUInt8* pixels = image->GetPixels();
glReadPixels(0, 0, size.x, size.y, GL_RGBA, GL_UNSIGNED_BYTE, pixels);
image->FlipVertically();
return true;
}
bool NzRenderWindow::CopyToTexture(NzTexture* texture)
{
#if NAZARA_RENDERER_SAFE
if (!m_context)
{
NazaraError("Window has not been created");
return false;
}
if (!texture)
{
NazaraError("Texture must be valid");
return false;
}
#endif
if (!m_context->SetActive(true))
{
NazaraError("Failed to activate context");
return false;
}
NzVector2ui size = GetSize();
if (!texture->Create(nzImageType_2D, nzPixelFormat_RGBA8, size.x, size.y, 1, 1, true))
{
NazaraError("Failed to create texture");
return false;
}
glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, size.x, size.y);
texture->Unlock();
return true;
}
bool NzRenderWindow::Create(NzVideoMode mode, const NzString& title, nzUInt32 style, const NzContextParameters& parameters)
@@ -56,7 +136,7 @@ bool NzRenderWindow::Create(NzWindowHandle handle, const NzContextParameters& pa
void NzRenderWindow::Display()
{
if (m_context)
if (m_context && m_parameters.doubleBuffered)
m_context->SwapBuffers();
}
@@ -64,49 +144,35 @@ void NzRenderWindow::EnableVerticalSync(bool enabled)
{
if (m_context)
{
#if defined(NAZARA_PLATFORM_WINDOWS)
#if defined(NAZARA_PLATFORM_WINDOWS)
if (!m_context->SetActive(true))
{
NazaraError("Unable to activate context");
return;
}
{
NazaraError("Failed to activate context");
return;
}
if (wglSwapInterval)
wglSwapInterval(enabled ? 1 : 0);
else
#elif defined(NAZARA_PLATFORM_LINUX)
#elif defined(NAZARA_PLATFORM_LINUX)
if (!m_context->SetActive(true))
{
NazaraError("Unable to activate context");
NazaraError("Failed to activate context");
return;
}
if (glXSwapInterval)
glXSwapInterval(enabled ? 1 : 0);
else
#else
#error Vertical Sync is not supported on this platform
#endif
#else
#error Vertical Sync is not supported on this platform
#endif
NazaraError("Vertical Sync is not supported on this platform");
}
else
NazaraError("No context");
}
NzRenderTargetParameters NzRenderWindow::GetRenderTargetParameters() const
{
if (m_context)
{
const NzContextParameters& parameters = m_context->GetParameters();
return NzRenderTargetParameters(parameters.antialiasingLevel, parameters.depthBits, parameters.stencilBits);
}
else
{
NazaraError("Window not created/context not initialized");
return NzRenderTargetParameters();
}
}
NzContextParameters NzRenderWindow::GetContextParameters() const
{
if (m_context)
@@ -118,14 +184,52 @@ NzContextParameters NzRenderWindow::GetContextParameters() const
}
}
unsigned int NzRenderWindow::GetHeight() const
{
return NzWindow::GetHeight();
}
NzRenderTargetParameters NzRenderWindow::GetParameters() const
{
if (m_context)
{
const NzContextParameters& parameters = m_context->GetParameters();
return NzRenderTargetParameters(parameters.antialiasingLevel, parameters.depthBits, parameters.stencilBits);
}
else
{
NazaraError("Window not created/context not initialized");
return NzRenderTargetParameters();
}
}
unsigned int NzRenderWindow::GetWidth() const
{
return NzWindow::GetWidth();
}
bool NzRenderWindow::HasContext() const
{
return true;
}
bool NzRenderWindow::IsValid() const
{
return m_impl != nullptr && m_context != nullptr;
}
bool NzRenderWindow::Activate()
{
return m_context->SetActive(true);
if (m_context->SetActive(true))
{
glDrawBuffer((m_parameters.doubleBuffered) ? GL_BACK : GL_FRONT);
return true;
}
else
{
NazaraError("Failed to activate window's context");
return false;
}
}
void NzRenderWindow::OnClose()
@@ -137,6 +241,7 @@ bool NzRenderWindow::OnCreate()
{
m_parameters.doubleBuffered = true;
m_parameters.window = GetHandle();
m_context = new NzContext;
if (!m_context->Create(m_parameters))
{

View File

@@ -4,6 +4,7 @@
#include <Nazara/Renderer/OpenGL.hpp> // Pour éviter une redéfinition de WIN32_LEAN_AND_MEAN
#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>
@@ -13,29 +14,123 @@
#include <Nazara/Renderer/Shader.hpp>
#include <Nazara/Renderer/ShaderImpl.hpp>
#include <Nazara/Renderer/VertexBuffer.hpp>
#include <Nazara/Renderer/VertexDeclaration.hpp>
#include <Nazara/Utility/Utility.hpp>
#include <stdexcept>
#include <Nazara/Renderer/Debug.hpp>
namespace
{
GLenum openglPrimitive[] = {
GL_LINES, // nzPrimitiveType_LineList,
GL_LINE_STRIP, // nzPrimitiveType_LineStrip,
GL_POINTS, // nzPrimitiveType_PointList,
GL_TRIANGLES, // nzPrimitiveType_TriangleList,
const nzUInt8 attribIndex[] =
{
2, // nzElementUsage_Diffuse
1, // nzElementUsage_Normal
0, // nzElementUsage_Position
3, // nzElementUsage_Tangent
4 // nzElementUsage_TexCoord
};
const GLenum blendFunc[] =
{
GL_DST_ALPHA, // nzBlendFunc_DestAlpha
GL_DST_COLOR, // nzBlendFunc_DestColor
GL_SRC_ALPHA, // nzBlendFunc_SrcAlpha
GL_SRC_COLOR, // nzBlendFunc_SrcColor
GL_ONE_MINUS_DST_ALPHA, // nzBlendFunc_InvDestAlpha
GL_ONE_MINUS_DST_COLOR, // nzBlendFunc_InvDestColor
GL_ONE_MINUS_SRC_ALPHA, // nzBlendFunc_InvSrcAlpha
GL_ONE_MINUS_SRC_COLOR, // nzBlendFunc_InvSrcColor
GL_ONE, // nzBlendFunc_One
GL_ZERO // nzBlendFunc_Zero
};
const GLenum faceCullingMode[] =
{
GL_BACK, // nzFaceCulling_Back
GL_FRONT, // nzFaceCulling_Front
GL_FRONT_AND_BACK // nzFaceCulling_FrontAndBack
};
const GLenum faceFillingMode[] =
{
GL_POINT, // nzFaceFilling_Point
GL_LINE, // nzFaceFilling_Line
GL_FILL // nzFaceFilling_Fill
};
const GLenum openglPrimitive[] =
{
GL_LINES, // nzPrimitiveType_LineList,
GL_LINE_STRIP, // nzPrimitiveType_LineStrip,
GL_POINTS, // nzPrimitiveType_PointList,
GL_TRIANGLES, // nzPrimitiveType_TriangleList,
GL_TRIANGLE_STRIP, // nzPrimitiveType_TriangleStrip,
GL_TRIANGLE_FAN // nzPrimitiveType_TriangleFan
GL_TRIANGLE_FAN // nzPrimitiveType_TriangleFan
};
const nzUInt8 openglSize[] =
{
4, // nzElementType_Color
1, // nzElementType_Double1
2, // nzElementType_Double2
3, // nzElementType_Double3
4, // nzElementType_Double4
1, // nzElementType_Float1
2, // nzElementType_Float2
3, // nzElementType_Float3
4 // nzElementType_Float4
};
const GLenum openglType[] =
{
GL_UNSIGNED_BYTE, // nzElementType_Color
GL_DOUBLE, // nzElementType_Double1
GL_DOUBLE, // nzElementType_Double2
GL_DOUBLE, // nzElementType_Double3
GL_DOUBLE, // nzElementType_Double4
GL_FLOAT, // nzElementType_Float1
GL_FLOAT, // nzElementType_Float2
GL_FLOAT, // nzElementType_Float3
GL_FLOAT // nzElementType_Float4
};
const GLenum rendererComparison[] =
{
GL_ALWAYS, // nzRendererComparison_Always
GL_EQUAL, // nzRendererComparison_Equal
GL_GREATER, // nzRendererComparison_Greater
GL_GEQUAL, // nzRendererComparison_GreaterOrEqual
GL_LESS, // nzRendererComparison_Less
GL_LEQUAL, // nzRendererComparison_LessOrEqual
GL_NEVER // nzRendererComparison_Never
};
const GLenum rendererParameter[] =
{
GL_BLEND, // nzRendererParameter_Blend
GL_NONE, // nzRendererParameter_ColorWrite
GL_DEPTH_TEST, // nzRendererParameter_DepthTest
GL_NONE, // nzRendererParameter_DepthWrite
GL_CULL_FACE, // nzRendererParameter_FaceCulling
GL_STENCIL_TEST // nzRendererParameter_Stencil
};
const GLenum stencilOperation[] =
{
GL_DECR, // nzStencilOperation_Decrement
GL_DECR_WRAP, // nzStencilOperation_DecrementToSaturation
GL_INCR, // nzStencilOperation_Increment
GL_INCR_WRAP, // nzStencilOperation_IncrementToSaturation
GL_INVERT, // nzStencilOperation_Invert
GL_KEEP, // nzStencilOperation_Keep
GL_REPLACE, // nzStencilOperation_Replace
GL_ZERO // nzStencilOperation_Zero
};
}
NzRenderer::NzRenderer() :
m_indexBuffer(nullptr),
m_target(nullptr),
m_shader(nullptr),
m_vertexBuffer(nullptr),
m_vertexDeclaration(nullptr),
m_vertexBufferUpdated(false)
NzRenderer::NzRenderer()
{
#if NAZARA_RENDERER_SAFE
if (s_instance)
@@ -53,7 +148,7 @@ NzRenderer::~NzRenderer()
s_instance = nullptr;
}
void NzRenderer::Clear(nzRendererClear flags)
void NzRenderer::Clear(unsigned long flags)
{
#ifdef NAZARA_DEBUG
if (NzContext::GetCurrent() == nullptr)
@@ -83,6 +178,12 @@ void NzRenderer::Clear(nzRendererClear flags)
void NzRenderer::DrawIndexedPrimitives(nzPrimitiveType primitive, unsigned int firstIndex, unsigned int indexCount)
{
#ifdef NAZARA_DEBUG
if (NzContext::GetCurrent() == nullptr)
{
NazaraError("No active context");
return;
}
if (!m_indexBuffer)
{
NazaraError("No index buffer");
@@ -90,13 +191,10 @@ void NzRenderer::DrawIndexedPrimitives(nzPrimitiveType primitive, unsigned int f
}
#endif
if (!m_vertexBufferUpdated)
if (!EnsureStateUpdate())
{
if (!UpdateVertexBuffer())
{
NazaraError("Failed to update vertex buffer");
return;
}
NazaraError("Failed to update states");
return;
}
nzUInt8 indexSize = m_indexBuffer->GetIndexSize();
@@ -126,30 +224,66 @@ void NzRenderer::DrawIndexedPrimitives(nzPrimitiveType primitive, unsigned int f
void NzRenderer::DrawPrimitives(nzPrimitiveType primitive, unsigned int firstVertex, unsigned int vertexCount)
{
if (!m_vertexBufferUpdated)
#ifdef NAZARA_DEBUG
if (NzContext::GetCurrent() == nullptr)
{
if (!UpdateVertexBuffer())
{
NazaraError("Failed to update vertex buffer");
return;
}
NazaraError("No active context");
return;
}
#endif
if (!EnsureStateUpdate())
{
NazaraError("Failed to update states");
return;
}
glDrawArrays(openglPrimitive[primitive], firstVertex, vertexCount);
}
void NzRenderer::Enable(nzRendererParameter parameter, bool enable)
{
#ifdef NAZARA_DEBUG
if (NzContext::GetCurrent() == nullptr)
{
NazaraError("No active context");
return;
}
#endif
switch (parameter)
{
case nzRendererParameter_ColorWrite:
glColorMask(enable, enable, enable, enable);
break;
case nzRendererParameter_DepthWrite:
glDepthMask(enable);
break;
default:
if (enable)
glEnable(rendererParameter[parameter]);
else
glDisable(rendererParameter[parameter]);
break;
}
}
unsigned int NzRenderer::GetMaxAnisotropyLevel() const
{
return m_maxAnisotropyLevel;
}
unsigned int NzRenderer::GetMaxRenderTargets() const
{
return m_maxRenderTarget;
}
unsigned int NzRenderer::GetMaxTextureUnits() const
{
static int maxTextureUnits = -1;
if (maxTextureUnits == -1)
{
if (m_capabilities[nzRendererCap_TextureMulti])
glGetIntegerv(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, &maxTextureUnits);
else
maxTextureUnits = 1;
}
return maxTextureUnits;
return m_maxTextureUnit;
}
NzShader* NzRenderer::GetShader() const
@@ -162,6 +296,22 @@ NzRenderTarget* NzRenderer::GetTarget() const
return m_target;
}
NzRectui NzRenderer::GetViewport() const
{
#ifdef NAZARA_DEBUG
if (NzContext::GetCurrent() == nullptr)
{
NazaraError("No active context");
return NzRectui();
}
#endif
GLint params[4];
glGetIntegerv(GL_VIEWPORT, &params[0]);
return NzRectui(params[0], params[1], params[2], params[3]);
}
bool NzRenderer::HasCapability(nzRendererCap capability) const
{
return m_capabilities[capability];
@@ -186,17 +336,68 @@ bool NzRenderer::Initialize()
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;
m_stencilFail = nzStencilOperation_Keep;
m_stencilFuncUpdated = true;
m_stencilMask = 0xFFFFFFFF;
m_stencilOpUpdated = true;
m_stencilPass = nzStencilOperation_Keep;
m_stencilReference = 0;
m_stencilZFail = nzStencilOperation_Keep;
m_target = nullptr;
m_vertexBuffer = nullptr;
m_vertexDeclaration = nullptr;
// Récupération des capacités
m_capabilities[nzRendererCap_AnisotropicFilter] = NzOpenGL::IsSupported(NzOpenGL::AnisotropicFilter);
m_capabilities[nzRendererCap_FP64] = NzOpenGL::IsSupported(NzOpenGL::FP64);
m_capabilities[nzRendererCap_HardwareBuffer] = true; // Natif depuis OpenGL 1.5
m_capabilities[nzRendererCap_MultipleRenderTargets] = true; // Natif depuis OpenGL 2.0
m_capabilities[nzRendererCap_OcclusionQuery] = // Natif depuis OpenGL 1.5
m_capabilities[nzRendererCap_SoftwareBuffer] = NzOpenGL::GetVersion() <= 300; // Déprécié en OpenGL 3
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_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
m_capabilities[nzRendererCap_TextureNPOT] = true; // Natif depuis OpenGL 2.0
if (m_capabilities[nzRendererCap_AnisotropicFilter])
{
GLint maxAnisotropy;
glGetIntegerv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &maxAnisotropy);
m_maxAnisotropyLevel = static_cast<unsigned int>(maxAnisotropy);
}
else
m_maxAnisotropyLevel = 1;
if (m_capabilities[nzRendererCap_MultipleRenderTargets])
{
GLint maxDrawBuffers;
glGetIntegerv(GL_MAX_DRAW_BUFFERS, &maxDrawBuffers);
m_maxRenderTarget = static_cast<unsigned int>(maxDrawBuffers);
}
else
m_maxRenderTarget = 1;
if (m_capabilities[nzRendererCap_TextureMulti])
{
GLint maxTextureUnits;
glGetIntegerv(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, &maxTextureUnits);
m_maxTextureUnit = static_cast<unsigned int>(maxTextureUnits);
}
else
m_maxTextureUnit = 1;
s_initialized = true;
return true;
@@ -205,6 +406,32 @@ bool NzRenderer::Initialize()
return false;
}
void NzRenderer::SetBlendFunc(nzBlendFunc src, nzBlendFunc dest)
{
#ifdef NAZARA_DEBUG
if (NzContext::GetCurrent() == nullptr)
{
NazaraError("No active context");
return;
}
#endif
glBlendFunc(blendFunc[src], blendFunc[dest]);
}
void NzRenderer::SetClearColor(const NzColor& color)
{
#ifdef NAZARA_DEBUG
if (NzContext::GetCurrent() == nullptr)
{
NazaraError("No active context");
return;
}
#endif
glClearColor(color.r/255.f, color.g/255.f, color.b/255.f, color.a/255.f);
}
void NzRenderer::SetClearColor(nzUInt8 r, nzUInt8 g, nzUInt8 b, nzUInt8 a)
{
#ifdef NAZARA_DEBUG
@@ -244,14 +471,40 @@ void NzRenderer::SetClearStencil(unsigned int value)
glClearStencil(value);
}
void NzRenderer::SetFaceCulling(nzFaceCulling cullingMode)
{
#ifdef NAZARA_DEBUG
if (NzContext::GetCurrent() == nullptr)
{
NazaraError("No active context");
return;
}
#endif
glCullFace(faceCullingMode[cullingMode]);
}
void NzRenderer::SetFaceFilling(nzFaceFilling fillingMode)
{
#ifdef NAZARA_DEBUG
if (NzContext::GetCurrent() == nullptr)
{
NazaraError("No active context");
return;
}
#endif
glPolygonMode(GL_FRONT_AND_BACK, faceFillingMode[fillingMode]);
}
bool NzRenderer::SetIndexBuffer(const NzIndexBuffer* indexBuffer)
{
if (indexBuffer == m_indexBuffer)
return true;
// OpenGL ne nécessite pas de débinder un index buffer pour ne pas l'utiliser
if (indexBuffer)
indexBuffer->GetBuffer()->m_impl->Bind();
if (indexBuffer != m_indexBuffer)
{
m_indexBuffer = indexBuffer;
m_vaoUpdated = false;
}
return true;
}
@@ -261,12 +514,17 @@ bool NzRenderer::SetShader(NzShader* shader)
if (shader == m_shader)
return true;
if (m_shader)
m_shader->m_impl->Unbind();
if (shader)
{
#if NAZARA_RENDERER_SAFE
if (!shader->IsCompiled())
{
NazaraError("Shader is not compiled");
m_shader = nullptr;
return false;
}
#endif
@@ -274,39 +532,91 @@ bool NzRenderer::SetShader(NzShader* shader)
if (!shader->m_impl->Bind())
{
NazaraError("Failed to bind shader");
m_shader = nullptr;
return false;
}
m_shader = shader;
m_vertexBufferUpdated = false;
}
else if (m_shader)
{
m_shader->m_impl->Unbind();
else
m_shader = nullptr;
}
m_shader = shader;
return true;
}
void NzRenderer::SetStencilCompareFunction(nzRendererComparison compareFunc)
{
if (compareFunc != m_stencilCompare)
{
m_stencilCompare = compareFunc;
m_stencilFuncUpdated = false;
}
}
void NzRenderer::SetStencilFailOperation(nzStencilOperation failOperation)
{
if (failOperation != m_stencilFail)
{
m_stencilFail = failOperation;
m_stencilOpUpdated = false;
}
}
void NzRenderer::SetStencilMask(nzUInt32 mask)
{
if (mask != m_stencilMask)
{
m_stencilMask = mask;
m_stencilFuncUpdated = false;
}
}
void NzRenderer::SetStencilPassOperation(nzStencilOperation passOperation)
{
if (passOperation != m_stencilPass)
{
m_stencilPass = passOperation;
m_stencilOpUpdated = false;
}
}
void NzRenderer::SetStencilReferenceValue(unsigned int refValue)
{
if (refValue != m_stencilReference)
{
m_stencilReference = refValue;
m_stencilFuncUpdated = false;
}
}
void NzRenderer::SetStencilZFailOperation(nzStencilOperation zfailOperation)
{
if (zfailOperation != m_stencilZFail)
{
m_stencilZFail = zfailOperation;
m_stencilOpUpdated = false;
}
}
bool NzRenderer::SetTarget(NzRenderTarget* target)
{
if (target == m_target)
return true;
#if NAZARA_RENDERER_SAFE
if (target && !target->CanActivate())
{
NazaraError("Target cannot be activated");
return false;
}
#endif
if (m_target && !m_target->HasContext())
m_target->Desactivate();
if (target)
{
#if NAZARA_RENDERER_SAFE
if (!target->IsValid())
{
NazaraError("Target not valid");
return false;
}
#endif
if (target->Activate())
m_target = target;
else
@@ -325,28 +635,63 @@ bool NzRenderer::SetTarget(NzRenderTarget* target)
bool NzRenderer::SetVertexBuffer(const NzVertexBuffer* vertexBuffer)
{
if (m_vertexBuffer == vertexBuffer)
return true;
if (m_vertexBuffer && vertexBuffer)
if (m_vertexBuffer != vertexBuffer)
{
// Si l'ancien buffer et le nouveau sont hardware, pas besoin de mettre à jour la déclaration
if (!m_vertexBuffer->IsHardware() || !vertexBuffer->IsHardware())
m_vertexBufferUpdated = false;
m_vertexBuffer = vertexBuffer;
m_vaoUpdated = false;
}
m_vertexBuffer = vertexBuffer;
return true;
}
bool NzRenderer::SetVertexDeclaration(const NzVertexDeclaration* vertexDeclaration)
{
m_vertexDeclaration = vertexDeclaration;
m_vertexBufferUpdated = false;
if (m_vertexDeclaration != vertexDeclaration)
{
m_vertexDeclaration = vertexDeclaration;
m_vaoUpdated = false;
}
return true;
}
void NzRenderer::SetViewport(const NzRectui& viewport)
{
#ifdef NAZARA_DEBUG
if (NzContext::GetCurrent() == nullptr)
{
NazaraError("No active context");
return;
}
#endif
unsigned int height = m_target->GetHeight();
#if NAZARA_RENDERER_SAFE
if (!m_target)
{
NazaraError("Renderer has no target");
return;
}
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)
{
NazaraError("Rectangle dimensions are out of bounds");
return;
}
#endif
glViewport(viewport.x, height-viewport.height-viewport.y, viewport.width, viewport.height);
glScissor(viewport.x, height-viewport.height-viewport.y, viewport.width, viewport.height);
}
void NzRenderer::Uninitialize()
{
#if NAZARA_RENDERER_SAFE
@@ -357,10 +702,19 @@ void NzRenderer::Uninitialize()
}
#endif
NzOpenGL::Uninitialize();
NzContext::EnsureContext();
s_initialized = false;
// Libération des VAOs
for (auto it = m_vaos.begin(); it != m_vaos.end(); ++it)
{
GLuint vao = static_cast<GLuint>(it->second);
glDeleteVertexArrays(1, &vao);
}
NzOpenGL::Uninitialize();
if (m_utilityModule)
{
delete m_utilityModule;
@@ -383,32 +737,120 @@ bool NzRenderer::IsInitialized()
return s_initialized;
}
bool NzRenderer::UpdateVertexBuffer()
bool NzRenderer::EnsureStateUpdate()
{
#if NAZARA_RENDERER_SAFE
if (!m_shader)
#ifdef NAZARA_DEBUG
if (NzContext::GetCurrent() == nullptr)
{
NazaraError("No shader");
return false;
}
if (!m_vertexBuffer)
{
NazaraError("No vertex buffer");
return false;
}
if (!m_vertexDeclaration)
{
NazaraError("No vertex declaration");
NazaraError("No active context");
return false;
}
#endif
if (!m_shader->m_impl->UpdateVertexBuffer(m_vertexBuffer, m_vertexDeclaration))
return false;
if (!m_stencilFuncUpdated)
{
glStencilFunc(rendererComparison[m_stencilCompare], m_stencilReference, m_stencilMask);
m_stencilFuncUpdated = true;
}
m_vertexBufferUpdated = true;
if (!m_stencilOpUpdated)
{
glStencilOp(stencilOperation[m_stencilFail], stencilOperation[m_stencilZFail], stencilOperation[m_stencilPass]);
m_stencilOpUpdated = true;
}
if (!m_vaoUpdated)
{
#if NAZARA_RENDERER_SAFE
if (!m_vertexBuffer)
{
NazaraError("No vertex buffer");
return false;
}
if (!m_vertexDeclaration)
{
NazaraError("No vertex declaration");
return false;
}
#endif
static const bool vaoSupported = NzOpenGL::IsSupported(NzOpenGL::VertexArrayObject);
bool update;
GLuint vao;
// Si les VAOs sont supportés, on entoure nos appels par ceux-ci
if (vaoSupported)
{
// On recherche si un VAO existe déjà avec notre configuration
// Note: Les VAOs ne sont pas partagés entre les contextes, ces derniers font donc partie de notre configuration
auto key = std::make_tuple(NzContext::GetCurrent(), m_indexBuffer, m_vertexBuffer, m_vertexDeclaration);
auto it = m_vaos.find(key);
if (it == m_vaos.end())
{
// On créé notre VAO
glGenVertexArrays(1, &vao);
glBindVertexArray(vao);
// On l'ajoute à notre liste
m_vaos.insert(std::make_pair(key, static_cast<unsigned int>(vao)));
// Et on indique qu'on veut le programmer
update = true;
}
else
{
// Notre VAO existe déjà, il est donc inutile de le reprogrammer
vao = it->second;
update = false;
}
}
else
update = true; // Fallback si les VAOs ne sont pas supportés
if (update)
{
m_vertexBuffer->GetBuffer()->GetImpl()->Bind();
const nzUInt8* buffer = reinterpret_cast<const nzUInt8*>(m_vertexBuffer->GetBufferPtr());
///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)
{
const NzVertexDeclaration::Element* element = m_vertexDeclaration->GetElement(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 (m_indexBuffer)
m_indexBuffer->GetBuffer()->GetImpl()->Bind();
}
if (vaoSupported)
{
// Si nous venons de définir notre VAO, nous devons le débinder pour indiquer la fin de sa construction
if (update)
glBindVertexArray(0);
// Nous (re)bindons le VAO pour définir les attributs de vertice
glBindVertexArray(vao);
}
m_vaoUpdated = true;
}
return true;
}

View File

@@ -253,11 +253,12 @@ bool NzShader::LoadFromFile(nzShaderType type, const NzString& filePath)
return false;
}
NzString source;
unsigned int length = file.GetSize();
NzString source;
source.Resize(length);
if (file.Read(&source[0], sizeof(char), length) != length*sizeof(char))
if (file.Read(&source[0], length) != length)
{
NazaraError("Failed to read shader file");
return false;
@@ -371,6 +372,115 @@ bool NzShader::SendMatrix(const NzString& name, const NzMatrix4f& matrix)
return m_impl->SendMatrix(name, matrix);
}
bool NzShader::SendVector(const NzString& name, const NzVector2d& vector)
{
#if NAZARA_RENDERER_SAFE
if (!m_impl)
{
NazaraError("Shader not created");
return false;
}
if (!NazaraRenderer->HasCapability(nzRendererCap_FP64))
{
NazaraError("FP64 is not supported");
return false;
}
#endif
return m_impl->SendVector(name, vector);
}
bool NzShader::SendVector(const NzString& name, const NzVector2f& vector)
{
#if NAZARA_RENDERER_SAFE
if (!m_impl)
{
NazaraError("Shader not created");
return false;
}
#endif
return m_impl->SendVector(name, vector);
}
bool NzShader::SendVector(const NzString& name, const NzVector3d& vector)
{
#if NAZARA_RENDERER_SAFE
if (!m_impl)
{
NazaraError("Shader not created");
return false;
}
if (!NazaraRenderer->HasCapability(nzRendererCap_FP64))
{
NazaraError("FP64 is not supported");
return false;
}
#endif
return m_impl->SendVector(name, vector);
}
bool NzShader::SendVector(const NzString& name, const NzVector3f& vector)
{
#if NAZARA_RENDERER_SAFE
if (!m_impl)
{
NazaraError("Shader not created");
return false;
}
#endif
return m_impl->SendVector(name, vector);
}
bool NzShader::SendVector(const NzString& name, const NzVector4d& vector)
{
#if NAZARA_RENDERER_SAFE
if (!m_impl)
{
NazaraError("Shader not created");
return false;
}
if (!NazaraRenderer->HasCapability(nzRendererCap_FP64))
{
NazaraError("FP64 is not supported");
return false;
}
#endif
return m_impl->SendVector(name, vector);
}
bool NzShader::SendVector(const NzString& name, const NzVector4f& vector)
{
#if NAZARA_RENDERER_SAFE
if (!m_impl)
{
NazaraError("Shader not created");
return false;
}
#endif
return m_impl->SendVector(name, vector);
}
bool NzShader::SendTexture(const NzString& name, NzTexture* texture)
{
#if NAZARA_RENDERER_SAFE
if (!m_impl)
{
NazaraError("Shader not created");
return false;
}
#endif
return m_impl->SendTexture(name, texture);
}
void NzShader::Unlock()
{
#if NAZARA_RENDERER_SAFE

View File

@@ -10,6 +10,7 @@
#include <Nazara/Renderer/Shader.hpp>
class NzRenderer;
class NzTexture;
class NzVertexBuffer;
class NzVertexDeclaration;
@@ -36,7 +37,7 @@ class NzShaderImpl
virtual bool Load(nzShaderType type, const NzString& source) = 0;
virtual bool Lock() const = 0;
virtual bool Lock() = 0;
virtual bool SendBoolean(const NzString& name, bool value) = 0;
virtual bool SendDouble(const NzString& name, double value) = 0;
@@ -44,12 +45,16 @@ class NzShaderImpl
virtual bool SendInteger(const NzString& name, int value) = 0;
virtual bool SendMatrix(const NzString& name, const NzMatrix4d& matrix) = 0;
virtual bool SendMatrix(const NzString& name, const NzMatrix4f& matrix) = 0;
virtual bool SendVector(const NzString& name, const NzVector2d& vector) = 0;
virtual bool SendVector(const NzString& name, const NzVector2f& vector) = 0;
virtual bool SendVector(const NzString& name, const NzVector3d& vector) = 0;
virtual bool SendVector(const NzString& name, const NzVector3f& vector) = 0;
virtual bool SendVector(const NzString& name, const NzVector4d& vector) = 0;
virtual bool SendVector(const NzString& name, const NzVector4f& vector) = 0;
virtual bool SendTexture(const NzString& name, NzTexture* texture) = 0;
virtual void Unbind() = 0;
virtual void Unlock() const = 0;
protected:
virtual bool UpdateVertexBuffer(const NzVertexBuffer* vertexBuffer, const NzVertexDeclaration* vertexDeclaration) = 0;
virtual void Unlock() = 0;
};
#endif // NAZARA_SHADERIMPL_HPP

View File

@@ -6,6 +6,7 @@
#include <Nazara/Renderer/SoftwareBuffer.hpp>
#include <Nazara/Core/Error.hpp>
#include <Nazara/Renderer/Config.hpp>
#include <Nazara/Renderer/Context.hpp>
#include <cstring>
#include <stdexcept>
#include <Nazara/Renderer/Debug.hpp>
@@ -30,6 +31,14 @@ NzSoftwareBuffer::~NzSoftwareBuffer()
void NzSoftwareBuffer::Bind()
{
#ifdef NAZARA_DEBUG
if (NzContext::GetCurrent() == nullptr)
{
NazaraError("No active context");
return;
}
#endif
glBindBuffer(bufferTarget[m_type], 0);
}
@@ -48,7 +57,7 @@ bool NzSoftwareBuffer::Create(unsigned int size, nzBufferUsage usage)
return false;
}
m_locked = false;
m_mapped = false;
return true;
}
@@ -61,9 +70,9 @@ void NzSoftwareBuffer::Destroy()
bool NzSoftwareBuffer::Fill(const void* data, unsigned int offset, unsigned int size)
{
#if NAZARA_RENDERER_SAFE
if (m_locked)
if (m_mapped)
{
NazaraError("Buffer already locked");
NazaraError("Buffer already mapped");
return false;
}
#endif
@@ -83,35 +92,35 @@ bool NzSoftwareBuffer::IsHardware() const
return false;
}
void* NzSoftwareBuffer::Lock(nzBufferLock lock, unsigned int offset, unsigned int size)
void* NzSoftwareBuffer::Map(nzBufferAccess access, unsigned int offset, unsigned int size)
{
NazaraUnused(lock);
NazaraUnused(access);
NazaraUnused(size);
#if NAZARA_RENDERER_SAFE
if (m_locked)
if (m_mapped)
{
NazaraError("Buffer already locked");
NazaraError("Buffer already mapped");
return nullptr;
}
#endif
m_locked = true;
m_mapped = true;
return &m_buffer[offset];
}
bool NzSoftwareBuffer::Unlock()
bool NzSoftwareBuffer::Unmap()
{
#if NAZARA_RENDERER_SAFE
if (!m_locked)
if (!m_mapped)
{
NazaraError("Buffer not locked");
NazaraError("Buffer not mapped");
return true;
}
#endif
m_locked = false;
m_mapped = false;
return true;
}

View File

@@ -27,13 +27,13 @@ class NzSoftwareBuffer : public NzBufferImpl
bool IsHardware() const;
void* Lock(nzBufferLock lock, unsigned int offset = 0, unsigned int length = 0);
bool Unlock();
void* Map(nzBufferAccess access, unsigned int offset = 0, unsigned int length = 0);
bool Unmap();
private:
nzBufferType m_type;
nzUInt8* m_buffer;
bool m_locked;
bool m_mapped;
};
#endif // NAZARA_SOFTWAREBUFFER_HPP

File diff suppressed because it is too large Load Diff

View File

@@ -97,7 +97,7 @@ bool NzVertexBuffer::IsHardware() const
return m_buffer->IsHardware();
}
void* NzVertexBuffer::Lock(nzBufferLock lock, unsigned int offset, unsigned int length)
void* NzVertexBuffer::Map(nzBufferAccess access, unsigned int offset, unsigned int length)
{
#if NAZARA_RENDERER_SAFE
if (offset+length > m_vertexCount)
@@ -107,10 +107,10 @@ void* NzVertexBuffer::Lock(nzBufferLock lock, unsigned int offset, unsigned int
}
#endif
return m_buffer->Lock(lock, m_startVertex+offset, (length) ? length : m_vertexCount-offset);
return m_buffer->Map(access, m_startVertex+offset, (length) ? length : m_vertexCount-offset);
}
bool NzVertexBuffer::Unlock()
bool NzVertexBuffer::Unmap()
{
return m_buffer->Unlock();
return m_buffer->Unmap();
}

View File

@@ -7,7 +7,7 @@
#include <Nazara/Renderer/OpenGL.hpp>
#include <Nazara/Renderer/Win32/ContextImpl.hpp>
#include <Nazara/Core/Error.hpp>
#include <Nazara/Core/Lock.hpp>
#include <Nazara/Core/LockGuard.hpp>
#include <Nazara/Core/Mutex.hpp>
#include <Nazara/Renderer/Context.hpp>
#include <cstring>
@@ -153,6 +153,8 @@ bool NzContextImpl::Create(NzContextParameters& parameters)
*attrib++ = WGL_CONTEXT_MINOR_VERSION_ARB;
*attrib++ = parameters.minorVersion;
int flags = 0;
if (parameters.majorVersion >= 3)
{
*attrib++ = WGL_CONTEXT_PROFILE_MASK_ARB;
@@ -162,11 +164,19 @@ bool NzContextImpl::Create(NzContextParameters& parameters)
{
*attrib++ = WGL_CONTEXT_CORE_PROFILE_BIT_ARB;
*attrib++ = WGL_CONTEXT_FLAGS_ARB;
*attrib++ = WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB;
flags |= WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB;
}
}
if (parameters.debugMode)
flags |= WGL_CONTEXT_DEBUG_BIT_ARB;
if (flags)
{
*attrib++ = WGL_CONTEXT_FLAGS_ARB;
*attrib++ = flags;
}
*attrib++ = 0;
m_context = wglCreateContextAttribs(m_deviceContext, shareContext, attributes);
@@ -180,7 +190,7 @@ bool NzContextImpl::Create(NzContextParameters& parameters)
{
// wglShareLists n'est pas thread-safe (source: SFML)
static NzMutex mutex;
NzLock lock(mutex);
NzLockGuard lock(mutex);
if (!wglShareLists(shareContext, m_context))
NazaraWarning("Failed to share the context: " + NzGetLastSystemError());

View File

@@ -7,22 +7,22 @@
#include <Nazara/Core/Debug/MemoryLeakTracker.hpp>
#include <new>
void* operator new(std::size_t size) throw(std::bad_alloc)
void* operator new(std::size_t size)
{
return NzMemoryManager::Allocate(size, false);
}
void* operator new[](std::size_t size) throw(std::bad_alloc)
void* operator new[](std::size_t size)
{
return NzMemoryManager::Allocate(size, true);
}
void operator delete(void* pointer) throw()
void operator delete(void* pointer) noexcept
{
NzMemoryManager::Free(pointer, false);
}
void operator delete[](void* pointer) throw()
void operator delete[](void* pointer) noexcept
{
NzMemoryManager::Free(pointer, true);
}

File diff suppressed because it is too large Load Diff

View File

@@ -74,7 +74,7 @@ namespace
return false;
}
#if NAZARA_ENDIANNESS_BIGENDIAN
#if NAZARA_BIG_ENDIAN
// Les fichiers PCX sont en little endian
NzByteSwap(&header.xmin, sizeof(nzUInt16));
NzByteSwap(&header.ymin, sizeof(nzUInt16));
@@ -93,7 +93,7 @@ namespace
unsigned int width = header.xmax - header.xmin+1;
unsigned int height = header.ymax - header.ymin+1;
if (!resource->Create(nzImageType_2D, nzPixelFormat_R8G8B8, width, height))
if (!resource->Create(nzImageType_2D, nzPixelFormat_RGB8, width, height, 1, (parameters.levelCount > 0) ? parameters.levelCount : 1))
{
NazaraError("Failed to create image");
return false;
@@ -343,6 +343,9 @@ namespace
return false;
}
if (parameters.loadFormat != nzPixelFormat_Undefined)
resource->Convert(parameters.loadFormat);
return true;
}

View File

@@ -11,7 +11,7 @@
#include <Nazara/Utility/Image.hpp>
#define STBI_HEADER_FILE_ONLY
#include <Nazara/Utility/Loaders/STB/stb_image.c>
#include <Nazara/Utility/Loaders/STB/stb_image.cpp>
#include <Nazara/Utility/Debug.hpp>
@@ -21,19 +21,19 @@ namespace
{
int Read(void* userdata, char* data, int size)
{
NzInputStream* stream = static_cast<NzInputStream*>(userdata);
NzInputStream* stream = reinterpret_cast<NzInputStream*>(userdata);
return static_cast<int>(stream->Read(data, size));
}
void Skip(void* userdata, unsigned int size)
{
NzInputStream* stream = static_cast<NzInputStream*>(userdata);
NzInputStream* stream = reinterpret_cast<NzInputStream*>(userdata);
stream->Read(nullptr, size);
}
int Eof(void* userdata)
{
NzInputStream* stream = static_cast<NzInputStream*>(userdata);
NzInputStream* stream = reinterpret_cast<NzInputStream*>(userdata);
return stream->GetCursorPos() >= stream->GetSize();
}
@@ -63,15 +63,45 @@ namespace
{
NazaraUnused(parameters);
static nzPixelFormat format[4] = {
static const nzPixelFormat formats[4] =
{
nzPixelFormat_L8,
nzPixelFormat_L8A8,
nzPixelFormat_R8G8B8,
nzPixelFormat_R8G8B8A8
nzPixelFormat_LA8,
nzPixelFormat_RGB8,
nzPixelFormat_RGBA8
};
nzPixelFormat format;
int stbiFormat;
switch (parameters.loadFormat)
{
case nzPixelFormat_L8:
format = nzPixelFormat_L8;
stbiFormat = STBI_grey;
break;
case nzPixelFormat_LA8:
format = nzPixelFormat_LA8;
stbiFormat = STBI_grey_alpha;
break;
case nzPixelFormat_RGB8:
format = nzPixelFormat_RGB8;
stbiFormat = STBI_rgb;
break;
case nzPixelFormat_RGBA8:
format = nzPixelFormat_RGBA8;
stbiFormat = STBI_rgb_alpha;
break;
default:
format = nzPixelFormat_Undefined;
stbiFormat = STBI_default;
}
int width, height, bpp;
nzUInt8* ptr = stbi_load_from_callbacks(&callbacks, &stream, &width, &height, &bpp, STBI_default);
nzUInt8* ptr = stbi_load_from_callbacks(&callbacks, &stream, &width, &height, &bpp, stbiFormat);
if (!ptr)
{
@@ -79,7 +109,10 @@ namespace
return false;
}
if (!resource->Create(nzImageType_2D, format[bpp-1], width, height))
if (format == nzPixelFormat_Undefined)
format = formats[bpp-1];
if (!resource->Create(nzImageType_2D, format, width, height, 1, (parameters.levelCount > 0) ? parameters.levelCount : 1))
{
NazaraError("Failed to create image");
stbi_image_free(ptr);
@@ -88,8 +121,12 @@ namespace
}
resource->Update(ptr);
stbi_image_free(ptr);
if (stbiFormat == STBI_default && parameters.loadFormat != nzPixelFormat_Undefined)
resource->Convert(parameters.loadFormat);
return true;
}
@@ -98,7 +135,7 @@ namespace
NazaraUnused(parameters);
int width, height, bpp;
return stbi_info_from_memory(static_cast<const stbi_uc*>(data), size, &width, &height, &bpp);
return stbi_info_from_memory(reinterpret_cast<const stbi_uc*>(data), size, &width, &height, &bpp);
}
bool NzLoader_STB_IsStreamLoadingSupported(NzInputStream& stream, const NzImageParams& parameters)

File diff suppressed because it is too large Load Diff

View File

@@ -7,6 +7,8 @@
#include <Nazara/Utility/Config.hpp>
#include <Nazara/Utility/Loaders/PCX.hpp>
#include <Nazara/Utility/Loaders/STB.hpp>
#include <Nazara/Utility/PixelFormat.hpp>
#include <Nazara/Utility/Window.hpp>
#include <Nazara/Utility/Debug.hpp>
NzUtility::NzUtility()
@@ -29,6 +31,20 @@ bool NzUtility::Initialize()
}
#endif
if (!NzPixelFormat::Initialize())
{
NazaraError("Failed to initialize pixel format");
return false;
}
if (!NzWindow::Initialize())
{
NazaraError("Failed to initialize window's system");
NzPixelFormat::Uninitialize();
return false;
}
// Loaders spécialisés
NzLoaders_PCX_Register(); // Loader de fichiers .PCX (1, 4, 8, 24)
@@ -53,6 +69,10 @@ void NzUtility::Uninitialize()
NzLoaders_STB_Unregister();
NzLoaders_PCX_Unregister();
NzWindow::Uninitialize();
NzPixelFormat::Uninitialize();
s_initialized = false;
}

View File

@@ -18,7 +18,7 @@ NzVector2i NzEventImpl::GetMousePosition()
NzVector2i NzEventImpl::GetMousePosition(const NzWindow& relativeTo)
{
HWND handle = static_cast<HWND>(relativeTo.GetHandle());
HWND handle = reinterpret_cast<HWND>(relativeTo.GetHandle());
if (handle)
{
POINT pos;
@@ -229,7 +229,7 @@ void NzEventImpl::SetMousePosition(int x, int y)
void NzEventImpl::SetMousePosition(int x, int y, const NzWindow& relativeTo)
{
HWND handle = static_cast<HWND>(relativeTo.GetHandle());
HWND handle = reinterpret_cast<HWND>(relativeTo.GetHandle());
if (handle)
{
POINT pos = {x, y};

View File

@@ -4,6 +4,8 @@
// Un grand merci à Laurent Gomila pour la SFML qui m'aura bien aidé à réaliser cette implémentation
#define OEMRESOURCE
#include <Nazara/Utility/Win32/WindowImpl.hpp>
#include <Nazara/Core/Error.hpp>
#include <Nazara/Core/Mutex.hpp>
@@ -14,6 +16,11 @@
#include <windowsx.h>
#include <Nazara/Utility/Debug.hpp>
#ifdef _WIN64
#define GWL_USERDATA GWLP_USERDATA
#define GCL_HCURSOR GCLP_HCURSOR
#endif
// N'est pas définit avec MinGW apparemment
#ifndef MAPVK_VK_TO_VSC
#define MAPVK_VK_TO_VSC 0
@@ -25,7 +32,6 @@ namespace
{
const wchar_t* className = L"Nazara Window";
NzWindowImpl* fullscreenWindow = nullptr;
unsigned int windowCount = 0;
}
NzWindowImpl::NzWindowImpl(NzWindow* parent) :
@@ -62,19 +68,10 @@ void NzWindowImpl::Close()
}
else
SetEventListener(false);
if (--windowCount == 0)
Uninitialize();
}
bool NzWindowImpl::Create(NzVideoMode mode, const NzString& title, nzUInt32 style)
{
if (windowCount++ == 0 && !Initialize())
{
NazaraError("Unable to initialize window implementation");
return false;
}
bool fullscreen = (style & NzWindow::Fullscreen) != 0;
DWORD win32Style, win32StyleEx;
unsigned int x, y;
@@ -126,7 +123,7 @@ bool NzWindowImpl::Create(NzVideoMode mode, const NzString& title, nzUInt32 styl
win32StyleEx = 0;
RECT rect = {0, 0, width, height};
RECT rect = {0, 0, static_cast<LONG>(width), static_cast<LONG>(height)};
AdjustWindowRect(&rect, win32Style, false);
width = rect.right-rect.left;
height = rect.bottom-rect.top;
@@ -165,15 +162,7 @@ bool NzWindowImpl::Create(NzVideoMode mode, const NzString& title, nzUInt32 styl
m_eventListener = true;
m_ownsWindow = true;
if (m_handle != nullptr)
return true;
else
{
if (--windowCount == 0)
Uninitialize();
return false;
}
return m_handle != nullptr;
}
bool NzWindowImpl::Create(NzWindowHandle handle)
@@ -184,7 +173,7 @@ bool NzWindowImpl::Create(NzWindowHandle handle)
return false;
}
m_handle = static_cast<HWND>(handle);
m_handle = reinterpret_cast<HWND>(handle);
m_eventListener = false;
m_ownsWindow = false;
@@ -220,11 +209,11 @@ NzVector2i NzWindowImpl::GetPosition() const
return NzVector2i(rect.left, rect.top);
}
NzVector2i NzWindowImpl::GetSize() const
NzVector2ui NzWindowImpl::GetSize() const
{
RECT rect;
GetClientRect(m_handle, &rect);
return NzVector2i(rect.right-rect.left, rect.bottom-rect.top);
return NzVector2ui(rect.right-rect.left, rect.bottom-rect.top);
}
NzString NzWindowImpl::GetTitle() const
@@ -348,7 +337,7 @@ void NzWindowImpl::SetPosition(int x, int y)
void NzWindowImpl::SetSize(unsigned int width, unsigned int height)
{
// SetWindowPos demande la taille totale de la fenêtre
RECT rect = {0, 0, width, height};
RECT rect = {0, 0, static_cast<LONG>(width), static_cast<LONG>(height)};
AdjustWindowRect(&rect, GetWindowLongPtr(m_handle, GWL_STYLE), false);
SetWindowPos(m_handle, 0, 0, 0, rect.right - rect.left, rect.bottom - rect.top, SWP_NOMOVE | SWP_NOZORDER);
@@ -372,7 +361,7 @@ void NzWindowImpl::ShowMouseCursor(bool show)
// http://msdn.microsoft.com/en-us/library/windows/desktop/ms648045(v=vs.85).aspx
if (show)
m_cursor = static_cast<HCURSOR>(LoadImage(nullptr, MAKEINTRESOURCE(OCR_NORMAL), IMAGE_CURSOR, 0, 0, LR_SHARED));
m_cursor = reinterpret_cast<HCURSOR>(LoadImage(nullptr, MAKEINTRESOURCE(OCR_NORMAL), IMAGE_CURSOR, 0, 0, LR_SHARED));
else
m_cursor = nullptr;
@@ -707,7 +696,7 @@ bool NzWindowImpl::HandleMessage(HWND window, UINT message, WPARAM wParam, LPARA
{
if (wParam != SIZE_MINIMIZED)
{
NzVector2i size = GetSize(); // On récupère uniquement la taille de la zone client
NzVector2ui size = GetSize(); // On récupère uniquement la taille de la zone client
NzEvent event;
event.type = NzEvent::Resized;
@@ -776,6 +765,30 @@ bool NzWindowImpl::HandleMessage(HWND window, UINT message, WPARAM wParam, LPARA
return false;
}
bool NzWindowImpl::Initialize()
{
// Nous devons faire un type Unicode pour que la fenêtre le soit également
// http://msdn.microsoft.com/en-us/library/windows/desktop/ms633574(v=vs.85).aspx
WNDCLASSW windowClass;
windowClass.cbClsExtra = 0;
windowClass.cbWndExtra = 0;
windowClass.hbrBackground = nullptr;
windowClass.hCursor = nullptr; // Le curseur est définit dynamiquement
windowClass.hIcon = nullptr; // L'icône est définie dynamiquement
windowClass.hInstance = GetModuleHandle(nullptr);
windowClass.lpfnWndProc = MessageHandler;
windowClass.lpszClassName = className;
windowClass.lpszMenuName = nullptr;
windowClass.style = CS_DBLCLKS; // Gestion du double-clic
return RegisterClassW(&windowClass);
}
void NzWindowImpl::Uninitialize()
{
UnregisterClassW(className, GetModuleHandle(nullptr));
}
LRESULT CALLBACK NzWindowImpl::MessageHandler(HWND window, UINT message, WPARAM wParam, LPARAM lParam)
{
NzWindowImpl* me;
@@ -798,25 +811,6 @@ LRESULT CALLBACK NzWindowImpl::MessageHandler(HWND window, UINT message, WPARAM
return DefWindowProcW(window, message, wParam, lParam);
}
bool NzWindowImpl::Initialize()
{
// Nous devons faire un type Unicode pour que la fenêtre le soit également
// http://msdn.microsoft.com/en-us/library/windows/desktop/ms633574(v=vs.85).aspx
WNDCLASSW windowClass;
windowClass.cbClsExtra = 0;
windowClass.cbWndExtra = 0;
windowClass.hbrBackground = nullptr;
windowClass.hCursor = nullptr; // Le curseur est définit dynamiquement
windowClass.hIcon = nullptr; // L'icône est définie dynamiquement
windowClass.hInstance = GetModuleHandle(nullptr);
windowClass.lpfnWndProc = MessageHandler;
windowClass.lpszClassName = className;
windowClass.lpszMenuName = nullptr;
windowClass.style = CS_DBLCLKS; // Gestion du double-clic
return RegisterClassW(&windowClass);
}
NzKeyboard::Key NzWindowImpl::ConvertVirtualKey(WPARAM key, LPARAM flags)
{
switch (key)
@@ -949,11 +943,6 @@ NzKeyboard::Key NzWindowImpl::ConvertVirtualKey(WPARAM key, LPARAM flags)
}
}
void NzWindowImpl::Uninitialize()
{
UnregisterClassW(className, GetModuleHandle(nullptr));
}
#if NAZARA_UTILITY_THREADED_WINDOW
void NzWindowImpl::WindowThread(HWND* handle, DWORD styleEx, const wchar_t* title, DWORD style, unsigned int x, unsigned int y, unsigned int width, unsigned int height, NzWindowImpl* window, NzMutex* mutex, NzThreadCondition* condition)
{

View File

@@ -9,12 +9,12 @@
#ifndef NAZARA_WINDOWIMPL_HPP
#define NAZARA_WINDOWIMPL_HPP
#include <Nazara/Core/NonCopyable.hpp>
#include <Nazara/Core/String.hpp>
#include <Nazara/Math/Vector2.hpp>
#include <Nazara/Utility/Config.hpp>
#include <Nazara/Utility/Keyboard.hpp>
#include <Nazara/Utility/Mouse.hpp>
#include <Nazara/Utility/NonCopyable.hpp>
#include <Nazara/Utility/VideoMode.hpp>
#include <Nazara/Utility/Window.hpp>
#include <windows.h>
@@ -24,6 +24,7 @@ class NzMutex;
class NzThread;
class NzThreadCondition;
#endif
class NzWindow;
#undef IsMinimized // Conflit avec la méthode du même nom
@@ -44,7 +45,7 @@ class NzWindowImpl : NzNonCopyable
NzWindowHandle GetHandle() const;
unsigned int GetHeight() const;
NzVector2i GetPosition() const;
NzVector2i GetSize() const;
NzVector2ui GetSize() const;
NzString GetTitle() const;
unsigned int GetWidth() const;
@@ -67,13 +68,14 @@ class NzWindowImpl : NzNonCopyable
void ShowMouseCursor(bool show);
void StayOnTop(bool stayOnTop);
static bool Initialize();
static void Uninitialize();
private:
bool HandleMessage(HWND window, UINT message, WPARAM wParam, LPARAM lParam);
static bool Initialize();
static LRESULT CALLBACK MessageHandler(HWND window, UINT message, WPARAM wParam, LPARAM lParam);
static NzKeyboard::Key ConvertVirtualKey(WPARAM key, LPARAM flags);
static void Uninitialize();
#if NAZARA_UTILITY_THREADED_WINDOW
static void WindowThread(HWND* handle, DWORD styleEx, const wchar_t* title, DWORD style, unsigned int x, unsigned int y, unsigned int width, unsigned int height, NzWindowImpl* window, NzMutex* mutex, NzThreadCondition* condition);
#endif

View File

@@ -4,7 +4,7 @@
#include <Nazara/Utility/Window.hpp>
#include <Nazara/Core/Error.hpp>
#include <Nazara/Core/Lock.hpp>
#include <Nazara/Core/LockGuard.hpp>
#include <stdexcept>
#if defined(NAZARA_PLATFORM_WINDOWS)
@@ -222,12 +222,12 @@ NzVector2i NzWindow::GetPosition() const
return NzVector2i(0);
}
NzVector2i NzWindow::GetSize() const
NzVector2ui NzWindow::GetSize() const
{
if (m_impl)
return m_impl->GetSize();
else
return NzVector2i(0);
return NzVector2ui(0U);
}
NzString NzWindow::GetTitle() const
@@ -281,7 +281,7 @@ bool NzWindow::PollEvent(NzEvent* event)
return false;
#if NAZARA_UTILITY_THREADED_WINDOW
NzLock lock(m_eventMutex);
NzLockGuard lock(m_eventMutex);
#else
m_impl->ProcessEvents(false);
#endif
@@ -308,7 +308,8 @@ void NzWindow::SetEventListener(bool listener)
m_impl->SetEventListener(listener);
if (!listener)
{
NzLock lock(m_eventMutex);
// On vide la pile des évènements
NzLockGuard lock(m_eventMutex);
while (!m_events.empty())
m_events.pop();
}
@@ -408,7 +409,7 @@ bool NzWindow::WaitEvent(NzEvent* event)
return false;
#if NAZARA_UTILITY_THREADED_WINDOW
NzLock lock(m_eventMutex);
NzLockGuard lock(m_eventMutex);
if (m_events.empty())
{
@@ -473,3 +474,13 @@ void NzWindow::PushEvent(const NzEvent& event)
}
#endif
}
bool NzWindow::Initialize()
{
return NzWindowImpl::Initialize();
}
void NzWindow::Uninitialize()
{
NzWindowImpl::Uninitialize();
}