PageRenderTime 38ms CodeModel.GetById 13ms RepoModel.GetById 0ms app.codeStats 0ms

/torcs-1.3.3/src/modules/graphic/ssggraph/grmain.cpp

#
C++ | 488 lines | 373 code | 82 blank | 33 comment | 38 complexity | c86d2effeec184a86d54c59f74bce0e8 MD5 | raw file
Possible License(s): GPL-2.0, LGPL-2.0
  1. /***************************************************************************
  2. file : grmain.cpp
  3. created : Thu Aug 17 23:23:49 CEST 2000
  4. copyright : (C) 2000 by Eric Espie
  5. email : torcs@free.fr
  6. version : $Id: grmain.cpp,v 1.60.2.3 2012/02/09 22:36:26 berniw Exp $
  7. ***************************************************************************/
  8. /***************************************************************************
  9. * *
  10. * This program is free software; you can redistribute it and/or modify *
  11. * it under the terms of the GNU General Public License as published by *
  12. * the Free Software Foundation; either version 2 of the License, or *
  13. * (at your option) any later version. *
  14. * *
  15. ***************************************************************************/
  16. #include <time.h>
  17. #include <stdlib.h>
  18. #include <stdio.h>
  19. #ifdef WIN32
  20. #include <windows.h>
  21. #endif
  22. #include <GL/glut.h>
  23. #include <plib/ssg.h>
  24. #include <tgfclient.h>
  25. #include <portability.h>
  26. #include <graphic.h>
  27. #include "grmain.h"
  28. #include "grshadow.h"
  29. #include "grskidmarks.h"
  30. #include "grsmoke.h"
  31. #include "grcar.h"
  32. #include "grscreen.h"
  33. #include "grcam.h"
  34. #include "grscene.h"
  35. #include "grsound.h"
  36. #include "grboard.h"
  37. #include "grutil.h"
  38. #include "grtrackmap.h"
  39. #include "grcarlight.h"
  40. #include <glfeatures.h>
  41. int maxTextureUnits = 0;
  42. static double OldTime;
  43. static int nFrame;
  44. float grFps;
  45. double grCurTime;
  46. double grDeltaTime;
  47. int segIndice = 0;
  48. tdble grMaxDammage = 10000.0;
  49. int grNbCars = 0;
  50. void *grHandle = NULL;
  51. void *grTrackHandle = NULL;
  52. int grWinx, grWiny, grWinw, grWinh;
  53. static float grMouseRatioX, grMouseRatioY;
  54. tgrCarInfo *grCarInfo;
  55. ssgContext grContext;
  56. class cGrScreen *grScreens[GR_NB_MAX_SCREEN] = {NULL, NULL, NULL, NULL};
  57. int grNbScreen = 1;
  58. tdble grLodFactorValue = 1.0;
  59. EWheelDetail grUseDetailedWheels = DETAILED;
  60. #ifdef WIN32
  61. #include <GL/glext.h>
  62. PFNGLMULTITEXCOORD2FARBPROC glMultiTexCoord2fARB = NULL;
  63. PFNGLMULTITEXCOORD2FVARBPROC glMultiTexCoord2fvARB = NULL;
  64. PFNGLACTIVETEXTUREARBPROC glActiveTextureARB = NULL;
  65. PFNGLCLIENTACTIVETEXTUREARBPROC glClientActiveTextureARB = NULL;
  66. #endif
  67. // InitMultiTex
  68. // desc: sets up OpenGL for multitexturing support
  69. bool InitMultiTex(void)
  70. {
  71. if (GetSingleTextureMode ()) {
  72. maxTextureUnits = 1;
  73. return true;
  74. } else {
  75. // list of available extensions
  76. char *extensionStr = (char*)glGetString(GL_EXTENSIONS);
  77. if (extensionStr == NULL)
  78. return false;
  79. if (strstr(extensionStr, "GL_ARB_multitexture")) {
  80. // retrieve the maximum number of texture units allowed
  81. glGetIntegerv(GL_MAX_TEXTURE_UNITS_ARB, &maxTextureUnits);
  82. #ifdef WIN32
  83. // retrieve addresses of multitexturing functions
  84. glMultiTexCoord2fARB = (PFNGLMULTITEXCOORD2FARBPROC) wglGetProcAddress("glMultiTexCoord2fARB");
  85. glActiveTextureARB = (PFNGLACTIVETEXTUREARBPROC) wglGetProcAddress("glActiveTextureARB");
  86. glClientActiveTextureARB = (PFNGLCLIENTACTIVETEXTUREARBPROC) wglGetProcAddress("glClientActiveTextureARB");
  87. glMultiTexCoord2fvARB = (PFNGLMULTITEXCOORD2FVARBPROC) wglGetProcAddress("glMultiTexCoord2fvARB");
  88. #endif
  89. return true;
  90. } else {
  91. return false;
  92. }
  93. }
  94. }
  95. static void grAdaptScreenSize(void)
  96. {
  97. switch (grNbScreen) {
  98. case 0:
  99. case 1:
  100. grScreens[0]->activate(grWinx, grWiny, grWinw, grWinh);
  101. grScreens[1]->desactivate();
  102. grScreens[2]->desactivate();
  103. grScreens[3]->desactivate();
  104. break;
  105. case 2:
  106. grScreens[0]->activate(grWinx, grWiny + grWinh / 2, grWinw, grWinh / 2);
  107. grScreens[1]->activate(grWinx, grWiny, grWinw, grWinh / 2);
  108. grScreens[2]->desactivate();
  109. grScreens[3]->desactivate();
  110. break;
  111. case 3:
  112. grScreens[0]->activate(grWinx, grWiny + grWinh / 2, grWinw / 2, grWinh / 2);
  113. grScreens[1]->activate(grWinx + grWinw / 2, grWiny + grWinh / 2, grWinw / 2, grWinh / 2);
  114. grScreens[2]->activate(grWinx + grWinw / 4, grWiny, grWinw / 2, grWinh / 2);
  115. grScreens[3]->desactivate();
  116. break;
  117. case 4:
  118. grScreens[0]->activate(grWinx, grWiny + grWinh / 2, grWinw / 2, grWinh / 2);
  119. grScreens[1]->activate(grWinx + grWinw / 2, grWiny + grWinh / 2, grWinw / 2, grWinh / 2);
  120. grScreens[2]->activate(grWinx, grWiny, grWinw / 2, grWinh / 2);
  121. grScreens[3]->activate(grWinx + grWinw / 2, grWiny, grWinw / 2, grWinh / 2);
  122. break;
  123. }
  124. }
  125. static void
  126. grSplitScreen(void *vp)
  127. {
  128. long p = (long)vp;
  129. switch (p) {
  130. case GR_SPLIT_ADD:
  131. grNbScreen++;
  132. if (grNbScreen > GR_NB_MAX_SCREEN) {
  133. grNbScreen = GR_NB_MAX_SCREEN;
  134. }
  135. break;
  136. case GR_SPLIT_REM:
  137. grNbScreen--;
  138. if (grNbScreen < 1) {
  139. grNbScreen = 1;
  140. }
  141. break;
  142. }
  143. GfParmSetNum(grHandle, GR_SCT_DISPMODE, GR_ATT_NB_SCREENS, NULL, grNbScreen);
  144. GfParmWriteFile(NULL, grHandle, "Graph");
  145. grAdaptScreenSize();
  146. }
  147. static class cGrScreen *
  148. grGetcurrentScreen(void)
  149. {
  150. tMouseInfo *mouse;
  151. int i;
  152. int x, y;
  153. mouse = GfuiMouseInfo();
  154. x = (int)(mouse->X * grMouseRatioX);
  155. y = (int)(mouse->Y * grMouseRatioY);
  156. for (i = 0; i < GR_NB_MAX_SCREEN; i++) {
  157. if (grScreens[i]->isInScreen(x, y)) {
  158. return grScreens[i];
  159. }
  160. }
  161. return grScreens[0];
  162. }
  163. static void
  164. grSetZoom(void *vp)
  165. {
  166. grGetcurrentScreen()->setZoom((long)vp);
  167. }
  168. static void
  169. grSelectCamera(void *vp)
  170. {
  171. grGetcurrentScreen()->selectCamera((long)vp);
  172. }
  173. static void
  174. grSelectBoard(void *vp)
  175. {
  176. grGetcurrentScreen()->selectBoard((long)vp);
  177. }
  178. static void
  179. grSelectTrackMap(void * /* vp */)
  180. {
  181. grGetcurrentScreen()->selectTrackMap();
  182. }
  183. static void
  184. grPrevCar(void * /* dummy */)
  185. {
  186. grGetcurrentScreen()->selectPrevCar();
  187. }
  188. static void
  189. grNextCar(void * /* dummy */)
  190. {
  191. grGetcurrentScreen()->selectNextCar();
  192. }
  193. static void
  194. grSwitchMirror(void * /* dummy */)
  195. {
  196. grGetcurrentScreen()->switchMirror();
  197. }
  198. int
  199. initView(int x, int y, int width, int height, int /* flag */, void *screen)
  200. {
  201. int i;
  202. const int BUFSIZE = 1024;
  203. char buf[BUFSIZE];
  204. if (maxTextureUnits==0) {
  205. InitMultiTex();
  206. }
  207. grWinx = x;
  208. grWiny = y;
  209. grWinw = width;
  210. grWinh = height;
  211. grMouseRatioX = width / 640.0;
  212. grMouseRatioY = height / 480.0;
  213. OldTime = GfTimeClock();
  214. nFrame = 0;
  215. grFps = 0;
  216. snprintf(buf, BUFSIZE, "%s%s", GetLocalDir(), GR_PARAM_FILE);
  217. grHandle = GfParmReadFile(buf, GFPARM_RMODE_STD | GFPARM_RMODE_CREAT);
  218. for (i = 0; i < GR_NB_MAX_SCREEN; i++) {
  219. grScreens[i]->initBoard ();
  220. }
  221. GfuiAddSKey(screen, GLUT_KEY_HOME, "Zoom Maximum", (void*)GR_ZOOM_MAX, grSetZoom, NULL);
  222. GfuiAddSKey(screen, GLUT_KEY_END, "Zoom Minimum", (void*)GR_ZOOM_MIN, grSetZoom, NULL);
  223. GfuiAddKey(screen, '*', "Zoom Default", (void*)GR_ZOOM_DFLT, grSetZoom, NULL);
  224. GfuiAddSKey(screen, GLUT_KEY_PAGE_UP, "Select Previous Car", (void*)0, grPrevCar, NULL);
  225. GfuiAddSKey(screen, GLUT_KEY_PAGE_DOWN, "Select Next Car", (void*)0, grNextCar, NULL);
  226. GfuiAddSKey(screen, GLUT_KEY_F2, "Driver Views", (void*)0, grSelectCamera, NULL);
  227. GfuiAddSKey(screen, GLUT_KEY_F3, "Car Views", (void*)1, grSelectCamera, NULL);
  228. GfuiAddSKey(screen, GLUT_KEY_F4, "Side Car Views", (void*)2, grSelectCamera, NULL);
  229. GfuiAddSKey(screen, GLUT_KEY_F5, "Up Car View", (void*)3, grSelectCamera, NULL);
  230. GfuiAddSKey(screen, GLUT_KEY_F6, "Persp Car View", (void*)4, grSelectCamera, NULL);
  231. GfuiAddSKey(screen, GLUT_KEY_F7, "All Circuit Views", (void*)5, grSelectCamera, NULL);
  232. GfuiAddSKey(screen, GLUT_KEY_F8, "Track View", (void*)6, grSelectCamera, NULL);
  233. GfuiAddSKey(screen, GLUT_KEY_F9, "Track View Zoomed", (void*)7, grSelectCamera, NULL);
  234. GfuiAddSKey(screen, GLUT_KEY_F10, "Follow Car Zoomed", (void*)8, grSelectCamera, NULL);
  235. GfuiAddSKey(screen, GLUT_KEY_F11, "TV Director View", (void*)9, grSelectCamera, NULL);
  236. GfuiAddKey(screen, '5', "FPS Counter", (void*)3, grSelectBoard, NULL);
  237. GfuiAddKey(screen, '4', "G/Cmd Graph", (void*)4, grSelectBoard, NULL);
  238. GfuiAddKey(screen, '3', "Leaders Board", (void*)2, grSelectBoard, NULL);
  239. GfuiAddKey(screen, '2', "Driver Counters", (void*)1, grSelectBoard, NULL);
  240. GfuiAddKey(screen, '1', "Driver Board", (void*)0, grSelectBoard, NULL);
  241. GfuiAddKey(screen, '9', "Mirror", (void*)0, grSwitchMirror, NULL);
  242. GfuiAddKey(screen, '0', "Arcade Board", (void*)5, grSelectBoard, NULL);
  243. GfuiAddKey(screen, '>', "Zoom In", (void*)GR_ZOOM_IN, grSetZoom, NULL);
  244. GfuiAddKey(screen, '<', "Zoom Out", (void*)GR_ZOOM_OUT, grSetZoom, NULL);
  245. GfuiAddKey(screen, '[', "Split Screen", (void*)GR_SPLIT_ADD, grSplitScreen, NULL);
  246. GfuiAddKey(screen, ']', "UnSplit Screen", (void*)GR_SPLIT_REM, grSplitScreen, NULL);
  247. GfuiAddKey(screen, 'm', "Track Maps", (void*)0, grSelectTrackMap, NULL);
  248. grAdaptScreenSize();
  249. grInitScene();
  250. grLodFactorValue = GfParmGetNum(grHandle, GR_SCT_GRAPHIC, GR_ATT_LODFACTOR, NULL, 1.0);
  251. const char* wheelDetailOption = GfParmGetStr(grHandle, GR_SCT_GRAPHIC, GR_ATT_WHEELRENDERING, GR_ATT_WHEELRENDERING_DETAILED);
  252. if (strcmp(wheelDetailOption,GR_ATT_WHEELRENDERING_DETAILED ) == 0) {
  253. grUseDetailedWheels = DETAILED;
  254. } else if (strcmp(wheelDetailOption,GR_ATT_WHEELRENDERING_SIMPLE ) == 0) {
  255. grUseDetailedWheels = SIMPLE;
  256. }
  257. return 0;
  258. }
  259. int
  260. refresh(tSituation *s)
  261. {
  262. int i;
  263. START_PROFILE("refresh");
  264. nFrame++;
  265. grCurTime = GfTimeClock();
  266. grDeltaTime = grCurTime - OldTime;
  267. if ((grCurTime - OldTime) > 1.0) {
  268. /* The Frames Per Second (FPS) display is refreshed every second */
  269. grFps = (tdble)nFrame / (grCurTime - OldTime);
  270. nFrame = 0;
  271. OldTime = grCurTime;
  272. }
  273. TRACE_GL("refresh: start");
  274. START_PROFILE("grRefreshSound*");
  275. grRefreshSound(s, grScreens[0]->getCurCamera());
  276. STOP_PROFILE("grRefreshSound*");
  277. START_PROFILE("grDrawBackground/glClear");
  278. glDepthFunc(GL_LEQUAL);
  279. glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
  280. STOP_PROFILE("grDrawBackground/glClear");
  281. for (i = 0; i < GR_NB_MAX_SCREEN; i++) {
  282. grScreens[i]->update(s, grFps);
  283. }
  284. grUpdateSmoke(s->currentTime);
  285. STOP_PROFILE("refresh");
  286. return 0;
  287. }
  288. int
  289. initCars(tSituation *s)
  290. {
  291. const int IDXSIZE = 16;
  292. char idx[IDXSIZE];
  293. int index;
  294. int i;
  295. tCarElt *elt;
  296. void *hdle;
  297. const int BUFSIZE = 1024;
  298. char buf[1024];
  299. TRACE_GL("initCars: start");
  300. snprintf(buf, BUFSIZE, "%s%s", GetLocalDir(), GR_PARAM_FILE);
  301. grHandle = GfParmReadFile(buf, GFPARM_RMODE_STD | GFPARM_RMODE_CREAT);
  302. grInitCommonState();
  303. grInitCarlight(s->_ncars);
  304. grMaxDammage = (tdble)s->_maxDammage;
  305. grNbCars = s->_ncars;
  306. grCustomizePits();
  307. grCarInfo = (tgrCarInfo*)calloc(s->_ncars, sizeof(tgrCarInfo));
  308. for (i = 0; i < s->_ncars; i++) {
  309. elt = s->cars[i];
  310. /* Shadow init (Should be done before the cars for display order) */
  311. grInitShadow(elt);
  312. /* Skidmarks init */
  313. grInitSkidmarks(elt);
  314. }
  315. grNbScreen = 0;
  316. for (i = 0; i < s->_ncars; i++) {
  317. elt = s->cars[i];
  318. index = elt->index;
  319. hdle = elt->_paramsHandle;
  320. snprintf(idx, IDXSIZE, "Robots/index/%d", elt->_driverIndex);
  321. grCarInfo[index].iconColor[0] = GfParmGetNum(hdle, idx, "red", (char*)NULL, 0);
  322. grCarInfo[index].iconColor[1] = GfParmGetNum(hdle, idx, "green", (char*)NULL, 0);
  323. grCarInfo[index].iconColor[2] = GfParmGetNum(hdle, idx, "blue", (char*)NULL, 0);
  324. grCarInfo[index].iconColor[3] = 1.0;
  325. grInitCar(elt);
  326. if ((elt->_driverType == RM_DRV_HUMAN) && (grNbScreen < GR_NB_MAX_SCREEN)) {
  327. grScreens[grNbScreen]->setCurrentCar(elt);
  328. grNbScreen++;
  329. }
  330. }
  331. if (grNbScreen == 0) {
  332. grNbScreen = (int)GfParmGetNum(grHandle, GR_SCT_DISPMODE, GR_ATT_NB_SCREENS, NULL, 1.0);
  333. }
  334. for (i = 0; i < GR_NB_MAX_SCREEN; i++) {
  335. grScreens[i]->initCams(s);
  336. }
  337. TRACE_GL("initCars: end");
  338. grInitSmoke(s->_ncars);
  339. grInitSound(s, s->_ncars);
  340. grAdaptScreenSize();
  341. return 0;
  342. }
  343. void
  344. shutdownCars(void)
  345. {
  346. int i;
  347. GfOut("-- shutdownCars\n");
  348. grShutdownSound(grNbCars);
  349. if (grNbCars) {
  350. grShutdownBoardCar();
  351. grShutdownSkidmarks();
  352. grShutdownSmoke();
  353. grShudownCarlight();
  354. /* Delete ssg objects */
  355. CarsAnchor->removeAllKids();
  356. ShadowAnchor->removeAllKids();
  357. for (i = 0; i < grNbCars; i++) {
  358. ssgDeRefDelete(grCarInfo[i].envSelector);
  359. ssgDeRefDelete(grCarInfo[i].shadowBase);
  360. if (grCarInfo[i].driverSelectorinsg == false) {
  361. delete grCarInfo[i].driverSelector;
  362. }
  363. }
  364. PitsAnchor->removeAllKids();
  365. ThePits = 0;
  366. free(grCarInfo);
  367. }
  368. GfParmReleaseHandle(grHandle);
  369. for (i = 0; i < GR_NB_MAX_SCREEN; i++) {
  370. grScreens[i]->setCurrentCar(NULL);
  371. }
  372. }
  373. int
  374. initTrack(tTrack *track)
  375. {
  376. int i;
  377. // The inittrack does as well init the context, that is highly inconsistent, IMHO.
  378. // TODO: Find a solution to init the graphics first independent of objects.
  379. grContext.makeCurrent();
  380. grTrackHandle = GfParmReadFile(track->filename, GFPARM_RMODE_STD | GFPARM_RMODE_CREAT);
  381. grLoadScene(track);
  382. for (i = 0; i < GR_NB_MAX_SCREEN; i++) {
  383. grScreens[i] = new cGrScreen(i);
  384. }
  385. return 0;
  386. }
  387. void
  388. shutdownTrack(void)
  389. {
  390. int i;
  391. grShutdownScene();
  392. grShutdownState();
  393. for (i = 0; i < GR_NB_MAX_SCREEN; i++) {
  394. if (grScreens[i] != NULL) {
  395. delete grScreens[i];
  396. grScreens[i] = NULL;
  397. }
  398. }
  399. }
  400. /*void bendCar (int index, sgVec3 poc, sgVec3 force, int cnt)
  401. {
  402. if (grCarInfo)
  403. grPropagateDamage (grCarInfo[index].carEntity, poc, force, cnt);
  404. }*/