Merge pull request #21 from ThorsDev/features/scissor-rect
Added scissor rect for UI
This commit is contained in:
@@ -26,6 +26,16 @@ void CStateManager::GetLight(DWORD index, D3DLIGHT9* pLight)
|
||||
*pLight = m_kLightData.m_akD3DLight[index];
|
||||
}
|
||||
|
||||
void CStateManager::SetScissorRect(const RECT& c_rRect)
|
||||
{
|
||||
m_lpD3DDev->SetScissorRect(&c_rRect);
|
||||
}
|
||||
|
||||
void CStateManager::GetScissorRect(RECT* pRect)
|
||||
{
|
||||
m_lpD3DDev->GetScissorRect(pRect);
|
||||
}
|
||||
|
||||
bool CStateManager::BeginScene()
|
||||
{
|
||||
m_bScene = true;
|
||||
@@ -216,6 +226,7 @@ void CStateManager::SetDefaultState()
|
||||
SetRenderState(D3DRS_VERTEXBLEND, D3DVBF_DISABLE);
|
||||
SetRenderState(D3DRS_CLIPPLANEENABLE, 0);
|
||||
SaveVertexProcessing(FALSE);
|
||||
SetRenderState(D3DRS_SCISSORTESTENABLE, FALSE);
|
||||
SetRenderState(D3DRS_MULTISAMPLEANTIALIAS, TRUE);
|
||||
SetRenderState(D3DRS_MULTISAMPLEMASK, 0xFFFFFFFF);
|
||||
SetRenderState(D3DRS_PATCHEDGESTYLE, D3DPATCHEDGE_CONTINUOUS);
|
||||
|
||||
@@ -245,6 +245,10 @@ public:
|
||||
void SetLight(DWORD index, CONST D3DLIGHT9* pLight);
|
||||
void GetLight(DWORD index, D3DLIGHT9* pLight);
|
||||
|
||||
// Scissor Rect
|
||||
void SetScissorRect(const RECT& c_rRect);
|
||||
void GetScissorRect(RECT* pRect);
|
||||
|
||||
// Renderstates
|
||||
void SaveRenderState(D3DRENDERSTATETYPE Type, DWORD dwValue);
|
||||
void RestoreRenderState(D3DRENDERSTATETYPE Type);
|
||||
|
||||
@@ -4,11 +4,63 @@
|
||||
#include "PythonSlotWindow.h"
|
||||
#include "PythonWindowManager.h"
|
||||
|
||||
#include "EterLib/StateManager.h"
|
||||
|
||||
BOOL g_bOutlineBoxEnable = FALSE;
|
||||
|
||||
namespace UI
|
||||
{
|
||||
|
||||
struct ScopedScissorRect
|
||||
{
|
||||
DWORD __OldState = 0;
|
||||
RECT __OldRect = { 0 };
|
||||
|
||||
bool __Enable;
|
||||
RECT __Rect;
|
||||
|
||||
ScopedScissorRect(const RECT& rect, bool enable)
|
||||
: __Rect(rect), __Enable(enable)
|
||||
{
|
||||
__OldState = STATEMANAGER.GetRenderState(D3DRS_SCISSORTESTENABLE);
|
||||
STATEMANAGER.GetScissorRect(&__OldRect);
|
||||
|
||||
STATEMANAGER.SetRenderState(D3DRS_SCISSORTESTENABLE, enable);
|
||||
STATEMANAGER.SetScissorRect(rect);
|
||||
}
|
||||
|
||||
~ScopedScissorRect()
|
||||
{
|
||||
STATEMANAGER.SetRenderState(D3DRS_SCISSORTESTENABLE, __OldState);
|
||||
STATEMANAGER.SetScissorRect(__OldRect);
|
||||
}
|
||||
};
|
||||
|
||||
template<typename Func>
|
||||
CWindow* FindWindowUpwards(CWindow* start, Func& f)
|
||||
{
|
||||
while (start && start->IsWindow())
|
||||
{
|
||||
if (f(start))
|
||||
return start;
|
||||
|
||||
start = start->GetParent();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static CWindow* GetParentScissorWindow(CWindow* pWin)
|
||||
{
|
||||
if (!pWin)
|
||||
return nullptr;
|
||||
|
||||
auto f = [](CWindow* pCurrWin) -> bool
|
||||
{
|
||||
return pCurrWin->IsScissorRectEnabled();
|
||||
};
|
||||
|
||||
return FindWindowUpwards(pWin, f);
|
||||
}
|
||||
|
||||
CWindow::CWindow(PyObject * ppyObject) :
|
||||
m_x(0),
|
||||
m_y(0),
|
||||
@@ -16,6 +68,7 @@ namespace UI
|
||||
m_lHeight(0),
|
||||
m_poHandler(ppyObject),
|
||||
m_bShow(false),
|
||||
m_bEnableScissorRect(false),
|
||||
m_pParent(NULL),
|
||||
m_dwFlag(0),
|
||||
m_isUpdatingChildren(FALSE)
|
||||
@@ -145,15 +198,57 @@ namespace UI
|
||||
if (!IsShow())
|
||||
return;
|
||||
|
||||
OnRender();
|
||||
|
||||
if (g_bOutlineBoxEnable)
|
||||
if (m_bEnableScissorRect)
|
||||
{
|
||||
CPythonGraphic::Instance().SetDiffuseColor(1.0f, 1.0f, 1.0f);
|
||||
CPythonGraphic::Instance().RenderBox2d(m_rect.left, m_rect.top, m_rect.right, m_rect.bottom);
|
||||
}
|
||||
|
||||
RECT scissorRect;
|
||||
scissorRect.left = std::max<int32_t>(0, m_rect.left);
|
||||
scissorRect.top = std::max<int32_t>(0, m_rect.top);
|
||||
scissorRect.right = m_rect.left + m_lWidth;
|
||||
scissorRect.bottom = m_rect.top + m_lHeight;
|
||||
|
||||
std::for_each(m_pChildList.begin(), m_pChildList.end(), std::mem_fn(&CWindow::Render));
|
||||
CWindow* pParentScissorWindow = GetParentScissorWindow(GetParent());
|
||||
|
||||
if (pParentScissorWindow)
|
||||
{
|
||||
const RECT& parentRect = pParentScissorWindow->m_rect;
|
||||
RECT parentScissorRect;
|
||||
|
||||
parentScissorRect.left = std::max<int32_t>(0, parentRect.left);
|
||||
parentScissorRect.top = std::max<int32_t>(0, parentRect.top);
|
||||
parentScissorRect.right = parentRect.left + pParentScissorWindow->GetWidth();
|
||||
parentScissorRect.bottom = parentRect.top + pParentScissorWindow->GetHeight();
|
||||
|
||||
scissorRect.left = std::max<int32_t>(scissorRect.left, parentScissorRect.left);
|
||||
scissorRect.top = std::max<int32_t>(scissorRect.top, parentScissorRect.top);
|
||||
scissorRect.right = std::min<int32_t>(scissorRect.right, parentScissorRect.right);
|
||||
scissorRect.bottom = std::min<int32_t>(scissorRect.bottom, parentScissorRect.bottom);
|
||||
}
|
||||
|
||||
ScopedScissorRect scopedScissorRect(scissorRect, true);
|
||||
|
||||
OnRender();
|
||||
|
||||
if (g_bOutlineBoxEnable)
|
||||
{
|
||||
CPythonGraphic::Instance().SetDiffuseColor(1.0f, 1.0f, 1.0f);
|
||||
CPythonGraphic::Instance().RenderBox2d(m_rect.left, m_rect.top, m_rect.right, m_rect.bottom);
|
||||
}
|
||||
|
||||
std::for_each(m_pChildList.begin(), m_pChildList.end(), std::mem_fn(&CWindow::Render));
|
||||
}
|
||||
else
|
||||
{
|
||||
OnRender();
|
||||
|
||||
if (g_bOutlineBoxEnable)
|
||||
{
|
||||
CPythonGraphic::Instance().SetDiffuseColor(1.0f, 1.0f, 1.0f);
|
||||
CPythonGraphic::Instance().RenderBox2d(m_rect.left, m_rect.top, m_rect.right, m_rect.bottom);
|
||||
}
|
||||
|
||||
std::for_each(m_pChildList.begin(), m_pChildList.end(), std::mem_fn(&CWindow::Render));
|
||||
}
|
||||
}
|
||||
|
||||
void CWindow::OnUpdate()
|
||||
@@ -171,6 +266,21 @@ namespace UI
|
||||
|
||||
}
|
||||
|
||||
void CWindow::EnableScissorRect()
|
||||
{
|
||||
m_bEnableScissorRect = true;
|
||||
}
|
||||
|
||||
void CWindow::DisableScissorRect()
|
||||
{
|
||||
m_bEnableScissorRect = false;
|
||||
}
|
||||
|
||||
bool CWindow::IsScissorRectEnabled() const
|
||||
{
|
||||
return m_bEnableScissorRect;
|
||||
}
|
||||
|
||||
void CWindow::OnRender()
|
||||
{
|
||||
if (!m_poHandler)
|
||||
|
||||
@@ -99,6 +99,11 @@ namespace UI
|
||||
void AddFlag(DWORD flag) { SET_BIT(m_dwFlag, flag); }
|
||||
void RemoveFlag(DWORD flag) { REMOVE_BIT(m_dwFlag, flag); }
|
||||
bool IsFlag(DWORD flag) { return (m_dwFlag & flag) ? true : false; }
|
||||
|
||||
|
||||
void EnableScissorRect();
|
||||
void DisableScissorRect();
|
||||
bool IsScissorRectEnabled() const;
|
||||
/////////////////////////////////////
|
||||
|
||||
virtual void OnRender();
|
||||
@@ -173,6 +178,7 @@ namespace UI
|
||||
|
||||
bool m_bMovable;
|
||||
bool m_bShow;
|
||||
bool m_bEnableScissorRect;
|
||||
|
||||
DWORD m_dwFlag;
|
||||
|
||||
|
||||
@@ -2307,6 +2307,35 @@ PyObject * wndMgrShowOverInWindowName(PyObject * poSelf, PyObject * poArgs)
|
||||
return Py_BuildNone();
|
||||
}
|
||||
|
||||
PyObject* wndMgrEnableScissorRect(PyObject* poSelf, PyObject* poArgs)
|
||||
{
|
||||
UI::CWindow* pWindow;
|
||||
if (!PyTuple_GetWindow(poArgs, 0, &pWindow))
|
||||
return Py_BuildException();
|
||||
|
||||
pWindow->EnableScissorRect();
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
PyObject* wndMgrDisableScissorRect(PyObject* poSelf, PyObject* poArgs)
|
||||
{
|
||||
UI::CWindow* pWindow;
|
||||
if (!PyTuple_GetWindow(poArgs, 0, &pWindow))
|
||||
return Py_BuildException();
|
||||
|
||||
pWindow->DisableScissorRect();
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
PyObject* wndMgrIsScissorRectEnabled(PyObject* poSelf, PyObject* poArgs)
|
||||
{
|
||||
UI::CWindow* pWindow;
|
||||
if (!PyTuple_GetWindow(poArgs, 0, &pWindow))
|
||||
return Py_BuildException();
|
||||
|
||||
return Py_BuildValue("b", pWindow->IsScissorRectEnabled());
|
||||
}
|
||||
|
||||
void initwndMgr()
|
||||
{
|
||||
static PyMethodDef s_methods[] =
|
||||
@@ -2502,6 +2531,10 @@ void initwndMgr()
|
||||
{ "SetOutlineFlag", wndMgrSetOutlineFlag, METH_VARARGS },
|
||||
{ "ShowOverInWindowName", wndMgrShowOverInWindowName, METH_VARARGS },
|
||||
|
||||
{ "EnableScissorRect", wndMgrEnableScissorRect, METH_VARARGS },
|
||||
{ "DisableScissorRect", wndMgrDisableScissorRect, METH_VARARGS },
|
||||
{ "IsScissorRectEnabled", wndMgrIsScissorRectEnabled, METH_VARARGS },
|
||||
|
||||
{ NULL, NULL, NULL },
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user