Added new editor layout similar to idTech 5.

Cleaned up the entity inspector.
Fixed numerous radiant bugs.
This commit is contained in:
Justin Marshall
2026-05-06 12:47:20 -07:00
parent baeae00185
commit 1a08d4af90
11 changed files with 3883 additions and 723 deletions
+559 -10
View File
@@ -826,6 +826,496 @@ static void CameraNav_DrawOverlay(CCamWnd* cam) {
}
/*
========================
Camera window embedded menu bar
The camera view is an OpenGL window, so the menu is a real child window at the
very top of the camera client area. CCamWnd reserves that strip in OnSize() and
all GL viewports/scissors use the reduced camera height, which keeps the camera
view from drawing underneath the menu.
========================
*/
bool IsBModel(brush_t* b);
static const char* CAMWND_MENU_BAR_CLASS = "QER_CamWndMenuBar";
static const char* CAMWND_PROP_MENU_BAR = "QER_CamWnd_MenuBar";
static const char* CAMWND_PROP_RENDER_MODE = "QER_CamWnd_RenderMode";
static const char* CAMWND_PROP_REBUILD_MODE = "QER_CamWnd_RebuildMode";
static const char* CAMWND_PROP_ENTITY_MODE = "QER_CamWnd_EntityMode";
static const char* CAMWND_PROP_FILTER_MASK = "QER_CamWnd_FilterMask";
#define CAMWND_MENU_HEIGHT 22
#define CAMWND_MENU_CHILD_ID 62000
#define CAMWND_MENU_CMD_REALTIME_LIGHTING 62100
#define CAMWND_MENU_CMD_SHOW_WORLD 62101
#define CAMWND_MENU_CMD_SHOW_PATCHES 62102
#define CAMWND_MENU_CMD_SHOW_MODELS 62103
#define CAMWND_MENU_CMD_SHOW_ENTITIES 62104
#define CAMWND_MENU_CMD_SHOW_LIGHTS 62105
#define CAMWND_MENU_CMD_RESET_FILTERS 62106
#define CAMWND_FILTER_HIDE_WORLD 0x00000001
#define CAMWND_FILTER_HIDE_PATCHES 0x00000002
#define CAMWND_FILTER_HIDE_MODELS 0x00000004
#define CAMWND_FILTER_HIDE_ENTITIES 0x00000008
#define CAMWND_FILTER_HIDE_LIGHTS 0x00000010
static LRESULT CALLBACK CamWnd_MenuBarProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
static int CamWnd_GetMenuHeight() {
return CAMWND_MENU_HEIGHT;
}
static int CamWnd_GetIntProp(HWND hWnd, const char* name, int defaultValue = 0) {
if (!hWnd) {
return defaultValue;
}
HANDLE value = GetProp(hWnd, name);
if (!value) {
return defaultValue;
}
return (int)(INT_PTR)value;
}
static void CamWnd_SetIntProp(HWND hWnd, const char* name, int value) {
if (!hWnd) {
return;
}
if (value == 0) {
RemoveProp(hWnd, name);
}
else {
SetProp(hWnd, name, (HANDLE)(INT_PTR)value);
}
}
static int CamWnd_GetFilterMask(CCamWnd* cam) {
return cam ? CamWnd_GetIntProp(cam->GetSafeHwnd(), CAMWND_PROP_FILTER_MASK, 0) : 0;
}
static void CamWnd_SetFilterMask(CCamWnd* cam, int mask) {
if (!cam) {
return;
}
CamWnd_SetIntProp(cam->GetSafeHwnd(), CAMWND_PROP_FILTER_MASK, mask);
}
static CCamWnd* CamWnd_FromMenuBar(HWND hWnd) {
HWND parent = GetParent(hWnd);
if (!parent) {
return NULL;
}
CWnd* wnd = CWnd::FromHandlePermanent(parent);
return DYNAMIC_DOWNCAST(CCamWnd, wnd);
}
static HWND CamWnd_GetMenuBar(CCamWnd* cam) {
if (!cam || !cam->GetSafeHwnd()) {
return NULL;
}
HWND hBar = (HWND)GetProp(cam->GetSafeHwnd(), CAMWND_PROP_MENU_BAR);
return IsWindow(hBar) ? hBar : NULL;
}
static void CamWnd_RequestRedraw(CCamWnd* cam) {
if (cam && cam->GetSafeHwnd()) {
cam->InvalidateRect(NULL, FALSE);
}
Sys_UpdateWindows(W_CAMERA);
if (g_pParentWnd) {
g_pParentWnd->PostMessage(WM_TIMER, 0, 0);
}
}
static void CamWnd_GetMenuItemRect(HWND hWnd, int item, RECT& rect) {
GetClientRect(hWnd, &rect);
rect.top = 1;
rect.bottom = CAMWND_MENU_HEIGHT - 1;
if (item == 0) {
rect.left = 4;
rect.right = 86;
}
else {
rect.left = 86;
rect.right = 156;
}
}
static int CamWnd_MenuHitTest(HWND hWnd, int x, int y) {
RECT rect;
for (int i = 0; i < 2; i++) {
CamWnd_GetMenuItemRect(hWnd, i, rect);
if (x >= rect.left && x < rect.right && y >= rect.top && y < rect.bottom) {
return i;
}
}
return -1;
}
static bool CamWnd_RealtimeLightingEnabled(CCamWnd* cam) {
if (!cam || !cam->GetSafeHwnd()) {
return false;
}
const HWND hWnd = cam->GetSafeHwnd();
return CamWnd_GetIntProp(hWnd, CAMWND_PROP_RENDER_MODE, 0) != 0 &&
CamWnd_GetIntProp(hWnd, CAMWND_PROP_REBUILD_MODE, 0) != 0;
}
static void CamWnd_SetRealtimeLighting(CCamWnd* cam, bool enabled) {
if (!cam || !cam->GetSafeHwnd()) {
return;
}
const HWND hWnd = cam->GetSafeHwnd();
bool renderMode = CamWnd_GetIntProp(hWnd, CAMWND_PROP_RENDER_MODE, 0) != 0;
bool rebuildMode = CamWnd_GetIntProp(hWnd, CAMWND_PROP_REBUILD_MODE, 0) != 0;
if (enabled) {
if (!renderMode) {
cam->ToggleRenderMode();
}
if (!rebuildMode) {
cam->ToggleRebuildMode();
}
}
else {
if (rebuildMode) {
cam->ToggleRebuildMode();
}
if (renderMode) {
cam->ToggleRenderMode();
}
}
CamWnd_RequestRedraw(cam);
}
static void CamWnd_ToggleRealtimeLighting(CCamWnd* cam) {
CamWnd_SetRealtimeLighting(cam, !CamWnd_RealtimeLightingEnabled(cam));
}
static void CamWnd_ToggleFilterBit(CCamWnd* cam, int bit) {
int mask = CamWnd_GetFilterMask(cam);
mask ^= bit;
CamWnd_SetFilterMask(cam, mask);
CamWnd_RequestRedraw(cam);
}
static void CamWnd_ResetFilters(CCamWnd* cam) {
CamWnd_SetFilterMask(cam, 0);
CamWnd_RequestRedraw(cam);
}
static void CamWnd_HandleMenuCommand(CCamWnd* cam, int command) {
switch (command) {
case CAMWND_MENU_CMD_REALTIME_LIGHTING:
CamWnd_ToggleRealtimeLighting(cam);
break;
case CAMWND_MENU_CMD_SHOW_WORLD:
CamWnd_ToggleFilterBit(cam, CAMWND_FILTER_HIDE_WORLD);
break;
case CAMWND_MENU_CMD_SHOW_PATCHES:
CamWnd_ToggleFilterBit(cam, CAMWND_FILTER_HIDE_PATCHES);
break;
case CAMWND_MENU_CMD_SHOW_MODELS:
CamWnd_ToggleFilterBit(cam, CAMWND_FILTER_HIDE_MODELS);
break;
case CAMWND_MENU_CMD_SHOW_ENTITIES:
CamWnd_ToggleFilterBit(cam, CAMWND_FILTER_HIDE_ENTITIES);
break;
case CAMWND_MENU_CMD_SHOW_LIGHTS:
CamWnd_ToggleFilterBit(cam, CAMWND_FILTER_HIDE_LIGHTS);
break;
case CAMWND_MENU_CMD_RESET_FILTERS:
CamWnd_ResetFilters(cam);
break;
}
}
static void CamWnd_AppendVisibleFilterItem(HMENU menu, int mask, int bit, UINT command, const char* text) {
UINT flags = MF_STRING;
if ((mask & bit) == 0) {
flags |= MF_CHECKED;
}
AppendMenu(menu, flags, command, text);
}
static void CamWnd_ShowLightingMenu(HWND hWnd, CCamWnd* cam) {
RECT itemRect;
POINT pt;
HMENU menu;
int command;
CamWnd_GetMenuItemRect(hWnd, 0, itemRect);
pt.x = itemRect.left;
pt.y = itemRect.bottom;
ClientToScreen(hWnd, &pt);
menu = CreatePopupMenu();
AppendMenu(menu, MF_STRING | (CamWnd_RealtimeLightingEnabled(cam) ? MF_CHECKED : 0), CAMWND_MENU_CMD_REALTIME_LIGHTING, "Real-time lighting");
command = TrackPopupMenu(menu, TPM_RETURNCMD | TPM_LEFTALIGN | TPM_TOPALIGN, pt.x, pt.y, 0, hWnd, NULL);
DestroyMenu(menu);
if (command) {
CamWnd_HandleMenuCommand(cam, command);
}
}
static void CamWnd_ShowFiltersMenu(HWND hWnd, CCamWnd* cam) {
RECT itemRect;
POINT pt;
HMENU menu;
int command;
int mask = CamWnd_GetFilterMask(cam);
CamWnd_GetMenuItemRect(hWnd, 1, itemRect);
pt.x = itemRect.left;
pt.y = itemRect.bottom;
ClientToScreen(hWnd, &pt);
menu = CreatePopupMenu();
CamWnd_AppendVisibleFilterItem(menu, mask, CAMWND_FILTER_HIDE_WORLD, CAMWND_MENU_CMD_SHOW_WORLD, "Show world geometry");
CamWnd_AppendVisibleFilterItem(menu, mask, CAMWND_FILTER_HIDE_PATCHES, CAMWND_MENU_CMD_SHOW_PATCHES, "Show patches");
CamWnd_AppendVisibleFilterItem(menu, mask, CAMWND_FILTER_HIDE_MODELS, CAMWND_MENU_CMD_SHOW_MODELS, "Show models");
CamWnd_AppendVisibleFilterItem(menu, mask, CAMWND_FILTER_HIDE_ENTITIES, CAMWND_MENU_CMD_SHOW_ENTITIES, "Show entities");
CamWnd_AppendVisibleFilterItem(menu, mask, CAMWND_FILTER_HIDE_LIGHTS, CAMWND_MENU_CMD_SHOW_LIGHTS, "Show lights");
AppendMenu(menu, MF_SEPARATOR, 0, NULL);
AppendMenu(menu, MF_STRING, CAMWND_MENU_CMD_RESET_FILTERS, "Reset filters");
command = TrackPopupMenu(menu, TPM_RETURNCMD | TPM_LEFTALIGN | TPM_TOPALIGN, pt.x, pt.y, 0, hWnd, NULL);
DestroyMenu(menu);
if (command) {
CamWnd_HandleMenuCommand(cam, command);
}
}
static void CamWnd_ShowTopMenu(HWND hWnd, int item) {
CCamWnd* cam = CamWnd_FromMenuBar(hWnd);
if (!cam) {
return;
}
if (item == 0) {
CamWnd_ShowLightingMenu(hWnd, cam);
}
else if (item == 1) {
CamWnd_ShowFiltersMenu(hWnd, cam);
}
}
static void CamWnd_RegisterMenuBarClass() {
static bool registered = false;
if (registered) {
return;
}
WNDCLASS wc;
memset(&wc, 0, sizeof(wc));
wc.style = CS_HREDRAW | CS_VREDRAW;
wc.lpfnWndProc = CamWnd_MenuBarProc;
wc.hInstance = AfxGetInstanceHandle();
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hbrBackground = (HBRUSH)(COLOR_BTNFACE + 1);
wc.lpszClassName = CAMWND_MENU_BAR_CLASS;
AfxRegisterClass(&wc);
registered = true;
}
static HWND CamWnd_EnsureMenuBar(CCamWnd* cam) {
if (!cam || !cam->GetSafeHwnd()) {
return NULL;
}
HWND hBar = CamWnd_GetMenuBar(cam);
if (hBar) {
return hBar;
}
CamWnd_RegisterMenuBarClass();
CRect rect;
cam->GetClientRect(rect);
hBar = CreateWindowEx(
0,
CAMWND_MENU_BAR_CLASS,
"",
WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS | WS_CLIPCHILDREN,
0,
0,
rect.Width(),
CAMWND_MENU_HEIGHT,
cam->GetSafeHwnd(),
(HMENU)CAMWND_MENU_CHILD_ID,
AfxGetInstanceHandle(),
NULL);
if (hBar) {
SetProp(cam->GetSafeHwnd(), CAMWND_PROP_MENU_BAR, hBar);
SendMessage(hBar, WM_SETFONT, (WPARAM)GetStockObject(DEFAULT_GUI_FONT), FALSE);
}
return hBar;
}
static void CamWnd_LayoutMenuBar(CCamWnd* cam) {
if (!cam || !cam->GetSafeHwnd()) {
return;
}
HWND hBar = CamWnd_EnsureMenuBar(cam);
if (!hBar) {
return;
}
CRect rect;
cam->GetClientRect(rect);
MoveWindow(hBar, 0, 0, rect.Width(), CAMWND_MENU_HEIGHT, TRUE);
}
static void CamWnd_DestroyMenuBar(CCamWnd* cam) {
if (!cam || !cam->GetSafeHwnd()) {
return;
}
HWND hBar = CamWnd_GetMenuBar(cam);
if (hBar) {
DestroyWindow(hBar);
}
RemoveProp(cam->GetSafeHwnd(), CAMWND_PROP_MENU_BAR);
RemoveProp(cam->GetSafeHwnd(), CAMWND_PROP_RENDER_MODE);
RemoveProp(cam->GetSafeHwnd(), CAMWND_PROP_REBUILD_MODE);
RemoveProp(cam->GetSafeHwnd(), CAMWND_PROP_ENTITY_MODE);
RemoveProp(cam->GetSafeHwnd(), CAMWND_PROP_FILTER_MASK);
}
static bool CamWnd_PointInMenuBar(CCamWnd* cam, const CPoint& point) {
if (!cam || !cam->GetSafeHwnd()) {
return false;
}
return point.y >= 0 && point.y < CAMWND_MENU_HEIGHT;
}
static void CamWnd_UpdateRuntimeState(CCamWnd* cam, bool renderMode, bool rebuildMode, bool entityMode) {
if (!cam || !cam->GetSafeHwnd()) {
return;
}
const HWND hWnd = cam->GetSafeHwnd();
CamWnd_SetIntProp(hWnd, CAMWND_PROP_RENDER_MODE, renderMode ? 1 : 0);
CamWnd_SetIntProp(hWnd, CAMWND_PROP_REBUILD_MODE, rebuildMode ? 1 : 0);
CamWnd_SetIntProp(hWnd, CAMWND_PROP_ENTITY_MODE, entityMode ? 1 : 0);
HWND hBar = CamWnd_GetMenuBar(cam);
if (hBar) {
InvalidateRect(hBar, NULL, FALSE);
}
}
static bool CamWnd_MenuFilterBrush(CCamWnd* cam, brush_t* brush) {
if (!cam || !brush) {
return false;
}
const int mask = CamWnd_GetFilterMask(cam);
if (mask == 0) {
return false;
}
const bool hasOwner = (brush->owner != NULL && brush->owner->eclass != NULL);
const bool isLight = hasOwner && ((brush->owner->eclass->nShowFlags & ECLASS_LIGHT) != 0);
const bool isPatch = (brush->pPatch != NULL);
const bool isModel = (brush->modelHandle > 0) || (hasOwner && brush->owner->eclass->entityModel) || brush->entityModel;
const bool isBrushModel = hasOwner && IsBModel(brush);
const bool isFixedEntity = hasOwner && brush->owner->eclass->fixedsize;
const bool isEntity = isLight || isModel || isBrushModel || isFixedEntity;
if ((mask & CAMWND_FILTER_HIDE_LIGHTS) && isLight) {
return true;
}
if ((mask & CAMWND_FILTER_HIDE_MODELS) && isModel) {
return true;
}
if ((mask & CAMWND_FILTER_HIDE_ENTITIES) && isEntity) {
return true;
}
if ((mask & CAMWND_FILTER_HIDE_PATCHES) && isPatch) {
return true;
}
if ((mask & CAMWND_FILTER_HIDE_WORLD) && !isEntity && !isPatch && !isModel) {
return true;
}
return false;
}
static LRESULT CALLBACK CamWnd_MenuBarProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) {
switch (uMsg) {
case WM_ERASEBKGND:
return 1;
case WM_SETCURSOR:
SetCursor(LoadCursor(NULL, IDC_ARROW));
return TRUE;
case WM_LBUTTONDOWN:
SetCapture(hWnd);
return 0;
case WM_LBUTTONUP:
{
if (GetCapture() == hWnd) {
ReleaseCapture();
}
const int x = (short)LOWORD(lParam);
const int y = (short)HIWORD(lParam);
const int item = CamWnd_MenuHitTest(hWnd, x, y);
if (item >= 0) {
CamWnd_ShowTopMenu(hWnd, item);
}
return 0;
}
case WM_PAINT:
{
PAINTSTRUCT ps;
HDC hDC = BeginPaint(hWnd, &ps);
RECT rect;
GetClientRect(hWnd, &rect);
FillRect(hDC, &rect, (HBRUSH)(COLOR_BTNFACE + 1));
RECT lineRect = rect;
lineRect.top = CAMWND_MENU_HEIGHT - 1;
FillRect(hDC, &lineRect, (HBRUSH)(COLOR_3DSHADOW + 1));
HFONT font = (HFONT)SendMessage(hWnd, WM_GETFONT, 0, 0);
HFONT oldFont = NULL;
if (font) {
oldFont = (HFONT)SelectObject(hDC, font);
}
SetBkMode(hDC, TRANSPARENT);
SetTextColor(hDC, GetSysColor(COLOR_BTNTEXT));
RECT itemRect;
CamWnd_GetMenuItemRect(hWnd, 0, itemRect);
DrawText(hDC, "Lighting", -1, &itemRect, DT_SINGLELINE | DT_CENTER | DT_VCENTER);
CamWnd_GetMenuItemRect(hWnd, 1, itemRect);
DrawText(hDC, "Filters", -1, &itemRect, DT_SINGLELINE | DT_CENTER | DT_VCENTER);
if (oldFont) {
SelectObject(hDC, oldFont);
}
EndPaint(hWnd, &ps);
return 0;
}
}
return DefWindowProc(hWnd, uMsg, wParam, lParam);
}
int g_axialAnchor = -1;
int g_axialDest = -1;
bool g_bAxialMode = false;
@@ -969,6 +1459,10 @@ BOOL CCamWnd::PreCreateWindow(CREATESTRUCT& cs) {
cs.style = QE3_SPLITTER_STYLE;
}
// Keep the OpenGL camera surface out of child-window areas such as the
// embedded menu bar.
cs.style |= WS_CLIPCHILDREN | WS_CLIPSIBLINGS;
BOOL bResult = CWnd::PreCreateWindow(cs);
//
@@ -1000,6 +1494,8 @@ void CCamWnd::OnPaint() {
bool bPaint = true;
UpdateCaption();
CamWnd_EnsureMenuBar(this);
CamWnd_LayoutMenuBar(this);
idGraphicsDeviceContextHelper context(dc.m_hDC, hglrc);
@@ -1026,6 +1522,7 @@ void CCamWnd::SetXYFriend(CXYWnd* pWnd) {
=======================================================================================================================
*/
void CCamWnd::OnDestroy() {
CamWnd_DestroyMenuBar(this);
CWnd::OnDestroy();
}
@@ -1078,12 +1575,14 @@ void CCamWnd::OnMouseMove(UINT nFlags, CPoint point) {
=======================================================================================================================
*/
void CCamWnd::OnLButtonDown(UINT nFlags, CPoint point) {
if (CamWnd_PointInMenuBar(this, point)) {
return;
}
m_ptLastCursor = point;
if (CameraNav_IsActive(this)) {
CRect r;
GetClientRect(r);
int x = r.Width() / 2;
int y = r.Height() / 2;
int x = m_Camera.width / 2;
int y = m_Camera.height / 2;
Cam_MouseDown(x, y, MK_LBUTTON);
Cam_MouseUp(x, y, 0);
Sys_UpdateWindows(W_ALL);
@@ -1105,6 +1604,10 @@ void CCamWnd::OnLButtonUp(UINT nFlags, CPoint point) {
=======================================================================================================================
*/
void CCamWnd::OnMButtonDown(UINT nFlags, CPoint point) {
if (CamWnd_PointInMenuBar(this, point)) {
return;
}
OriginalMouseDown(nFlags, point);
}
@@ -1121,6 +1624,10 @@ void CCamWnd::OnMButtonUp(UINT nFlags, CPoint point) {
=======================================================================================================================
*/
void CCamWnd::OnRButtonDown(UINT nFlags, CPoint point) {
if (CamWnd_PointInMenuBar(this, point)) {
return;
}
m_ptLastCursor = point;
if (!(nFlags & (MK_SHIFT | MK_CONTROL)) && CameraNav_Begin(this)) {
return;
@@ -1213,6 +1720,10 @@ int CCamWnd::OnCreate(LPCREATESTRUCT lpCreateStruct) {
common->Printf("GL_VERSION: %s\n", glGetString(GL_VERSION));
common->Printf("GL_EXTENSIONS: %s\n", glGetString(GL_EXTENSIONS));
CamWnd_UpdateRuntimeState(this, renderMode, rebuildMode, entityMode);
CamWnd_EnsureMenuBar(this);
CamWnd_LayoutMenuBar(this);
return 0;
}
@@ -1791,6 +2302,7 @@ void CCamWnd::Cam_Draw() {
glViewport(0, 0, m_Camera.width, m_Camera.height);
glEnable(GL_SCISSOR_TEST);
glScissor(0, 0, m_Camera.width, m_Camera.height);
glClearColor(g_qeglobals.d_savedinfo.colors[COLOR_CAMERABACK][0], g_qeglobals.d_savedinfo.colors[COLOR_CAMERABACK][1], g_qeglobals.d_savedinfo.colors[COLOR_CAMERABACK][2], 0);
@@ -1821,6 +2333,10 @@ void CCamWnd::Cam_Draw() {
continue;
}
if (CamWnd_MenuFilterBrush(this, brush)) {
continue;
}
if (renderMode) {
if (!(entityMode && brush->owner->eclass->fixedsize)) {
continue;
@@ -1842,6 +2358,9 @@ void CCamWnd::Cam_Draw() {
if (!renderMode) {
// draw normally
for (brush = pList->next; brush != pList; brush = brush->next) {
if (CamWnd_MenuFilterBrush(this, brush)) {
continue;
}
if (brush->pPatch) {
continue;
}
@@ -1860,6 +2379,9 @@ void CCamWnd::Cam_Draw() {
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
globalImages->BindNull();
for (brush = pList->next; brush != pList; brush = brush->next) {
if (CamWnd_MenuFilterBrush(this, brush)) {
continue;
}
if (brush->pPatch || brush->modelHandle > 0) {
Brush_Draw(brush, true);
@@ -1905,6 +2427,9 @@ void CCamWnd::Cam_Draw() {
glColor3f(1, 1, 1);
for (brush = pList->next; brush != pList; brush = brush->next) {
if (CamWnd_MenuFilterBrush(this, brush)) {
continue;
}
if (brush->pPatch || brush->modelHandle > 0) {
continue;
}
@@ -1964,6 +2489,7 @@ void CCamWnd::Cam_Draw() {
CameraNav_DrawOverlay(this);
glDisable(GL_SCISSOR_TEST);
glFinish();
QE_CheckOpenGLForErrors();
@@ -1982,8 +2508,13 @@ void CCamWnd::OnSize(UINT nType, int cx, int cy) {
CRect rect;
GetClientRect(rect);
m_Camera.width = rect.right;
m_Camera.height = rect.bottom;
CamWnd_EnsureMenuBar(this);
CamWnd_LayoutMenuBar(this);
m_Camera.width = rect.Width();
m_Camera.height = rect.Height() - CamWnd_GetMenuHeight();
if (m_Camera.height < 1) {
m_Camera.height = 1;
}
InvalidateRect(NULL, false);
}
@@ -2225,11 +2756,14 @@ static unsigned int EditorHashBrushGeometry(brush_t* brush, const idVec3& origin
return hash;
}
static unsigned int EditorHashBModelGeometry(entity_t* ent) {
static unsigned int EditorHashBModelGeometry(CCamWnd* cam, entity_t* ent) {
unsigned int hash = EDITOR_RENDER_HASH_INIT;
hash = EditorHashString(hash, ValueForKey(ent, "name"));
for (brush_t* brush = ent->brushes.onext; brush != &ent->brushes; brush = brush->onext) {
if (FilterBrush(brush) || CamWnd_MenuFilterBrush(cam, brush) || Map_IsBrushFiltered(brush)) {
continue;
}
const unsigned int brushHash = EditorHashBrushGeometry(brush, ent->origin);
hash = EditorHashInt(hash, brushHash);
}
@@ -2281,11 +2815,14 @@ static idRenderModel* EditorBuildSingleBrushModel(brush_t* brush, const idVec3&
return model;
}
static idRenderModel* EditorBuildBModel(entity_t* ent, const char* name) {
static idRenderModel* EditorBuildBModel(CCamWnd* cam, entity_t* ent, const char* name) {
idTriList tris(1024);
idMatList mats(1024);
for (brush_t* brush = ent->brushes.onext; brush != &ent->brushes; brush = brush->onext) {
if (FilterBrush(brush) || CamWnd_MenuFilterBrush(cam, brush) || Map_IsBrushFiltered(brush)) {
continue;
}
Brush_ToTris(brush, &tris, &mats, false, true);
}
@@ -2384,6 +2921,9 @@ static bool EditorWorldBrushRenderable(CCamWnd* cam, brush_t* brush) {
if (FilterBrush(brush)) {
return false;
}
if (CamWnd_MenuFilterBrush(cam, brush)) {
return false;
}
if (cam->CullBrush(brush, true)) {
return false;
}
@@ -2631,6 +3171,7 @@ void CCamWnd::BuildEntityRenderState(entity_t* ent, bool update) {
// If the entity is no longer renderable, remove only this entity's defs.
if (ent->brushes.onext == &ent->brushes ||
FilterBrush(ent->brushes.onext) ||
CamWnd_MenuFilterBrush(this, ent->brushes.onext) ||
CullBrush(ent->brushes.onext, true) ||
Map_IsBrushFiltered(ent->brushes.onext)) {
EditorFreeEntityModelDef(entityState, ent);
@@ -2655,7 +3196,7 @@ void CCamWnd::BuildEntityRenderState(entity_t* ent, bool update) {
// Brush model entity. Rebuild the renderModel only when the
// entity-local brush geometry/materials changed. Plain movement
// is handled by UpdateEntityDef below.
const unsigned int geometryHash = EditorHashBModelGeometry(ent);
const unsigned int geometryHash = EditorHashBModelGeometry(this, ent);
editorRenderBModelState_t* bmodelState = EditorTouchBModelState(ent);
idRenderModel* oldModel = NULL;
@@ -2665,7 +3206,7 @@ void CCamWnd::BuildEntityRenderState(entity_t* ent, bool update) {
idStr::Icmp(bmodelState->modelName.c_str(), name) != 0);
if (geometryChanged) {
idRenderModel* newModel = EditorBuildBModel(ent, name);
idRenderModel* newModel = EditorBuildBModel(this, ent, name);
if (newModel) {
oldModel = bmodelState->model;
bmodelState->model = newModel;
@@ -3229,6 +3770,7 @@ void CCamWnd::UpdateCaption() {
strCaption += (animationMode) ? " +anim" : "";
}
strCaption += (soundMode) ? " +snd" : "";
CamWnd_UpdateRuntimeState(this, renderMode, rebuildMode, entityMode);
SetWindowText(strCaption);
}
@@ -3379,6 +3921,10 @@ void CCamWnd::DrawEntityData() {
continue;
}
if (CamWnd_MenuFilterBrush(this, brush)) {
continue;
}
if ((pass == 1 && selectMode) || (entityMode && pass == 0 && brush->owner->lightDef >= 0)) {
Brush_DrawXY(brush, 0, true, true);
}
@@ -3413,6 +3959,8 @@ void CCamWnd::Cam_Render() {
// save the editor state
//glPushAttrib( GL_ALL_ATTRIB_BITS );
glViewport(0, 0, m_Camera.width, m_Camera.height);
glEnable(GL_SCISSOR_TEST);
glClearColor(0.1f, 0.1f, 0.1f, 0.0f);
glScissor(0, 0, m_Camera.width, m_Camera.height);
glClear(GL_COLOR_BUFFER_BIT);
@@ -3453,6 +4001,7 @@ void CCamWnd::Cam_Render() {
//wglSwapBuffers(dc.m_hDC);
// get back to the editor state
glDisable(GL_SCISSOR_TEST);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
Cam_BuildMatrix();