Merge remote-tracking branch 'origin/master' into Resource-Update

Conflicts:
	include/Nazara/Audio/Music.hpp
	include/Nazara/Audio/SoundBuffer.hpp
	include/Nazara/Core/Resource.hpp
	include/Nazara/Core/ResourceListener.hpp
	include/Nazara/Graphics/Material.hpp
	include/Nazara/Renderer/Context.hpp
	include/Nazara/Renderer/RenderBuffer.hpp
	include/Nazara/Renderer/Shader.hpp
	include/Nazara/Renderer/Texture.hpp
	include/Nazara/Renderer/UberShader.hpp
	include/Nazara/Utility/Animation.hpp
	include/Nazara/Utility/Buffer.hpp
	include/Nazara/Utility/Image.hpp
	include/Nazara/Utility/IndexBuffer.hpp
	include/Nazara/Utility/Mesh.hpp
	include/Nazara/Utility/SkeletalMesh.hpp
	include/Nazara/Utility/Skeleton.hpp
	include/Nazara/Utility/StaticMesh.hpp
	include/Nazara/Utility/SubMesh.hpp
	include/Nazara/Utility/VertexBuffer.hpp
	include/Nazara/Utility/VertexDeclaration.hpp
	src/Nazara/Core/Resource.cpp
	src/Nazara/Core/ResourceListener.cpp
	src/Nazara/Graphics/DeferredRenderQueue.cpp
	src/Nazara/Graphics/ForwardRenderQueue.cpp
	src/Nazara/Graphics/SkinningManager.cpp
	src/Nazara/Renderer/RenderTexture.cpp
	src/Nazara/Renderer/Renderer.cpp
	src/Nazara/Utility/Mesh.cpp

Former-commit-id: 99b5ad26a19fe9c9f8118da7b5920bffe89f60f8
This commit is contained in:
Lynix
2015-01-25 19:29:55 +01:00
579 changed files with 11958 additions and 3706 deletions

View File

@@ -1,4 +1,4 @@
// Copyright (C) 2014 Jérôme Leclercq
// Copyright (C) 2015 Jérôme Leclercq
// This file is part of the "Nazara Engine - Renderer module"
// For conditions of distribution and use, see copyright notice in Config.hpp
@@ -38,7 +38,7 @@ namespace
switch (source)
{
case GL_DEBUG_SOURCE_API:
ss << "OpenGL";
ss << "OpenGL API";
break;
case GL_DEBUG_SOURCE_WINDOW_SYSTEM:

View File

@@ -1,4 +1,4 @@
// Copyright (C) 2014 Jérôme Leclercq
// Copyright (C) 2015 Jérôme Leclercq
// This file is part of the "Nazara Engine - Renderer module"
// For conditions of distribution and use, see copyright notice in Config.hpp

View File

@@ -1,4 +1,4 @@
// Copyright (C) 2014 Jérôme Leclercq
// Copyright (C) 2015 Jérôme Leclercq
// This file is part of the "Nazara Engine - Renderer module"
// For conditions of distribution and use, see copyright notice in Config.hpp
@@ -159,64 +159,64 @@ void NzDebugDrawer::Draw(const NzFrustumf& frustum)
NzBufferMapper<NzVertexBuffer> mapper(s_vertexBuffer, nzBufferAccess_DiscardAndWrite, 0, 24);
NzVertexStruct_XYZ* vertex = reinterpret_cast<NzVertexStruct_XYZ*>(mapper.GetPointer());
vertex->position.Set(frustum.GetCorner(nzCorner_NearLeftBottom));
vertex->position.Set(frustum.GetCorner(nzBoxCorner_NearLeftBottom));
vertex++;
vertex->position.Set(frustum.GetCorner(nzCorner_NearRightBottom));
vertex->position.Set(frustum.GetCorner(nzBoxCorner_NearRightBottom));
vertex++;
vertex->position.Set(frustum.GetCorner(nzCorner_NearLeftBottom));
vertex->position.Set(frustum.GetCorner(nzBoxCorner_NearLeftBottom));
vertex++;
vertex->position.Set(frustum.GetCorner(nzCorner_NearLeftTop));
vertex->position.Set(frustum.GetCorner(nzBoxCorner_NearLeftTop));
vertex++;
vertex->position.Set(frustum.GetCorner(nzCorner_NearLeftBottom));
vertex->position.Set(frustum.GetCorner(nzBoxCorner_NearLeftBottom));
vertex++;
vertex->position.Set(frustum.GetCorner(nzCorner_FarLeftBottom));
vertex->position.Set(frustum.GetCorner(nzBoxCorner_FarLeftBottom));
vertex++;
vertex->position.Set(frustum.GetCorner(nzCorner_FarRightTop));
vertex->position.Set(frustum.GetCorner(nzBoxCorner_FarRightTop));
vertex++;
vertex->position.Set(frustum.GetCorner(nzCorner_FarLeftTop));
vertex->position.Set(frustum.GetCorner(nzBoxCorner_FarLeftTop));
vertex++;
vertex->position.Set(frustum.GetCorner(nzCorner_FarRightTop));
vertex->position.Set(frustum.GetCorner(nzBoxCorner_FarRightTop));
vertex++;
vertex->position.Set(frustum.GetCorner(nzCorner_FarRightBottom));
vertex->position.Set(frustum.GetCorner(nzBoxCorner_FarRightBottom));
vertex++;
vertex->position.Set(frustum.GetCorner(nzCorner_FarRightTop));
vertex->position.Set(frustum.GetCorner(nzBoxCorner_FarRightTop));
vertex++;
vertex->position.Set(frustum.GetCorner(nzCorner_NearRightTop));
vertex->position.Set(frustum.GetCorner(nzBoxCorner_NearRightTop));
vertex++;
vertex->position.Set(frustum.GetCorner(nzCorner_FarLeftBottom));
vertex->position.Set(frustum.GetCorner(nzBoxCorner_FarLeftBottom));
vertex++;
vertex->position.Set(frustum.GetCorner(nzCorner_FarRightBottom));
vertex->position.Set(frustum.GetCorner(nzBoxCorner_FarRightBottom));
vertex++;
vertex->position.Set(frustum.GetCorner(nzCorner_FarLeftBottom));
vertex->position.Set(frustum.GetCorner(nzBoxCorner_FarLeftBottom));
vertex++;
vertex->position.Set(frustum.GetCorner(nzCorner_FarLeftTop));
vertex->position.Set(frustum.GetCorner(nzBoxCorner_FarLeftTop));
vertex++;
vertex->position.Set(frustum.GetCorner(nzCorner_NearLeftTop));
vertex->position.Set(frustum.GetCorner(nzBoxCorner_NearLeftTop));
vertex++;
vertex->position.Set(frustum.GetCorner(nzCorner_NearRightTop));
vertex->position.Set(frustum.GetCorner(nzBoxCorner_NearRightTop));
vertex++;
vertex->position.Set(frustum.GetCorner(nzCorner_NearLeftTop));
vertex->position.Set(frustum.GetCorner(nzBoxCorner_NearLeftTop));
vertex++;
vertex->position.Set(frustum.GetCorner(nzCorner_FarLeftTop));
vertex->position.Set(frustum.GetCorner(nzBoxCorner_FarLeftTop));
vertex++;
vertex->position.Set(frustum.GetCorner(nzCorner_NearRightBottom));
vertex->position.Set(frustum.GetCorner(nzBoxCorner_NearRightBottom));
vertex++;
vertex->position.Set(frustum.GetCorner(nzCorner_NearRightTop));
vertex->position.Set(frustum.GetCorner(nzBoxCorner_NearRightTop));
vertex++;
vertex->position.Set(frustum.GetCorner(nzCorner_NearRightBottom));
vertex->position.Set(frustum.GetCorner(nzBoxCorner_NearRightBottom));
vertex++;
vertex->position.Set(frustum.GetCorner(nzCorner_FarRightBottom));
vertex->position.Set(frustum.GetCorner(nzBoxCorner_FarRightBottom));
vertex++;
mapper.Unmap();
@@ -241,64 +241,64 @@ void NzDebugDrawer::Draw(const NzOrientedBoxf& orientedBox)
NzBufferMapper<NzVertexBuffer> mapper(s_vertexBuffer, nzBufferAccess_DiscardAndWrite, 0, 24);
NzVertexStruct_XYZ* vertex = reinterpret_cast<NzVertexStruct_XYZ*>(mapper.GetPointer());
vertex->position.Set(orientedBox.GetCorner(nzCorner_NearLeftBottom));
vertex->position.Set(orientedBox.GetCorner(nzBoxCorner_NearLeftBottom));
vertex++;
vertex->position.Set(orientedBox.GetCorner(nzCorner_NearRightBottom));
vertex->position.Set(orientedBox.GetCorner(nzBoxCorner_NearRightBottom));
vertex++;
vertex->position.Set(orientedBox.GetCorner(nzCorner_NearLeftBottom));
vertex->position.Set(orientedBox.GetCorner(nzBoxCorner_NearLeftBottom));
vertex++;
vertex->position.Set(orientedBox.GetCorner(nzCorner_NearLeftTop));
vertex->position.Set(orientedBox.GetCorner(nzBoxCorner_NearLeftTop));
vertex++;
vertex->position.Set(orientedBox.GetCorner(nzCorner_NearLeftBottom));
vertex->position.Set(orientedBox.GetCorner(nzBoxCorner_NearLeftBottom));
vertex++;
vertex->position.Set(orientedBox.GetCorner(nzCorner_FarLeftBottom));
vertex->position.Set(orientedBox.GetCorner(nzBoxCorner_FarLeftBottom));
vertex++;
vertex->position.Set(orientedBox.GetCorner(nzCorner_FarRightTop));
vertex->position.Set(orientedBox.GetCorner(nzBoxCorner_FarRightTop));
vertex++;
vertex->position.Set(orientedBox.GetCorner(nzCorner_FarLeftTop));
vertex->position.Set(orientedBox.GetCorner(nzBoxCorner_FarLeftTop));
vertex++;
vertex->position.Set(orientedBox.GetCorner(nzCorner_FarRightTop));
vertex->position.Set(orientedBox.GetCorner(nzBoxCorner_FarRightTop));
vertex++;
vertex->position.Set(orientedBox.GetCorner(nzCorner_FarRightBottom));
vertex->position.Set(orientedBox.GetCorner(nzBoxCorner_FarRightBottom));
vertex++;
vertex->position.Set(orientedBox.GetCorner(nzCorner_FarRightTop));
vertex->position.Set(orientedBox.GetCorner(nzBoxCorner_FarRightTop));
vertex++;
vertex->position.Set(orientedBox.GetCorner(nzCorner_NearRightTop));
vertex->position.Set(orientedBox.GetCorner(nzBoxCorner_NearRightTop));
vertex++;
vertex->position.Set(orientedBox.GetCorner(nzCorner_FarLeftBottom));
vertex->position.Set(orientedBox.GetCorner(nzBoxCorner_FarLeftBottom));
vertex++;
vertex->position.Set(orientedBox.GetCorner(nzCorner_FarRightBottom));
vertex->position.Set(orientedBox.GetCorner(nzBoxCorner_FarRightBottom));
vertex++;
vertex->position.Set(orientedBox.GetCorner(nzCorner_FarLeftBottom));
vertex->position.Set(orientedBox.GetCorner(nzBoxCorner_FarLeftBottom));
vertex++;
vertex->position.Set(orientedBox.GetCorner(nzCorner_FarLeftTop));
vertex->position.Set(orientedBox.GetCorner(nzBoxCorner_FarLeftTop));
vertex++;
vertex->position.Set(orientedBox.GetCorner(nzCorner_NearLeftTop));
vertex->position.Set(orientedBox.GetCorner(nzBoxCorner_NearLeftTop));
vertex++;
vertex->position.Set(orientedBox.GetCorner(nzCorner_NearRightTop));
vertex->position.Set(orientedBox.GetCorner(nzBoxCorner_NearRightTop));
vertex++;
vertex->position.Set(orientedBox.GetCorner(nzCorner_NearLeftTop));
vertex->position.Set(orientedBox.GetCorner(nzBoxCorner_NearLeftTop));
vertex++;
vertex->position.Set(orientedBox.GetCorner(nzCorner_FarLeftTop));
vertex->position.Set(orientedBox.GetCorner(nzBoxCorner_FarLeftTop));
vertex++;
vertex->position.Set(orientedBox.GetCorner(nzCorner_NearRightBottom));
vertex->position.Set(orientedBox.GetCorner(nzBoxCorner_NearRightBottom));
vertex++;
vertex->position.Set(orientedBox.GetCorner(nzCorner_NearRightTop));
vertex->position.Set(orientedBox.GetCorner(nzBoxCorner_NearRightTop));
vertex++;
vertex->position.Set(orientedBox.GetCorner(nzCorner_NearRightBottom));
vertex->position.Set(orientedBox.GetCorner(nzBoxCorner_NearRightBottom));
vertex++;
vertex->position.Set(orientedBox.GetCorner(nzCorner_FarRightBottom));
vertex->position.Set(orientedBox.GetCorner(nzBoxCorner_FarRightBottom));
vertex++;
mapper.Unmap();
@@ -363,6 +363,11 @@ void NzDebugDrawer::Draw(const NzSkeleton* skeleton)
}
}
void NzDebugDrawer::Draw(const NzVector3f& position, float size)
{
Draw(NzBoxf(position.x - size*0.5f, position.y - size*0.5f, position.z - size*0.5f, size, size, size));
}
void NzDebugDrawer::DrawBinormals(const NzStaticMesh* subMesh)
{
if (!Initialize())
@@ -661,8 +666,8 @@ bool NzDebugDrawer::Initialize()
// s_vertexBuffer
try
{
NzErrorFlags flags(nzErrorFlag_ThrowException);
s_vertexBuffer.Reset(NzVertexDeclaration::Get(nzVertexLayout_XYZ), 65365, nzBufferStorage_Hardware, nzBufferUsage_Dynamic);
NzErrorFlags flags(nzErrorFlag_ThrowException, true);
s_vertexBuffer.Reset(NzVertexDeclaration::Get(nzVertexLayout_XYZ), 65365, nzDataStorage_Hardware, nzBufferUsage_Dynamic);
}
catch (const std::exception& e)
{

View File

@@ -1,4 +1,4 @@
// Copyright (C) 2014 Jérôme Leclercq
// Copyright (C) 2015 Jérôme Leclercq
// This file is part of the "Nazara Engine - Renderer module"
// For conditions of distribution and use, see copyright notice in Config.hpp

View File

@@ -1,4 +1,4 @@
// Copyright (C) 2014 Jérôme Leclercq
// Copyright (C) 2015 Jérôme Leclercq
// This file is part of the "Nazara Engine - Renderer module"
// For conditions of distribution and use, see copyright notice in Config.hpp

View File

@@ -1,4 +1,4 @@
// Copyright (C) 2014 Jérôme Leclercq
// Copyright (C) 2015 Jérôme Leclercq
// This file is part of the "Nazara Engine - Renderer module"
// For conditions of distribution and use, see copyright notice in Config.hpp

View File

@@ -1,4 +1,4 @@
// Copyright (C) 2014 Jérôme Leclercq
// Copyright (C) 2015 Jérôme Leclercq
// This file is part of the "Nazara Engine - Renderer module"
// For conditions of distribution and use, see copyright notice in Config.hpp
@@ -6,7 +6,7 @@
#include <Nazara/Core/CallOnExit.hpp>
#include <Nazara/Core/Error.hpp>
#include <Nazara/Core/Log.hpp>
#include <Nazara/Math/Basic.hpp>
#include <Nazara/Math/Algorithm.hpp>
#include <Nazara/Renderer/Context.hpp>
#include <Nazara/Renderer/RenderTarget.hpp>
#include <cstring>
@@ -1072,7 +1072,7 @@ bool NzOpenGL::Initialize()
}
// DrawInstanced
if (s_openglVersion >= 330)
if (s_openglVersion >= 310)
{
try
{
@@ -1463,8 +1463,42 @@ void NzOpenGL::SetViewport(const NzRecti& viewport)
bool NzOpenGL::TranslateFormat(nzPixelFormat pixelFormat, Format* format, FormatType type)
{
// Par défaut
format->swizzle[0] = GL_RED;
format->swizzle[1] = GL_GREEN;
format->swizzle[2] = GL_BLUE;
format->swizzle[3] = GL_ALPHA;
switch (pixelFormat)
{
case nzPixelFormat_A8:
if (type == FormatType_Texture) // Format supporté uniquement par les textures
{
if (GetVersion() >= 300)
{
format->dataFormat = GL_RED;
format->dataType = GL_UNSIGNED_BYTE;
format->internalFormat = GL_R8;
// Simulation du format
format->swizzle[0] = GL_ONE;
format->swizzle[1] = GL_ONE;
format->swizzle[2] = GL_ONE;
format->swizzle[3] = GL_RED;
}
else
{
// Le bon vieux format GL_ALPHA
format->dataFormat = GL_ALPHA;
format->dataType = GL_UNSIGNED_BYTE;
format->internalFormat = GL_ALPHA;
}
return true;
}
else
return false;
case nzPixelFormat_BGR8:
format->dataFormat = GL_BGR;
format->dataType = GL_UNSIGNED_BYTE;
@@ -1496,8 +1530,58 @@ bool NzOpenGL::TranslateFormat(nzPixelFormat pixelFormat, Format* format, Format
return true;
case nzPixelFormat_L8:
if (type == FormatType_Texture) // Format supporté uniquement par les textures
{
if (GetVersion() >= 300)
{
format->dataFormat = GL_RED;
format->dataType = GL_UNSIGNED_BYTE;
format->internalFormat = GL_R8;
// Simulation du format
format->swizzle[0] = GL_RED;
format->swizzle[1] = GL_RED;
format->swizzle[2] = GL_RED;
format->swizzle[3] = GL_ONE;
}
else
{
format->dataFormat = 0x1909; // GL_LUMINANCE
format->dataType = GL_UNSIGNED_BYTE;
format->internalFormat = 0x1909; // GL_LUMINANCE
}
return true;
}
else
return false;
case nzPixelFormat_LA8:
return false;
if (type == FormatType_Texture) // Format supporté uniquement par les textures
{
if (GetVersion() >= 300)
{
format->dataFormat = GL_RG;
format->dataType = GL_UNSIGNED_BYTE;
format->internalFormat = GL_RG8;
// Simulation du format
format->swizzle[0] = GL_RED;
format->swizzle[1] = GL_RED;
format->swizzle[2] = GL_RED;
format->swizzle[3] = GL_GREEN;
}
else
{
format->dataFormat = 0x190A; // GL_LUMINANCE_ALPHA
format->dataType = GL_UNSIGNED_BYTE;
format->internalFormat = 0x190A; // GL_LUMINANCE_ALPHA;
}
return true;
}
else
return false;
case nzPixelFormat_R8:
format->dataFormat = GL_RED;
@@ -1941,8 +2025,8 @@ GLenum NzOpenGL::CubemapFace[] =
{
GL_TEXTURE_CUBE_MAP_POSITIVE_X, // nzCubemapFace_PositiveX
GL_TEXTURE_CUBE_MAP_NEGATIVE_X, // nzCubemapFace_NegativeX
GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, // nzCubemapFace_PositiveY (Inversion pour les standards OpenGL)
GL_TEXTURE_CUBE_MAP_POSITIVE_Y, // nzCubemapFace_NegativeY (Inversion pour les standards OpenGL)
GL_TEXTURE_CUBE_MAP_POSITIVE_Y, // nzCubemapFace_PositiveY
GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, // nzCubemapFace_NegativeY
GL_TEXTURE_CUBE_MAP_POSITIVE_Z, // nzCubemapFace_PositiveZ
GL_TEXTURE_CUBE_MAP_NEGATIVE_Z // nzCubemapFace_NegativeZ
};
@@ -1951,9 +2035,9 @@ static_assert(nzCubemapFace_Max+1 == 6, "Cubemap face array is incomplete");
GLenum NzOpenGL::FaceFilling[] =
{
GL_POINT, // nzFaceFilling_Point
GL_FILL, // nzFaceFilling_Fill
GL_LINE, // nzFaceFilling_Line
GL_FILL // nzFaceFilling_Fill
GL_POINT // nzFaceFilling_Point
};
static_assert(nzFaceFilling_Max+1 == 3, "Face filling array is incomplete");
@@ -2104,16 +2188,16 @@ nzUInt8 NzOpenGL::VertexComponentIndex[] =
13, // nzVertexComponent_InstanceData3
14, // nzVertexComponent_InstanceData4
15, // nzVertexComponent_InstanceData5
4, // nzVertexComponent_Color
2, // nzVertexComponent_Normal
0, // nzVertexComponent_Position
3, // nzVertexComponent_Tangent
1, // nzVertexComponent_TexCoord
4, // nzVertexComponent_Userdata0
5, // nzVertexComponent_Userdata1
6, // nzVertexComponent_Userdata2
7, // nzVertexComponent_Userdata3
8, // nzVertexComponent_Userdata4
9 // nzVertexComponent_Userdata5
5, // nzVertexComponent_Userdata0
6, // nzVertexComponent_Userdata1
7, // nzVertexComponent_Userdata2
8, // nzVertexComponent_Userdata3
9 // nzVertexComponent_Userdata4
};
static_assert(nzVertexComponent_Max+1 == 16, "Attribute index array is incomplete");

View File

@@ -1,4 +1,4 @@
// Copyright (C) 2014 Jérôme Leclercq
// Copyright (C) 2015 Jérôme Leclercq
// This file is part of the "Nazara Engine - Renderer module"
// For conditions of distribution and use, see copyright notice in Config.hpp

View File

@@ -1,4 +1,4 @@
// Copyright (C) 2014 Jérôme Leclercq
// Copyright (C) 2015 Jérôme Leclercq
// This file is part of the "Nazara Engine - Renderer module"
// For conditions of distribution and use, see copyright notice in Config.hpp

View File

@@ -1,4 +1,4 @@
// Copyright (C) 2014 Jérôme Leclercq
// Copyright (C) 2015 Jérôme Leclercq
// This file is part of the "Nazara Engine - Renderer module"
// For conditions of distribution and use, see copyright notice in Config.hpp
@@ -9,6 +9,7 @@
#include <Nazara/Renderer/OpenGL.hpp>
#include <Nazara/Renderer/Renderer.hpp>
#include <Nazara/Renderer/RenderBuffer.hpp>
#include <Nazara/Utility/PixelFormat.hpp>
#include <limits>
#include <memory>
#include <vector>
@@ -18,8 +19,17 @@ namespace
{
struct Attachment
{
Attachment(NzObjectListener* listener, int bufferIndex = 0, int textureIndex = 0) :
bufferListener(listener, bufferIndex),
textureListener(listener, textureIndex)
{
}
NzRenderBufferRef buffer;
NzTextureRef texture;
// Les listeners doivent se trouver après les références (pour être libérés avant elles)
NzRenderBufferListener bufferListener;
NzTextureListener textureListener;
nzAttachmentPoint attachmentPoint;
bool isBuffer;
@@ -50,11 +60,16 @@ namespace
struct NzRenderTextureImpl
{
NzRenderTextureImpl(NzObjectListener* listener, int contextIndex = 0) :
context(listener, contextIndex)
{
}
GLuint fbo;
std::vector<Attachment> attachments;
std::vector<nzUInt8> colorTargets;
mutable std::vector<GLenum> drawBuffers;
const NzContext* context;
NzContextConstListener context;
bool checked = false;
bool complete = false;
bool userDefinedTargets = false;
@@ -138,20 +153,23 @@ bool NzRenderTexture::AttachBuffer(nzAttachmentPoint attachmentPoint, nzUInt8 in
Unlock();
unsigned int attachIndex = attachmentIndex[attachmentPoint]+index;
if (m_impl->attachments.size() <= attachIndex)
m_impl->attachments.resize(attachIndex+1);
unsigned int attachIndex = attachmentIndex[attachmentPoint] + index;
// On créé les attachements si ça n'a pas déjà été fait
for (unsigned int i = m_impl->attachments.size(); i <= attachIndex; ++i)
{
Attachment attachment(this, attachIndex, attachIndex);
m_impl->attachments.emplace_back(std::move(attachment));
}
Attachment& attachment = m_impl->attachments[attachIndex];
attachment.attachmentPoint = attachmentPoint;
attachment.buffer = buffer;
attachment.bufferListener = buffer;
attachment.isBuffer = true;
attachment.isUsed = true;
attachment.height = buffer->GetHeight();
attachment.width = buffer->GetWidth();
buffer->AddObjectListener(this, attachIndex);
m_impl->checked = false;
if (attachmentPoint == nzAttachmentPoint_Color && !m_impl->userDefinedTargets)
@@ -282,9 +300,14 @@ bool NzRenderTexture::AttachTexture(nzAttachmentPoint attachmentPoint, nzUInt8 i
Unlock();
unsigned int attachIndex = attachmentIndex[attachmentPoint]+index;
if (m_impl->attachments.size() <= attachIndex)
m_impl->attachments.resize(attachIndex+1);
unsigned int attachIndex = attachmentIndex[attachmentPoint] + index;
// On créé les attachements si ça n'a pas déjà été fait
for (unsigned int i = m_impl->attachments.size(); i <= attachIndex; ++i)
{
Attachment attachment(this, attachIndex, attachIndex);
m_impl->attachments.emplace_back(std::move(attachment));
}
Attachment& attachment = m_impl->attachments[attachIndex];
attachment.attachmentPoint = attachmentPoint;
@@ -292,10 +315,9 @@ bool NzRenderTexture::AttachTexture(nzAttachmentPoint attachmentPoint, nzUInt8 i
attachment.isUsed = true;
attachment.height = texture->GetHeight();
attachment.texture = texture;
attachment.textureListener = texture;
attachment.width = texture->GetWidth();
texture->AddObjectListener(this, attachIndex);
m_impl->checked = false;
if (attachmentPoint == nzAttachmentPoint_Color && !m_impl->userDefinedTargets)
@@ -326,7 +348,7 @@ bool NzRenderTexture::Create(bool lock)
}
#endif
std::unique_ptr<NzRenderTextureImpl> impl(new NzRenderTextureImpl);
std::unique_ptr<NzRenderTextureImpl> impl(new NzRenderTextureImpl(this));
impl->fbo = 0;
glGenFramebuffers(1, &impl->fbo);
@@ -339,7 +361,6 @@ bool NzRenderTexture::Create(bool lock)
m_impl = impl.release();
m_impl->context = NzContext::GetCurrent();
m_impl->context->AddObjectListener(this);
if (lock)
{
@@ -371,19 +392,6 @@ void NzRenderTexture::Destroy()
if (IsActive())
NzRenderer::SetTarget(nullptr);
m_impl->context->RemoveObjectListener(this);
for (const Attachment& attachment : m_impl->attachments)
{
if (attachment.isUsed)
{
if (attachment.isBuffer)
attachment.buffer->RemoveObjectListener(this);
else
attachment.texture->RemoveObjectListener(this);
}
}
// Le FBO devant être supprimé dans son contexte d'origine, nous déléguons sa suppression à la classe OpenGL
// Celle-ci va libérer le FBO dès que possible (la prochaine fois que son contexte d'origine sera actif)
NzOpenGL::DeleteFrameBuffer(m_impl->context, m_impl->fbo);
@@ -409,7 +417,7 @@ void NzRenderTexture::Detach(nzAttachmentPoint attachmentPoint, nzUInt8 index)
}
#endif
unsigned int attachIndex = attachmentIndex[attachmentPoint]+index;
unsigned int attachIndex = attachmentIndex[attachmentPoint] + index;
if (attachIndex >= m_impl->attachments.size())
return;
@@ -429,7 +437,7 @@ void NzRenderTexture::Detach(nzAttachmentPoint attachmentPoint, nzUInt8 index)
{
glFramebufferRenderbuffer(GL_DRAW_FRAMEBUFFER, NzOpenGL::Attachment[attachmentPoint]+index, GL_RENDERBUFFER, 0);
attachement.buffer->RemoveObjectListener(this);
attachement.bufferListener = nullptr;
attachement.buffer = nullptr;
}
else
@@ -439,7 +447,7 @@ void NzRenderTexture::Detach(nzAttachmentPoint attachmentPoint, nzUInt8 index)
else
glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, NzOpenGL::Attachment[attachmentPoint]+index, 0, 0, 0);
attachement.texture->RemoveObjectListener(this);
attachement.textureListener = nullptr;
attachement.texture = nullptr;
}

View File

@@ -1,9 +1,10 @@
// Copyright (C) 2014 Jérôme Leclercq
// Copyright (C) 2015 Jérôme Leclercq
// This file is part of the "Nazara Engine - Renderer module"
// For conditions of distribution and use, see copyright notice in Config.hpp
#include <Nazara/Renderer/RenderWindow.hpp>
#include <Nazara/Core/Error.hpp>
#include <Nazara/Core/ErrorFlags.hpp>
#include <Nazara/Core/Thread.hpp>
#include <Nazara/Renderer/Context.hpp>
#include <Nazara/Renderer/OpenGL.hpp>
@@ -12,30 +13,18 @@
#include <stdexcept>
#include <Nazara/Renderer/Debug.hpp>
///TODO: Améliorer les méthode CopyTo*
NzRenderWindow::NzRenderWindow(NzVideoMode mode, const NzString& title, nzUInt32 style, const NzContextParameters& parameters)
{
NzErrorFlags flags(nzErrorFlag_ThrowException, true);
Create(mode, title, style, parameters);
#ifdef NAZARA_DEBUG
if (!m_impl)
{
NazaraError("Failed to create render window");
throw std::runtime_error("Constructor failed");
}
#endif
}
NzRenderWindow::NzRenderWindow(NzWindowHandle handle, const NzContextParameters& parameters)
{
NzErrorFlags flags(nzErrorFlag_ThrowException, true);
Create(handle, parameters);
#ifdef NAZARA_DEBUG
if (!m_impl)
{
NazaraError("Failed to create render window");
throw std::runtime_error("Constructor failed");
}
#endif
}
NzRenderWindow::~NzRenderWindow()
@@ -331,4 +320,3 @@ void NzRenderWindow::OnWindowResized()
{
NotifySizeChange();
}

View File

@@ -1,4 +1,4 @@
// Copyright (C) 2014 Jérôme Leclercq
// Copyright (C) 2015 Jérôme Leclercq
// This file is part of the "Nazara Engine - Renderer module"
// For conditions of distribution and use, see copyright notice in Config.hpp
@@ -35,6 +35,22 @@
namespace
{
const nzUInt8 r_coreFragmentShader[] = {
#include <Nazara/Renderer/Resources/Shaders/Debug/core.frag.h>
};
const nzUInt8 r_coreVertexShader[] = {
#include <Nazara/Renderer/Resources/Shaders/Debug/core.vert.h>
};
const nzUInt8 r_compatibilityFragmentShader[] = {
#include <Nazara/Renderer/Resources/Shaders/Debug/compatibility.frag.h>
};
const nzUInt8 r_compatibilityVertexShader[] = {
#include <Nazara/Renderer/Resources/Shaders/Debug/compatibility.vert.h>
};
enum ObjectType
{
ObjectType_Context,
@@ -67,10 +83,38 @@ namespace
bool samplerUpdated = false;
};
using VAO_Key = std::tuple<const NzIndexBuffer*, const NzVertexBuffer*, const NzVertexDeclaration*, const NzVertexDeclaration*>;
using VAO_Map = std::map<VAO_Key, GLuint>;
struct VAO_Entry
{
VAO_Entry(NzObjectListener* listener, int indexBufferIndex, int vertexBufferIndex, int vertexDeclarationIndex, int instancingDeclarationIndex) :
indexBufferListener(listener, indexBufferIndex),
vertexBufferListener(listener, vertexBufferIndex),
instancingDeclarationListener(listener, instancingDeclarationIndex),
vertexDeclarationListener(listener, vertexDeclarationIndex)
{
}
using Context_Map = std::unordered_map<const NzContext*, VAO_Map>;
GLuint vao;
NzIndexBufferConstListener indexBufferListener;
NzVertexBufferConstListener vertexBufferListener;
NzVertexDeclarationConstListener instancingDeclarationListener;
NzVertexDeclarationConstListener vertexDeclarationListener;
};
using VAO_Key = std::tuple<const NzIndexBuffer*, const NzVertexBuffer*, const NzVertexDeclaration*, const NzVertexDeclaration*>;
using VAO_Map = std::map<VAO_Key, VAO_Entry>;
struct Context_Entry
{
Context_Entry(NzObjectListener* listener, int index) :
contextListener(listener, index)
{
}
NzContextConstListener contextListener;
VAO_Map vaoMap;
};
using Context_Map = std::unordered_map<const NzContext*, Context_Entry>;
Context_Map s_vaos;
std::vector<unsigned int> s_dirtyTextureUnits;
@@ -93,6 +137,7 @@ namespace
bool s_useVertexArrayObjects;
unsigned int s_maxColorAttachments;
unsigned int s_maxRenderTarget;
unsigned int s_maxTextureSize;
unsigned int s_maxTextureUnit;
unsigned int s_maxVertexAttribs;
@@ -116,7 +161,7 @@ namespace
for (auto& pair : s_vaos)
{
const NzContext* context = pair.first;
VAO_Map& vaos = pair.second;
VAO_Map& vaos = pair.second.vaoMap;
auto it = vaos.begin();
while (it != vaos.end())
@@ -131,7 +176,7 @@ namespace
// son contexte d'origine est actif, sinon il faudra le mettre en file d'attente
// Ceci est géré par la méthode OpenGL::DeleteVertexArray
NzOpenGL::DeleteVertexArray(context, it->second);
NzOpenGL::DeleteVertexArray(context, it->second.vao);
vaos.erase(it++);
}
else
@@ -147,7 +192,7 @@ namespace
for (auto& pair : s_vaos)
{
const NzContext* context = pair.first;
VAO_Map& vaos = pair.second;
VAO_Map& vaos = pair.second.vaoMap;
auto it = vaos.begin();
while (it != vaos.end())
@@ -162,7 +207,7 @@ namespace
// son contexte d'origine est actif, sinon il faudra le mettre en file d'attente
// Ceci est géré par la méthode OpenGL::DeleteVertexArray
NzOpenGL::DeleteVertexArray(context, it->second);
NzOpenGL::DeleteVertexArray(context, it->second.vao);
vaos.erase(it++);
}
else
@@ -178,7 +223,7 @@ namespace
for (auto& pair : s_vaos)
{
const NzContext* context = pair.first;
VAO_Map& vaos = pair.second;
VAO_Map& vaos = pair.second.vaoMap;
auto it = vaos.begin();
while (it != vaos.end())
@@ -194,7 +239,7 @@ namespace
// son contexte d'origine est actif, sinon il faudra le mettre en file d'attente
// Ceci est géré par la méthode OpenGL::DeleteVertexArray
NzOpenGL::DeleteVertexArray(context, it->second);
NzOpenGL::DeleteVertexArray(context, it->second.vao);
vaos.erase(it++);
}
else
@@ -376,7 +421,7 @@ void NzRenderer::DrawIndexedPrimitivesInstanced(unsigned int instanceCount, nzPr
if (instanceCount == 0)
{
NazaraError("Instance count must be over 0");
NazaraError("Instance count must be over zero");
return;
}
@@ -471,7 +516,7 @@ void NzRenderer::DrawPrimitivesInstanced(unsigned int instanceCount, nzPrimitive
if (instanceCount == 0)
{
NazaraError("Instance count must be over 0");
NazaraError("Instance count must be over zero");
return;
}
@@ -613,6 +658,11 @@ unsigned int NzRenderer::GetMaxRenderTargets()
return s_maxRenderTarget;
}
unsigned int NzRenderer::GetMaxTextureSize()
{
return s_maxTextureSize;
}
unsigned int NzRenderer::GetMaxTextureUnits()
{
return s_maxTextureUnit;
@@ -693,7 +743,10 @@ bool NzRenderer::Initialize()
return false;
}
NzBuffer::SetBufferFunction(nzBufferStorage_Hardware, [](NzBuffer* parent, nzBufferType type) -> NzAbstractBuffer* { return new NzHardwareBuffer(parent, type); } );
NzBuffer::SetBufferFactory(nzDataStorage_Hardware, [](NzBuffer* parent, nzBufferType type) -> NzAbstractBuffer*
{
return new NzHardwareBuffer(parent, type);
});
for (unsigned int i = 0; i <= nzMatrixType_Max; ++i)
{
@@ -704,19 +757,19 @@ bool NzRenderer::Initialize()
}
// Récupération des capacités d'OpenGL
s_capabilities[nzRendererCap_AnisotropicFilter] = NzOpenGL::IsSupported(nzOpenGLExtension_AnisotropicFilter);
s_capabilities[nzRendererCap_ConditionalRendering] = NzOpenGL::IsSupported(nzOpenGLExtension_ConditionalRender);
s_capabilities[nzRendererCap_FP64] = NzOpenGL::IsSupported(nzOpenGLExtension_FP64);
s_capabilities[nzRendererCap_HardwareBuffer] = true; // Natif depuis OpenGL 1.5
s_capabilities[nzRendererCap_Instancing] = NzOpenGL::IsSupported(nzOpenGLExtension_DrawInstanced) && NzOpenGL::IsSupported(nzOpenGLExtension_InstancedArray);
s_capabilities[nzRendererCap_AnisotropicFilter] = NzOpenGL::IsSupported(nzOpenGLExtension_AnisotropicFilter);
s_capabilities[nzRendererCap_ConditionalRendering] = NzOpenGL::IsSupported(nzOpenGLExtension_ConditionalRender);
s_capabilities[nzRendererCap_FP64] = NzOpenGL::IsSupported(nzOpenGLExtension_FP64);
s_capabilities[nzRendererCap_HardwareBuffer] = true; // Natif depuis OpenGL 1.5
s_capabilities[nzRendererCap_Instancing] = NzOpenGL::IsSupported(nzOpenGLExtension_DrawInstanced) && NzOpenGL::IsSupported(nzOpenGLExtension_InstancedArray);
s_capabilities[nzRendererCap_MultipleRenderTargets] = (glBindFragDataLocation != nullptr); // Natif depuis OpenGL 2.0 mais inutile sans glBindFragDataLocation
s_capabilities[nzRendererCap_OcclusionQuery] = true; // Natif depuis OpenGL 1.5
s_capabilities[nzRendererCap_PixelBufferObject] = NzOpenGL::IsSupported(nzOpenGLExtension_PixelBufferObject);
s_capabilities[nzRendererCap_RenderTexture] = NzOpenGL::IsSupported(nzOpenGLExtension_FrameBufferObject);
s_capabilities[nzRendererCap_Texture3D] = true; // Natif depuis OpenGL 1.2
s_capabilities[nzRendererCap_TextureCubemap] = true; // Natif depuis OpenGL 1.3
s_capabilities[nzRendererCap_TextureMulti] = true; // Natif depuis OpenGL 1.3
s_capabilities[nzRendererCap_TextureNPOT] = true; // Natif depuis OpenGL 2.0
s_capabilities[nzRendererCap_OcclusionQuery] = true; // Natif depuis OpenGL 1.5
s_capabilities[nzRendererCap_PixelBufferObject] = NzOpenGL::IsSupported(nzOpenGLExtension_PixelBufferObject);
s_capabilities[nzRendererCap_RenderTexture] = NzOpenGL::IsSupported(nzOpenGLExtension_FrameBufferObject);
s_capabilities[nzRendererCap_Texture3D] = true; // Natif depuis OpenGL 1.2
s_capabilities[nzRendererCap_TextureCubemap] = true; // Natif depuis OpenGL 1.3
s_capabilities[nzRendererCap_TextureMulti] = true; // Natif depuis OpenGL 1.3
s_capabilities[nzRendererCap_TextureNPOT] = true; // Natif depuis OpenGL 2.0
NzContext::EnsureContext();
@@ -760,6 +813,10 @@ bool NzRenderer::Initialize()
else
s_maxTextureUnit = 1;
GLint maxTextureSize;
glGetIntegerv(GL_MAX_TEXTURE_SIZE, &maxTextureSize);
s_maxTextureSize = maxTextureSize;
GLint maxVertexAttribs;
glGetIntegerv(GL_MAX_VERTEX_ATTRIBS, &maxVertexAttribs);
s_maxVertexAttribs = static_cast<unsigned int>(maxVertexAttribs);
@@ -776,7 +833,7 @@ bool NzRenderer::Initialize()
s_updateFlags = Update_Matrices | Update_Shader | Update_VAO;
s_vertexBuffer = nullptr;
s_fullscreenQuadBuffer.Reset(NzVertexDeclaration::Get(nzVertexLayout_XY), 4, nzBufferStorage_Hardware, nzBufferUsage_Static);
s_fullscreenQuadBuffer.Reset(NzVertexDeclaration::Get(nzVertexLayout_XY), 4, nzDataStorage_Hardware, nzBufferUsage_Static);
float vertices[4*2] =
{
@@ -797,7 +854,7 @@ bool NzRenderer::Initialize()
try
{
NzErrorFlags errFlags(nzErrorFlag_ThrowException, true);
s_instanceBuffer.Reset(nullptr, NAZARA_RENDERER_INSTANCE_BUFFER_SIZE, nzBufferStorage_Hardware, nzBufferUsage_Dynamic);
s_instanceBuffer.Reset(nullptr, NAZARA_RENDERER_INSTANCE_BUFFER_SIZE, nzDataStorage_Hardware, nzBufferUsage_Dynamic);
}
catch (const std::exception& e)
{
@@ -836,39 +893,23 @@ bool NzRenderer::Initialize()
return false;
}
const nzUInt8 coreFragmentShader[] = {
#include <Nazara/Renderer/Resources/Shaders/Debug/core.frag.h>
};
const nzUInt8 coreVertexShader[] = {
#include <Nazara/Renderer/Resources/Shaders/Debug/core.vert.h>
};
const nzUInt8 compatibilityFragmentShader[] = {
#include <Nazara/Renderer/Resources/Shaders/Debug/compatibility.frag.h>
};
const nzUInt8 compatibilityVertexShader[] = {
#include <Nazara/Renderer/Resources/Shaders/Debug/compatibility.vert.h>
};
const char* fragmentShader;
const char* vertexShader;
unsigned int fragmentShaderLength;
unsigned int vertexShaderLength;
if (NzOpenGL::GetGLSLVersion() >= 140)
{
fragmentShader = reinterpret_cast<const char*>(coreFragmentShader);
fragmentShaderLength = sizeof(coreFragmentShader);
vertexShader = reinterpret_cast<const char*>(coreVertexShader);
vertexShaderLength = sizeof(coreVertexShader);
fragmentShader = reinterpret_cast<const char*>(r_coreFragmentShader);
fragmentShaderLength = sizeof(r_coreFragmentShader);
vertexShader = reinterpret_cast<const char*>(r_coreVertexShader);
vertexShaderLength = sizeof(r_coreVertexShader);
}
else
{
fragmentShader = reinterpret_cast<const char*>(compatibilityFragmentShader);
fragmentShaderLength = sizeof(compatibilityFragmentShader);
vertexShader = reinterpret_cast<const char*>(compatibilityVertexShader);
vertexShaderLength = sizeof(compatibilityVertexShader);
fragmentShader = reinterpret_cast<const char*>(r_compatibilityFragmentShader);
fragmentShaderLength = sizeof(r_compatibilityFragmentShader);
vertexShader = reinterpret_cast<const char*>(r_compatibilityVertexShader);
vertexShaderLength = sizeof(r_compatibilityVertexShader);
}
if (!shader->AttachStageFromSource(nzShaderStage_Fragment, fragmentShader, fragmentShaderLength))
@@ -925,7 +966,7 @@ bool NzRenderer::IsComponentTypeSupported(nzComponentType type)
return false;
}
NazaraError("Attribute type out of enum (0x" + NzString::Number(type, 16) + ')');
NazaraError("Attribute type not handled (0x" + NzString::Number(type, 16) + ')');
return false;
}
@@ -1521,28 +1562,14 @@ void NzRenderer::Uninitialize()
for (auto& pair : s_vaos)
{
const NzContext* context = pair.first;
const Context_Entry& contextEntry = pair.second;
for (auto& pair2 : pair.second)
for (auto& pair2 : contextEntry.vaoMap)
{
const VAO_Key& key = pair2.first;
const NzIndexBuffer* indexBuffer = std::get<0>(key);
const NzVertexBuffer* vertexBuffer = std::get<1>(key);
const NzVertexDeclaration* vertexDeclaration = std::get<2>(key);
const NzVertexDeclaration* instancingDeclaration = std::get<3>(key);
if (indexBuffer)
indexBuffer->RemoveObjectListener(&s_listener);
vertexBuffer->RemoveObjectListener(&s_listener);
vertexDeclaration->RemoveObjectListener(&s_listener);
if (instancingDeclaration)
instancingDeclaration->RemoveObjectListener(&s_listener);
NzOpenGL::DeleteVertexArray(context, pair2.second);
const VAO_Entry& entry = pair2.second;
NzOpenGL::DeleteVertexArray(context, entry.vao);
}
}
s_vaos.clear();
NzOpenGL::Uninitialize();
@@ -1707,16 +1734,16 @@ bool NzRenderer::EnsureStateUpdate()
// Note: Les VAOs ne sont pas partagés entre les contextes, nous avons donc un tableau de VAOs par contexte
const NzContext* context = NzContext::GetCurrent();
VAO_Map* vaos;
auto it = s_vaos.find(context);
if (it == s_vaos.end())
{
context->AddObjectListener(&s_listener, ObjectType_Context);
auto pair = s_vaos.insert(std::make_pair(context, Context_Map::mapped_type()));
vaos = &pair.first->second;
Context_Entry entry(&s_listener, ObjectType_Context);
entry.contextListener = context;
it = s_vaos.insert(std::make_pair(context, std::move(entry))).first;
}
else
vaos = &it->second;
VAO_Map& vaoMap = it->second.vaoMap;
// Notre clé est composée de ce qui définit un VAO
const NzVertexDeclaration* vertexDeclaration = s_vertexBuffer->GetVertexDeclaration();
@@ -1724,23 +1751,22 @@ bool NzRenderer::EnsureStateUpdate()
VAO_Key key(s_indexBuffer, s_vertexBuffer, vertexDeclaration, instancingDeclaration);
// On recherche un VAO existant avec notre configuration
vaoIt = vaos->find(key);
if (vaoIt == vaos->end())
vaoIt = vaoMap.find(key);
if (vaoIt == vaoMap.end())
{
// On créé notre VAO
glGenVertexArrays(1, &s_currentVAO);
glBindVertexArray(s_currentVAO);
// On l'ajoute à notre liste
vaoIt = vaos->insert(std::make_pair(key, s_currentVAO)).first;
if (s_indexBuffer)
s_indexBuffer->AddObjectListener(&s_listener, ObjectType_IndexBuffer);
VAO_Entry entry(&s_listener, ObjectType_IndexBuffer, ObjectType_VertexBuffer, ObjectType_VertexDeclaration, ObjectType_VertexDeclaration);
entry.indexBufferListener = std::get<0>(key);
entry.instancingDeclarationListener = std::get<3>(key);
entry.vertexBufferListener = std::get<1>(key);
entry.vertexDeclarationListener = std::get<2>(key);
entry.vao = s_currentVAO;
s_vertexBuffer->AddObjectListener(&s_listener, ObjectType_VertexBuffer);
vertexDeclaration->AddObjectListener(&s_listener, ObjectType_VertexDeclaration);
if (instancingDeclaration)
instancingDeclaration->AddObjectListener(&s_listener, ObjectType_VertexDeclaration);
vaoIt = vaoMap.insert(std::make_pair(key, std::move(entry))).first;
// Et on indique qu'on veut le programmer
update = true;
@@ -1748,7 +1774,7 @@ bool NzRenderer::EnsureStateUpdate()
else
{
// Notre VAO existe déjà, il est donc inutile de le reprogrammer
s_currentVAO = vaoIt->second;
s_currentVAO = vaoIt->second.vao;
update = false;
}
@@ -1787,15 +1813,15 @@ bool NzRenderer::EnsureStateUpdate()
unsigned int offset;
vertexDeclaration->GetComponent(static_cast<nzVertexComponent>(j), &enabled, &type, &offset);
if (!IsComponentTypeSupported(type))
{
NazaraError("Invalid vertex declaration " + NzString::Pointer(vertexDeclaration) + ": Vertex component 0x" + NzString::Number(j, 16) + " (type: 0x" + NzString::Number(type, 16) + ") is not supported");
updateFailed = true;
break;
}
if (enabled)
{
if (!IsComponentTypeSupported(type))
{
NazaraError("Invalid vertex declaration " + NzString::Pointer(vertexDeclaration) + ": Vertex component 0x" + NzString::Number(j, 16) + " (type: 0x" + NzString::Number(type, 16) + ") is not supported");
updateFailed = true;
break;
}
glEnableVertexAttribArray(NzOpenGL::VertexComponentIndex[j]);
switch (type)
@@ -1857,7 +1883,7 @@ bool NzRenderer::EnsureStateUpdate()
default:
{
NazaraInternalError("Unsupported component type");
NazaraInternalError("Unsupported component type (0x" + NzString::Number(type, 16) + ')');
break;
}
}
@@ -1899,8 +1925,8 @@ bool NzRenderer::EnsureStateUpdate()
if (updateFailed)
{
// La création de notre VAO a échoué, libérons-le et marquons-le comme problématique
glDeleteVertexArrays(1, &vaoIt->second);
vaoIt->second = 0;
glDeleteVertexArrays(1, &vaoIt->second.vao);
vaoIt->second.vao = 0;
s_currentVAO = 0;
}
else
@@ -1964,7 +1990,8 @@ void NzRenderer::OnTextureReleased(const NzTexture* texture)
{
if (unit.texture == texture)
unit.texture = nullptr;
// Inutile de changer le flag pour une texture désactivée
// Inutile de changer le flag pour une texture désactivée
}
}

View File

@@ -1,4 +1,4 @@
// Copyright (C) 2014 Jérôme Leclercq
// Copyright (C) 2015 Jérôme Leclercq
// This file is part of the "Nazara Engine - Renderer module"
// For conditions of distribution and use, see copyright notice in Config.hpp
@@ -16,17 +16,6 @@ m_program(0)
{
}
NzShader::NzShader(NzShader&& shader) :
m_linked(shader.m_linked),
m_program(shader.m_program)
{
for (unsigned int i = 0; i <= nzShaderStage_Max; ++i)
m_attachedShaders[i] = std::move(shader.m_attachedShaders[i]);
shader.m_linked = false;
shader.m_program = 0;
}
NzShader::~NzShader()
{
Destroy();
@@ -155,6 +144,7 @@ bool NzShader::Create()
glBindAttribLocation(m_program, NzOpenGL::VertexComponentIndex[nzVertexComponent_InstanceData3], "InstanceData3");
glBindAttribLocation(m_program, NzOpenGL::VertexComponentIndex[nzVertexComponent_InstanceData4], "InstanceData4");
glBindAttribLocation(m_program, NzOpenGL::VertexComponentIndex[nzVertexComponent_InstanceData5], "InstanceData5");
glBindAttribLocation(m_program, NzOpenGL::VertexComponentIndex[nzVertexComponent_Color], "VertexColor");
glBindAttribLocation(m_program, NzOpenGL::VertexComponentIndex[nzVertexComponent_Normal], "VertexNormal");
glBindAttribLocation(m_program, NzOpenGL::VertexComponentIndex[nzVertexComponent_Position], "VertexPosition");
glBindAttribLocation(m_program, NzOpenGL::VertexComponentIndex[nzVertexComponent_Tangent], "VertexTangent");
@@ -164,7 +154,6 @@ bool NzShader::Create()
glBindAttribLocation(m_program, NzOpenGL::VertexComponentIndex[nzVertexComponent_Userdata2], "VertexUserdata2");
glBindAttribLocation(m_program, NzOpenGL::VertexComponentIndex[nzVertexComponent_Userdata3], "VertexUserdata3");
glBindAttribLocation(m_program, NzOpenGL::VertexComponentIndex[nzVertexComponent_Userdata4], "VertexUserdata4");
glBindAttribLocation(m_program, NzOpenGL::VertexComponentIndex[nzVertexComponent_Userdata5], "VertexUserdata5");
if (NzRenderer::HasCapability(nzRendererCap_MultipleRenderTargets))
{
@@ -254,10 +243,10 @@ NzString NzShader::GetSourceCode(nzShaderStage stage) const
unsigned int totalLength = 0;
for (unsigned int shader : m_attachedShaders[stage])
{
GLint length;
glGetShaderiv(shader, GL_SHADER_SOURCE_LENGTH, &length);
GLint length;
glGetShaderiv(shader, GL_SHADER_SOURCE_LENGTH, &length);
totalLength += length - 1;
totalLength += length - 1;
}
totalLength += (m_attachedShaders[stage].size()-1)*(sizeof(sep)/sizeof(char));
@@ -757,22 +746,6 @@ unsigned int NzShader::GetOpenGLID() const
return m_program;
}
NzShader& NzShader::operator=(NzShader&& shader)
{
Destroy();
for (unsigned int i = 0; i <= nzShaderStage_Max; ++i)
m_attachedShaders[i] = std::move(shader.m_attachedShaders[i]);
m_linked = shader.m_linked;
m_program = shader.m_program;
shader.m_linked = false;
shader.m_program = 0;
return *this;
}
bool NzShader::IsStageSupported(nzShaderStage stage)
{
return NzShaderStage::IsSupported(stage);
@@ -789,7 +762,6 @@ bool NzShader::PostLinkage()
// Pour éviter de se tromper entre le nom et la constante
#define CacheUniform(name) m_uniformLocations[nzShaderUniform_##name] = glGetUniformLocation(m_program, #name)
CacheUniform(EyePosition);
CacheUniform(InvProjMatrix);
CacheUniform(InvTargetSize);
CacheUniform(InvViewMatrix);
@@ -798,7 +770,6 @@ bool NzShader::PostLinkage()
CacheUniform(InvWorldViewMatrix);
CacheUniform(InvWorldViewProjMatrix);
CacheUniform(ProjMatrix);
CacheUniform(SceneAmbient);
CacheUniform(TargetSize);
CacheUniform(ViewMatrix);
CacheUniform(ViewProjMatrix);

View File

@@ -1,4 +1,4 @@
// Copyright (C) 2014 Jérôme Leclercq
// Copyright (C) 2015 Jérôme Leclercq
// This file is part of the "Nazara Engine - Renderer module"
// For conditions of distribution and use, see copyright notice in Config.hpp

View File

@@ -1,4 +1,4 @@
// Copyright (C) 2014 Jérôme Leclercq
// Copyright (C) 2015 Jérôme Leclercq
// This file is part of the "Nazara Engine - Renderer module"
// For conditions of distribution and use, see copyright notice in Config.hpp

File diff suppressed because it is too large Load Diff

View File

@@ -1,4 +1,4 @@
// Copyright (C) 2014 Jérôme Leclercq
// Copyright (C) 2015 Jérôme Leclercq
// This file is part of the "Nazara Engine - Renderer module"
// For conditions of distribution and use, see copyright notice in Config.hpp

View File

@@ -1,4 +1,4 @@
// Copyright (C) 2014 Jérôme Leclercq
// Copyright (C) 2015 Jérôme Leclercq
// This file is part of the "Nazara Engine - Renderer module"
// For conditions of distribution and use, see copyright notice in Config.hpp

View File

@@ -1,4 +1,4 @@
// Copyright (C) 2014 Jérôme Leclercq
// Copyright (C) 2015 Jérôme Leclercq
// This file is part of the "Nazara Engine - Renderer module"
// For conditions of distribution and use, see copyright notice in Config.hpp

View File

@@ -1,4 +1,4 @@
// Copyright (C) 2014 Jérôme Leclercq
// Copyright (C) 2015 Jérôme Leclercq
// This file is part of the "Nazara Engine - Renderer module"
// For conditions of distribution and use, see copyright notice in Config.hpp

View File

@@ -1,4 +1,4 @@
// Copyright (C) 2014 Jérôme Leclercq
// Copyright (C) 2015 Jérôme Leclercq
// This file is part of the "Nazara Engine - Renderer module"
// For conditions of distribution and use, see copyright notice in Config.hpp

View File

@@ -1,4 +1,4 @@
// Copyright (C) 2014 Jérôme Leclercq
// Copyright (C) 2015 Jérôme Leclercq
// This file is part of the "Nazara Engine - Renderer module"
// For conditions of distribution and use, see copyright notice in Config.hpp
@@ -32,7 +32,8 @@ NzUberShaderInstance* NzUberShaderPreprocessor::Get(const NzParameterList& param
{
try
{
NzErrorFlags errFlags(nzErrorFlag_Silent | nzErrorFlag_ThrowException);
// Une exception sera lancée à la moindre erreur et celle-ci ne sera pas enregistrée dans le log (car traitée dans le bloc catch)
NzErrorFlags errFlags(nzErrorFlag_Silent | nzErrorFlag_ThrowException, true);
std::unique_ptr<NzShader> shader(new NzShader);
shader->SetPersistent(false);
@@ -42,7 +43,8 @@ NzUberShaderInstance* NzUberShaderPreprocessor::Get(const NzParameterList& param
{
const Shader& shaderStage = m_shaders[i];
if (shaderStage.present)
// Le shader stage est-il activé dans cette version du shader ?
if (shaderStage.present && (flags & shaderStage.requiredFlags) == shaderStage.requiredFlags)
{
nzUInt32 stageFlags = 0;
for (auto it = shaderStage.flags.begin(); it != shaderStage.flags.end(); ++it)
@@ -73,49 +75,46 @@ NzUberShaderInstance* NzUberShaderPreprocessor::Get(const NzParameterList& param
for (auto it = shaderStage.flags.begin(); it != shaderStage.flags.end(); ++it)
code << "#define " << it->first << ' ' << ((stageFlags & it->second) ? '1' : '0') << '\n';
code << "\n#line 1\n";
code << "\n#line 1\n"; // Pour que les éventuelles erreurs du shader se réfèrent à la bonne ligne
code << shaderStage.source;
stage.SetSource(code);
stage.Compile();
shader->AttachStage(static_cast<nzShaderStage>(i), stage);
shaderStage.cache.emplace(flags, std::move(stage));
stageIt = shaderStage.cache.emplace(flags, std::move(stage)).first;
}
else
shader->AttachStage(static_cast<nzShaderStage>(i), stageIt->second);
shader->AttachStage(static_cast<nzShaderStage>(i), stageIt->second);
}
}
shader->Link();
auto pair = m_cache.emplace(flags, shader.get());
// On construit l'instant
shaderIt = m_cache.emplace(flags, shader.get()).first;
shader.release();
return &(pair.first)->second; // On retourne l'objet construit
}
catch (const std::exception& e)
{
NzErrorFlags errFlags(nzErrorFlag_ThrowExceptionDisabled);
NazaraError("Failed to build uber shader instance: " + NzError::GetLastError());
NazaraError("Failed to build UberShader instance: " + NzError::GetLastError());
throw;
}
}
else
return &shaderIt->second;
return &shaderIt->second;
}
void NzUberShaderPreprocessor::SetShader(nzShaderStage stage, const NzString& source, const NzString& flagString)
void NzUberShaderPreprocessor::SetShader(nzShaderStage stage, const NzString& source, const NzString& shaderFlags, const NzString& requiredFlags)
{
Shader& shader = m_shaders[stage];
shader.present = true;
shader.source = source;
// On extrait les flags de la chaîne
std::vector<NzString> flags;
flagString.Split(flags, ' ');
shaderFlags.Split(flags, ' ');
for (NzString& flag : flags)
{
@@ -127,9 +126,31 @@ void NzUberShaderPreprocessor::SetShader(nzShaderStage stage, const NzString& so
if (it2 == shader.flags.end())
shader.flags[flag] = 1U << shader.flags.size();
}
// On construit les flags requis pour l'activation du shader
shader.requiredFlags = 0;
flags.clear();
requiredFlags.Split(flags, ' ');
for (NzString& flag : flags)
{
nzUInt32 flagVal;
auto it = m_flags.find(flag);
if (it == m_flags.end())
{
flagVal = 1U << m_flags.size();
m_flags[flag] = flagVal;
}
else
flagVal = it->second;
shader.requiredFlags |= flagVal;
}
}
bool NzUberShaderPreprocessor::SetShaderFromFile(nzShaderStage stage, const NzString& filePath, const NzString& flags)
bool NzUberShaderPreprocessor::SetShaderFromFile(nzShaderStage stage, const NzString& filePath, const NzString& shaderFlags, const NzString& requiredFlags)
{
NzFile file(filePath);
if (!file.Open(NzFile::ReadOnly | NzFile::Text))
@@ -150,7 +171,7 @@ bool NzUberShaderPreprocessor::SetShaderFromFile(nzShaderStage stage, const NzSt
file.Close();
SetShader(stage, source, flags);
SetShader(stage, source, shaderFlags, requiredFlags);
return true;
}

View File

@@ -1,4 +1,4 @@
// Copyright (C) 2014 Jérôme Leclercq
// Copyright (C) 2015 Jérôme Leclercq
// This file is part of the "Nazara Engine - Renderer module"
// For conditions of distribution and use, see copyright notice in Config.hpp
@@ -160,15 +160,15 @@ bool NzContextImpl::Create(NzContextParameters& parameters)
{
*attrib++ = WGL_CONTEXT_PROFILE_MASK_ARB;
*attrib++ = (parameters.compatibilityProfile) ? WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB : WGL_CONTEXT_CORE_PROFILE_BIT_ARB;
// Les contextes forward-compatible ne sont plus utilisés pour cette raison :
// http://www.opengl.org/discussion_boards/showthread.php/175052-Forward-compatible-vs-Core-profile
}
if (parameters.debugMode)
{
*attrib++ = WGL_CONTEXT_FLAGS_ARB;
*attrib++ = WGL_CONTEXT_DEBUG_BIT_ARB;
// Les contextes forward-compatible ne sont plus utilisés pour cette raison :
// http://www.opengl.org/discussion_boards/showthread.php/175052-Forward-compatible-vs-Core-profile
}
*attrib++ = 0;

View File

@@ -1,4 +1,4 @@
// Copyright (C) 2014 Jérôme Leclercq
// Copyright (C) 2015 Jérôme Leclercq
// This file is part of the "Nazara Engine".
// For conditions of distribution and use, see copyright notice in Config.hpp