From 952c5c128f9efaea89d41d882c4ea3ade7df4591 Mon Sep 17 00:00:00 2001 From: zakk Date: Fri, 26 Aug 2005 04:48:05 +0000 Subject: Itsa me, quake3io! git-svn-id: svn://svn.icculus.org/quake3/trunk@2 edf5b092-35ff-0310-97b2-ce42778d08ea --- q3radiant/CamWnd.cpp | 1165 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 1165 insertions(+) create mode 100755 q3radiant/CamWnd.cpp (limited to 'q3radiant/CamWnd.cpp') diff --git a/q3radiant/CamWnd.cpp b/q3radiant/CamWnd.cpp new file mode 100755 index 0000000..0ea352d --- /dev/null +++ b/q3radiant/CamWnd.cpp @@ -0,0 +1,1165 @@ +/* +=========================================================================== +Copyright (C) 1999-2005 Id Software, Inc. + +This file is part of Quake III Arena source code. + +Quake III Arena 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 2 of the License, +or (at your option) any later version. + +Quake III Arena 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 Foobar; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +=========================================================================== +*/ +// CamWnd.cpp : implementation file +// + +#include "stdafx.h" +#include "Radiant.h" +#include "XYWnd.h" +#include "CamWnd.h" +#include "qe3.h" +#include "splines/splines.h" + +#ifdef _DEBUG +#define new DEBUG_NEW +#undef THIS_FILE +static char THIS_FILE[] = __FILE__; +#endif + +extern void DrawPathLines(); + +int g_nAngleSpeed = 300; +int g_nMoveSpeed = 400; + + +///////////////////////////////////////////////////////////////////////////// +// CCamWnd +IMPLEMENT_DYNCREATE(CCamWnd, CWnd); + +CCamWnd::CCamWnd() +{ + m_pXYFriend = NULL; + m_nNumTransBrushes = 0; + memset(&m_Camera, 0, sizeof(camera_t)); + m_pSide_select = NULL; + m_bClipMode = false; + Cam_Init(); +} + +CCamWnd::~CCamWnd() +{ +} + + +BEGIN_MESSAGE_MAP(CCamWnd, CWnd) + //{{AFX_MSG_MAP(CCamWnd) + ON_WM_KEYDOWN() + ON_WM_PAINT() + ON_WM_DESTROY() + ON_WM_CLOSE() + ON_WM_MOUSEMOVE() + ON_WM_LBUTTONDOWN() + ON_WM_LBUTTONUP() + ON_WM_MBUTTONDOWN() + ON_WM_MBUTTONUP() + ON_WM_RBUTTONDOWN() + ON_WM_RBUTTONUP() + ON_WM_CREATE() + ON_WM_SIZE() + ON_WM_NCCALCSIZE() + ON_WM_KILLFOCUS() + ON_WM_SETFOCUS() + ON_WM_KEYUP() + //}}AFX_MSG_MAP +END_MESSAGE_MAP() + + +LONG WINAPI CamWndProc ( + HWND hWnd, + UINT uMsg, + WPARAM wParam, + LPARAM lParam) +{ + RECT rect; + + GetClientRect(hWnd, &rect); + + switch (uMsg) + { + case WM_KILLFOCUS: + case WM_SETFOCUS: + SendMessage( hWnd, WM_NCACTIVATE, uMsg == WM_SETFOCUS, 0 ); + return 0; + + case WM_NCCALCSIZE:// don't let windows copy pixels + DefWindowProc (hWnd, uMsg, wParam, lParam); + return WVR_REDRAW; + + } + + return DefWindowProc( hWnd, uMsg, wParam, lParam ); +} + + +///////////////////////////////////////////////////////////////////////////// +// CCamWnd message handlers + +BOOL CCamWnd::PreCreateWindow(CREATESTRUCT& cs) +{ + WNDCLASS wc; + HINSTANCE hInstance = AfxGetInstanceHandle(); + if (::GetClassInfo(hInstance, CAMERA_WINDOW_CLASS, &wc) == FALSE) + { + // Register a new class + memset (&wc, 0, sizeof(wc)); + wc.style = CS_NOCLOSE | CS_OWNDC; + wc.lpszClassName = CAMERA_WINDOW_CLASS; + wc.hCursor = LoadCursor (NULL,IDC_ARROW); + wc.lpfnWndProc = CamWndProc; + if (AfxRegisterClass(&wc) == FALSE) + Error ("CCamWnd RegisterClass: failed"); + } + + cs.lpszClass = CAMERA_WINDOW_CLASS; + cs.lpszName = "CAM"; + if (cs.style != QE3_CHILDSTYLE) + cs.style = QE3_SPLITTER_STYLE; + + BOOL bResult = CWnd::PreCreateWindow(cs); + + // See if the class already exists and if not then we need + // to register our new window class. + return bResult; + +} + + +void CCamWnd::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags) +{ + g_pParentWnd->HandleKey(nChar, nRepCnt, nFlags); +} + + +brush_t* g_pSplitList = NULL; + +void CCamWnd::OnPaint() +{ + CPaintDC dc(this); // device context for painting + bool bPaint = true; + if (!qwglMakeCurrent( dc.m_hDC, g_qeglobals.d_hglrcBase )) + { + Sys_Printf("ERROR: wglMakeCurrent failed..\n "); + Sys_Printf("Please restart Q3Radiant if the camera view is not working\n"); + } + else + { + QE_CheckOpenGLForErrors(); + g_pSplitList = NULL; + if (g_bClipMode) + { + if (g_Clip1.Set() && g_Clip2.Set()) + { + g_pSplitList = ( (g_pParentWnd->ActiveXY()->GetViewType() == XZ) ? !g_bSwitch : g_bSwitch) ? &g_brBackSplits : &g_brFrontSplits; + } + } + Cam_Draw (); + QE_CheckOpenGLForErrors(); + qwglSwapBuffers(dc.m_hDC); + } +} + + +void CCamWnd::SetXYFriend(CXYWnd * pWnd) +{ + m_pXYFriend = pWnd; +} + +void CCamWnd::OnDestroy() +{ + QEW_StopGL(GetSafeHwnd(), g_qeglobals.d_hglrcBase, g_qeglobals.d_hdcBase ); + CWnd::OnDestroy(); +} + +void CCamWnd::OnClose() +{ + CWnd::OnClose(); +} + +extern void Select_ShiftTexture(int x, int y); +extern void Select_RotateTexture(int amt); +extern void Select_ScaleTexture(int x, int y); +void CCamWnd::OnMouseMove(UINT nFlags, CPoint point) +{ + CRect r; + GetClientRect(r); + if (GetCapture() == this && (GetKeyState(VK_MENU) & 0x8000) && !((GetKeyState(VK_SHIFT) & 0x8000) || (GetKeyState(VK_CONTROL) & 0x8000))) + { + if (GetKeyState(VK_CONTROL) & 0x8000) + Select_RotateTexture(point.y - m_ptLastCursor.y); + else + if (GetKeyState(VK_SHIFT) & 0x8000) + Select_ScaleTexture(point.x - m_ptLastCursor.x, m_ptLastCursor.y - point.y); + else + Select_ShiftTexture(point.x - m_ptLastCursor.x, m_ptLastCursor.y - point.y); + } + else + { + Cam_MouseMoved(point.x, r.bottom - 1 - point.y, nFlags); + } + m_ptLastCursor = point; +} + +void CCamWnd::OnLButtonDown(UINT nFlags, CPoint point) +{ + m_ptLastCursor = point; + OriginalMouseDown(nFlags, point); +} + +void CCamWnd::OnLButtonUp(UINT nFlags, CPoint point) +{ + OriginalMouseUp(nFlags, point); +} + +void CCamWnd::OnMButtonDown(UINT nFlags, CPoint point) +{ + OriginalMouseDown(nFlags, point); +} + +void CCamWnd::OnMButtonUp(UINT nFlags, CPoint point) +{ + OriginalMouseUp(nFlags, point); +} + +void CCamWnd::OnRButtonDown(UINT nFlags, CPoint point) +{ + OriginalMouseDown(nFlags, point); +} + +void CCamWnd::OnRButtonUp(UINT nFlags, CPoint point) +{ + OriginalMouseUp(nFlags, point); +} + +int CCamWnd::OnCreate(LPCREATESTRUCT lpCreateStruct) +{ + if (CWnd::OnCreate(lpCreateStruct) == -1) + return -1; + + g_qeglobals.d_hdcBase = GetDC()->m_hDC; + QEW_SetupPixelFormat(g_qeglobals.d_hdcBase, true); + + if ((g_qeglobals.d_hglrcBase = qwglCreateContext(g_qeglobals.d_hdcBase)) == 0) + Error("wglCreateContext failed"); + + if (!qwglMakeCurrent(g_qeglobals.d_hdcBase, g_qeglobals.d_hglrcBase)) + Error ("wglMakeCurrent failed"); + + + // + // create GL font + // + HFONT hfont = ::CreateFont( + 12, // logical height of font + 6, // logical average character width + 0, // angle of escapement + 0, // base-line orientation angle + 0, // font weight + 0, // italic attribute flag + 0, // underline attribute flag + 0, // strikeout attribute flag + 0, // character set identifier + 0, // output precision + 0, // clipping precision + 0, // output quality + 0, // pitch and family + "system font" // pointer to typeface name string + ); + + if (!hfont) + Error( "couldn't create font" ); + + ::SelectObject(g_qeglobals.d_hdcBase, hfont); + + if ((g_qeglobals.d_font_list = qglGenLists (256)) == 0) + Error( "couldn't create font dlists" ); + + // create the bitmap display lists + // we're making images of glyphs 0 thru 255 + + if (g_PrefsDlg.m_bBuggyICD) + { + if ( !qwglUseFontBitmaps (g_qeglobals.d_hdcBase, 1, 255, g_qeglobals.d_font_list-1) ) + Error( "wglUseFontBitmaps faileD" ); + } + else + { + if ( !qwglUseFontBitmaps (g_qeglobals.d_hdcBase, 1, 255, g_qeglobals.d_font_list) ) + Error( "wglUseFontBitmaps faileD" ); + } + + // indicate start of glyph display lists + qglListBase (g_qeglobals.d_font_list); + + // report OpenGL information + Sys_Printf ("GL_VENDOR: %s\n", qglGetString (GL_VENDOR)); + Sys_Printf ("GL_RENDERER: %s\n", qglGetString (GL_RENDERER)); + Sys_Printf ("GL_VERSION: %s\n", qglGetString (GL_VERSION)); + Sys_Printf ("GL_EXTENSIONS: %s\n", qglGetString (GL_EXTENSIONS)); + + g_qeglobals.d_hwndCamera = GetSafeHwnd(); + + return 0; +} + +void CCamWnd::OriginalMouseUp(UINT nFlags, CPoint point) +{ + CRect r; + GetClientRect(r); + Cam_MouseUp(point.x, r.bottom - 1 - point.y, nFlags); + if (!(nFlags & (MK_LBUTTON|MK_RBUTTON|MK_MBUTTON))) + ReleaseCapture (); +} + +void CCamWnd::OriginalMouseDown(UINT nFlags, CPoint point) +{ + //if (GetTopWindow()->GetSafeHwnd() != GetSafeHwnd()) + // BringWindowToTop(); + CRect r; + GetClientRect(r); + SetFocus(); + SetCapture(); + //if (!(GetKeyState(VK_MENU) & 0x8000)) + Cam_MouseDown (point.x, r.bottom - 1 - point.y, nFlags); +} + +void CCamWnd::Cam_Init() +{ + //m_Camera.draw_mode = cd_texture; + m_Camera.timing = false; + m_Camera.origin[0] = 0; + m_Camera.origin[1] = 20; + m_Camera.origin[2] = 46; + m_Camera.color[0] = 0.3; + m_Camera.color[1] = 0.3; + m_Camera.color[2] = 0.3; +} + +void CCamWnd::Cam_BuildMatrix() +{ + float xa, ya; + float matrix[4][4]; + int i; + + xa = m_Camera.angles[0]/180*Q_PI; + ya = m_Camera.angles[1]/180*Q_PI; + + // the movement matrix is kept 2d + + m_Camera.forward[0] = cos(ya); + m_Camera.forward[1] = sin(ya); + m_Camera.right[0] = m_Camera.forward[1]; + m_Camera.right[1] = -m_Camera.forward[0]; + + qglGetFloatv (GL_PROJECTION_MATRIX, &matrix[0][0]); + + for (i=0 ; i<3 ; i++) + { + m_Camera.vright[i] = matrix[i][0]; + m_Camera.vup[i] = matrix[i][1]; + m_Camera.vpn[i] = matrix[i][2]; + } + + VectorNormalize (m_Camera.vright); + VectorNormalize (m_Camera.vup); + VectorNormalize (m_Camera.vpn); +} + + + +void CCamWnd::Cam_ChangeFloor (qboolean up) +{ + brush_t *b; + float d, bestd, current; + vec3_t start, dir; + + start[0] = m_Camera.origin[0]; + start[1] = m_Camera.origin[1]; + start[2] = 8192; + dir[0] = dir[1] = 0; + dir[2] = -1; + + current = 8192 - (m_Camera.origin[2] - 48); + if (up) + bestd = 0; + else + bestd = 16384; + + for (b=active_brushes.next ; b != &active_brushes ; b=b->next) + { + if ( b->pTerrain && !Terrain_Ray( start, dir, b, &d ) ) + continue; + if ( !b->pTerrain && !Brush_Ray (start, dir, b, &d) ) + continue; + if (up && d < current && d > bestd) + bestd = d; + if (!up && d > current && d < bestd) + bestd = d; + } + + if (bestd == 0 || bestd == 16384) + return; + + m_Camera.origin[2] += current - bestd; + Sys_UpdateWindows (W_CAMERA|W_Z_OVERLAY); +} + + +void CCamWnd::Cam_PositionDrag() +{ + int x, y; + Sys_GetCursorPos (&x, &y); + if (x != m_ptCursor.x || y != m_ptCursor.y) + { + x -= m_ptCursor.x; + VectorMA (m_Camera.origin, x, m_Camera.vright, m_Camera.origin); + y -= m_ptCursor.y; + m_Camera.origin[2] -= y; + SetCursorPos(m_ptCursor.x, m_ptCursor.y); + Sys_UpdateWindows (W_CAMERA | W_XY_OVERLAY); + } +} + + +void CCamWnd::Cam_MouseControl (float dtime) +{ + int xl, xh; + int yl, yh; + float xf, yf; + if (g_PrefsDlg.m_nMouseButtons == 2) + { + if (m_nCambuttonstate != (MK_RBUTTON | MK_SHIFT)) + return; + } + else + { + if (m_nCambuttonstate != MK_RBUTTON) + return; + } + + xf = (float)(m_ptButton.x - m_Camera.width/2) / (m_Camera.width/2); + yf = (float)(m_ptButton.y - m_Camera.height/2) / (m_Camera.height/2); + + + xl = m_Camera.width/3; + xh = xl*2; + yl = m_Camera.height/3; + yh = yl*2; + + //Sys_Printf("xf-%f yf-%f xl-%i xh-i% yl-i% yh-i%\n",xf,yf,xl,xh,yl,yh); +#if 0 + // strafe + if (buttony < yl && (buttonx < xl || buttonx > xh)) + VectorMA (camera.origin, xf*dtime*g_nMoveSpeed, camera.right, camera.origin); + else +#endif + { + xf *= 1.0 - fabs(yf); + if (xf < 0) + { + xf += 0.1; + if (xf > 0) + xf = 0; + } + else + { + xf -= 0.1; + if (xf < 0) + xf = 0; + } + + VectorMA (m_Camera.origin, yf*dtime*g_nMoveSpeed, m_Camera.forward, m_Camera.origin); + m_Camera.angles[YAW] += xf*-dtime*g_nAngleSpeed; + } + +#if 0 + if (g_PrefsDlg.m_bQE4Painting) + { + MSG msg; + if (::PeekMessage( &msg, NULL, 0, 0, PM_REMOVE )) + { + TranslateMessage(&msg); + DispatchMessage(&msg); + } + } +#endif + + int nUpdate = (g_PrefsDlg.m_bCamXYUpdate) ? (W_CAMERA | W_XY) : (W_CAMERA); + Sys_UpdateWindows (nUpdate); + g_pParentWnd->PostMessage(WM_TIMER, 0, 0); + +} + + + +void CCamWnd::Cam_MouseDown(int x, int y, int buttons) +{ + vec3_t dir; + float f, r, u; + int i; + + // + // calc ray direction + // + u = (float)(y - m_Camera.height/2) / (m_Camera.width/2); + r = (float)(x - m_Camera.width/2) / (m_Camera.width/2); + f = 1; + + for (i=0 ; i<3 ; i++) + dir[i] = m_Camera.vpn[i] * f + m_Camera.vright[i] * r + m_Camera.vup[i] * u; + VectorNormalize (dir); + + GetCursorPos(&m_ptCursor); + + m_nCambuttonstate = buttons; + m_ptButton.x = x; + m_ptButton.y = y; + + // 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 + int nMouseButton = g_PrefsDlg.m_nMouseButtons == 2 ? MK_RBUTTON : MK_MBUTTON; + if ((buttons == MK_LBUTTON) + || (buttons == (MK_LBUTTON | MK_SHIFT)) + || (buttons == (MK_LBUTTON | MK_CONTROL)) + || (buttons == (MK_LBUTTON | MK_CONTROL | MK_SHIFT)) + || (buttons == nMouseButton) + || (buttons == (nMouseButton|MK_SHIFT)) + || (buttons == (nMouseButton|MK_CONTROL)) + || (buttons == (nMouseButton|MK_SHIFT|MK_CONTROL))) + { + + if (g_PrefsDlg.m_nMouseButtons == 2 && (buttons == (MK_RBUTTON | MK_SHIFT))) + Cam_MouseControl (0.1); + else + { + // something global needs to track which window is responsible for stuff + Patch_SetView(W_CAMERA); + Drag_Begin (x, y, buttons, m_Camera.vright, m_Camera.vup, m_Camera.origin, dir); + } + return; + } + + if (buttons == MK_RBUTTON) + { + Cam_MouseControl (0.1); + return; + } +} + + +void CCamWnd::Cam_MouseUp (int x, int y, int buttons) +{ + m_nCambuttonstate = 0; + Drag_MouseUp (buttons); +} + + +void CCamWnd::Cam_MouseMoved (int x, int y, int buttons) +{ + m_nCambuttonstate = buttons; + if (!buttons) { + if ( ( g_qeglobals.d_select_mode == sel_terrainpoint ) || ( g_qeglobals.d_select_mode == sel_terraintexture ) ) { + vec3_t dir; + float f, r, u; + int i; + + // + // calc ray direction + // + u = (float)(y - m_Camera.height/2) / (m_Camera.width/2); + r = (float)(x - m_Camera.width/2) / (m_Camera.width/2); + f = 1; + + for (i=0 ; i<3 ; i++) + dir[i] = m_Camera.vpn[i] * f + m_Camera.vright[i] * r + m_Camera.vup[i] * u; + VectorNormalize (dir); + + m_ptButton.x = x; + m_ptButton.y = y; + + Terrain_SelectPointByRay( m_Camera.origin, dir, buttons ); + + Sys_UpdateWindows(W_CAMERA); + } + + return; + } + m_ptButton.x = x; + m_ptButton.y = y; + + if (buttons == (MK_RBUTTON|MK_CONTROL) ) + { + Cam_PositionDrag (); + Sys_UpdateWindows (W_XY|W_CAMERA|W_Z); + return; + } + + GetCursorPos(&m_ptCursor); + + if (buttons & (MK_LBUTTON | MK_MBUTTON) ) + { + Drag_MouseMoved (x, y, buttons); + Sys_UpdateWindows (W_XY|W_CAMERA|W_Z); + } +} + + +void CCamWnd::InitCull() +{ + int i; + + VectorSubtract (m_Camera.vpn, m_Camera.vright, m_vCull1); + VectorAdd (m_Camera.vpn, m_Camera.vright, m_vCull2); + + for (i=0 ; i<3 ; i++) + { + if (m_vCull1[i] > 0) + m_nCullv1[i] = 3+i; + else + m_nCullv1[i] = i; + if (m_vCull2[i] > 0) + m_nCullv2[i] = 3+i; + else + m_nCullv2[i] = i; + } +} + +qboolean CCamWnd::CullBrush (brush_t *b) +{ + int i; + vec3_t point; + float d; + + if (g_PrefsDlg.m_bCubicClipping) + { + float fLevel = g_PrefsDlg.m_nCubicScale * 64; + + point[0] = m_Camera.origin[0] - fLevel; + point[1] = m_Camera.origin[1] - fLevel; + point[2] = m_Camera.origin[2] - fLevel; + + for (i=0; i<3; i++) + if (b->mins[i] < point[i] && b->maxs[i] < point[i]) + return true; + + point[0] = m_Camera.origin[0] + fLevel; + point[1] = m_Camera.origin[1] + fLevel; + point[2] = m_Camera.origin[2] + fLevel; + + for (i=0; i<3; i++) + if (b->mins[i] > point[i] && b->maxs[i] > point[i]) + return true; + } + + + for (i=0 ; i<3 ; i++) + point[i] = b->mins[m_nCullv1[i]] - m_Camera.origin[i]; + + d = DotProduct (point, m_vCull1); + if (d < -1) + return true; + + for (i=0 ; i<3 ; i++) + point[i] = b->mins[m_nCullv2[i]] - m_Camera.origin[i]; + + d = DotProduct (point, m_vCull2); + if (d < -1) + return true; + + return false; +} + +#if 0 +void CCamWnd::DrawLightRadius(brush_t* pBrush) +{ + // if lighting + int nRadius = Brush_LightRadius(pBrush); + if (nRadius > 0) + { + Brush_SetLightColor(pBrush); + qglEnable (GL_BLEND); + qglPolygonMode (GL_FRONT_AND_BACK, GL_LINE); + qglBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + qglDisable (GL_TEXTURE_2D); + + qglEnable(GL_TEXTURE_2D); + qglDisable(GL_BLEND); + qglPolygonMode (GL_FRONT_AND_BACK, GL_FILL); + } +} +#endif + +/* +============== +Cam_Draw +============== +*/ + +void CCamWnd::Cam_Draw() +{ + brush_t *brush; + face_t *face; + float screenaspect; + float yfov; + double start, end; + int i; + + /* + FILE *f = fopen("g:/nardo/raduffy/editorhack.dat", "w"); + if (f != NULL) { + fwrite(&m_Camera.origin[0], sizeof(float), 1, f); + fwrite(&m_Camera.origin[1], sizeof(float), 1, f); + fwrite(&m_Camera.origin[2], sizeof(float), 1, f); + fwrite(&m_Camera.angles[PITCH], sizeof(float), 1, f); + fwrite(&m_Camera.angles[YAW], sizeof(float), 1, f); + fclose(f); + } + */ + + if (!active_brushes.next) + return; // not valid yet + + if (m_Camera.timing) + start = Sys_DoubleTime (); + + // + // clear + // + QE_CheckOpenGLForErrors(); + + qglViewport(0, 0, m_Camera.width, m_Camera.height); + qglScissor(0, 0, m_Camera.width, m_Camera.height); + qglClearColor (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); + qglClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + // + // set up viewpoint + // + vec5_t lightPos; + + if (g_PrefsDlg.m_bGLLighting) + { + qglEnable(GL_LIGHTING); + //qglEnable(GL_LIGHT0); + + lightPos[0] = lightPos[1] = lightPos[2] = 3.5; + lightPos[3] = 1.0; + qglLightModelfv(GL_LIGHT_MODEL_AMBIENT, lightPos); + //qglLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, GL_TRUE); + //lightPos[0] = lightPos[1] = lightPos[2] = 3.5; + //qglLightfv(GL_LIGHT0, GL_AMBIENT, lightPos); + } + else + { + qglDisable(GL_LIGHTING); + } + + qglMatrixMode(GL_PROJECTION); + qglLoadIdentity (); + + screenaspect = (float)m_Camera.width / m_Camera.height; + yfov = 2*atan((float)m_Camera.height / m_Camera.width)*180/Q_PI; + qgluPerspective (yfov, screenaspect, 2, 8192); + + qglRotatef (-90, 1, 0, 0); // put Z going up + qglRotatef (90, 0, 0, 1); // put Z going up + qglRotatef (m_Camera.angles[0], 0, 1, 0); + qglRotatef (-m_Camera.angles[1], 0, 0, 1); + qglTranslatef (-m_Camera.origin[0], -m_Camera.origin[1], -m_Camera.origin[2]); + + Cam_BuildMatrix (); + + + //if (m_Camera.draw_mode == cd_light) + //{ +// if (g_PrefsDlg.m_bGLLighting) +// { +// VectorCopy(m_Camera.origin, lightPos); +// lightPos[3] = 1; +// qglLightfv(GL_LIGHT0, GL_POSITION, lightPos); +// } + //} + + InitCull (); + + // + // draw stuff + // + GLfloat lAmbient[] = {1.0, 1.0, 1.0, 1.0}; + + switch (m_Camera.draw_mode) + { + case cd_wire: + qglPolygonMode (GL_FRONT_AND_BACK, GL_LINE); + qglDisable(GL_TEXTURE_2D); + qglDisable(GL_TEXTURE_1D); + qglDisable(GL_BLEND); + qglDisable(GL_DEPTH_TEST); + qglColor3f(1.0, 1.0, 1.0); + // qglEnable (GL_LINE_SMOOTH); + break; + + case cd_solid: + qglCullFace(GL_FRONT); + qglEnable(GL_CULL_FACE); + qglShadeModel (GL_FLAT); + qglPolygonMode (GL_FRONT_AND_BACK, GL_FILL); + qglDisable(GL_TEXTURE_2D); + qglDisable(GL_BLEND); + qglEnable(GL_DEPTH_TEST); + qglDepthFunc (GL_LEQUAL); + break; + + case cd_texture: + qglCullFace(GL_FRONT); + qglEnable(GL_CULL_FACE); + qglShadeModel (GL_FLAT); + qglPolygonMode (GL_FRONT_AND_BACK, GL_FILL); + qglEnable(GL_TEXTURE_2D); + qglTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); + qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); + qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); + qglDisable(GL_BLEND); + qglEnable(GL_DEPTH_TEST); + qglDepthFunc (GL_LEQUAL); + break; + + case cd_blend: + qglCullFace(GL_FRONT); + qglEnable(GL_CULL_FACE); + qglShadeModel (GL_FLAT); + qglPolygonMode (GL_FRONT_AND_BACK, GL_FILL); + qglEnable(GL_TEXTURE_2D); + qglTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); + qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); + qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); + qglDisable(GL_DEPTH_TEST); + qglEnable (GL_BLEND); + qglBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + break; + } + + qglMatrixMode(GL_TEXTURE); + + m_nNumTransBrushes = 0; + + for (brush = active_brushes.next ; brush != &active_brushes ; brush=brush->next) + { + //DrawLightRadius(brush); + + if (CullBrush (brush)) + continue; + + if (FilterBrush (brush)) + continue; + + if ((brush->brush_faces->texdef.flags & (SURF_TRANS33 | SURF_TRANS66)) || (brush->brush_faces->d_texture->bFromShader && brush->brush_faces->d_texture->fTrans != 1.0)) + { + m_TransBrushes [ m_nNumTransBrushes++ ] = brush; + } + else + { + //-- if (brush->patchBrush) + //-- m_TransBrushes [ m_nNumTransBrushes++ ] = brush; + //-- else + Brush_Draw(brush); + } + + + } + + if (g_PrefsDlg.m_bGLLighting) + { + qglDisable (GL_LIGHTING); + } + + // + //qglDepthMask ( 0 ); // Don't write to depth buffer + qglEnable ( GL_BLEND ); + qglBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + for ( i = 0; i < m_nNumTransBrushes; i++ ) + Brush_Draw (m_TransBrushes[i]); + + //qglDepthMask ( 1 ); // Ok, write now + + qglMatrixMode(GL_PROJECTION); + + // + // now draw selected brushes + // + + if (g_PrefsDlg.m_bGLLighting) + { + qglEnable (GL_LIGHTING); + } + + qglTranslatef (g_qeglobals.d_select_translate[0], g_qeglobals.d_select_translate[1], g_qeglobals.d_select_translate[2]); + qglMatrixMode(GL_TEXTURE); + + brush_t* pList = (g_bClipMode && g_pSplitList) ? g_pSplitList : &selected_brushes; + // draw normally + for (brush = pList->next ; brush != pList ; brush=brush->next) + { + //DrawLightRadius(brush); + //if (brush->patchBrush && g_qeglobals.d_select_mode == sel_curvepoint) + // continue; + + Brush_Draw(brush); + } + + // blend on top + qglMatrixMode(GL_PROJECTION); + + + qglDisable (GL_LIGHTING); + qglColor4f(1.0, 0.0, 0.0, 0.3); + qglEnable (GL_BLEND); + qglPolygonMode (GL_FRONT_AND_BACK, GL_FILL); + qglBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + qglDisable (GL_TEXTURE_2D); + for (brush = pList->next ; brush != pList ; brush=brush->next) + { + if ( (brush->patchBrush && g_qeglobals.d_select_mode == sel_curvepoint) || + (brush->terrainBrush && g_qeglobals.d_select_mode == sel_terrainpoint) ) + continue; + + for (face=brush->brush_faces ; face ; face=face->next) + Face_Draw( face ); + } + + + int nCount = g_ptrSelectedFaces.GetSize(); + if (nCount > 0) + { + for (int i = 0; i < nCount; i++) + { + face_t *selFace = reinterpret_cast(g_ptrSelectedFaces.GetAt(i)); + Face_Draw(selFace); + } + } + + // non-zbuffered outline + + qglDisable (GL_BLEND); + qglDisable (GL_DEPTH_TEST); + qglPolygonMode (GL_FRONT_AND_BACK, GL_LINE); + qglColor3f (1, 1, 1); + for (brush = pList->next ; brush != pList ; brush=brush->next) + { + if (g_qeglobals.dontDrawSelectedOutlines || (brush->patchBrush && g_qeglobals.d_select_mode == sel_curvepoint) || + (brush->terrainBrush && g_qeglobals.d_select_mode == sel_terrainpoint)) + continue; + + for (face=brush->brush_faces ; face ; face=face->next) + Face_Draw( face ); + } + + + // edge / vertex flags + + if (g_qeglobals.d_select_mode == sel_vertex) + { + qglPointSize (4); + qglColor3f (0,1,0); + qglBegin (GL_POINTS); + for (i=0 ; idraw(static_cast(g_qeglobals.d_select_mode == sel_addpoint || g_qeglobals.d_select_mode == sel_editpoint)); + if (g_qeglobals.selectObject && (g_qeglobals.d_select_mode == sel_addpoint || g_qeglobals.d_select_mode == sel_editpoint)) { + g_qeglobals.selectObject->drawSelection(); + } + + // + // draw pointfile + // + + qglEnable(GL_DEPTH_TEST); + + + DrawPathLines (); + + + + if (g_qeglobals.d_pointfile_display_list) + { + Pointfile_Draw(); + // glCallList (g_qeglobals.d_pointfile_display_list); + } + + // bind back to the default texture so that we don't have problems + // elsewhere using/modifying texture maps between contexts + qglBindTexture( GL_TEXTURE_2D, 0 ); + +#if 0 + // area selection hack + if (g_qeglobals.d_select_mode == sel_area) + { + qglEnable (GL_BLEND); + qglBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + qglColor4f(0.0, 0.0, 1.0, 0.25); + qglPolygonMode (GL_FRONT_AND_BACK, GL_FILL); + qglRectfv(g_qeglobals.d_vAreaTL, g_qeglobals.d_vAreaBR); + qglDisable (GL_BLEND); + } +#endif + + qglFinish(); + QE_CheckOpenGLForErrors(); + // Sys_EndWait(); + if (m_Camera.timing) + { + end = Sys_DoubleTime (); + Sys_Printf ("Camera: %i ms\n", (int)(1000*(end-start))); + } +} + + +void CCamWnd::OnSize(UINT nType, int cx, int cy) +{ + CWnd::OnSize(nType, cx, cy); + CRect rect; + GetClientRect(rect); + m_Camera.width = rect.right; + m_Camera.height = rect.bottom; + InvalidateRect(NULL, false); +} + +void CCamWnd::BenchMark() +{ + PAINTSTRUCT ps; + CRect rct; + GetWindowRect(rct); + long lStyle = ::GetWindowLong(GetSafeHwnd(), GWL_STYLE); + ::SetWindowLong(GetSafeHwnd(), GWL_STYLE, QE3_CHILDSTYLE); + CWnd* pParent = GetParent(); + SetParent(g_pParentWnd); + MoveWindow(CRect(30, 30, 400, 400), TRUE); + + BeginPaint(&ps); + if (!qwglMakeCurrent(ps.hdc, g_qeglobals.d_hglrcBase)) + Error ("wglMakeCurrent failed in Benchmark"); + + qglDrawBuffer (GL_FRONT); + double dStart = Sys_DoubleTime (); + for (int i=0 ; i < 100 ; i++) + { + m_Camera.angles[YAW] = i*4; + Cam_Draw(); + } + qwglSwapBuffers(ps.hdc); + qglDrawBuffer (GL_BACK); + double dEnd = Sys_DoubleTime (); + EndPaint(&ps); + Sys_Printf ("%5.2f seconds\n", dEnd - dStart); + ::SetWindowLong(GetSafeHwnd(), GWL_STYLE, lStyle); + SetParent(pParent); + MoveWindow(rct, TRUE); +} + +void CCamWnd::ReInitGL() +{ + + qwglMakeCurrent(0,0); + QEW_SetupPixelFormat(GetDC()->m_hDC, true); + if (!qwglMakeCurrent(g_qeglobals.d_hdcBase, g_qeglobals.d_hglrcBase)) + Error ("wglMakeCurrent failed"); + + return; + + long lStyle = ::GetWindowLong(GetSafeHwnd(), GWL_STYLE); + int nID = ::GetWindowLong(GetSafeHwnd(), GWL_ID); + CWnd* pParent = GetParent(); + CRect rctClient; + GetClientRect(rctClient); + DestroyWindow(); + Create(CAMERA_WINDOW_CLASS, "", lStyle, rctClient, pParent, nID); +} + +void CCamWnd::OnKeyUp(UINT nChar, UINT nRepCnt, UINT nFlags) +{ + g_pParentWnd->HandleKey(nChar, nRepCnt, nFlags, false); +} + +// Timo +// brush primitive texture shifting, using camera view to select translations : +void CCamWnd::ShiftTexture_BrushPrimit(face_t *f, int x, int y) +{ + vec3_t texS,texT; + vec3_t viewX,viewY; + int XS,XT,YS,YT; + int outS,outT; +#ifdef _DEBUG + if (!g_qeglobals.m_bBrushPrimitMode) + { + Sys_Printf("Warning : unexpected call to CCamWnd::ShiftTexture_BrushPrimit with brush primitive mode disbaled\n"); + return; + } +#endif + // compute face axis base + ComputeAxisBase( f->plane.normal, texS, texT ); + // compute camera view vectors + VectorCopy( m_Camera.vup, viewY ); + VectorCopy( m_Camera.vright, viewX ); + // compute best vectors + ComputeBest2DVector( viewX, texS, texT, XS, XT ); + ComputeBest2DVector( viewY, texS, texT, YS, YT ); + // check this is not a degenerate case + if ( ( XS == YS ) && ( XT == YT ) ) + { +#ifdef _DEBUG + Sys_Printf("Warning : degenerate best vectors axis base in CCamWnd::ShiftTexture_BrushPrimit\n"); +#endif + // forget it + Select_ShiftTexture_BrushPrimit( f, x, y ); + return; + } + // compute best fitted translation in face axis base + outS = XS*x + YS*y; + outT = XT*x + YT*y; + // call actual texture shifting code + Select_ShiftTexture_BrushPrimit( f, outS, outT ); +} -- cgit v1.2.3