Main.cpp
上传用户:gb3593
上传日期:2022-01-07
资源大小:3028k
文件大小:9k
源码类别:

游戏引擎

开发平台:

Visual C++

  1. /*
  2. * Copyright (c) 2006-2007 Erin Catto http://www.gphysics.com
  3. *
  4. * This software is provided 'as-is', without any express or implied
  5. * warranty.  In no event will the authors be held liable for any damages
  6. * arising from the use of this software.
  7. * Permission is granted to anyone to use this software for any purpose,
  8. * including commercial applications, and to alter it and redistribute it
  9. * freely, subject to the following restrictions:
  10. * 1. The origin of this software must not be misrepresented; you must not
  11. * claim that you wrote the original software. If you use this software
  12. * in a product, an acknowledgment in the product documentation would be
  13. * appreciated but is not required.
  14. * 2. Altered source versions must be plainly marked as such, and must not be
  15. * misrepresented as being the original software.
  16. * 3. This notice may not be removed or altered from any source distribution.
  17. */
  18. #include "Render.h"
  19. #include "Test.h"
  20. #include "glui/GL/glui.h"
  21. #include <cstdio>
  22. namespace
  23. {
  24. int32 testIndex = 0;
  25. int32 testSelection = 0;
  26. int32 testCount = 0;
  27. TestEntry* entry;
  28. Test* test;
  29. Settings settings;
  30. int32 width = 640;
  31. int32 height = 480;
  32. int32 framePeriod = 16;
  33. int32 mainWindow;
  34. float settingsHz = 60.0;
  35. GLUI *glui;
  36. float32 viewZoom = 1.0f;
  37. b2Vec2 viewCenter(0.0f, 20.0f);
  38. int tx, ty, tw, th;
  39. bool rMouseDown;
  40. b2Vec2 lastp;
  41. }
  42. void Resize(int32 w, int32 h)
  43. {
  44. width = w;
  45. height = h;
  46. GLUI_Master.get_viewport_area(&tx, &ty, &tw, &th);
  47. glViewport(tx, ty, tw, th);
  48. glMatrixMode(GL_PROJECTION);
  49. glLoadIdentity();
  50. float32 ratio = float32(tw) / float32(th);
  51. b2Vec2 extents(ratio * 25.0f, 25.0f);
  52. extents *= viewZoom;
  53. b2Vec2 lower = viewCenter - extents;
  54. b2Vec2 upper = viewCenter + extents;
  55. // L/R/B/T
  56. gluOrtho2D(lower.x, upper.x, lower.y, upper.y);
  57. }
  58. b2Vec2 ConvertScreenToWorld(int32 x, int32 y)
  59. {
  60. float32 u = x / float32(tw);
  61. float32 v = (th - y) / float32(th);
  62. float32 ratio = float32(tw) / float32(th);
  63. b2Vec2 extents(ratio * 25.0f, 25.0f);
  64. extents *= viewZoom;
  65. b2Vec2 lower = viewCenter - extents;
  66. b2Vec2 upper = viewCenter + extents;
  67. b2Vec2 p;
  68. p.x = (1.0f - u) * lower.x + u * upper.x;
  69. p.y = (1.0f - v) * lower.y + v * upper.y;
  70. return p;
  71. }
  72. // This is used to control the frame rate (60Hz).
  73. void Timer(int)
  74. {
  75. glutSetWindow(mainWindow);
  76. glutPostRedisplay();
  77. glutTimerFunc(framePeriod, Timer, 0);
  78. }
  79. void SimulationLoop()
  80. {
  81. glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
  82. glMatrixMode(GL_MODELVIEW);
  83. glLoadIdentity();
  84. test->SetTextLine(30);
  85. settings.hz = settingsHz;
  86. test->Step(&settings);
  87. test->DrawTitle(5, 15, entry->name);
  88. glutSwapBuffers();
  89. if (testSelection != testIndex)
  90. {
  91. testIndex = testSelection;
  92. delete test;
  93. entry = g_testEntries + testIndex;
  94. test = entry->createFcn();
  95. viewZoom = 1.0f;
  96. viewCenter.Set(0.0f, 20.0f);
  97. Resize(width, height);
  98. }
  99. }
  100. void Keyboard(unsigned char key, int x, int y)
  101. {
  102. B2_NOT_USED(x);
  103. B2_NOT_USED(y);
  104. switch (key)
  105. {
  106. case 27:
  107. exit(0);
  108. break;
  109. // Press 'z' to zoom out.
  110. case 'z':
  111. viewZoom = b2Min(1.1f * viewZoom, 20.0f);
  112. Resize(width, height);
  113. break;
  114. // Press 'x' to zoom in.
  115. case 'x':
  116. viewZoom = b2Max(0.9f * viewZoom, 0.02f);
  117. Resize(width, height);
  118. break;
  119. // Press 'r' to reset.
  120. case 'r':
  121. delete test;
  122. test = entry->createFcn();
  123. break;
  124. // Press space to launch a bomb.
  125. case ' ':
  126. if (test)
  127. {
  128. test->LaunchBomb();
  129. }
  130. break;
  131.  
  132. case 'p':
  133. settings.pause = !settings.pause;
  134. break;
  135. // Press [ to prev test.
  136. case '[':
  137. --testSelection;
  138. if (testSelection < 0)
  139. {
  140. testSelection = testCount - 1;
  141. }
  142. glui->sync_live();
  143. break;
  144. // Press ] to next test.
  145. case ']':
  146. ++testSelection;
  147. if (testSelection == testCount)
  148. {
  149. testSelection = 0;
  150. }
  151. glui->sync_live();
  152. break;
  153. default:
  154. if (test)
  155. {
  156. test->Keyboard(key);
  157. }
  158. }
  159. }
  160. void KeyboardSpecial(int key, int x, int y)
  161. {
  162. B2_NOT_USED(x);
  163. B2_NOT_USED(y);
  164. switch (key)
  165. {
  166. case GLUT_ACTIVE_SHIFT:
  167. // Press left to pan left.
  168. case GLUT_KEY_LEFT:
  169. viewCenter.x -= 0.5f;
  170. Resize(width, height);
  171. break;
  172. // Press right to pan right.
  173. case GLUT_KEY_RIGHT:
  174. viewCenter.x += 0.5f;
  175. Resize(width, height);
  176. break;
  177. // Press down to pan down.
  178. case GLUT_KEY_DOWN:
  179. viewCenter.y -= 0.5f;
  180. Resize(width, height);
  181. break;
  182. // Press up to pan up.
  183. case GLUT_KEY_UP:
  184. viewCenter.y += 0.5f;
  185. Resize(width, height);
  186. break;
  187. // Press home to reset the view.
  188. case GLUT_KEY_HOME:
  189. viewZoom = 1.0f;
  190. viewCenter.Set(0.0f, 20.0f);
  191. Resize(width, height);
  192. break;
  193. }
  194. }
  195. void Mouse(int32 button, int32 state, int32 x, int32 y)
  196. {
  197. // Use the mouse to move things around.
  198. if (button == GLUT_LEFT_BUTTON)
  199. {
  200. int mod = glutGetModifiers();
  201. b2Vec2 p = ConvertScreenToWorld(x, y);
  202. if (state == GLUT_DOWN)
  203. {
  204. b2Vec2 p = ConvertScreenToWorld(x, y);
  205. if (mod == GLUT_ACTIVE_SHIFT)
  206. {
  207. test->ShiftMouseDown(p);
  208. }
  209. else
  210. {
  211. test->MouseDown(p);
  212. }
  213. }
  214. if (state == GLUT_UP)
  215. {
  216. test->MouseUp(p);
  217. }
  218. }
  219. else if (button == GLUT_RIGHT_BUTTON)
  220. {
  221. if (state == GLUT_DOWN)
  222. {
  223. lastp = ConvertScreenToWorld(x, y);
  224. rMouseDown = true;
  225. }
  226. if (state == GLUT_UP)
  227. {
  228. rMouseDown = false;
  229. }
  230. }
  231. }
  232. void MouseMotion(int32 x, int32 y)
  233. {
  234. b2Vec2 p = ConvertScreenToWorld(x, y);
  235. test->MouseMove(p);
  236. if (rMouseDown)
  237. {
  238. b2Vec2 diff = p - lastp;
  239. viewCenter.x -= diff.x;
  240. viewCenter.y -= diff.y;
  241. Resize(width, height);
  242. lastp = ConvertScreenToWorld(x, y);
  243. }
  244. }
  245. void MouseWheel(int wheel, int direction, int x, int y)
  246. {
  247. B2_NOT_USED(wheel);
  248. B2_NOT_USED(x);
  249. B2_NOT_USED(y);
  250. if (direction > 0)
  251. {
  252. viewZoom /= 1.1f;
  253. }
  254. else
  255. {
  256. viewZoom *= 1.1f;
  257. }
  258. Resize(width, height);
  259. }
  260. void Restart(int)
  261. {
  262. delete test;
  263. entry = g_testEntries + testIndex;
  264. test = entry->createFcn();
  265.     Resize(width, height);
  266. }
  267. void Pause(int)
  268. {
  269. settings.pause = !settings.pause;
  270. }
  271. void SingleStep(int)
  272. {
  273. settings.pause = 1;
  274. settings.singleStep = 1;
  275. }
  276. int main(int argc, char** argv)
  277. {
  278. testCount = 0;
  279. while (g_testEntries[testCount].createFcn != NULL)
  280. {
  281. ++testCount;
  282. }
  283. testIndex = b2Clamp(testIndex, 0, testCount-1);
  284. testSelection = testIndex;
  285. entry = g_testEntries + testIndex;
  286. test = entry->createFcn();
  287. glutInit(&argc, argv);
  288. glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE);
  289. glutInitWindowSize(width, height);
  290. char title[32];
  291. sprintf(title, "Box2D Version %d.%d.%d", b2_version.major, b2_version.minor, b2_version.revision);
  292. mainWindow = glutCreateWindow(title);
  293. //glutSetOption (GLUT_ACTION_ON_WINDOW_CLOSE, GLUT_ACTION_GLUTMAINLOOP_RETURNS);
  294. glutDisplayFunc(SimulationLoop);
  295. GLUI_Master.set_glutReshapeFunc(Resize);  
  296. GLUI_Master.set_glutKeyboardFunc(Keyboard);
  297. GLUI_Master.set_glutSpecialFunc(KeyboardSpecial);
  298. GLUI_Master.set_glutMouseFunc(Mouse);
  299. #ifdef FREEGLUT
  300. glutMouseWheelFunc(MouseWheel);
  301. #endif
  302. glutMotionFunc(MouseMotion);
  303. glui = GLUI_Master.create_glui_subwindow( mainWindow, 
  304. GLUI_SUBWINDOW_RIGHT );
  305. glui->add_statictext("Tests");
  306. GLUI_Listbox* testList =
  307. glui->add_listbox("", &testSelection);
  308. glui->add_separator();
  309. GLUI_Spinner* velocityIterationSpinner =
  310. glui->add_spinner("Vel Iters", GLUI_SPINNER_INT, &settings.velocityIterations);
  311. velocityIterationSpinner->set_int_limits(1, 500);
  312. GLUI_Spinner* positionIterationSpinner =
  313. glui->add_spinner("Pos Iters", GLUI_SPINNER_INT, &settings.positionIterations);
  314. positionIterationSpinner->set_int_limits(0, 100);
  315. GLUI_Spinner* hertzSpinner =
  316. glui->add_spinner("Hertz", GLUI_SPINNER_FLOAT, &settingsHz);
  317. hertzSpinner->set_float_limits(5.0f, 200.0f);
  318. glui->add_checkbox("Warm Starting", &settings.enableWarmStarting);
  319. glui->add_checkbox("Time of Impact", &settings.enableContinuous);
  320. //glui->add_separator();
  321. GLUI_Panel* drawPanel = glui->add_panel("Draw");
  322. glui->add_checkbox_to_panel(drawPanel, "Shapes", &settings.drawShapes);
  323. glui->add_checkbox_to_panel(drawPanel, "Joints", &settings.drawJoints);
  324. glui->add_checkbox_to_panel(drawPanel, "AABBs", &settings.drawAABBs);
  325. glui->add_checkbox_to_panel(drawPanel, "Pairs", &settings.drawPairs);
  326. glui->add_checkbox_to_panel(drawPanel, "Contact Points", &settings.drawContactPoints);
  327. glui->add_checkbox_to_panel(drawPanel, "Contact Normals", &settings.drawContactNormals);
  328. glui->add_checkbox_to_panel(drawPanel, "Contact Forces", &settings.drawContactForces);
  329. glui->add_checkbox_to_panel(drawPanel, "Friction Forces", &settings.drawFrictionForces);
  330. glui->add_checkbox_to_panel(drawPanel, "Center of Masses", &settings.drawCOMs);
  331. glui->add_checkbox_to_panel(drawPanel, "Statistics", &settings.drawStats);
  332. int32 testCount = 0;
  333. TestEntry* e = g_testEntries;
  334. while (e->createFcn)
  335. {
  336. testList->add_item(testCount, e->name);
  337. ++testCount;
  338. ++e;
  339. }
  340. glui->add_button("Pause", 0, Pause);
  341. glui->add_button("Single Step", 0, SingleStep);
  342. glui->add_button("Restart", 0, Restart);
  343. glui->add_button("Quit", 0,(GLUI_Update_CB)exit);
  344. glui->set_main_gfx_window( mainWindow );
  345. // Use a timer to control the frame rate.
  346. glutTimerFunc(framePeriod, Timer, 0);
  347. glutMainLoop();
  348. return 0;
  349. }