From f679f323c2182daab4b295d564871e6d793553e3 Mon Sep 17 00:00:00 2001 From: Lynix Date: Mon, 26 Aug 2013 13:37:33 +0200 Subject: [PATCH] Made scissor rect/viewport Recti instead of Rectui Also greatly optimized Renderer::Get[ScissorRect|Viewport] Former-commit-id: 87945543144216715520a4c3ab30629636995afd --- include/Nazara/Graphics/AbstractViewer.hpp | 2 +- include/Nazara/Graphics/Camera.hpp | 6 +- include/Nazara/Graphics/View.hpp | 6 +- include/Nazara/Renderer/OpenGL.hpp | 16 +- include/Nazara/Renderer/Renderer.hpp | 8 +- src/Nazara/Graphics/Camera.cpp | 11 +- src/Nazara/Graphics/View.cpp | 4 +- src/Nazara/Renderer/OpenGL.cpp | 218 +++++++++++++++++++-- src/Nazara/Renderer/RenderWindow.cpp | 11 +- src/Nazara/Renderer/Renderer.cpp | 91 +-------- 10 files changed, 258 insertions(+), 115 deletions(-) diff --git a/include/Nazara/Graphics/AbstractViewer.hpp b/include/Nazara/Graphics/AbstractViewer.hpp index c357ecea1..5e8288ea3 100644 --- a/include/Nazara/Graphics/AbstractViewer.hpp +++ b/include/Nazara/Graphics/AbstractViewer.hpp @@ -31,7 +31,7 @@ class NAZARA_API NzAbstractViewer virtual const NzMatrix4f& GetProjectionMatrix() const = 0; virtual const NzRenderTarget* GetTarget() const = 0; virtual const NzMatrix4f& GetViewMatrix() const = 0; - virtual const NzRectui& GetViewport() const = 0; + virtual const NzRecti& GetViewport() const = 0; virtual float GetZFar() const = 0; virtual float GetZNear() const = 0; }; diff --git a/include/Nazara/Graphics/Camera.hpp b/include/Nazara/Graphics/Camera.hpp index db081712a..214ff7597 100644 --- a/include/Nazara/Graphics/Camera.hpp +++ b/include/Nazara/Graphics/Camera.hpp @@ -36,7 +36,7 @@ class NAZARA_API NzCamera : public NzAbstractViewer, public NzNode, NzRenderTarg const NzRenderTarget* GetTarget() const; const NzRectf& GetTargetRegion() const; const NzMatrix4f& GetViewMatrix() const; - const NzRectui& GetViewport() const; + const NzRecti& GetViewport() const; float GetZFar() const; float GetZNear() const; @@ -44,7 +44,7 @@ class NAZARA_API NzCamera : public NzAbstractViewer, public NzNode, NzRenderTarg void SetTarget(const NzRenderTarget* renderTarget); void SetTarget(const NzRenderTarget& renderTarget); void SetTargetRegion(const NzRectf& region); - void SetViewport(const NzRectui& viewport); + void SetViewport(const NzRecti& viewport); void SetZFar(float zFar); void SetZNear(float zNear); @@ -64,7 +64,7 @@ class NAZARA_API NzCamera : public NzAbstractViewer, public NzNode, NzRenderTarg mutable NzMatrix4f m_projectionMatrix; mutable NzMatrix4f m_viewMatrix; NzRectf m_targetRegion; - mutable NzRectui m_viewport; + mutable NzRecti m_viewport; const NzRenderTarget* m_target; mutable bool m_frustumUpdated; mutable bool m_projectionMatrixUpdated; diff --git a/include/Nazara/Graphics/View.hpp b/include/Nazara/Graphics/View.hpp index d630b95af..71be60abe 100644 --- a/include/Nazara/Graphics/View.hpp +++ b/include/Nazara/Graphics/View.hpp @@ -35,14 +35,14 @@ class NAZARA_API NzView : public NzAbstractViewer, public NzNode, NzRenderTarget const NzRenderTarget* GetTarget() const; const NzRectf& GetTargetRegion() const; const NzMatrix4f& GetViewMatrix() const; - const NzRectui& GetViewport() const; + const NzRecti& GetViewport() const; float GetZFar() const; float GetZNear() const; void SetTarget(const NzRenderTarget* renderTarget); void SetTarget(const NzRenderTarget& renderTarget); void SetTargetRegion(const NzRectf& region); - void SetViewport(const NzRectui& viewport); + void SetViewport(const NzRecti& viewport); void SetZFar(float zFar); void SetZNear(float zNear); @@ -62,7 +62,7 @@ class NAZARA_API NzView : public NzAbstractViewer, public NzNode, NzRenderTarget mutable NzMatrix4f m_projectionMatrix; mutable NzMatrix4f m_viewMatrix; NzRectf m_targetRegion; - mutable NzRectui m_viewport; + mutable NzRecti m_viewport; const NzRenderTarget* m_target; mutable bool m_frustumUpdated; mutable bool m_projectionMatrixUpdated; diff --git a/include/Nazara/Renderer/OpenGL.hpp b/include/Nazara/Renderer/OpenGL.hpp index c4e27f75f..270a037be 100644 --- a/include/Nazara/Renderer/OpenGL.hpp +++ b/include/Nazara/Renderer/OpenGL.hpp @@ -13,9 +13,10 @@ #include #include #include -#include +#include #include #include +#include // Inclusion des extensions #include @@ -47,6 +48,8 @@ enum nzOpenGLExtension }; class NzContext; +class NzRenderTarget; + using NzOpenGLFunc = void (*)(); class NAZARA_API NzOpenGL @@ -75,9 +78,11 @@ class NAZARA_API NzOpenGL static void BindBuffer(nzBufferType type, GLuint id); static void BindProgram(GLuint id); + static void BindScissorBox(const NzRecti& scissorBox); static void BindTexture(nzImageType type, GLuint id); static void BindTexture(unsigned int textureUnit, nzImageType type, GLuint id); static void BindTextureUnit(unsigned int textureUnit); + static void BindViewport(const NzRecti& viewport); static void DeleteBuffer(nzBufferType type, GLuint id); static void DeleteProgram(GLuint id); @@ -85,12 +90,16 @@ class NAZARA_API NzOpenGL static GLuint GetCurrentBuffer(nzBufferType type); static GLuint GetCurrentProgram(); + static const NzRenderTarget* GetCurrentTarget(); + static NzRecti GetCurrentScissorBox(); static GLuint GetCurrentTexture(); static GLuint GetCurrentTexture(unsigned int textureUnit); + static unsigned int GetCurrentTextureUnit(); + static NzRecti GetCurrentViewport(); + static NzOpenGLFunc GetEntry(const NzString& entryPoint); static unsigned int GetGLSLVersion(); static NzString GetRendererName(); - static unsigned int GetTextureUnit(); static NzString GetVendorName(); static unsigned int GetVersion(); @@ -101,10 +110,13 @@ class NAZARA_API NzOpenGL static bool IsSupported(const NzString& string); static void SetBuffer(nzBufferType type, GLuint id); + static void SetScissorBox(const NzRecti& scissorBox); static void SetProgram(GLuint id); + static void SetTarget(const NzRenderTarget* renderTarget); static void SetTexture(GLuint id); static void SetTexture(unsigned int textureUnit, GLuint id); static void SetTextureUnit(unsigned int textureUnit); + static void SetViewport(const NzRecti& viewport); static bool TranslateFormat(nzPixelFormat pixelFormat, Format* format, FormatType target); diff --git a/include/Nazara/Renderer/Renderer.hpp b/include/Nazara/Renderer/Renderer.hpp index 813f5c30f..c7295c899 100644 --- a/include/Nazara/Renderer/Renderer.hpp +++ b/include/Nazara/Renderer/Renderer.hpp @@ -56,10 +56,10 @@ class NAZARA_API NzRenderer static unsigned int GetMaxVertexAttribs(); static float GetPointSize(); static const NzRenderStates& GetRenderStates(); - static NzRectui GetScissorRect(); + static NzRecti GetScissorRect(); static const NzShaderProgram* GetShaderProgram(); static const NzRenderTarget* GetTarget(); - static NzRectui GetViewport(); + static NzRecti GetViewport(); static bool HasCapability(nzRendererCap capability); @@ -81,7 +81,7 @@ class NAZARA_API NzRenderer static void SetMatrix(nzMatrixType type, const NzMatrix4f& matrix); static void SetPointSize(float size); static void SetRenderStates(const NzRenderStates& states); - static void SetScissorRect(const NzRectui& viewport); + static void SetScissorRect(const NzRecti& rect); static void SetShaderProgram(const NzShaderProgram* shader); static void SetStencilCompareFunction(nzRendererComparison compareFunc); static void SetStencilFailOperation(nzStencilOperation failOperation); @@ -93,7 +93,7 @@ class NAZARA_API NzRenderer static void SetTexture(nzUInt8 unit, const NzTexture* texture); static void SetTextureSampler(nzUInt8 textureUnit, const NzTextureSampler& sampler); static void SetVertexBuffer(const NzVertexBuffer* vertexBuffer); - static void SetViewport(const NzRectui& viewport); + static void SetViewport(const NzRecti& viewport); static void Uninitialize(); diff --git a/src/Nazara/Graphics/Camera.cpp b/src/Nazara/Graphics/Camera.cpp index 88aecc2f5..46a39a153 100644 --- a/src/Nazara/Graphics/Camera.cpp +++ b/src/Nazara/Graphics/Camera.cpp @@ -106,7 +106,7 @@ const NzMatrix4f& NzCamera::GetViewMatrix() const return m_viewMatrix; } -const NzRectui& NzCamera::GetViewport() const +const NzRecti& NzCamera::GetViewport() const { #if NAZARA_GRAPHICS_SAFE if (!m_target) @@ -164,7 +164,7 @@ void NzCamera::SetTargetRegion(const NzRectf& region) m_viewportUpdated = false; } -void NzCamera::SetViewport(const NzRectui& viewport) +void NzCamera::SetViewport(const NzRecti& viewport) { #if NAZARA_GRAPHICS_SAFE if (!m_target) @@ -250,11 +250,14 @@ bool NzCamera::OnRenderTargetSizeChange(const NzRenderTarget* renderTarget, void m_frustumUpdated = false; m_projectionMatrixUpdated = false; m_viewportUpdated = false; + + return true; } else + { NazaraInternalError("Not listening to " + NzString::Pointer(renderTarget)); - - return true; + return false; + } } void NzCamera::UpdateFrustum() const diff --git a/src/Nazara/Graphics/View.cpp b/src/Nazara/Graphics/View.cpp index ac129e313..1e1181094 100644 --- a/src/Nazara/Graphics/View.cpp +++ b/src/Nazara/Graphics/View.cpp @@ -99,7 +99,7 @@ const NzMatrix4f& NzView::GetViewMatrix() const return m_viewMatrix; } -const NzRectui& NzView::GetViewport() const +const NzRecti& NzView::GetViewport() const { #if NAZARA_GRAPHICS_SAFE if (!m_target) @@ -149,7 +149,7 @@ void NzView::SetTargetRegion(const NzRectf& region) m_viewportUpdated = false; } -void NzView::SetViewport(const NzRectui& viewport) +void NzView::SetViewport(const NzRecti& viewport) { #if NAZARA_GRAPHICS_SAFE if (!m_target) diff --git a/src/Nazara/Renderer/OpenGL.cpp b/src/Nazara/Renderer/OpenGL.cpp index ad5879ab5..88887c3cc 100644 --- a/src/Nazara/Renderer/OpenGL.cpp +++ b/src/Nazara/Renderer/OpenGL.cpp @@ -7,6 +7,7 @@ #include #include #include +#include #include #include #include @@ -66,7 +67,12 @@ namespace GLuint buffersBinding[nzBufferType_Max+1] = {0}; GLuint currentProgram = 0; GLuint texturesBinding[32] = {0}; // 32 est pour l'instant la plus haute limite (GL_TEXTURE31) + NzRecti currentScissorBox = NzRecti(0,0,0,0); + NzRecti currentViewport = NzRecti(0,0,0,0); NzRenderStates renderStates; // Toujours synchronisé avec OpenGL + const NzRenderTarget* currentTarget = nullptr; + bool scissorBoxUpdated = true; + bool viewportUpdated = true; unsigned int textureUnit = 0; }; @@ -313,6 +319,45 @@ void NzOpenGL::BindProgram(GLuint id) } } +void NzOpenGL::BindScissorBox(const NzRecti& scissorBox) +{ + #ifdef NAZARA_DEBUG + if (!s_contextStates) + { + NazaraError("No context activated"); + return; + } + #endif + + #if NAZARA_RENDERER_SAFE + if (scissorBox.width < 0) + { + NazaraError("Scissor box width must be positive"); + return; + } + + if (scissorBox.height < 0) + { + NazaraError("Scissor box height must be positive"); + return; + } + #endif + + if (s_contextStates->currentScissorBox != scissorBox) + { + if (s_contextStates->currentTarget) + { + unsigned int height = s_contextStates->currentTarget->GetHeight(); + glScissor(scissorBox.x, height - scissorBox.height - scissorBox.y, scissorBox.width, scissorBox.height); + s_contextStates->scissorBoxUpdated = true; + } + else + s_contextStates->scissorBoxUpdated = false; // Sinon on attend d'avoir un target + + s_contextStates->currentScissorBox = scissorBox; + } +} + void NzOpenGL::BindTexture(nzImageType type, GLuint id) { #ifdef NAZARA_DEBUG @@ -351,6 +396,14 @@ void NzOpenGL::BindTexture(unsigned int textureUnit, nzImageType type, GLuint id void NzOpenGL::BindTextureUnit(unsigned int textureUnit) { + #ifdef NAZARA_DEBUG + if (!s_contextStates) + { + NazaraError("No context activated"); + return; + } + #endif + if (s_contextStates->textureUnit != textureUnit) { glActiveTexture(GL_TEXTURE0 + textureUnit); @@ -358,6 +411,45 @@ void NzOpenGL::BindTextureUnit(unsigned int textureUnit) } } +void NzOpenGL::BindViewport(const NzRecti& viewport) +{ + #ifdef NAZARA_DEBUG + if (!s_contextStates) + { + NazaraError("No context activated"); + return; + } + #endif + + #if NAZARA_RENDERER_SAFE + if (viewport.width < 0) + { + NazaraError("Viewport width must be positive"); + return; + } + + if (viewport.height < 0) + { + NazaraError("Viewport height must be positive"); + return; + } + #endif + + if (s_contextStates->currentViewport != viewport) + { + if (s_contextStates->currentTarget) + { + unsigned int height = s_contextStates->currentTarget->GetHeight(); + glViewport(viewport.x, height - viewport.height - viewport.y, viewport.width, viewport.height); + s_contextStates->viewportUpdated = true; + } + else + s_contextStates->viewportUpdated = false; // Sinon on attend d'avoir un target + + s_contextStates->currentViewport = viewport; + } +} + void NzOpenGL::DeleteBuffer(nzBufferType type, GLuint id) { #ifdef NAZARA_DEBUG @@ -433,6 +525,32 @@ GLuint NzOpenGL::GetCurrentProgram() return s_contextStates->currentProgram; } +NzRecti NzOpenGL::GetCurrentScissorBox() +{ + #ifdef NAZARA_DEBUG + if (!s_contextStates) + { + NazaraError("No context activated"); + return NzRecti(); + } + #endif + + return s_contextStates->currentScissorBox; +} + +const NzRenderTarget* NzOpenGL::GetCurrentTarget() +{ + #ifdef NAZARA_DEBUG + if (!s_contextStates) + { + NazaraError("No context activated"); + return nullptr; + } + #endif + + return s_contextStates->currentTarget; +} + GLuint NzOpenGL::GetCurrentTexture() { #ifdef NAZARA_DEBUG @@ -459,6 +577,32 @@ GLuint NzOpenGL::GetCurrentTexture(unsigned int textureUnit) return s_contextStates->texturesBinding[textureUnit]; } +unsigned int NzOpenGL::GetCurrentTextureUnit() +{ + #ifdef NAZARA_DEBUG + if (!s_contextStates) + { + NazaraError("No context activated"); + return 0; + } + #endif + + return s_contextStates->textureUnit; +} + +NzRecti NzOpenGL::GetCurrentViewport() +{ + #ifdef NAZARA_DEBUG + if (!s_contextStates) + { + NazaraError("No context activated"); + return NzRecti(); + } + #endif + + return s_contextStates->currentViewport; +} + NzOpenGLFunc NzOpenGL::GetEntry(const NzString& entryPoint) { return LoadEntry(entryPoint.GetConstBuffer(), false); @@ -474,19 +618,6 @@ NzString NzOpenGL::GetRendererName() return s_rendererName; } -unsigned int NzOpenGL::GetTextureUnit() -{ - #ifdef NAZARA_DEBUG - if (!s_contextStates) - { - NazaraError("No context activated"); - return 0; - } - #endif - - return s_contextStates->textureUnit; -} - NzString NzOpenGL::GetVendorName() { return s_vendorName; @@ -1094,6 +1225,19 @@ void NzOpenGL::SetBuffer(nzBufferType type, GLuint id) s_contextStates->buffersBinding[type] = id; } +void NzOpenGL::SetScissorBox(const NzRecti& scissorBox) +{ + #ifdef NAZARA_DEBUG + if (!s_contextStates) + { + NazaraError("No context activated"); + return; + } + #endif + + s_contextStates->currentScissorBox = scissorBox; +} + void NzOpenGL::SetProgram(GLuint id) { #ifdef NAZARA_DEBUG @@ -1107,6 +1251,41 @@ void NzOpenGL::SetProgram(GLuint id) s_contextStates->currentProgram = id; } +void NzOpenGL::SetTarget(const NzRenderTarget* renderTarget) +{ + #ifdef NAZARA_DEBUG + if (!s_contextStates) + { + NazaraError("No context activated"); + return; + } + #endif + + s_contextStates->currentTarget = renderTarget; + if (renderTarget) + { + if (!s_contextStates->scissorBoxUpdated) + { + const NzRecti& scissorBox = s_contextStates->currentViewport; + + unsigned int height = s_contextStates->currentTarget->GetHeight(); + glScissor(scissorBox.x, height - scissorBox.height - scissorBox.y, scissorBox.width, scissorBox.height); + + s_contextStates->scissorBoxUpdated = true; + } + + if (!s_contextStates->viewportUpdated) + { + const NzRecti& viewport = s_contextStates->currentViewport; + + unsigned int height = s_contextStates->currentTarget->GetHeight(); + glViewport(viewport.x, height - viewport.height - viewport.y, viewport.width, viewport.height); + + s_contextStates->viewportUpdated = true; + } + } +} + void NzOpenGL::SetTexture(GLuint id) { #ifdef NAZARA_DEBUG @@ -1146,6 +1325,19 @@ void NzOpenGL::SetTextureUnit(unsigned int textureUnit) s_contextStates->textureUnit = textureUnit; } +void NzOpenGL::SetViewport(const NzRecti& viewport) +{ + #ifdef NAZARA_DEBUG + if (!s_contextStates) + { + NazaraError("No context activated"); + return; + } + #endif + + s_contextStates->currentViewport = viewport; +} + bool NzOpenGL::TranslateFormat(nzPixelFormat pixelFormat, Format* format, FormatType type) { switch (pixelFormat) diff --git a/src/Nazara/Renderer/RenderWindow.cpp b/src/Nazara/Renderer/RenderWindow.cpp index 85a8cd882..9fa419d06 100644 --- a/src/Nazara/Renderer/RenderWindow.cpp +++ b/src/Nazara/Renderer/RenderWindow.cpp @@ -289,11 +289,18 @@ bool NzRenderWindow::OnWindowCreated() return false; } - EnableVerticalSync(false); - if (!SetActive(true)) // Les fenêtres s'activent à la création NazaraWarning("Failed to activate window"); + EnableVerticalSync(false); + + NzVector2ui size = GetSize(); + + // Le scissorBox/viewport (à la création) est de la taille de la fenêtre + // https://www.opengl.org/sdk/docs/man/xhtml/glGet.xml + NzOpenGL::SetScissorBox(NzRecti(0, 0, size.x, size.y)); + NzOpenGL::SetViewport(NzRecti(0, 0, size.x, size.y)); + NotifyParametersChange(); NotifySizeChange(); diff --git a/src/Nazara/Renderer/Renderer.cpp b/src/Nazara/Renderer/Renderer.cpp index c49abd2c3..9582dab49 100644 --- a/src/Nazara/Renderer/Renderer.cpp +++ b/src/Nazara/Renderer/Renderer.cpp @@ -549,20 +549,9 @@ const NzRenderStates& NzRenderer::GetRenderStates() return s_states; } -NzRectui NzRenderer::GetScissorRect() +NzRecti NzRenderer::GetScissorRect() { - #ifdef NAZARA_DEBUG - if (NzContext::GetCurrent() == nullptr) - { - NazaraError("No active context"); - return NzRectui(); - } - #endif - - GLint params[4]; - glGetIntegerv(GL_SCISSOR_BOX, ¶ms[0]); - - return NzRectui(params[0], params[1], params[2], params[3]); + return NzOpenGL::GetCurrentScissorBox(); } const NzShaderProgram* NzRenderer::GetShaderProgram() @@ -575,20 +564,9 @@ const NzRenderTarget* NzRenderer::GetTarget() return s_target; } -NzRectui NzRenderer::GetViewport() +NzRecti NzRenderer::GetViewport() { - #ifdef NAZARA_DEBUG - if (NzContext::GetCurrent() == nullptr) - { - NazaraError("No active context"); - return NzRectui(); - } - #endif - - GLint params[4]; - glGetIntegerv(GL_VIEWPORT, ¶ms[0]); - - return NzRectui(params[0], params[1], params[2], params[3]); + return NzOpenGL::GetCurrentViewport(); } bool NzRenderer::HasCapability(nzRendererCap capability) @@ -985,34 +963,9 @@ void NzRenderer::SetRenderStates(const NzRenderStates& states) s_states = states; } -void NzRenderer::SetScissorRect(const NzRectui& rect) +void NzRenderer::SetScissorRect(const NzRecti& rect) { - #ifdef NAZARA_DEBUG - if (NzContext::GetCurrent() == nullptr) - { - NazaraError("No active context"); - return; - } - #endif - - unsigned int height = s_target->GetHeight(); - - #if NAZARA_RENDERER_SAFE - if (!s_target) - { - NazaraError("Renderer has no target"); - return; - } - - unsigned int width = s_target->GetWidth(); - if (rect.x+rect.width > width || rect.y+rect.height > height) - { - NazaraError("Rectangle dimensions are out of bounds"); - return; - } - #endif - - glScissor(rect.x, height-rect.height-rect.y, rect.width, rect.height); + NzOpenGL::BindScissorBox(rect); } void NzRenderer::SetShaderProgram(const NzShaderProgram* program) @@ -1129,6 +1082,8 @@ bool NzRenderer::SetTarget(const NzRenderTarget* target) s_uniformTargetSizeUpdated = false; } + NzOpenGL::SetTarget(s_target); + return true; } @@ -1195,35 +1150,9 @@ void NzRenderer::SetVertexBuffer(const NzVertexBuffer* vertexBuffer) } } -void NzRenderer::SetViewport(const NzRectui& viewport) +void NzRenderer::SetViewport(const NzRecti& viewport) { - #ifdef NAZARA_DEBUG - if (NzContext::GetCurrent() == nullptr) - { - NazaraError("No active context"); - return; - } - #endif - - unsigned int height = s_target->GetHeight(); - - #if NAZARA_RENDERER_SAFE - if (!s_target) - { - NazaraError("Renderer has no target"); - return; - } - - unsigned int width = s_target->GetWidth(); - if (viewport.x+viewport.width > width || viewport.y+viewport.height > height) - { - NazaraError("Rectangle dimensions are out of bounds (" + NzString::Number(viewport.x+viewport.width) + ", " + NzString::Number(viewport.y+viewport.height) + " > " - + NzString::Number(width) + ", " + NzString::Number(height) + ")"); - return; - } - #endif - - glViewport(viewport.x, height-viewport.height-viewport.y, viewport.width, viewport.height); + NzOpenGL::BindViewport(viewport); } void NzRenderer::Uninitialize()