diff --git a/src/bgfx_p.h b/src/bgfx_p.h index b62a904d0..8a09de5bf 100755 --- a/src/bgfx_p.h +++ b/src/bgfx_p.h @@ -182,6 +182,18 @@ namespace bgfx return UINT64_C(0) == ui64; } + void intersect(const Rect& _a, const Rect& _b) + { + const uint16_t sx = uint16_max(_a.m_x, _b.m_x); + const uint16_t sy = uint16_max(_a.m_y, _b.m_y); + const uint16_t ex = uint16_min(_a.m_x + _a.m_width, _b.m_x + _b.m_width ); + const uint16_t ey = uint16_min(_a.m_y + _a.m_height, _b.m_y + _b.m_height); + m_x = sx; + m_y = sy; + m_width = ex - sx; + m_height = ey - sy; + } + uint16_t m_x; uint16_t m_y; uint16_t m_width; diff --git a/src/renderer_d3d11.cpp b/src/renderer_d3d11.cpp index e6c1592f2..f669e8d83 100644 --- a/src/renderer_d3d11.cpp +++ b/src/renderer_d3d11.cpp @@ -2325,6 +2325,8 @@ namespace bgfx D3D11_PRIMITIVE_TOPOLOGY primType = D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST; deviceCtx->IASetPrimitiveTopology(primType); uint32_t primNumVerts = 3; + bool viewHasScissor = false; + Rect viewScissorRect; uint32_t statsNumPrimsSubmitted = 0; uint32_t statsNumIndices = 0; @@ -2367,7 +2369,10 @@ namespace bgfx s_renderCtx.setRenderTarget(rt); } - Rect& rect = m_render->m_rect[view]; + const Rect& rect = m_render->m_rect[view]; + const Rect& scissorRect = m_render->m_scissor[view]; + viewHasScissor = !scissorRect.isZero(); + viewScissorRect = viewHasScissor ? scissorRect : rect; D3D11_VIEWPORT vp; vp.TopLeftX = rect.m_x; @@ -2403,21 +2408,21 @@ namespace bgfx if (UINT16_MAX == scissor) { - const Rect& scissorRect = m_render->m_scissor[view]; - scissorEnabled = !scissorRect.isZero(); - if (scissorEnabled) + scissorEnabled = viewHasScissor; + if (viewHasScissor) { D3D11_RECT rc; - rc.left = scissorRect.m_x; - rc.top = scissorRect.m_y; - rc.right = scissorRect.m_x + scissorRect.m_width; - rc.bottom = scissorRect.m_y + scissorRect.m_height; + rc.left = viewScissorRect.m_x; + rc.top = viewScissorRect.m_y; + rc.right = viewScissorRect.m_x + viewScissorRect.m_width; + rc.bottom = viewScissorRect.m_y + viewScissorRect.m_height; deviceCtx->RSSetScissorRects(1, &rc); } } else { - const Rect& scissorRect = m_render->m_rectCache.m_cache[scissor]; + Rect scissorRect; + scissorRect.intersect(viewScissorRect, m_render->m_rectCache.m_cache[scissor]); scissorEnabled = true; D3D11_RECT rc; rc.left = scissorRect.m_x; diff --git a/src/renderer_d3d9.cpp b/src/renderer_d3d9.cpp index 6a886b940..56ff27663 100644 --- a/src/renderer_d3d9.cpp +++ b/src/renderer_d3d9.cpp @@ -2261,6 +2261,8 @@ namespace bgfx uint32_t blendFactor = 0; D3DPRIMITIVETYPE primType = D3DPT_TRIANGLELIST; uint32_t primNumVerts = 3; + bool viewHasScissor = false; + Rect viewScissorRect; uint32_t statsNumPrimsSubmitted = 0; uint32_t statsNumIndices = 0; @@ -2305,7 +2307,11 @@ namespace bgfx s_renderCtx.setRenderTarget(rt); } - Rect& rect = m_render->m_rect[view]; + const Rect& rect = m_render->m_rect[view]; + const Rect& scissorRect = m_render->m_scissor[view]; + viewHasScissor = !scissorRect.isZero(); + viewScissorRect = viewHasScissor ? scissorRect : rect; + D3DVIEWPORT9 vp; vp.X = rect.m_x; vp.Y = rect.m_y; @@ -2370,23 +2376,22 @@ namespace bgfx if (UINT16_MAX == scissor) { - const Rect& scissorRect = m_render->m_scissor[view]; - bool scissorEnabled = !scissorRect.isZero(); - DX_CHECK(device->SetRenderState(D3DRS_SCISSORTESTENABLE, scissorEnabled) ); - if (scissorEnabled) + DX_CHECK(device->SetRenderState(D3DRS_SCISSORTESTENABLE, viewHasScissor) ); + if (viewHasScissor) { RECT rc; - rc.left = scissorRect.m_x; - rc.top = scissorRect.m_y; - rc.right = scissorRect.m_x + scissorRect.m_width; - rc.bottom = scissorRect.m_y + scissorRect.m_height; + rc.left = viewScissorRect.m_x; + rc.top = viewScissorRect.m_y; + rc.right = viewScissorRect.m_x + viewScissorRect.m_width; + rc.bottom = viewScissorRect.m_y + viewScissorRect.m_height; DX_CHECK(device->SetScissorRect(&rc) ); } } else { + Rect scissorRect; + scissorRect.intersect(viewScissorRect, m_render->m_rectCache.m_cache[scissor]); DX_CHECK(device->SetRenderState(D3DRS_SCISSORTESTENABLE, true) ); - const Rect& scissorRect = m_render->m_rectCache.m_cache[scissor]; RECT rc; rc.left = scissorRect.m_x; rc.top = scissorRect.m_y; diff --git a/src/renderer_gl.cpp b/src/renderer_gl.cpp index d0c11af11..72e7902a3 100644 --- a/src/renderer_gl.cpp +++ b/src/renderer_gl.cpp @@ -2819,6 +2819,8 @@ namespace bgfx uint32_t primNumVerts = 3; uint32_t baseVertex = 0; GLuint currentVao = 0; + bool viewHasScissor = false; + Rect viewScissorRect; uint32_t statsNumPrimsSubmitted = 0; uint32_t statsNumIndices = 0; @@ -2862,7 +2864,10 @@ namespace bgfx height = s_renderCtx.setRenderTarget(rt, m_render->m_resolution.m_height); } - Rect& rect = m_render->m_rect[view]; + const Rect& rect = m_render->m_rect[view]; + const Rect& scissorRect = m_render->m_scissor[view]; + viewHasScissor = !scissorRect.isZero(); + viewScissorRect = viewHasScissor ? scissorRect : rect; GL_CHECK(glViewport(rect.m_x, height-rect.m_height-rect.m_y, rect.m_width, rect.m_height) ); @@ -2887,12 +2892,10 @@ namespace bgfx if (UINT16_MAX == scissor) { - const Rect& scissorRect = m_render->m_scissor[view]; - bool scissor = !scissorRect.isZero(); - if (scissor) + if (viewHasScissor) { GL_CHECK(glEnable(GL_SCISSOR_TEST) ); - GL_CHECK(glScissor(scissorRect.m_x, height-scissorRect.m_height-scissorRect.m_y, scissorRect.m_width, scissorRect.m_height) ); + GL_CHECK(glScissor(viewScissorRect.m_x, height-viewScissorRect.m_height-viewScissorRect.m_y, viewScissorRect.m_width, viewScissorRect.m_height) ); } else { @@ -2901,7 +2904,8 @@ namespace bgfx } else { - const Rect& scissorRect = m_render->m_rectCache.m_cache[scissor]; + Rect scissorRect; + scissorRect.intersect(viewScissorRect, m_render->m_rectCache.m_cache[scissor]); GL_CHECK(glEnable(GL_SCISSOR_TEST) ); GL_CHECK(glScissor(scissorRect.m_x, height-scissorRect.m_height-scissorRect.m_y, scissorRect.m_width, scissorRect.m_height) ); }