example.cpp 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382
  1. /*
  2. This is an example program that came with AntTweakBar modified to use ReAntTweakBar
  3. On mac os x compile with:
  4. g++ -c example.cpp -o example.o
  5. g++ -o example example.o -framework OpenGL -framework GLUT -lAntTweakBar
  6. rm *.o
  7. */
  8. #ifdef __APPLE__
  9. #define _MACOSX
  10. #endif
  11. // ORIGINAL COPYRIGHT INFO
  12. // ---------------------------------------------------------------------------
  13. //
  14. // @file TwSimpleGLUT.c
  15. // @brief A simple example that uses AntTweakBar with OpenGL and GLUT.
  16. //
  17. // AntTweakBar: http://www.antisphere.com/Wiki/tools:anttweakbar
  18. // OpenGL: http://www.opengl.org
  19. // GLUT: http://opengl.org/resources/libraries/glut
  20. //
  21. // @author Philippe Decaudin - http://www.antisphere.com
  22. // @date 2006/05/20
  23. //
  24. // Compilation:
  25. // http://www.antisphere.com/Wiki/tools:anttweakbar:examples#twsimpleglut
  26. //
  27. // ---------------------------------------------------------------------------
  28. #include <igl/ReAntTweakBar.h>
  29. using namespace igl;
  30. #include <stdlib.h>
  31. #include <stdio.h>
  32. #include <math.h>
  33. #if defined(_WIN32) || defined(_WIN64)
  34. // MiniGLUT.h is provided to avoid the need of having GLUT installed to
  35. // recompile this example. Do not use it in your own programs, better
  36. // install and use the actual GLUT library SDK.
  37. # define USE_MINI_GLUT
  38. #endif
  39. #if defined(USE_MINI_GLUT)
  40. # include "../src/MiniGLUT.h"
  41. #elif defined(_MACOSX)
  42. # include <GLUT/glut.h>
  43. #else
  44. # include <GL/glut.h>
  45. #endif
  46. #define REBAR_NAME "temp.rbr"
  47. // This example displays one of the following shapes
  48. typedef enum { SHAPE_TEAPOT=1, SHAPE_TORUS, SHAPE_CONE, SHAPE_SPHERE } Shape;
  49. #define NUM_SHAPES 4
  50. Shape g_CurrentShape = SHAPE_TORUS;
  51. // Shapes scale
  52. float g_Zoom = 1.0f;
  53. // Shape orientation (stored as a quaternion)
  54. float g_Rotation[] = { 0.0f, 0.0f, 0.0f, 1.0f };
  55. // Auto rotate
  56. int g_AutoRotate = 0;
  57. int g_RotateTime = 0;
  58. float g_RotateStart[] = { 0.0f, 0.0f, 0.0f, 1.0f };
  59. // Shapes material
  60. float g_MatAmbient[] = { 0.5f, 0.0f, 0.0f, 1.0f };
  61. float g_MatDiffuse[] = { 1.0f, 1.0f, 0.0f, 1.0f };
  62. // Light parameter
  63. double g_LightMultiplier = 1.0f;
  64. float g_LightDirection[] = { -0.57735f, -0.57735f, -0.57735f };
  65. ReTwBar rebar; // Pointer to the tweak bar
  66. // Routine to set a quaternion from a rotation axis and angle
  67. // ( input axis = float[3] angle = float output: quat = float[4] )
  68. void SetQuaternionFromAxisAngle(const float *axis, float angle, float *quat)
  69. {
  70. float sina2, norm;
  71. sina2 = (float)sin(0.5f * angle);
  72. norm = (float)sqrt(axis[0]*axis[0] + axis[1]*axis[1] + axis[2]*axis[2]);
  73. quat[0] = sina2 * axis[0] / norm;
  74. quat[1] = sina2 * axis[1] / norm;
  75. quat[2] = sina2 * axis[2] / norm;
  76. quat[3] = (float)cos(0.5f * angle);
  77. }
  78. // Routine to convert a quaternion to a 4x4 matrix
  79. // ( input: quat = float[4] output: mat = float[4*4] )
  80. void ConvertQuaternionToMatrix(const float *quat, float *mat)
  81. {
  82. float yy2 = 2.0f * quat[1] * quat[1];
  83. float xy2 = 2.0f * quat[0] * quat[1];
  84. float xz2 = 2.0f * quat[0] * quat[2];
  85. float yz2 = 2.0f * quat[1] * quat[2];
  86. float zz2 = 2.0f * quat[2] * quat[2];
  87. float wz2 = 2.0f * quat[3] * quat[2];
  88. float wy2 = 2.0f * quat[3] * quat[1];
  89. float wx2 = 2.0f * quat[3] * quat[0];
  90. float xx2 = 2.0f * quat[0] * quat[0];
  91. mat[0*4+0] = - yy2 - zz2 + 1.0f;
  92. mat[0*4+1] = xy2 + wz2;
  93. mat[0*4+2] = xz2 - wy2;
  94. mat[0*4+3] = 0;
  95. mat[1*4+0] = xy2 - wz2;
  96. mat[1*4+1] = - xx2 - zz2 + 1.0f;
  97. mat[1*4+2] = yz2 + wx2;
  98. mat[1*4+3] = 0;
  99. mat[2*4+0] = xz2 + wy2;
  100. mat[2*4+1] = yz2 - wx2;
  101. mat[2*4+2] = - xx2 - yy2 + 1.0f;
  102. mat[2*4+3] = 0;
  103. mat[3*4+0] = mat[3*4+1] = mat[3*4+2] = 0;
  104. mat[3*4+3] = 1;
  105. }
  106. // Routine to multiply 2 quaternions (ie, compose rotations)
  107. // ( input q1 = float[4] q2 = float[4] output: qout = float[4] )
  108. void MultiplyQuaternions(const float *q1, const float *q2, float *qout)
  109. {
  110. float qr[4];
  111. qr[0] = q1[3]*q2[0] + q1[0]*q2[3] + q1[1]*q2[2] - q1[2]*q2[1];
  112. qr[1] = q1[3]*q2[1] + q1[1]*q2[3] + q1[2]*q2[0] - q1[0]*q2[2];
  113. qr[2] = q1[3]*q2[2] + q1[2]*q2[3] + q1[0]*q2[1] - q1[1]*q2[0];
  114. qr[3] = q1[3]*q2[3] - (q1[0]*q2[0] + q1[1]*q2[1] + q1[2]*q2[2]);
  115. qout[0] = qr[0]; qout[1] = qr[1]; qout[2] = qr[2]; qout[3] = qr[3];
  116. }
  117. // Callback function called by GLUT to render screen
  118. void Display(void)
  119. {
  120. float v[4]; // will be used to set light paramters
  121. float mat[4*4]; // rotation matrix
  122. // Clear frame buffer
  123. glClearColor(0, 0, 0, 1);
  124. glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
  125. glEnable(GL_DEPTH_TEST);
  126. glDisable(GL_CULL_FACE);
  127. glEnable(GL_NORMALIZE);
  128. // Set light
  129. glEnable(GL_LIGHTING);
  130. glEnable(GL_LIGHT0);
  131. v[0] = v[1] = v[2] = g_LightMultiplier*0.4f; v[3] = 1.0f;
  132. glLightfv(GL_LIGHT0, GL_AMBIENT, v);
  133. v[0] = v[1] = v[2] = g_LightMultiplier*0.8f; v[3] = 1.0f;
  134. glLightfv(GL_LIGHT0, GL_DIFFUSE, v);
  135. v[0] = -g_LightDirection[0]; v[1] = -g_LightDirection[1]; v[2] = -g_LightDirection[2]; v[3] = 0.0f;
  136. glLightfv(GL_LIGHT0, GL_POSITION, v);
  137. // Set material
  138. glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, g_MatAmbient);
  139. glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, g_MatDiffuse);
  140. // Rotate and draw shape
  141. glPushMatrix();
  142. glTranslatef(0.5f, -0.3f, 0.0f);
  143. if( g_AutoRotate )
  144. {
  145. float axis[3] = { 0, 1, 0 };
  146. float angle = (float)(glutGet(GLUT_ELAPSED_TIME)-g_RotateTime)/1000.0f;
  147. float quat[4];
  148. SetQuaternionFromAxisAngle(axis, angle, quat);
  149. MultiplyQuaternions(g_RotateStart, quat, g_Rotation);
  150. }
  151. ConvertQuaternionToMatrix(g_Rotation, mat);
  152. glMultMatrixf(mat);
  153. glScalef(g_Zoom, g_Zoom, g_Zoom);
  154. glCallList(g_CurrentShape);
  155. glPopMatrix();
  156. // Draw tweak bars
  157. TwDraw();
  158. // Present frame buffer
  159. glutSwapBuffers();
  160. // Recall Display at next frame
  161. glutPostRedisplay();
  162. }
  163. // Callback function called by GLUT when window size changes
  164. void Reshape(int width, int height)
  165. {
  166. // Set OpenGL viewport and camera
  167. glViewport(0, 0, width, height);
  168. glMatrixMode(GL_PROJECTION);
  169. glLoadIdentity();
  170. gluPerspective(40, (double)width/height, 1, 10);
  171. glMatrixMode(GL_MODELVIEW);
  172. glLoadIdentity();
  173. gluLookAt(0,0,5, 0,0,0, 0,1,0);
  174. glTranslatef(0, 0.6f, -1);
  175. // Send the new window size to AntTweakBar
  176. TwWindowSize(width, height);
  177. }
  178. // Function called at exit
  179. void Terminate(void)
  180. {
  181. rebar.save(REBAR_NAME);
  182. glDeleteLists(SHAPE_TEAPOT, NUM_SHAPES);
  183. TwTerminate();
  184. }
  185. // Callback function called when the 'AutoRotate' variable value of the tweak bar has changed
  186. void TW_CALL SetAutoRotateCB(const void *value, void *clientData)
  187. {
  188. (void)clientData; // unused
  189. g_AutoRotate = *(const int *)(value); // copy value to g_AutoRotate
  190. if( g_AutoRotate!=0 )
  191. {
  192. // init rotation
  193. g_RotateTime = glutGet(GLUT_ELAPSED_TIME);
  194. g_RotateStart[0] = g_Rotation[0];
  195. g_RotateStart[1] = g_Rotation[1];
  196. g_RotateStart[2] = g_Rotation[2];
  197. g_RotateStart[3] = g_Rotation[3];
  198. // make Rotation variable read-only
  199. TwDefine(" TweakBar/ObjRotation readonly ");
  200. }
  201. else
  202. // make Rotation variable read-write
  203. TwDefine(" TweakBar/ObjRotation readwrite ");
  204. }
  205. // Callback function called by the tweak bar to get the 'AutoRotate' value
  206. void TW_CALL GetAutoRotateCB(void *value, void *clientData)
  207. {
  208. (void)clientData; // unused
  209. *(int *)(value) = g_AutoRotate; // copy g_AutoRotate to value
  210. }
  211. // Main
  212. int main(int argc, char *argv[])
  213. {
  214. float axis[] = { 0.7f, 0.7f, 0.0f }; // initial model rotation
  215. float angle = 0.8f;
  216. // Initialize AntTweakBar
  217. // (note that AntTweakBar could also be intialized after GLUT, no matter)
  218. if( !TwInit(TW_OPENGL, NULL) )
  219. {
  220. // A fatal error occured
  221. fprintf(stderr, "AntTweakBar initialization failed: %s\n", TwGetLastError());
  222. return 1;
  223. }
  224. // Initialize GLUT
  225. glutInit(&argc, argv);
  226. glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
  227. glutInitWindowSize(640, 480);
  228. glutCreateWindow("AntTweakBar simple example using GLUT");
  229. glutCreateMenu(NULL);
  230. // Set GLUT callbacks
  231. glutDisplayFunc(Display);
  232. glutReshapeFunc(Reshape);
  233. atexit(Terminate); // Called after glutMainLoop ends
  234. // Set GLUT event callbacks
  235. // - Directly redirect GLUT mouse button events to AntTweakBar
  236. glutMouseFunc((GLUTmousebuttonfun)TwEventMouseButtonGLUT);
  237. // - Directly redirect GLUT mouse motion events to AntTweakBar
  238. glutMotionFunc((GLUTmousemotionfun)TwEventMouseMotionGLUT);
  239. // - Directly redirect GLUT mouse "passive" motion events to AntTweakBar (same as MouseMotion)
  240. glutPassiveMotionFunc((GLUTmousemotionfun)TwEventMouseMotionGLUT);
  241. // - Directly redirect GLUT key events to AntTweakBar
  242. glutKeyboardFunc((GLUTkeyboardfun)TwEventKeyboardGLUT);
  243. // - Directly redirect GLUT special key events to AntTweakBar
  244. glutSpecialFunc((GLUTspecialfun)TwEventSpecialGLUT);
  245. // - Send 'glutGetModifers' function pointer to AntTweakBar;
  246. // required because the GLUT key event functions do not report key modifiers states.
  247. TwGLUTModifiersFunc(glutGetModifiers);
  248. // Create some 3D objects (stored in display lists)
  249. glNewList(SHAPE_TEAPOT, GL_COMPILE);
  250. glutSolidTeapot(1.0);
  251. glEndList();
  252. glNewList(SHAPE_TORUS, GL_COMPILE);
  253. glutSolidTorus(0.3, 1.0, 16, 32);
  254. glEndList();
  255. glNewList(SHAPE_CONE, GL_COMPILE);
  256. glutSolidCone(1.0, 1.5, 64, 4);
  257. glEndList();
  258. glNewList(SHAPE_SPHERE, GL_COMPILE);
  259. glutSolidSphere(1.0, 50, 40);
  260. glEndList();
  261. // Create a tweak bar
  262. rebar.TwNewBar("TweakBar");
  263. TwDefine(" GLOBAL help='This example shows how to integrate AntTweakBar with GLUT and OpenGL.' "); // Message added to the help bar.
  264. TwDefine(" TweakBar size='200 400' color='96 216 224' "); // change default tweak bar size and color
  265. // Add 'g_Zoom' to 'bar': this is a modifable (RW) variable of type TW_TYPE_FLOAT. Its key shortcuts are [z] and [Z].
  266. rebar.TwAddVarRW("Zoom", TW_TYPE_FLOAT, &g_Zoom,
  267. " min=0.01 max=2.5 step=0.01 keyIncr=z keyDecr=Z help='Scale the object (1=original size).' ");
  268. // Add 'g_Rotation' to 'bar': this is a variable of type TW_TYPE_QUAT4F which defines the object's orientation
  269. rebar.TwAddVarRW("ObjRotation", TW_TYPE_QUAT4F, &g_Rotation,
  270. " label='Object rotation' open help='Change the object orientation.' ");
  271. // Add callback to toggle auto-rotate mode (callback functions are defined above).
  272. rebar.TwAddVarCB("AutoRotate", TW_TYPE_BOOL32, SetAutoRotateCB, GetAutoRotateCB, NULL,
  273. " label='Auto-rotate' key=space help='Toggle auto-rotate mode.' ");
  274. // Add 'g_LightMultiplier' to 'bar': this is a variable of type TW_TYPE_FLOAT. Its key shortcuts are [+] and [-].
  275. rebar.TwAddVarRW("Multiplier", TW_TYPE_DOUBLE, &g_LightMultiplier,
  276. " label='Light booster' min=0.1 max=4 step=0.02 keyIncr='+' keyDecr='-' help='Increase/decrease the light power.' ");
  277. // Add 'g_LightDirection' to 'bar': this is a variable of type TW_TYPE_DIR3F which defines the light direction
  278. rebar.TwAddVarRW("Light Dir", TW_TYPE_DIR3F, &g_LightDirection,
  279. " label='Light direction' open help='Change the light direction.' ");
  280. // Add 'g_MatAmbient' to 'bar': this is a variable of type TW_TYPE_COLOR3F (3 floats color, alpha is ignored)
  281. // and is inserted into a group named 'Material'.
  282. rebar.TwAddVarRW("Ambient", TW_TYPE_COLOR3F, &g_MatAmbient, " group='Material' ");
  283. // Add 'g_MatDiffuse' to 'bar': this is a variable of type TW_TYPE_COLOR3F (3 floats color, alpha is ignored)
  284. // and is inserted into group 'Material'.
  285. rebar.TwAddVarRW("Diffuse", TW_TYPE_COLOR3F, &g_MatDiffuse, " group='Material' ");
  286. // Add the enum variable 'g_CurrentShape' to 'bar'
  287. // (before adding an enum variable, its enum type must be declared to AntTweakBar as follow)
  288. {
  289. // ShapeEV associates Shape enum values with labels that will be displayed instead of enum values
  290. TwEnumVal shapeEV[NUM_SHAPES] = { {SHAPE_TEAPOT, "Teapot"}, {SHAPE_TORUS, "Torus"}, {SHAPE_CONE, "Cone"} , {SHAPE_SPHERE, "Sphere"}};
  291. // Create a type for the enum shapeEV
  292. TwType shapeType = ReTwDefineEnum("ShapeType", shapeEV, NUM_SHAPES);
  293. // add 'g_CurrentShape' to 'bar': this is a variable of type ShapeType. Its key shortcuts are [<] and [>].
  294. rebar.TwAddVarRW("Shape", shapeType, &g_CurrentShape, " keyIncr='<' keyDecr='>' help='Change object shape.' ");
  295. }
  296. // Store time
  297. g_RotateTime = glutGet(GLUT_ELAPSED_TIME);
  298. // Init rotation
  299. SetQuaternionFromAxisAngle(axis, angle, g_Rotation);
  300. SetQuaternionFromAxisAngle(axis, angle, g_RotateStart);
  301. FILE * fp = fopen(REBAR_NAME,"r");
  302. if(fp != NULL)
  303. {
  304. fclose(fp);
  305. if(rebar.load(REBAR_NAME))
  306. {
  307. printf("ReAntTweakBar reloaded successfully from %s.\n",REBAR_NAME);
  308. }else
  309. {
  310. printf("ReAntTweakBar failed to load from %s.\n",REBAR_NAME);
  311. }
  312. }else
  313. {
  314. printf("%s ReAntTweakBar file does not exist (yet).\n",REBAR_NAME);
  315. }
  316. // Call the GLUT main loop
  317. glutMainLoop();
  318. return 0;
  319. }