example.cpp 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739
  1. #include <igl/Camera.h>
  2. #include <igl/PI.h>
  3. #include <igl/REDRUM.h>
  4. #include <igl/STR.h>
  5. #include <igl/opengl2/draw_floor.h>
  6. #include <igl/opengl2/draw_mesh.h>
  7. #include <igl/get_seconds.h>
  8. #include <igl/opengl2/lens_flare.h>
  9. #include <igl/list_to_matrix.h>
  10. #include <igl/material_colors.h>
  11. #include <igl/pathinfo.h>
  12. #include <igl/per_face_normals.h>
  13. #include <igl/polygon_mesh_to_triangle_mesh.h>
  14. #include <igl/quat_to_mat.h>
  15. #include <igl/readMESH.h>
  16. #include <igl/readOBJ.h>
  17. #include <igl/readOFF.h>
  18. #include <igl/readWRL.h>
  19. #include <igl/opengl/render_to_tga.h>
  20. #include <igl/opengl/report_gl_error.h>
  21. #include <igl/snap_to_canonical_view_quat.h>
  22. #include <igl/snap_to_fixed_up.h>
  23. #include <igl/trackball.h>
  24. #include <igl/two_axis_valuator_fixed_up.h>
  25. #include <igl/writeOBJ.h>
  26. #include <igl/writeOFF.h>
  27. #include <igl/anttweakbar/ReAntTweakBar.h>
  28. #include <Eigen/Core>
  29. #include <Eigen/Geometry>
  30. #ifdef __APPLE__
  31. #include <GLUT/glut.h>
  32. #else
  33. #include <GL/glut.h>
  34. #endif
  35. #ifndef GLUT_WHEEL_UP
  36. #define GLUT_WHEEL_UP 3
  37. #endif
  38. #ifndef GLUT_WHEEL_DOWN
  39. #define GLUT_WHEEL_DOWN 4
  40. #endif
  41. #ifndef GLUT_WHEEL_RIGHT
  42. #define GLUT_WHEEL_RIGHT 5
  43. #endif
  44. #ifndef GLUT_WHEEL_LEFT
  45. #define GLUT_WHEEL_LEFT 6
  46. #endif
  47. #ifndef GLUT_ACTIVE_COMMAND
  48. #define GLUT_ACTIVE_COMMAND 8
  49. #endif
  50. #include <string>
  51. #include <vector>
  52. #include <iomanip>
  53. #include <stack>
  54. #include <iostream>
  55. bool eyes_visible = true;
  56. double x=6,y=232,z=61;
  57. std::vector<igl::opengl2::Flare> flares;
  58. std::vector<GLuint> shine_ids;
  59. std::vector<GLuint> flare_ids;
  60. int shine_tic = 0;
  61. GLuint list_id = 0;
  62. Eigen::MatrixXd V,N;
  63. Eigen::VectorXd Vmid,Vmin,Vmax;
  64. double bbd = 1.0;
  65. Eigen::MatrixXi F;
  66. struct State
  67. {
  68. igl::Camera camera;
  69. } s;
  70. // See README for descriptions
  71. enum RotationType
  72. {
  73. ROTATION_TYPE_IGL_TRACKBALL = 0,
  74. ROTATION_TYPE_TWO_AXIS_VALUATOR_FIXED_UP = 1,
  75. NUM_ROTATION_TYPES = 2,
  76. } rotation_type;
  77. std::stack<State> undo_stack;
  78. std::stack<State> redo_stack;
  79. bool is_rotating = false;
  80. int down_x,down_y;
  81. igl::Camera down_camera;
  82. bool render_to_tga_on_next = false;
  83. int render_count = 0;
  84. int width,height;
  85. Eigen::Vector4f light_pos(-0.1,-0.1,0.9,0);
  86. #define REBAR_NAME "temp.rbr"
  87. igl::anttweakbar::ReTwBar rebar;
  88. bool is_animating = false;
  89. double animation_start_time = 0;
  90. double ANIMATION_DURATION = 0.5;
  91. Eigen::Quaterniond animation_from_quat;
  92. Eigen::Quaterniond animation_to_quat;
  93. void push_undo()
  94. {
  95. undo_stack.push(s);
  96. // Clear
  97. redo_stack = std::stack<State>();
  98. }
  99. void TW_CALL set_rotation_type(const void * value, void * clientData)
  100. {
  101. using namespace Eigen;
  102. using namespace std;
  103. using namespace igl;
  104. const RotationType old_rotation_type = rotation_type;
  105. rotation_type = *(const RotationType *)(value);
  106. if(rotation_type == ROTATION_TYPE_TWO_AXIS_VALUATOR_FIXED_UP &&
  107. old_rotation_type != ROTATION_TYPE_TWO_AXIS_VALUATOR_FIXED_UP)
  108. {
  109. push_undo();
  110. animation_from_quat = s.camera.m_rotation_conj;
  111. snap_to_fixed_up(animation_from_quat,animation_to_quat);
  112. // start animation
  113. animation_start_time = get_seconds();
  114. is_animating = true;
  115. }
  116. }
  117. void TW_CALL get_rotation_type(void * value, void *clientData)
  118. {
  119. RotationType * rt = (RotationType *)(value);
  120. *rt = rotation_type;
  121. }
  122. void reshape(int width, int height)
  123. {
  124. ::width = width;
  125. ::height = height;
  126. glViewport(0,0,width,height);
  127. // Send the new window size to AntTweakBar
  128. TwWindowSize(width, height);
  129. s.camera.m_aspect = (double)width/(double)height;
  130. }
  131. void push_scene()
  132. {
  133. using namespace igl;
  134. using namespace std;
  135. glMatrixMode(GL_PROJECTION);
  136. glPushMatrix();
  137. glLoadIdentity();
  138. auto & camera = s.camera;
  139. glMultMatrixd(camera.projection().data());
  140. glMatrixMode(GL_MODELVIEW);
  141. glPushMatrix();
  142. glLoadIdentity();
  143. gluLookAt(
  144. camera.eye()(0), camera.eye()(1), camera.eye()(2),
  145. camera.at()(0), camera.at()(1), camera.at()(2),
  146. camera.up()(0), camera.up()(1), camera.up()(2));
  147. }
  148. void push_object()
  149. {
  150. using namespace igl;
  151. glPushMatrix();
  152. glScaled(2./bbd,2./bbd,2./bbd);
  153. glTranslated(-Vmid(0),-Vmid(1),-Vmid(2));
  154. }
  155. void pop_object()
  156. {
  157. glPopMatrix();
  158. }
  159. void pop_scene()
  160. {
  161. glMatrixMode(GL_PROJECTION);
  162. glPopMatrix();
  163. glMatrixMode(GL_MODELVIEW);
  164. glPopMatrix();
  165. }
  166. // Set up double-sided lights
  167. void lights()
  168. {
  169. using namespace std;
  170. using namespace Eigen;
  171. glEnable(GL_LIGHTING);
  172. glLightModelf(GL_LIGHT_MODEL_TWO_SIDE,GL_TRUE);
  173. glEnable(GL_LIGHT0);
  174. glEnable(GL_LIGHT1);
  175. float WHITE[4] = {0.8,0.8,0.8,1.};
  176. float GREY[4] = {0.2,0.2,0.2,1.};
  177. float BLACK[4] = {0.,0.,0.,1.};
  178. Vector4f pos = light_pos;
  179. glLightfv(GL_LIGHT0,GL_AMBIENT,GREY);
  180. glLightfv(GL_LIGHT0,GL_DIFFUSE,WHITE);
  181. glLightfv(GL_LIGHT0,GL_SPECULAR,GREY);
  182. glLightfv(GL_LIGHT0,GL_POSITION,pos.data());
  183. pos(0) *= -1;
  184. pos(1) *= -1;
  185. pos(2) *= -1;
  186. glLightfv(GL_LIGHT1,GL_AMBIENT,GREY);
  187. glLightfv(GL_LIGHT1,GL_DIFFUSE,WHITE);
  188. glLightfv(GL_LIGHT1,GL_SPECULAR,BLACK);
  189. glLightfv(GL_LIGHT1,GL_POSITION,pos.data());
  190. }
  191. void init_flare()
  192. {
  193. }
  194. void draw_flare()
  195. {
  196. using namespace igl;
  197. using namespace Eigen;
  198. glPushMatrix();
  199. glScaled(bbd*0.5,bbd*0.5,bbd*0.5);
  200. glScaled(0.2,0.2,0.2);
  201. Vector3f light(0,0,0);
  202. igl::opengl2::lens_flare_draw(flares,shine_ids,flare_ids,light,1.0,shine_tic);
  203. glPopMatrix();
  204. }
  205. void draw_eyes()
  206. {
  207. using namespace Eigen;
  208. using namespace std;
  209. using namespace igl;
  210. #define NUM_LEDS 2
  211. Vector3d LED_pos[NUM_LEDS];
  212. LED_pos[0] = Vector3d( x,y,z);
  213. LED_pos[1] = Vector3d(-x,y,z);
  214. enum LEDMethod
  215. {
  216. LED_METHOD_COLORED_CIRCLE = 0,
  217. LED_METHOD_OUTLINED_CIRCLE = 1,
  218. LED_METHOD_TEXTURE_FLARE = 2
  219. } method = LED_METHOD_TEXTURE_FLARE;
  220. for(int l = 0;l<NUM_LEDS;l++)
  221. {
  222. glPushMatrix();
  223. glTranslated(LED_pos[l](0), LED_pos[l](1), LED_pos[l](2));
  224. const double r = 2.0;
  225. const float color[4] = {1,0,0,1};
  226. glScaled(r,r,r);
  227. switch(method)
  228. {
  229. case LED_METHOD_COLORED_CIRCLE:
  230. {
  231. glEnable(GL_COLOR_MATERIAL);
  232. glColorMaterial(GL_FRONT,GL_AMBIENT);
  233. glColor4fv(color);
  234. glBegin(GL_TRIANGLE_FAN);
  235. glVertex3d(0,0,0);
  236. for(double theta = 0;theta<2.*PI;theta+=2.*PI/15.)
  237. {
  238. glVertex3d(cos(theta),sin(theta),0);
  239. }
  240. glEnd();
  241. break;
  242. }
  243. case LED_METHOD_OUTLINED_CIRCLE:
  244. {
  245. glEnable(GL_COLOR_MATERIAL);
  246. glDisable(GL_LIGHTING);
  247. glColorMaterial(GL_FRONT,GL_DIFFUSE);
  248. glBegin(GL_TRIANGLE_FAN);
  249. glColor4fv(color);
  250. glVertex3d(0,0,0);
  251. glColor4f(0,0,0,1);
  252. for(double theta = 0;theta<2.*PI;theta+=2.*PI/15.)
  253. {
  254. glVertex3d(cos(theta),sin(theta),0);
  255. }
  256. glEnd();
  257. break;
  258. }
  259. case LED_METHOD_TEXTURE_FLARE:
  260. {
  261. draw_flare();
  262. break;
  263. }
  264. }
  265. glPopMatrix();
  266. }
  267. }
  268. void display()
  269. {
  270. using namespace igl;
  271. using namespace Eigen;
  272. using namespace std;
  273. glClearColor(0.03,0.03,0.04,0);
  274. glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
  275. if(is_animating)
  276. {
  277. double t = (get_seconds() - animation_start_time)/ANIMATION_DURATION;
  278. if(t > 1)
  279. {
  280. t = 1;
  281. is_animating = false;
  282. }
  283. Quaterniond q = animation_from_quat.slerp(t,animation_to_quat).normalized();
  284. auto & camera = s.camera;
  285. camera.orbit(q.conjugate());
  286. }
  287. glEnable(GL_DEPTH_TEST);
  288. glEnable(GL_BLEND);
  289. glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
  290. glEnable(GL_NORMALIZE);
  291. lights();
  292. push_scene();
  293. if(list_id == 0)
  294. {
  295. list_id = glGenLists(1);
  296. glNewList(list_id,GL_COMPILE);
  297. push_object();
  298. // Set material properties
  299. glDisable(GL_COLOR_MATERIAL);
  300. const float NEAR_BLACK[4] = {0.1,0.1,0.1,1.0};
  301. glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, NEAR_BLACK);
  302. glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, MIDNIGHT_BLUE_DIFFUSE);
  303. glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, SILVER_SPECULAR);
  304. glMaterialf (GL_FRONT_AND_BACK, GL_SHININESS, 128);
  305. igl::opengl2::draw_mesh(V,F,N);
  306. pop_object();
  307. // Draw a nice floor
  308. glPushMatrix();
  309. const double floor_offset =
  310. -2./bbd*(V.col(1).maxCoeff()-Vmid(1));
  311. glTranslated(0,floor_offset,0);
  312. const float GREY[4] = {0.5,0.5,0.6,1.0};
  313. const float DARK_GREY[4] = {0.2,0.2,0.3,1.0};
  314. igl::opengl2::draw_floor(GREY,DARK_GREY);
  315. glPopMatrix();
  316. glEndList();
  317. }
  318. glCallList(list_id);
  319. push_object();
  320. if(eyes_visible)
  321. {
  322. draw_eyes();
  323. }
  324. pop_object();
  325. pop_scene();
  326. igl::opengl::report_gl_error();
  327. if(render_to_tga_on_next)
  328. {
  329. GLint viewport[4];
  330. glGetIntegerv(GL_VIEWPORT,viewport);
  331. igl::opengl::render_to_tga(
  332. STR("./"<< "flare-eyes-" << setw(4) << setfill('0') << render_count++ << ".tga"),
  333. viewport[2],viewport[3],true);
  334. //render_to_tga_on_next = false;
  335. }
  336. TwDraw();
  337. glutSwapBuffers();
  338. glutPostRedisplay();
  339. }
  340. void mouse_wheel(int wheel, int direction, int mouse_x, int mouse_y)
  341. {
  342. using namespace std;
  343. using namespace igl;
  344. using namespace Eigen;
  345. GLint viewport[4];
  346. glGetIntegerv(GL_VIEWPORT,viewport);
  347. if(wheel == 0 && TwMouseMotion(mouse_x, viewport[3] - mouse_y))
  348. {
  349. static double mouse_scroll_y = 0;
  350. const double delta_y = 0.125*direction;
  351. mouse_scroll_y += delta_y;
  352. TwMouseWheel(mouse_scroll_y);
  353. return;
  354. }
  355. push_undo();
  356. auto & camera = s.camera;
  357. if(wheel==0)
  358. {
  359. // factor of zoom change
  360. double s = (1.-0.01*direction);
  361. //// FOV zoom: just widen angle. This is hardly ever appropriate.
  362. //camera.m_angle *= s;
  363. //camera.m_angle = min(max(camera.m_angle,1),89);
  364. camera.push_away(s);
  365. }else
  366. {
  367. // Dolly zoom:
  368. camera.dolly_zoom((double)direction*1.0);
  369. }
  370. }
  371. void mouse(int glutButton, int glutState, int mouse_x, int mouse_y)
  372. {
  373. using namespace std;
  374. using namespace Eigen;
  375. using namespace igl;
  376. bool tw_using = TwEventMouseButtonGLUT(glutButton,glutState,mouse_x,mouse_y);
  377. switch(glutButton)
  378. {
  379. case GLUT_RIGHT_BUTTON:
  380. case GLUT_LEFT_BUTTON:
  381. {
  382. switch(glutState)
  383. {
  384. case 1:
  385. // up
  386. glutSetCursor(GLUT_CURSOR_INHERIT);
  387. is_rotating = false;
  388. break;
  389. case 0:
  390. if(!tw_using)
  391. {
  392. push_undo();
  393. glutSetCursor(GLUT_CURSOR_CYCLE);
  394. // collect information for trackball
  395. is_rotating = true;
  396. down_camera = s.camera;
  397. down_x = mouse_x;
  398. down_y = mouse_y;
  399. }
  400. break;
  401. }
  402. break;
  403. }
  404. #ifdef GLUT_WHEEL_DOWN
  405. // Scroll down
  406. case GLUT_WHEEL_DOWN:
  407. {
  408. mouse_wheel(0,-1,mouse_x,mouse_y);
  409. break;
  410. }
  411. #endif
  412. #ifdef GLUT_WHEEL_UP
  413. // Scroll up
  414. case GLUT_WHEEL_UP:
  415. {
  416. mouse_wheel(0,1,mouse_x,mouse_y);
  417. break;
  418. }
  419. #endif
  420. #ifdef GLUT_WHEEL_LEFT
  421. // Scroll left
  422. case GLUT_WHEEL_LEFT:
  423. {
  424. mouse_wheel(1,-1,mouse_x,mouse_y);
  425. break;
  426. }
  427. #endif
  428. #ifdef GLUT_WHEEL_RIGHT
  429. // Scroll right
  430. case GLUT_WHEEL_RIGHT:
  431. {
  432. mouse_wheel(1,1,mouse_x,mouse_y);
  433. break;
  434. }
  435. #endif
  436. }
  437. }
  438. void mouse_drag(int mouse_x, int mouse_y)
  439. {
  440. using namespace igl;
  441. using namespace std;
  442. using namespace Eigen;
  443. /*bool tw_using =*/ TwMouseMotion(mouse_x,mouse_y);
  444. if(is_rotating)
  445. {
  446. glutSetCursor(GLUT_CURSOR_CYCLE);
  447. Quaterniond q;
  448. auto & camera = s.camera;
  449. switch(rotation_type)
  450. {
  451. case ROTATION_TYPE_IGL_TRACKBALL:
  452. {
  453. // Rotate according to trackball
  454. igl::trackball<double>(
  455. width,
  456. height,
  457. 2.0,
  458. down_camera.m_rotation_conj.coeffs().data(),
  459. down_x,
  460. down_y,
  461. mouse_x,
  462. mouse_y,
  463. q.coeffs().data());
  464. break;
  465. }
  466. case ROTATION_TYPE_TWO_AXIS_VALUATOR_FIXED_UP:
  467. {
  468. // Rotate according to two axis valuator with fixed up vector
  469. two_axis_valuator_fixed_up(
  470. width, height,
  471. 2.0,
  472. down_camera.m_rotation_conj,
  473. down_x, down_y, mouse_x, mouse_y,
  474. q);
  475. break;
  476. }
  477. default:
  478. break;
  479. }
  480. camera.orbit(q.conjugate());
  481. }
  482. }
  483. void init_relative()
  484. {
  485. using namespace Eigen;
  486. using namespace igl;
  487. using namespace std;
  488. per_face_normals(V,F,N);
  489. Vmax = V.colwise().maxCoeff();
  490. Vmin = V.colwise().minCoeff();
  491. Vmid = 0.5*(Vmax + Vmin);
  492. bbd = (Vmax-Vmin).norm();
  493. }
  494. void undo()
  495. {
  496. using namespace std;
  497. if(!undo_stack.empty())
  498. {
  499. redo_stack.push(s);
  500. s = undo_stack.top();
  501. undo_stack.pop();
  502. }
  503. }
  504. void redo()
  505. {
  506. using namespace std;
  507. if(!redo_stack.empty())
  508. {
  509. undo_stack.push(s);
  510. s = redo_stack.top();
  511. redo_stack.pop();
  512. }
  513. }
  514. void key(unsigned char key, int mouse_x, int mouse_y)
  515. {
  516. using namespace std;
  517. using namespace igl;
  518. using namespace Eigen;
  519. int mod = glutGetModifiers();
  520. switch(key)
  521. {
  522. // ESC
  523. case char(27):
  524. rebar.save(REBAR_NAME);
  525. // ^C
  526. case char(3):
  527. exit(0);
  528. case 'z':
  529. case 'Z':
  530. if(mod & GLUT_ACTIVE_COMMAND)
  531. {
  532. if(mod & GLUT_ACTIVE_SHIFT)
  533. {
  534. redo();
  535. }else
  536. {
  537. undo();
  538. }
  539. break;
  540. }else
  541. {
  542. push_undo();
  543. Quaterniond q;
  544. snap_to_canonical_view_quat(s.camera.m_rotation_conj,1.0,q);
  545. s.camera.orbit(q.conjugate());
  546. break;
  547. }
  548. case ' ':
  549. render_to_tga_on_next = !render_to_tga_on_next;
  550. break;
  551. default:
  552. if(!TwEventKeyboardGLUT(key,mouse_x,mouse_y))
  553. {
  554. cout<<"Unknown key command: "<<key<<" "<<int(key)<<endl;
  555. }
  556. }
  557. }
  558. int main(int argc, char * argv[])
  559. {
  560. using namespace std;
  561. using namespace Eigen;
  562. using namespace igl;
  563. string filename = "../shared/beast.obj";
  564. if(argc < 2)
  565. {
  566. cerr<<"Usage:"<<endl<<" ./example input.obj"<<endl;
  567. cout<<endl<<"Opening default mesh..."<<endl;
  568. }else
  569. {
  570. // Read and prepare mesh
  571. filename = argv[1];
  572. }
  573. // print key commands
  574. cout<<"[Click] and [drag] Rotate model using trackball."<<endl;
  575. cout<<"[Z,z] Snap rotation to canonical view."<<endl;
  576. cout<<"[⌘ Z] Undo."<<endl;
  577. cout<<"[⇧ ⌘ Z] Redo."<<endl;
  578. cout<<"[^C,ESC] Exit."<<endl;
  579. // dirname, basename, extension and filename
  580. string d,b,ext,f;
  581. pathinfo(filename,d,b,ext,f);
  582. // Convert extension to lower case
  583. transform(ext.begin(), ext.end(), ext.begin(), ::tolower);
  584. vector<vector<double > > vV,vN,vTC;
  585. vector<vector<int > > vF,vFTC,vFN;
  586. if(ext == "obj")
  587. {
  588. // Convert extension to lower case
  589. if(!igl::readOBJ(filename,vV,vTC,vN,vF,vFTC,vFN))
  590. {
  591. return 1;
  592. }
  593. }else if(ext == "off")
  594. {
  595. // Convert extension to lower case
  596. if(!igl::readOFF(filename,vV,vF,vN))
  597. {
  598. return 1;
  599. }
  600. }else if(ext == "wrl")
  601. {
  602. // Convert extension to lower case
  603. if(!igl::readWRL(filename,vV,vF))
  604. {
  605. return 1;
  606. }
  607. //}else
  608. //{
  609. // // Convert extension to lower case
  610. // MatrixXi T;
  611. // if(!igl::readMESH(filename,V,T,F))
  612. // {
  613. // return 1;
  614. // }
  615. // //if(F.size() > T.size() || F.size() == 0)
  616. // {
  617. // boundary_facets(T,F);
  618. // }
  619. }
  620. if(vV.size() > 0)
  621. {
  622. if(!list_to_matrix(vV,V))
  623. {
  624. return 1;
  625. }
  626. polygon_mesh_to_triangle_mesh(vF,F);
  627. }
  628. init_relative();
  629. // Init glut
  630. glutInit(&argc,argv);
  631. if( !TwInit(TW_OPENGL, NULL) )
  632. {
  633. // A fatal error occured
  634. fprintf(stderr, "AntTweakBar initialization failed: %s\n", TwGetLastError());
  635. return 1;
  636. }
  637. // Create a tweak bar
  638. rebar.TwNewBar("TweakBar");
  639. rebar.TwAddVarRW("camera_rotation", TW_TYPE_QUAT4D,
  640. s.camera.m_rotation_conj.coeffs().data(),"open readonly=true");
  641. TwType RotationTypeTW = igl::anttweakbar::ReTwDefineEnumFromString("RotationType",
  642. "igl_trackball,two-axis-valuator-fixed-up");
  643. rebar.TwAddVarCB( "rotation_type", RotationTypeTW,
  644. set_rotation_type,get_rotation_type,NULL,"keyIncr=] keyDecr=[");
  645. rebar.TwAddVarRW( "x",TW_TYPE_DOUBLE, &x,"");
  646. rebar.TwAddVarRW( "y",TW_TYPE_DOUBLE, &y,"");
  647. rebar.TwAddVarRW( "z",TW_TYPE_DOUBLE, &z,"");
  648. rebar.TwAddVarRW( "eyes_visible",TW_TYPE_BOOLCPP, &eyes_visible,"key=e");
  649. rebar.load(REBAR_NAME);
  650. animation_from_quat = Quaterniond(1,0,0,0);
  651. s.camera.m_rotation_conj = animation_from_quat;
  652. animation_start_time = get_seconds();
  653. // Init antweakbar
  654. glutInitDisplayString( "rgba depth double samples>=8 ");
  655. glutInitWindowSize(glutGet(GLUT_SCREEN_WIDTH)/2.0,glutGet(GLUT_SCREEN_HEIGHT)/2.0);
  656. glutCreateWindow("upright");
  657. glutDisplayFunc(display);
  658. glutReshapeFunc(reshape);
  659. glutKeyboardFunc(key);
  660. glutMouseFunc(mouse);
  661. glutMotionFunc(mouse_drag);
  662. glutPassiveMotionFunc((GLUTmousemotionfun)TwEventMouseMotionGLUT);
  663. // Init flares
  664. igl::opengl2::lens_flare_load_textures(shine_ids,flare_ids);
  665. const float RED[3] = {1,0,0};
  666. const float GREEN[3] = {0,1,0};
  667. const float BLUE[3] = {0,0,1};
  668. //lens_flare_create(RED,GREEN,BLUE,flares);
  669. flares.resize(4);
  670. flares[0] = igl::opengl2::Flare(-1, 1.0f, 1.*0.1f, RED, 1.0);
  671. flares[1] = igl::opengl2::Flare(-1, 1.0f, 1.*0.15f, GREEN, 1.0);
  672. flares[2] = igl::opengl2::Flare(-1, 1.0f, 1.*0.35f, BLUE, 1.0);
  673. flares[3] = igl::opengl2::Flare( 2, 1.0f, 1.*0.1f, BLUE, 0.4);
  674. glutMainLoop();
  675. return 0;
  676. }