CamWnd.cpp (27714B)
1 /* 2 =========================================================================== 3 Copyright (C) 1999-2005 Id Software, Inc. 4 5 This file is part of Quake III Arena source code. 6 7 Quake III Arena source code is free software; you can redistribute it 8 and/or modify it under the terms of the GNU General Public License as 9 published by the Free Software Foundation; either version 2 of the License, 10 or (at your option) any later version. 11 12 Quake III Arena source code is distributed in the hope that it will be 13 useful, but WITHOUT ANY WARRANTY; without even the implied warranty of 14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 GNU General Public License for more details. 16 17 You should have received a copy of the GNU General Public License 18 along with Foobar; if not, write to the Free Software 19 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 20 =========================================================================== 21 */ 22 // CamWnd.cpp : implementation file 23 // 24 25 #include "stdafx.h" 26 #include "Radiant.h" 27 #include "XYWnd.h" 28 #include "CamWnd.h" 29 #include "qe3.h" 30 #include "splines/splines.h" 31 32 #ifdef _DEBUG 33 #define new DEBUG_NEW 34 #undef THIS_FILE 35 static char THIS_FILE[] = __FILE__; 36 #endif 37 38 extern void DrawPathLines(); 39 40 int g_nAngleSpeed = 300; 41 int g_nMoveSpeed = 400; 42 43 44 ///////////////////////////////////////////////////////////////////////////// 45 // CCamWnd 46 IMPLEMENT_DYNCREATE(CCamWnd, CWnd); 47 48 CCamWnd::CCamWnd() 49 { 50 m_pXYFriend = NULL; 51 m_nNumTransBrushes = 0; 52 memset(&m_Camera, 0, sizeof(camera_t)); 53 m_pSide_select = NULL; 54 m_bClipMode = false; 55 Cam_Init(); 56 } 57 58 CCamWnd::~CCamWnd() 59 { 60 } 61 62 63 BEGIN_MESSAGE_MAP(CCamWnd, CWnd) 64 //{{AFX_MSG_MAP(CCamWnd) 65 ON_WM_KEYDOWN() 66 ON_WM_PAINT() 67 ON_WM_DESTROY() 68 ON_WM_CLOSE() 69 ON_WM_MOUSEMOVE() 70 ON_WM_LBUTTONDOWN() 71 ON_WM_LBUTTONUP() 72 ON_WM_MBUTTONDOWN() 73 ON_WM_MBUTTONUP() 74 ON_WM_RBUTTONDOWN() 75 ON_WM_RBUTTONUP() 76 ON_WM_CREATE() 77 ON_WM_SIZE() 78 ON_WM_NCCALCSIZE() 79 ON_WM_KILLFOCUS() 80 ON_WM_SETFOCUS() 81 ON_WM_KEYUP() 82 //}}AFX_MSG_MAP 83 END_MESSAGE_MAP() 84 85 86 LONG WINAPI CamWndProc ( 87 HWND hWnd, 88 UINT uMsg, 89 WPARAM wParam, 90 LPARAM lParam) 91 { 92 RECT rect; 93 94 GetClientRect(hWnd, &rect); 95 96 switch (uMsg) 97 { 98 case WM_KILLFOCUS: 99 case WM_SETFOCUS: 100 SendMessage( hWnd, WM_NCACTIVATE, uMsg == WM_SETFOCUS, 0 ); 101 return 0; 102 103 case WM_NCCALCSIZE:// don't let windows copy pixels 104 DefWindowProc (hWnd, uMsg, wParam, lParam); 105 return WVR_REDRAW; 106 107 } 108 109 return DefWindowProc( hWnd, uMsg, wParam, lParam ); 110 } 111 112 113 ///////////////////////////////////////////////////////////////////////////// 114 // CCamWnd message handlers 115 116 BOOL CCamWnd::PreCreateWindow(CREATESTRUCT& cs) 117 { 118 WNDCLASS wc; 119 HINSTANCE hInstance = AfxGetInstanceHandle(); 120 if (::GetClassInfo(hInstance, CAMERA_WINDOW_CLASS, &wc) == FALSE) 121 { 122 // Register a new class 123 memset (&wc, 0, sizeof(wc)); 124 wc.style = CS_NOCLOSE | CS_OWNDC; 125 wc.lpszClassName = CAMERA_WINDOW_CLASS; 126 wc.hCursor = LoadCursor (NULL,IDC_ARROW); 127 wc.lpfnWndProc = CamWndProc; 128 if (AfxRegisterClass(&wc) == FALSE) 129 Error ("CCamWnd RegisterClass: failed"); 130 } 131 132 cs.lpszClass = CAMERA_WINDOW_CLASS; 133 cs.lpszName = "CAM"; 134 if (cs.style != QE3_CHILDSTYLE) 135 cs.style = QE3_SPLITTER_STYLE; 136 137 BOOL bResult = CWnd::PreCreateWindow(cs); 138 139 // See if the class already exists and if not then we need 140 // to register our new window class. 141 return bResult; 142 143 } 144 145 146 void CCamWnd::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags) 147 { 148 g_pParentWnd->HandleKey(nChar, nRepCnt, nFlags); 149 } 150 151 152 brush_t* g_pSplitList = NULL; 153 154 void CCamWnd::OnPaint() 155 { 156 CPaintDC dc(this); // device context for painting 157 bool bPaint = true; 158 if (!qwglMakeCurrent( dc.m_hDC, g_qeglobals.d_hglrcBase )) 159 { 160 Sys_Printf("ERROR: wglMakeCurrent failed..\n "); 161 Sys_Printf("Please restart Q3Radiant if the camera view is not working\n"); 162 } 163 else 164 { 165 QE_CheckOpenGLForErrors(); 166 g_pSplitList = NULL; 167 if (g_bClipMode) 168 { 169 if (g_Clip1.Set() && g_Clip2.Set()) 170 { 171 g_pSplitList = ( (g_pParentWnd->ActiveXY()->GetViewType() == XZ) ? !g_bSwitch : g_bSwitch) ? &g_brBackSplits : &g_brFrontSplits; 172 } 173 } 174 Cam_Draw (); 175 QE_CheckOpenGLForErrors(); 176 qwglSwapBuffers(dc.m_hDC); 177 } 178 } 179 180 181 void CCamWnd::SetXYFriend(CXYWnd * pWnd) 182 { 183 m_pXYFriend = pWnd; 184 } 185 186 void CCamWnd::OnDestroy() 187 { 188 QEW_StopGL(GetSafeHwnd(), g_qeglobals.d_hglrcBase, g_qeglobals.d_hdcBase ); 189 CWnd::OnDestroy(); 190 } 191 192 void CCamWnd::OnClose() 193 { 194 CWnd::OnClose(); 195 } 196 197 extern void Select_ShiftTexture(int x, int y); 198 extern void Select_RotateTexture(int amt); 199 extern void Select_ScaleTexture(int x, int y); 200 void CCamWnd::OnMouseMove(UINT nFlags, CPoint point) 201 { 202 CRect r; 203 GetClientRect(r); 204 if (GetCapture() == this && (GetKeyState(VK_MENU) & 0x8000) && !((GetKeyState(VK_SHIFT) & 0x8000) || (GetKeyState(VK_CONTROL) & 0x8000))) 205 { 206 if (GetKeyState(VK_CONTROL) & 0x8000) 207 Select_RotateTexture(point.y - m_ptLastCursor.y); 208 else 209 if (GetKeyState(VK_SHIFT) & 0x8000) 210 Select_ScaleTexture(point.x - m_ptLastCursor.x, m_ptLastCursor.y - point.y); 211 else 212 Select_ShiftTexture(point.x - m_ptLastCursor.x, m_ptLastCursor.y - point.y); 213 } 214 else 215 { 216 Cam_MouseMoved(point.x, r.bottom - 1 - point.y, nFlags); 217 } 218 m_ptLastCursor = point; 219 } 220 221 void CCamWnd::OnLButtonDown(UINT nFlags, CPoint point) 222 { 223 m_ptLastCursor = point; 224 OriginalMouseDown(nFlags, point); 225 } 226 227 void CCamWnd::OnLButtonUp(UINT nFlags, CPoint point) 228 { 229 OriginalMouseUp(nFlags, point); 230 } 231 232 void CCamWnd::OnMButtonDown(UINT nFlags, CPoint point) 233 { 234 OriginalMouseDown(nFlags, point); 235 } 236 237 void CCamWnd::OnMButtonUp(UINT nFlags, CPoint point) 238 { 239 OriginalMouseUp(nFlags, point); 240 } 241 242 void CCamWnd::OnRButtonDown(UINT nFlags, CPoint point) 243 { 244 OriginalMouseDown(nFlags, point); 245 } 246 247 void CCamWnd::OnRButtonUp(UINT nFlags, CPoint point) 248 { 249 OriginalMouseUp(nFlags, point); 250 } 251 252 int CCamWnd::OnCreate(LPCREATESTRUCT lpCreateStruct) 253 { 254 if (CWnd::OnCreate(lpCreateStruct) == -1) 255 return -1; 256 257 g_qeglobals.d_hdcBase = GetDC()->m_hDC; 258 QEW_SetupPixelFormat(g_qeglobals.d_hdcBase, true); 259 260 if ((g_qeglobals.d_hglrcBase = qwglCreateContext(g_qeglobals.d_hdcBase)) == 0) 261 Error("wglCreateContext failed"); 262 263 if (!qwglMakeCurrent(g_qeglobals.d_hdcBase, g_qeglobals.d_hglrcBase)) 264 Error ("wglMakeCurrent failed"); 265 266 267 // 268 // create GL font 269 // 270 HFONT hfont = ::CreateFont( 271 12, // logical height of font 272 6, // logical average character width 273 0, // angle of escapement 274 0, // base-line orientation angle 275 0, // font weight 276 0, // italic attribute flag 277 0, // underline attribute flag 278 0, // strikeout attribute flag 279 0, // character set identifier 280 0, // output precision 281 0, // clipping precision 282 0, // output quality 283 0, // pitch and family 284 "system font" // pointer to typeface name string 285 ); 286 287 if (!hfont) 288 Error( "couldn't create font" ); 289 290 ::SelectObject(g_qeglobals.d_hdcBase, hfont); 291 292 if ((g_qeglobals.d_font_list = qglGenLists (256)) == 0) 293 Error( "couldn't create font dlists" ); 294 295 // create the bitmap display lists 296 // we're making images of glyphs 0 thru 255 297 298 if (g_PrefsDlg.m_bBuggyICD) 299 { 300 if ( !qwglUseFontBitmaps (g_qeglobals.d_hdcBase, 1, 255, g_qeglobals.d_font_list-1) ) 301 Error( "wglUseFontBitmaps faileD" ); 302 } 303 else 304 { 305 if ( !qwglUseFontBitmaps (g_qeglobals.d_hdcBase, 1, 255, g_qeglobals.d_font_list) ) 306 Error( "wglUseFontBitmaps faileD" ); 307 } 308 309 // indicate start of glyph display lists 310 qglListBase (g_qeglobals.d_font_list); 311 312 // report OpenGL information 313 Sys_Printf ("GL_VENDOR: %s\n", qglGetString (GL_VENDOR)); 314 Sys_Printf ("GL_RENDERER: %s\n", qglGetString (GL_RENDERER)); 315 Sys_Printf ("GL_VERSION: %s\n", qglGetString (GL_VERSION)); 316 Sys_Printf ("GL_EXTENSIONS: %s\n", qglGetString (GL_EXTENSIONS)); 317 318 g_qeglobals.d_hwndCamera = GetSafeHwnd(); 319 320 return 0; 321 } 322 323 void CCamWnd::OriginalMouseUp(UINT nFlags, CPoint point) 324 { 325 CRect r; 326 GetClientRect(r); 327 Cam_MouseUp(point.x, r.bottom - 1 - point.y, nFlags); 328 if (!(nFlags & (MK_LBUTTON|MK_RBUTTON|MK_MBUTTON))) 329 ReleaseCapture (); 330 } 331 332 void CCamWnd::OriginalMouseDown(UINT nFlags, CPoint point) 333 { 334 //if (GetTopWindow()->GetSafeHwnd() != GetSafeHwnd()) 335 // BringWindowToTop(); 336 CRect r; 337 GetClientRect(r); 338 SetFocus(); 339 SetCapture(); 340 //if (!(GetKeyState(VK_MENU) & 0x8000)) 341 Cam_MouseDown (point.x, r.bottom - 1 - point.y, nFlags); 342 } 343 344 void CCamWnd::Cam_Init() 345 { 346 //m_Camera.draw_mode = cd_texture; 347 m_Camera.timing = false; 348 m_Camera.origin[0] = 0; 349 m_Camera.origin[1] = 20; 350 m_Camera.origin[2] = 46; 351 m_Camera.color[0] = 0.3; 352 m_Camera.color[1] = 0.3; 353 m_Camera.color[2] = 0.3; 354 } 355 356 void CCamWnd::Cam_BuildMatrix() 357 { 358 float xa, ya; 359 float matrix[4][4]; 360 int i; 361 362 xa = m_Camera.angles[0]/180*Q_PI; 363 ya = m_Camera.angles[1]/180*Q_PI; 364 365 // the movement matrix is kept 2d 366 367 m_Camera.forward[0] = cos(ya); 368 m_Camera.forward[1] = sin(ya); 369 m_Camera.right[0] = m_Camera.forward[1]; 370 m_Camera.right[1] = -m_Camera.forward[0]; 371 372 qglGetFloatv (GL_PROJECTION_MATRIX, &matrix[0][0]); 373 374 for (i=0 ; i<3 ; i++) 375 { 376 m_Camera.vright[i] = matrix[i][0]; 377 m_Camera.vup[i] = matrix[i][1]; 378 m_Camera.vpn[i] = matrix[i][2]; 379 } 380 381 VectorNormalize (m_Camera.vright); 382 VectorNormalize (m_Camera.vup); 383 VectorNormalize (m_Camera.vpn); 384 } 385 386 387 388 void CCamWnd::Cam_ChangeFloor (qboolean up) 389 { 390 brush_t *b; 391 float d, bestd, current; 392 vec3_t start, dir; 393 394 start[0] = m_Camera.origin[0]; 395 start[1] = m_Camera.origin[1]; 396 start[2] = 8192; 397 dir[0] = dir[1] = 0; 398 dir[2] = -1; 399 400 current = 8192 - (m_Camera.origin[2] - 48); 401 if (up) 402 bestd = 0; 403 else 404 bestd = 16384; 405 406 for (b=active_brushes.next ; b != &active_brushes ; b=b->next) 407 { 408 if ( b->pTerrain && !Terrain_Ray( start, dir, b, &d ) ) 409 continue; 410 if ( !b->pTerrain && !Brush_Ray (start, dir, b, &d) ) 411 continue; 412 if (up && d < current && d > bestd) 413 bestd = d; 414 if (!up && d > current && d < bestd) 415 bestd = d; 416 } 417 418 if (bestd == 0 || bestd == 16384) 419 return; 420 421 m_Camera.origin[2] += current - bestd; 422 Sys_UpdateWindows (W_CAMERA|W_Z_OVERLAY); 423 } 424 425 426 void CCamWnd::Cam_PositionDrag() 427 { 428 int x, y; 429 Sys_GetCursorPos (&x, &y); 430 if (x != m_ptCursor.x || y != m_ptCursor.y) 431 { 432 x -= m_ptCursor.x; 433 VectorMA (m_Camera.origin, x, m_Camera.vright, m_Camera.origin); 434 y -= m_ptCursor.y; 435 m_Camera.origin[2] -= y; 436 SetCursorPos(m_ptCursor.x, m_ptCursor.y); 437 Sys_UpdateWindows (W_CAMERA | W_XY_OVERLAY); 438 } 439 } 440 441 442 void CCamWnd::Cam_MouseControl (float dtime) 443 { 444 int xl, xh; 445 int yl, yh; 446 float xf, yf; 447 if (g_PrefsDlg.m_nMouseButtons == 2) 448 { 449 if (m_nCambuttonstate != (MK_RBUTTON | MK_SHIFT)) 450 return; 451 } 452 else 453 { 454 if (m_nCambuttonstate != MK_RBUTTON) 455 return; 456 } 457 458 xf = (float)(m_ptButton.x - m_Camera.width/2) / (m_Camera.width/2); 459 yf = (float)(m_ptButton.y - m_Camera.height/2) / (m_Camera.height/2); 460 461 462 xl = m_Camera.width/3; 463 xh = xl*2; 464 yl = m_Camera.height/3; 465 yh = yl*2; 466 467 //Sys_Printf("xf-%f yf-%f xl-%i xh-i% yl-i% yh-i%\n",xf,yf,xl,xh,yl,yh); 468 #if 0 469 // strafe 470 if (buttony < yl && (buttonx < xl || buttonx > xh)) 471 VectorMA (camera.origin, xf*dtime*g_nMoveSpeed, camera.right, camera.origin); 472 else 473 #endif 474 { 475 xf *= 1.0 - fabs(yf); 476 if (xf < 0) 477 { 478 xf += 0.1; 479 if (xf > 0) 480 xf = 0; 481 } 482 else 483 { 484 xf -= 0.1; 485 if (xf < 0) 486 xf = 0; 487 } 488 489 VectorMA (m_Camera.origin, yf*dtime*g_nMoveSpeed, m_Camera.forward, m_Camera.origin); 490 m_Camera.angles[YAW] += xf*-dtime*g_nAngleSpeed; 491 } 492 493 #if 0 494 if (g_PrefsDlg.m_bQE4Painting) 495 { 496 MSG msg; 497 if (::PeekMessage( &msg, NULL, 0, 0, PM_REMOVE )) 498 { 499 TranslateMessage(&msg); 500 DispatchMessage(&msg); 501 } 502 } 503 #endif 504 505 int nUpdate = (g_PrefsDlg.m_bCamXYUpdate) ? (W_CAMERA | W_XY) : (W_CAMERA); 506 Sys_UpdateWindows (nUpdate); 507 g_pParentWnd->PostMessage(WM_TIMER, 0, 0); 508 509 } 510 511 512 513 void CCamWnd::Cam_MouseDown(int x, int y, int buttons) 514 { 515 vec3_t dir; 516 float f, r, u; 517 int i; 518 519 // 520 // calc ray direction 521 // 522 u = (float)(y - m_Camera.height/2) / (m_Camera.width/2); 523 r = (float)(x - m_Camera.width/2) / (m_Camera.width/2); 524 f = 1; 525 526 for (i=0 ; i<3 ; i++) 527 dir[i] = m_Camera.vpn[i] * f + m_Camera.vright[i] * r + m_Camera.vup[i] * u; 528 VectorNormalize (dir); 529 530 GetCursorPos(&m_ptCursor); 531 532 m_nCambuttonstate = buttons; 533 m_ptButton.x = x; 534 m_ptButton.y = y; 535 536 // LBUTTON = manipulate selection 537 // shift-LBUTTON = select 538 // middle button = grab texture 539 // ctrl-middle button = set entire brush to texture 540 // ctrl-shift-middle button = set single face to texture 541 int nMouseButton = g_PrefsDlg.m_nMouseButtons == 2 ? MK_RBUTTON : MK_MBUTTON; 542 if ((buttons == MK_LBUTTON) 543 || (buttons == (MK_LBUTTON | MK_SHIFT)) 544 || (buttons == (MK_LBUTTON | MK_CONTROL)) 545 || (buttons == (MK_LBUTTON | MK_CONTROL | MK_SHIFT)) 546 || (buttons == nMouseButton) 547 || (buttons == (nMouseButton|MK_SHIFT)) 548 || (buttons == (nMouseButton|MK_CONTROL)) 549 || (buttons == (nMouseButton|MK_SHIFT|MK_CONTROL))) 550 { 551 552 if (g_PrefsDlg.m_nMouseButtons == 2 && (buttons == (MK_RBUTTON | MK_SHIFT))) 553 Cam_MouseControl (0.1); 554 else 555 { 556 // something global needs to track which window is responsible for stuff 557 Patch_SetView(W_CAMERA); 558 Drag_Begin (x, y, buttons, m_Camera.vright, m_Camera.vup, m_Camera.origin, dir); 559 } 560 return; 561 } 562 563 if (buttons == MK_RBUTTON) 564 { 565 Cam_MouseControl (0.1); 566 return; 567 } 568 } 569 570 571 void CCamWnd::Cam_MouseUp (int x, int y, int buttons) 572 { 573 m_nCambuttonstate = 0; 574 Drag_MouseUp (buttons); 575 } 576 577 578 void CCamWnd::Cam_MouseMoved (int x, int y, int buttons) 579 { 580 m_nCambuttonstate = buttons; 581 if (!buttons) { 582 if ( ( g_qeglobals.d_select_mode == sel_terrainpoint ) || ( g_qeglobals.d_select_mode == sel_terraintexture ) ) { 583 vec3_t dir; 584 float f, r, u; 585 int i; 586 587 // 588 // calc ray direction 589 // 590 u = (float)(y - m_Camera.height/2) / (m_Camera.width/2); 591 r = (float)(x - m_Camera.width/2) / (m_Camera.width/2); 592 f = 1; 593 594 for (i=0 ; i<3 ; i++) 595 dir[i] = m_Camera.vpn[i] * f + m_Camera.vright[i] * r + m_Camera.vup[i] * u; 596 VectorNormalize (dir); 597 598 m_ptButton.x = x; 599 m_ptButton.y = y; 600 601 Terrain_SelectPointByRay( m_Camera.origin, dir, buttons ); 602 603 Sys_UpdateWindows(W_CAMERA); 604 } 605 606 return; 607 } 608 m_ptButton.x = x; 609 m_ptButton.y = y; 610 611 if (buttons == (MK_RBUTTON|MK_CONTROL) ) 612 { 613 Cam_PositionDrag (); 614 Sys_UpdateWindows (W_XY|W_CAMERA|W_Z); 615 return; 616 } 617 618 GetCursorPos(&m_ptCursor); 619 620 if (buttons & (MK_LBUTTON | MK_MBUTTON) ) 621 { 622 Drag_MouseMoved (x, y, buttons); 623 Sys_UpdateWindows (W_XY|W_CAMERA|W_Z); 624 } 625 } 626 627 628 void CCamWnd::InitCull() 629 { 630 int i; 631 632 VectorSubtract (m_Camera.vpn, m_Camera.vright, m_vCull1); 633 VectorAdd (m_Camera.vpn, m_Camera.vright, m_vCull2); 634 635 for (i=0 ; i<3 ; i++) 636 { 637 if (m_vCull1[i] > 0) 638 m_nCullv1[i] = 3+i; 639 else 640 m_nCullv1[i] = i; 641 if (m_vCull2[i] > 0) 642 m_nCullv2[i] = 3+i; 643 else 644 m_nCullv2[i] = i; 645 } 646 } 647 648 qboolean CCamWnd::CullBrush (brush_t *b) 649 { 650 int i; 651 vec3_t point; 652 float d; 653 654 if (g_PrefsDlg.m_bCubicClipping) 655 { 656 float fLevel = g_PrefsDlg.m_nCubicScale * 64; 657 658 point[0] = m_Camera.origin[0] - fLevel; 659 point[1] = m_Camera.origin[1] - fLevel; 660 point[2] = m_Camera.origin[2] - fLevel; 661 662 for (i=0; i<3; i++) 663 if (b->mins[i] < point[i] && b->maxs[i] < point[i]) 664 return true; 665 666 point[0] = m_Camera.origin[0] + fLevel; 667 point[1] = m_Camera.origin[1] + fLevel; 668 point[2] = m_Camera.origin[2] + fLevel; 669 670 for (i=0; i<3; i++) 671 if (b->mins[i] > point[i] && b->maxs[i] > point[i]) 672 return true; 673 } 674 675 676 for (i=0 ; i<3 ; i++) 677 point[i] = b->mins[m_nCullv1[i]] - m_Camera.origin[i]; 678 679 d = DotProduct (point, m_vCull1); 680 if (d < -1) 681 return true; 682 683 for (i=0 ; i<3 ; i++) 684 point[i] = b->mins[m_nCullv2[i]] - m_Camera.origin[i]; 685 686 d = DotProduct (point, m_vCull2); 687 if (d < -1) 688 return true; 689 690 return false; 691 } 692 693 #if 0 694 void CCamWnd::DrawLightRadius(brush_t* pBrush) 695 { 696 // if lighting 697 int nRadius = Brush_LightRadius(pBrush); 698 if (nRadius > 0) 699 { 700 Brush_SetLightColor(pBrush); 701 qglEnable (GL_BLEND); 702 qglPolygonMode (GL_FRONT_AND_BACK, GL_LINE); 703 qglBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); 704 qglDisable (GL_TEXTURE_2D); 705 706 qglEnable(GL_TEXTURE_2D); 707 qglDisable(GL_BLEND); 708 qglPolygonMode (GL_FRONT_AND_BACK, GL_FILL); 709 } 710 } 711 #endif 712 713 /* 714 ============== 715 Cam_Draw 716 ============== 717 */ 718 719 void CCamWnd::Cam_Draw() 720 { 721 brush_t *brush; 722 face_t *face; 723 float screenaspect; 724 float yfov; 725 double start, end; 726 int i; 727 728 /* 729 FILE *f = fopen("g:/nardo/raduffy/editorhack.dat", "w"); 730 if (f != NULL) { 731 fwrite(&m_Camera.origin[0], sizeof(float), 1, f); 732 fwrite(&m_Camera.origin[1], sizeof(float), 1, f); 733 fwrite(&m_Camera.origin[2], sizeof(float), 1, f); 734 fwrite(&m_Camera.angles[PITCH], sizeof(float), 1, f); 735 fwrite(&m_Camera.angles[YAW], sizeof(float), 1, f); 736 fclose(f); 737 } 738 */ 739 740 if (!active_brushes.next) 741 return; // not valid yet 742 743 if (m_Camera.timing) 744 start = Sys_DoubleTime (); 745 746 // 747 // clear 748 // 749 QE_CheckOpenGLForErrors(); 750 751 qglViewport(0, 0, m_Camera.width, m_Camera.height); 752 qglScissor(0, 0, m_Camera.width, m_Camera.height); 753 qglClearColor (g_qeglobals.d_savedinfo.colors[COLOR_CAMERABACK][0], 754 g_qeglobals.d_savedinfo.colors[COLOR_CAMERABACK][1], 755 g_qeglobals.d_savedinfo.colors[COLOR_CAMERABACK][2], 0); 756 qglClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 757 758 // 759 // set up viewpoint 760 // 761 vec5_t lightPos; 762 763 if (g_PrefsDlg.m_bGLLighting) 764 { 765 qglEnable(GL_LIGHTING); 766 //qglEnable(GL_LIGHT0); 767 768 lightPos[0] = lightPos[1] = lightPos[2] = 3.5; 769 lightPos[3] = 1.0; 770 qglLightModelfv(GL_LIGHT_MODEL_AMBIENT, lightPos); 771 //qglLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, GL_TRUE); 772 //lightPos[0] = lightPos[1] = lightPos[2] = 3.5; 773 //qglLightfv(GL_LIGHT0, GL_AMBIENT, lightPos); 774 } 775 else 776 { 777 qglDisable(GL_LIGHTING); 778 } 779 780 qglMatrixMode(GL_PROJECTION); 781 qglLoadIdentity (); 782 783 screenaspect = (float)m_Camera.width / m_Camera.height; 784 yfov = 2*atan((float)m_Camera.height / m_Camera.width)*180/Q_PI; 785 qgluPerspective (yfov, screenaspect, 2, 8192); 786 787 qglRotatef (-90, 1, 0, 0); // put Z going up 788 qglRotatef (90, 0, 0, 1); // put Z going up 789 qglRotatef (m_Camera.angles[0], 0, 1, 0); 790 qglRotatef (-m_Camera.angles[1], 0, 0, 1); 791 qglTranslatef (-m_Camera.origin[0], -m_Camera.origin[1], -m_Camera.origin[2]); 792 793 Cam_BuildMatrix (); 794 795 796 //if (m_Camera.draw_mode == cd_light) 797 //{ 798 // if (g_PrefsDlg.m_bGLLighting) 799 // { 800 // VectorCopy(m_Camera.origin, lightPos); 801 // lightPos[3] = 1; 802 // qglLightfv(GL_LIGHT0, GL_POSITION, lightPos); 803 // } 804 //} 805 806 InitCull (); 807 808 // 809 // draw stuff 810 // 811 GLfloat lAmbient[] = {1.0, 1.0, 1.0, 1.0}; 812 813 switch (m_Camera.draw_mode) 814 { 815 case cd_wire: 816 qglPolygonMode (GL_FRONT_AND_BACK, GL_LINE); 817 qglDisable(GL_TEXTURE_2D); 818 qglDisable(GL_TEXTURE_1D); 819 qglDisable(GL_BLEND); 820 qglDisable(GL_DEPTH_TEST); 821 qglColor3f(1.0, 1.0, 1.0); 822 // qglEnable (GL_LINE_SMOOTH); 823 break; 824 825 case cd_solid: 826 qglCullFace(GL_FRONT); 827 qglEnable(GL_CULL_FACE); 828 qglShadeModel (GL_FLAT); 829 qglPolygonMode (GL_FRONT_AND_BACK, GL_FILL); 830 qglDisable(GL_TEXTURE_2D); 831 qglDisable(GL_BLEND); 832 qglEnable(GL_DEPTH_TEST); 833 qglDepthFunc (GL_LEQUAL); 834 break; 835 836 case cd_texture: 837 qglCullFace(GL_FRONT); 838 qglEnable(GL_CULL_FACE); 839 qglShadeModel (GL_FLAT); 840 qglPolygonMode (GL_FRONT_AND_BACK, GL_FILL); 841 qglEnable(GL_TEXTURE_2D); 842 qglTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); 843 qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); 844 qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); 845 qglDisable(GL_BLEND); 846 qglEnable(GL_DEPTH_TEST); 847 qglDepthFunc (GL_LEQUAL); 848 break; 849 850 case cd_blend: 851 qglCullFace(GL_FRONT); 852 qglEnable(GL_CULL_FACE); 853 qglShadeModel (GL_FLAT); 854 qglPolygonMode (GL_FRONT_AND_BACK, GL_FILL); 855 qglEnable(GL_TEXTURE_2D); 856 qglTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); 857 qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); 858 qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); 859 qglDisable(GL_DEPTH_TEST); 860 qglEnable (GL_BLEND); 861 qglBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); 862 break; 863 } 864 865 qglMatrixMode(GL_TEXTURE); 866 867 m_nNumTransBrushes = 0; 868 869 for (brush = active_brushes.next ; brush != &active_brushes ; brush=brush->next) 870 { 871 //DrawLightRadius(brush); 872 873 if (CullBrush (brush)) 874 continue; 875 876 if (FilterBrush (brush)) 877 continue; 878 879 if ((brush->brush_faces->texdef.flags & (SURF_TRANS33 | SURF_TRANS66)) || (brush->brush_faces->d_texture->bFromShader && brush->brush_faces->d_texture->fTrans != 1.0)) 880 { 881 m_TransBrushes [ m_nNumTransBrushes++ ] = brush; 882 } 883 else 884 { 885 //-- if (brush->patchBrush) 886 //-- m_TransBrushes [ m_nNumTransBrushes++ ] = brush; 887 //-- else 888 Brush_Draw(brush); 889 } 890 891 892 } 893 894 if (g_PrefsDlg.m_bGLLighting) 895 { 896 qglDisable (GL_LIGHTING); 897 } 898 899 // 900 //qglDepthMask ( 0 ); // Don't write to depth buffer 901 qglEnable ( GL_BLEND ); 902 qglBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); 903 for ( i = 0; i < m_nNumTransBrushes; i++ ) 904 Brush_Draw (m_TransBrushes[i]); 905 906 //qglDepthMask ( 1 ); // Ok, write now 907 908 qglMatrixMode(GL_PROJECTION); 909 910 // 911 // now draw selected brushes 912 // 913 914 if (g_PrefsDlg.m_bGLLighting) 915 { 916 qglEnable (GL_LIGHTING); 917 } 918 919 qglTranslatef (g_qeglobals.d_select_translate[0], g_qeglobals.d_select_translate[1], g_qeglobals.d_select_translate[2]); 920 qglMatrixMode(GL_TEXTURE); 921 922 brush_t* pList = (g_bClipMode && g_pSplitList) ? g_pSplitList : &selected_brushes; 923 // draw normally 924 for (brush = pList->next ; brush != pList ; brush=brush->next) 925 { 926 //DrawLightRadius(brush); 927 //if (brush->patchBrush && g_qeglobals.d_select_mode == sel_curvepoint) 928 // continue; 929 930 Brush_Draw(brush); 931 } 932 933 // blend on top 934 qglMatrixMode(GL_PROJECTION); 935 936 937 qglDisable (GL_LIGHTING); 938 qglColor4f(1.0, 0.0, 0.0, 0.3); 939 qglEnable (GL_BLEND); 940 qglPolygonMode (GL_FRONT_AND_BACK, GL_FILL); 941 qglBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); 942 qglDisable (GL_TEXTURE_2D); 943 for (brush = pList->next ; brush != pList ; brush=brush->next) 944 { 945 if ( (brush->patchBrush && g_qeglobals.d_select_mode == sel_curvepoint) || 946 (brush->terrainBrush && g_qeglobals.d_select_mode == sel_terrainpoint) ) 947 continue; 948 949 for (face=brush->brush_faces ; face ; face=face->next) 950 Face_Draw( face ); 951 } 952 953 954 int nCount = g_ptrSelectedFaces.GetSize(); 955 if (nCount > 0) 956 { 957 for (int i = 0; i < nCount; i++) 958 { 959 face_t *selFace = reinterpret_cast<face_t*>(g_ptrSelectedFaces.GetAt(i)); 960 Face_Draw(selFace); 961 } 962 } 963 964 // non-zbuffered outline 965 966 qglDisable (GL_BLEND); 967 qglDisable (GL_DEPTH_TEST); 968 qglPolygonMode (GL_FRONT_AND_BACK, GL_LINE); 969 qglColor3f (1, 1, 1); 970 for (brush = pList->next ; brush != pList ; brush=brush->next) 971 { 972 if (g_qeglobals.dontDrawSelectedOutlines || (brush->patchBrush && g_qeglobals.d_select_mode == sel_curvepoint) || 973 (brush->terrainBrush && g_qeglobals.d_select_mode == sel_terrainpoint)) 974 continue; 975 976 for (face=brush->brush_faces ; face ; face=face->next) 977 Face_Draw( face ); 978 } 979 980 981 // edge / vertex flags 982 983 if (g_qeglobals.d_select_mode == sel_vertex) 984 { 985 qglPointSize (4); 986 qglColor3f (0,1,0); 987 qglBegin (GL_POINTS); 988 for (i=0 ; i<g_qeglobals.d_numpoints ; i++) 989 qglVertex3fv (g_qeglobals.d_points[i]); 990 qglEnd (); 991 qglPointSize (1); 992 } 993 else if (g_qeglobals.d_select_mode == sel_edge) 994 { 995 float *v1, *v2; 996 997 qglPointSize (4); 998 qglColor3f (0,0,1); 999 qglBegin (GL_POINTS); 1000 for (i=0 ; i<g_qeglobals.d_numedges ; i++) 1001 { 1002 v1 = g_qeglobals.d_points[g_qeglobals.d_edges[i].p1]; 1003 v2 = g_qeglobals.d_points[g_qeglobals.d_edges[i].p2]; 1004 qglVertex3f ( (v1[0]+v2[0])*0.5,(v1[1]+v2[1])*0.5,(v1[2]+v2[2])*0.5); 1005 } 1006 qglEnd (); 1007 qglPointSize (1); 1008 } 1009 1010 1011 g_splineList->draw(static_cast<qboolean>(g_qeglobals.d_select_mode == sel_addpoint || g_qeglobals.d_select_mode == sel_editpoint)); 1012 if (g_qeglobals.selectObject && (g_qeglobals.d_select_mode == sel_addpoint || g_qeglobals.d_select_mode == sel_editpoint)) { 1013 g_qeglobals.selectObject->drawSelection(); 1014 } 1015 1016 // 1017 // draw pointfile 1018 // 1019 1020 qglEnable(GL_DEPTH_TEST); 1021 1022 1023 DrawPathLines (); 1024 1025 1026 1027 if (g_qeglobals.d_pointfile_display_list) 1028 { 1029 Pointfile_Draw(); 1030 // glCallList (g_qeglobals.d_pointfile_display_list); 1031 } 1032 1033 // bind back to the default texture so that we don't have problems 1034 // elsewhere using/modifying texture maps between contexts 1035 qglBindTexture( GL_TEXTURE_2D, 0 ); 1036 1037 #if 0 1038 // area selection hack 1039 if (g_qeglobals.d_select_mode == sel_area) 1040 { 1041 qglEnable (GL_BLEND); 1042 qglBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); 1043 qglColor4f(0.0, 0.0, 1.0, 0.25); 1044 qglPolygonMode (GL_FRONT_AND_BACK, GL_FILL); 1045 qglRectfv(g_qeglobals.d_vAreaTL, g_qeglobals.d_vAreaBR); 1046 qglDisable (GL_BLEND); 1047 } 1048 #endif 1049 1050 qglFinish(); 1051 QE_CheckOpenGLForErrors(); 1052 // Sys_EndWait(); 1053 if (m_Camera.timing) 1054 { 1055 end = Sys_DoubleTime (); 1056 Sys_Printf ("Camera: %i ms\n", (int)(1000*(end-start))); 1057 } 1058 } 1059 1060 1061 void CCamWnd::OnSize(UINT nType, int cx, int cy) 1062 { 1063 CWnd::OnSize(nType, cx, cy); 1064 CRect rect; 1065 GetClientRect(rect); 1066 m_Camera.width = rect.right; 1067 m_Camera.height = rect.bottom; 1068 InvalidateRect(NULL, false); 1069 } 1070 1071 void CCamWnd::BenchMark() 1072 { 1073 PAINTSTRUCT ps; 1074 CRect rct; 1075 GetWindowRect(rct); 1076 long lStyle = ::GetWindowLong(GetSafeHwnd(), GWL_STYLE); 1077 ::SetWindowLong(GetSafeHwnd(), GWL_STYLE, QE3_CHILDSTYLE); 1078 CWnd* pParent = GetParent(); 1079 SetParent(g_pParentWnd); 1080 MoveWindow(CRect(30, 30, 400, 400), TRUE); 1081 1082 BeginPaint(&ps); 1083 if (!qwglMakeCurrent(ps.hdc, g_qeglobals.d_hglrcBase)) 1084 Error ("wglMakeCurrent failed in Benchmark"); 1085 1086 qglDrawBuffer (GL_FRONT); 1087 double dStart = Sys_DoubleTime (); 1088 for (int i=0 ; i < 100 ; i++) 1089 { 1090 m_Camera.angles[YAW] = i*4; 1091 Cam_Draw(); 1092 } 1093 qwglSwapBuffers(ps.hdc); 1094 qglDrawBuffer (GL_BACK); 1095 double dEnd = Sys_DoubleTime (); 1096 EndPaint(&ps); 1097 Sys_Printf ("%5.2f seconds\n", dEnd - dStart); 1098 ::SetWindowLong(GetSafeHwnd(), GWL_STYLE, lStyle); 1099 SetParent(pParent); 1100 MoveWindow(rct, TRUE); 1101 } 1102 1103 void CCamWnd::ReInitGL() 1104 { 1105 1106 qwglMakeCurrent(0,0); 1107 QEW_SetupPixelFormat(GetDC()->m_hDC, true); 1108 if (!qwglMakeCurrent(g_qeglobals.d_hdcBase, g_qeglobals.d_hglrcBase)) 1109 Error ("wglMakeCurrent failed"); 1110 1111 return; 1112 1113 long lStyle = ::GetWindowLong(GetSafeHwnd(), GWL_STYLE); 1114 int nID = ::GetWindowLong(GetSafeHwnd(), GWL_ID); 1115 CWnd* pParent = GetParent(); 1116 CRect rctClient; 1117 GetClientRect(rctClient); 1118 DestroyWindow(); 1119 Create(CAMERA_WINDOW_CLASS, "", lStyle, rctClient, pParent, nID); 1120 } 1121 1122 void CCamWnd::OnKeyUp(UINT nChar, UINT nRepCnt, UINT nFlags) 1123 { 1124 g_pParentWnd->HandleKey(nChar, nRepCnt, nFlags, false); 1125 } 1126 1127 // Timo 1128 // brush primitive texture shifting, using camera view to select translations : 1129 void CCamWnd::ShiftTexture_BrushPrimit(face_t *f, int x, int y) 1130 { 1131 vec3_t texS,texT; 1132 vec3_t viewX,viewY; 1133 int XS,XT,YS,YT; 1134 int outS,outT; 1135 #ifdef _DEBUG 1136 if (!g_qeglobals.m_bBrushPrimitMode) 1137 { 1138 Sys_Printf("Warning : unexpected call to CCamWnd::ShiftTexture_BrushPrimit with brush primitive mode disbaled\n"); 1139 return; 1140 } 1141 #endif 1142 // compute face axis base 1143 ComputeAxisBase( f->plane.normal, texS, texT ); 1144 // compute camera view vectors 1145 VectorCopy( m_Camera.vup, viewY ); 1146 VectorCopy( m_Camera.vright, viewX ); 1147 // compute best vectors 1148 ComputeBest2DVector( viewX, texS, texT, XS, XT ); 1149 ComputeBest2DVector( viewY, texS, texT, YS, YT ); 1150 // check this is not a degenerate case 1151 if ( ( XS == YS ) && ( XT == YT ) ) 1152 { 1153 #ifdef _DEBUG 1154 Sys_Printf("Warning : degenerate best vectors axis base in CCamWnd::ShiftTexture_BrushPrimit\n"); 1155 #endif 1156 // forget it 1157 Select_ShiftTexture_BrushPrimit( f, x, y ); 1158 return; 1159 } 1160 // compute best fitted translation in face axis base 1161 outS = XS*x + YS*y; 1162 outT = XT*x + YT*y; 1163 // call actual texture shifting code 1164 Select_ShiftTexture_BrushPrimit( f, outS, outT ); 1165 }