Added support for per primitive scissor.
This commit is contained in:
parent
a1e226cb5b
commit
bac2073b76
7 changed files with 151 additions and 48 deletions
examples/common/imgui
include
src
|
@ -130,6 +130,7 @@ struct Imgui
|
|||
, m_insideCurrentScroll(false)
|
||||
, m_areaId(0)
|
||||
, m_widgetId(0)
|
||||
, m_scissor(UINT16_MAX)
|
||||
, m_scrollTop(0)
|
||||
, m_scrollBottom(0)
|
||||
, m_scrollRight(0)
|
||||
|
@ -403,7 +404,7 @@ struct Imgui
|
|||
, imguiRGBA(255, 255, 255, 128)
|
||||
);
|
||||
|
||||
// setScissor(_x + SCROLL_AREA_PADDING, _y + SCROLL_AREA_PADDING, _width - SCROLL_AREA_PADDING * 4, _height - AREA_HEADER - SCROLL_AREA_PADDING);
|
||||
m_scissor = bgfx::setScissor(_x + SCROLL_AREA_PADDING, _y + SCROLL_AREA_PADDING, _width - SCROLL_AREA_PADDING * 4, _height - AREA_HEADER - SCROLL_AREA_PADDING);
|
||||
|
||||
return m_insideScrollArea;
|
||||
}
|
||||
|
@ -411,7 +412,7 @@ struct Imgui
|
|||
void endScrollArea()
|
||||
{
|
||||
// Disable scissoring.
|
||||
// setScissor(-1, -1, -1, -1);
|
||||
m_scissor = UINT16_MAX;
|
||||
|
||||
// Draw scroll bar
|
||||
int32_t xx = m_scrollRight + SCROLL_AREA_PADDING / 2;
|
||||
|
@ -1066,6 +1067,7 @@ struct Imgui
|
|||
| BGFX_STATE_BLEND_FUNC(BGFX_STATE_BLEND_SRC_ALPHA, BGFX_STATE_BLEND_INV_SRC_ALPHA)
|
||||
);
|
||||
bgfx::setProgram(m_colorProgram);
|
||||
bgfx::setScissor(m_scissor);
|
||||
bgfx::submit(m_view);
|
||||
}
|
||||
}
|
||||
|
@ -1354,6 +1356,7 @@ struct Imgui
|
|||
| BGFX_STATE_BLEND_FUNC(BGFX_STATE_BLEND_SRC_ALPHA, BGFX_STATE_BLEND_INV_SRC_ALPHA)
|
||||
);
|
||||
bgfx::setProgram(m_textureProgram);
|
||||
bgfx::setScissor(m_scissor);
|
||||
bgfx::submit(m_view);
|
||||
}
|
||||
}
|
||||
|
@ -1380,6 +1383,7 @@ struct Imgui
|
|||
|
||||
uint32_t m_areaId;
|
||||
uint32_t m_widgetId;
|
||||
uint16_t m_scissor;
|
||||
|
||||
float m_tempCoords[MAX_TEMP_COORDS * 2];
|
||||
float m_tempNormals[MAX_TEMP_COORDS * 2];
|
||||
|
|
|
@ -853,9 +853,10 @@ namespace bgfx
|
|||
|
||||
/// Set scissor from cache for draw primitive.
|
||||
///
|
||||
/// @param _cache Index in scissor cache.
|
||||
/// @param _cache Index in scissor cache. Passing UINT16_MAX unset primitive
|
||||
/// scissor and primitive will use view scissor instead.
|
||||
///
|
||||
void setScissor(uint16_t _cache);
|
||||
void setScissor(uint16_t _cache = UINT16_MAX);
|
||||
|
||||
/// Set model matrix for draw primitive. If it is not called model will
|
||||
/// be rendered with identity model matrix.
|
||||
|
|
42
src/bgfx_p.h
42
src/bgfx_p.h
|
@ -651,6 +651,38 @@ namespace bgfx
|
|||
uint32_t m_num;
|
||||
};
|
||||
|
||||
struct RectCache
|
||||
{
|
||||
RectCache()
|
||||
: m_num(0)
|
||||
{
|
||||
}
|
||||
|
||||
void reset()
|
||||
{
|
||||
m_num = 0;
|
||||
}
|
||||
|
||||
uint32_t add(uint16_t _x, uint16_t _y, uint16_t _width, uint16_t _height)
|
||||
{
|
||||
BX_CHECK(m_num+1 < BGFX_CONFIG_MAX_RECT_CACHE, "Rect cache overflow. %d (max: %d)", m_num, BGFX_CONFIG_MAX_RECT_CACHE);
|
||||
|
||||
uint32_t first = m_num;
|
||||
Rect& rect = m_cache[m_num];
|
||||
|
||||
rect.m_x = _x;
|
||||
rect.m_y = _y;
|
||||
rect.m_width = _width;
|
||||
rect.m_height = _height;
|
||||
|
||||
m_num++;
|
||||
return first;
|
||||
}
|
||||
|
||||
Rect m_cache[BGFX_CONFIG_MAX_RECT_CACHE];
|
||||
uint32_t m_num;
|
||||
};
|
||||
|
||||
struct Sampler
|
||||
{
|
||||
uint32_t m_flags;
|
||||
|
@ -860,7 +892,7 @@ namespace bgfx
|
|||
m_instanceDataStride = 0;
|
||||
m_numInstances = 1;
|
||||
m_num = 1;
|
||||
m_scissor = 0;
|
||||
m_scissor = UINT16_MAX;
|
||||
m_vertexBuffer.idx = invalidHandle;
|
||||
m_vertexDecl.idx = invalidHandle;
|
||||
m_indexBuffer.idx = invalidHandle;
|
||||
|
@ -958,6 +990,7 @@ namespace bgfx
|
|||
{
|
||||
m_state.reset();
|
||||
m_matrixCache.reset();
|
||||
m_rectCache.reset();
|
||||
m_key.reset();
|
||||
m_num = 0;
|
||||
m_numRenderStates = 0;
|
||||
|
@ -1008,9 +1041,9 @@ namespace bgfx
|
|||
|
||||
uint16_t setScissor(uint16_t _x, uint16_t _y, uint16_t _width, uint16_t _height)
|
||||
{
|
||||
BX_UNUSED(_x, _y, _width, _height);
|
||||
m_state.m_scissor = 0;
|
||||
return 0;
|
||||
uint16_t scissor = m_rectCache.add(_x, _y, _width, _height);
|
||||
m_state.m_scissor = scissor;
|
||||
return scissor;
|
||||
}
|
||||
|
||||
void setScissor(uint16_t _cache)
|
||||
|
@ -1256,6 +1289,7 @@ namespace bgfx
|
|||
uint16_t m_numDropped;
|
||||
|
||||
MatrixCache m_matrixCache;
|
||||
RectCache m_rectCache;
|
||||
|
||||
uint32_t m_iboffset;
|
||||
uint32_t m_vboffset;
|
||||
|
|
|
@ -127,6 +127,10 @@
|
|||
# define BGFX_CONFIG_MAX_MATRIX_CACHE (16<<10)
|
||||
#endif // BGFX_CONFIG_MAX_MATRIX_CACHE
|
||||
|
||||
#ifndef BGFX_CONFIG_MAX_RECT_CACHE
|
||||
# define BGFX_CONFIG_MAX_RECT_CACHE 512
|
||||
#endif // BGFX_CONFIG_MAX_RECT_CACHE
|
||||
|
||||
#ifndef BGFX_CONFIG_MAX_VIEWS
|
||||
# define BGFX_CONFIG_MAX_VIEWS 32
|
||||
#endif // BGFX_CONFIG_MAX_VIEWS
|
||||
|
|
|
@ -2314,7 +2314,7 @@ namespace bgfx
|
|||
}
|
||||
|
||||
bool wireframe = !!(m_render->m_debug&BGFX_DEBUG_WIREFRAME);
|
||||
bool scissor = false;
|
||||
bool scissorEnabled = false;
|
||||
s_renderCtx.setDebugWireframe(wireframe);
|
||||
|
||||
uint16_t programIdx = invalidHandle;
|
||||
|
@ -2349,6 +2349,7 @@ namespace bgfx
|
|||
if (key.m_view != view)
|
||||
{
|
||||
currentState.clear();
|
||||
currentState.m_scissor = !state.m_scissor;
|
||||
changedFlags = BGFX_STATE_MASK;
|
||||
changedStencil = packStencil(BGFX_STENCIL_MASK, BGFX_STENCIL_MASK);
|
||||
currentState.m_flags = newFlags;
|
||||
|
@ -2383,21 +2384,8 @@ namespace bgfx
|
|||
m_clearQuad.clear(rect, clear);
|
||||
}
|
||||
|
||||
Rect& scissorRect = m_render->m_scissor[view];
|
||||
scissor = !scissorRect.isZero();
|
||||
if (scissor)
|
||||
{
|
||||
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;
|
||||
deviceCtx->RSSetScissorRects(1, &rc);
|
||||
}
|
||||
|
||||
s_renderCtx.setBlendState(BGFX_STATE_DEFAULT);
|
||||
s_renderCtx.setDepthStencilState(BGFX_STATE_DEFAULT, packStencil(BGFX_STENCIL_DEFAULT, BGFX_STENCIL_DEFAULT) );
|
||||
s_renderCtx.setRasterizerState(BGFX_STATE_DEFAULT, wireframe, scissor);
|
||||
s_renderCtx.setBlendState(newFlags);
|
||||
s_renderCtx.setDepthStencilState(newFlags, packStencil(BGFX_STENCIL_DEFAULT, BGFX_STENCIL_DEFAULT) );
|
||||
|
||||
uint8_t primIndex = uint8_t( (newFlags&BGFX_STATE_PT_MASK)>>BGFX_STATE_PT_SHIFT);
|
||||
if (primType != s_primType[primIndex])
|
||||
|
@ -2408,6 +2396,40 @@ namespace bgfx
|
|||
}
|
||||
}
|
||||
|
||||
uint16_t scissor = state.m_scissor;
|
||||
if (currentState.m_scissor != scissor)
|
||||
{
|
||||
currentState.m_scissor = scissor;
|
||||
|
||||
if (UINT16_MAX == scissor)
|
||||
{
|
||||
const Rect& scissorRect = m_render->m_scissor[view];
|
||||
scissorEnabled = !scissorRect.isZero();
|
||||
if (scissorEnabled)
|
||||
{
|
||||
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;
|
||||
deviceCtx->RSSetScissorRects(1, &rc);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
const Rect& scissorRect = m_render->m_rectCache.m_cache[scissor];
|
||||
scissorEnabled = true;
|
||||
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;
|
||||
deviceCtx->RSSetScissorRects(1, &rc);
|
||||
}
|
||||
|
||||
s_renderCtx.setRasterizerState(newFlags, wireframe, scissorEnabled);
|
||||
}
|
||||
|
||||
if ( (BGFX_STATE_DEPTH_WRITE|BGFX_STATE_DEPTH_TEST_MASK) & changedFlags
|
||||
|| 0 != changedStencil)
|
||||
{
|
||||
|
@ -2433,7 +2455,7 @@ namespace bgfx
|
|||
|
||||
if ( (BGFX_STATE_CULL_MASK|BGFX_STATE_MSAA) & changedFlags)
|
||||
{
|
||||
s_renderCtx.setRasterizerState(newFlags, wireframe, scissor);
|
||||
s_renderCtx.setRasterizerState(newFlags, wireframe, scissorEnabled);
|
||||
}
|
||||
|
||||
if (BGFX_STATE_ALPHA_REF_MASK & changedFlags)
|
||||
|
|
|
@ -2287,6 +2287,7 @@ namespace bgfx
|
|||
if (key.m_view != view)
|
||||
{
|
||||
currentState.clear();
|
||||
currentState.m_scissor = !state.m_scissor;
|
||||
changedFlags = BGFX_STATE_MASK;
|
||||
changedStencil = packStencil(BGFX_STENCIL_MASK, BGFX_STENCIL_MASK);
|
||||
currentState.m_flags = newFlags;
|
||||
|
@ -2354,11 +2355,38 @@ namespace bgfx
|
|||
}
|
||||
}
|
||||
|
||||
Rect& scissorRect = m_render->m_scissor[view];
|
||||
bool scissor = !scissorRect.isZero();
|
||||
DX_CHECK(device->SetRenderState(D3DRS_SCISSORTESTENABLE, scissor) );
|
||||
if (scissor)
|
||||
DX_CHECK(device->SetRenderState(D3DRS_STENCILENABLE, FALSE) );
|
||||
DX_CHECK(device->SetRenderState(D3DRS_ZENABLE, TRUE) );
|
||||
DX_CHECK(device->SetRenderState(D3DRS_ZFUNC, D3DCMP_LESS) );
|
||||
DX_CHECK(device->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE) );
|
||||
DX_CHECK(device->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE) );
|
||||
DX_CHECK(device->SetRenderState(D3DRS_ALPHAFUNC, D3DCMP_GREATER) );
|
||||
}
|
||||
|
||||
uint16_t scissor = state.m_scissor;
|
||||
if (currentState.m_scissor != scissor)
|
||||
{
|
||||
currentState.m_scissor = scissor;
|
||||
|
||||
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)
|
||||
{
|
||||
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;
|
||||
DX_CHECK(device->SetScissorRect(&rc) );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
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;
|
||||
|
@ -2366,13 +2394,6 @@ namespace bgfx
|
|||
rc.bottom = scissorRect.m_y + scissorRect.m_height;
|
||||
DX_CHECK(device->SetScissorRect(&rc) );
|
||||
}
|
||||
|
||||
DX_CHECK(device->SetRenderState(D3DRS_STENCILENABLE, FALSE) );
|
||||
DX_CHECK(device->SetRenderState(D3DRS_ZENABLE, TRUE) );
|
||||
DX_CHECK(device->SetRenderState(D3DRS_ZFUNC, D3DCMP_LESS) );
|
||||
DX_CHECK(device->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE) );
|
||||
DX_CHECK(device->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE) );
|
||||
DX_CHECK(device->SetRenderState(D3DRS_ALPHAFUNC, D3DCMP_GREATER) );
|
||||
}
|
||||
|
||||
if (0 != changedStencil)
|
||||
|
|
|
@ -2836,9 +2836,11 @@ namespace bgfx
|
|||
if (key.m_view != view)
|
||||
{
|
||||
currentState.clear();
|
||||
currentState.m_scissor = !state.m_scissor;
|
||||
changedFlags = BGFX_STATE_MASK;
|
||||
changedStencil = packStencil(BGFX_STENCIL_MASK, BGFX_STENCIL_MASK);
|
||||
currentState.m_flags = newFlags;
|
||||
currentState.m_stencil = newStencil;
|
||||
|
||||
GREMEDY_SETMARKER(s_viewName[key.m_view]);
|
||||
|
||||
|
@ -2862,18 +2864,6 @@ namespace bgfx
|
|||
m_clearQuad.clear(rect, clear, height);
|
||||
}
|
||||
|
||||
Rect& scissorRect = m_render->m_scissor[view];
|
||||
bool scissor = !scissorRect.isZero();
|
||||
if (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) );
|
||||
}
|
||||
else
|
||||
{
|
||||
GL_CHECK(glDisable(GL_SCISSOR_TEST) );
|
||||
}
|
||||
|
||||
GL_CHECK(glDisable(GL_STENCIL_TEST) );
|
||||
GL_CHECK(glEnable(GL_DEPTH_TEST) );
|
||||
GL_CHECK(glDepthFunc(GL_LESS) );
|
||||
|
@ -2881,6 +2871,33 @@ namespace bgfx
|
|||
GL_CHECK(glDisable(GL_BLEND) );
|
||||
}
|
||||
|
||||
uint16_t scissor = state.m_scissor;
|
||||
if (currentState.m_scissor != scissor)
|
||||
{
|
||||
currentState.m_scissor = scissor;
|
||||
|
||||
if (UINT16_MAX == scissor)
|
||||
{
|
||||
const Rect& scissorRect = m_render->m_scissor[view];
|
||||
bool scissor = !scissorRect.isZero();
|
||||
if (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) );
|
||||
}
|
||||
else
|
||||
{
|
||||
GL_CHECK(glDisable(GL_SCISSOR_TEST) );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
const Rect& scissorRect = 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) );
|
||||
}
|
||||
}
|
||||
|
||||
if (0 != changedStencil)
|
||||
{
|
||||
if (0 != newStencil)
|
||||
|
|
Reference in a new issue