First part of render texture commit

Added NzContext::EnsureContext and NzContext::GetThreadContext
Added NzCube
Added NzRect::GetCenter
Added methods to send vectors to shaders
Added NzRenderer::SetViewport
Fixed NzRect::ExtendTo calculations
Fixed NzImage::Update checks with level > 0
No longer use glTexStorage when creating a texture to prevent a bug
NzBuffer's Lock and Unlock operations renamed to Map and Unmap
NzVector2/3/4 can now cast implicitly to a pointer
Optimized compilation time of String.hpp
Optimized normalisaton of quaternions
Optimized passing uniforms to shaders
Quaternion now automaticaly Normalize h
Removed macro definition of NAZARA_RENDERER_OPENGL from Renderer
Removed implicit cast from NzVector2/3/4 to NzString
Renamed nzBufferLock to nzBufferAccess
Renamed NzRenderTarget::CanActivate to IsValid
This commit is contained in:
Lynix 2012-06-13 07:40:31 +02:00
parent b1632842ae
commit e2a38b3790
55 changed files with 1400 additions and 417 deletions

View File

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

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>

View File

@ -0,0 +1,58 @@
// 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/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]);
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,183 @@
// 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>
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

@ -47,13 +47,11 @@ template<typename T> class NzQuaternion
//NzMatrix3<T> ToRotationMatrix() const;
NzString ToString() const;
NzQuaternion operator+(const NzQuaternion& quat) const;
NzQuaternion operator*(const NzQuaternion& quat) const;
NzVector3<T> operator*(const NzVector3<T>& vec) const;
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);

View File

@ -76,17 +76,21 @@ double NzQuaternion<T>::Magnitude() const
template<typename T>
double 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)
{
double length = std::sqrt(squaredLength);
w /= length;
x /= length;
y /= length;
z /= length;
}
return length;
return length;
}
else
return std::sqrt(squaredLength);
}
template<typename T>
@ -102,6 +106,8 @@ void NzQuaternion<T>::Set(T W, T X, T Y, T Z)
x = X;
y = Y;
z = Z;
Normalize();
}
template<typename T>
@ -111,6 +117,8 @@ void NzQuaternion<T>::Set(T quat[4])
x = quat[1];
y = quat[2];
z = quat[3];
Normalize();
}
template<typename T>
@ -195,35 +203,32 @@ NzString NzQuaternion<T>::ToString() const
return ss << "Quaternion(" << w << " | " << x << ", " << y << ", " << z << ')';
}
template<typename T>
NzQuaternion<T> NzQuaternion<T>::operator+(const NzQuaternion& quat) const
{
return NzQuaternion(w + quat.w,
x + quat.x,
y + quat.y,
z + quat.z);
}
template<typename T>
NzQuaternion<T> NzQuaternion<T>::operator*(const NzQuaternion& quat) const
{
return NzQuaternion(w * quat.w - x * quat.x - y * quat.y - z * quat.z,
w * quat.x + x * quat.w + y * quat.z - z * quat.y,
w * quat.y + y * quat.w + z * quat.x - x * quat.z,
w * quat.z + z * quat.w + x * quat.y - y * quat.x);
NzQuaternion result(w * quat.w - x * quat.x - y * quat.y - z * quat.z,
w * quat.x + x * quat.w + y * quat.z - z * quat.y,
w * quat.y + y * quat.w + z * quat.x - x * quat.z,
w * quat.z + z * quat.w + x * quat.y - y * quat.x);
result.Normalize();
return result;
}
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;
result = operator*(qvec * GetConjugate());
return NzVector3<T>(result.x, result.y, result.z);
return vec + uv + uuv;
}
template<typename T>
@ -241,24 +246,12 @@ NzQuaternion<T> NzQuaternion<T>::operator/(const NzQuaternion& quat) const
return GetConjugate(quat) * (*this);
}
template<typename T>
NzQuaternion<T> NzQuaternion<T>::operator+=(const NzQuaternion& quat)
{
w += quat.w;
x += quat.x;
y += quat.y;
z += quat.z;
return *this;
}
template<typename T>
NzQuaternion<T> NzQuaternion<T>::operator*=(const NzQuaternion& quat)
{
NzQuaternion q(*this);
operator=(q * quat);
return *this;
return operator=(q * quat);
}
template<typename T>
@ -276,9 +269,8 @@ template<typename T>
NzQuaternion<T> NzQuaternion<T>::operator/=(const NzQuaternion& quat)
{
NzQuaternion q(*this);
operator=(q / quat);
return *this;
return operator=(q / 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

@ -33,7 +33,8 @@ template<typename T> class NzVector2
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

@ -136,9 +136,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>

View File

@ -34,7 +34,8 @@ template<typename T> class NzVector3
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

@ -153,9 +153,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>

View File

@ -28,7 +28,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

@ -120,9 +120,15 @@ NzString NzVector4<T>::ToString() const
}
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>

View File

@ -17,22 +17,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_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

View File

@ -11,12 +11,12 @@
#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

@ -30,11 +30,12 @@ class NAZARA_API NzContext
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

@ -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

@ -37,6 +37,7 @@ class NAZARA_API NzOpenGL
DebugOutput,
FP64,
FrameBufferObject,
SeparateShaderObjects,
Texture3D,
TextureCompression_s3tc,
TextureStorage,
@ -131,6 +132,17 @@ NAZARA_API extern PFNGLLINKPROGRAMPROC glLinkProgram;
NAZARA_API extern PFNGLMAPBUFFERPROC glMapBuffer;
NAZARA_API extern PFNGLMAPBUFFERRANGEPROC glMapBufferRange;
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;

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,13 +10,10 @@
#define NAZARA_RENDERWINDOW_HPP
#include <Nazara/Prerequesites.hpp>
#include <Nazara/Renderer/RenderTarget.hpp>
#include <Nazara/Renderer/Config.hpp>
#include <Nazara/Utility/Window.hpp>
#ifndef NAZARA_RENDERER_COMMON
#include <Nazara/Renderer/ContextParameters.hpp>
#endif
#include <Nazara/Renderer/RenderTarget.hpp>
#include <Nazara/Utility/Window.hpp>
class NzContext;
class NzImage;
@ -25,16 +22,12 @@ struct NzContextParameters;
class NAZARA_API NzRenderWindow : public NzRenderTarget, public NzWindow
{
friend class NzTexture;
public:
NzRenderWindow();
NzRenderWindow(NzVideoMode mode, const NzString& title, nzUInt32 style = NzWindow::Default, const NzContextParameters& parameters = NzContextParameters());
NzRenderWindow(NzWindowHandle handle, const NzContextParameters& parameters = NzContextParameters());
virtual ~NzRenderWindow();
bool CanActivate() const;
bool CopyToImage(NzImage* image); ///TODO: Const
bool CopyToTexture(NzTexture* texture); ///TODO: Const
@ -45,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,6 +8,7 @@
#define NAZARA_RENDERER_HPP
#include <Nazara/Prerequesites.hpp>
#include <Nazara/Math/Rect.hpp>
#include <map>
#include <tuple>
@ -87,7 +88,6 @@ enum nzRendererComparison
enum nzRendererParameter
{
nzRendererParameter_AlphaTest,
nzRendererParameter_Blend,
nzRendererParameter_ColorWrite,
nzRendererParameter_DepthTest,
@ -135,10 +135,12 @@ class NAZARA_API NzRenderer
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);
@ -156,6 +158,7 @@ class NAZARA_API NzRenderer
bool SetTarget(NzRenderTarget* target);
bool SetVertexBuffer(const NzVertexBuffer* vertexBuffer);
bool SetVertexDeclaration(const NzVertexDeclaration* vertexDeclaration);
void SetViewport(const NzRectui& viewport);
void Uninitialize();

View File

@ -11,6 +11,9 @@
#include <Nazara/Core/NonCopyable.hpp>
#include <Nazara/Core/String.hpp>
#include <Nazara/Math/Matrix4.hpp>
#include <Nazara/Math/Vector2.hpp>
#include <Nazara/Math/Vector3.hpp>
#include <Nazara/Math/Vector4.hpp>
#include <Nazara/Utility/Resource.hpp>
enum nzShaderLanguage
@ -66,6 +69,12 @@ 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

@ -39,7 +39,9 @@ class NAZARA_API NzTexture : public NzResource, NzNonCopyable
explicit NzTexture(const NzImage& image);
~NzTexture();
bool Bind();
#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();
@ -60,6 +62,7 @@ class NAZARA_API NzTexture : public NzResource, NzNonCopyable
bool IsCompressed() const;
bool IsCubemap() const;
bool IsTarget() const;
bool IsValid() const;
bool LoadFromFile(const NzString& filePath, const NzImageParams& params = NzImageParams());
@ -76,10 +79,10 @@ class NAZARA_API NzTexture : public NzResource, NzNonCopyable
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 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 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);
@ -92,6 +95,8 @@ class NAZARA_API NzTexture : public NzResource, NzNonCopyable
static bool IsTypeSupported(nzImageType type);
private:
void SetTarget(bool isTarget);
NzTextureImpl* m_impl;
};

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

@ -10,6 +10,7 @@
#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/Utility/ResourceLoader.hpp>
#include <Nazara/Utility/PixelFormat.hpp>
@ -104,7 +105,7 @@ class NAZARA_API NzImage : public NzResource, public NzResourceLoader<NzImage, N
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 Update(const nzUInt8* pixels, const NzCubeui& cube, 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);

View File

@ -35,6 +35,16 @@ enum nzPixelFormat
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
};

View File

@ -35,7 +35,7 @@ inline bool NzPixelFormat::Convert(nzPixelFormat srcFormat, nzPixelFormat dstFor
return false;
}
if (!func(static_cast<const nzUInt8*>(src), static_cast<const nzUInt8*>(src) + GetBPP(srcFormat), static_cast<nzUInt8*>(dst)))
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;
@ -48,7 +48,7 @@ inline bool NzPixelFormat::Convert(nzPixelFormat srcFormat, nzPixelFormat dstFor
{
if (srcFormat == dstFormat)
{
std::memcpy(dst, start, static_cast<const nzUInt8*>(end)-static_cast<const nzUInt8*>(start));
std::memcpy(dst, start, reinterpret_cast<const nzUInt8*>(end)-reinterpret_cast<const nzUInt8*>(start));
return true;
}
@ -59,7 +59,7 @@ inline bool NzPixelFormat::Convert(nzPixelFormat srcFormat, nzPixelFormat dstFor
return false;
}
if (!func(static_cast<const nzUInt8*>(start), static_cast<const nzUInt8*>(end), static_cast<nzUInt8*>(dst)))
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;
@ -72,10 +72,6 @@ inline nzUInt8 NzPixelFormat::GetBPP(nzPixelFormat format)
{
switch (format)
{
case nzPixelFormat_Count:
case nzPixelFormat_Undefined:
return 0;
case nzPixelFormat_BGR8:
return 3;
@ -132,6 +128,11 @@ inline nzUInt8 NzPixelFormat::GetBPP(nzPixelFormat format)
case nzPixelFormat_RGBA8:
return 4;
case nzPixelFormat_Count:
case nzPixelFormat_Undefined:
NazaraError("Invalid pixel format");
return 0;
}
NazaraInternalError("Invalid pixel format");
@ -152,9 +153,19 @@ inline bool NzPixelFormat::HasAlpha(nzPixelFormat format)
case nzPixelFormat_RGBA8:
return true;
default:
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)
@ -258,13 +269,13 @@ inline NzString NzPixelFormat::ToString(nzPixelFormat format)
case nzPixelFormat_RGBA8:
return "RGBA8";
default:
NazaraInternalError("Invalid pixel format");
case nzPixelFormat_Count:
case nzPixelFormat_Undefined:
return "Invalid format";
break;
}
NazaraError("Invalid pixel format");
return "Invalid format";
}
#include <Nazara/Utility/DebugOff.hpp>

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

@ -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

@ -67,7 +67,7 @@ void NzThreadImpl::Terminate()
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

@ -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;
}
@ -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

@ -8,6 +8,7 @@
#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>
@ -21,9 +22,10 @@
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)
{
@ -269,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;
}
@ -279,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;
@ -299,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

@ -6,6 +6,7 @@
#include <Nazara/Renderer/GLSLShader.hpp>
#include <Nazara/Core/Error.hpp>
#include <Nazara/Core/String.hpp>
#include <Nazara/Renderer/Context.hpp>
#include <Nazara/Renderer/Renderer.hpp>
#include <Nazara/Renderer/Texture.hpp>
#include <Nazara/Renderer/VertexDeclaration.hpp>
@ -52,6 +53,14 @@ bool NzGLSLShader::Bind()
}
#endif
#ifdef NAZARA_DEBUG
if (NzContext::GetCurrent() == nullptr)
{
NazaraError("No active context");
return false;
}
#endif
glUseProgram(m_program);
for (auto it = m_textures.begin(); it != m_textures.end(); ++it)
@ -66,6 +75,8 @@ bool NzGLSLShader::Bind()
bool NzGLSLShader::Compile()
{
NzContext::EnsureContext();
m_idCache.clear();
glLinkProgram(m_program);
@ -104,6 +115,8 @@ bool NzGLSLShader::Compile()
bool NzGLSLShader::Create()
{
NzContext::EnsureContext();
m_program = glCreateProgram();
if (!m_program)
{
@ -126,13 +139,13 @@ bool NzGLSLShader::Create()
for (int i = 0; i < nzShaderType_Count; ++i)
m_shaders[i] = 0;
m_textureFreeID = 0;
return true;
}
void NzGLSLShader::Destroy()
{
NzContext::EnsureContext();
for (GLuint shader : m_shaders)
if (shader)
glDeleteShader(shader);
@ -153,6 +166,8 @@ nzShaderLanguage NzGLSLShader::GetLanguage() const
NzString NzGLSLShader::GetSourceCode(nzShaderType type) const
{
NzContext::EnsureContext();
NzString source;
GLint length;
@ -172,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;
}
@ -188,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)
{
@ -244,6 +263,8 @@ bool NzGLSLShader::Lock()
{
if (lockedLevel++ == 0)
{
NzContext::EnsureContext();
GLint previous;
glGetIntegerv(GL_CURRENT_PROGRAM, &previous);
@ -258,54 +279,168 @@ bool NzGLSLShader::Lock()
bool NzGLSLShader::SendBoolean(const NzString& name, bool value)
{
Lock();
glUniform1i(GetUniformLocation(name), value);
Unlock();
if (glProgramUniform1i)
glProgramUniform1i(m_program, GetUniformLocation(name), value);
else
{
Lock();
glUniform1i(GetUniformLocation(name), value);
Unlock();
}
return true;
}
bool NzGLSLShader::SendDouble(const NzString& name, double value)
{
Lock();
glUniform1d(GetUniformLocation(name), value);
Unlock();
if (glProgramUniform1d)
glProgramUniform1d(m_program, GetUniformLocation(name), value);
else
{
Lock();
glUniform1d(GetUniformLocation(name), value);
Unlock();
}
return true;
}
bool NzGLSLShader::SendFloat(const NzString& name, float value)
{
Lock();
glUniform1f(GetUniformLocation(name), value);
Unlock();
if (glProgramUniform1f)
glProgramUniform1f(m_program, GetUniformLocation(name), value);
else
{
Lock();
glUniform1f(GetUniformLocation(name), value);
Unlock();
}
return true;
}
bool NzGLSLShader::SendInteger(const NzString& name, int value)
{
Lock();
glUniform1i(GetUniformLocation(name), value);
Unlock();
if (glProgramUniform1i)
glProgramUniform1i(m_program, GetUniformLocation(name), value);
else
{
Lock();
glUniform1i(GetUniformLocation(name), value);
Unlock();
}
return true;
}
bool NzGLSLShader::SendMatrix(const NzString& name, const NzMatrix4d& matrix)
{
Lock();
glUniformMatrix4dv(GetUniformLocation(name), 1, GL_FALSE, matrix);
Unlock();
if (glProgramUniformMatrix4dv)
glProgramUniformMatrix4dv(m_program, GetUniformLocation(name), 1, GL_FALSE, matrix);
else
{
Lock();
glUniformMatrix4dv(GetUniformLocation(name), 1, GL_FALSE, matrix);
Unlock();
}
return true;
}
bool NzGLSLShader::SendMatrix(const NzString& name, const NzMatrix4f& matrix)
{
Lock();
glUniformMatrix4fv(GetUniformLocation(name), 1, GL_FALSE, matrix);
Unlock();
if (glProgramUniformMatrix4fv)
glProgramUniformMatrix4fv(m_program, GetUniformLocation(name), 1, GL_FALSE, matrix);
else
{
Lock();
glUniformMatrix4fv(GetUniformLocation(name), 1, GL_FALSE, matrix);
Unlock();
}
return true;
}
bool NzGLSLShader::SendVector(const NzString& name, const NzVector2d& vector)
{
if (glProgramUniform2dv)
glProgramUniform2dv(m_program, GetUniformLocation(name), 1, vector);
else
{
Lock();
glUniform2dv(GetUniformLocation(name), 1, vector);
Unlock();
}
return true;
}
bool NzGLSLShader::SendVector(const NzString& name, const NzVector2f& vector)
{
if (glProgramUniform2fv)
glProgramUniform2fv(m_program, GetUniformLocation(name), 1, vector);
else
{
Lock();
glUniform2fv(GetUniformLocation(name), 1, vector);
Unlock();
}
return true;
}
bool NzGLSLShader::SendVector(const NzString& name, const NzVector3d& vector)
{
if (glProgramUniform3dv)
glProgramUniform3dv(m_program, GetUniformLocation(name), 1, vector);
else
{
Lock();
glUniform3dv(GetUniformLocation(name), 1, vector);
Unlock();
}
return true;
}
bool NzGLSLShader::SendVector(const NzString& name, const NzVector3f& vector)
{
if (glProgramUniform3fv)
glProgramUniform3fv(m_program, GetUniformLocation(name), 1, vector);
else
{
Lock();
glUniform3fv(GetUniformLocation(name), 1, vector);
Unlock();
}
return true;
}
bool NzGLSLShader::SendVector(const NzString& name, const NzVector4d& vector)
{
if (glProgramUniform4dv)
glProgramUniform4dv(m_program, GetUniformLocation(name), 1, vector);
else
{
Lock();
glUniform4dv(GetUniformLocation(name), 1, vector);
Unlock();
}
return true;
}
bool NzGLSLShader::SendVector(const NzString& name, const NzVector4f& vector)
{
if (glProgramUniform4fv)
glProgramUniform4fv(m_program, GetUniformLocation(name), 1, vector);
else
{
Lock();
glUniform4fv(GetUniformLocation(name), 1, vector);
Unlock();
}
return true;
}
@ -356,25 +491,48 @@ bool NzGLSLShader::SendTexture(const NzString& name, NzTexture* texture)
m_textures[location] = TextureSlot{unit, texture};
Lock();
glUniform1i(location, unit);
Unlock();
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()
{
#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 (--lockedLevel == 0 && lockedPrevious != m_program)
glUseProgram(lockedPrevious);

View File

@ -42,6 +42,12 @@ 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();
@ -58,7 +64,6 @@ class NzGLSLShader : public NzShaderImpl
std::map<GLint, TextureSlot> m_textures;
GLuint m_program;
GLuint m_shaders[nzShaderType_Count];
nzUInt8 m_textureFreeID;
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");
@ -38,6 +43,8 @@ NzOcclusionQuery::~NzOcclusionQuery()
{
if (m_id)
{
NzContext::EnsureContext();
GLuint query = static_cast<GLuint>(m_id);
glDeleteQueries(1, &query);
}
@ -45,16 +52,34 @@ NzOcclusionQuery::~NzOcclusionQuery()
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);
@ -63,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

@ -116,7 +116,6 @@ 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;
@ -124,8 +123,8 @@ bool NzOpenGL::Initialize()
/*
Note: Même le contexte de chargement nécessite quelques fonctions de base pour correctement s'initialiser
Pour cette raison, sa création est faite en deux fois, la première sert à récupérer le strict minimum,
la seconde à créer le véritable contexte de chargement.
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
*/
@ -371,50 +370,50 @@ bool NzOpenGL::Initialize()
}
// FrameBufferObject
try
if (openGLversion >= 300 || IsSupported("GL_ARB_framebuffer_object"))
{
glBindFramebuffer = reinterpret_cast<PFNGLBINDFRAMEBUFFERPROC>(LoadEntry("glBindFramebuffer"));
glBindRenderbuffer = reinterpret_cast<PFNGLBINDRENDERBUFFERPROC>(LoadEntry("glBindRenderbuffer"));
glCheckFramebufferStatus = reinterpret_cast<PFNGLCHECKFRAMEBUFFERSTATUSPROC>(LoadEntry("glCheckFramebufferStatus"));
glDeleteFramebuffers = reinterpret_cast<PFNGLDELETEFRAMEBUFFERSPROC>(LoadEntry("glDeleteFramebuffers"));
glDeleteRenderbuffers = reinterpret_cast<PFNGLDELETERENDERBUFFERSPROC>(LoadEntry("glDeleteRenderbuffers"));
glFramebufferRenderbuffer = reinterpret_cast<PFNGLFRAMEBUFFERRENDERBUFFERPROC>(LoadEntry("glFramebufferRenderbuffer"));
glFramebufferTexture2D = reinterpret_cast<PFNGLFRAMEBUFFERTEXTURE2DPROC>(LoadEntry("glFramebufferTexture2D"));
glGenerateMipmap = reinterpret_cast<PFNGLGENERATEMIPMAPPROC>(LoadEntry("glGenerateMipmap"));
glGenFramebuffers = reinterpret_cast<PFNGLGENFRAMEBUFFERSPROC>(LoadEntry("glGenFramebuffers"));
glGenRenderbuffers = reinterpret_cast<PFNGLGENRENDERBUFFERSPROC>(LoadEntry("glGenRenderbuffers"));
glRenderbufferStorage = reinterpret_cast<PFNGLRENDERBUFFERSTORAGEPROC>(LoadEntry("glRenderbufferStorage"));
openGLextensions[NzOpenGL::FrameBufferObject] = true;
}
catch (const std::exception& e)
{
if (openGLversion >= 300)
NazaraWarning("Failed to load core FBOs (" + NzString(e.what()) + ")");
if (IsSupported("GL_EXT_framebuffer_object"))
try
{
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"));
glBindFramebuffer = reinterpret_cast<PFNGLBINDFRAMEBUFFERPROC>(LoadEntry("glBindFramebuffer"));
glBindRenderbuffer = reinterpret_cast<PFNGLBINDRENDERBUFFERPROC>(LoadEntry("glBindRenderbuffer"));
glCheckFramebufferStatus = reinterpret_cast<PFNGLCHECKFRAMEBUFFERSTATUSPROC>(LoadEntry("glCheckFramebufferStatus"));
glDeleteFramebuffers = reinterpret_cast<PFNGLDELETEFRAMEBUFFERSPROC>(LoadEntry("glDeleteFramebuffers"));
glDeleteRenderbuffers = reinterpret_cast<PFNGLDELETERENDERBUFFERSPROC>(LoadEntry("glDeleteRenderbuffers"));
glFramebufferRenderbuffer = reinterpret_cast<PFNGLFRAMEBUFFERRENDERBUFFERPROC>(LoadEntry("glFramebufferRenderbuffer"));
glFramebufferTexture2D = reinterpret_cast<PFNGLFRAMEBUFFERTEXTURE2DPROC>(LoadEntry("glFramebufferTexture2D"));
glGenerateMipmap = reinterpret_cast<PFNGLGENERATEMIPMAPPROC>(LoadEntry("glGenerateMipmap"));
glGenFramebuffers = reinterpret_cast<PFNGLGENFRAMEBUFFERSPROC>(LoadEntry("glGenFramebuffers"));
glGenRenderbuffers = reinterpret_cast<PFNGLGENRENDERBUFFERSPROC>(LoadEntry("glGenRenderbuffers"));
glRenderbufferStorage = reinterpret_cast<PFNGLRENDERBUFFERSTORAGEPROC>(LoadEntry("glRenderbufferStorage"));
openGLextensions[NzOpenGL::FrameBufferObject] = true;
}
catch (const std::exception& e)
{
NazaraError("Failed to load EXT_framebuffer_object: " + NzString(e.what()));
}
openGLextensions[NzOpenGL::FrameBufferObject] = true;
}
catch (const std::exception& e)
{
NazaraError("Failed to load ARB_framebuffer_object: (" + NzString(e.what()) + ")");
}
}
// SeparateShaderObjects
if (openGLversion >= 400 || IsSupported("GL_ARB_gpu_shader_fp64"))
{
glProgramUniform1f = reinterpret_cast<PFNGLPROGRAMUNIFORM1FPROC>(LoadEntry("glProgramUniform1f"));
glProgramUniform1i = reinterpret_cast<PFNGLPROGRAMUNIFORM1IPROC>(LoadEntry("glProgramUniform1i"));
glProgramUniform2fv = reinterpret_cast<PFNGLPROGRAMUNIFORM2FVPROC>(LoadEntry("glProgramUniform2fv"));
glProgramUniform3fv = reinterpret_cast<PFNGLPROGRAMUNIFORM3FVPROC>(LoadEntry("glProgramUniform3fv"));
glProgramUniform4fv = reinterpret_cast<PFNGLPROGRAMUNIFORM4FVPROC>(LoadEntry("glProgramUniform4fv"));
glProgramUniformMatrix4fv = reinterpret_cast<PFNGLPROGRAMUNIFORMMATRIX4FVPROC>(LoadEntry("glProgramUniformMatrix4fv"));
if (openGLextensions[NzOpenGL::FP64])
{
glProgramUniform1d = reinterpret_cast<PFNGLPROGRAMUNIFORM1DPROC>(LoadEntry("glProgramUniform1d"));
glProgramUniform2dv = reinterpret_cast<PFNGLPROGRAMUNIFORM2DVPROC>(LoadEntry("glProgramUniform2dv"));
glProgramUniform3dv = reinterpret_cast<PFNGLPROGRAMUNIFORM3DVPROC>(LoadEntry("glProgramUniform3dv"));
glProgramUniform4dv = reinterpret_cast<PFNGLPROGRAMUNIFORM4DVPROC>(LoadEntry("glProgramUniform4dv"));
glProgramUniformMatrix4dv = reinterpret_cast<PFNGLPROGRAMUNIFORMMATRIX4DVPROC>(LoadEntry("glProgramUniformMatrix4dv"));
}
openGLextensions[NzOpenGL::SeparateShaderObjects] = true;
}
// Texture3D
@ -452,7 +451,7 @@ bool NzOpenGL::Initialize()
// TextureCompression_s3tc
openGLextensions[NzOpenGL::TextureCompression_s3tc] = IsSupported("GL_EXT_texture_compression_s3tc");
// VertexArrayObject
// TextureStorage
if (openGLversion >= 420 || IsSupported("GL_ARB_texture_storage"))
{
try
@ -489,16 +488,14 @@ bool NzOpenGL::Initialize()
/****************************************Contexte de référence****************************************/
///FIXME: Utiliser le contexte de chargement comme référence ? (Vérifier mode debug)
if (!NzContext::InitializeReference())
if (!NzContext::Initialize())
{
NazaraError("Failed to initialize reference context");
NazaraError("Failed to initialize contexts");
Uninitialize();
return false;
}
NzContextParameters::defaultShareContext = NzContext::GetReference();
return true;
}
@ -514,7 +511,7 @@ bool NzOpenGL::IsSupported(const NzString& string)
void NzOpenGL::Uninitialize()
{
NzContext::UninitializeReference();
NzContext::Uninitialize();
for (bool& ext : openGLextensions)
ext = false;
@ -604,6 +601,17 @@ PFNGLLINKPROGRAMPROC glLinkProgram = nullptr;
PFNGLMAPBUFFERPROC glMapBuffer = nullptr;
PFNGLMAPBUFFERRANGEPROC glMapBufferRange = 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;

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,9 +5,7 @@
#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>
@ -49,11 +47,6 @@ NzRenderWindow::~NzRenderWindow()
{
}
bool NzRenderWindow::CanActivate() const
{
return m_impl != nullptr && m_context != nullptr;
}
bool NzRenderWindow::CopyToImage(NzImage* image)
{
#if NAZARA_RENDERER_SAFE
@ -144,7 +137,7 @@ bool NzRenderWindow::Create(NzWindowHandle handle, const NzContextParameters& pa
void NzRenderWindow::Display()
{
if (m_context)
if (m_context && m_parameters.doubleBuffered)
m_context->SwapBuffers();
}
@ -181,7 +174,23 @@ void NzRenderWindow::EnableVerticalSync(bool enabled)
NazaraError("No context");
}
NzRenderTargetParameters NzRenderWindow::GetRenderTargetParameters() const
NzContextParameters NzRenderWindow::GetContextParameters() const
{
if (m_context)
return m_context->GetParameters();
else
{
NazaraError("Window not created/context not initialized");
return NzContextParameters();
}
}
unsigned int NzRenderWindow::GetHeight() const
{
return NzWindow::GetHeight();
}
NzRenderTargetParameters NzRenderWindow::GetParameters() const
{
if (m_context)
{
@ -195,15 +204,9 @@ NzRenderTargetParameters NzRenderWindow::GetRenderTargetParameters() const
}
}
NzContextParameters NzRenderWindow::GetContextParameters() const
unsigned int NzRenderWindow::GetWidth() const
{
if (m_context)
return m_context->GetParameters();
else
{
NazaraError("Window not created/context not initialized");
return NzContextParameters();
}
return NzWindow::GetWidth();
}
bool NzRenderWindow::HasContext() const
@ -211,9 +214,23 @@ 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()

View File

@ -23,17 +23,32 @@ namespace
{
const nzUInt8 attribIndex[] =
{
2, // nzElementUsage_Diffuse
1, // nzElementUsage_Normal
0, // nzElementUsage_Position
3, // nzElementUsage_Tangent
4 // nzElementUsage_TexCoord
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_BACK, // nzFaceCulling_Back
GL_FRONT, // nzFaceCulling_Front
GL_FRONT_AND_BACK // nzFaceCulling_FrontAndBack
};
@ -41,18 +56,18 @@ namespace
{
GL_POINT, // nzFaceFilling_Point
GL_LINE, // nzFaceFilling_Line
GL_FILL // nzFaceFilling_Fill
GL_FILL // nzFaceFilling_Fill
};
const GLenum openglPrimitive[] =
{
GL_LINES, // nzPrimitiveType_LineList,
GL_LINE_STRIP, // nzPrimitiveType_LineStrip,
GL_POINTS, // nzPrimitiveType_PointList,
GL_TRIANGLES, // nzPrimitiveType_TriangleList,
GL_LINES, // nzPrimitiveType_LineList,
GL_LINE_STRIP, // nzPrimitiveType_LineStrip,
GL_POINTS, // nzPrimitiveType_PointList,
GL_TRIANGLES, // nzPrimitiveType_TriangleList,
GL_TRIANGLE_STRIP, // nzPrimitiveType_TriangleStrip,
GL_TRIANGLE_FAN // nzPrimitiveType_TriangleFan
GL_TRIANGLE_FAN // nzPrimitiveType_TriangleFan
};
const nzUInt8 openglSize[] =
@ -71,47 +86,47 @@ namespace
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
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
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
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, // nzStencilOperation_Decrement
GL_DECR_WRAP, // nzStencilOperation_DecrementToSaturation
GL_INCR, // nzStencilOperation_Increment
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
GL_INVERT, // nzStencilOperation_Invert
GL_KEEP, // nzStencilOperation_Keep
GL_REPLACE, // nzStencilOperation_Replace
GL_ZERO // nzStencilOperation_Zero
};
}
@ -228,6 +243,14 @@ void NzRenderer::DrawPrimitives(nzPrimitiveType primitive, unsigned int firstVer
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:
@ -273,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];
@ -297,6 +336,11 @@ 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;
@ -318,7 +362,7 @@ bool NzRenderer::Initialize()
m_capabilities[nzRendererCap_HardwareBuffer] = true; // Natif depuis OpenGL 1.5
m_capabilities[nzRendererCap_MultipleRenderTargets] = true; // Natif depuis OpenGL 2.0
m_capabilities[nzRendererCap_OcclusionQuery] = true; // Natif depuis OpenGL 1.5
m_capabilities[nzRendererCap_SoftwareBuffer] = NzOpenGL::GetVersion() <= 300; // Déprécié en OpenGL 3
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
@ -336,14 +380,10 @@ bool NzRenderer::Initialize()
if (m_capabilities[nzRendererCap_MultipleRenderTargets])
{
// Permettre de gérer plus de targets que de nombre de sorties dans le shader ne servirait à rien
GLint maxDrawBuffers;
glGetIntegerv(GL_MAX_DRAW_BUFFERS, &maxDrawBuffers);
GLint maxRenderTextureTargets;
glGetIntegerv(GL_MAX_COLOR_ATTACHMENTS, &maxRenderTextureTargets);
m_maxRenderTarget = static_cast<unsigned int>(std::min(maxDrawBuffers, maxRenderTextureTargets));
m_maxRenderTarget = static_cast<unsigned int>(maxDrawBuffers);
}
else
m_maxRenderTarget = 1;
@ -366,6 +406,19 @@ 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
@ -462,10 +515,7 @@ bool NzRenderer::SetShader(NzShader* shader)
return true;
if (m_shader)
{
m_shader->m_impl->Unbind();
m_shader = nullptr;
}
if (shader)
{
@ -473,6 +523,8 @@ bool NzRenderer::SetShader(NzShader* shader)
if (!shader->IsCompiled())
{
NazaraError("Shader is not compiled");
m_shader = nullptr;
return false;
}
#endif
@ -480,9 +532,13 @@ 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;
@ -548,19 +604,19 @@ 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
@ -599,6 +655,43 @@ bool NzRenderer::SetVertexDeclaration(const NzVertexDeclaration* vertexDeclarati
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
@ -609,6 +702,8 @@ void NzRenderer::Uninitialize()
}
#endif
NzContext::EnsureContext();
s_initialized = false;
// Libération des VAOs
@ -644,6 +739,14 @@ bool NzRenderer::IsInitialized()
bool NzRenderer::EnsureStateUpdate()
{
#ifdef NAZARA_DEBUG
if (NzContext::GetCurrent() == nullptr)
{
NazaraError("No active context");
return false;
}
#endif
if (!m_stencilFuncUpdated)
{
glStencilFunc(rendererComparison[m_stencilCompare], m_stencilReference, m_stencilMask);

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,102 @@ 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

View File

@ -45,6 +45,12 @@ 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;

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

View File

@ -5,6 +5,7 @@
#include <Nazara/Renderer/OpenGL.hpp>
#include <Nazara/Renderer/Texture.hpp>
#include <Nazara/Core/Error.hpp>
#include <Nazara/Renderer/Context.hpp>
#include <Nazara/Renderer/Renderer.hpp>
#include <Nazara/Renderer/RenderWindow.hpp>
#include <stdexcept>
@ -14,8 +15,9 @@ struct NzTextureImpl
{
// GCC 4.7 !!!!!!
NzTextureImpl() :
isTarget(false),
mipmapping(false),
mipmapsUpdated(false)
mipmapsUpdated(true)
{
}
@ -23,6 +25,7 @@ struct NzTextureImpl
nzImageType type;
nzPixelFormat format;
nzUInt8 levelCount;
bool isTarget;
bool mipmapping;
bool mipmapsUpdated;
unsigned int depth;
@ -73,31 +76,31 @@ namespace
format->dataFormat = GL_BGR;
format->dataType = GL_UNSIGNED_BYTE;
format->internalFormat = GL_RGB8;
break;
return true;
case nzPixelFormat_BGRA8:
format->dataFormat = GL_BGRA;
format->dataType = GL_UNSIGNED_BYTE;
format->internalFormat = GL_RGBA8;
break;
return true;
case nzPixelFormat_DXT1:
format->dataFormat = GL_RGB;
format->dataType = GL_UNSIGNED_BYTE;
format->internalFormat = GL_COMPRESSED_RGB_S3TC_DXT1_EXT;
break;
return true;
case nzPixelFormat_DXT3:
format->dataFormat = GL_RGBA;
format->dataType = GL_UNSIGNED_BYTE;
format->internalFormat = GL_COMPRESSED_RGBA_S3TC_DXT3_EXT;
break;
return true;
case nzPixelFormat_DXT5:
format->dataFormat = GL_RGBA;
format->dataType = GL_UNSIGNED_BYTE;
format->internalFormat = GL_COMPRESSED_RGBA_S3TC_DXT5_EXT;
break;
return true;
case nzPixelFormat_L8:
case nzPixelFormat_LA8:
@ -108,32 +111,35 @@ namespace
format->dataFormat = GL_RGBA;
format->dataType = GL_UNSIGNED_SHORT_5_5_5_1;
format->internalFormat = GL_RGB5_A1;
break;
return true;
case nzPixelFormat_RGB8:
format->dataFormat = GL_RGB;
format->dataType = GL_UNSIGNED_BYTE;
format->internalFormat = GL_RGB8;
break;
return true;
case nzPixelFormat_RGBA4:
format->dataFormat = GL_RGBA;
format->dataType = GL_UNSIGNED_SHORT_4_4_4_4;
format->internalFormat = GL_RGBA4;
break;
return true;
case nzPixelFormat_RGBA8:
format->dataFormat = GL_RGBA;
format->dataType = GL_UNSIGNED_BYTE;
format->internalFormat = GL_RGBA8;
break;
return true;
default:
NazaraError("Pixel format not handled");
case nzPixelFormat_Undefined:
case nzPixelFormat_Count:
NazaraInternalError("Invalid pixel format");
return false;
}
return true;
NazaraError("Pixel format not handled");
return false;
}
bool CreateTexture(NzTextureImpl* impl, bool proxy)
@ -145,8 +151,6 @@ namespace
return false;
}
static const bool texStorageSupported = NzOpenGL::IsSupported(NzOpenGL::TextureStorage);
GLenum target;
switch (impl->type)
{
@ -154,15 +158,16 @@ namespace
{
target = (proxy) ? GL_TEXTURE_1D : GL_PROXY_TEXTURE_1D;
if (texStorageSupported)
/*if (glTexStorage1D)
glTexStorage1D(target, impl->levelCount, openGLFormat.internalFormat, impl->width);
else
else*/
{
unsigned int w = impl->width;
for (nzUInt8 level = 0; level < impl->levelCount; ++level)
{
glTexImage1D(target, level, openGLFormat.internalFormat, w, 0, openGLFormat.dataFormat, openGLFormat.dataType, nullptr);
w = std::max(w/2, 1U);
if (w > 1U)
w >>= 1;
}
}
break;
@ -172,17 +177,20 @@ namespace
{
target = (proxy) ? GL_TEXTURE_2D : GL_PROXY_TEXTURE_2D;
if (texStorageSupported)
/*if (glTexStorage2D)
glTexStorage2D(target, impl->levelCount, openGLFormat.internalFormat, impl->width, impl->height);
else
else*/
{
unsigned int w = impl->width;
unsigned int h = impl->height;
for (nzUInt8 level = 0; level < impl->levelCount; ++level)
{
glTexImage2D(target, level, openGLFormat.internalFormat, w, h, 0, openGLFormat.dataFormat, openGLFormat.dataType, nullptr);
w = std::max(w/2, 1U);
h = std::max(h/2, 1U);
if (w > 1U)
w >>= 1;
if (h > 1U)
h >>= 1;
}
}
break;
@ -192,9 +200,9 @@ namespace
{
target = (proxy) ? GL_TEXTURE_3D : GL_PROXY_TEXTURE_3D;
if (texStorageSupported)
/*if (glTexStorage3D)
glTexStorage3D(target, impl->levelCount, openGLFormat.internalFormat, impl->width, impl->height, impl->depth);
else
else*/
{
unsigned int w = impl->width;
unsigned int h = impl->height;
@ -202,9 +210,14 @@ namespace
for (nzUInt8 level = 0; level < impl->levelCount; ++level)
{
glTexImage3D(target, level, openGLFormat.internalFormat, w, h, d, 0, openGLFormat.dataFormat, openGLFormat.dataType, nullptr);
w = std::max(w/2, 1U);
h = std::max(h/2, 1U);
d = std::max(d/2, 1U);
if (w > 1U)
w >>= 1;
if (h > 1U)
h >>= 1;
if (d > 1U)
d >>= 1;
}
}
break;
@ -214,9 +227,9 @@ namespace
{
target = (proxy) ? GL_TEXTURE_CUBE_MAP : GL_PROXY_TEXTURE_CUBE_MAP;
if (texStorageSupported)
/*if (glTexStorage2D)
glTexStorage2D(target, impl->levelCount, openGLFormat.internalFormat, impl->width, impl->height);
else
else*/
{
unsigned int size = impl->width; // Les cubemaps ont une longueur et largeur identique
for (nzUInt8 level = 0; level < impl->levelCount; ++level)
@ -224,7 +237,8 @@ namespace
for (GLenum face : cubemapFace)
glTexImage2D(face, level, openGLFormat.internalFormat, size, size, 0, openGLFormat.dataFormat, openGLFormat.dataType, nullptr);
size = std::max(size/2, 1U);
if (size > 1U)
size >>= 1;
}
}
break;
@ -253,6 +267,8 @@ namespace
{
if (lockedLevel[impl->type]++ == 0)
{
NzContext::EnsureContext();
GLint previous;
glGetIntegerv(openglTargetBinding[impl->type], &previous);
@ -265,6 +281,14 @@ namespace
void UnlockTexture(NzTextureImpl* impl)
{
#ifdef NAZARA_DEBUG
if (NzContext::GetCurrent() == nullptr)
{
NazaraError("No active context");
return;
}
#endif
#if NAZARA_RENDERER_SAFE
if (lockedLevel[impl->type] == 0)
{
@ -302,7 +326,7 @@ NzTexture::~NzTexture()
Destroy();
}
bool NzTexture::Bind()
bool NzTexture::Bind() const
{
#if NAZARA_RENDERER_SAFE
if (lockedLevel[m_impl->type] > 0)
@ -314,11 +338,25 @@ bool NzTexture::Bind()
glBindTexture(openglTarget[m_impl->type], m_impl->id);
if (!m_impl->mipmapsUpdated)
{
glGenerateMipmap(openglTarget[m_impl->type]);
m_impl->mipmapsUpdated = true;
}
return true;
}
bool NzTexture::Create(nzImageType type, nzPixelFormat format, unsigned int width, unsigned int height, unsigned int depth, nzUInt8 levelCount, bool lock)
{
#if NAZARA_RENDERER_SAFE
if (m_impl && m_impl->isTarget)
{
NazaraError("Texture is a target, it cannot be recreated");
return false;
}
#endif
Destroy();
if (width == 0 || height == 0 || depth == 0)
@ -348,7 +386,7 @@ bool NzTexture::Create(nzImageType type, nzPixelFormat format, unsigned int widt
case nzImageType_1D:
if (height > 1)
{
NazaraError("1D textures must be 1 height");
NazaraError("One dimensional texture's height must be 1");
return false;
}
@ -390,6 +428,8 @@ bool NzTexture::Create(nzImageType type, nzPixelFormat format, unsigned int widt
}
#endif
NzContext::EnsureContext();
levelCount = std::min(levelCount, NzImage::GetMaxLevel(width, height, depth));
NzTextureImpl* impl = new NzTextureImpl;
@ -433,6 +473,12 @@ bool NzTexture::Create(nzImageType type, nzPixelFormat format, unsigned int widt
SetMipmapRange(0, m_impl->levelCount);
SetWrapMode(nzTextureWrap_Repeat);
if (m_impl->levelCount > 1U)
{
m_impl->mipmapping = true;
m_impl->mipmapsUpdated = false;
}
if (!lock)
UnlockTexture(impl);
@ -443,6 +489,16 @@ void NzTexture::Destroy()
{
if (m_impl)
{
#if NAZARA_RENDERER_SAFE
if (m_impl->isTarget)
{
NazaraError("Texture is a target, it cannot be destroyed");
return;
}
#endif
NzContext::EnsureContext();
glDeleteTextures(1, &m_impl->id);
delete m_impl;
m_impl = nullptr;
@ -505,9 +561,14 @@ bool NzTexture::Download(NzImage* image) const
ptr += faceSize;
}
width = std::max(width >> 1, 1U);
height = std::max(height >> 1, 1U);
depth = std::max(depth >> 1, 1U);
if (width > 1)
width >>= 1;
if (height > 1)
height >>= 1;
if (depth > 1)
depth >>= 1;
}
UnlockTexture(m_impl);
@ -533,15 +594,22 @@ bool NzTexture::EnableMipmapping(bool enable)
return false;
}
LockTexture(m_impl);
if (!m_impl->mipmapping && enable)
glGenerateMipmap(openglTarget[m_impl->type]);
{
GLint tex;
glGetIntegerv(openglTargetBinding[m_impl->type], &tex);
if (m_impl->id == static_cast<GLuint>(tex))
{
glGenerateMipmap(openglTarget[m_impl->type]);
m_impl->mipmapsUpdated = true;
}
else
m_impl->mipmapsUpdated = false;
}
m_impl->mipmapping = enable;
UnlockTexture(m_impl);
return true;
}
@ -744,6 +812,19 @@ bool NzTexture::IsCubemap() const
return m_impl->type == nzImageType_Cubemap;
}
bool NzTexture::IsTarget() const
{
#if NAZARA_RENDERER_SAFE
if (!IsValid())
{
NazaraError("Texture must be valid");
return false;
}
#endif
return m_impl->isTarget;
}
bool NzTexture::IsValid() const
{
return m_impl != nullptr;
@ -1059,7 +1140,7 @@ bool NzTexture::Update(const NzImage& image, const NzRectui& rect, unsigned int
return Update(image.GetConstPixels(level), rect, z, level);
}
/*
bool NzTexture::Update(const NzImage& image, const NzCubeui& cube, nzUInt8 level)
{
#if NAZARA_RENDERER_SAFE
@ -1078,7 +1159,7 @@ bool NzTexture::Update(const NzImage& image, const NzCubeui& cube, nzUInt8 level
return Update(image.GetConstPixels(level), cube, level);
}
*/
bool NzTexture::Update(const nzUInt8* pixels, nzUInt8 level)
{
#if NAZARA_RENDERER_SAFE
@ -1090,11 +1171,7 @@ bool NzTexture::Update(const nzUInt8* pixels, nzUInt8 level)
#endif
if (m_impl->type == nzImageType_3D)
{
NazaraInternalError("Not implemented yet, sorry");
return false;
//return Update(pixels, NzCube(0, 0, 0, std::max(m_impl->width >> level, 1U), std::max(m_impl->height >> level, 1U), std::max(m_impl->depth >> level, 1U)), level);
}
return Update(pixels, NzCubeui(0, 0, 0, std::max(m_impl->width >> level, 1U), std::max(m_impl->height >> level, 1U), std::max(m_impl->depth >> level, 1U)), level);
else
return Update(pixels, NzRectui(0, 0, std::max(m_impl->width >> level, 1U), std::max(m_impl->height >> level, 1U)), 0, level);
}
@ -1108,6 +1185,12 @@ bool NzTexture::Update(const nzUInt8* pixels, const NzRectui& rect, unsigned int
return false;
}
if (m_impl->isTarget)
{
NazaraError("Texture is a target, it cannot be updated");
return false;
}
if (m_impl->type == nzImageType_Cubemap)
{
NazaraError("Update is not designed for cubemaps, use UpdateFace instead");
@ -1190,8 +1273,8 @@ bool NzTexture::Update(const nzUInt8* pixels, const NzRectui& rect, unsigned int
return true;
}
/*
bool NzTexture::Update(const nzUInt8* pixels, const NzCubeui& cube, nzUInt8 level = 0)
bool NzTexture::Update(const nzUInt8* pixels, const NzCubeui& cube, nzUInt8 level)
{
#if NAZARA_RENDERER_SAFE
if (!IsValid())
@ -1200,6 +1283,12 @@ bool NzTexture::Update(const nzUInt8* pixels, const NzCubeui& cube, nzUInt8 leve
return false;
}
if (m_impl->isTarget)
{
NazaraError("Texture is a target, it cannot be updated");
return false;
}
if (m_impl->type == nzImageType_Cubemap)
{
NazaraError("Update is not designed for cubemaps, use UpdateFace instead");
@ -1263,15 +1352,15 @@ bool NzTexture::Update(const nzUInt8* pixels, const NzCubeui& cube, nzUInt8 leve
switch (m_impl->type)
{
case nzImageType_1D:
glTexSubImage1D(GL_TEXTURE_1D, level, cube.x, cube.width, format->dataFormat, format->dataType, mirrored);
glTexSubImage1D(GL_TEXTURE_1D, level, cube.x, cube.width, format.dataFormat, format.dataType, mirrored);
break;
case nzImageType_2D:
glTexSubImage1D(GL_TEXTURE_2D, level, cube.x, cube.y, cube.width, cube.height, format->dataFormat, format->dataType, mirrored);
glTexSubImage2D(GL_TEXTURE_2D, level, cube.x, cube.y, cube.width, cube.height, format.dataFormat, format.dataType, mirrored);
break;
case nzImageType_3D:
glTexSubImage1D(GL_TEXTURE_3D, level, cube.x, cube.y, cube.z, cube.width, cube.height, cube.depth, format->dataFormat, format->dataType, mirrored);
glTexSubImage3D(GL_TEXTURE_3D, level, cube.x, cube.y, cube.z, cube.width, cube.height, cube.depth, format.dataFormat, format.dataType, mirrored);
break;
default:
@ -1284,7 +1373,7 @@ bool NzTexture::Update(const nzUInt8* pixels, const NzCubeui& cube, nzUInt8 leve
return true;
}
*/
bool NzTexture::UpdateFace(nzCubemapFace face, const NzImage& image, nzUInt8 level)
{
#if NAZARA_RENDERER_SAFE
@ -1345,6 +1434,12 @@ bool NzTexture::UpdateFace(nzCubemapFace face, const nzUInt8* pixels, const NzRe
return false;
}
if (m_impl->isTarget)
{
NazaraError("Texture is a target, it cannot be updated");
return false;
}
if (m_impl->type != nzImageType_Cubemap)
{
NazaraError("UpdateFace is designed for cubemaps, use Update instead");
@ -1433,14 +1528,6 @@ unsigned int NzTexture::GetValidSize(unsigned int size)
bool NzTexture::IsFormatSupported(nzPixelFormat format)
{
#if NAZARA_RENDERER_SAFE
if (!NzPixelFormat::IsValid(format))
{
NazaraError("Invalid pixel format");
return nzPixelFormat_Undefined;
}
#endif
switch (format)
{
// Formats de base
@ -1468,9 +1555,14 @@ bool NzTexture::IsFormatSupported(nzPixelFormat format)
return supported;
}
default:
return false;
case nzPixelFormat_Undefined:
case nzPixelFormat_Count:
break;
}
NazaraError("Invalid pixel format");
return false;
}
bool NzTexture::IsTypeSupported(nzImageType type)
@ -1487,3 +1579,16 @@ bool NzTexture::IsTypeSupported(nzImageType type)
return false;
}
}
void NzTexture::SetTarget(bool isTarget)
{
#if NAZARA_RENDERER_SAFE
if (!IsValid())
{
NazaraInternalError("Texture must be valid");
return;
}
#endif
m_impl->isTarget = isTarget;
}

View File

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

View File

@ -701,21 +701,72 @@ bool NzImage::Update(const nzUInt8* pixels, const NzRectui& rect, unsigned int z
return false;
}
if (level >= m_sharedImage->levelCount)
{
NazaraError("Level out of bounds (" + NzString::Number(level) + " >= " + NzString::Number(m_sharedImage->levelCount) + ')');
return false;
}
#endif
unsigned int width = std::max(m_sharedImage->width >> level, 1U);
unsigned int height = std::max(m_sharedImage->height >> level, 1U);
#if NAZARA_UTILITY_SAFE
if (!rect.IsValid())
{
NazaraError("Invalid rectangle");
return false;
}
if (rect.x+rect.width > std::max(m_sharedImage->width >> level, 1U) || rect.y+rect.height > std::max(m_sharedImage->height >> level, 1U))
if (rect.x+rect.width > width || rect.y+rect.height > height)
{
NazaraError("Rectangle dimensions are out of bounds");
return false;
}
if (z >= std::max(m_sharedImage->depth >> level, 1U))
unsigned int depth = std::max(m_sharedImage->depth >> level, 1U);
if (z >= depth)
{
NazaraError("Z value exceeds depth (" + NzString::Number(z) + " >= (" + NzString::Number(m_sharedImage->depth) + ')');
NazaraError("Z value exceeds depth (" + NzString::Number(z) + " >= (" + NzString::Number(depth) + ')');
return false;
}
#endif
EnsureOwnership();
nzUInt8 bpp = NzPixelFormat::GetBPP(m_sharedImage->format);
nzUInt8* dstPixels = &m_sharedImage->pixels[level][(height*(width*z + rect.y) + rect.x) * bpp];
unsigned int srcStride = rect.width * bpp;
unsigned int blockSize = width * bpp;
for (unsigned int i = 0; i < rect.height; ++i)
{
std::memcpy(dstPixels, pixels, blockSize);
pixels += srcStride;
dstPixels += blockSize;
}
return true;
}
bool NzImage::Update(const nzUInt8* pixels, const NzCubeui& cube, nzUInt8 level)
{
///FIXME: Vérifier que ça fonctionne correctement
#if NAZARA_UTILITY_SAFE
if (!IsValid())
{
NazaraError("Image must be valid");
return false;
}
if (m_sharedImage->type == nzImageType_Cubemap)
{
NazaraError("Update is not designed for cubemaps, use UpdateFace instead");
return false;
}
if (!pixels)
{
NazaraError("Invalid pixel source");
return false;
}
@ -726,17 +777,42 @@ bool NzImage::Update(const nzUInt8* pixels, const NzRectui& rect, unsigned int z
}
#endif
unsigned int width = std::max(m_sharedImage->width >> level, 1U);
unsigned int height = std::max(m_sharedImage->height >> level, 1U);
unsigned int depth = std::max(m_sharedImage->height >> level, 1U);
#if NAZARA_UTILITY_SAFE
if (!cube.IsValid())
{
NazaraError("Invalid cube");
return false;
}
if (cube.x+cube.width > width || cube.y+cube.height > height || cube.z+cube.depth > depth)
{
NazaraError("Cube dimensions are out of bounds");
return false;
}
#endif
EnsureOwnership();
nzUInt8 bpp = NzPixelFormat::GetBPP(m_sharedImage->format);
nzUInt8* dstPixels = &m_sharedImage->pixels[level][(m_sharedImage->height*(m_sharedImage->width*z + rect.y) + rect.x) * bpp];
unsigned int srcStride = rect.width * bpp;
unsigned int blockSize = m_sharedImage->width * bpp;
for (unsigned int i = 0; i < rect.height; ++i)
nzUInt8* dstPixels = &m_sharedImage->pixels[level][(height*(width*cube.z + cube.y) + cube.x) * bpp];
unsigned int srcStride = cube.width * bpp;
unsigned int blockSize = width * bpp;
unsigned int faceSize = width * height * bpp;
for (unsigned int z = 0; z < cube.depth; ++z)
{
std::memcpy(dstPixels, pixels, blockSize);
pixels += srcStride;
dstPixels += blockSize;
nzUInt8* facePixels = dstPixels;
for (unsigned int i = 0; i < cube.height; ++i)
{
std::memcpy(dstPixels, pixels, blockSize);
pixels += srcStride;
facePixels += blockSize;
}
dstPixels += faceSize;
}
return true;

View File

@ -21,19 +21,19 @@ namespace
{
int Read(void* userdata, char* data, int size)
{
NzInputStream* stream = static_cast<NzInputStream*>(userdata);
NzInputStream* stream = reinterpret_cast<NzInputStream*>(userdata);
return static_cast<int>(stream->Read(data, size));
}
void Skip(void* userdata, unsigned int size)
{
NzInputStream* stream = static_cast<NzInputStream*>(userdata);
NzInputStream* stream = reinterpret_cast<NzInputStream*>(userdata);
stream->Read(nullptr, size);
}
int Eof(void* userdata)
{
NzInputStream* stream = static_cast<NzInputStream*>(userdata);
NzInputStream* stream = reinterpret_cast<NzInputStream*>(userdata);
return stream->GetCursorPos() >= stream->GetSize();
}
@ -63,7 +63,8 @@ namespace
{
NazaraUnused(parameters);
static nzPixelFormat formats[4] = {
static const nzPixelFormat formats[4] =
{
nzPixelFormat_L8,
nzPixelFormat_LA8,
nzPixelFormat_RGB8,
@ -134,7 +135,7 @@ namespace
NazaraUnused(parameters);
int width, height, bpp;
return stbi_info_from_memory(static_cast<const stbi_uc*>(data), size, &width, &height, &bpp);
return stbi_info_from_memory(reinterpret_cast<const stbi_uc*>(data), size, &width, &height, &bpp);
}
bool NzLoader_STB_IsStreamLoadingSupported(NzInputStream& stream, const NzImageParams& parameters)

View File

@ -1317,4 +1317,4 @@ void NzPixelFormat::Uninitialize()
std::memset(s_convertFunctions, 0, nzPixelFormat_Count*nzPixelFormat_Count*sizeof(NzPixelFormat::ConvertFunction));
}
NzPixelFormat::ConvertFunction NzPixelFormat::s_convertFunctions[nzPixelFormat_Count][nzPixelFormat_Count] = {{0}};
NzPixelFormat::ConvertFunction NzPixelFormat::s_convertFunctions[nzPixelFormat_Count][nzPixelFormat_Count] = {{0}}; ///FIXME: Fonctionne correctement ?

View File

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

View File

@ -166,7 +166,7 @@ bool NzWindowImpl::Create(NzWindowHandle handle)
return false;
}
m_handle = static_cast<HWND>(handle);
m_handle = reinterpret_cast<HWND>(handle);
m_eventListener = false;
m_ownsWindow = false;
@ -354,7 +354,7 @@ void NzWindowImpl::ShowMouseCursor(bool show)
// http://msdn.microsoft.com/en-us/library/windows/desktop/ms648045(v=vs.85).aspx
if (show)
m_cursor = static_cast<HCURSOR>(LoadImage(nullptr, MAKEINTRESOURCE(OCR_NORMAL), IMAGE_CURSOR, 0, 0, LR_SHARED));
m_cursor = reinterpret_cast<HCURSOR>(LoadImage(nullptr, MAKEINTRESOURCE(OCR_NORMAL), IMAGE_CURSOR, 0, 0, LR_SHARED));
else
m_cursor = nullptr;