CamWnd.cpp 27 KB

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