example.cpp 17 KB

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