From 9bf66e7e160377a1bd1147658a5a2d91a07e7c27 Mon Sep 17 00:00:00 2001 From: Lynix Date: Sat, 11 Jan 2014 19:10:19 +0100 Subject: [PATCH] Added RenderTexture::Blit Added RenderTexture::GetSize Former-commit-id: f385ccc39a2051765db9befa3b77f75b17529447 --- include/Nazara/Renderer/OpenGL.hpp | 1 + include/Nazara/Renderer/RenderTexture.hpp | 3 + src/Nazara/Renderer/OpenGL.cpp | 2 + src/Nazara/Renderer/RenderTexture.cpp | 94 +++++++++++++++++++++++ 4 files changed, 100 insertions(+) diff --git a/include/Nazara/Renderer/OpenGL.hpp b/include/Nazara/Renderer/OpenGL.hpp index db1623aeb..8dc9f9db4 100644 --- a/include/Nazara/Renderer/OpenGL.hpp +++ b/include/Nazara/Renderer/OpenGL.hpp @@ -165,6 +165,7 @@ NAZARA_API extern PFNGLBINDTEXTUREPROC glBindTexture; NAZARA_API extern PFNGLBINDVERTEXARRAYPROC glBindVertexArray; NAZARA_API extern PFNGLBLENDFUNCPROC glBlendFunc; NAZARA_API extern PFNGLBLENDFUNCSEPARATEPROC glBlendFuncSeparate; +NAZARA_API extern PFNGLBLITFRAMEBUFFERPROC glBlitFramebuffer; NAZARA_API extern PFNGLBUFFERDATAPROC glBufferData; NAZARA_API extern PFNGLBUFFERSUBDATAPROC glBufferSubData; NAZARA_API extern PFNGLCLEARPROC glClear; diff --git a/include/Nazara/Renderer/RenderTexture.hpp b/include/Nazara/Renderer/RenderTexture.hpp index ac4563ef2..ec83166ba 100644 --- a/include/Nazara/Renderer/RenderTexture.hpp +++ b/include/Nazara/Renderer/RenderTexture.hpp @@ -37,6 +37,7 @@ class NAZARA_API NzRenderTexture : public NzRenderTarget, NzResourceListener, Nz unsigned int GetHeight() const; NzRenderTargetParameters GetParameters() const; + NzVector2ui GetSize() const; unsigned int GetWidth() const; bool IsComplete() const; @@ -55,6 +56,8 @@ class NAZARA_API NzRenderTexture : public NzRenderTarget, NzResourceListener, Nz unsigned int GetOpenGLID() const; bool HasContext() const override; + static void Blit(NzRenderTexture* src, NzRenderTexture* dst, nzUInt32 buffers = nzRendererBuffer_Color | nzRendererBuffer_Depth | nzRendererBuffer_Stencil, bool bilinearFilter = false); + static void Blit(NzRenderTexture* src, NzRectui srcRect, NzRenderTexture* dst, NzRectui dstRect, nzUInt32 buffers = nzRendererBuffer_Color | nzRendererBuffer_Depth | nzRendererBuffer_Stencil, bool bilinearFilter = false); static bool IsSupported(); protected: diff --git a/src/Nazara/Renderer/OpenGL.cpp b/src/Nazara/Renderer/OpenGL.cpp index 72b616f75..815107c1d 100644 --- a/src/Nazara/Renderer/OpenGL.cpp +++ b/src/Nazara/Renderer/OpenGL.cpp @@ -1057,6 +1057,7 @@ bool NzOpenGL::Initialize() { glBindFramebuffer = reinterpret_cast(LoadEntry("glBindFramebuffer")); glBindRenderbuffer = reinterpret_cast(LoadEntry("glBindRenderbuffer")); + glBlitFramebuffer = reinterpret_cast(LoadEntry("glBlitFramebuffer")); glCheckFramebufferStatus = reinterpret_cast(LoadEntry("glCheckFramebufferStatus")); glDeleteFramebuffers = reinterpret_cast(LoadEntry("glDeleteFramebuffers")); glDeleteRenderbuffers = reinterpret_cast(LoadEntry("glDeleteRenderbuffers")); @@ -2035,6 +2036,7 @@ PFNGLBINDTEXTUREPROC glBindTexture = nullptr; PFNGLBINDVERTEXARRAYPROC glBindVertexArray = nullptr; PFNGLBLENDFUNCPROC glBlendFunc = nullptr; PFNGLBLENDFUNCSEPARATEPROC glBlendFuncSeparate = nullptr; +PFNGLBLITFRAMEBUFFERPROC glBlitFramebuffer = nullptr; PFNGLBUFFERDATAPROC glBufferData = nullptr; PFNGLBUFFERSUBDATAPROC glBufferSubData = nullptr; PFNGLCLEARPROC glClear = nullptr; diff --git a/src/Nazara/Renderer/RenderTexture.cpp b/src/Nazara/Renderer/RenderTexture.cpp index 558fb195d..0b18936f2 100644 --- a/src/Nazara/Renderer/RenderTexture.cpp +++ b/src/Nazara/Renderer/RenderTexture.cpp @@ -486,6 +486,22 @@ NzRenderTargetParameters NzRenderTexture::GetParameters() const return NzRenderTargetParameters(); } +NzVector2ui NzRenderTexture::GetSize() const +{ + #if NAZARA_RENDERER_SAFE + if (!m_impl) + { + NazaraError("Render texture not created"); + return 0; + } + #endif + + if (!m_impl->targetsUpdated) + UpdateTargets(); + + return NzVector2ui(m_impl->width, m_impl->height); +} + unsigned int NzRenderTexture::GetWidth() const { #if NAZARA_RENDERER_SAFE @@ -728,6 +744,84 @@ bool NzRenderTexture::IsSupported() return NzOpenGL::IsSupported(nzOpenGLExtension_FrameBufferObject); } +void NzRenderTexture::Blit(NzRenderTexture* src, NzRenderTexture* dst, nzUInt32 buffers, bool bilinearFilter) +{ + #if NAZARA_RENDERER_SAFE + if (!src) + { + NazaraError("Invalid source render texture"); + return; + } + + if (!dst) + { + NazaraError("Invalid source render texture"); + return; + } + #endif + + Blit(src, src->GetSize(), dst, dst->GetSize(), buffers, bilinearFilter); +} + +void NzRenderTexture::Blit(NzRenderTexture* src, NzRectui srcRect, NzRenderTexture* dst, NzRectui dstRect, nzUInt32 buffers, bool bilinearFilter) +{ + #if NAZARA_RENDERER_SAFE + if (!src || !src->IsValid()) + { + NazaraError("Invalid source render texture"); + return; + } + + if (srcRect.x+srcRect.width > src->GetWidth() || srcRect.y+srcRect.height > src->GetHeight()) + { + NazaraError("Source rectangle dimensions are out of bounds"); + return; + } + + if (!dst || !dst->IsValid()) + { + NazaraError("Invalid source render texture"); + return; + } + + if (dstRect.x+dstRect.width > dst->GetWidth() || dstRect.y+dstRect.height > dst->GetHeight()) + { + NazaraError("Destination rectangle dimensions are out of bounds"); + return; + } + + if (bilinearFilter && (buffers & nzRendererBuffer_Depth || buffers & nzRendererBuffer_Stencil)) + { + NazaraError("Filter cannot be bilinear when blitting depth/stencil buffers"); + return; + } + #endif + + GLbitfield mask = 0; + if (buffers & nzRendererBuffer_Color) + mask |= GL_COLOR_BUFFER_BIT; + + if (buffers & nzRendererBuffer_Depth) + mask |= GL_DEPTH_BUFFER_BIT; + + if (buffers & nzRendererBuffer_Stencil) + mask |= GL_STENCIL_BUFFER_BIT; + + GLint previousDrawBuffer, previousReadBuffer; + glGetIntegerv(GL_DRAW_FRAMEBUFFER_BINDING, &previousDrawBuffer); + glGetIntegerv(GL_READ_FRAMEBUFFER_BINDING, &previousReadBuffer); + + glBindFramebuffer(GL_DRAW_FRAMEBUFFER, dst->GetOpenGLID()); + glBindFramebuffer(GL_READ_FRAMEBUFFER, src->GetOpenGLID()); + + glBlitFramebuffer(srcRect.x, srcRect.y, srcRect.x + srcRect.width, srcRect.y + srcRect.height, + dstRect.x, dstRect.y, dstRect.x + dstRect.width, dstRect.y + dstRect.height, + mask, (bilinearFilter) ? GL_LINEAR : GL_NEAREST); + + glBindFramebuffer(GL_DRAW_FRAMEBUFFER, previousDrawBuffer); + glBindFramebuffer(GL_READ_FRAMEBUFFER, previousReadBuffer); +} + bool NzRenderTexture::Activate() const { #if NAZARA_RENDERER_SAFE