diff --git a/include/Nazara/Renderer/RenderTexture.hpp b/include/Nazara/Renderer/RenderTexture.hpp index 0794b5e67..e41f86202 100644 --- a/include/Nazara/Renderer/RenderTexture.hpp +++ b/include/Nazara/Renderer/RenderTexture.hpp @@ -24,10 +24,10 @@ class NAZARA_API NzRenderTexture : public NzRenderTarget, NzResourceListener, Nz NzRenderTexture() = default; ~NzRenderTexture(); - bool AttachBuffer(nzAttachmentPoint attachmentPoint, nzUInt8 index, nzPixelFormat format); + bool AttachBuffer(nzAttachmentPoint attachmentPoint, nzUInt8 index, nzPixelFormat format, unsigned int width, unsigned int height); bool AttachTexture(nzAttachmentPoint attachmentPoint, nzUInt8 index, NzTexture* texture, unsigned int z = 0); - bool Create(unsigned int width, unsigned int height, bool lock = false); + bool Create(bool lock = false); void Destroy(); void Detach(nzAttachmentPoint attachmentPoint, nzUInt8 index); @@ -41,6 +41,11 @@ class NAZARA_API NzRenderTexture : public NzRenderTarget, NzResourceListener, Nz bool IsValid() const; bool Lock() const; + + void SetColorTarget(nzUInt8 target); + void SetColorTargets(const nzUInt8* targets, unsigned int targetCount); + void SetColorTargets(const std::initializer_list& targets); + void Unlock() const; // Fonctions OpenGL @@ -51,9 +56,12 @@ class NAZARA_API NzRenderTexture : public NzRenderTarget, NzResourceListener, Nz protected: bool Activate() const override; void Desactivate() const override; + void EnsureTargetUpdated() const override; private: bool OnResourceDestroy(const NzResource* resource, int index) override; + void UpdateDrawBuffers() const; + void UpdateTargets() const; NzRenderTextureImpl* m_impl = nullptr; }; diff --git a/include/Nazara/Renderer/RenderWindow.hpp b/include/Nazara/Renderer/RenderWindow.hpp index 9eca87021..c54611dc0 100644 --- a/include/Nazara/Renderer/RenderWindow.hpp +++ b/include/Nazara/Renderer/RenderWindow.hpp @@ -54,6 +54,7 @@ class NAZARA_API NzRenderWindow : public NzRenderTarget, public NzWindow protected: bool Activate() const override; + void EnsureTargetUpdated() const override; private: bool OnWindowCreated() override; diff --git a/include/Nazara/Renderer/Renderer.hpp b/include/Nazara/Renderer/Renderer.hpp index 30a9fbc8d..b4df2c7bc 100644 --- a/include/Nazara/Renderer/Renderer.hpp +++ b/include/Nazara/Renderer/Renderer.hpp @@ -56,6 +56,7 @@ class NAZARA_API NzRenderer static float GetLineWidth(); static NzMatrix4f GetMatrix(nzMatrixType type); static nzUInt8 GetMaxAnisotropyLevel(); + static unsigned int GetMaxColorAttachments(); static unsigned int GetMaxRenderTargets(); static unsigned int GetMaxTextureUnits(); static unsigned int GetMaxVertexAttribs(); diff --git a/src/Nazara/Renderer/RenderTexture.cpp b/src/Nazara/Renderer/RenderTexture.cpp index a97a62b2f..3a8b7ac6e 100644 --- a/src/Nazara/Renderer/RenderTexture.cpp +++ b/src/Nazara/Renderer/RenderTexture.cpp @@ -7,6 +7,7 @@ #include #include #include +#include #include #include @@ -19,6 +20,8 @@ namespace bool isBuffer; bool isUsed = false; + unsigned int height; + unsigned int width; }; unsigned int attachmentIndex[nzAttachmentPoint_Max+1] = @@ -44,12 +47,15 @@ namespace struct NzRenderTextureImpl { GLuint fbo; - std::vector attachements; + std::vector attachments; + std::vector colorTargets; mutable std::vector drawBuffers; const NzContext* context; bool checked = false; bool complete = false; + bool userDefinedTargets = false; mutable bool drawBuffersUpdated = true; + mutable bool targetsUpdated = true; unsigned int height; unsigned int width; }; @@ -59,7 +65,7 @@ NzRenderTexture::~NzRenderTexture() Destroy(); } -bool NzRenderTexture::AttachBuffer(nzAttachmentPoint attachmentPoint, nzUInt8 index, nzPixelFormat format) +bool NzRenderTexture::AttachBuffer(nzAttachmentPoint attachmentPoint, nzUInt8 index, nzPixelFormat format, unsigned int width, unsigned int height) { #if NAZARA_RENDERER_SAFE if (!m_impl) @@ -68,14 +74,25 @@ bool NzRenderTexture::AttachBuffer(nzAttachmentPoint attachmentPoint, nzUInt8 in return false; } - if (attachmentPoint != nzAttachmentPoint_Color && index > 0) + if (attachmentPoint != nzAttachmentPoint_Color) { - NazaraError("Index must be 0 for non-color attachments"); - return false; + if (index > 0) + { + NazaraError("Index must be 0 for non-color attachments"); + return false; + } + } + else + { + if (index >= NzRenderer::GetMaxColorAttachments()) + { + NazaraError("Color index is over max color attachments (" + NzString::Number(index) + ", " + NzString::Number(NzRenderer::GetMaxColorAttachments()) + ")"); + return false; + } } unsigned int depthStencilIndex = attachmentIndex[nzAttachmentPoint_DepthStencil]; - if (m_impl->attachements.size() > depthStencilIndex && m_impl->attachements[depthStencilIndex].isUsed) + if (m_impl->attachments.size() > depthStencilIndex && m_impl->attachments[depthStencilIndex].isUsed) { if (attachmentPoint == nzAttachmentPoint_Depth) { @@ -96,6 +113,12 @@ bool NzRenderTexture::AttachBuffer(nzAttachmentPoint attachmentPoint, nzUInt8 in NazaraError("Pixel format type does not match attachment point type"); return false; } + + if (width == 0 || height == 0) + { + NazaraError("Invalid size"); + return false; + } #endif NzOpenGL::Format openglFormat; @@ -127,7 +150,7 @@ bool NzRenderTexture::AttachBuffer(nzAttachmentPoint attachmentPoint, nzUInt8 in glGetIntegerv(GL_RENDERBUFFER_BINDING, &previous); glBindRenderbuffer(GL_RENDERBUFFER, renderBuffer); - glRenderbufferStorage(GL_RENDERBUFFER, openglFormat.internalFormat, m_impl->width, m_impl->height); + glRenderbufferStorage(GL_RENDERBUFFER, openglFormat.internalFormat, width, height); if (previous != 0) glBindRenderbuffer(GL_RENDERBUFFER, previous); @@ -136,16 +159,24 @@ bool NzRenderTexture::AttachBuffer(nzAttachmentPoint attachmentPoint, nzUInt8 in Unlock(); unsigned int minSize = attachmentIndex[attachmentPoint]+index+1; - if (m_impl->attachements.size() < minSize) - m_impl->attachements.resize(minSize); + if (m_impl->attachments.size() < minSize) + m_impl->attachments.resize(minSize); - Attachment& attachment = m_impl->attachements[minSize-1]; + Attachment& attachment = m_impl->attachments[minSize-1]; + attachment.buffer = renderBuffer; attachment.isBuffer = true; attachment.isUsed = true; - attachment.buffer = renderBuffer; + attachment.height = height; + attachment.width = width; m_impl->checked = false; - m_impl->drawBuffersUpdated = false; + + if (attachmentPoint == nzAttachmentPoint_Color && !m_impl->userDefinedTargets) + { + m_impl->colorTargets.push_back(index); + m_impl->drawBuffersUpdated = false; + m_impl->targetsUpdated = false; + } return true; } @@ -159,10 +190,21 @@ bool NzRenderTexture::AttachTexture(nzAttachmentPoint attachmentPoint, nzUInt8 i return false; } - if (attachmentPoint != nzAttachmentPoint_Color && index > 0) + if (attachmentPoint != nzAttachmentPoint_Color) { - NazaraError("Index must be 0 for non-color attachments"); - return false; + if (index > 0) + { + NazaraError("Index must be 0 for non-color attachments"); + return false; + } + } + else + { + if (index >= NzRenderer::GetMaxColorAttachments()) + { + NazaraError("Color index is over max color attachments (" + NzString::Number(index) + ", " + NzString::Number(NzRenderer::GetMaxColorAttachments()) + ")"); + return false; + } } if (attachmentPoint == nzAttachmentPoint_Stencil) @@ -172,8 +214,8 @@ bool NzRenderTexture::AttachTexture(nzAttachmentPoint attachmentPoint, nzUInt8 i } unsigned int depthStencilIndex = attachmentIndex[nzAttachmentPoint_DepthStencil]; - if (attachmentPoint == nzAttachmentPoint_Depth && m_impl->attachements.size() > depthStencilIndex && - m_impl->attachements[depthStencilIndex].isUsed) + if (attachmentPoint == nzAttachmentPoint_Depth && m_impl->attachments.size() > depthStencilIndex && + m_impl->attachments[depthStencilIndex].isUsed) { NazaraError("Depth target already attached by DepthStencil attachment"); return false; @@ -185,12 +227,6 @@ bool NzRenderTexture::AttachTexture(nzAttachmentPoint attachmentPoint, nzUInt8 i return false; } - if (texture->GetWidth() < m_impl->width || texture->GetHeight() < m_impl->height) - { - NazaraError("Texture cannot be smaller than render texture"); - return false; - } - unsigned int depth = (texture->GetType() == nzImageType_Cubemap) ? 6 : texture->GetDepth(); if (z >= depth) { @@ -243,23 +279,31 @@ bool NzRenderTexture::AttachTexture(nzAttachmentPoint attachmentPoint, nzUInt8 i Unlock(); unsigned int minSize = attachmentIndex[attachmentPoint]+index+1; - if (m_impl->attachements.size() < minSize) - m_impl->attachements.resize(minSize); + if (m_impl->attachments.size() < minSize) + m_impl->attachments.resize(minSize); - Attachment& attachment = m_impl->attachements[minSize-1]; + Attachment& attachment = m_impl->attachments[minSize-1]; attachment.isBuffer = false; attachment.isUsed = true; + attachment.height = texture->GetHeight(); attachment.texture = texture; + attachment.width = texture->GetWidth(); texture->AddResourceListener(this); m_impl->checked = false; - m_impl->drawBuffersUpdated = false; + + if (attachmentPoint == nzAttachmentPoint_Color && !m_impl->userDefinedTargets) + { + m_impl->colorTargets.push_back(index); + m_impl->drawBuffersUpdated = false; + m_impl->targetsUpdated = false; + } return true; } -bool NzRenderTexture::Create(unsigned int width, unsigned int height, bool lock) +bool NzRenderTexture::Create(bool lock) { if (!IsSupported()) { @@ -270,18 +314,6 @@ bool NzRenderTexture::Create(unsigned int width, unsigned int height, bool lock) Destroy(); #if NAZARA_RENDERER_SAFE - if (width == 0) - { - NazaraError("Width must be at least 1 (0)"); - return false; - } - - if (height == 0) - { - NazaraError("Height must be at least 1 (0)"); - return false; - } - if (NzContext::GetCurrent() == nullptr) { NazaraError("No active context"); @@ -290,8 +322,6 @@ bool NzRenderTexture::Create(unsigned int width, unsigned int height, bool lock) #endif NzRenderTextureImpl* impl = new NzRenderTextureImpl; - impl->width = width; - impl->height = height; impl->context = NzContext::GetCurrent(); impl->context->AddResourceListener(this); @@ -301,9 +331,9 @@ bool NzRenderTexture::Create(unsigned int width, unsigned int height, bool lock) if (!impl->fbo) { - NazaraError("Failed to create framebuffer"); delete impl; + NazaraError("Failed to create framebuffer"); return false; } @@ -311,10 +341,10 @@ bool NzRenderTexture::Create(unsigned int width, unsigned int height, bool lock) if (lock && !Lock()) { - NazaraError("Failed to lock render texture"); delete impl; m_impl = nullptr; + NazaraError("Failed to lock render texture"); return false; } @@ -339,7 +369,7 @@ void NzRenderTexture::Destroy() m_impl->context->RemoveResourceListener(this); - for (const Attachment& attachment : m_impl->attachements) + for (const Attachment& attachment : m_impl->attachments) { if (attachment.isUsed) { @@ -375,10 +405,10 @@ void NzRenderTexture::Detach(nzAttachmentPoint attachmentPoint, nzUInt8 index) #endif unsigned int attachIndex = attachmentIndex[attachmentPoint]+index; - if (attachIndex >= m_impl->attachements.size()) + if (attachIndex >= m_impl->attachments.size()) return; - Attachment& attachement = m_impl->attachements[attachIndex]; + Attachment& attachement = m_impl->attachments[attachIndex]; if (!attachement.isUsed) return; @@ -404,13 +434,14 @@ void NzRenderTexture::Detach(nzAttachmentPoint attachmentPoint, nzUInt8 index) attachement.texture->RemoveResourceListener(this); attachement.texture = nullptr; + + m_impl->drawBuffersUpdated = false; + m_impl->targetsUpdated = false; } Unlock(); m_impl->checked = false; - m_impl->drawBuffersUpdated = false; - } unsigned int NzRenderTexture::GetHeight() const @@ -423,6 +454,9 @@ unsigned int NzRenderTexture::GetHeight() const } #endif + if (!m_impl->targetsUpdated) + UpdateTargets(); + return m_impl->height; } @@ -450,6 +484,9 @@ unsigned int NzRenderTexture::GetWidth() const } #endif + if (!m_impl->targetsUpdated) + UpdateTargets(); + return m_impl->width; } @@ -522,7 +559,7 @@ bool NzRenderTexture::IsComplete() const bool NzRenderTexture::IsRenderable() const { - return IsComplete(); + return IsComplete() && !m_impl->attachments.empty(); } bool NzRenderTexture::IsValid() const @@ -560,6 +597,70 @@ bool NzRenderTexture::Lock() const return true; } +void NzRenderTexture::SetColorTarget(nzUInt8 target) +{ + SetColorTargets(&target, 1); +} + +void NzRenderTexture::SetColorTargets(const nzUInt8* targets, unsigned int targetCount) +{ + #if NAZARA_RENDERER_SAFE + if (!m_impl) + { + NazaraError("Render texture not created"); + return; + } + + for (unsigned int i = 0; i < targetCount; ++i) + { + unsigned int index = attachmentIndex[nzAttachmentPoint_Color] + targets[i]; + if (index >= m_impl->attachments.size() || !m_impl->attachments[index].isUsed) + { + NazaraError("Target " + NzString::Number(targets[i]) + " not attached"); + return; + } + } + #endif + + m_impl->colorTargets.resize(targetCount); + std::memcpy(&m_impl->colorTargets[0], targets, targetCount*sizeof(nzUInt8)); + + m_impl->drawBuffersUpdated = false; + m_impl->targetsUpdated = false; + m_impl->userDefinedTargets = true; +} + +void NzRenderTexture::SetColorTargets(const std::initializer_list& targets) +{ + #if NAZARA_RENDERER_SAFE + if (!m_impl) + { + NazaraError("Render texture not created"); + return; + } + + for (nzUInt8 target : targets) + { + unsigned int index = attachmentIndex[nzAttachmentPoint_Color] + target; + if (index >= m_impl->attachments.size() || !m_impl->attachments[index].isUsed) + { + NazaraError("Target " + NzString::Number(target) + " not attached"); + return; + } + } + #endif + + m_impl->colorTargets.resize(targets.size()); + + nzUInt8* ptr = &m_impl->colorTargets[0]; + for (nzUInt8 index : targets) + *ptr++ = index; + + m_impl->drawBuffersUpdated = false; + m_impl->targetsUpdated = false; + m_impl->userDefinedTargets = true; +} + void NzRenderTexture::Unlock() const { #if NAZARA_RENDERER_SAFE @@ -593,7 +694,7 @@ bool NzRenderTexture::HasContext() const bool NzRenderTexture::IsSupported() { - return NzRenderer::HasCapability(nzRendererCap_RenderTexture); + return NzOpenGL::IsSupported(nzOpenGLExtension_FrameBufferObject); } bool NzRenderTexture::Activate() const @@ -606,21 +707,9 @@ bool NzRenderTexture::Activate() const } #endif - if (!m_impl->drawBuffersUpdated) - { - m_impl->drawBuffers.clear(); - m_impl->drawBuffers.reserve(m_impl->attachements.size()); - for (unsigned int i = attachmentIndex[nzAttachmentPoint_Color]; i < m_impl->attachements.size(); ++i) - { - if (m_impl->attachements[i].isUsed) - m_impl->drawBuffers.push_back(GL_COLOR_ATTACHMENT0 + i - attachmentIndex[nzAttachmentPoint_Color]); - } - - m_impl->drawBuffersUpdated = true; - } - glBindFramebuffer(GL_DRAW_FRAMEBUFFER, m_impl->fbo); - glDrawBuffers(m_impl->drawBuffers.size(), &m_impl->drawBuffers[0]); + + m_impl->drawBuffersUpdated = false; return true; } @@ -640,6 +729,19 @@ void NzRenderTexture::Desactivate() const glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0); } +void NzRenderTexture::EnsureTargetUpdated() const +{ + if (!m_impl->drawBuffersUpdated) + UpdateDrawBuffers(); + + for (nzUInt8 index : m_impl->colorTargets) + { + Attachment& attachment = m_impl->attachments[attachmentIndex[nzAttachmentPoint_Color] + index]; + if (!attachment.isBuffer) + attachment.texture->InvalidateMipmaps(); + } +} + bool NzRenderTexture::OnResourceDestroy(const NzResource* resource, int index) { if (resource == m_impl->context) @@ -648,12 +750,49 @@ bool NzRenderTexture::OnResourceDestroy(const NzResource* resource, int index) else // Sinon, c'est une texture { // La ressource n'est plus, du coup nous mettons à jour - Attachment& attachement = m_impl->attachements[index]; + Attachment& attachement = m_impl->attachments[index]; attachement.isUsed = false; m_impl->checked = false; - m_impl->drawBuffersUpdated = false; + m_impl->targetsUpdated = false; } return false; } + +void NzRenderTexture::UpdateDrawBuffers() const +{ + if (!m_impl->targetsUpdated) + UpdateTargets(); + + glDrawBuffers(m_impl->drawBuffers.size(), &m_impl->drawBuffers[0]); + + m_impl->drawBuffersUpdated = true; +} + +void NzRenderTexture::UpdateTargets() const +{ + m_impl->width = std::numeric_limits::max(); + m_impl->height = std::numeric_limits::max(); + + if (m_impl->colorTargets.empty()) + { + m_impl->drawBuffers.resize(1); + m_impl->drawBuffers[0] = GL_NONE; + } + else + { + m_impl->drawBuffers.resize(m_impl->colorTargets.size()); + GLenum* ptr = &m_impl->drawBuffers[0]; + for (nzUInt8 index : m_impl->colorTargets) + { + *ptr++ = GL_COLOR_ATTACHMENT0 + index; + + Attachment& attachment = m_impl->attachments[attachmentIndex[nzAttachmentPoint_Color] + index]; + m_impl->height = std::min(m_impl->height, attachment.height); + m_impl->width = std::min(m_impl->width, attachment.width); + } + } + + m_impl->targetsUpdated = true; +} diff --git a/src/Nazara/Renderer/RenderWindow.cpp b/src/Nazara/Renderer/RenderWindow.cpp index 9fa419d06..00b7617b1 100644 --- a/src/Nazara/Renderer/RenderWindow.cpp +++ b/src/Nazara/Renderer/RenderWindow.cpp @@ -162,7 +162,7 @@ void NzRenderWindow::Display() { if (m_framerateLimit > 0) { - int remainingTime = 1000/m_framerateLimit - m_clock.GetMilliseconds(); + int remainingTime = 1000/static_cast(m_framerateLimit) - static_cast(m_clock.GetMilliseconds()); if (remainingTime > 0) NzThread::Sleep(remainingTime); @@ -275,6 +275,11 @@ bool NzRenderWindow::Activate() const } } +void NzRenderWindow::EnsureTargetUpdated() const +{ + // Rien à faire +} + bool NzRenderWindow::OnWindowCreated() { m_parameters.doubleBuffered = true; diff --git a/src/Nazara/Renderer/Renderer.cpp b/src/Nazara/Renderer/Renderer.cpp index df9b67a2a..13611054f 100644 --- a/src/Nazara/Renderer/Renderer.cpp +++ b/src/Nazara/Renderer/Renderer.cpp @@ -5,6 +5,7 @@ #include #include #include +#include #include #include #include @@ -46,7 +47,7 @@ namespace Update_None = 0, Update_Matrices = 0x1, - Update_Program = 0x2, + Update_Program = 0x2, Update_Textures = 0x4, Update_VAO = 0x8 }; @@ -92,9 +93,9 @@ namespace const NzVertexDeclaration* s_instancingDeclaration; bool s_capabilities[nzRendererCap_Max+1]; bool s_instancing; - bool s_uniformTargetSizeUpdated; bool s_useSamplerObjects; bool s_useVertexArrayObjects; + unsigned int s_maxColorAttachments; unsigned int s_maxRenderTarget; unsigned int s_maxTextureUnit; unsigned int s_maxVertexAttribs; @@ -217,6 +218,8 @@ void NzRenderer::Clear(nzUInt32 flags) if (flags) { + // On n'oublie pas de mettre à jour la cible + s_target->EnsureTargetUpdated(); // Les états du rendu sont suceptibles d'influencer glClear NzOpenGL::ApplyStates(s_states); @@ -298,12 +301,12 @@ void NzRenderer::DrawIndexedPrimitives(nzPrimitiveMode mode, unsigned int firstI if (s_indexBuffer->HasLargeIndices()) { - offset += firstIndex*sizeof(nzUInt64); + offset += firstIndex*sizeof(nzUInt32); type = GL_UNSIGNED_INT; } else { - offset += firstIndex*sizeof(nzUInt32); + offset += firstIndex*sizeof(nzUInt16); type = GL_UNSIGNED_SHORT; } @@ -369,12 +372,12 @@ void NzRenderer::DrawIndexedPrimitivesInstanced(unsigned int instanceCount, nzPr if (s_indexBuffer->HasLargeIndices()) { - offset += firstIndex*sizeof(nzUInt64); + offset += firstIndex*sizeof(nzUInt32); type = GL_UNSIGNED_INT; } else { - offset += firstIndex*sizeof(nzUInt32); + offset += firstIndex*sizeof(nzUInt16); type = GL_UNSIGNED_SHORT; } @@ -566,6 +569,11 @@ nzUInt8 NzRenderer::GetMaxAnisotropyLevel() return s_maxAnisotropyLevel; } +unsigned int NzRenderer::GetMaxColorAttachments() +{ + return s_maxColorAttachments; +} + unsigned int NzRenderer::GetMaxRenderTargets() { return s_maxRenderTarget; @@ -684,6 +692,16 @@ bool NzRenderer::Initialize() else s_maxAnisotropyLevel = 1; + if (s_capabilities[nzRendererCap_RenderTexture]) + { + GLint maxColorAttachments; + glGetIntegerv(GL_MAX_COLOR_ATTACHMENTS, &maxColorAttachments); + + s_maxColorAttachments = static_cast(maxColorAttachments); + } + else + s_maxColorAttachments = 1; + if (s_capabilities[nzRendererCap_MultipleRenderTargets]) { GLint maxDrawBuffers; @@ -713,8 +731,8 @@ bool NzRenderer::Initialize() s_indexBuffer = nullptr; s_program = nullptr; s_target = nullptr; + s_targetSize.Set(0U); s_textureUnits.resize(s_maxTextureUnit); - s_uniformTargetSizeUpdated = false; s_useSamplerObjects = NzOpenGL::IsSupported(nzOpenGLExtension_SamplerObjects); s_useVertexArrayObjects = NzOpenGL::IsSupported(nzOpenGLExtension_VertexArrayObjects); s_vertexBuffer = nullptr; @@ -742,6 +760,7 @@ bool NzRenderer::Initialize() { try { + NzErrorFlags errFlags(nzErrorFlag_ThrowException); s_instanceBuffer.Reset(nullptr, NAZARA_RENDERER_INSTANCE_BUFFER_SIZE, nzBufferStorage_Hardware, nzBufferUsage_Dynamic); } catch (const std::exception& e) @@ -1267,9 +1286,6 @@ bool NzRenderer::SetTarget(const NzRenderTarget* target) } s_target = target; - s_targetSize.Set(target->GetWidth(), target->GetHeight()); - - s_uniformTargetSizeUpdated = false; } NzOpenGL::SetTarget(s_target); @@ -1438,8 +1454,16 @@ bool NzRenderer::EnsureStateUpdate() NazaraError("No shader program"); return false; } + + if (!s_target) + { + NazaraError("No target"); + return false; + } #endif + s_target->EnsureTargetUpdated(); + NzAbstractShaderProgram* programImpl = s_program->m_impl; programImpl->Bind(); // Active le programme si ce n'est pas déjà le cas @@ -1462,7 +1486,7 @@ bool NzRenderer::EnsureStateUpdate() s_matrices[nzMatrixType_InvWorldView].location = programImpl->GetUniformLocation(nzShaderUniform_InvWorldViewMatrix); s_matrices[nzMatrixType_InvWorldViewProj].location = programImpl->GetUniformLocation(nzShaderUniform_InvWorldViewProjMatrix); - s_uniformTargetSizeUpdated = false; + s_targetSize.Set(0U); // On force l'envoi des uniformes s_updateFlags |= Update_Matrices; // Changement de programme, on renvoie toutes les matrices demandées s_updateFlags &= ~Update_Program; @@ -1471,19 +1495,20 @@ bool NzRenderer::EnsureStateUpdate() programImpl->BindTextures(); // Envoi des uniformes liées au Renderer - if (!s_uniformTargetSizeUpdated) + NzVector2ui targetSize(s_target->GetWidth(), s_target->GetHeight()); + if (s_targetSize != targetSize) { int location; location = programImpl->GetUniformLocation(nzShaderUniform_InvTargetSize); if (location != -1) - programImpl->SendVector(location, 1.f/NzVector2f(s_targetSize)); + programImpl->SendVector(location, 1.f/NzVector2f(targetSize)); location = programImpl->GetUniformLocation(nzShaderUniform_TargetSize); if (location != -1) - programImpl->SendVector(location, NzVector2f(s_targetSize)); + programImpl->SendVector(location, NzVector2f(targetSize)); - s_uniformTargetSizeUpdated = true; + s_targetSize.Set(targetSize); } if (s_updateFlags != Update_None) @@ -1501,7 +1526,7 @@ bool NzRenderer::EnsureStateUpdate() if (!unit.textureUpdated) { NzOpenGL::BindTextureUnit(i); - unit.texture->Bind(); + unit.texture->EnsureMipmapsUpdate(); unit.textureUpdated = true; } @@ -1524,7 +1549,7 @@ bool NzRenderer::EnsureStateUpdate() { NzOpenGL::BindTextureUnit(i); - unit.texture->Bind(); + unit.texture->EnsureMipmapsUpdate(); unit.textureUpdated = true; unit.sampler.Apply(unit.texture);