example.cpp 13 KB

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