home *** CD-ROM | disk | FTP | other *** search
/ PC PowerPlay 58 / pcpp58a.iso / extras / quake 3 source / Q3A_ToolSource.exe / Main / CamWnd.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  2001-01-02  |  26.0 KB  |  1,107 lines

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