Merge remote-tracking branch 'upstream/master'

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

151
.gitignore vendored Normal file
View File

@ -0,0 +1,151 @@
# Codeblocks
*.cbp
*.cscope_file_list
*.depend
*.layout
*.workspace
# Compiled Object files
*.slo
*.lo
*.o
# Compiled Dynamic libraries
*.so
# Compiled Static libraries
*.lai
*.la
*.a
# Object files
*.o
# Libraries
*.lib
# Shared objects (inc. Windows DLLs)
*.dll
*.so
# Executables
*.exe
*.out
# Windows image file caches
Thumbs.db
# Folder config file
Desktop.ini
# Recycle Bin used on file shares
$RECYCLE.BIN/
## Ignore Visual Studio temporary files, build results, and
## files generated by popular Visual Studio add-ons.
# User-specific files
*.suo
*.user
*.sln.docstates
# Build results
[Dd]ebug*/
[Rr]elease/
build/
[Tt]est[Rr]esult
[Bb]uild[Ll]og.*
*_i.c
*_p.c
*.ilk
*.meta
*.obj
*.pch
*.pdb
*.pgc
*.pgd
*.rsp
*.sbr
*.tlb
*.tli
*.tlh
*.tmp
*.vspscc
*.vssscc
.builds
*.pidb
*.log
*.scc
# Visual C++ cache files
ipch/
*.aps
*.ncb
*.opensdf
*.sdf
# Visual Studio profiler
*.psess
*.vsp
# Guidance Automation Toolkit
*.gpState
# ReSharper is a .NET coding add-in
_ReSharper*/
*.[Rr]e[Ss]harper
# NCrunch
*.ncrunch*
.*crunch*.local.xml
# Installshield output folder
[Ee]xpress
# DocProject is a documentation generator add-in
DocProject/buildhelp/
DocProject/Help/*.HxT
DocProject/Help/*.HxC
DocProject/Help/*.hhc
DocProject/Help/*.hhk
DocProject/Help/*.hhp
DocProject/Help/Html2
DocProject/Help/html
# Click-Once directory
publish
# Publish Web Output
*.Publish.xml
# Others
[Bb]in
[Oo]bj
sql
TestResults
[Tt]est[Rr]esult*
*.Cache
ClientBin
[Ss]tyle[Cc]op.*
~$*
*.dbmdl
*.[Pp]ublish.xml
Generated_Code #added for RIA/Silverlight projects
# Backup & report files from converting an old project file to a newer
# Visual Studio version. Backup files are not needed, because we have git ;-)
_UpgradeReport_Files/
Backup*/
UpgradeLog*.XML
# NuGet
packages/

View File

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

View File

@ -32,5 +32,8 @@ configuration "*Static"
configuration "*DLL"
kind "SharedLib"
configuration "gmake"
buildoptions "-std=c++11"
configuration { "linux or bsd or macosx", "gmake" }
buildoptions "-fvisibility=hidden"

View File

@ -1,6 +1,5 @@
project "NazaraRenderer"
defines "NAZARA_RENDERER_OPENGL"
links "gdi32"
links "opengl32"
links "winmm"

View File

@ -7,6 +7,7 @@ files
"../include/Nazara/Utility/**.hpp",
"../include/Nazara/Utility/**.inl",
"../src/Nazara/Utility/**.hpp",
"../src/Nazara/Utility/**.c",
"../src/Nazara/Utility/**.cpp"
}

View File

@ -1,27 +0,0 @@
// Copyright (C) 2012 Jérôme Leclercq
// This file is part of the "Nazara Engine".
// For conditions of distribution and use, see copyright notice in Config.hpp
#pragma once
#ifndef NAZARA_SOUND_HPP
#define NAZARA_SOUND_HPP
#include <Nazara/Prerequesites.hpp>
#include <Nazara/Core/String.hpp>
#include <Nazara/Utility/Resource.hpp>
class NAZARA_API NzSound
{
public:
NzSound();
~NzSound();
bool LoadFromFile(const NzString& filePath);
bool LoadFromMemory(const nzUInt8* ptr, std::size_t size);
private:
};
#endif // NAZARA_SOUND_HPP

View File

@ -0,0 +1,68 @@
// Copyright (C) 2012 Jérôme Leclercq
// This file is part of the "Nazara Engine".
// For conditions of distribution and use, see copyright notice in Config.hpp
#pragma once
#ifndef NAZARA_COLOR_HPP
#define NAZARA_COLOR_HPP
#include <Nazara/Prerequesites.hpp>
#include <Nazara/Core/String.hpp>
#include <Nazara/Math/Vector3.hpp>
class NzColor
{
public:
NzColor();
NzColor(nzUInt8 red, nzUInt8 green, nzUInt8 blue, nzUInt8 alpha = 255);
explicit NzColor(nzUInt8 lightness);
NzColor(nzUInt8 color[3], nzUInt8 alpha = 255);
NzColor(const NzColor& color) = default;
~NzColor() = default;
NzString ToString() const;
NzColor operator+(const NzColor& angles) const;
NzColor operator*(const NzColor& angles) const;
NzColor operator+=(const NzColor& angles);
NzColor operator*=(const NzColor& angles);
bool operator==(const NzColor& angles) const;
bool operator!=(const NzColor& angles) const;
static NzColor FromCMY(float cyan, float magenta, float yellow);
static NzColor FromCMYK(float cyan, float magenta, float yellow, float black);
static NzColor FromHSL(nzUInt8 hue, nzUInt8 saturation, nzUInt8 lightness);
static NzColor FromHSV(nzUInt8 hue, nzUInt8 saturation, float value);
static NzColor FromXYZ(const NzVector3f& vec);
static NzColor FromXYZ(float x, float y, float z);
static void ToCMY(const NzColor& color, float* cyan, float* magenta, float* yellow);
static void ToCMYK(const NzColor& color, float* cyan, float* magenta, float* yellow, float* black);
static void ToHSL(const NzColor& color, nzUInt8* hue, nzUInt8* saturation, nzUInt8* lightness);
static void ToHSV(const NzColor& color, nzUInt8* hue, nzUInt8* saturation, float* value);
static void ToXYZ(const NzColor& color, NzVector3f* vec);
static void ToXYZ(const NzColor& color, float* x, float* y, float* z);
nzUInt8 r, g, b, a;
static NAZARA_API const NzColor Black;
static NAZARA_API const NzColor Blue;
static NAZARA_API const NzColor Cyan;
static NAZARA_API const NzColor Green;
static NAZARA_API const NzColor Magenta;
static NAZARA_API const NzColor Orange;
static NAZARA_API const NzColor Red;
static NAZARA_API const NzColor Yellow;
static NAZARA_API const NzColor White;
private:
static float Hue2RGB(float v1, float v2, float vH);
};
std::ostream& operator<<(std::ostream& out, const NzColor& color);
#include <Nazara/Core/Color.inl>
#endif // NAZARA_COLOR_HPP

View File

@ -0,0 +1,410 @@
// 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/StringStream.hpp>
#include <cmath>
#include <cstdlib>
#include <stdexcept>
#include <Nazara/Utility/Debug.hpp>
inline NzColor::NzColor()
{
}
inline NzColor::NzColor(nzUInt8 red, nzUInt8 green, nzUInt8 blue, nzUInt8 alpha) :
r(red),
g(green),
b(blue),
a(alpha)
{
}
inline NzColor::NzColor(nzUInt8 lightness) :
r(lightness),
g(lightness),
b(lightness),
a(255)
{
}
inline NzColor::NzColor(nzUInt8 vec[3], nzUInt8 alpha) :
r(vec[0]),
g(vec[1]),
b(vec[2]),
a(alpha)
{
}
inline NzString NzColor::ToString() const
{
NzStringStream ss;
ss << "Color(" << static_cast<int>(r) << ", " << static_cast<int>(g) << ", " << static_cast<int>(b);
if (a != 255)
ss << ", " << static_cast<int>(a);
ss << ')';
return ss;
}
inline NzColor NzColor::operator+(const NzColor& color) const
{
return NzColor(std::min(static_cast<nzUInt16>(r) + color.r, 255),
std::min(static_cast<nzUInt16>(r) + color.r, 255),
std::min(static_cast<nzUInt16>(r) + color.r, 255),
std::min(static_cast<nzUInt16>(r) + color.r, 255));
}
inline NzColor NzColor::operator*(const NzColor& color) const
{
return NzColor(static_cast<nzUInt16>(r) * color.r/255,
static_cast<nzUInt16>(r) * color.r/255,
static_cast<nzUInt16>(r) * color.r/255,
static_cast<nzUInt16>(r) * color.r/255);
}
inline NzColor NzColor::operator+=(const NzColor& color)
{
return operator=(operator+(color));
}
inline NzColor NzColor::operator*=(const NzColor& color)
{
return operator=(operator+(color));
}
inline bool NzColor::operator==(const NzColor& color) const
{
return r == color.r && g == color.g && b == color.b && a == color.a;
}
inline bool NzColor::operator!=(const NzColor& color) const
{
return !operator==(color);
}
// Algorithmes venant de http://www.easyrgb.com/index.php?X=MATH
inline NzColor NzColor::FromCMY(float cyan, float magenta, float yellow)
{
return NzColor((1.f-cyan)*255.f, (1.f-magenta)*255.f, (1.f-yellow)*255.f);
}
inline NzColor NzColor::FromCMYK(float cyan, float magenta, float yellow, float black)
{
return FromCMY(cyan * (1.f - black) + black,
magenta * (1.f - black) + black,
yellow * (1.f - black) + black);
}
inline NzColor NzColor::FromHSL(nzUInt8 hue, nzUInt8 saturation, nzUInt8 lightness)
{
// Norme Windows
float l = lightness/240.f;
if (saturation == 0)
{
// RGB results from 0 to 255
return NzColor(lightness * 255.f,
lightness * 255.f,
lightness * 255.f);
}
else
{
float h = hue/240.f;
float s = saturation/240.f;
float v2;
if (l < 0.5f)
v2 = l * (1.f + s);
else
v2 = (l + s) - (s*l);
float v1 = 2.f * l - v2;
return NzColor(255.f * Hue2RGB(v1, v2, h + (1.f/3.f)),
255.f * Hue2RGB(v1, v2, h),
255.f * Hue2RGB(v1, v2, h - (1.f/3.f)));
}
}
inline NzColor NzColor::FromHSV(nzUInt8 hue, nzUInt8 saturation, float value)
{
if (saturation == 0)
return NzColor(static_cast<nzUInt8>(value * 255.f));
else
{
float h = hue/240.f * 6.f;
float s = saturation/240.f;
if (NzNumberEquals(h, 6.f))
h = 0; // hue must be < 1
int i = h;
float v1 = value * (1.f - s);
float v2 = value * (1.f - s * (h - i));
float v3 = value * (1.f - s * (1.f - (h - i)));
float r, g, b;
switch (i)
{
case 0:
r = value;
g = v3;
b = v1;
case 1:
r = v2;
g = value;
b = v1;
case 2:
r = v1;
g = value;
b = v3;
case 3:
r = v1;
g = v2;
b = value;
case 4:
r = v3;
g = v1;
b = value;
default:
r = value;
g = v1;
b = v2;
}
// RGB results from 0 to 255
return NzColor(r*255.f, g*255.f, b*255.f);
}
}
inline NzColor NzColor::FromXYZ(const NzVector3f& vec)
{
return FromXYZ(vec.x, vec.y, vec.z);
}
inline NzColor NzColor::FromXYZ(float x, float y, float z)
{
x /= 100; // X from 0 to 95.047
y /= 100; // Y from 0 to 100.000
z /= 100; // Z from 0 to 108.883
double r = x * 3.2406 + y * -1.5372 + z * -0.4986;
double g = x * -0.9689 + y * 1.8758 + z * 0.0415;
double b = x * 0.0557 + y * -0.2040 + z * 1.0570;
if (r > 0.0031308)
r = 1.055 * (std::pow(r, 1.0/2.4)) - 0.055;
else
r *= 12.92;
if (g > 0.0031308)
g = 1.055 * (std::pow(g, 1.0/2.4)) - 0.055;
else
g *= 12.92;
if (b > 0.0031308)
b = 1.055 * (std::pow(b, 1.0/2.4)) - 0.055;
else
b *= 12.92;
return NzColor(r * 255.0, g * 255.0, b * 255.0);
}
inline void NzColor::ToCMY(const NzColor& color, float* cyan, float* magenta, float* yellow)
{
*cyan = 1.f - color.r/255.f;
*magenta = 1.f - color.g/255.f;
*yellow = 1.f - color.b/255.f;
}
inline void NzColor::ToCMYK(const NzColor& color, float* cyan, float* magenta, float* yellow, float* black)
{
float c, m, y;
ToCMY(color, &c, &m, &y);
float k = std::min(std::min(std::min(1.f, c), m), y);
if (NzNumberEquals(k, 1.f))
{
//Black
*cyan = 0.f;
*magenta = 0.f;
*yellow = 0.f;
}
else
{
*cyan = (c-k)/(1.f-k);
*magenta = (m-k)/(1.f-k);
*yellow = (y-k)/(1.f-k);
}
*black = k;
}
inline void NzColor::ToHSL(const NzColor& color, nzUInt8* hue, nzUInt8* saturation, nzUInt8* lightness)
{
float r = color.r / 255.f;
float g = color.g / 255.f;
float b = color.b / 255.f;
float min = std::min(std::min(r, g), b); // Min. value of RGB
float max = std::max(std::max(r, g), b); // Max. value of RGB
float deltaMax = max - min; //Delta RGB value
float l = (max + min)/2.f;
if (NzNumberEquals(deltaMax, 0.f))
{
//This is a gray, no chroma...
*hue = 0; //HSL results from 0 to 1
*saturation = 0;
}
else
{
//Chromatic data...
if (l < 0.5f)
*saturation = deltaMax/(max+min)*240.f;
else
*saturation = deltaMax/(2.f-max-min)*240.f;
*lightness = l*240.f;
float deltaR = ((max - r)/6.f + deltaMax/2.f)/deltaMax;
float deltaG = ((max - g)/6.f + deltaMax/2.f)/deltaMax;
float deltaB = ((max - b)/6.f + deltaMax/2.f)/deltaMax;
float h;
if (NzNumberEquals(r, max))
h = deltaB - deltaG;
else if (NzNumberEquals(g, max))
h = (1.f/3.f) + deltaR - deltaB;
else if (NzNumberEquals(b, max))
h = (2.f/3.f) + deltaG - deltaR;
if (h < 0.f)
h += 1.f;
else if (h > 1.f)
h -= 1.f;
*hue = h*240.f;
}
}
inline void NzColor::ToHSV(const NzColor& color, nzUInt8* hue, nzUInt8* saturation, float* value)
{
float r = color.r / 255.f;
float g = color.g / 255.f;
float b = color.b / 255.f;
float min = std::min(std::min(r, g), b); //Min. value of RGB
float max = std::max(std::max(r, g), b); //Max. value of RGB
float deltaMax = max - min; //Delta RGB value
*value = max;
if (NzNumberEquals(deltaMax, 0.f))
{
//This is a gray, no chroma...
*hue = 0; //HSV results from 0 to 1
*saturation = 0;
}
else
{
//Chromatic data...
*saturation = deltaMax/max*240.f;
float deltaR = ((max - r)/6.f + deltaMax/2.f)/deltaMax;
float deltaG = ((max - g)/6.f + deltaMax/2.f)/deltaMax;
float deltaB = ((max - b)/6.f + deltaMax/2.f)/deltaMax;
float h;
if (NzNumberEquals(r, max))
h = deltaB - deltaG;
else if (NzNumberEquals(g, max))
h = (1.f/3.f) + deltaR - deltaB;
else if (NzNumberEquals(b, max))
h = (2.f/3.f) + deltaG - deltaR;
if (h < 0.f)
h += 1.f;
else if (h > 1.f)
h -= 1.f;
*hue = h*240.f;
}
}
inline void NzColor::ToXYZ(const NzColor& color, NzVector3f* vec)
{
return ToXYZ(color, &vec->x, &vec->y, &vec->z);
}
inline void NzColor::ToXYZ(const NzColor& color, float* x, float* y, float* z)
{
double r = color.r/255.0; //R from 0 to 255
double g = color.g/255.0; //G from 0 to 255
double b = color.b/255.0; //B from 0 to 255
if (r > 0.04045)
r = std::pow((r + 0.055)/1.055, 2.4);
else
r /= 12.92;
if (g > 0.04045)
g = std::pow((g + 0.055)/1.055, 2.4);
else
g /= 12.92;
if (b > 0.04045)
b = std::pow((b + 0.055)/1.055, 2.4);
else
b /= 12.92;
r *= 100.0;
g *= 100.0;
b *= 100.0;
//Observer. = 2°, Illuminant = D65
*x = r*0.4124 + g*0.3576 + b*0.1805;
*y = r*0.2126 + g*0.7152 + b*0.0722;
*z = r*0.0193 + g*0.1192 + b*0.9505;
}
inline float NzColor::Hue2RGB(float v1, float v2, float vH)
{
if (vH < 0.f)
vH += 1;
if (vH > 1.f)
vH -= 1;
if ((6.f * vH) < 1.f)
return v1 + (v2-v1)*6*vH;
if ((2.f * vH) < 1.f)
return v2;
if ((3.f * vH) < 2.f)
return v1 + (v2 - v1)*(2.f/3.f - vH)*6;
return v1;
}
inline std::ostream& operator<<(std::ostream& out, const NzColor& color)
{
return out << color.ToString();
}
#include <Nazara/Utility/DebugOff.hpp>

View File

@ -8,8 +8,8 @@
#define NAZARA_DYNLIB_HPP
#include <Nazara/Prerequesites.hpp>
#include <Nazara/Core/NonCopyable.hpp>
#include <Nazara/Core/String.hpp>
#include <Nazara/Utility/NonCopyable.hpp>
#define NAZARA_CLASS_DYNLIB
#include <Nazara/Core/ThreadSafety.hpp>

View File

@ -9,26 +9,18 @@
#include <Nazara/Prerequesites.hpp>
#if defined(NAZARA_ENDIANNESS_BIGENDIAN)
#define NAZARA_ENDIANNESS_DETECTED 1
#define NazaraEndianness nzEndianness_BigEndian
#elif defined(NAZARA_ENDIANNESS_LITTLEENDIAN)
#define NAZARA_ENDIANNESS_DETECTED 1
#define NazaraEndianness nzEndianness_LittleEndian
#else
#if !defined(NAZARA_BIG_ENDIAN) && !defined(NAZARA_LITTLE_ENDIAN)
// Détection automatique selon les macros du compilateur
#if defined(__m68k__) || defined(mc68000) || defined(_M_M68K) || (defined(__MIPS__) && defined(__MISPEB__)) || \
defined(__ppc__) || defined(__POWERPC__) || defined(_M_PPC) || defined(__sparc__) || defined(__hppa__)
#define NAZARA_ENDIANNESS_DETECTED 1
#define NAZARA_ENDIANNESS_BIGENDIAN
#define NazaraEndianness nzEndianness_BigEndian
#define NAZARA_BIG_ENDIAN
#elif defined(__i386__) || defined(__i386) || defined(__X86__) || defined (__x86_64)
#define NAZARA_ENDIANNESS_DETECTED 1
#define NAZARA_ENDIANNESS_LITTLEENDIAN
#define NazaraEndianness nzEndianness_LittleEndian
#define NAZARA_LITTLE_ENDIAN
#else
#define NAZARA_ENDIANNESS_DETECTED 0
#define NazaraEndianness NzGetPlatformEndianness()
#error Failed to identify endianness, you must define either NAZARA_BIG_ENDIAN or NAZARA_LITTLE_ENDIAN
#endif
#elif defined(NAZARA_BIG_ENDIAN) && defined(NAZARA_LITTLE_ENDIAN)
#error You cannot define both NAZARA_BIG_ENDIAN and NAZARA_LITTLE_ENDIAN
#endif
enum nzEndianness

View File

@ -17,27 +17,11 @@ inline void NzByteSwap(void* buffer, unsigned int size)
inline nzEndianness NzGetPlatformEndianness()
{
#if NAZARA_ENDIANNESS_DETECTED
return NazaraEndianness;
#else
static nzEndianness endianness = nzEndianness_Unknown;
static bool tested = false;
if (!tested)
{
nzUInt32 i = 1;
nzUInt8* p = reinterpret_cast<nzUInt8*>(&i);
// Méthode de récupération de l'endianness au runtime
if (p[0] == 1)
endianness = nzEndianness_LittleEndian;
else if (p[3] == 1)
endianness = nzEndianness_BigEndian;
tested = true;
}
return endianness;
#endif
#if defined(NAZARA_BIG_ENDIAN)
return nzEndianness_BigEndian;
#elif defined(NAZARA_LITTLE_ENDIAN)
return nzEndianness_LittleEndian;
#endif
}
#include <Nazara/Core/DebugOff.hpp>

View File

@ -13,8 +13,8 @@
#include <Nazara/Core/Hashable.hpp>
#include <Nazara/Core/HashDigest.hpp>
#include <Nazara/Core/InputStream.hpp>
#include <Nazara/Core/NonCopyable.hpp>
#include <Nazara/Core/String.hpp>
#include <Nazara/Utility/NonCopyable.hpp>
#define NAZARA_CLASS_FILE
#include <Nazara/Core/ThreadSafety.hpp>

View File

@ -7,7 +7,7 @@
#ifndef NAZARA_FUNCTOR_HPP
#define NAZARA_FUNCTOR_HPP
#include <Nazara/Utility/Tuple.hpp>
#include <Nazara/Core/Tuple.hpp>
// Inspiré du code de la SFML par Laurent Gomila
@ -40,6 +40,6 @@ template<typename F, typename... Args> struct NzFunctorWithArgs : NzFunctor
template<typename F> struct NzFunctorWithoutArgs;
template<typename F, typename... Args> struct NzFunctorWithArgs;
#include <Nazara/Utility/Functor.inl>
#include <Nazara/Core/Functor.inl>
#endif // NAZARA_FUNCTOR_HPP

View File

@ -11,7 +11,7 @@
#include <Nazara/Core/Hashable.hpp>
#include <Nazara/Core/HashDigest.hpp>
#include <Nazara/Core/HashImpl.hpp>
#include <Nazara/Utility/NonCopyable.hpp>
#include <Nazara/Core/NonCopyable.hpp>
class NAZARA_API NzHash : NzNonCopyable
{

View File

@ -8,7 +8,7 @@
#define NAZARA_HASHIMPL_HPP
#include <Nazara/Prerequesites.hpp>
#include <Nazara/Utility/NonCopyable.hpp>
#include <Nazara/Core/NonCopyable.hpp>
class NzHashDigest;

View File

@ -4,21 +4,21 @@
#pragma once
#ifndef NAZARA_LOCK_HPP
#define NAZARA_LOCK_HPP
#ifndef NAZARA_LOCKGUARD_HPP
#define NAZARA_LOCKGUARD_HPP
#include <Nazara/Prerequesites.hpp>
class NzMutex;
class NAZARA_API NzLock
class NAZARA_API NzLockGuard
{
public:
NzLock(NzMutex& mutex);
~NzLock();
NzLockGuard(NzMutex& mutex);
~NzLockGuard();
private:
NzMutex& m_mutex;
};
#endif // NAZARA_LOCK_HPP
#endif // NAZARA_LOCKGUARD_HPP

View File

@ -9,13 +9,14 @@
#include <Nazara/Prerequesites.hpp>
#include <Nazara/Core/Error.hpp>
#include <Nazara/Core/NonCopyable.hpp>
#include <Nazara/Core/String.hpp>
#include <Nazara/Utility/NonCopyable.hpp>
#define NAZARA_CLASS_LOG
#include <Nazara/Core/ThreadSafety.hpp>
#define NazaraLog NzLog::Instance()
#define NazaraNotice(txt) NazaraLog->Write(txt)
class NzFile;

View File

@ -8,7 +8,7 @@
#define NAZARA_MUTEX_HPP
#include <Nazara/Prerequesites.hpp>
#include <Nazara/Utility/NonCopyable.hpp>
#include <Nazara/Core/NonCopyable.hpp>
class NzMutexImpl;
class NzThreadCondition;

View File

@ -8,7 +8,7 @@
#define NAZARA_SEMAPHORE_HPP
#include <Nazara/Prerequesites.hpp>
#include <Nazara/Utility/NonCopyable.hpp>
#include <Nazara/Core/NonCopyable.hpp>
class NzSemaphoreImpl;

View File

@ -9,8 +9,7 @@
#include <Nazara/Prerequesites.hpp>
#include <Nazara/Core/Hashable.hpp>
#include <istream>
#include <ostream>
#include <iosfwd>
#include <string>
#include <vector>
@ -27,7 +26,9 @@ class NAZARA_API NzString : public NzHashable
{
None = 0x00, // Mode par défaut
CaseInsensitive = 0x01, // Insensible à la casse
HandleUtf8 = 0x02 // Traite les octets comme une suite de caractères UTF-8
HandleUtf8 = 0x02, // Traite les octets comme une suite de caractères UTF-8
TrimOnlyLeft = 0x04, // Trim(med), ne coupe que la partie gauche de la chaîne
TrimOnlyRight = 0x08 // Trim(med), ne coupe que la partie droite de la chaîne
};
struct SharedString;

View File

@ -10,8 +10,8 @@
#define NAZARA_THREAD_HPP
#include <Nazara/Prerequesites.hpp>
#include <Nazara/Utility/Functor.hpp>
#include <Nazara/Utility/NonCopyable.hpp>
#include <Nazara/Core/Functor.hpp>
#include <Nazara/Core/NonCopyable.hpp>
class NzThreadImpl;

View File

@ -24,10 +24,10 @@
(NAZARA_THREADSAFETY_STRING && defined(NAZARA_CLASS_STRING)) || \
(NAZARA_THREADSAFETY_STRINGSTREAM && defined(NAZARA_CLASS_STRINGSTREAM)))
#include <Nazara/Core/Lock.hpp>
#include <Nazara/Core/LockGuard.hpp>
#include <Nazara/Core/Mutex.hpp>
#define NazaraLock(mutex) NzLock lock_mutex(mutex);
#define NazaraLock(mutex) NzLockGuard lock_mutex(mutex);
#define NazaraMutex(name) NzMutex name;
#define NazaraMutexAttrib(name, attribute) attribute NzMutex name;
#define NazaraMutexLock(mutex) mutex.Lock();

View File

@ -11,6 +11,6 @@
template<typename F, typename... ArgsT> void NzUnpackTuple(F func, const std::tuple<ArgsT...>& t);
#include <Nazara/Utility/Tuple.inl>
#include <Nazara/Core/Tuple.inl>
#endif // NAZARA_TUPLE_HPP

View File

@ -0,0 +1,60 @@
// Copyright (C) 2012 Jérôme Leclercq
// This file is part of the "Nazara Engine".
// For conditions of distribution and use, see copyright notice in Config.hpp
#pragma once
#ifndef NAZARA_CUBE_HPP
#define NAZARA_CUBE_HPP
#include <Nazara/Core/String.hpp>
#include <Nazara/Math/Rect.hpp>
#include <Nazara/Math/Vector3.hpp>
template<typename T>
class NzCube
{
public:
NzCube();
NzCube(T X, T Y, T Z, T Width, T Height, T Depth);
NzCube(T cube[6]);
NzCube(const NzRect<T>& rect);
template<typename U> explicit NzCube(const NzCube<U>& rect);
NzCube(const NzCube& rect) = default;
~NzCube() = default;
bool Contains(T X, T Y, T Z) const;
bool Contains(const NzVector3<T>& point) const;
bool Contains(const NzCube& rect) const;
void ExtendTo(const NzVector3<T>& point);
void ExtendTo(const NzCube& rect);
NzVector3<T> GetCenter() const;
bool Intersect(const NzCube& rect) const;
bool Intersect(const NzCube& rect, NzCube& intersection) const;
bool IsValid() const;
NzString ToString() const;
operator NzString() const;
T& operator[](unsigned int i);
T operator[](unsigned int i) const;
T x, y, z, width, height, depth;
};
template<typename T>
std::ostream& operator<<(std::ostream& out, const NzCube<T>& vec);
typedef NzCube<double> NzCubed;
typedef NzCube<float> NzCubef;
typedef NzCube<int> NzCubei;
typedef NzCube<unsigned int> NzCubeui;
#include <Nazara/Math/Cube.inl>
#endif // NAZARA_CUBE_HPP

View File

@ -0,0 +1,194 @@
// 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/StringStream.hpp>
#include <algorithm>
#include <Nazara/Core/Debug.hpp>
template<typename T>
NzCube<T>::NzCube()
{
}
template<typename T>
NzCube<T>::NzCube(T X, T Y, T Z, T Width, T Height, T Depth) :
x(X),
y(Y),
z(Z),
width(Width),
height(Height),
depth(Depth)
{
}
template<typename T>
NzCube<T>::NzCube(T vec[6]) :
x(vec[0]),
y(vec[1]),
z(vec[2]),
width(vec[3]),
height(vec[4]),
depth(vec[5])
{
}
template<typename T>
NzCube<T>::NzCube(const NzRect<T>& rect) :
x(rect.x),
y(rect.y),
z(0),
width(rect.width),
height(rect.height),
depth(1)
{
}
template<typename T>
template<typename U>
NzCube<T>::NzCube(const NzCube<U>& rect) :
x(static_cast<T>(rect.x)),
y(static_cast<T>(rect.y)),
z(static_cast<T>(rect.z)),
width(static_cast<T>(rect.width)),
height(static_cast<T>(rect.height)),
depth(static_cast<T>(rect.depth))
{
}
template<typename T>
bool NzCube<T>::Contains(T X, T Y, T Z) const
{
return X >= x && X < x+width &&
Y >= y && Y < y+height &&
Z >= z && Z < z+depth;
}
template<typename T>
bool NzCube<T>::Contains(const NzVector3<T>& point) const
{
return Contains(point.x, point.y, point.z);
}
template<typename T>
bool NzCube<T>::Contains(const NzCube<T>& rect) const
{
return Contains(rect.x, rect.y, rect.z) &&
Contains(rect.x + rect.width, rect.y + rect.height, rect.z + rect.depth);
}
template<typename T>
void NzCube<T>::ExtendTo(const NzVector3<T>& point)
{
x = std::min(x, point.x);
y = std::min(y, point.y);
z = std::min(z, point.z);
width = std::max(x+width, point.x)-x;
height = std::max(y+height, point.x)-y;
depth = std::max(z+depth, point.x)-z;
}
template<typename T>
void NzCube<T>::ExtendTo(const NzCube& rect)
{
x = std::min(x, rect.x);
y = std::min(y, rect.y);
z = std::min(y, rect.z);
width = std::max(x+width, rect.x+rect.width)-x;
height = std::max(x+height, rect.y+rect.height)-y;
depth = std::max(x+depth, rect.z+rect.depth)-z;
}
template<typename T>
NzVector3<T> NzCube<T>::GetCenter() const
{
return NzVector3<T>((x+width)/2, (y+height)/2, (z+depth)/2);
}
template<typename T>
bool NzCube<T>::Intersect(const NzCube& rect) const
{
NzCube intersection; // Optimisé par le compilateur
return Intersect(rect, intersection);
}
template<typename T>
bool NzCube<T>::Intersect(const NzCube& rect, NzCube& intersection) const
{
T left = std::max(x, rect.x);
T right = std::min(x+width, rect.x+rect.width);
T top = std::max(y, rect.y);
T bottom = std::min(y+height, rect.y+rect.height);
T up = std::max(z, rect.z);
T down = std::min(z+depth, rect.z+rect.depth);
if (left < right && top < bottom && up < down)
{
intersection.x = left;
intersection.y = top;
intersection.z = up;
intersection.width = right-left;
intersection.height = bottom-top;
intersection.depth = down-up;
return true;
}
else
return false;
}
template<typename T>
bool NzCube<T>::IsValid() const
{
return width > 0 && height > 0 && depth > 0;
}
template<typename T>
NzString NzCube<T>::ToString() const
{
NzStringStream ss;
return ss << "Cube(" << x << ", " << y << ", " << z << ", " << width << ", " << height << ", " << depth << ')';
}
template<typename T>
NzCube<T>::operator NzString() const
{
return ToString();
}
template<typename T>
T& NzCube<T>::operator[](unsigned int i)
{
if (i >= 6)
{
NzStringStream ss;
ss << __FILE__ << ':' << __LINE__ << ": Index out of range (" << i << " >= 4)";
throw std::domain_error(ss.ToString());
}
return *(&x+i);
}
template<typename T>
T NzCube<T>::operator[](unsigned int i) const
{
if (i >= 6)
{
NzStringStream ss;
ss << __FILE__ << ':' << __LINE__ << ": Index out of range (" << i << " >= 4)";
throw std::domain_error(ss.ToString());
}
return *(&x+i);
}
template<typename T>
std::ostream& operator<<(std::ostream& out, const NzCube<T>& rect)
{
return out << rect.ToString();
}
#include <Nazara/Core/DebugOff.hpp>

View File

@ -96,17 +96,12 @@ template<typename T> class NzMatrix4
struct SharedMatrix
{
SharedMatrix() : // Vivement GCC 4.7 sur Windows
refCount(1)
{
}
T m11, m12, m13, m14;
T m21, m22, m23, m24;
T m31, m32, m33, m34;
T m41, m42, m43, m44;
unsigned short refCount;
unsigned short refCount = 1;
NazaraMutex(mutex)
};

View File

@ -107,7 +107,7 @@ NzMatrix4<T> NzMatrix4<T>::GetInverse() const
NzMatrix4 matrix;
T det = GetDeterminant();
if (det != 0.0)
if (!NzNumberEquals(det, static_cast<T>(0.0)))
{
matrix(0, 0) = (m_sharedMatrix->m22 * (m_sharedMatrix->m33 * m_sharedMatrix->m44 - m_sharedMatrix->m34 * m_sharedMatrix->m43) - m_sharedMatrix->m32 * (m_sharedMatrix->m23 * m_sharedMatrix->m44 - m_sharedMatrix->m43 * m_sharedMatrix->m24) + m_sharedMatrix->m42 * (m_sharedMatrix->m23 * m_sharedMatrix->m34 - m_sharedMatrix->m33 * m_sharedMatrix->m24)) / det;
matrix(0, 1) = -(m_sharedMatrix->m12 * (m_sharedMatrix->m33 * m_sharedMatrix->m44 - m_sharedMatrix->m43 * m_sharedMatrix->m34) - m_sharedMatrix->m32 * (m_sharedMatrix->m13 * m_sharedMatrix->m44 - m_sharedMatrix->m43 * m_sharedMatrix->m14) + m_sharedMatrix->m42 * (m_sharedMatrix->m13 * m_sharedMatrix->m34 - m_sharedMatrix->m33 * m_sharedMatrix->m14)) / det;

View File

@ -26,11 +26,13 @@ template<typename T> class NzQuaternion
NzQuaternion(const NzQuaternion& quat) = default;
~NzQuaternion() = default;
T DotProduct(const NzQuaternion& vec) const;
NzQuaternion GetConjugate() const;
NzQuaternion GetNormalized() const;
double Magnitude() const;
double Normalize();
T Magnitude() const;
T Normalize();
T SquaredMagnitude() const;
void Set(T W, T X, T Y, T Z);
@ -53,10 +55,10 @@ template<typename T> class NzQuaternion
NzQuaternion operator*(T scale) const;
NzQuaternion operator/(const NzQuaternion& quat) const;
NzQuaternion operator+=(const NzQuaternion& quat);
NzQuaternion operator*=(const NzQuaternion& quat);
NzQuaternion operator*=(T scale);
NzQuaternion operator/=(const NzQuaternion& quat);
NzQuaternion& operator+=(const NzQuaternion& quat);
NzQuaternion& operator*=(const NzQuaternion& quat);
NzQuaternion& operator*=(T scale);
NzQuaternion& operator/=(const NzQuaternion& quat);
bool operator==(const NzQuaternion& quat) const;
bool operator!=(const NzQuaternion& quat) const;
@ -65,6 +67,8 @@ template<typename T> class NzQuaternion
bool operator>(const NzQuaternion& quat) const;
bool operator>=(const NzQuaternion& quat) const;
static NzQuaternion Slerp(const NzQuaternion& quatA, const NzQuaternion& quatB, T interp);
T w, x, y, z;
};

View File

@ -52,6 +52,12 @@ NzQuaternion<T>::NzQuaternion(const NzQuaternion<U>& quat)
Set(quat);
}
template<typename T>
T NzQuaternion<T>::DotProduct(const NzQuaternion& vec) const
{
return w*vec.w + x*vec.x + y*vec.y + z.vec.z;
}
template<typename T>
NzQuaternion<T> NzQuaternion<T>::GetConjugate() const
{
@ -68,25 +74,29 @@ NzQuaternion<T> NzQuaternion<T>::GetNormalized() const
}
template<typename T>
double NzQuaternion<T>::Magnitude() const
T NzQuaternion<T>::Magnitude() const
{
return std::sqrt(SquaredMagnitude());
}
template<typename T>
double NzQuaternion<T>::Normalize()
T NzQuaternion<T>::Normalize()
{
double length = Magnitude();
T squaredLength = SquaredMagnitude();
if (length != 0.0)
if (std::fabs(squaredLength) > 0.00001 && std::fabs(squaredLength - 1.0) > 0.00001)
{
T length = std::sqrt(squaredLength);
w /= length;
x /= length;
y /= length;
z /= length;
}
return length;
}
else
return 1.0; // Le quaternion est déjà normalisé
}
template<typename T>
@ -167,9 +177,55 @@ void NzQuaternion<T>::SetZero()
Set(0.0, 0.0, 0.0, 0.0);
}
template<typename T>
NzQuaternion<T> NzQuaternion<T>::Slerp(const NzQuaternion& quatA, const NzQuaternion& quatB, T interp)
{
if (interp <= 0.0)
return quatA;
if (interp >= 1.0)
return quatB;
NzQuaternion q;
T cosOmega = quatA.DotProduct(quatB);
if (cosOmega < 0.0)
{
// On inverse tout
q.Set(-quatB.w, -quatB.x, -quatB.y, -quatB.z);
cosOmega = -cosOmega;
}
else
q.Set(quatB);
T k0, k1;
if (cosOmega > 0.9999)
{
// Interpolation linéaire pour éviter une division par zéro
k0 = 1.0 - interp;
k1 = interp;
}
else
{
T sinOmega = std::sqrt(1.0f - (cosOmega * cosOmega));
T omega = std::atan2(sinOmega, cosOmega);
// Pour éviter deux divisions
sinOmega = 1/sinOmega;
k0 = std::sin((1.0 - interp) * omega) * sinOmega;
k1 = std::sin(interp * omega) * sinOmega;
}
NzQuaternion result(k0 * quatA.w, k0 * quatA.x, k0 * quatA.y, k0 * quatA.z);
return result += q;
}
template<typename T>
NzEulerAngles<T> NzQuaternion<T>::ToEulerAngles() const
{
Normalize();
T test = x*y + z*w;
if (test > 0.499)
// singularity at north pole
@ -216,14 +272,14 @@ NzQuaternion<T> NzQuaternion<T>::operator*(const NzQuaternion& quat) const
template<typename T>
NzVector3<T> NzQuaternion<T>::operator*(const NzVector3<T>& vec) const
{
NzVector3<T> uv, uuv;
NzVector3<T> qvec(x, y, z);
uv = qvec.CrossProduct(vec);
uuv = qvec.CrossProduct(uv);
uv *= 2.0 * w;
uuv *= 2.0;
NzVector3<T> normal(vec);
normal.Normalise();
NzQuaternion qvec(0.0, normal.x, normal.y, normal.z);
NzQuaternion result = operator*(qvec * GetConjugate());
return NzVector3<T>(result.x, result.y, result.z);
return vec + uv + uuv;
}
template<typename T>
@ -242,43 +298,27 @@ NzQuaternion<T> NzQuaternion<T>::operator/(const NzQuaternion& quat) const
}
template<typename T>
NzQuaternion<T> NzQuaternion<T>::operator+=(const NzQuaternion& quat)
NzQuaternion<T>& NzQuaternion<T>::operator+=(const NzQuaternion& quat)
{
w += quat.w;
x += quat.x;
y += quat.y;
z += quat.z;
return *this;
return operator=(operator+(quat));
}
template<typename T>
NzQuaternion<T> NzQuaternion<T>::operator*=(const NzQuaternion& quat)
NzQuaternion<T>& NzQuaternion<T>::operator*=(const NzQuaternion& quat)
{
NzQuaternion q(*this);
operator=(q * quat);
return *this;
return operator=(operator*(quat));
}
template<typename T>
NzQuaternion<T> NzQuaternion<T>::operator*=(T scale)
NzQuaternion<T>& NzQuaternion<T>::operator*=(T scale)
{
w *= scale;
x *= scale;
y *= scale;
z *= scale;
return *this;
return operator=(operator*(scale));
}
template<typename T>
NzQuaternion<T> NzQuaternion<T>::operator/=(const NzQuaternion& quat)
NzQuaternion<T>& NzQuaternion<T>::operator/=(const NzQuaternion& quat)
{
NzQuaternion q(*this);
operator=(q / quat);
return *this;
return operator=(operator/(quat));
}
template<typename T>

View File

@ -28,6 +28,8 @@ class NzRect
void ExtendTo(const NzVector2<T>& point);
void ExtendTo(const NzRect& rect);
NzVector2<T> GetCenter() const;
bool Intersect(const NzRect& rect) const;
bool Intersect(const NzRect& rect, NzRect& intersection) const;

View File

@ -65,7 +65,7 @@ void NzRect<T>::ExtendTo(const NzVector2<T>& point)
x = std::min(x, point.x);
y = std::min(y, point.y);
width = std::max(x+width, point.x)-x;
height = std::max(x+width, point.x)-y;
height = std::max(y+height, point.y)-y;
}
template<typename T>
@ -74,7 +74,13 @@ void NzRect<T>::ExtendTo(const NzRect& rect)
x = std::min(x, rect.x);
y = std::min(y, rect.y);
width = std::max(x+width, rect.x+rect.width)-x;
height = std::max(x+width, rect.x+rect.height)-y;
height = std::max(x+height, rect.y+rect.height)-y;
}
template<typename T>
NzVector2<T> NzRect<T>::GetCenter() const
{
return NzVector2<T>((x+width)/2, (y+height)/2);
}
template<typename T>
@ -97,7 +103,7 @@ bool NzRect<T>::Intersect(const NzRect& rect, NzRect& intersection) const
intersection.x = left;
intersection.y = top;
intersection.width = right-left;
intersection.height = top-bottom;
intersection.height = bottom-top;
return true;
}

View File

@ -21,19 +21,22 @@ template<typename T> class NzVector2
~NzVector2() = default;
T AbsDotProduct(const NzVector2& vec) const;
double Distance(const NzVector2& vec) const;
T Distance(const NzVector2& vec) const;
float Distancef(const NzVector2& vec) const;
T DotProduct(const NzVector2& vec) const;
NzVector2 GetNormal() const;
void MakeCeil(const NzVector2& vec);
void MakeFloor(const NzVector2& vec);
double Length() const;
double Normalize();
T Length() const;
float Lengthf() const;
void Normalize();
T SquaredDistance(const NzVector2& vec) const;
T SquaredLength() const;
NzString ToString() const;
operator NzString() const;
operator T*();
operator const T*() const;
T& operator[](unsigned int i);
T operator[](unsigned int i) const;

View File

@ -49,17 +49,30 @@ T NzVector2<T>::AbsDotProduct(const NzVector2& vec) const
return std::fabs(x * vec.x) + std::fabs(y * vec.y);
}
template<> inline int NzVector2<int>::AbsDotProduct(const NzVector2<int>& vec) const
template<>
inline int NzVector2<int>::AbsDotProduct(const NzVector2<int>& vec) const
{
return std::labs(x * vec.x) + std::labs(y * vec.y);
}
template<>
inline unsigned int NzVector2<unsigned int>::AbsDotProduct(const NzVector2<unsigned int>& vec) const
{
return std::labs(x * vec.x) + std::labs(y * vec.y);
}
template<typename T>
double NzVector2<T>::Distance(const NzVector2& vec) const
T NzVector2<T>::Distance(const NzVector2& vec) const
{
return std::sqrt(SquaredDistance(vec));
}
template<typename T>
float NzVector2<T>::Distancef(const NzVector2& vec) const
{
return std::sqrt(static_cast<float>(SquaredDistance(vec)));
}
template<typename T>
T NzVector2<T>::DotProduct(const NzVector2& vec) const
{
@ -96,23 +109,27 @@ void NzVector2<T>::MakeFloor(const NzVector2& vec)
}
template<typename T>
double NzVector2<T>::Length() const
T NzVector2<T>::Length() const
{
return std::sqrt(SquaredLength());
}
template<typename T>
double NzVector2<T>::Normalize()
float NzVector2<T>::Lengthf() const
{
double length = Length();
return std::sqrt(static_cast<float>(SquaredLength()));
}
if (length != 0.f)
template<typename T>
void NzVector2<T>::Normalize()
{
auto length = Length();
if (!NzNumberEquals(length, static_cast<T>(0.0)))
{
x /= length;
y /= length;
}
return length;
}
template<typename T>
@ -136,9 +153,15 @@ NzString NzVector2<T>::ToString() const
}
template<typename T>
NzVector2<T>::operator NzString() const
NzVector2<T>::operator T*()
{
return ToString();
return &x;
}
template<typename T>
NzVector2<T>::operator const T*() const
{
return &x;
}
template<typename T>
@ -208,7 +231,7 @@ NzVector2<T> NzVector2<T>::operator*(T scale) const
template<typename T>
NzVector2<T> NzVector2<T>::operator/(const NzVector2& vec) const
{
if (vec.x == 0.f || vec.y == 0.f)
if (NzNumberEquals(vec.x, static_cast<T>(0.0)) || NzNumberEquals(vec.y, static_cast<T>(0.0)))
{
NzStringStream ss;
ss << __FILE__ << ':' << __LINE__ << ": Division by zero";
@ -222,7 +245,7 @@ NzVector2<T> NzVector2<T>::operator/(const NzVector2& vec) const
template<typename T>
NzVector2<T> NzVector2<T>::operator/(T scale) const
{
if (scale == 0.f)
if (NzNumberEquals(scale, static_cast<T>(0.0)))
{
NzStringStream ss;
ss << __FILE__ << ':' << __LINE__ << ": Division by zero";
@ -272,7 +295,7 @@ NzVector2<T>& NzVector2<T>::operator*=(T scale)
template<typename T>
NzVector2<T>& NzVector2<T>::operator/=(const NzVector2& vec)
{
if (vec.x == 0.f || vec.y == 0.f)
if (NzNumberEquals(vec.x, static_cast<T>(0.0)) || NzNumberEquals(vec.y, static_cast<T>(0.0)) || NzNumberEquals(vec.z, static_cast<T>(0.0)))
{
NzStringStream ss;
ss << __FILE__ << ':' << __LINE__ << ": Division by zero";
@ -289,7 +312,7 @@ NzVector2<T>& NzVector2<T>::operator/=(const NzVector2& vec)
template<typename T>
NzVector2<T>& NzVector2<T>::operator/=(T scale)
{
if (scale == 0.f)
if (NzNumberEquals(scale, static_cast<T>(0.0)))
{
NzStringStream ss;
ss << __FILE__ << ':' << __LINE__ << ": Division by zero";
@ -355,7 +378,7 @@ NzVector2<T> operator*(T scale, const NzVector2<T>& vec)
template<typename T>
NzVector2<T> operator/(T scale, const NzVector2<T>& vec)
{
if (vec.x == 0.f || vec.y == 0.f)
if (NzNumberEquals(vec.x, static_cast<T>(0.0)) || NzNumberEquals(vec.y, static_cast<T>(0.0)) || NzNumberEquals(vec.z, static_cast<T>(0.0)))
{
NzStringStream ss;
ss << __FILE__ << ':' << __LINE__ << ": Division by zero";

View File

@ -8,6 +8,7 @@
#define NAZARA_VECTOR3_HPP
#include <Nazara/Core/String.hpp>
#include <Nazara/Math/Vector2.hpp>
template<typename T> class NzVector3
{
@ -16,25 +17,29 @@ template<typename T> class NzVector3
NzVector3(T X, T Y, T Z);
explicit NzVector3(T scale);
NzVector3(T vec[3]);
NzVector3(const NzVector2<T>& vec);
template<typename U> explicit NzVector3(const NzVector3<U>& vec);
NzVector3(const NzVector3& vec) = default;
~NzVector3() = default;
T AbsDotProduct(const NzVector3& vec) const;
NzVector3 CrossProduct(const NzVector3& vec) const;
double Distance(const NzVector3& vec) const;
T Distance(const NzVector3& vec) const;
float Distancef(const NzVector3& vec) const;
T DotProduct(const NzVector3& vec) const;
NzVector3 GetNormal() const;
void MakeCeil(const NzVector3& vec);
void MakeFloor(const NzVector3& vec);
double Length() const;
double Normalize();
T Length() const;
float Lengthf() const;
void Normalize();
T SquaredDistance(const NzVector3& vec) const;
T SquaredLength() const;
NzString ToString() const;
operator NzString() const;
operator T*();
operator const T*() const;
T& operator[](unsigned int i);
T operator[](unsigned int i) const;
@ -76,6 +81,7 @@ template<typename T> NzVector3<T> operator/(T scale, const NzVector3<T>& vec);
typedef NzVector3<double> NzVector3d;
typedef NzVector3<float> NzVector3f;
typedef NzVector3<int> NzVector3i;
typedef NzVector3<unsigned int> NzVector3ui;
#include <Nazara/Math/Vector3.inl>

View File

@ -38,6 +38,14 @@ z(vec[2])
{
}
template<typename T>
NzVector3<T>::NzVector3(const NzVector2<T>& vec) :
x(vec.x),
y(vec.y),
z(0)
{
}
template<typename T>
template<typename U>
NzVector3<T>::NzVector3(const NzVector3<U>& vec) :
@ -53,7 +61,14 @@ T NzVector3<T>::AbsDotProduct(const NzVector3& vec) const
return std::fabs(x * vec.x) + std::fabs(y * vec.y) + std::fabs(z * vec.z);
}
template<> inline int NzVector3<int>::AbsDotProduct(const NzVector3<int>& vec) const
template<>
inline int NzVector3<int>::AbsDotProduct(const NzVector3<int>& vec) const
{
return std::labs(x * vec.x) + std::labs(y * vec.y) + std::labs(z * vec.z);
}
template<>
inline unsigned int NzVector3<unsigned int>::AbsDotProduct(const NzVector3<unsigned int>& vec) const
{
return std::labs(x * vec.x) + std::labs(y * vec.y) + std::labs(z * vec.z);
}
@ -65,11 +80,17 @@ NzVector3<T> NzVector3<T>::CrossProduct(const NzVector3& vec) const
}
template<typename T>
double NzVector3<T>::Distance(const NzVector3& vec) const
T NzVector3<T>::Distance(const NzVector3& vec) const
{
return std::sqrt(SquaredDistance(vec));
}
template<typename T>
float NzVector3<T>::Distancef(const NzVector3& vec) const
{
return std::sqrt(static_cast<float>(SquaredDistance()));
}
template<typename T>
T NzVector3<T>::DotProduct(const NzVector3& vec) const
{
@ -112,24 +133,28 @@ void NzVector3<T>::MakeFloor(const NzVector3& vec)
}
template<typename T>
double NzVector3<T>::Length() const
T NzVector3<T>::Length() const
{
return std::sqrt(SquaredLength());
}
template<typename T>
double NzVector3<T>::Normalize()
float NzVector3<T>::Lengthf() const
{
double length = Length();
return std::sqrt(static_cast<float>(SquaredLength()));
}
if (length != 0.f)
template<typename T>
void NzVector3<T>::Normalize()
{
T length = Length();
if (!NzNumberEquals(length, static_cast<T>(0.0)))
{
x /= length;
y /= length;
z /= length;
}
return length;
}
template<typename T>
@ -153,9 +178,15 @@ NzString NzVector3<T>::ToString() const
}
template<typename T>
NzVector3<T>::operator NzString() const
NzVector3<T>::operator T*()
{
return ToString();
return &x;
}
template<typename T>
NzVector3<T>::operator const T*() const
{
return &x;
}
template<typename T>
@ -225,7 +256,7 @@ NzVector3<T> NzVector3<T>::operator*(T scale) const
template<typename T>
NzVector3<T> NzVector3<T>::operator/(const NzVector3& vec) const
{
if (vec.x == 0.f || vec.y == 0.f || vec.z == 0.f)
if (NzNumberEquals(vec.x, static_cast<T>(0.0)) || NzNumberEquals(vec.y, static_cast<T>(0.0)) || NzNumberEquals(vec.z, static_cast<T>(0.0)))
{
NzStringStream ss;
ss << __FILE__ << ':' << __LINE__ << ": Division by zero";
@ -239,7 +270,7 @@ NzVector3<T> NzVector3<T>::operator/(const NzVector3& vec) const
template<typename T>
NzVector3<T> NzVector3<T>::operator/(T scale) const
{
if (scale == 0.f)
if (NzNumberEquals(scale, static_cast<T>(0.0)))
{
NzStringStream ss;
ss << __FILE__ << ':' << __LINE__ << ": Division by zero";
@ -293,7 +324,7 @@ NzVector3<T>& NzVector3<T>::operator*=(T scale)
template<typename T>
NzVector3<T>& NzVector3<T>::operator/=(const NzVector3& vec)
{
if (vec.x == 0.f || vec.y == 0.f || vec.z == 0.f)
if (NzNumberEquals(vec.x, static_cast<T>(0.0)) || NzNumberEquals(vec.y, static_cast<T>(0.0)) || NzNumberEquals(vec.z, static_cast<T>(0.0)))
{
NzStringStream ss;
ss << __FILE__ << ':' << __LINE__ << ": Division by zero";
@ -311,7 +342,7 @@ NzVector3<T>& NzVector3<T>::operator/=(const NzVector3& vec)
template<typename T>
NzVector3<T>& NzVector3<T>::operator/=(T scale)
{
if (scale == 0.f)
if (NzNumberEquals(scale, static_cast<T>(0.0)))
{
NzStringStream ss;
ss << __FILE__ << ':' << __LINE__ << ": Division by zero";
@ -379,7 +410,7 @@ NzVector3<T> operator*(T scale, const NzVector3<T>& vec)
template<typename T>
NzVector3<T> operator/(T scale, const NzVector3<T>& vec)
{
if (vec.x == 0.f || vec.y == 0.f || vec.z == 0.f)
if (NzNumberEquals(vec.x, static_cast<T>(0.0)) || NzNumberEquals(vec.y, static_cast<T>(0.0)) || NzNumberEquals(vec.z, static_cast<T>(0.0)))
{
NzStringStream ss;
ss << __FILE__ << ':' << __LINE__ << ": Division by zero";

View File

@ -8,6 +8,7 @@
#define NAZARA_VECTOR4_HPP
#include <Nazara/Core/String.hpp>
#include <Nazara/Math/Vector3.hpp>
template<typename T> class NzVector4
{
@ -17,6 +18,7 @@ template<typename T> class NzVector4
explicit NzVector4(T scale);
NzVector4(T vec[4]);
template<typename U> explicit NzVector4(const NzVector4<U>& vec);
NzVector4(const NzVector3<T>& vec, T W = 1.0);
NzVector4(const NzVector4& vec) = default;
~NzVector4() = default;
@ -28,7 +30,8 @@ template<typename T> class NzVector4
NzString ToString() const;
operator NzString() const;
operator T*();
operator const T*() const;
T& operator[](unsigned int i);
T operator[](unsigned int i) const;

View File

@ -51,13 +51,29 @@ w(static_cast<T>(vec.w))
{
}
template<typename T>
NzVector4<T>::NzVector4(const NzVector3<T>& vec, T W) :
x(vec.x),
y(vec.y),
z(vec.z),
w(W)
{
}
template<typename T>
T NzVector4<T>::AbsDotProduct(const NzVector4& vec) const
{
return std::fabs(x * vec.x) + std::fabs(y * vec.y) + std::fabs(z * vec.z) + std::fabs(w * vec.w);
}
template<> inline int NzVector4<int>::AbsDotProduct(const NzVector4<int>& vec) const
template<>
inline int NzVector4<int>::AbsDotProduct(const NzVector4<int>& vec) const
{
return std::labs(x * vec.x) + std::labs(y * vec.y) + std::labs(z * vec.z) + std::labs(w * vec.w);
}
template<>
inline unsigned int NzVector4<unsigned int>::AbsDotProduct(const NzVector4<unsigned int>& vec) const
{
return std::labs(x * vec.x) + std::labs(y * vec.y) + std::labs(z * vec.z) + std::labs(w * vec.w);
}
@ -103,7 +119,7 @@ void NzVector4<T>::MakeFloor(const NzVector4& vec)
template<typename T>
void NzVector4<T>::Normalize()
{
if (w != 0.f)
if (!NzNumberEquals(w, static_cast<T>(0.0)))
{
x /= w;
y /= w;
@ -116,13 +132,19 @@ NzString NzVector4<T>::ToString() const
{
NzStringStream ss;
return ss << "Vector4(" << x << ", " << y << ", " << z <<')';
return ss << "Vector4(" << x << ", " << y << ", " << z << ", " << w << ')';
}
template<typename T>
NzVector4<T>::operator NzString() const
NzVector4<T>::operator T*()
{
return ToString();
return &x;
}
template<typename T>
NzVector4<T>::operator const T*() const
{
return &x;
}
template<typename T>
@ -174,7 +196,7 @@ NzVector4<T> NzVector4<T>::operator+(const NzVector4& vec) const
template<typename T>
NzVector4<T> NzVector4<T>::operator-(const NzVector4& vec) const
{
return NzVector4(x - vec.x, y - vec.y, z - vec.z);
return NzVector4(x - vec.x, y - vec.y, z - vec.z, w - vec.w);
}
template<typename T>
@ -192,7 +214,7 @@ NzVector4<T> NzVector4<T>::operator*(T scale) const
template<typename T>
NzVector4<T> NzVector4<T>::operator/(const NzVector4& vec) const
{
if (vec.x == 0.f || vec.y == 0.f || vec.z == 0.f || vec.w == 0.f)
if (NzNumberEquals(vec.x, static_cast<T>(0.0)) || NzNumberEquals(vec.y, static_cast<T>(0.0)) || NzNumberEquals(vec.z, static_cast<T>(0.0)) || NzNumberEquals(vec.w, static_cast<T>(0.0)))
{
NzStringStream ss;
ss << __FILE__ << ':' << __LINE__ << ": Division by zero";
@ -206,7 +228,7 @@ NzVector4<T> NzVector4<T>::operator/(const NzVector4& vec) const
template<typename T>
NzVector4<T> NzVector4<T>::operator/(T scale) const
{
if (scale == 0.f)
if (NzNumberEquals(scale, static_cast<T>(0.0)))
{
NzStringStream ss;
ss << __FILE__ << ':' << __LINE__ << ": Division by zero";
@ -264,7 +286,7 @@ NzVector4<T>& NzVector4<T>::operator*=(T scale)
template<typename T>
NzVector4<T>& NzVector4<T>::operator/=(const NzVector4& vec)
{
if (vec.x == 0.f || vec.y == 0.f || vec.z == 0.f || vec.w == 0.f)
if (NzNumberEquals(vec.x, static_cast<T>(0.0)) || NzNumberEquals(vec.y, static_cast<T>(0.0)) || NzNumberEquals(vec.z, static_cast<T>(0.0)) || NzNumberEquals(vec.w, static_cast<T>(0.0)))
{
NzStringStream ss;
ss << __FILE__ << ':' << __LINE__ << ": Division by zero";
@ -283,7 +305,7 @@ NzVector4<T>& NzVector4<T>::operator/=(const NzVector4& vec)
template<typename T>
NzVector4<T>& NzVector4<T>::operator/=(T scale)
{
if (scale == 0.f)
if (NzNumberEquals(scale, static_cast<T>(0.0)))
{
NzStringStream ss;
ss << __FILE__ << ':' << __LINE__ << ": Division by zero";
@ -353,7 +375,7 @@ NzVector4<T> operator*(T scale, const NzVector4<T>& vec)
template<typename T>
NzVector4<T> operator/(T scale, const NzVector4<T>& vec)
{
if (vec.x == 0.f || vec.y == 0.f || vec.z == 0.f || vec.w == 0.f)
if (NzNumberEquals(vec.x, static_cast<T>(0.0)) || NzNumberEquals(vec.y, static_cast<T>(0.0)) || NzNumberEquals(vec.z, static_cast<T>(0.0)) || NzNumberEquals(vec.w, static_cast<T>(0.0)))
{
NzStringStream ss;
ss << __FILE__ << ':' << __LINE__ << ": Division by zero";

View File

@ -5,10 +5,9 @@
#ifndef NAZARA_PREREQUESITES_HPP
#define NAZARA_PREREQUESITES_HPP
// (Commenté en attendant GCC 4.7)
/*#if __cplusplus < 201103L
#if __cplusplus < 201103L
#error Nazara requires a C++11 compliant compiler
#endif*/
#endif
// Version du moteur
#define NAZARA_VERSION_MAJOR 0
@ -17,23 +16,27 @@
#include <Nazara/Core/Config.hpp>
///TODO: Rajouter des tests d'identification de compilateurs
// NAZARA_THREADLOCAL n'existe qu'en attendant le support complet de thread_local
#if defined(_MSC_VER)
#define NAZARA_COMPILER_MSVC
#define NAZARA_DEPRECATED(txt) __declspec(deprecated(txt))
#define NAZARA_FUNCTION __FUNCSIG__
#define NAZARA_THREADLOCAL __declspec(thread)
#elif defined(__GNUC__)
#define NAZARA_COMPILER_GCC
#define NAZARA_FUNCTION __PRETTY_FUNCTION__
#define NAZARA_DEPRECATED(txt) __attribute__((__deprecated__(txt)))
#define NAZARA_FUNCTION __PRETTY_FUNCTION__
#define NAZARA_THREADLOCAL __thread
#elif defined(__BORLANDC__)
#define NAZARA_COMPILER_BORDLAND
#define NAZARA_DEPRECATED(txt)
#define NAZARA_FUNCTION __FUNC__
#define NAZARA_THREADLOCAL __declspec(thread)
#else
#define NAZARA_COMPILER_UNKNOWN
#define NAZARA_DEPRECATED(txt)
#define NAZARA_FUNCTION __func__ // __func__ est standard depuis le C++11
#define NAZARA_THREADLOCAL thread_local
#error This compiler is not fully supported
#endif
@ -63,24 +66,18 @@
#if NAZARA_CORE_WINDOWS_VISTA
// Version de Windows minimale : Vista
#define NAZARA_WINNT 0x0600
#else
#define NAZARA_WINNT 0x0501
#endif
#if defined(_WIN32_WINNT)
#if _WIN32_WINNT < 0x0600
#if _WIN32_WINNT < NAZARA_WINNT
#undef _WIN32_WINNT
#define _WIN32_WINNT 0x0600
#define _WIN32_WINNT NAZARA_WINNT
#endif
#else
#define _WIN32_WINNT 0x0600
#endif
#else
// Version de Windows minimale : XP
#if defined(_WIN32_WINNT)
#if _WIN32_WINNT < 0x0501
#undef _WIN32_WINNT
#define _WIN32_WINNT 0x0501
#endif
#else
#define _WIN32_WINNT 0x0501
#endif
#define _WIN32_WINNT NAZARA_WINNT
#endif
#endif
#elif defined(linux) || defined(__linux)

View File

@ -8,15 +8,15 @@
#define NAZARA_BUFFER_HPP
#include <Nazara/Prerequesites.hpp>
#include <Nazara/Utility/NonCopyable.hpp>
#include <Nazara/Core/NonCopyable.hpp>
#include <Nazara/Utility/Resource.hpp>
enum nzBufferLock
enum nzBufferAccess
{
nzBufferLock_DiscardAndWrite,
nzBufferLock_ReadOnly,
nzBufferLock_ReadWrite,
nzBufferLock_WriteOnly
nzBufferAccess_DiscardAndWrite,
nzBufferAccess_ReadOnly,
nzBufferAccess_ReadWrite,
nzBufferAccess_WriteOnly
};
enum nzBufferStorage
@ -68,8 +68,8 @@ class NAZARA_API NzBuffer : public NzResource, NzNonCopyable
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();
static bool IsSupported(nzBufferStorage storage);

View File

@ -38,6 +38,9 @@
// Utilise un tracker pour repérer les éventuels leaks (Ralentit l'exécution)
#define NAZARA_RENDERER_MEMORYLEAKTRACKER 0
// Active le paramère debug des paramètres des contextes par défaut (Perte de performances mais capable de recevoir des messages d'OpenGL)
#define NAZARA_RENDERER_OPENGL_DEBUG 0
// Active les tests de sécurité basés sur le code (Conseillé pour le développement)
#define NAZARA_RENDERER_SAFE 1

View File

@ -24,16 +24,18 @@ class NAZARA_API NzContext
~NzContext();
bool Create(const NzContextParameters& parameters = NzContextParameters());
void Destroy();
const NzContextParameters& GetParameters() const;
bool IsActive() const;
bool SetActive(bool active);
void SwapBuffers();
static const NzContext* GetCurrent();
static bool EnsureContext();
static NzContext* GetCurrent();
static const NzContext* GetReference();
static const NzContext* GetThreadContext();
static bool InitializeReference();
static void UninitializeReference();
static NzContext* GetThreadContext();
static bool Initialize();
static void Uninitialize();
private:
NzContextParameters m_parameters;

View File

@ -25,6 +25,7 @@ struct NAZARA_API NzContextParameters
shareContext(defaultShareContext),
window(defaultWindow),
compatibilityProfile(defaultCompatibilityProfile),
debugMode(defaultDebugMode),
doubleBuffered(defaultDoubleBuffered),
shared(defaultShared)
{
@ -39,6 +40,7 @@ struct NAZARA_API NzContextParameters
const NzContext* shareContext;
NzWindowHandle window;
bool compatibilityProfile;
bool debugMode;
bool doubleBuffered;
bool shared;
@ -47,6 +49,7 @@ struct NAZARA_API NzContextParameters
static const NzContext* defaultShareContext;
static NzWindowHandle defaultWindow;
static bool defaultCompatibilityProfile;
static bool defaultDebugMode;
static bool defaultDoubleBuffered;
static bool defaultShared;
};

View File

@ -30,8 +30,8 @@ class NAZARA_API NzIndexBuffer
bool IsHardware() const;
bool IsSequential() 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:
NzBuffer* m_buffer;

View File

@ -8,7 +8,7 @@
#define NAZARA_OCCLUSIONQUERY_HPP
#include <Nazara/Prerequesites.hpp>
#include <Nazara/Utility/NonCopyable.hpp>
#include <Nazara/Core/NonCopyable.hpp>
class NAZARA_API NzOcclusionQuery : NzNonCopyable
{

View File

@ -34,13 +34,19 @@ class NAZARA_API NzOpenGL
enum Extension
{
AnisotropicFilter,
DebugOutput,
FP64,
Framebuffer_Object,
FrameBufferObject,
SeparateShaderObjects,
Texture3D,
TextureCompression_s3tc,
TextureStorage,
VertexArrayObject,
Count
};
static NzOpenGLFunc GetEntry(const NzString& entryPoint);
static unsigned int GetVersion();
static bool Initialize();
static bool IsSupported(Extension extension);
@ -56,6 +62,7 @@ NAZARA_API extern PFNGLBINDBUFFERPROC glBindBuffer;
NAZARA_API extern PFNGLBINDFRAMEBUFFERPROC glBindFramebuffer;
NAZARA_API extern PFNGLBINDRENDERBUFFERPROC glBindRenderbuffer;
NAZARA_API extern PFNGLBINDTEXTUREPROC glBindTexture;
NAZARA_API extern PFNGLBINDVERTEXARRAYPROC glBindVertexArray;
NAZARA_API extern PFNGLBLENDFUNCPROC glBlendFunc;
NAZARA_API extern PFNGLBUFFERDATAPROC glBufferData;
NAZARA_API extern PFNGLBUFFERSUBDATAPROC glBufferSubData;
@ -69,6 +76,10 @@ NAZARA_API extern PFNGLCHECKFRAMEBUFFERSTATUSPROC glCheckFramebufferStatus;
NAZARA_API extern PFNGLCOLORMASKPROC glColorMask;
NAZARA_API extern PFNGLCULLFACEPROC glCullFace;
NAZARA_API extern PFNGLCOMPILESHADERPROC glCompileShader;
NAZARA_API extern PFNGLCOPYTEXSUBIMAGE2DPROC glCopyTexSubImage2D;
NAZARA_API extern PFNGLDEBUGMESSAGECONTROLARBPROC glDebugMessageControl;
NAZARA_API extern PFNGLDEBUGMESSAGEINSERTARBPROC glDebugMessageInsert;
NAZARA_API extern PFNGLDEBUGMESSAGECALLBACKARBPROC glDebugMessageCallback;
NAZARA_API extern PFNGLDELETEBUFFERSPROC glDeleteBuffers;
NAZARA_API extern PFNGLDELETEFRAMEBUFFERSPROC glDeleteFramebuffers;
NAZARA_API extern PFNGLDELETEPROGRAMPROC glDeleteProgram;
@ -76,6 +87,7 @@ NAZARA_API extern PFNGLDELETEQUERIESPROC glDeleteQueries;
NAZARA_API extern PFNGLDELETERENDERBUFFERSPROC glDeleteRenderbuffers;
NAZARA_API extern PFNGLDELETESHADERPROC glDeleteShader;
NAZARA_API extern PFNGLDELETETEXTURESPROC glDeleteTextures;
NAZARA_API extern PFNGLDELETEVERTEXARRAYSPROC glDeleteVertexArrays;
NAZARA_API extern PFNGLDEPTHFUNCPROC glDepthFunc;
NAZARA_API extern PFNGLDEPTHMASKPROC glDepthMask;
NAZARA_API extern PFNGLDISABLEPROC glDisable;
@ -96,7 +108,9 @@ NAZARA_API extern PFNGLGENFRAMEBUFFERSPROC glGenFramebuffers;
NAZARA_API extern PFNGLGENQUERIESPROC glGenQueries;
NAZARA_API extern PFNGLGENRENDERBUFFERSPROC glGenRenderbuffers;
NAZARA_API extern PFNGLGENTEXTURESPROC glGenTextures;
NAZARA_API extern PFNGLGENVERTEXARRAYSPROC glGenVertexArrays;
NAZARA_API extern PFNGLGETBUFFERPARAMETERIVPROC glGetBufferParameteriv;
NAZARA_API extern PFNGLGETDEBUGMESSAGELOGARBPROC glGetDebugMessageLog;
NAZARA_API extern PFNGLGETERRORPROC glGetError;
NAZARA_API extern PFNGLGETINTEGERVPROC glGetIntegerv;
NAZARA_API extern PFNGLGETPROGRAMIVPROC glGetProgramiv;
@ -110,24 +124,44 @@ NAZARA_API extern PFNGLGETSHADERSOURCEPROC glGetShaderSource;
NAZARA_API extern PFNGLGETSTRINGPROC glGetString;
NAZARA_API extern PFNGLGETSTRINGIPROC glGetStringi;
NAZARA_API extern PFNGLGETTEXIMAGEPROC glGetTexImage;
NAZARA_API extern PFNGLGETTEXLEVELPARAMETERFVPROC glGetTexLevelParameterfv;
NAZARA_API extern PFNGLGETTEXLEVELPARAMETERIVPROC glGetTexLevelParameteriv;
NAZARA_API extern PFNGLGETTEXPARAMETERFVPROC glGetTexParameterfv;
NAZARA_API extern PFNGLGETTEXPARAMETERIVPROC glGetTexParameteriv;
NAZARA_API extern PFNGLGETUNIFORMLOCATIONPROC glGetUniformLocation;
NAZARA_API extern PFNGLLINKPROGRAMPROC glLinkProgram;
NAZARA_API extern PFNGLMAPBUFFERPROC glMapBuffer;
NAZARA_API extern PFNGLMAPBUFFERRANGEPROC glMapBufferRange;
NAZARA_API extern PFNGLPIXELSTOREIPROC glPixelStorei;
NAZARA_API extern PFNGLPOLYGONMODEPROC glPolygonMode;
NAZARA_API extern PFNGLPROGRAMUNIFORM1DPROC glProgramUniform1d;
NAZARA_API extern PFNGLPROGRAMUNIFORM1FPROC glProgramUniform1f;
NAZARA_API extern PFNGLPROGRAMUNIFORM1IPROC glProgramUniform1i;
NAZARA_API extern PFNGLPROGRAMUNIFORM2DVPROC glProgramUniform2dv;
NAZARA_API extern PFNGLPROGRAMUNIFORM2FVPROC glProgramUniform2fv;
NAZARA_API extern PFNGLPROGRAMUNIFORM3DVPROC glProgramUniform3dv;
NAZARA_API extern PFNGLPROGRAMUNIFORM3FVPROC glProgramUniform3fv;
NAZARA_API extern PFNGLPROGRAMUNIFORM4DVPROC glProgramUniform4dv;
NAZARA_API extern PFNGLPROGRAMUNIFORM4FVPROC glProgramUniform4fv;
NAZARA_API extern PFNGLPROGRAMUNIFORMMATRIX4DVPROC glProgramUniformMatrix4dv;
NAZARA_API extern PFNGLPROGRAMUNIFORMMATRIX4FVPROC glProgramUniformMatrix4fv;
NAZARA_API extern PFNGLREADPIXELSPROC glReadPixels;
NAZARA_API extern PFNGLRENDERBUFFERSTORAGEPROC glRenderbufferStorage;
NAZARA_API extern PFNGLSCISSORPROC glScissor;
NAZARA_API extern PFNGLSHADERSOURCEPROC glShaderSource;
NAZARA_API extern PFNGLSTENCILFUNCPROC glStencilFunc;
NAZARA_API extern PFNGLSTENCILOPPROC glStencilOp;
NAZARA_API extern PFNGLTEXIMAGE1DPROC glTexImage1D;
NAZARA_API extern PFNGLTEXIMAGE2DPROC glTexImage2D;
NAZARA_API extern PFNGLTEXIMAGE3DEXTPROC glTexImage3D;
NAZARA_API extern PFNGLTEXIMAGE3DPROC glTexImage3D;
NAZARA_API extern PFNGLTEXPARAMETERFPROC glTexParameterf;
NAZARA_API extern PFNGLTEXPARAMETERIPROC glTexParameteri;
NAZARA_API extern PFNGLTEXSTORAGE1DPROC glTexStorage1D;
NAZARA_API extern PFNGLTEXSTORAGE2DPROC glTexStorage2D;
NAZARA_API extern PFNGLTEXSTORAGE3DPROC glTexStorage3D;
NAZARA_API extern PFNGLTEXSUBIMAGE1DPROC glTexSubImage1D;
NAZARA_API extern PFNGLTEXSUBIMAGE2DPROC glTexSubImage2D;
NAZARA_API extern PFNGLTEXSUBIMAGE3DEXTPROC glTexSubImage3D;
NAZARA_API extern PFNGLTEXSUBIMAGE3DPROC glTexSubImage3D;
NAZARA_API extern PFNGLUNIFORM1DPROC glUniform1d;
NAZARA_API extern PFNGLUNIFORM1FPROC glUniform1f;
NAZARA_API extern PFNGLUNIFORM1IPROC glUniform1i;

View File

@ -21,15 +21,16 @@ class NAZARA_API NzRenderTarget
NzRenderTarget() = default;
virtual ~NzRenderTarget();
virtual bool CanActivate() const = 0;
virtual NzRenderTargetParameters GetRenderTargetParameters() const = 0;
#ifdef NAZARA_RENDERER_OPENGL
#ifndef NAZARA_RENDERER_COMMON
virtual bool HasContext() const = 0;
#endif
virtual unsigned int GetHeight() const = 0;
virtual NzRenderTargetParameters GetParameters() const = 0;
virtual unsigned int GetWidth() const = 0;
bool IsActive() const;
virtual bool IsValid() const = 0;
bool SetActive(bool active);

View File

@ -10,15 +10,14 @@
#define NAZARA_RENDERWINDOW_HPP
#include <Nazara/Prerequesites.hpp>
#include <Nazara/Renderer/RenderTarget.hpp>
#include <Nazara/Renderer/Config.hpp>
#include <Nazara/Renderer/ContextParameters.hpp>
#include <Nazara/Renderer/RenderTarget.hpp>
#include <Nazara/Utility/Window.hpp>
#ifndef NAZARA_RENDERER_COMMON
#include <Nazara/Renderer/ContextParameters.hpp>
#endif
class NzContext;
class NzImage;
class NzTexture;
struct NzContextParameters;
class NAZARA_API NzRenderWindow : public NzRenderTarget, public NzWindow
@ -29,7 +28,8 @@ class NAZARA_API NzRenderWindow : public NzRenderTarget, public NzWindow
NzRenderWindow(NzWindowHandle handle, const NzContextParameters& parameters = NzContextParameters());
virtual ~NzRenderWindow();
bool CanActivate() const;
bool CopyToImage(NzImage* image); ///TODO: Const
bool CopyToTexture(NzTexture* texture); ///TODO: Const
bool Create(NzVideoMode mode, const NzString& title, nzUInt32 style = NzWindow::Default, const NzContextParameters& parameters = NzContextParameters());
bool Create(NzWindowHandle handle, const NzContextParameters& parameters = NzContextParameters());
@ -38,14 +38,20 @@ class NAZARA_API NzRenderWindow : public NzRenderTarget, public NzWindow
void EnableVerticalSync(bool enabled);
NzRenderTargetParameters GetRenderTargetParameters() const;
#ifndef NAZARA_RENDERER_COMMON
NzContextParameters GetContextParameters() const;
#endif
unsigned int GetHeight() const;
NzRenderTargetParameters GetParameters() const;
unsigned int GetWidth() const;
#ifndef NAZARA_RENDERER_COMMON
bool HasContext() const;
#endif
bool IsValid() const;
protected:
bool Activate();

View File

@ -8,9 +8,40 @@
#define NAZARA_RENDERER_HPP
#include <Nazara/Prerequesites.hpp>
#include <Nazara/Math/Rect.hpp>
#include <map>
#include <tuple>
#define NazaraRenderer NzRenderer::Instance()
enum nzBlendFunc
{
nzBlendFunc_DestAlpha,
nzBlendFunc_DestColor,
nzBlendFunc_SrcAlpha,
nzBlendFunc_SrcColor,
nzBlendFunc_InvDestAlpha,
nzBlendFunc_InvDestColor,
nzBlendFunc_InvSrcAlpha,
nzBlendFunc_InvSrcColor,
nzBlendFunc_One,
nzBlendFunc_Zero
};
enum nzFaceCulling
{
nzFaceCulling_Back,
nzFaceCulling_Front,
nzFaceCulling_FrontAndBack
};
enum nzFaceFilling
{
nzFaceFilling_Point,
nzFaceFilling_Line,
nzFaceFilling_Fill
};
enum nzPrimitiveType
{
nzPrimitiveType_LineList,
@ -44,6 +75,41 @@ enum nzRendererClear
nzRendererClear_Stencil = 0x04
};
enum nzRendererComparison
{
nzRendererComparison_Always,
nzRendererComparison_Equal,
nzRendererComparison_Greater,
nzRendererComparison_GreaterOrEqual,
nzRendererComparison_Less,
nzRendererComparison_LessOrEqual,
nzRendererComparison_Never
};
enum nzRendererParameter
{
nzRendererParameter_Blend,
nzRendererParameter_ColorWrite,
nzRendererParameter_DepthTest,
nzRendererParameter_DepthWrite,
nzRendererParameter_FaceCulling,
nzRendererParameter_Stencil
};
enum nzStencilOperation
{
nzStencilOperation_Decrement,
nzStencilOperation_DecrementToSaturation,
nzStencilOperation_Increment,
nzStencilOperation_IncrementToSaturation,
nzStencilOperation_Invert,
nzStencilOperation_Keep,
nzStencilOperation_Replace,
nzStencilOperation_Zero
};
class NzColor;
class NzContext;
class NzIndexBuffer;
class NzRenderTarget;
class NzShader;
@ -57,26 +123,42 @@ class NAZARA_API NzRenderer
NzRenderer();
~NzRenderer();
void Clear(nzRendererClear flags);
void Clear(unsigned long flags = nzRendererClear_Color | nzRendererClear_Depth);
void DrawIndexedPrimitives(nzPrimitiveType primitive, unsigned int firstIndex, unsigned int indexCount);
void DrawPrimitives(nzPrimitiveType primitive, unsigned int firstVertex, unsigned int vertexCount);
void Enable(nzRendererParameter parameter, bool enable);
unsigned int GetMaxAnisotropyLevel() const;
unsigned int GetMaxRenderTargets() const;
unsigned int GetMaxTextureUnits() const;
NzShader* GetShader() const;
NzRenderTarget* GetTarget() const;
NzRectui GetViewport() const;
bool HasCapability(nzRendererCap capability) const;
bool Initialize();
void SetBlendFunc(nzBlendFunc src, nzBlendFunc dest);
void SetClearColor(const NzColor& color);
void SetClearColor(nzUInt8 r, nzUInt8 g, nzUInt8 b, nzUInt8 a = 255);
void SetClearDepth(double depth);
void SetClearStencil(unsigned int value);
void SetFaceCulling(nzFaceCulling cullingMode);
void SetFaceFilling(nzFaceFilling fillingMode);
bool SetIndexBuffer(const NzIndexBuffer* indexBuffer);
bool SetShader(NzShader* shader);
void SetStencilCompareFunction(nzRendererComparison compareFunc);
void SetStencilFailOperation(nzStencilOperation failOperation);
void SetStencilMask(nzUInt32 mask);
void SetStencilPassOperation(nzStencilOperation passOperation);
void SetStencilReferenceValue(unsigned int refValue);
void SetStencilZFailOperation(nzStencilOperation zfailOperation);
bool SetTarget(NzRenderTarget* target);
bool SetVertexBuffer(const NzVertexBuffer* vertexBuffer);
bool SetVertexDeclaration(const NzVertexDeclaration* vertexDeclaration);
void SetViewport(const NzRectui& viewport);
void Uninitialize();
@ -84,16 +166,30 @@ class NAZARA_API NzRenderer
static bool IsInitialized();
private:
bool UpdateVertexBuffer();
bool EnsureStateUpdate();
typedef std::tuple<const NzContext*, const NzIndexBuffer*, const NzVertexBuffer*, const NzVertexDeclaration*> VAO_Key;
std::map<VAO_Key, unsigned int> m_vaos;
nzRendererComparison m_stencilCompare;
nzStencilOperation m_stencilFail;
nzStencilOperation m_stencilPass;
nzStencilOperation m_stencilZFail;
nzUInt32 m_stencilMask;
const NzIndexBuffer* m_indexBuffer;
NzRenderTarget* m_target;
NzShader* m_shader;
NzUtility* m_utilityModule;
const NzVertexBuffer* m_vertexBuffer;
const NzVertexDeclaration* m_vertexDeclaration;
bool m_vaoUpdated;
bool m_capabilities[nzRendererCap_Count];
bool m_vertexBufferUpdated;
bool m_stencilFuncUpdated;
bool m_stencilOpUpdated;
unsigned int m_maxAnisotropyLevel;
unsigned int m_maxRenderTarget;
unsigned int m_maxTextureUnit;
unsigned int m_stencilReference;
static NzRenderer* s_instance;
static bool s_initialized;

View File

@ -8,9 +8,12 @@
#define NAZARA_SHADER_HPP
#include <Nazara/Prerequesites.hpp>
#include <Nazara/Core/NonCopyable.hpp>
#include <Nazara/Core/String.hpp>
#include <Nazara/Math/Matrix4.hpp>
#include <Nazara/Utility/NonCopyable.hpp>
#include <Nazara/Math/Vector2.hpp>
#include <Nazara/Math/Vector3.hpp>
#include <Nazara/Math/Vector4.hpp>
#include <Nazara/Utility/Resource.hpp>
enum nzShaderLanguage
@ -32,6 +35,7 @@ enum nzShaderType
class NzRenderer;
class NzShaderImpl;
class NzTexture;
class NAZARA_API NzShader : public NzResource, NzNonCopyable
{
@ -65,6 +69,13 @@ class NAZARA_API NzShader : public NzResource, NzNonCopyable
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 Unlock();

View File

@ -0,0 +1,103 @@
// Copyright (C) 2012 Jérôme Leclercq
// This file is part of the "Nazara Engine".
// For conditions of distribution and use, see copyright notice in Config.hpp
#pragma once
#ifndef NAZARA_TEXTURE_HPP
#define NAZARA_TEXTURE_HPP
#include <Nazara/Prerequesites.hpp>
#include <Nazara/Core/NonCopyable.hpp>
#include <Nazara/Utility/Image.hpp>
#include <Nazara/Utility/PixelFormat.hpp>
enum nzTextureFilter
{
nzTextureFilter_Bilinear,
nzTextureFilter_Nearest,
nzTextureFilter_Trilinear,
nzTextureFilter_Unknown
};
enum nzTextureWrap
{
nzTextureWrap_Clamp,
nzTextureWrap_Repeat,
nzTextureWrap_Unknown
};
class NzShader;
struct NzTextureImpl;
class NAZARA_API NzTexture : public NzResource, NzNonCopyable
{
friend class NzShader;
public:
NzTexture();
explicit NzTexture(const NzImage& image);
~NzTexture();
#ifndef NAZARA_RENDERER_COMMON
bool Bind() const;
#endif
bool Create(nzImageType type, nzPixelFormat format, unsigned int width, unsigned int height, unsigned int depth = 1, nzUInt8 levelCount = 1, bool lock = false);
void Destroy();
bool Download(NzImage* image) const;
bool EnableMipmapping(bool enable);
unsigned int GetAnisotropyLevel() const;
nzUInt8 GetBPP() const;
unsigned int GetDepth() const;
nzTextureFilter GetFilterMode() const;
nzPixelFormat GetFormat() const;
unsigned int GetHeight() const;
nzImageType GetType() const;
unsigned int GetWidth() const;
nzTextureWrap GetWrapMode() const;
bool IsCompressed() const;
bool IsCubemap() const;
bool IsTarget() const;
bool IsValid() const;
bool LoadFromFile(const NzString& filePath, const NzImageParams& params = NzImageParams());
bool LoadFromImage(const NzImage& image);
bool LoadFromMemory(const void* data, std::size_t size, const NzImageParams& params = NzImageParams());
bool LoadFromStream(NzInputStream& stream, const NzImageParams& params = NzImageParams());
bool Lock();
bool SetAnisotropyLevel(unsigned int anistropyLevel);
bool SetFilterMode(nzTextureFilter filter);
bool SetMipmapRange(nzUInt8 minLevel, nzUInt8 maxLevel);
bool SetWrapMode(nzTextureWrap wrap);
bool Update(const NzImage& image, nzUInt8 level = 0);
bool Update(const NzImage& image, const NzRectui& rect, unsigned int z = 0, nzUInt8 level = 0);
bool Update(const NzImage& image, const NzCubeui& cube, nzUInt8 level = 0);
bool Update(const nzUInt8* pixels, nzUInt8 level = 0);
bool Update(const nzUInt8* pixels, const NzRectui& rect, unsigned int z = 0, nzUInt8 level = 0);
bool Update(const nzUInt8* pixels, const NzCubeui& cube, nzUInt8 level = 0);
bool UpdateFace(nzCubemapFace face, const NzImage& image, nzUInt8 level = 0);
bool UpdateFace(nzCubemapFace face, const NzImage& image, const NzRectui& rect, nzUInt8 level = 0);
bool UpdateFace(nzCubemapFace face, const nzUInt8* pixels, nzUInt8 level = 0);
bool UpdateFace(nzCubemapFace face, const nzUInt8* pixels, const NzRectui& rect, nzUInt8 level = 0);
void Unlock();
static unsigned int GetValidSize(unsigned int size);
static bool IsFormatSupported(nzPixelFormat format);
static bool IsTypeSupported(nzImageType type);
private:
void SetTarget(bool isTarget);
NzTextureImpl* m_impl;
};
#endif // NAZARA_TEXTURE_HPP

View File

@ -29,8 +29,8 @@ class NAZARA_API NzVertexBuffer
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:
NzBuffer* m_buffer;

View File

@ -36,6 +36,6 @@
#define NAZARA_UTILITY_SAFE 1
// Fait tourner chaque fenêtre dans un thread séparé si le système le supporte
#define NAZARA_UTILITY_THREADED_WINDOW 1
#define NAZARA_UTILITY_THREADED_WINDOW 0 ///FIXME: Buggé depuis GCC 4.7
#endif // NAZARA_CONFIG_UTILITY_HPP

View File

@ -8,8 +8,11 @@
#define NAZARA_IMAGE_HPP
#include <Nazara/Prerequesites.hpp>
#include <Nazara/Core/Color.hpp>
#include <Nazara/Core/InputStream.hpp>
#include <Nazara/Math/Cube.hpp>
#include <Nazara/Math/Rect.hpp>
#include <Nazara/Math/Vector3.hpp>
#include <Nazara/Utility/ResourceLoader.hpp>
#include <Nazara/Utility/PixelFormat.hpp>
#include <Nazara/Utility/Resource.hpp>
@ -17,12 +20,12 @@
enum nzCubemapFace
{
nzCubemapFace_PositiveX,
nzCubemapFace_NegativeX,
nzCubemapFace_PositiveY,
nzCubemapFace_NegativeY,
nzCubemapFace_PositiveZ,
nzCubemapFace_NegativeZ
nzCubemapFace_PositiveX = 0,
nzCubemapFace_NegativeX = 1,
nzCubemapFace_PositiveY = 2,
nzCubemapFace_NegativeY = 3,
nzCubemapFace_PositiveZ = 4,
nzCubemapFace_NegativeZ = 5
};
enum nzImageType
@ -30,19 +33,23 @@ enum nzImageType
nzImageType_1D,
nzImageType_2D,
nzImageType_3D,
nzImageType_Cubemap
nzImageType_Cubemap,
nzImageType_Count
};
struct NzImageParams
{
nzPixelFormat loadFormat = nzPixelFormat_Undefined;
nzUInt8 levelCount = 0;
bool IsValid() const
{
return true;
return loadFormat == nzPixelFormat_Undefined || NzPixelFormat::IsValid(loadFormat);
}
};
///TODO: Filtres
///TODO: Mipmaps
class NAZARA_API NzImage : public NzResource, public NzResourceLoader<NzImage, NzImageParams>
{
@ -55,21 +62,33 @@ class NAZARA_API NzImage : public NzResource, public NzResourceLoader<NzImage, N
NzImage(SharedImage* sharedImage);
~NzImage();
bool Copy(const NzImage& source, const NzRectui& srcRect, const NzVector2ui& dstPos);
bool CopyToFace(nzCubemapFace face, const NzImage& source, const NzRectui& srcRect, const NzVector2ui& dstPos);
bool Convert(nzPixelFormat format);
bool Create(nzImageType type, nzPixelFormat format, unsigned int width, unsigned int height = 1, unsigned int depth = 1);
bool Copy(const NzImage& source, const NzCubeui& srcCube, const NzVector3ui& dstPos);
bool Create(nzImageType type, nzPixelFormat format, unsigned int width, unsigned int height, unsigned int depth = 1, nzUInt8 levelCount = 1);
void Destroy();
bool Fill(const NzColor& color);
bool Fill(const NzColor& color, const NzRectui& rect, unsigned int z = 0);
bool Fill(const NzColor& color, const NzCubeui& cube);
bool FlipHorizontally();
bool FlipVertically();
nzUInt8 GetBPP() const;
const nzUInt8* GetConstPixels() const;
unsigned int GetDepth() const;
const nzUInt8* GetConstPixels(nzUInt8 level = 0, unsigned int x = 0, unsigned int y = 0, unsigned int z = 0) const;
unsigned int GetDepth(nzUInt8 level = 0) const;
nzPixelFormat GetFormat() const;
unsigned int GetHeight() const;
nzUInt8* GetPixels();
unsigned int GetHeight(nzUInt8 level = 0) const;
nzUInt8 GetLevelCount() const;
nzUInt8 GetMaxLevel() const;
NzColor GetPixelColor(unsigned int x, unsigned int y = 0, unsigned int z = 0) const;
nzUInt8* GetPixels(nzUInt8 level = 0, unsigned int x = 0, unsigned int y = 0, unsigned int z = 0);
unsigned int GetSize() const;
unsigned int GetSize(nzUInt8 level) const;
nzImageType GetType() const;
unsigned int GetWidth() const;
unsigned int GetWidth(nzUInt8 level = 0) const;
bool IsCompressed() const;
bool IsCubemap() const;
@ -79,14 +98,17 @@ class NAZARA_API NzImage : public NzResource, public NzResourceLoader<NzImage, N
bool LoadFromMemory(const void* data, std::size_t size, const NzImageParams& params = NzImageParams());
bool LoadFromStream(NzInputStream& stream, const NzImageParams& params = NzImageParams());
bool Update(const nzUInt8* pixels);
bool Update(const nzUInt8* pixels, const NzRectui& rect);
bool UpdateFace(nzCubemapFace face, const nzUInt8* pixels);
bool UpdateFace(nzCubemapFace face, const nzUInt8* pixels, const NzRectui& rect);
bool SetLevelCount(nzUInt8 levelCount);
bool SetPixelColor(const NzColor& color, unsigned int x, unsigned int y = 0, unsigned int z = 0);
bool Update(const nzUInt8* pixels, nzUInt8 level = 0);
bool Update(const nzUInt8* pixels, const NzRectui& rect, unsigned int z = 0, nzUInt8 level = 0);
bool Update(const nzUInt8* pixels, const NzCubeui& cube, nzUInt8 level = 0);
NzImage& operator=(const NzImage& image);
NzImage& operator=(NzImage&& image);
static nzUInt8 GetMaxLevel(unsigned int width, unsigned int height, unsigned int depth = 1);
static void RegisterFileLoader(const NzString& extensions, LoadFileFunction loadFile);
static void RegisterMemoryLoader(IsMemoryLoadingSupportedFunction isLoadingSupported, LoadMemoryFunction loadMemory);
static void RegisterStreamLoader(IsStreamLoadingSupportedFunction isLoadingSupported, LoadStreamFunction loadStream);
@ -96,14 +118,10 @@ class NAZARA_API NzImage : public NzResource, public NzResourceLoader<NzImage, N
struct SharedImage
{
SharedImage() : // Vivement GCC 4.7 sur Windows
refCount(1)
{
}
SharedImage(unsigned short RefCount, nzImageType Type, nzPixelFormat Format, nzUInt8* Pixels, unsigned int Width, unsigned int Height = 1, unsigned int Depth = 1) :
SharedImage(unsigned short RefCount, nzImageType Type, nzPixelFormat Format, nzUInt8 LevelCount = 1, nzUInt8** Pixels = nullptr, unsigned int Width = 1, unsigned int Height = 1, unsigned int Depth = 1) :
type(Type),
format(Format),
levelCount(LevelCount),
pixels(Pixels),
depth(Depth),
height(Height),
@ -114,12 +132,13 @@ class NAZARA_API NzImage : public NzResource, public NzResourceLoader<NzImage, N
nzImageType type;
nzPixelFormat format;
nzUInt8* pixels;
nzUInt8 levelCount;
nzUInt8** pixels;
unsigned int depth;
unsigned int height;
unsigned int width;
unsigned short refCount;
unsigned short refCount = 1;
NazaraMutex(mutex)
};

View File

@ -8,31 +8,76 @@
#define NAZARA_PIXELFORMAT_HPP
#include <Nazara/Prerequesites.hpp>
#include <Nazara/Core/String.hpp>
enum nzPixelFormat
{
nzPixelFormat_Undefined,
nzPixelFormat_B8G8R8,
nzPixelFormat_B8G8R8A8,
nzPixelFormat_BGR8, // 3*nzUInt8
nzPixelFormat_BGRA8, // 4*nzUInt8
nzPixelFormat_DXT1,
nzPixelFormat_DXT3,
nzPixelFormat_DXT5,
nzPixelFormat_L8,
nzPixelFormat_L8A8,
nzPixelFormat_R4G4A4A4,
nzPixelFormat_R5G5A5A1,
nzPixelFormat_R8,
nzPixelFormat_R8G8,
nzPixelFormat_R8G8B8,
nzPixelFormat_R8G8B8A8
nzPixelFormat_L8, // 1*nzUInt8
nzPixelFormat_LA8, // 2*nzUInt8
/*
nzPixelFormat_RGB16F,
nzPixelFormat_RGB16I, // 4*nzUInt16
nzPixelFormat_RGB32F,
nzPixelFormat_RGB32I, // 4*nzUInt32
nzPixelFormat_RGBA16F,
nzPixelFormat_RGBA16I, // 4*nzUInt16
nzPixelFormat_RGBA32F,
nzPixelFormat_RGBA32I, // 4*nzUInt32
*/
nzPixelFormat_RGBA4, // 1*nzUInt16
nzPixelFormat_RGB5A1, // 1*nzUInt16
nzPixelFormat_RGB8, // 3*nzUInt8
nzPixelFormat_RGBA8, // 4*nzUInt8
/*
nzPixelFormat_Depth16,
nzPixelFormat_Depth24,
nzPixelFormat_Depth24Stencil8,
nzPixelFormat_Depth32,
nzPixelFormat_Stencil1,
nzPixelFormat_Stencil4,
nzPixelFormat_Stencil8,
nzPixelFormat_Stencil16,
*/
nzPixelFormat_Count
};
class NzUtility;
class NzPixelFormat
{
friend class NzUtility;
public:
typedef nzUInt8* (*ConvertFunction)(const nzUInt8* start, const nzUInt8* end, nzUInt8* dst);
static bool Convert(nzPixelFormat srcFormat, nzPixelFormat dstFormat, const void* src, void* dst);
static bool Convert(nzPixelFormat srcFormat, nzPixelFormat dstFormat, const void* start, const void* end, void* dst);
static nzUInt8 GetBPP(nzPixelFormat format);
static bool HasAlpha(nzPixelFormat format);
static bool IsCompressed(nzPixelFormat format);
static bool IsConversionSupported(nzPixelFormat srcFormat, nzPixelFormat dstFormat);
static bool IsValid(nzPixelFormat format);
static void SetConvertFunction(nzPixelFormat srcFormat, nzPixelFormat dstFormat, ConvertFunction);
static NzString ToString(nzPixelFormat format);
private:
static bool Initialize();
static void Uninitialize();
static NAZARA_API ConvertFunction s_convertFunctions[nzPixelFormat_Count][nzPixelFormat_Count];
};
#include <Nazara/Utility/PixelFormat.inl>

View File

@ -2,19 +2,80 @@
// This file is part of the "Nazara Engine".
// For conditions of distribution and use, see copyright notice in Config.hpp
#include <Nazara/Core/Debug.hpp>
#include <Nazara/Core/Error.hpp>
#include <cstring>
#include <Nazara/Utility/Debug.hpp>
inline bool NzPixelFormat::Convert(nzPixelFormat srcFormat, nzPixelFormat dstFormat, const void* src, void* dst)
{
if (srcFormat == dstFormat)
{
std::memcpy(dst, src, GetBPP(srcFormat));
return true;
}
#if NAZARA_UTILITY_SAFE
if (IsCompressed(srcFormat))
{
NazaraError("Cannot convert single pixel from compressed format");
return false;
}
if (IsCompressed(dstFormat))
{
NazaraError("Cannot convert single pixel to compressed format");
return false;
}
#endif
ConvertFunction func = s_convertFunctions[srcFormat][dstFormat];
if (!func)
{
NazaraError("Pixel format conversion from " + ToString(srcFormat) + " to " + ToString(dstFormat) + " is not supported");
return false;
}
if (!func(reinterpret_cast<const nzUInt8*>(src), reinterpret_cast<const nzUInt8*>(src) + GetBPP(srcFormat), reinterpret_cast<nzUInt8*>(dst)))
{
NazaraError("Pixel format conversion from " + ToString(srcFormat) + " to " + ToString(dstFormat) + " failed");
return false;
}
return true;
}
inline bool NzPixelFormat::Convert(nzPixelFormat srcFormat, nzPixelFormat dstFormat, const void* start, const void* end, void* dst)
{
if (srcFormat == dstFormat)
{
std::memcpy(dst, start, reinterpret_cast<const nzUInt8*>(end)-reinterpret_cast<const nzUInt8*>(start));
return true;
}
ConvertFunction func = s_convertFunctions[srcFormat][dstFormat];
if (!func)
{
NazaraError("Pixel format conversion from " + ToString(srcFormat) + " to " + ToString(dstFormat) + " is not supported");
return false;
}
if (!func(reinterpret_cast<const nzUInt8*>(start), reinterpret_cast<const nzUInt8*>(end), reinterpret_cast<nzUInt8*>(dst)))
{
NazaraError("Pixel format conversion from " + ToString(srcFormat) + " to " + ToString(dstFormat) + " failed");
return false;
}
return true;
}
inline nzUInt8 NzPixelFormat::GetBPP(nzPixelFormat format)
{
switch (format)
{
case nzPixelFormat_Undefined:
return 0;
case nzPixelFormat_B8G8R8:
case nzPixelFormat_BGR8:
return 3;
case nzPixelFormat_B8G8R8A8:
case nzPixelFormat_BGRA8:
return 4;
case nzPixelFormat_DXT1:
@ -29,31 +90,84 @@ inline nzUInt8 NzPixelFormat::GetBPP(nzPixelFormat format)
case nzPixelFormat_L8:
return 1;
case nzPixelFormat_L8A8:
case nzPixelFormat_LA8:
return 2;
/*
case nzPixelFormat_RGB16F:
return 6;
case nzPixelFormat_RGB16I:
return 6;
case nzPixelFormat_RGB32F:
return 12;
case nzPixelFormat_RGB32I:
return 12;
case nzPixelFormat_RGBA16F:
return 8;
case nzPixelFormat_RGBA16I:
return 8;
case nzPixelFormat_RGBA32F:
return 16;
case nzPixelFormat_RGBA32I:
return 16;
*/
case nzPixelFormat_RGBA4:
return 2;
case nzPixelFormat_R4G4A4A4:
case nzPixelFormat_RGB5A1:
return 2;
case nzPixelFormat_R5G5A5A1:
return 2;
case nzPixelFormat_R8:
return 1;
case nzPixelFormat_R8G8:
return 2;
case nzPixelFormat_R8G8B8:
case nzPixelFormat_RGB8:
return 3;
case nzPixelFormat_R8G8B8A8:
case nzPixelFormat_RGBA8:
return 4;
case nzPixelFormat_Count:
case nzPixelFormat_Undefined:
NazaraError("Invalid pixel format");
return 0;
}
NazaraInternalError("Invalid pixel format");
return 0;
}
inline bool NzPixelFormat::HasAlpha(nzPixelFormat format)
{
switch (format)
{
case nzPixelFormat_BGRA8:
case nzPixelFormat_DXT3:
case nzPixelFormat_DXT5:
case nzPixelFormat_LA8:
case nzPixelFormat_RGB5A1:
case nzPixelFormat_RGBA4:
case nzPixelFormat_RGBA8:
return true;
case nzPixelFormat_BGR8:
case nzPixelFormat_DXT1:
case nzPixelFormat_L8:
case nzPixelFormat_RGB8:
return false;
case nzPixelFormat_Count:
case nzPixelFormat_Undefined:
break;
}
NazaraError("Invalid pixel format");
return false;
}
inline bool NzPixelFormat::IsCompressed(nzPixelFormat format)
{
switch (format)
@ -68,4 +182,100 @@ inline bool NzPixelFormat::IsCompressed(nzPixelFormat format)
}
}
#include <Nazara/Core/DebugOff.hpp>
inline bool NzPixelFormat::IsConversionSupported(nzPixelFormat srcFormat, nzPixelFormat dstFormat)
{
if (srcFormat == dstFormat)
return true;
return s_convertFunctions[srcFormat][dstFormat] != nullptr;
}
inline bool NzPixelFormat::IsValid(nzPixelFormat format)
{
switch (format)
{
case nzPixelFormat_Count:
case nzPixelFormat_Undefined:
return false;
default:
return true;
}
}
inline void NzPixelFormat::SetConvertFunction(nzPixelFormat srcFormat, nzPixelFormat dstFormat, ConvertFunction func)
{
s_convertFunctions[srcFormat][dstFormat] = func;
}
inline NzString NzPixelFormat::ToString(nzPixelFormat format)
{
switch (format)
{
case nzPixelFormat_BGR8:
return "BGR8";
case nzPixelFormat_BGRA8:
return "BGRA8";
case nzPixelFormat_DXT1:
return "DXT1";
case nzPixelFormat_DXT3:
return "DXT3";
case nzPixelFormat_DXT5:
return "DXT5";
case nzPixelFormat_L8:
return "L8";
case nzPixelFormat_LA8:
return "LA8";
/*
case nzPixelFormat_RGB16F:
return "RGB16F";
case nzPixelFormat_RGB16I:
return "RGB16I";
case nzPixelFormat_RGB32F:
return "RGB32F";
case nzPixelFormat_RGB32I:
return "RGB32I";
case nzPixelFormat_RGBA16F:
return "RGBA16F";
case nzPixelFormat_RGBA16I:
return "RGBA16I";
case nzPixelFormat_RGBA32F:
return "RGBA32F";
case nzPixelFormat_RGBA32I:
return "RGBA32I";
*/
case nzPixelFormat_RGBA4:
return "RGBA4";
case nzPixelFormat_RGB5A1:
return "RGB5A1";
case nzPixelFormat_RGB8:
return "RGB8";
case nzPixelFormat_RGBA8:
return "RGBA8";
case nzPixelFormat_Count:
case nzPixelFormat_Undefined:
break;
}
NazaraError("Invalid pixel format");
return "Invalid format";
}
#include <Nazara/Utility/DebugOff.hpp>

View File

@ -35,14 +35,20 @@ bool NzResourceLoader<Type, Parameters>::LoadResourceFromFile(Type* resource, co
return false;
}
for (auto it = range.first; it != range.second; ++it)
// range.second est un itérateur vers l'élément après le dernier élémént du range
auto it = range.second;
do
{
it--;
// Chargement de la ressource
if (it->second(resource, filePath, parameters))
return true;
NazaraWarning("Loader failed");
}
while (it != range.first);
NazaraError("Failed to load file: all loaders failed");
@ -66,7 +72,7 @@ bool NzResourceLoader<Type, Parameters>::LoadResourceFromMemory(Type* resource,
}
#endif
for (auto loader = s_memoryLoaders.begin(); loader != s_memoryLoaders.end(); ++loader)
for (auto loader = s_memoryLoaders.rbegin(); loader != s_memoryLoaders.rend(); ++loader)
{
// Le loader supporte-t-il les données ?
if (!loader->first(data, size, parameters))
@ -101,7 +107,7 @@ bool NzResourceLoader<Type, Parameters>::LoadResourceFromStream(Type* resource,
#endif
nzUInt64 streamPos = stream.GetCursorPos();
for (auto loader = s_streamLoaders.begin(); loader != s_streamLoaders.end(); ++loader)
for (auto loader = s_streamLoaders.rbegin(); loader != s_streamLoaders.rend(); ++loader)
{
stream.SetCursorPos(streamPos);
@ -164,7 +170,6 @@ void NzResourceLoader<Type, Parameters>::UnregisterResourceFileLoader(const NzSt
}
}
}
//s_fileLoaders.erase(std::make_pair(ext, loadFile));
}
template<typename Type, typename Parameters>

View File

@ -10,11 +10,11 @@
#define NAZARA_WINDOW_HPP
#include <Nazara/Prerequesites.hpp>
#include <Nazara/Core/NonCopyable.hpp>
#include <Nazara/Core/String.hpp>
#include <Nazara/Math/Vector2.hpp>
#include <Nazara/Utility/Config.hpp>
#include <Nazara/Utility/Event.hpp>
#include <Nazara/Utility/NonCopyable.hpp>
#include <Nazara/Utility/VideoMode.hpp>
#include <Nazara/Utility/WindowHandle.hpp>
#include <queue>
@ -24,10 +24,12 @@
#include <Nazara/Core/ThreadCondition.hpp>
#endif
class NzUtility;
class NzWindowImpl;
class NAZARA_API NzWindow : NzNonCopyable
{
friend class NzUtility;
friend class NzWindowImpl;
public:
@ -59,7 +61,7 @@ class NAZARA_API NzWindow : NzNonCopyable
NzWindowHandle GetHandle() const;
unsigned int GetHeight() const;
NzVector2i GetPosition() const;
NzVector2i GetSize() const;
NzVector2ui GetSize() const;
NzString GetTitle() const;
unsigned int GetWidth() const;
@ -99,6 +101,9 @@ class NAZARA_API NzWindow : NzNonCopyable
private:
void PushEvent(const NzEvent& event);
static bool Initialize();
static void Uninitialize();
std::queue<NzEvent> m_events;
#if NAZARA_UTILITY_THREADED_WINDOW
NzMutex m_eventMutex;

View File

@ -41,3 +41,6 @@ Links
Website : http://www.digitalpulsesoftware.com
Wiki : http://wiki.digitalpulsesoftware.com/index.php?title=Nazara
Forum : http://forum.digitalpulsesoftware.com
Thanks to
-RafBill: Finding bugs

View File

@ -41,3 +41,6 @@ Liens
Site web : http://www.digitalpulsesoftware.com
Wiki : http://wiki.digitalpulsesoftware.com/index.php?title=Nazara
Forum : http://forum.digitalpulsesoftware.com
Merci à
-RafBill: Recherche de bugs

View File

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

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

@ -0,0 +1,16 @@
// Copyright (C) 2012 Jérôme Leclercq
// This file is part of the "Nazara Engine".
// For conditions of distribution and use, see copyright notice in Config.hpp
#include <Nazara/Core/Color.hpp>
#include <Nazara/Core/Debug.hpp>
const NzColor NzColor::Black(0, 0, 0);
const NzColor NzColor::Blue(0, 0, 255);
const NzColor NzColor::Cyan(0, 255, 255);
const NzColor NzColor::Green(0, 255, 0);
const NzColor NzColor::Magenta(255, 0, 255);
const NzColor NzColor::Orange(255, 165, 0);
const NzColor NzColor::Red(255, 0, 0);
const NzColor NzColor::Yellow(255, 255, 0);
const NzColor NzColor::White(255, 255, 255);

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -4,6 +4,7 @@
#include <Nazara/Renderer/OpenGL.hpp> // Pour éviter une redéfinition de WIN32_LEAN_AND_MEAN
#include <Nazara/Renderer/Renderer.hpp>
#include <Nazara/Core/Color.hpp>
#include <Nazara/Core/Error.hpp>
#include <Nazara/Renderer/BufferImpl.hpp>
#include <Nazara/Renderer/Config.hpp>
@ -13,13 +14,54 @@
#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[] = {
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,
@ -27,15 +69,68 @@ namespace
GL_TRIANGLE_STRIP, // nzPrimitiveType_TriangleStrip,
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,14 +191,11 @@ void NzRenderer::DrawIndexedPrimitives(nzPrimitiveType primitive, unsigned int f
}
#endif
if (!m_vertexBufferUpdated)
if (!EnsureStateUpdate())
{
if (!UpdateVertexBuffer())
{
NazaraError("Failed to update vertex buffer");
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");
NazaraError("No active context");
return;
}
#endif
if (!EnsureStateUpdate())
{
NazaraError("Failed to update states");
return;
}
glDrawArrays(openglPrimitive[primitive], firstVertex, vertexCount);
}
void NzRenderer::Enable(nzRendererParameter parameter, bool enable)
{
#ifdef NAZARA_DEBUG
if (NzContext::GetCurrent() == nullptr)
{
NazaraError("No active context");
return;
}
#endif
switch (parameter)
{
case nzRendererParameter_ColorWrite:
glColorMask(enable, enable, enable, enable);
break;
case nzRendererParameter_DepthWrite:
glDepthMask(enable);
break;
default:
if (enable)
glEnable(rendererParameter[parameter]);
else
glDisable(rendererParameter[parameter]);
break;
}
}
unsigned int NzRenderer::GetMaxAnisotropyLevel() const
{
return m_maxAnisotropyLevel;
}
unsigned int NzRenderer::GetMaxRenderTargets() const
{
return m_maxRenderTarget;
}
unsigned int NzRenderer::GetMaxTextureUnits() const
{
static int maxTextureUnits = -1;
if (maxTextureUnits == -1)
{
if (m_capabilities[nzRendererCap_TextureMulti])
glGetIntegerv(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, &maxTextureUnits);
else
maxTextureUnits = 1;
}
return maxTextureUnits;
return m_maxTextureUnit;
}
NzShader* NzRenderer::GetShader() const
@ -162,6 +296,22 @@ NzRenderTarget* NzRenderer::GetTarget() const
return m_target;
}
NzRectui NzRenderer::GetViewport() const
{
#ifdef NAZARA_DEBUG
if (NzContext::GetCurrent() == nullptr)
{
NazaraError("No active context");
return NzRectui();
}
#endif
GLint params[4];
glGetIntegerv(GL_VIEWPORT, &params[0]);
return NzRectui(params[0], params[1], params[2], params[3]);
}
bool NzRenderer::HasCapability(nzRendererCap capability) const
{
return m_capabilities[capability];
@ -186,17 +336,68 @@ bool NzRenderer::Initialize()
if (NzOpenGL::Initialize())
{
NzContext::EnsureContext();
const NzContext* context = NzContext::GetReference();
bool compatibility = context->GetParameters().compatibilityProfile;
m_vaoUpdated = false;
m_indexBuffer = nullptr;
m_shader = nullptr;
m_stencilCompare = nzRendererComparison_Always;
m_stencilFail = nzStencilOperation_Keep;
m_stencilFuncUpdated = true;
m_stencilMask = 0xFFFFFFFF;
m_stencilOpUpdated = true;
m_stencilPass = nzStencilOperation_Keep;
m_stencilReference = 0;
m_stencilZFail = nzStencilOperation_Keep;
m_target = nullptr;
m_vertexBuffer = nullptr;
m_vertexDeclaration = nullptr;
// Récupération des capacités
m_capabilities[nzRendererCap_AnisotropicFilter] = NzOpenGL::IsSupported(NzOpenGL::AnisotropicFilter);
m_capabilities[nzRendererCap_FP64] = NzOpenGL::IsSupported(NzOpenGL::FP64);
m_capabilities[nzRendererCap_HardwareBuffer] = true; // Natif depuis OpenGL 1.5
m_capabilities[nzRendererCap_MultipleRenderTargets] = true; // Natif depuis OpenGL 2.0
m_capabilities[nzRendererCap_OcclusionQuery] = // Natif depuis OpenGL 1.5
m_capabilities[nzRendererCap_SoftwareBuffer] = NzOpenGL::GetVersion() <= 300; // Déprécié en OpenGL 3
m_capabilities[nzRendererCap_OcclusionQuery] = true; // Natif depuis OpenGL 1.5
m_capabilities[nzRendererCap_SoftwareBuffer] = compatibility || NzOpenGL::GetVersion() <= 300; // Déprécié en OpenGL 3
m_capabilities[nzRendererCap_Texture3D] = NzOpenGL::IsSupported(NzOpenGL::Texture3D);
m_capabilities[nzRendererCap_TextureCubemap] = true; // Natif depuis OpenGL 1.3
m_capabilities[nzRendererCap_TextureMulti] = true; // Natif depuis OpenGL 1.3
m_capabilities[nzRendererCap_TextureNPOT] = true; // Natif depuis OpenGL 2.0
if (m_capabilities[nzRendererCap_AnisotropicFilter])
{
GLint maxAnisotropy;
glGetIntegerv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &maxAnisotropy);
m_maxAnisotropyLevel = static_cast<unsigned int>(maxAnisotropy);
}
else
m_maxAnisotropyLevel = 1;
if (m_capabilities[nzRendererCap_MultipleRenderTargets])
{
GLint maxDrawBuffers;
glGetIntegerv(GL_MAX_DRAW_BUFFERS, &maxDrawBuffers);
m_maxRenderTarget = static_cast<unsigned int>(maxDrawBuffers);
}
else
m_maxRenderTarget = 1;
if (m_capabilities[nzRendererCap_TextureMulti])
{
GLint maxTextureUnits;
glGetIntegerv(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, &maxTextureUnits);
m_maxTextureUnit = static_cast<unsigned int>(maxTextureUnits);
}
else
m_maxTextureUnit = 1;
s_initialized = true;
return true;
@ -205,6 +406,32 @@ bool NzRenderer::Initialize()
return false;
}
void NzRenderer::SetBlendFunc(nzBlendFunc src, nzBlendFunc dest)
{
#ifdef NAZARA_DEBUG
if (NzContext::GetCurrent() == nullptr)
{
NazaraError("No active context");
return;
}
#endif
glBlendFunc(blendFunc[src], blendFunc[dest]);
}
void NzRenderer::SetClearColor(const NzColor& color)
{
#ifdef NAZARA_DEBUG
if (NzContext::GetCurrent() == nullptr)
{
NazaraError("No active context");
return;
}
#endif
glClearColor(color.r/255.f, color.g/255.f, color.b/255.f, color.a/255.f);
}
void NzRenderer::SetClearColor(nzUInt8 r, nzUInt8 g, nzUInt8 b, nzUInt8 a)
{
#ifdef NAZARA_DEBUG
@ -244,14 +471,40 @@ void NzRenderer::SetClearStencil(unsigned int value)
glClearStencil(value);
}
void NzRenderer::SetFaceCulling(nzFaceCulling cullingMode)
{
#ifdef NAZARA_DEBUG
if (NzContext::GetCurrent() == nullptr)
{
NazaraError("No active context");
return;
}
#endif
glCullFace(faceCullingMode[cullingMode]);
}
void NzRenderer::SetFaceFilling(nzFaceFilling fillingMode)
{
#ifdef NAZARA_DEBUG
if (NzContext::GetCurrent() == nullptr)
{
NazaraError("No active context");
return;
}
#endif
glPolygonMode(GL_FRONT_AND_BACK, faceFillingMode[fillingMode]);
}
bool NzRenderer::SetIndexBuffer(const NzIndexBuffer* indexBuffer)
{
if (indexBuffer == m_indexBuffer)
return true;
// OpenGL ne nécessite pas de débinder un index buffer pour ne pas l'utiliser
if (indexBuffer)
indexBuffer->GetBuffer()->m_impl->Bind();
if (indexBuffer != m_indexBuffer)
{
m_indexBuffer = indexBuffer;
m_vaoUpdated = false;
}
return true;
}
@ -261,12 +514,17 @@ bool NzRenderer::SetShader(NzShader* shader)
if (shader == m_shader)
return true;
if (m_shader)
m_shader->m_impl->Unbind();
if (shader)
{
#if NAZARA_RENDERER_SAFE
if (!shader->IsCompiled())
{
NazaraError("Shader is not compiled");
m_shader = nullptr;
return false;
}
#endif
@ -274,39 +532,91 @@ bool NzRenderer::SetShader(NzShader* shader)
if (!shader->m_impl->Bind())
{
NazaraError("Failed to bind shader");
m_shader = nullptr;
return false;
}
}
else
m_shader = nullptr;
m_shader = shader;
m_vertexBufferUpdated = false;
}
else if (m_shader)
{
m_shader->m_impl->Unbind();
m_shader = nullptr;
}
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;
}
return true;
}
bool NzRenderer::SetVertexDeclaration(const NzVertexDeclaration* vertexDeclaration)
{
if (m_vertexDeclaration != vertexDeclaration)
{
m_vertexDeclaration = vertexDeclaration;
m_vertexBufferUpdated = false;
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,15 +737,31 @@ 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");
NazaraError("No active context");
return false;
}
#endif
if (!m_stencilFuncUpdated)
{
glStencilFunc(rendererComparison[m_stencilCompare], m_stencilReference, m_stencilMask);
m_stencilFuncUpdated = 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");
@ -405,10 +775,82 @@ bool NzRenderer::UpdateVertexBuffer()
}
#endif
if (!m_shader->m_impl->UpdateVertexBuffer(m_vertexBuffer, m_vertexDeclaration))
return false;
static const bool vaoSupported = NzOpenGL::IsSupported(NzOpenGL::VertexArrayObject);
bool update;
GLuint vao;
m_vertexBufferUpdated = true;
// Si les VAOs sont supportés, on entoure nos appels par ceux-ci
if (vaoSupported)
{
// On recherche si un VAO existe déjà avec notre configuration
// Note: Les VAOs ne sont pas partagés entre les contextes, ces derniers font donc partie de notre configuration
auto key = std::make_tuple(NzContext::GetCurrent(), m_indexBuffer, m_vertexBuffer, m_vertexDeclaration);
auto it = m_vaos.find(key);
if (it == m_vaos.end())
{
// On créé notre VAO
glGenVertexArrays(1, &vao);
glBindVertexArray(vao);
// On l'ajoute à notre liste
m_vaos.insert(std::make_pair(key, static_cast<unsigned int>(vao)));
// Et on indique qu'on veut le programmer
update = true;
}
else
{
// Notre VAO existe déjà, il est donc inutile de le reprogrammer
vao = it->second;
update = false;
}
}
else
update = true; // Fallback si les VAOs ne sont pas supportés
if (update)
{
m_vertexBuffer->GetBuffer()->GetImpl()->Bind();
const nzUInt8* buffer = reinterpret_cast<const nzUInt8*>(m_vertexBuffer->GetBufferPtr());
///FIXME: Améliorer les déclarations pour permettre de faire ça plus simplement
for (int i = 0; i < 12; ++i) // Solution temporaire, à virer
glDisableVertexAttribArray(i); // Chaque itération tue un chaton :(
unsigned int stride = m_vertexDeclaration->GetStride();
unsigned int elementCount = m_vertexDeclaration->GetElementCount();
for (unsigned int i = 0; i < elementCount; ++i)
{
const NzVertexDeclaration::Element* element = m_vertexDeclaration->GetElement(i);
glEnableVertexAttribArray(attribIndex[element->usage]+element->usageIndex);
glVertexAttribPointer(attribIndex[element->usage]+element->usageIndex,
openglSize[element->type],
openglType[element->type],
(element->type == nzElementType_Color) ? GL_TRUE : GL_FALSE,
stride,
&buffer[element->offset]);
}
if (m_indexBuffer)
m_indexBuffer->GetBuffer()->GetImpl()->Bind();
}
if (vaoSupported)
{
// Si nous venons de définir notre VAO, nous devons le débinder pour indiquer la fin de sa construction
if (update)
glBindVertexArray(0);
// Nous (re)bindons le VAO pour définir les attributs de vertice
glBindVertexArray(vao);
}
m_vaoUpdated = true;
}
return true;
}

View File

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

View File

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

View File

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

View File

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

Some files were not shown because too many files have changed in this diff Show More