example.cpp 16 KB

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