Main Page | Class Hierarchy | Alphabetical List | Data Structures | Directories | File List | Data Fields | Globals

CamWnd.cpp

Go to the documentation of this file.
00001 /*
00002 ===========================================================================
00003 Copyright (C) 1999-2005 Id Software, Inc.
00004 
00005 This file is part of Quake III Arena source code.
00006 
00007 Quake III Arena source code is free software; you can redistribute it
00008 and/or modify it under the terms of the GNU General Public License as
00009 published by the Free Software Foundation; either version 2 of the License,
00010 or (at your option) any later version.
00011 
00012 Quake III Arena source code is distributed in the hope that it will be
00013 useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
00014 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015 GNU General Public License for more details.
00016 
00017 You should have received a copy of the GNU General Public License
00018 along with Foobar; if not, write to the Free Software
00019 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
00020 ===========================================================================
00021 */
00022 // CamWnd.cpp : implementation file
00023 //
00024 
00025 #include "stdafx.h"
00026 #include "Radiant.h"
00027 #include "XYWnd.h"
00028 #include "CamWnd.h"
00029 #include "qe3.h"
00030 #include "splines/splines.h"
00031 
00032 #ifdef _DEBUG
00033 #define new DEBUG_NEW
00034 #undef THIS_FILE
00035 static char THIS_FILE[] = __FILE__;
00036 #endif
00037 
00038 extern void DrawPathLines();
00039 
00040 int g_nAngleSpeed = 300;
00041 int g_nMoveSpeed = 400;
00042 
00043 
00045 // CCamWnd
00046 IMPLEMENT_DYNCREATE(CCamWnd, CWnd);
00047 
00048 CCamWnd::CCamWnd()
00049 {
00050   m_pXYFriend = NULL;
00051   m_nNumTransBrushes = 0;
00052   memset(&m_Camera, 0, sizeof(camera_t));
00053   m_pSide_select = NULL;
00054   m_bClipMode = false;
00055   Cam_Init();
00056 }
00057 
00058 CCamWnd::~CCamWnd()
00059 {
00060 }
00061 
00062 
00063 BEGIN_MESSAGE_MAP(CCamWnd, CWnd)
00064     //{{AFX_MSG_MAP(CCamWnd)
00065     ON_WM_KEYDOWN()
00066     ON_WM_PAINT()
00067     ON_WM_DESTROY()
00068     ON_WM_CLOSE()
00069     ON_WM_MOUSEMOVE()
00070     ON_WM_LBUTTONDOWN()
00071     ON_WM_LBUTTONUP()
00072     ON_WM_MBUTTONDOWN()
00073     ON_WM_MBUTTONUP()
00074     ON_WM_RBUTTONDOWN()
00075     ON_WM_RBUTTONUP()
00076     ON_WM_CREATE()
00077     ON_WM_SIZE()
00078     ON_WM_NCCALCSIZE()
00079     ON_WM_KILLFOCUS()
00080     ON_WM_SETFOCUS()
00081     ON_WM_KEYUP()
00082     //}}AFX_MSG_MAP
00083 END_MESSAGE_MAP()
00084 
00085 
00086 LONG WINAPI CamWndProc (
00087     HWND    hWnd,
00088     UINT    uMsg,
00089     WPARAM  wParam,
00090     LPARAM  lParam)
00091 {
00092     RECT    rect;
00093 
00094     GetClientRect(hWnd, &rect);
00095 
00096     switch (uMsg)
00097     {
00098     case WM_KILLFOCUS:
00099     case WM_SETFOCUS:
00100         SendMessage( hWnd, WM_NCACTIVATE, uMsg == WM_SETFOCUS, 0 );
00101         return 0;
00102 
00103     case WM_NCCALCSIZE:// don't let windows copy pixels
00104         DefWindowProc (hWnd, uMsg, wParam, lParam);
00105         return WVR_REDRAW;
00106 
00107     }
00108 
00109     return DefWindowProc( hWnd, uMsg, wParam, lParam );
00110 }
00111 
00112 
00114 // CCamWnd message handlers
00115 
00116 BOOL CCamWnd::PreCreateWindow(CREATESTRUCT& cs) 
00117 {
00118   WNDCLASS wc;
00119   HINSTANCE hInstance = AfxGetInstanceHandle();
00120   if (::GetClassInfo(hInstance, CAMERA_WINDOW_CLASS, &wc) == FALSE)
00121   {
00122     // Register a new class
00123     memset (&wc, 0, sizeof(wc));
00124     wc.style         = CS_NOCLOSE | CS_OWNDC;
00125     wc.lpszClassName = CAMERA_WINDOW_CLASS;
00126     wc.hCursor       = LoadCursor (NULL,IDC_ARROW);
00127     wc.lpfnWndProc   = CamWndProc;
00128     if (AfxRegisterClass(&wc) == FALSE)
00129       Error ("CCamWnd RegisterClass: failed");
00130   }
00131 
00132   cs.lpszClass = CAMERA_WINDOW_CLASS;
00133   cs.lpszName = "CAM";
00134   if (cs.style != QE3_CHILDSTYLE)
00135     cs.style = QE3_SPLITTER_STYLE;
00136 
00137     BOOL bResult = CWnd::PreCreateWindow(cs);
00138 
00139   // See if the class already exists and if not then we need
00140   // to register our new window class.
00141   return bResult;
00142     
00143 }
00144 
00145 
00146 void CCamWnd::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags) 
00147 {
00148   g_pParentWnd->HandleKey(nChar, nRepCnt, nFlags);
00149 }
00150 
00151 
00152 brush_t* g_pSplitList = NULL;
00153 
00154 void CCamWnd::OnPaint() 
00155 {
00156     CPaintDC dc(this); // device context for painting
00157   bool bPaint = true;
00158   if (!qwglMakeCurrent( dc.m_hDC, g_qeglobals.d_hglrcBase ))
00159   {
00160     Sys_Printf("ERROR: wglMakeCurrent failed..\n ");
00161     Sys_Printf("Please restart Q3Radiant if the camera view is not working\n");
00162   }
00163   else
00164   {
00165     QE_CheckOpenGLForErrors();
00166     g_pSplitList = NULL;
00167     if (g_bClipMode)
00168     {
00169       if (g_Clip1.Set() && g_Clip2.Set())
00170       {
00171         g_pSplitList = ( (g_pParentWnd->ActiveXY()->GetViewType() == XZ) ? !g_bSwitch : g_bSwitch) ? &g_brBackSplits : &g_brFrontSplits;
00172       }
00173     }
00174         Cam_Draw ();
00175         QE_CheckOpenGLForErrors();
00176         qwglSwapBuffers(dc.m_hDC);
00177   }
00178 }
00179 
00180 
00181 void CCamWnd::SetXYFriend(CXYWnd * pWnd)
00182 {
00183   m_pXYFriend = pWnd;
00184 }
00185 
00186 void CCamWnd::OnDestroy() 
00187 {
00188     QEW_StopGL(GetSafeHwnd(), g_qeglobals.d_hglrcBase, g_qeglobals.d_hdcBase );
00189     CWnd::OnDestroy();
00190 }
00191 
00192 void CCamWnd::OnClose() 
00193 {
00194     CWnd::OnClose();
00195 }
00196 
00197 extern void Select_ShiftTexture(int x, int y);
00198 extern void Select_RotateTexture(int amt);
00199 extern void Select_ScaleTexture(int x, int y);
00200 void CCamWnd::OnMouseMove(UINT nFlags, CPoint point) 
00201 {
00202   CRect r;
00203   GetClientRect(r);
00204   if (GetCapture() == this && (GetKeyState(VK_MENU) & 0x8000) && !((GetKeyState(VK_SHIFT) & 0x8000) || (GetKeyState(VK_CONTROL) & 0x8000)))
00205   {
00206     if (GetKeyState(VK_CONTROL) & 0x8000)
00207       Select_RotateTexture(point.y - m_ptLastCursor.y);
00208     else
00209     if (GetKeyState(VK_SHIFT) & 0x8000)
00210       Select_ScaleTexture(point.x - m_ptLastCursor.x, m_ptLastCursor.y - point.y);
00211     else
00212       Select_ShiftTexture(point.x - m_ptLastCursor.x, m_ptLastCursor.y - point.y);
00213   }
00214   else
00215   {
00216     Cam_MouseMoved(point.x, r.bottom - 1 - point.y, nFlags);
00217   }
00218   m_ptLastCursor = point;
00219 }
00220 
00221 void CCamWnd::OnLButtonDown(UINT nFlags, CPoint point) 
00222 {
00223   m_ptLastCursor = point;
00224   OriginalMouseDown(nFlags, point);
00225 }
00226 
00227 void CCamWnd::OnLButtonUp(UINT nFlags, CPoint point) 
00228 {
00229   OriginalMouseUp(nFlags, point);
00230 }
00231 
00232 void CCamWnd::OnMButtonDown(UINT nFlags, CPoint point) 
00233 {
00234   OriginalMouseDown(nFlags, point);
00235 }
00236 
00237 void CCamWnd::OnMButtonUp(UINT nFlags, CPoint point) 
00238 {
00239   OriginalMouseUp(nFlags, point);
00240 }
00241 
00242 void CCamWnd::OnRButtonDown(UINT nFlags, CPoint point) 
00243 {
00244   OriginalMouseDown(nFlags, point);
00245 }
00246 
00247 void CCamWnd::OnRButtonUp(UINT nFlags, CPoint point) 
00248 {
00249   OriginalMouseUp(nFlags, point);
00250 }
00251 
00252 int CCamWnd::OnCreate(LPCREATESTRUCT lpCreateStruct) 
00253 {
00254   if (CWnd::OnCreate(lpCreateStruct) == -1)
00255         return -1;
00256 
00257     g_qeglobals.d_hdcBase = GetDC()->m_hDC;
00258     QEW_SetupPixelFormat(g_qeglobals.d_hdcBase, true);
00259 
00260   if ((g_qeglobals.d_hglrcBase = qwglCreateContext(g_qeglobals.d_hdcBase)) == 0)
00261       Error("wglCreateContext failed");
00262   
00263   if (!qwglMakeCurrent(g_qeglobals.d_hdcBase, g_qeglobals.d_hglrcBase))
00264       Error ("wglMakeCurrent failed");
00265 
00266 
00267     //
00268     // create GL font
00269     //
00270   HFONT hfont = ::CreateFont(
00271       12,   // logical height of font 
00272          6, // logical average character width 
00273          0, // angle of escapement 
00274          0, // base-line orientation angle 
00275          0, // font weight 
00276          0, // italic attribute flag 
00277          0, // underline attribute flag 
00278          0, // strikeout attribute flag 
00279          0, // character set identifier 
00280          0, // output precision 
00281          0, // clipping precision 
00282          0, // output quality 
00283          0, // pitch and family 
00284          "system font" // pointer to typeface name string 
00285             );
00286 
00287     if (!hfont)
00288       Error( "couldn't create font" );
00289 
00290   ::SelectObject(g_qeglobals.d_hdcBase, hfont);
00291 
00292     if ((g_qeglobals.d_font_list = qglGenLists (256)) == 0)
00293       Error( "couldn't create font dlists" );
00294             
00295     // create the bitmap display lists
00296     // we're making images of glyphs 0 thru 255
00297   
00298   if (g_PrefsDlg.m_bBuggyICD)
00299   {
00300       if ( !qwglUseFontBitmaps (g_qeglobals.d_hdcBase, 1, 255, g_qeglobals.d_font_list-1) )
00301         Error( "wglUseFontBitmaps faileD" );
00302   }
00303   else
00304   {
00305       if ( !qwglUseFontBitmaps (g_qeglobals.d_hdcBase, 1, 255, g_qeglobals.d_font_list) )
00306         Error( "wglUseFontBitmaps faileD" );
00307   }
00308     
00309     // indicate start of glyph display lists
00310     qglListBase (g_qeglobals.d_font_list);
00311 
00312     // report OpenGL information
00313     Sys_Printf ("GL_VENDOR: %s\n", qglGetString (GL_VENDOR));
00314     Sys_Printf ("GL_RENDERER: %s\n", qglGetString (GL_RENDERER));
00315     Sys_Printf ("GL_VERSION: %s\n", qglGetString (GL_VERSION));
00316     Sys_Printf ("GL_EXTENSIONS: %s\n", qglGetString (GL_EXTENSIONS));
00317 
00318   g_qeglobals.d_hwndCamera = GetSafeHwnd();
00319 
00320     return 0;
00321 }
00322 
00323 void CCamWnd::OriginalMouseUp(UINT nFlags, CPoint point)
00324 {
00325   CRect r;
00326   GetClientRect(r);
00327   Cam_MouseUp(point.x, r.bottom - 1 - point.y, nFlags);
00328     if (!(nFlags & (MK_LBUTTON|MK_RBUTTON|MK_MBUTTON)))
00329     ReleaseCapture ();
00330 }
00331 
00332 void CCamWnd::OriginalMouseDown(UINT nFlags, CPoint point)
00333 {
00334   //if (GetTopWindow()->GetSafeHwnd() != GetSafeHwnd())
00335   //  BringWindowToTop();
00336   CRect r;
00337   GetClientRect(r);
00338   SetFocus();
00339     SetCapture();
00340   //if (!(GetKeyState(VK_MENU) & 0x8000))
00341       Cam_MouseDown (point.x, r.bottom - 1 - point.y, nFlags);
00342 }
00343 
00344 void CCamWnd::Cam_Init()
00345 {
00346     //m_Camera.draw_mode = cd_texture;
00347     m_Camera.timing = false;
00348     m_Camera.origin[0] = 0;
00349     m_Camera.origin[1] = 20;
00350     m_Camera.origin[2] = 46;
00351     m_Camera.color[0] = 0.3;
00352     m_Camera.color[1] = 0.3;
00353     m_Camera.color[2] = 0.3;
00354 }
00355 
00356 void CCamWnd::Cam_BuildMatrix()
00357 {
00358     float   xa, ya;
00359     float   matrix[4][4];
00360     int     i;
00361 
00362     xa = m_Camera.angles[0]/180*Q_PI;
00363     ya = m_Camera.angles[1]/180*Q_PI;
00364 
00365     // the movement matrix is kept 2d
00366 
00367   m_Camera.forward[0] = cos(ya);
00368   m_Camera.forward[1] = sin(ya);
00369   m_Camera.right[0] = m_Camera.forward[1];
00370   m_Camera.right[1] = -m_Camera.forward[0];
00371 
00372     qglGetFloatv (GL_PROJECTION_MATRIX, &matrix[0][0]);
00373 
00374     for (i=0 ; i<3 ; i++)
00375     {
00376         m_Camera.vright[i] = matrix[i][0];
00377         m_Camera.vup[i] = matrix[i][1];
00378         m_Camera.vpn[i] = matrix[i][2];
00379     }
00380 
00381     VectorNormalize (m_Camera.vright);
00382     VectorNormalize (m_Camera.vup);
00383     VectorNormalize (m_Camera.vpn);
00384 }
00385 
00386 
00387 
00388 void CCamWnd::Cam_ChangeFloor (qboolean up)
00389 {
00390     brush_t *b;
00391     float   d, bestd, current;
00392     vec3_t  start, dir;
00393 
00394     start[0] = m_Camera.origin[0];
00395     start[1] = m_Camera.origin[1];
00396     start[2] = 8192;
00397     dir[0] = dir[1] = 0;
00398     dir[2] = -1;
00399 
00400     current = 8192 - (m_Camera.origin[2] - 48);
00401     if (up)
00402         bestd = 0;
00403     else
00404         bestd = 16384;
00405 
00406     for (b=active_brushes.next ; b != &active_brushes ; b=b->next)
00407     {
00408         if ( b->pTerrain && !Terrain_Ray( start, dir, b, &d ) )
00409             continue;
00410         if ( !b->pTerrain && !Brush_Ray (start, dir, b, &d) )
00411             continue;
00412         if (up && d < current && d > bestd)
00413             bestd = d;
00414         if (!up && d > current && d < bestd)
00415             bestd = d;
00416     }
00417 
00418     if (bestd == 0 || bestd == 16384)
00419         return;
00420 
00421     m_Camera.origin[2] += current - bestd;
00422     Sys_UpdateWindows (W_CAMERA|W_Z_OVERLAY);
00423 }
00424 
00425 
00426 void CCamWnd::Cam_PositionDrag()
00427 {
00428     int x, y;
00429     Sys_GetCursorPos (&x, &y);
00430     if (x != m_ptCursor.x || y != m_ptCursor.y)
00431     {
00432         x -= m_ptCursor.x;
00433         VectorMA (m_Camera.origin, x, m_Camera.vright, m_Camera.origin);
00434         y -= m_ptCursor.y;
00435         m_Camera.origin[2] -= y;
00436     SetCursorPos(m_ptCursor.x, m_ptCursor.y);
00437         Sys_UpdateWindows (W_CAMERA | W_XY_OVERLAY);
00438     }
00439 }
00440 
00441 
00442 void CCamWnd::Cam_MouseControl (float dtime)
00443 {
00444     int     xl, xh;
00445     int     yl, yh;
00446     float   xf, yf;
00447   if (g_PrefsDlg.m_nMouseButtons == 2)
00448   {
00449     if (m_nCambuttonstate != (MK_RBUTTON | MK_SHIFT))
00450       return;
00451   }
00452   else
00453   {
00454       if (m_nCambuttonstate != MK_RBUTTON)
00455       return;
00456   }
00457 
00458     xf = (float)(m_ptButton.x - m_Camera.width/2) / (m_Camera.width/2);
00459     yf = (float)(m_ptButton.y - m_Camera.height/2) / (m_Camera.height/2);
00460 
00461 
00462     xl = m_Camera.width/3;
00463     xh = xl*2;
00464     yl = m_Camera.height/3;
00465     yh = yl*2;
00466 
00467   //Sys_Printf("xf-%f  yf-%f  xl-%i  xh-i%  yl-i%  yh-i%\n",xf,yf,xl,xh,yl,yh);
00468 #if 0
00469     // strafe
00470     if (buttony < yl && (buttonx < xl || buttonx > xh))
00471         VectorMA (camera.origin, xf*dtime*g_nMoveSpeed, camera.right, camera.origin);
00472     else
00473 #endif
00474     {
00475         xf *= 1.0 - fabs(yf);
00476         if (xf < 0)
00477         {
00478             xf += 0.1;
00479             if (xf > 0)
00480                 xf = 0;
00481         }
00482         else
00483         {
00484             xf -= 0.1;
00485             if (xf < 0)
00486                 xf = 0;
00487         }
00488         
00489         VectorMA (m_Camera.origin, yf*dtime*g_nMoveSpeed, m_Camera.forward, m_Camera.origin);
00490         m_Camera.angles[YAW] += xf*-dtime*g_nAngleSpeed;
00491     }
00492 
00493 #if 0
00494   if (g_PrefsDlg.m_bQE4Painting)
00495   {
00496     MSG msg;
00497     if (::PeekMessage( &msg, NULL, 0, 0, PM_REMOVE )) 
00498     { 
00499       TranslateMessage(&msg);
00500       DispatchMessage(&msg);
00501     }
00502   }
00503 #endif
00504 
00505   int nUpdate = (g_PrefsDlg.m_bCamXYUpdate) ? (W_CAMERA | W_XY) : (W_CAMERA);
00506     Sys_UpdateWindows (nUpdate);
00507   g_pParentWnd->PostMessage(WM_TIMER, 0, 0);
00508 
00509 }
00510 
00511 
00512 
00513 void CCamWnd::Cam_MouseDown(int x, int y, int buttons)
00514 {
00515     vec3_t      dir;
00516     float       f, r, u;
00517     int         i;
00518 
00519     //
00520     // calc ray direction
00521     //
00522     u = (float)(y - m_Camera.height/2) / (m_Camera.width/2);
00523     r = (float)(x - m_Camera.width/2) / (m_Camera.width/2);
00524     f = 1;
00525 
00526     for (i=0 ; i<3 ; i++)
00527         dir[i] = m_Camera.vpn[i] * f + m_Camera.vright[i] * r + m_Camera.vup[i] * u;
00528     VectorNormalize (dir);
00529 
00530     GetCursorPos(&m_ptCursor);
00531 
00532     m_nCambuttonstate = buttons;
00533     m_ptButton.x = x;
00534     m_ptButton.y = y;
00535 
00536     // LBUTTON = manipulate selection
00537     // shift-LBUTTON = select
00538     // middle button = grab texture
00539     // ctrl-middle button = set entire brush to texture
00540     // ctrl-shift-middle button = set single face to texture
00541     int nMouseButton = g_PrefsDlg.m_nMouseButtons == 2 ? MK_RBUTTON : MK_MBUTTON;
00542     if ((buttons == MK_LBUTTON)
00543                 || (buttons == (MK_LBUTTON | MK_SHIFT))
00544                 || (buttons == (MK_LBUTTON | MK_CONTROL))
00545                 || (buttons == (MK_LBUTTON | MK_CONTROL | MK_SHIFT))
00546                 || (buttons == nMouseButton)
00547                 || (buttons == (nMouseButton|MK_SHIFT))
00548                 || (buttons == (nMouseButton|MK_CONTROL))
00549                 || (buttons == (nMouseButton|MK_SHIFT|MK_CONTROL)))
00550     {
00551 
00552     if (g_PrefsDlg.m_nMouseButtons == 2 && (buttons == (MK_RBUTTON | MK_SHIFT)))
00553           Cam_MouseControl (0.1);
00554     else
00555     {
00556       // something global needs to track which window is responsible for stuff
00557       Patch_SetView(W_CAMERA);
00558           Drag_Begin (x, y, buttons, m_Camera.vright, m_Camera.vup, m_Camera.origin, dir);
00559     }
00560     return;
00561     }
00562 
00563     if (buttons == MK_RBUTTON)
00564     {
00565         Cam_MouseControl (0.1);
00566         return;
00567     }
00568 }
00569 
00570 
00571 void CCamWnd::Cam_MouseUp (int x, int y, int buttons)
00572 {
00573     m_nCambuttonstate = 0;
00574     Drag_MouseUp (buttons);
00575 }
00576 
00577 
00578 void CCamWnd::Cam_MouseMoved (int x, int y, int buttons)
00579 {
00580     m_nCambuttonstate = buttons;
00581     if (!buttons) {
00582         if ( ( g_qeglobals.d_select_mode == sel_terrainpoint ) || ( g_qeglobals.d_select_mode == sel_terraintexture ) ) {
00583             vec3_t      dir;
00584             float       f, r, u;
00585             int         i;
00586 
00587             //
00588             // calc ray direction
00589             //
00590             u = (float)(y - m_Camera.height/2) / (m_Camera.width/2);
00591             r = (float)(x - m_Camera.width/2) / (m_Camera.width/2);
00592             f = 1;
00593 
00594             for (i=0 ; i<3 ; i++)
00595                 dir[i] = m_Camera.vpn[i] * f + m_Camera.vright[i] * r + m_Camera.vup[i] * u;
00596             VectorNormalize (dir);
00597 
00598             m_ptButton.x = x;
00599             m_ptButton.y = y;
00600 
00601             Terrain_SelectPointByRay( m_Camera.origin, dir, buttons );
00602 
00603             Sys_UpdateWindows(W_CAMERA);
00604         }
00605 
00606         return;
00607     }
00608     m_ptButton.x = x;
00609     m_ptButton.y = y;
00610 
00611     if (buttons == (MK_RBUTTON|MK_CONTROL) )
00612     {
00613         Cam_PositionDrag ();
00614         Sys_UpdateWindows (W_XY|W_CAMERA|W_Z);
00615         return;
00616     }
00617 
00618     GetCursorPos(&m_ptCursor);
00619 
00620     if (buttons & (MK_LBUTTON | MK_MBUTTON) )
00621     {
00622         Drag_MouseMoved (x, y, buttons);
00623         Sys_UpdateWindows (W_XY|W_CAMERA|W_Z);
00624     }
00625 }
00626 
00627 
00628 void CCamWnd::InitCull()
00629 {
00630     int     i;
00631 
00632     VectorSubtract (m_Camera.vpn, m_Camera.vright, m_vCull1);
00633     VectorAdd (m_Camera.vpn, m_Camera.vright, m_vCull2);
00634 
00635     for (i=0 ; i<3 ; i++)
00636     {
00637         if (m_vCull1[i] > 0)
00638             m_nCullv1[i] = 3+i;
00639         else
00640             m_nCullv1[i] = i;
00641         if (m_vCull2[i] > 0)
00642             m_nCullv2[i] = 3+i;
00643         else
00644             m_nCullv2[i] = i;
00645     }
00646 }
00647 
00648 qboolean CCamWnd::CullBrush (brush_t *b)
00649 {
00650     int     i;
00651     vec3_t  point;
00652     float   d;
00653 
00654     if (g_PrefsDlg.m_bCubicClipping)
00655     {
00656         float fLevel = g_PrefsDlg.m_nCubicScale * 64;
00657 
00658         point[0] = m_Camera.origin[0] - fLevel;
00659         point[1] = m_Camera.origin[1] - fLevel;
00660         point[2] = m_Camera.origin[2] - fLevel;
00661 
00662         for (i=0; i<3; i++)
00663             if (b->mins[i] < point[i] && b->maxs[i] < point[i])
00664                 return true;
00665 
00666         point[0] = m_Camera.origin[0] + fLevel;
00667         point[1] = m_Camera.origin[1] + fLevel;
00668         point[2] = m_Camera.origin[2] + fLevel;
00669     
00670         for (i=0; i<3; i++)
00671             if (b->mins[i] > point[i] && b->maxs[i] > point[i])
00672                 return true;
00673     }
00674 
00675 
00676     for (i=0 ; i<3 ; i++)
00677         point[i] = b->mins[m_nCullv1[i]] - m_Camera.origin[i];
00678 
00679     d = DotProduct (point, m_vCull1);
00680     if (d < -1)
00681         return true;
00682 
00683     for (i=0 ; i<3 ; i++)
00684         point[i] = b->mins[m_nCullv2[i]] - m_Camera.origin[i];
00685 
00686     d = DotProduct (point, m_vCull2);
00687     if (d < -1)
00688         return true;
00689 
00690     return false;
00691 }
00692 
00693 #if 0
00694 void CCamWnd::DrawLightRadius(brush_t* pBrush)
00695 {
00696   // if lighting
00697   int nRadius = Brush_LightRadius(pBrush);
00698   if (nRadius > 0)
00699   {
00700     Brush_SetLightColor(pBrush);
00701       qglEnable (GL_BLEND);
00702       qglPolygonMode (GL_FRONT_AND_BACK, GL_LINE);
00703       qglBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
00704       qglDisable (GL_TEXTURE_2D);
00705 
00706     qglEnable(GL_TEXTURE_2D);
00707     qglDisable(GL_BLEND);
00708     qglPolygonMode (GL_FRONT_AND_BACK, GL_FILL);
00709   }
00710 }
00711 #endif
00712 
00713 /*
00714 ==============
00715 Cam_Draw
00716 ==============
00717 */
00718 
00719 void CCamWnd::Cam_Draw()
00720 {
00721     brush_t *brush;
00722     face_t  *face;
00723     float   screenaspect;
00724     float   yfov;
00725     double  start, end;
00726     int     i;
00727 
00728     /*
00729   FILE *f = fopen("g:/nardo/raduffy/editorhack.dat", "w");
00730   if (f != NULL) {
00731     fwrite(&m_Camera.origin[0], sizeof(float), 1, f);
00732     fwrite(&m_Camera.origin[1], sizeof(float), 1, f);
00733     fwrite(&m_Camera.origin[2], sizeof(float), 1, f);
00734         fwrite(&m_Camera.angles[PITCH], sizeof(float), 1, f);
00735         fwrite(&m_Camera.angles[YAW], sizeof(float), 1, f);
00736     fclose(f);
00737   }
00738     */
00739     
00740     if (!active_brushes.next)
00741         return; // not valid yet
00742     
00743     if (m_Camera.timing)
00744         start = Sys_DoubleTime ();
00745     
00746     //
00747     // clear
00748     //
00749     QE_CheckOpenGLForErrors();
00750     
00751     qglViewport(0, 0, m_Camera.width, m_Camera.height);
00752     qglScissor(0, 0, m_Camera.width, m_Camera.height);
00753     qglClearColor (g_qeglobals.d_savedinfo.colors[COLOR_CAMERABACK][0],
00754         g_qeglobals.d_savedinfo.colors[COLOR_CAMERABACK][1],
00755         g_qeglobals.d_savedinfo.colors[COLOR_CAMERABACK][2], 0);
00756     qglClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
00757     
00758     //
00759     // set up viewpoint
00760     //
00761     vec5_t lightPos;
00762     
00763     if (g_PrefsDlg.m_bGLLighting)
00764     {
00765         qglEnable(GL_LIGHTING);
00766         //qglEnable(GL_LIGHT0);
00767         
00768         lightPos[0] = lightPos[1] = lightPos[2] = 3.5;
00769         lightPos[3] = 1.0;
00770         qglLightModelfv(GL_LIGHT_MODEL_AMBIENT, lightPos);
00771         //qglLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, GL_TRUE);
00772         //lightPos[0] = lightPos[1] = lightPos[2] = 3.5;
00773     //qglLightfv(GL_LIGHT0, GL_AMBIENT, lightPos);
00774     }
00775     else
00776     {
00777         qglDisable(GL_LIGHTING);
00778     }
00779     
00780     qglMatrixMode(GL_PROJECTION);
00781     qglLoadIdentity ();
00782     
00783     screenaspect = (float)m_Camera.width / m_Camera.height;
00784     yfov = 2*atan((float)m_Camera.height / m_Camera.width)*180/Q_PI;
00785     qgluPerspective (yfov,  screenaspect,  2,  8192);
00786     
00787     qglRotatef (-90,  1, 0, 0);     // put Z going up
00788     qglRotatef (90,  0, 0, 1);      // put Z going up
00789     qglRotatef (m_Camera.angles[0],  0, 1, 0);
00790     qglRotatef (-m_Camera.angles[1],  0, 0, 1);
00791     qglTranslatef (-m_Camera.origin[0],  -m_Camera.origin[1],  -m_Camera.origin[2]);
00792     
00793     Cam_BuildMatrix ();
00794     
00795     
00796     //if (m_Camera.draw_mode == cd_light)
00797     //{
00798 //  if (g_PrefsDlg.m_bGLLighting)
00799 //  {
00800 //      VectorCopy(m_Camera.origin, lightPos);
00801 //      lightPos[3] = 1;
00802 //      qglLightfv(GL_LIGHT0, GL_POSITION, lightPos);
00803 //  }
00804     //}
00805     
00806     InitCull ();
00807     
00808     //
00809     // draw stuff
00810     //
00811     GLfloat lAmbient[] = {1.0, 1.0, 1.0, 1.0};
00812     
00813     switch (m_Camera.draw_mode)
00814     {
00815     case cd_wire:
00816         qglPolygonMode (GL_FRONT_AND_BACK, GL_LINE);
00817         qglDisable(GL_TEXTURE_2D);
00818         qglDisable(GL_TEXTURE_1D);
00819         qglDisable(GL_BLEND);
00820         qglDisable(GL_DEPTH_TEST);
00821         qglColor3f(1.0, 1.0, 1.0);
00822         //      qglEnable (GL_LINE_SMOOTH);
00823         break;
00824         
00825     case cd_solid:
00826         qglCullFace(GL_FRONT);
00827         qglEnable(GL_CULL_FACE);
00828         qglShadeModel (GL_FLAT);
00829         qglPolygonMode (GL_FRONT_AND_BACK, GL_FILL);
00830         qglDisable(GL_TEXTURE_2D);
00831         qglDisable(GL_BLEND);
00832         qglEnable(GL_DEPTH_TEST);
00833         qglDepthFunc (GL_LEQUAL);
00834         break;
00835         
00836     case cd_texture:
00837         qglCullFace(GL_FRONT);
00838         qglEnable(GL_CULL_FACE);
00839         qglShadeModel (GL_FLAT);
00840         qglPolygonMode (GL_FRONT_AND_BACK, GL_FILL);
00841         qglEnable(GL_TEXTURE_2D);
00842         qglTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
00843         qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
00844         qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
00845         qglDisable(GL_BLEND);
00846         qglEnable(GL_DEPTH_TEST);
00847         qglDepthFunc (GL_LEQUAL);
00848         break;
00849         
00850     case cd_blend:
00851         qglCullFace(GL_FRONT);
00852         qglEnable(GL_CULL_FACE);
00853         qglShadeModel (GL_FLAT);
00854         qglPolygonMode (GL_FRONT_AND_BACK, GL_FILL);
00855         qglEnable(GL_TEXTURE_2D);
00856         qglTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
00857         qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
00858         qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
00859         qglDisable(GL_DEPTH_TEST);
00860         qglEnable (GL_BLEND);
00861         qglBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
00862         break;
00863     }
00864     
00865     qglMatrixMode(GL_TEXTURE);
00866     
00867     m_nNumTransBrushes = 0;
00868     
00869     for (brush = active_brushes.next ; brush != &active_brushes ; brush=brush->next)
00870     {
00871         //DrawLightRadius(brush);
00872         
00873         if (CullBrush (brush))
00874             continue;
00875         
00876         if (FilterBrush (brush))
00877             continue;
00878         
00879         if ((brush->brush_faces->texdef.flags & (SURF_TRANS33 | SURF_TRANS66)) || (brush->brush_faces->d_texture->bFromShader && brush->brush_faces->d_texture->fTrans != 1.0))
00880         {
00881             m_TransBrushes [ m_nNumTransBrushes++ ] = brush;
00882         } 
00883         else 
00884         {
00885             //--      if (brush->patchBrush)
00886             //--              m_TransBrushes [ m_nNumTransBrushes++ ] = brush;
00887             //--      else
00888             Brush_Draw(brush);
00889         }
00890         
00891         
00892     }
00893     
00894     if (g_PrefsDlg.m_bGLLighting)
00895     {
00896         qglDisable (GL_LIGHTING);
00897     }
00898     
00899     //
00900     //qglDepthMask ( 0 ); // Don't write to depth buffer
00901     qglEnable ( GL_BLEND );
00902     qglBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
00903     for ( i = 0; i < m_nNumTransBrushes; i++ ) 
00904         Brush_Draw (m_TransBrushes[i]);
00905     
00906     //qglDepthMask ( 1 ); // Ok, write now
00907     
00908     qglMatrixMode(GL_PROJECTION);
00909     
00910     //
00911     // now draw selected brushes
00912     //
00913     
00914     if (g_PrefsDlg.m_bGLLighting)
00915     {
00916         qglEnable (GL_LIGHTING);
00917     }
00918     
00919     qglTranslatef (g_qeglobals.d_select_translate[0], g_qeglobals.d_select_translate[1], g_qeglobals.d_select_translate[2]);
00920     qglMatrixMode(GL_TEXTURE);
00921     
00922     brush_t* pList = (g_bClipMode && g_pSplitList) ? g_pSplitList : &selected_brushes;
00923     // draw normally
00924     for (brush = pList->next ; brush != pList ; brush=brush->next)
00925     {
00926         //DrawLightRadius(brush);
00927         //if (brush->patchBrush && g_qeglobals.d_select_mode == sel_curvepoint)
00928         //  continue;
00929         
00930         Brush_Draw(brush);
00931     }
00932     
00933     // blend on top
00934     qglMatrixMode(GL_PROJECTION);
00935     
00936     
00937     qglDisable (GL_LIGHTING);
00938     qglColor4f(1.0, 0.0, 0.0, 0.3);
00939     qglEnable (GL_BLEND);
00940     qglPolygonMode (GL_FRONT_AND_BACK, GL_FILL);
00941     qglBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
00942     qglDisable (GL_TEXTURE_2D);
00943     for (brush = pList->next ; brush != pList ; brush=brush->next)
00944     {
00945         if ( (brush->patchBrush && g_qeglobals.d_select_mode == sel_curvepoint) || 
00946             (brush->terrainBrush && g_qeglobals.d_select_mode == sel_terrainpoint) )
00947             continue;
00948         
00949         for (face=brush->brush_faces ; face ; face=face->next)
00950             Face_Draw( face );
00951     }
00952     
00953  
00954   int nCount = g_ptrSelectedFaces.GetSize();
00955     if (nCount > 0)
00956   {
00957     for (int i = 0; i < nCount; i++)
00958     {
00959       face_t *selFace = reinterpret_cast<face_t*>(g_ptrSelectedFaces.GetAt(i));
00960           Face_Draw(selFace);
00961     }
00962   }
00963         
00964     // non-zbuffered outline
00965     
00966     qglDisable (GL_BLEND);
00967     qglDisable (GL_DEPTH_TEST);
00968     qglPolygonMode (GL_FRONT_AND_BACK, GL_LINE);
00969     qglColor3f (1, 1, 1);
00970     for (brush = pList->next ; brush != pList ; brush=brush->next)
00971     {
00972         if (g_qeglobals.dontDrawSelectedOutlines || (brush->patchBrush && g_qeglobals.d_select_mode == sel_curvepoint) ||
00973             (brush->terrainBrush && g_qeglobals.d_select_mode == sel_terrainpoint))
00974             continue;
00975         
00976         for (face=brush->brush_faces ; face ; face=face->next)
00977             Face_Draw( face );
00978     }
00979     
00980     
00981     // edge / vertex flags
00982     
00983     if (g_qeglobals.d_select_mode == sel_vertex)
00984     {
00985         qglPointSize (4);
00986         qglColor3f (0,1,0);
00987         qglBegin (GL_POINTS);
00988         for (i=0 ; i<g_qeglobals.d_numpoints ; i++)
00989             qglVertex3fv (g_qeglobals.d_points[i]);
00990         qglEnd ();
00991         qglPointSize (1);
00992     }
00993     else if (g_qeglobals.d_select_mode == sel_edge)
00994     {
00995         float   *v1, *v2;
00996         
00997         qglPointSize (4);
00998         qglColor3f (0,0,1);
00999         qglBegin (GL_POINTS);
01000         for (i=0 ; i<g_qeglobals.d_numedges ; i++)
01001         {
01002             v1 = g_qeglobals.d_points[g_qeglobals.d_edges[i].p1];
01003             v2 = g_qeglobals.d_points[g_qeglobals.d_edges[i].p2];
01004             qglVertex3f ( (v1[0]+v2[0])*0.5,(v1[1]+v2[1])*0.5,(v1[2]+v2[2])*0.5);
01005         }
01006         qglEnd ();
01007         qglPointSize (1);
01008     }
01009     
01010     
01011     g_splineList->draw(static_cast<qboolean>(g_qeglobals.d_select_mode == sel_addpoint || g_qeglobals.d_select_mode == sel_editpoint));
01012     if (g_qeglobals.selectObject && (g_qeglobals.d_select_mode == sel_addpoint || g_qeglobals.d_select_mode == sel_editpoint)) {
01013         g_qeglobals.selectObject->drawSelection();
01014     }
01015 
01016     //
01017     // draw pointfile
01018     //
01019 
01020     qglEnable(GL_DEPTH_TEST);
01021     
01022 
01023     DrawPathLines ();
01024     
01025     
01026     
01027     if (g_qeglobals.d_pointfile_display_list)
01028     {
01029         Pointfile_Draw();
01030         //      glCallList (g_qeglobals.d_pointfile_display_list);
01031     }
01032     
01033     // bind back to the default texture so that we don't have problems
01034     // elsewhere using/modifying texture maps between contexts
01035     qglBindTexture( GL_TEXTURE_2D, 0 );
01036     
01037 #if 0
01038     // area selection hack
01039     if (g_qeglobals.d_select_mode == sel_area)
01040     {
01041         qglEnable (GL_BLEND);
01042         qglBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
01043         qglColor4f(0.0, 0.0, 1.0, 0.25);
01044         qglPolygonMode (GL_FRONT_AND_BACK, GL_FILL);
01045         qglRectfv(g_qeglobals.d_vAreaTL, g_qeglobals.d_vAreaBR);
01046         qglDisable (GL_BLEND);
01047     }
01048 #endif
01049     
01050     qglFinish();
01051     QE_CheckOpenGLForErrors();
01052     //  Sys_EndWait();
01053     if (m_Camera.timing)
01054     {
01055         end = Sys_DoubleTime ();
01056         Sys_Printf ("Camera: %i ms\n", (int)(1000*(end-start)));
01057     }
01058 }
01059 
01060 
01061 void CCamWnd::OnSize(UINT nType, int cx, int cy) 
01062 {
01063     CWnd::OnSize(nType, cx, cy);
01064   CRect rect;
01065   GetClientRect(rect);
01066     m_Camera.width = rect.right;
01067     m_Camera.height = rect.bottom;
01068     InvalidateRect(NULL, false);
01069 }
01070 
01071 void CCamWnd::BenchMark()
01072 {
01073     PAINTSTRUCT ps;
01074   CRect rct;
01075   GetWindowRect(rct);
01076   long lStyle = ::GetWindowLong(GetSafeHwnd(), GWL_STYLE);
01077   ::SetWindowLong(GetSafeHwnd(), GWL_STYLE, QE3_CHILDSTYLE);
01078   CWnd* pParent = GetParent();
01079   SetParent(g_pParentWnd);
01080   MoveWindow(CRect(30, 30, 400, 400), TRUE);
01081 
01082   BeginPaint(&ps);
01083   if (!qwglMakeCurrent(ps.hdc, g_qeglobals.d_hglrcBase))
01084         Error ("wglMakeCurrent failed in Benchmark");
01085   
01086     qglDrawBuffer (GL_FRONT);
01087     double dStart = Sys_DoubleTime ();
01088     for (int i=0 ; i < 100 ; i++)
01089     {
01090         m_Camera.angles[YAW] = i*4;
01091         Cam_Draw();
01092     }
01093     qwglSwapBuffers(ps.hdc);
01094     qglDrawBuffer (GL_BACK);
01095     double dEnd = Sys_DoubleTime ();
01096     EndPaint(&ps);
01097     Sys_Printf ("%5.2f seconds\n", dEnd - dStart);
01098   ::SetWindowLong(GetSafeHwnd(), GWL_STYLE, lStyle);
01099   SetParent(pParent);
01100   MoveWindow(rct, TRUE);
01101 }
01102 
01103 void CCamWnd::ReInitGL()
01104 {
01105 
01106   qwglMakeCurrent(0,0);
01107     QEW_SetupPixelFormat(GetDC()->m_hDC, true);
01108   if (!qwglMakeCurrent(g_qeglobals.d_hdcBase, g_qeglobals.d_hglrcBase))
01109       Error ("wglMakeCurrent failed");
01110 
01111   return;
01112 
01113   long lStyle = ::GetWindowLong(GetSafeHwnd(), GWL_STYLE);
01114   int nID = ::GetWindowLong(GetSafeHwnd(), GWL_ID);
01115   CWnd* pParent = GetParent();
01116   CRect rctClient;
01117   GetClientRect(rctClient);
01118   DestroyWindow();
01119   Create(CAMERA_WINDOW_CLASS, "", lStyle, rctClient, pParent, nID);
01120 }
01121 
01122 void CCamWnd::OnKeyUp(UINT nChar, UINT nRepCnt, UINT nFlags) 
01123 {
01124   g_pParentWnd->HandleKey(nChar, nRepCnt, nFlags, false);
01125 }
01126 
01127 // Timo
01128 // brush primitive texture shifting, using camera view to select translations :
01129 void CCamWnd::ShiftTexture_BrushPrimit(face_t *f, int x, int y)
01130 {
01131     vec3_t texS,texT;
01132     vec3_t viewX,viewY;
01133     int XS,XT,YS,YT;
01134     int outS,outT;
01135 #ifdef _DEBUG
01136     if (!g_qeglobals.m_bBrushPrimitMode)
01137     {
01138         Sys_Printf("Warning : unexpected call to CCamWnd::ShiftTexture_BrushPrimit with brush primitive mode disbaled\n");
01139         return;
01140     }
01141 #endif
01142     // compute face axis base
01143     ComputeAxisBase( f->plane.normal, texS, texT );
01144     // compute camera view vectors
01145     VectorCopy( m_Camera.vup, viewY );
01146     VectorCopy( m_Camera.vright, viewX );
01147     // compute best vectors
01148     ComputeBest2DVector( viewX, texS, texT, XS, XT );
01149     ComputeBest2DVector( viewY, texS, texT, YS, YT );
01150     // check this is not a degenerate case
01151     if ( ( XS == YS ) && ( XT == YT ) )
01152     {
01153 #ifdef _DEBUG
01154         Sys_Printf("Warning : degenerate best vectors axis base in CCamWnd::ShiftTexture_BrushPrimit\n");
01155 #endif
01156         // forget it
01157         Select_ShiftTexture_BrushPrimit( f, x, y );
01158         return;
01159     }
01160     // compute best fitted translation in face axis base
01161     outS = XS*x + YS*y;
01162     outT = XT*x + YT*y;
01163     // call actual texture shifting code
01164     Select_ShiftTexture_BrushPrimit( f, outS, outT );
01165 }

Generated on Thu Aug 25 12:38:27 2005 for Quake III Arena by  doxygen 1.3.9.1