camera.c 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595
  1. /*
  2. ===========================================================================
  3. Copyright (C) 1997-2006 Id Software, Inc.
  4. This file is part of Quake 2 Tools source code.
  5. Quake 2 Tools 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 2 Tools 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 Quake 2 Tools source code; if not, write to the Free Software
  15. Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  16. ===========================================================================
  17. */
  18. #include "qe3.h"
  19. #define PAGEFLIPS 2
  20. void DrawPathLines (void);
  21. camera_t camera;
  22. /*
  23. ============
  24. Cam_Init
  25. ============
  26. */
  27. void Cam_Init (void)
  28. {
  29. // camera.draw_mode = cd_texture;
  30. // camera.draw_mode = cd_solid;
  31. // camera.draw_mode = cd_wire;
  32. camera.timing = false;
  33. camera.origin[0] = 0;
  34. camera.origin[1] = 20;
  35. camera.origin[2] = 46;
  36. camera.color[0] = 0.3;
  37. camera.color[1] = 0.3;
  38. camera.color[2] = 0.3;
  39. }
  40. //============================================================================
  41. void Cam_BuildMatrix (void)
  42. {
  43. float xa, ya;
  44. float matrix[4][4];
  45. int i;
  46. xa = camera.angles[0]/180*Q_PI;
  47. ya = camera.angles[1]/180*Q_PI;
  48. // the movement matrix is kept 2d
  49. camera.forward[0] = cos(ya);
  50. camera.forward[1] = sin(ya);
  51. camera.right[0] = camera.forward[1];
  52. camera.right[1] = -camera.forward[0];
  53. glGetFloatv (GL_PROJECTION_MATRIX, &matrix[0][0]);
  54. for (i=0 ; i<3 ; i++)
  55. {
  56. camera.vright[i] = matrix[i][0];
  57. camera.vup[i] = matrix[i][1];
  58. camera.vpn[i] = matrix[i][2];
  59. }
  60. VectorNormalize (camera.vright);
  61. VectorNormalize (camera.vup);
  62. VectorNormalize (camera.vpn);
  63. }
  64. //===============================================
  65. /*
  66. ===============
  67. Cam_ChangeFloor
  68. ===============
  69. */
  70. void Cam_ChangeFloor (qboolean up)
  71. {
  72. brush_t *b;
  73. float d, bestd, current;
  74. vec3_t start, dir;
  75. start[0] = camera.origin[0];
  76. start[1] = camera.origin[1];
  77. start[2] = 8192;
  78. dir[0] = dir[1] = 0;
  79. dir[2] = -1;
  80. current = 8192 - (camera.origin[2] - 48);
  81. if (up)
  82. bestd = 0;
  83. else
  84. bestd = 16384;
  85. for (b=active_brushes.next ; b != &active_brushes ; b=b->next)
  86. {
  87. if (!Brush_Ray (start, dir, b, &d))
  88. continue;
  89. if (up && d < current && d > bestd)
  90. bestd = d;
  91. if (!up && d > current && d < bestd)
  92. bestd = d;
  93. }
  94. if (bestd == 0 || bestd == 16384)
  95. return;
  96. camera.origin[2] += current - bestd;
  97. Sys_UpdateWindows (W_CAMERA|W_Z_OVERLAY);
  98. }
  99. //===============================================
  100. int cambuttonstate;
  101. static int buttonx, buttony;
  102. static int cursorx, cursory;
  103. face_t *side_select;
  104. #define ANGLE_SPEED 300
  105. #define MOVE_SPEED 400
  106. /*
  107. ================
  108. Cam_PositionDrag
  109. ================
  110. */
  111. void Cam_PositionDrag (void)
  112. {
  113. int x, y;
  114. Sys_GetCursorPos (&x, &y);
  115. if (x != cursorx || y != cursory)
  116. {
  117. x -= cursorx;
  118. VectorMA (camera.origin, x, camera.vright, camera.origin);
  119. y -= cursory;
  120. camera.origin[2] -= y;
  121. Sys_SetCursorPos (cursorx, cursory);
  122. Sys_UpdateWindows (W_CAMERA | W_XY_OVERLAY);
  123. }
  124. }
  125. /*
  126. ===============
  127. Cam_MouseControl
  128. ===============
  129. */
  130. void Cam_MouseControl (float dtime)
  131. {
  132. int xl, xh;
  133. int yl, yh;
  134. float xf, yf;
  135. if (cambuttonstate != MK_RBUTTON)
  136. return;
  137. xf = (float)(buttonx - camera.width/2) / (camera.width/2);
  138. yf = (float)(buttony - camera.height/2) / (camera.height/2);
  139. xl = camera.width/3;
  140. xh = xl*2;
  141. yl = camera.height/3;
  142. yh = yl*2;
  143. #if 0
  144. // strafe
  145. if (buttony < yl && (buttonx < xl || buttonx > xh))
  146. VectorMA (camera.origin, xf*dtime*MOVE_SPEED, camera.right, camera.origin);
  147. else
  148. #endif
  149. {
  150. xf *= 1.0 - fabs(yf);
  151. if (xf < 0)
  152. {
  153. xf += 0.1;
  154. if (xf > 0)
  155. xf = 0;
  156. }
  157. else
  158. {
  159. xf -= 0.1;
  160. if (xf < 0)
  161. xf = 0;
  162. }
  163. VectorMA (camera.origin, yf*dtime*MOVE_SPEED, camera.forward, camera.origin);
  164. camera.angles[YAW] += xf*-dtime*ANGLE_SPEED;
  165. }
  166. Sys_UpdateWindows (W_CAMERA|W_XY_OVERLAY);
  167. }
  168. /*
  169. ==============
  170. Cam_MouseDown
  171. ==============
  172. */
  173. void Cam_MouseDown (int x, int y, int buttons)
  174. {
  175. vec3_t dir;
  176. float f, r, u;
  177. int i;
  178. //
  179. // calc ray direction
  180. //
  181. u = (float)(y - camera.height/2) / (camera.width/2);
  182. r = (float)(x - camera.width/2) / (camera.width/2);
  183. f = 1;
  184. for (i=0 ; i<3 ; i++)
  185. dir[i] = camera.vpn[i] * f + camera.vright[i] * r + camera.vup[i] * u;
  186. VectorNormalize (dir);
  187. Sys_GetCursorPos (&cursorx, &cursory);
  188. cambuttonstate = buttons;
  189. buttonx = x;
  190. buttony = y;
  191. // LBUTTON = manipulate selection
  192. // shift-LBUTTON = select
  193. // middle button = grab texture
  194. // ctrl-middle button = set entire brush to texture
  195. // ctrl-shift-middle button = set single face to texture
  196. if ( (buttons == MK_LBUTTON)
  197. || (buttons == (MK_LBUTTON | MK_SHIFT))
  198. || (buttons == (MK_LBUTTON | MK_CONTROL))
  199. || (buttons == (MK_LBUTTON | MK_CONTROL | MK_SHIFT))
  200. || (buttons == MK_MBUTTON)
  201. || (buttons == (MK_MBUTTON|MK_CONTROL))
  202. || (buttons == (MK_MBUTTON|MK_SHIFT|MK_CONTROL)) )
  203. {
  204. Drag_Begin (x, y, buttons,
  205. camera.vright, camera.vup,
  206. camera.origin, dir);
  207. return;
  208. }
  209. if (buttons == MK_RBUTTON)
  210. {
  211. Cam_MouseControl (0.1);
  212. return;
  213. }
  214. }
  215. /*
  216. ==============
  217. Cam_MouseUp
  218. ==============
  219. */
  220. void Cam_MouseUp (int x, int y, int buttons)
  221. {
  222. cambuttonstate = 0;
  223. Drag_MouseUp ();
  224. }
  225. /*
  226. ==============
  227. Cam_MouseMoved
  228. ==============
  229. */
  230. void Cam_MouseMoved (int x, int y, int buttons)
  231. {
  232. cambuttonstate = buttons;
  233. if (!buttons)
  234. return;
  235. buttonx = x;
  236. buttony = y;
  237. if (buttons == (MK_RBUTTON|MK_CONTROL) )
  238. {
  239. Cam_PositionDrag ();
  240. Sys_UpdateWindows (W_XY|W_CAMERA|W_Z);
  241. return;
  242. }
  243. Sys_GetCursorPos (&cursorx, &cursory);
  244. if (buttons & (MK_LBUTTON | MK_MBUTTON) )
  245. {
  246. Drag_MouseMoved (x, y, buttons);
  247. Sys_UpdateWindows (W_XY|W_CAMERA|W_Z);
  248. }
  249. }
  250. vec3_t cull1, cull2;
  251. int cullv1[3], cullv2[3];
  252. void InitCull (void)
  253. {
  254. int i;
  255. VectorSubtract (camera.vpn, camera.vright, cull1);
  256. VectorAdd (camera.vpn, camera.vright, cull2);
  257. for (i=0 ; i<3 ; i++)
  258. {
  259. if (cull1[i] > 0)
  260. cullv1[i] = 3+i;
  261. else
  262. cullv1[i] = i;
  263. if (cull2[i] > 0)
  264. cullv2[i] = 3+i;
  265. else
  266. cullv2[i] = i;
  267. }
  268. }
  269. qboolean CullBrush (brush_t *b)
  270. {
  271. int i;
  272. vec3_t point;
  273. float d;
  274. for (i=0 ; i<3 ; i++)
  275. point[i] = b->mins[cullv1[i]] - camera.origin[i];
  276. d = DotProduct (point, cull1);
  277. if (d < -1)
  278. return true;
  279. for (i=0 ; i<3 ; i++)
  280. point[i] = b->mins[cullv2[i]] - camera.origin[i];
  281. d = DotProduct (point, cull2);
  282. if (d < -1)
  283. return true;
  284. return false;
  285. }
  286. /*
  287. ==============
  288. Cam_Draw
  289. ==============
  290. */
  291. void Cam_Draw (void)
  292. {
  293. brush_t *brush;
  294. face_t *face;
  295. float screenaspect;
  296. float yfov;
  297. double start, end;
  298. int i;
  299. if (!active_brushes.next)
  300. return; // not valid yet
  301. if (camera.timing)
  302. start = Sys_DoubleTime ();
  303. //
  304. // clear
  305. //
  306. QE_CheckOpenGLForErrors();
  307. glViewport(0, 0, camera.width, camera.height);
  308. glScissor(0, 0, camera.width, camera.height);
  309. glClearColor (
  310. g_qeglobals.d_savedinfo.colors[COLOR_CAMERABACK][0],
  311. g_qeglobals.d_savedinfo.colors[COLOR_CAMERABACK][1],
  312. g_qeglobals.d_savedinfo.colors[COLOR_CAMERABACK][2],
  313. 0);
  314. glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
  315. //
  316. // set up viewpoint
  317. //
  318. glMatrixMode(GL_PROJECTION);
  319. glLoadIdentity ();
  320. screenaspect = (float)camera.width/camera.height;
  321. yfov = 2*atan((float)camera.height/camera.width)*180/Q_PI;
  322. gluPerspective (yfov, screenaspect, 2, 8192);
  323. glRotatef (-90, 1, 0, 0); // put Z going up
  324. glRotatef (90, 0, 0, 1); // put Z going up
  325. glRotatef (camera.angles[0], 0, 1, 0);
  326. glRotatef (-camera.angles[1], 0, 0, 1);
  327. glTranslatef (-camera.origin[0], -camera.origin[1], -camera.origin[2]);
  328. Cam_BuildMatrix ();
  329. InitCull ();
  330. //
  331. // draw stuff
  332. //
  333. switch (camera.draw_mode)
  334. {
  335. case cd_wire:
  336. glPolygonMode (GL_FRONT_AND_BACK, GL_LINE);
  337. glDisable(GL_TEXTURE_2D);
  338. glDisable(GL_TEXTURE_1D);
  339. glDisable(GL_BLEND);
  340. glDisable(GL_DEPTH_TEST);
  341. glColor3f(1.0, 1.0, 1.0);
  342. // glEnable (GL_LINE_SMOOTH);
  343. break;
  344. case cd_solid:
  345. glCullFace(GL_FRONT);
  346. glEnable(GL_CULL_FACE);
  347. glShadeModel (GL_FLAT);
  348. glPolygonMode (GL_FRONT_AND_BACK, GL_FILL);
  349. glDisable(GL_TEXTURE_2D);
  350. glDisable(GL_BLEND);
  351. glEnable(GL_DEPTH_TEST);
  352. glDepthFunc (GL_LEQUAL);
  353. break;
  354. case cd_texture:
  355. glCullFace(GL_FRONT);
  356. glEnable(GL_CULL_FACE);
  357. glShadeModel (GL_FLAT);
  358. glPolygonMode (GL_FRONT_AND_BACK, GL_FILL);
  359. glEnable(GL_TEXTURE_2D);
  360. glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
  361. glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
  362. glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
  363. glDisable(GL_BLEND);
  364. glEnable(GL_DEPTH_TEST);
  365. glDepthFunc (GL_LEQUAL);
  366. #if 0
  367. {
  368. GLfloat fogColor[4] = {0.0, 1.0, 0.0, 0.25};
  369. glFogi (GL_FOG_MODE, GL_LINEAR);
  370. glHint (GL_FOG_HINT, GL_NICEST); /* per pixel */
  371. glFogf (GL_FOG_START, -8192);
  372. glFogf (GL_FOG_END, 65536);
  373. glFogfv (GL_FOG_COLOR, fogColor);
  374. }
  375. #endif
  376. break;
  377. case cd_blend:
  378. glCullFace(GL_FRONT);
  379. glEnable(GL_CULL_FACE);
  380. glShadeModel (GL_FLAT);
  381. glPolygonMode (GL_FRONT_AND_BACK, GL_FILL);
  382. glEnable(GL_TEXTURE_2D);
  383. glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
  384. glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
  385. glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
  386. glDisable(GL_DEPTH_TEST);
  387. glEnable (GL_BLEND);
  388. glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
  389. break;
  390. }
  391. glMatrixMode(GL_TEXTURE);
  392. for (brush = active_brushes.next ; brush != &active_brushes ; brush=brush->next)
  393. {
  394. if (CullBrush (brush))
  395. continue;
  396. if (FilterBrush (brush))
  397. continue;
  398. Brush_Draw( brush );
  399. }
  400. glMatrixMode(GL_PROJECTION);
  401. //
  402. // now draw selected brushes
  403. //
  404. glTranslatef (g_qeglobals.d_select_translate[0], g_qeglobals.d_select_translate[1], g_qeglobals.d_select_translate[2]);
  405. glMatrixMode(GL_TEXTURE);
  406. // draw normally
  407. for (brush = selected_brushes.next ; brush != &selected_brushes ; brush=brush->next)
  408. {
  409. Brush_Draw( brush );
  410. }
  411. // blend on top
  412. glMatrixMode(GL_PROJECTION);
  413. glColor4f(1.0, 0.0, 0.0, 0.3);
  414. glEnable (GL_BLEND);
  415. glPolygonMode (GL_FRONT_AND_BACK, GL_FILL);
  416. glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
  417. glDisable (GL_TEXTURE_2D);
  418. for (brush = selected_brushes.next ; brush != &selected_brushes ; brush=brush->next)
  419. for (face=brush->brush_faces ; face ; face=face->next)
  420. Face_Draw( face );
  421. if (selected_face)
  422. Face_Draw(selected_face);
  423. // non-zbuffered outline
  424. glDisable (GL_BLEND);
  425. glDisable (GL_DEPTH_TEST);
  426. glPolygonMode (GL_FRONT_AND_BACK, GL_LINE);
  427. glColor3f (1, 1, 1);
  428. for (brush = selected_brushes.next ; brush != &selected_brushes ; brush=brush->next)
  429. for (face=brush->brush_faces ; face ; face=face->next)
  430. Face_Draw( face );
  431. // edge / vertex flags
  432. if (g_qeglobals.d_select_mode == sel_vertex)
  433. {
  434. glPointSize (4);
  435. glColor3f (0,1,0);
  436. glBegin (GL_POINTS);
  437. for (i=0 ; i<g_qeglobals.d_numpoints ; i++)
  438. glVertex3fv (g_qeglobals.d_points[i]);
  439. glEnd ();
  440. glPointSize (1);
  441. }
  442. else if (g_qeglobals.d_select_mode == sel_edge)
  443. {
  444. float *v1, *v2;
  445. glPointSize (4);
  446. glColor3f (0,0,1);
  447. glBegin (GL_POINTS);
  448. for (i=0 ; i<g_qeglobals.d_numedges ; i++)
  449. {
  450. v1 = g_qeglobals.d_points[g_qeglobals.d_edges[i].p1];
  451. v2 = g_qeglobals.d_points[g_qeglobals.d_edges[i].p2];
  452. glVertex3f ( (v1[0]+v2[0])*0.5,(v1[1]+v2[1])*0.5,(v1[2]+v2[2])*0.5);
  453. }
  454. glEnd ();
  455. glPointSize (1);
  456. }
  457. //
  458. // draw pointfile
  459. //
  460. glEnable(GL_DEPTH_TEST);
  461. DrawPathLines ();
  462. if (g_qeglobals.d_pointfile_display_list)
  463. {
  464. Pointfile_Draw();
  465. // glCallList (g_qeglobals.d_pointfile_display_list);
  466. }
  467. // bind back to the default texture so that we don't have problems
  468. // elsewhere using/modifying texture maps between contexts
  469. glBindTexture( GL_TEXTURE_2D, 0 );
  470. glFinish();
  471. QE_CheckOpenGLForErrors();
  472. // Sys_EndWait();
  473. if (camera.timing)
  474. {
  475. end = Sys_DoubleTime ();
  476. Sys_Printf ("Camera: %i ms\n", (int)(1000*(end-start)));
  477. }
  478. }