scissor rect

This commit is contained in:
ThorsDev
2025-09-22 17:48:21 +02:00
parent bdcb68619a
commit c5feaaf2d9
5 changed files with 172 additions and 8 deletions

View File

@@ -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);

View File

@@ -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);

View File

@@ -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)

View File

@@ -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;

View File

@@ -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 },
};