PageRenderTime 72ms CodeModel.GetById 23ms RepoModel.GetById 0ms app.codeStats 0ms

/external/AntTweakBar-1.16/examples/TwDualGLUT.c

https://gitlab.com/dannywillems/mass_collide
C | 465 lines | 296 code | 84 blank | 85 comment | 18 complexity | 4499942a45859ec59d340d8c01915f63 MD5 | raw file
  1. // ---------------------------------------------------------------------------
  2. //
  3. // @file TwDualGLUT.c
  4. // @brief This example illustrates the use of AntTweakBar with multiple
  5. // windows. Here we are using GLUT to create a main window having
  6. // two sub-windows, each sub-window has a tweak bar.
  7. // This example extends the TwSimpleGLUT example.
  8. //
  9. // AntTweakBar: http://anttweakbar.sourceforge.net/doc
  10. // OpenGL: http://www.opengl.org
  11. // GLUT: http://opengl.org/resources/libraries/glut
  12. //
  13. // ---------------------------------------------------------------------------
  14. #include <AntTweakBar.h>
  15. #include <stdlib.h>
  16. #include <stdio.h>
  17. #include <math.h>
  18. #if defined(_WIN32) || defined(_WIN64)
  19. // MiniGLUT.h is provided to avoid the need of having GLUT installed to
  20. // recompile this example. Do not use it in your own programs, better
  21. // install and use the actual GLUT library SDK.
  22. # define USE_MINI_GLUT
  23. #endif
  24. #if defined(USE_MINI_GLUT)
  25. # include "../src/MiniGLUT.h"
  26. #elif defined(_MACOSX)
  27. # include <GLUT/glut.h>
  28. #else
  29. # include <GL/glut.h>
  30. #endif
  31. // This example displays one of the following shapes in each sub-window
  32. typedef enum { SHAPE_TEAPOT=1, SHAPE_TORUS, SHAPE_CONE } Shape;
  33. #define NUM_SHAPES 3
  34. typedef struct
  35. {
  36. int WinID;
  37. TwBar *Bar;
  38. Shape ObjectShape;
  39. float Zoom;
  40. float Rotation[4];
  41. int AutoRotate;
  42. int RotateTime;
  43. float RotateStart[4];
  44. float MatAmbient[4];
  45. float MatDiffuse[4];
  46. float LightMultiplier;
  47. float LightDirection[3];
  48. } SubWindowData;
  49. SubWindowData g_SubWindowData[2];
  50. // Routine to set a quaternion from a rotation axis and angle
  51. // ( input axis = float[3] angle = float output: quat = float[4] )
  52. void SetQuaternionFromAxisAngle(const float *axis, float angle, float *quat)
  53. {
  54. float sina2, norm;
  55. sina2 = (float)sin(0.5f * angle);
  56. norm = (float)sqrt(axis[0]*axis[0] + axis[1]*axis[1] + axis[2]*axis[2]);
  57. quat[0] = sina2 * axis[0] / norm;
  58. quat[1] = sina2 * axis[1] / norm;
  59. quat[2] = sina2 * axis[2] / norm;
  60. quat[3] = (float)cos(0.5f * angle);
  61. }
  62. // Routine to convert a quaternion to a 4x4 matrix
  63. // ( input: quat = float[4] output: mat = float[4*4] )
  64. void ConvertQuaternionToMatrix(const float *quat, float *mat)
  65. {
  66. float yy2 = 2.0f * quat[1] * quat[1];
  67. float xy2 = 2.0f * quat[0] * quat[1];
  68. float xz2 = 2.0f * quat[0] * quat[2];
  69. float yz2 = 2.0f * quat[1] * quat[2];
  70. float zz2 = 2.0f * quat[2] * quat[2];
  71. float wz2 = 2.0f * quat[3] * quat[2];
  72. float wy2 = 2.0f * quat[3] * quat[1];
  73. float wx2 = 2.0f * quat[3] * quat[0];
  74. float xx2 = 2.0f * quat[0] * quat[0];
  75. mat[0*4+0] = - yy2 - zz2 + 1.0f;
  76. mat[0*4+1] = xy2 + wz2;
  77. mat[0*4+2] = xz2 - wy2;
  78. mat[0*4+3] = 0;
  79. mat[1*4+0] = xy2 - wz2;
  80. mat[1*4+1] = - xx2 - zz2 + 1.0f;
  81. mat[1*4+2] = yz2 + wx2;
  82. mat[1*4+3] = 0;
  83. mat[2*4+0] = xz2 + wy2;
  84. mat[2*4+1] = yz2 - wx2;
  85. mat[2*4+2] = - xx2 - yy2 + 1.0f;
  86. mat[2*4+3] = 0;
  87. mat[3*4+0] = mat[3*4+1] = mat[3*4+2] = 0;
  88. mat[3*4+3] = 1;
  89. }
  90. // Routine to multiply 2 quaternions (ie, compose rotations)
  91. // ( input q1 = float[4] q2 = float[4] output: qout = float[4] )
  92. void MultiplyQuaternions(const float *q1, const float *q2, float *qout)
  93. {
  94. float qr[4];
  95. qr[0] = q1[3]*q2[0] + q1[0]*q2[3] + q1[1]*q2[2] - q1[2]*q2[1];
  96. qr[1] = q1[3]*q2[1] + q1[1]*q2[3] + q1[2]*q2[0] - q1[0]*q2[2];
  97. qr[2] = q1[3]*q2[2] + q1[2]*q2[3] + q1[0]*q2[1] - q1[1]*q2[0];
  98. qr[3] = q1[3]*q2[3] - (q1[0]*q2[0] + q1[1]*q2[1] + q1[2]*q2[2]);
  99. qout[0] = qr[0]; qout[1] = qr[1]; qout[2] = qr[2]; qout[3] = qr[3];
  100. }
  101. // Return elapsed time in milliseconds
  102. int GetTimeMs()
  103. {
  104. #if !defined(_WIN32)
  105. return glutGet(GLUT_ELAPSED_TIME);
  106. #else
  107. // glutGet(GLUT_ELAPSED_TIME) seems buggy on Windows
  108. return (int)GetTickCount();
  109. #endif
  110. }
  111. // Find the current WindowData
  112. SubWindowData *GetCurrentSubWindowData()
  113. {
  114. int i, currWinID;
  115. currWinID = glutGetWindow();
  116. for (i = 0; i < 2; i++)
  117. if (g_SubWindowData[i].WinID == currWinID)
  118. return &g_SubWindowData[i];
  119. return NULL;
  120. }
  121. // Callback function called by GLUT to render the main window content
  122. void DisplayMainWindow(void)
  123. {
  124. // Clear frame buffer
  125. glClearColor(1, 0.8f, 0.4f, 1);
  126. glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
  127. // Present frame buffer
  128. glutSwapBuffers();
  129. }
  130. // Callback function called by GLUT when the main window size has changed
  131. void ReshapeMainWindow(int width, int height)
  132. {
  133. if (width > 32 && height > 32)
  134. {
  135. glutSetWindow(g_SubWindowData[0].WinID);
  136. glutPositionWindow(8, 8);
  137. glutReshapeWindow(width/2-16, height-16);
  138. glutSetWindow(g_SubWindowData[1].WinID);
  139. glutPositionWindow(width/2+8, 8);
  140. glutReshapeWindow(width/2-16, height-16);
  141. }
  142. }
  143. // Callback function called by GLUT to render sub-window content
  144. void DisplaySubWindow(void)
  145. {
  146. float v[4]; // will be used to set light parameters
  147. float mat[4*4]; // rotation matrix
  148. SubWindowData *win;
  149. win = GetCurrentSubWindowData();
  150. if (win == NULL) return;
  151. // Tell AntTweakBar which is the current window
  152. TwSetCurrentWindow(win->WinID);
  153. // Clear frame buffer
  154. glClearColor(0, 0, 0, 1);
  155. glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
  156. glEnable(GL_DEPTH_TEST);
  157. glDisable(GL_CULL_FACE);
  158. glEnable(GL_NORMALIZE);
  159. // Set light
  160. glEnable(GL_LIGHTING);
  161. glEnable(GL_LIGHT0);
  162. v[0] = v[1] = v[2] = win->LightMultiplier*0.4f; v[3] = 1.0f;
  163. glLightfv(GL_LIGHT0, GL_AMBIENT, v);
  164. v[0] = v[1] = v[2] = win->LightMultiplier*0.8f; v[3] = 1.0f;
  165. glLightfv(GL_LIGHT0, GL_DIFFUSE, v);
  166. v[0] = -win->LightDirection[0]; v[1] = -win->LightDirection[1]; v[2] = -win->LightDirection[2]; v[3] = 0.0f;
  167. glLightfv(GL_LIGHT0, GL_POSITION, v);
  168. // Set material
  169. glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, win->MatAmbient);
  170. glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, win->MatDiffuse);
  171. // Rotate and draw shape
  172. glPushMatrix();
  173. glTranslatef(0.5f, -0.3f, 0.0f);
  174. if( win->AutoRotate )
  175. {
  176. float axis[3] = { 0, 1, 0 };
  177. float angle = (float)(GetTimeMs()-win->RotateTime)/1000.0f;
  178. float quat[4];
  179. SetQuaternionFromAxisAngle(axis, angle, quat);
  180. MultiplyQuaternions(win->RotateStart, quat, win->Rotation);
  181. }
  182. ConvertQuaternionToMatrix(win->Rotation, mat);
  183. glMultMatrixf(mat);
  184. glScalef(win->Zoom, win->Zoom, win->Zoom);
  185. glCallList(win->ObjectShape);
  186. glPopMatrix();
  187. // Draw tweak bars
  188. TwDraw();
  189. // Present frame buffer
  190. glutSwapBuffers();
  191. // Recall Display at next frame
  192. glutPostRedisplay();
  193. }
  194. // Callback function called by GLUT when sub-window size has changed
  195. void ReshapeSubWindow(int width, int height)
  196. {
  197. SubWindowData *win;
  198. win = GetCurrentSubWindowData();
  199. if (win == NULL) return;
  200. // Set OpenGL viewport and camera
  201. glViewport(0, 0, width, height);
  202. glMatrixMode(GL_PROJECTION);
  203. glLoadIdentity();
  204. gluPerspective(40, (double)width/height, 1, 10);
  205. glMatrixMode(GL_MODELVIEW);
  206. glLoadIdentity();
  207. gluLookAt(0,0,5, 0,0,0, 0,1,0);
  208. glTranslatef(0, 0.6f, -1);
  209. // Send the new window size to AntTweakBar
  210. TwSetCurrentWindow(win->WinID);
  211. TwWindowSize(width, height);
  212. }
  213. // Function called at exit
  214. void Terminate(void)
  215. {
  216. int i;
  217. for (i=0; i<2; i++) {
  218. glutSetWindow(g_SubWindowData[i].WinID);
  219. glDeleteLists(SHAPE_TEAPOT, NUM_SHAPES);
  220. }
  221. TwTerminate();
  222. }
  223. // Callback function called when the 'AutoRotate' variable value of the tweak bar has changed
  224. void TW_CALL SetAutoRotateCB(const void *value, void *clientData)
  225. {
  226. SubWindowData *win;
  227. win = (SubWindowData *)clientData;
  228. win->AutoRotate = *(const int *)value; // copy value to win->AutoRotate
  229. if (win->AutoRotate != 0)
  230. {
  231. // init rotation
  232. win->RotateTime = GetTimeMs();
  233. win->RotateStart[0] = win->Rotation[0];
  234. win->RotateStart[1] = win->Rotation[1];
  235. win->RotateStart[2] = win->Rotation[2];
  236. win->RotateStart[3] = win->Rotation[3];
  237. }
  238. // make Rotation variable read-only or read-write
  239. TwSetCurrentWindow(win->WinID);
  240. TwSetParam(win->Bar, "ObjRotation", "readonly", TW_PARAM_INT32, 1, &win->AutoRotate);
  241. }
  242. // Callback function called by the tweak bar to get the 'AutoRotate' value
  243. void TW_CALL GetAutoRotateCB(void *value, void *clientData)
  244. {
  245. SubWindowData *win;
  246. win = (SubWindowData *)clientData;
  247. *(int *)value = win->AutoRotate; // copy win->AutoRotate to value
  248. }
  249. // Mouse Button event callbacks
  250. int MouseButtonCB(int glutButton, int glutState, int mouseX, int mouseY)
  251. {
  252. TwSetCurrentWindow(glutGetWindow());
  253. return TwEventMouseButtonGLUT(glutButton,glutState,mouseX,mouseY);
  254. }
  255. // Mouse Motion event callbacks
  256. int MouseMotionCB(int mouseX, int mouseY)
  257. {
  258. TwSetCurrentWindow(glutGetWindow());
  259. return TwEventMouseMotionGLUT(mouseX,mouseY);
  260. }
  261. // Keyboard event callbacks
  262. int KeyboardCB(unsigned char glutKey, int mouseX, int mouseY)
  263. {
  264. TwSetCurrentWindow(glutGetWindow());
  265. return TwEventKeyboardGLUT(glutKey,mouseX,mouseY);
  266. }
  267. // Special key event callbacks
  268. int SpecialKeyCB(int glutKey, int mouseX, int mouseY)
  269. {
  270. TwSetCurrentWindow(glutGetWindow());
  271. return TwEventSpecialGLUT(glutKey,mouseX,mouseY);
  272. }
  273. // Setup new sub-window
  274. void SetupSubWindow(int subWinIdx)
  275. {
  276. float axis[] = { 0.7f, 0.7f, 0.0f }; // initial model rotation
  277. float angle = 0.8f;
  278. SubWindowData *win;
  279. win = &g_SubWindowData[subWinIdx];
  280. win->ObjectShape = (subWinIdx == 0) ? SHAPE_TEAPOT : SHAPE_TORUS;
  281. win->Zoom = 1;
  282. win->AutoRotate = (subWinIdx == 0);
  283. win->MatAmbient[0] = (subWinIdx == 1) ? 0.0f : 0.5f;; win->MatAmbient[1] = win->MatAmbient[2] = 0.2f; win->MatAmbient[3] = 1;
  284. win->MatDiffuse[0] = (subWinIdx == 1) ? 0.0f : 1.0f; win->MatDiffuse[1] = 1; win->MatDiffuse[2] = 0; win->MatDiffuse[3] = 1;
  285. win->LightMultiplier = 1;
  286. win->LightDirection[0] = win->LightDirection[1] = win->LightDirection[2] = -0.57735f;
  287. win->RotateTime = GetTimeMs();
  288. SetQuaternionFromAxisAngle(axis, angle, win->Rotation);
  289. SetQuaternionFromAxisAngle(axis, angle, win->RotateStart);
  290. glutSetWindow(win->WinID);
  291. // Set GLUT callbacks
  292. glutDisplayFunc(DisplaySubWindow);
  293. glutReshapeFunc(ReshapeSubWindow);
  294. // Set GLUT event callbacks
  295. // - Register mouse button events callback
  296. glutMouseFunc((GLUTmousebuttonfun)MouseButtonCB);
  297. // - Register mouse motion events callback
  298. glutMotionFunc((GLUTmousemotionfun)MouseMotionCB);
  299. // - Register mouse "passive" motion events (same as Motion)
  300. glutPassiveMotionFunc((GLUTmousemotionfun)MouseMotionCB);
  301. // - Register keyboard events callback
  302. glutKeyboardFunc((GLUTkeyboardfun)KeyboardCB);
  303. // - Register special key events callback
  304. glutSpecialFunc((GLUTspecialfun)SpecialKeyCB);
  305. // - Send 'glutGetModifers' function pointer to AntTweakBar;
  306. // required because the GLUT key event functions do not report key modifiers states.
  307. TwGLUTModifiersFunc(glutGetModifiers);
  308. // Create some 3D objects (stored in display lists)
  309. glNewList(SHAPE_TEAPOT, GL_COMPILE);
  310. glutSolidTeapot(1.0);
  311. glEndList();
  312. glNewList(SHAPE_TORUS, GL_COMPILE);
  313. glutSolidTorus(0.3, 1.0, 16, 32);
  314. glEndList();
  315. glNewList(SHAPE_CONE, GL_COMPILE);
  316. glutSolidCone(1.0, 1.5, 64, 4);
  317. glEndList();
  318. // Declare this window as current for AntTweakBar.
  319. // Here, this will create a new AntTweakBar context for this window,
  320. // which will be identified by the number WinID.
  321. TwSetCurrentWindow(win->WinID);
  322. // Create a tweak bar
  323. win->Bar = TwNewBar("TweakBar");
  324. TwDefine(" GLOBAL help='This example shows how to use AntTweakBar with multiple windows.' "); // Message added to the help bar.
  325. TwDefine(" TweakBar size='200 400' color='96 216 224' "); // change default tweak bar size and color
  326. // Add 'win->Zoom' to 'bar': this is a modifable (RW) variable of type TW_TYPE_FLOAT. Its key shortcuts are [z] and [Z].
  327. TwAddVarRW(win->Bar, "Zoom", TW_TYPE_FLOAT, &win->Zoom,
  328. " min=0.01 max=2.5 step=0.01 keyIncr=z keyDecr=Z help='Scale the object (1=original size).' ");
  329. // Add 'win->Rotation' to 'bar': this is a variable of type TW_TYPE_QUAT4F which defines the object's orientation
  330. TwAddVarRW(win->Bar, "ObjRotation", TW_TYPE_QUAT4F, &win->Rotation,
  331. " label='Object rotation' open help='Change the object orientation.' ");
  332. // Add callback to toggle auto-rotate mode (callback functions are defined above).
  333. TwAddVarCB(win->Bar, "AutoRotate", TW_TYPE_BOOL32, SetAutoRotateCB, GetAutoRotateCB, win,
  334. " label='Auto-rotate' key=space help='Toggle auto-rotate mode.' ");
  335. // Add 'win->LightMultiplier' to 'bar': this is a variable of type TW_TYPE_FLOAT. Its key shortcuts are [+] and [-].
  336. TwAddVarRW(win->Bar, "Multiplier", TW_TYPE_FLOAT, &win->LightMultiplier,
  337. " label='Light booster' min=0.1 max=4 step=0.02 keyIncr='+' keyDecr='-' help='Increase/decrease the light power.' ");
  338. // Add 'win->LightDirection' to 'bar': this is a variable of type TW_TYPE_DIR3F which defines the light direction
  339. TwAddVarRW(win->Bar, "LightDir", TW_TYPE_DIR3F, &win->LightDirection,
  340. " label='Light direction' open help='Change the light direction.' ");
  341. // Add 'win->MatAmbient' to 'bar': this is a variable of type TW_TYPE_COLOR3F (3 floats color, alpha is ignored)
  342. // and is inserted into a group named 'Material'.
  343. TwAddVarRW(win->Bar, "Ambient", TW_TYPE_COLOR3F, &win->MatAmbient, " group='Material' ");
  344. // Add 'win->MatDiffuse' to 'bar': this is a variable of type TW_TYPE_COLOR3F (3 floats color, alpha is ignored)
  345. // and is inserted into group 'Material'.
  346. TwAddVarRW(win->Bar, "Diffuse", TW_TYPE_COLOR3F, &win->MatDiffuse, " group='Material' ");
  347. // Add the enum variable 'win->ObjectShape' to 'bar'
  348. // (before adding an enum variable, its enum type must be declared to AntTweakBar as follow)
  349. {
  350. // ShapeEV associates Shape enum values with labels that will be displayed instead of enum values
  351. TwEnumVal shapeEV[NUM_SHAPES] = { {SHAPE_TEAPOT, "Teapot"}, {SHAPE_TORUS, "Torus"}, {SHAPE_CONE, "Cone"} };
  352. // Create a type for the enum shapeEV
  353. TwType shapeType = TwDefineEnum("ShapeType", shapeEV, NUM_SHAPES);
  354. // add 'win->CurrentShape' to 'bar': this is a variable of type ShapeType. Its key shortcuts are [<] and [>].
  355. TwAddVarRW(win->Bar, "Shape", shapeType, &win->ObjectShape, " keyIncr='<' keyDecr='>' help='Change object shape.' ");
  356. }
  357. }
  358. // Main
  359. int main(int argc, char *argv[])
  360. {
  361. int mainWinID;
  362. // Initialize GLUT
  363. glutInit(&argc, argv);
  364. glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
  365. glutInitWindowSize(960, 480);
  366. mainWinID = glutCreateWindow("AntTweakBar multi-window example");
  367. glutCreateMenu(NULL);
  368. glutDisplayFunc(DisplayMainWindow);
  369. glutReshapeFunc(ReshapeMainWindow);
  370. // Initialize AntTweakBar
  371. TwInit(TW_OPENGL, NULL);
  372. // Create two sub-windows
  373. g_SubWindowData[0].WinID = glutCreateSubWindow(mainWinID, 8, 8, 480, 464);
  374. SetupSubWindow(0);
  375. g_SubWindowData[1].WinID = glutCreateSubWindow(mainWinID, 488, 8, 464, 464);
  376. SetupSubWindow(1);
  377. atexit(Terminate); // Called after glutMainLoop ends
  378. // Call the GLUT main loop
  379. glutMainLoop();
  380. return 0;
  381. }