diff --git a/libraries/gpu/src/gpu/Batch.cpp b/libraries/gpu/src/gpu/Batch.cpp index 5fbac3bc6c..68a6a2d6f5 100644 --- a/libraries/gpu/src/gpu/Batch.cpp +++ b/libraries/gpu/src/gpu/Batch.cpp @@ -102,9 +102,10 @@ void Batch::drawIndexedInstanced(uint32 nbInstances, Primitive primitiveType, ui _params.push_back(nbInstances); } -void Batch::clearFramebuffer(Framebuffer::Masks targets, const Vec4& color, float depth, int stencil) { +void Batch::clearFramebuffer(Framebuffer::Masks targets, const Vec4& color, float depth, int stencil, bool enableScissor) { ADD_COMMAND(clearFramebuffer); + _params.push_back(enableScissor); _params.push_back(stencil); _params.push_back(depth); _params.push_back(color.w); @@ -114,20 +115,20 @@ void Batch::clearFramebuffer(Framebuffer::Masks targets, const Vec4& color, floa _params.push_back(targets); } -void Batch::clearColorFramebuffer(Framebuffer::Masks targets, const Vec4& color) { - clearFramebuffer(targets & Framebuffer::BUFFER_COLORS, color, 1.0f, 0); +void Batch::clearColorFramebuffer(Framebuffer::Masks targets, const Vec4& color, bool enableScissor) { + clearFramebuffer(targets & Framebuffer::BUFFER_COLORS, color, 1.0f, 0, enableScissor); } -void Batch::clearDepthFramebuffer(float depth) { - clearFramebuffer(Framebuffer::BUFFER_DEPTH, Vec4(0.0f), depth, 0); +void Batch::clearDepthFramebuffer(float depth, bool enableScissor) { + clearFramebuffer(Framebuffer::BUFFER_DEPTH, Vec4(0.0f), depth, 0, enableScissor); } -void Batch::clearStencilFramebuffer(int stencil) { - clearFramebuffer(Framebuffer::BUFFER_STENCIL, Vec4(0.0f), 1.0f, stencil); +void Batch::clearStencilFramebuffer(int stencil, bool enableScissor) { + clearFramebuffer(Framebuffer::BUFFER_STENCIL, Vec4(0.0f), 1.0f, stencil, enableScissor); } -void Batch::clearDepthStencilFramebuffer(float depth, int stencil) { - clearFramebuffer(Framebuffer::BUFFER_DEPTHSTENCIL, Vec4(0.0f), depth, stencil); +void Batch::clearDepthStencilFramebuffer(float depth, int stencil, bool enableScissor) { + clearFramebuffer(Framebuffer::BUFFER_DEPTHSTENCIL, Vec4(0.0f), depth, stencil, enableScissor); } diff --git a/libraries/gpu/src/gpu/Batch.h b/libraries/gpu/src/gpu/Batch.h index bf6883e3a9..f202186963 100644 --- a/libraries/gpu/src/gpu/Batch.h +++ b/libraries/gpu/src/gpu/Batch.h @@ -62,11 +62,12 @@ public: // Clear framebuffer layers // Targets can be any of the render buffers contained in the Framebuffer - void clearFramebuffer(Framebuffer::Masks targets, const Vec4& color, float depth, int stencil); - void clearColorFramebuffer(Framebuffer::Masks targets, const Vec4& color); // not a command, just a shortcut for clearFramebuffer, mask out targets to make sure it touches only color targets - void clearDepthFramebuffer(float depth); // not a command, just a shortcut for clearFramebuffer, it touches only depth target - void clearStencilFramebuffer(int stencil); // not a command, just a shortcut for clearFramebuffer, it touches only stencil target - void clearDepthStencilFramebuffer(float depth, int stencil); // not a command, just a shortcut for clearFramebuffer, it touches depth and stencil target + // Optionally the scissor test can be enabled locally for this command and to restrict the clearing command to the pixels contained in the scissor rectangle + void clearFramebuffer(Framebuffer::Masks targets, const Vec4& color, float depth, int stencil, bool enableScissor = false); + void clearColorFramebuffer(Framebuffer::Masks targets, const Vec4& color, bool enableScissor = false); // not a command, just a shortcut for clearFramebuffer, mask out targets to make sure it touches only color targets + void clearDepthFramebuffer(float depth, bool enableScissor = false); // not a command, just a shortcut for clearFramebuffer, it touches only depth target + void clearStencilFramebuffer(int stencil, bool enableScissor = false); // not a command, just a shortcut for clearFramebuffer, it touches only stencil target + void clearDepthStencilFramebuffer(float depth, int stencil, bool enableScissor = false); // not a command, just a shortcut for clearFramebuffer, it touches depth and stencil target // Input Stage // InputFormat @@ -90,13 +91,18 @@ public: void setModelTransform(const Transform& model); void setViewTransform(const Transform& view); void setProjectionTransform(const Mat4& proj); - void setViewportTransform(const Vec4i& viewport); // Viewport is xy = low left corner in the framebuffer, zw = width height of the viewport + // Viewport is xy = low left corner in framebuffer, zw = width height of the viewport, expressed in pixels + void setViewportTransform(const Vec4i& viewport); // Pipeline Stage void setPipeline(const PipelinePointer& pipeline); void setStateBlendFactor(const Vec4& factor); + // Set the Scissor rect + // the rect coordinates are xy for the low left corner of the rect and zw for the width and height of the rect, expressed in pixels + void setStateScissorRect(const Vec4i& rect); + void setUniformBuffer(uint32 slot, const BufferPointer& buffer, Offset offset, Offset size); void setUniformBuffer(uint32 slot, const BufferView& view); // not a command, just a shortcut from a BufferView @@ -173,6 +179,7 @@ public: COMMAND_setPipeline, COMMAND_setStateBlendFactor, + COMMAND_setStateScissorRect, COMMAND_setUniformBuffer, COMMAND_setResourceTexture, diff --git a/libraries/gpu/src/gpu/GLBackend.cpp b/libraries/gpu/src/gpu/GLBackend.cpp index adbef7cb31..1cabba2ebf 100644 --- a/libraries/gpu/src/gpu/GLBackend.cpp +++ b/libraries/gpu/src/gpu/GLBackend.cpp @@ -33,6 +33,7 @@ GLBackend::CommandCall GLBackend::_commandCalls[Batch::NUM_COMMANDS] = (&::gpu::GLBackend::do_setPipeline), (&::gpu::GLBackend::do_setStateBlendFactor), + (&::gpu::GLBackend::do_setStateScissorRect), (&::gpu::GLBackend::do_setUniformBuffer), (&::gpu::GLBackend::do_setResourceTexture), @@ -217,14 +218,15 @@ void GLBackend::do_drawIndexedInstanced(Batch& batch, uint32 paramOffset) { void GLBackend::do_clearFramebuffer(Batch& batch, uint32 paramOffset) { - uint32 masks = batch._params[paramOffset + 6]._uint; + uint32 masks = batch._params[paramOffset + 7]._uint; Vec4 color; - color.x = batch._params[paramOffset + 5]._float; - color.y = batch._params[paramOffset + 4]._float; - color.z = batch._params[paramOffset + 3]._float; - color.w = batch._params[paramOffset + 2]._float; - float depth = batch._params[paramOffset + 1]._float; - int stencil = batch._params[paramOffset + 0]._float; + color.x = batch._params[paramOffset + 6]._float; + color.y = batch._params[paramOffset + 5]._float; + color.z = batch._params[paramOffset + 4]._float; + color.w = batch._params[paramOffset + 3]._float; + float depth = batch._params[paramOffset + 2]._float; + int stencil = batch._params[paramOffset + 1]._int; + int useScissor = batch._params[paramOffset + 0]._int; GLuint glmask = 0; if (masks & Framebuffer::BUFFER_DEPTH) { @@ -252,8 +254,19 @@ void GLBackend::do_clearFramebuffer(Batch& batch, uint32 paramOffset) { } } + // Apply scissor if needed and if not already on + bool doEnableScissor = (useScissor && (!_pipeline._stateCache.scissorEnable)); + if (doEnableScissor) { + glEnable(GL_SCISSOR_TEST); + } + glClear(glmask); + // Restore scissor if needed + if (doEnableScissor) { + glDisable(GL_SCISSOR_TEST); + } + // Restore the color draw buffers only if a frmaebuffer is bound if (_output._framebuffer && !drawBuffers.empty()) { auto glFramebuffer = syncGPUObject(*_output._framebuffer); diff --git a/libraries/gpu/src/gpu/GLBackend.h b/libraries/gpu/src/gpu/GLBackend.h index 491897b281..aedf058c82 100644 --- a/libraries/gpu/src/gpu/GLBackend.h +++ b/libraries/gpu/src/gpu/GLBackend.h @@ -350,6 +350,7 @@ protected: // Pipeline Stage void do_setPipeline(Batch& batch, uint32 paramOffset); void do_setStateBlendFactor(Batch& batch, uint32 paramOffset); + void do_setStateScissorRect(Batch& batch, uint32 paramOffset); // Standard update pipeline check that the current Program and current State or good to go for a void updatePipeline(); diff --git a/libraries/gpu/src/gpu/GLBackendState.cpp b/libraries/gpu/src/gpu/GLBackendState.cpp index e898a29245..787fb35a4b 100644 --- a/libraries/gpu/src/gpu/GLBackendState.cpp +++ b/libraries/gpu/src/gpu/GLBackendState.cpp @@ -753,3 +753,14 @@ void GLBackend::do_setStateBlendFactor(Batch& batch, uint32 paramOffset) { glBlendColor(factor.x, factor.y, factor.z, factor.w); (void) CHECK_GL_ERROR(); } + +void GLBackend::do_setStateScissorRect(Batch& batch, uint32 paramOffset) { + + Vec4 rect(batch._params[paramOffset + 0]._float, + batch._params[paramOffset + 1]._float, + batch._params[paramOffset + 2]._float, + batch._params[paramOffset + 3]._float); + + glScissor(rect.x, rect.y, rect.z, rect.w); + (void) CHECK_GL_ERROR(); +}