Merge remote-tracking branch 'upstream/master'
This commit is contained in:
@@ -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
16
src/Nazara/Core/Color.cpp
Normal 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);
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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];
|
||||
|
||||
|
||||
@@ -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++)
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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>
|
||||
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
@@ -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()]);
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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))
|
||||
{
|
||||
|
||||
@@ -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, ¶ms[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;
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
1614
src/Nazara/Renderer/Texture.cpp
Normal file
1614
src/Nazara/Renderer/Texture.cpp
Normal file
File diff suppressed because it is too large
Load Diff
@@ -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();
|
||||
}
|
||||
|
||||
@@ -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());
|
||||
|
||||
@@ -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
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
1320
src/Nazara/Utility/PixelFormat.cpp
Normal file
1320
src/Nazara/Utility/PixelFormat.cpp
Normal file
File diff suppressed because it is too large
Load Diff
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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};
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user