/* =========================================================================== Doom 3 GPL Source Code Copyright (C) 1999-2011 id Software LLC, a ZeniMax Media company. This file is part of the Doom 3 GPL Source Code (?Doom 3 Source Code?). Doom 3 Source Code is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. Doom 3 Source Code is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Doom 3 Source Code. If not, see . In addition, the Doom 3 Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Doom 3 Source Code. If not, please request a copy in writing from id Software at the address below. If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA. =========================================================================== */ #include "../../idlib/precompiled.h" #pragma hdrstop #include "qe3.h" #define PAGEFLIPS 2 z_t z; /* ======================================================================================================================= Z_Init ======================================================================================================================= */ void Z_Init(void) { z.origin[0] = 0; z.origin[1] = 20; z.origin[2] = 46; z.scale = 1; } /* MOUSE ACTIONS */ static int cursorx, cursory; /* ======================================================================================================================= Z_MouseDown ======================================================================================================================= */ void Z_MouseDown(int x, int y, int buttons) { idVec3 org, dir, vup, vright; brush_t *b; Sys_GetCursorPos(&cursorx, &cursory); vup[0] = 0; vup[1] = 0; vup[2] = 1 / z.scale; VectorCopy(z.origin, org); org[2] += (y - (z.height / 2)) / z.scale; org[1] = MIN_WORLD_COORD; b = selected_brushes.next; if (b != &selected_brushes) { org[0] = (b->mins[0] + b->maxs[0]) / 2; } dir[0] = 0; dir[1] = 1; dir[2] = 0; vright[0] = 0; vright[1] = 0; vright[2] = 0; // new mouse code for ZClip, I'll do this stuff before falling through into the standard ZWindow mouse code... // if (g_pParentWnd->GetZWnd()->m_pZClip) // should always be the case I think, but this is safer { bool bToggle = false; bool bSetTop = false; bool bSetBot = false; bool bReset = false; if (g_PrefsDlg.m_nMouseButtons == 2) { // 2 button mice... // bToggle = (GetKeyState(VK_F1) & 0x8000) != 0; bSetTop = (GetKeyState(VK_F2) & 0x8000) != 0; bSetBot = (GetKeyState(VK_F3) & 0x8000) != 0; bReset = (GetKeyState(VK_F4) & 0x8000) != 0; } else { // 3 button mice... // bToggle = (buttons == (MK_RBUTTON|MK_SHIFT|MK_CONTROL)); bSetTop = (buttons == (MK_RBUTTON|MK_SHIFT)); bSetBot = (buttons == (MK_RBUTTON|MK_CONTROL)); bReset = (GetKeyState(VK_F4) & 0x8000) != 0; } if (bToggle) { g_pParentWnd->GetZWnd()->m_pZClip->Enable(!(g_pParentWnd->GetZWnd()->m_pZClip->IsEnabled())); Sys_UpdateWindows (W_ALL); return; } if (bSetTop) { g_pParentWnd->GetZWnd()->m_pZClip->SetTop(org[2]); Sys_UpdateWindows (W_ALL); return; } if (bSetBot) { g_pParentWnd->GetZWnd()->m_pZClip->SetBottom(org[2]); Sys_UpdateWindows (W_ALL); return; } if (bReset) { g_pParentWnd->GetZWnd()->m_pZClip->Reset(); Sys_UpdateWindows (W_ALL); return; } } // // LBUTTON = manipulate selection shift-LBUTTON = select middle button = grab // texture ctrl-middle button = set entire brush to texture ctrl-shift-middle // button = set single face to texture // // see code above for these next 3, I just commented them here as well for clarity... // // ctrl-shift-RIGHT button = toggle ZClip on/off // shift-RIGHT button = set ZClip top marker // ctrl-RIGHT button = set ZClip bottom marker int nMouseButton = g_PrefsDlg.m_nMouseButtons == 2 ? MK_RBUTTON : MK_MBUTTON; if ( (buttons == MK_LBUTTON) || (buttons == (MK_LBUTTON | MK_SHIFT)) || (buttons == MK_MBUTTON) // || (buttons == (MK_MBUTTON|MK_CONTROL)) || (buttons == (nMouseButton | MK_SHIFT | MK_CONTROL)) ) { Drag_Begin(x, y, buttons, vright, vup, org, dir); return; } // control mbutton = move camera if ((buttons == (MK_CONTROL | nMouseButton)) || (buttons == (MK_CONTROL | MK_LBUTTON))) { g_pParentWnd->GetCamera()->Camera().origin[2] = org[2]; Sys_UpdateWindows(W_CAMERA | W_XY_OVERLAY | W_Z); } } /* ======================================================================================================================= Z_MouseUp ======================================================================================================================= */ void Z_MouseUp(int x, int y, int buttons) { Drag_MouseUp(); } /* ======================================================================================================================= Z_MouseMoved ======================================================================================================================= */ void Z_MouseMoved(int x, int y, int buttons) { if (!buttons) { return; } if (buttons == MK_LBUTTON) { Drag_MouseMoved(x, y, buttons); Sys_UpdateWindows(W_Z | W_CAMERA_IFON | W_XY); return; } // rbutton = drag z origin if (buttons == MK_RBUTTON) { Sys_GetCursorPos(&x, &y); if (y != cursory) { z.origin[2] += y - cursory; Sys_SetCursorPos(cursorx, cursory); Sys_UpdateWindows(W_Z); } return; } // control mbutton = move camera int nMouseButton = g_PrefsDlg.m_nMouseButtons == 2 ? MK_RBUTTON : MK_MBUTTON; if ((buttons == (MK_CONTROL | nMouseButton)) || (buttons == (MK_CONTROL | MK_LBUTTON))) { g_pParentWnd->GetCamera()->Camera().origin[2] = z.origin[2] + (y - (z.height / 2)) / z.scale; Sys_UpdateWindows(W_CAMERA | W_XY_OVERLAY | W_Z); } } /* ======================================================================================================================= DRAWING £ Z_DrawGrid ======================================================================================================================= */ void Z_DrawGrid(void) { float zz, zb, ze; int w, h; char text[32]; w = z.width / 2 / z.scale; h = z.height / 2 / z.scale; zb = z.origin[2] - h; if (zb < region_mins[2]) { zb = region_mins[2]; } zb = 64 * floor(zb / 64); ze = z.origin[2] + h; if (ze > region_maxs[2]) { ze = region_maxs[2]; } ze = 64 * ceil(ze / 64); // draw major blocks qglColor3fv( g_qeglobals.d_savedinfo.colors[COLOR_GRIDMAJOR].ToFloatPtr() ); qglBegin(GL_LINES); qglVertex2f(0, zb); qglVertex2f(0, ze); for (zz = zb; zz < ze; zz += 64) { qglVertex2f(-w, zz); qglVertex2f(w, zz); } qglEnd(); // draw minor blocks if ( g_qeglobals.d_showgrid && g_qeglobals.d_gridsize * z.scale >= 4 && !g_qeglobals.d_savedinfo.colors[COLOR_GRIDMINOR].Compare( g_qeglobals.d_savedinfo.colors[COLOR_GRIDBACK] ) ) { qglColor3fv(g_qeglobals.d_savedinfo.colors[COLOR_GRIDMINOR].ToFloatPtr()); qglBegin(GL_LINES); for (zz = zb; zz < ze; zz += g_qeglobals.d_gridsize) { if (!((int)zz & 63)) { continue; } qglVertex2f(-w, zz); qglVertex2f(w, zz); } qglEnd(); } // draw coordinate text if needed qglColor3fv(g_qeglobals.d_savedinfo.colors[COLOR_GRIDTEXT].ToFloatPtr()); for (zz = zb; zz < ze; zz += 64) { qglRasterPos2f(-w + 1, zz); sprintf(text, "%i", (int)zz); qglCallLists(strlen(text), GL_UNSIGNED_BYTE, text); } } #define CAM_HEIGHT 48 // height of main part #define CAM_GIZMO 8 // height of the gizmo /* ======================================================================================================================= ======================================================================================================================= */ void ZDrawCameraIcon(void) { float x, y; int xCam = z.width / 4; x = 0; y = g_pParentWnd->GetCamera()->Camera().origin[2]; qglColor3f(0.0, 0.0, 1.0); qglBegin(GL_LINE_STRIP); qglVertex3f(x - xCam, y, 0); qglVertex3f(x, y + CAM_GIZMO, 0); qglVertex3f(x + xCam, y, 0); qglVertex3f(x, y - CAM_GIZMO, 0); qglVertex3f(x - xCam, y, 0); qglVertex3f(x + xCam, y, 0); qglVertex3f(x + xCam, y - CAM_HEIGHT, 0); qglVertex3f(x - xCam, y - CAM_HEIGHT, 0); qglVertex3f(x - xCam, y, 0); qglEnd(); } void ZDrawZClip() { float x,y; x = 0; y = g_pParentWnd->GetCamera()->Camera().origin[2]; if (g_pParentWnd->GetZWnd()->m_pZClip) // should always be the case I think g_pParentWnd->GetZWnd()->m_pZClip->Paint(); } GLbitfield glbitClear = GL_COLOR_BUFFER_BIT; // HACK /* ======================================================================================================================= Z_Draw ======================================================================================================================= */ void Z_Draw(void) { brush_t *brush; float w, h; float top, bottom; idVec3 org_top, org_bottom, dir_up, dir_down; int xCam = z.width / 3; if (!active_brushes.next) { return; // not valid yet } // clear qglViewport(0, 0, z.width, z.height); qglScissor(0, 0, z.width, z.height); qglClearColor ( g_qeglobals.d_savedinfo.colors[COLOR_GRIDBACK][0], g_qeglobals.d_savedinfo.colors[COLOR_GRIDBACK][1], g_qeglobals.d_savedinfo.colors[COLOR_GRIDBACK][2], 0 ); /* * GL Bug £ * When not using hw acceleration, gl will fault if we clear the depth buffer bit * on the first pass. The hack fix is to set the GL_DEPTH_BUFFER_BIT only after * Z_Draw() has been called once. Yeah, right. £ * qglClear(glbitClear); */ qglClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // // glbitClear |= GL_DEPTH_BUFFER_BIT; // qglClear(GL_DEPTH_BUFFER_BIT); // qglMatrixMode(GL_PROJECTION); qglLoadIdentity(); w = z.width / 2 / z.scale; h = z.height / 2 / z.scale; qglOrtho(-w, w, z.origin[2] - h, z.origin[2] + h, -8, 8); globalImages->BindNull(); qglDisable(GL_DEPTH_TEST); qglDisable(GL_BLEND); // now draw the grid Z_DrawGrid(); // draw stuff qglDisable(GL_CULL_FACE); qglPolygonMode(GL_FRONT_AND_BACK, GL_FILL); globalImages->BindNull(); // draw filled interiors and edges dir_up[0] = 0; dir_up[1] = 0; dir_up[2] = 1; dir_down[0] = 0; dir_down[1] = 0; dir_down[2] = -1; VectorCopy(z.origin, org_top); org_top[2] = 4096; VectorCopy(z.origin, org_bottom); org_bottom[2] = -4096; for (brush = active_brushes.next; brush != &active_brushes; brush = brush->next) { if ( brush->mins[0] >= z.origin[0] || brush->maxs[0] <= z.origin[0] || brush->mins[1] >= z.origin[1] || brush->maxs[1] <= z.origin[1] ) { continue; } if (!Brush_Ray(org_top, dir_down, brush, &top)) { continue; } top = org_top[2] - top; if (!Brush_Ray(org_bottom, dir_up, brush, &bottom)) { continue; } bottom = org_bottom[2] + bottom; //q = declManager->FindMaterial(brush->brush_faces->texdef.name); qglColor3f(brush->owner->eclass->color.x, brush->owner->eclass->color.y, brush->owner->eclass->color.z); qglBegin(GL_QUADS); qglVertex2f(-xCam, bottom); qglVertex2f(xCam, bottom); qglVertex2f(xCam, top); qglVertex2f(-xCam, top); qglEnd(); qglColor3f(1, 1, 1); qglBegin(GL_LINE_LOOP); qglVertex2f(-xCam, bottom); qglVertex2f(xCam, bottom); qglVertex2f(xCam, top); qglVertex2f(-xCam, top); qglEnd(); } // now draw selected brushes for (brush = selected_brushes.next; brush != &selected_brushes; brush = brush->next) { if ( !( brush->mins[0] >= z.origin[0] || brush->maxs[0] <= z.origin[0] || brush->mins[1] >= z.origin[1] || brush->maxs[1] <= z.origin[1] ) ) { if (Brush_Ray(org_top, dir_down, brush, &top)) { top = org_top[2] - top; if (Brush_Ray(org_bottom, dir_up, brush, &bottom)) { bottom = org_bottom[2] + bottom; //q = declManager->FindMaterial(brush->brush_faces->texdef.name); qglColor3f(brush->owner->eclass->color.x, brush->owner->eclass->color.y, brush->owner->eclass->color.z); qglBegin(GL_QUADS); qglVertex2f(-xCam, bottom); qglVertex2f(xCam, bottom); qglVertex2f(xCam, top); qglVertex2f(-xCam, top); qglEnd(); } } } qglColor3fv(g_qeglobals.d_savedinfo.colors[COLOR_SELBRUSHES].ToFloatPtr()); qglBegin(GL_LINE_LOOP); qglVertex2f(-xCam, brush->mins[2]); qglVertex2f(xCam, brush->mins[2]); qglVertex2f(xCam, brush->maxs[2]); qglVertex2f(-xCam, brush->maxs[2]); qglEnd(); } ZDrawCameraIcon(); ZDrawZClip(); qglFinish(); QE_CheckOpenGLForErrors(); }