example.cpp 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739
  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_tga_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_COLORED_CIRCLE;
  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_tga_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_tga_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 GLUT_WHEEL_DOWN:
  392. {
  393. mouse_wheel(0,-1,mouse_x,mouse_y);
  394. break;
  395. }
  396. // Scroll up
  397. case GLUT_WHEEL_UP:
  398. {
  399. mouse_wheel(0,1,mouse_x,mouse_y);
  400. break;
  401. }
  402. // Scroll left
  403. case GLUT_WHEEL_LEFT:
  404. {
  405. mouse_wheel(1,-1,mouse_x,mouse_y);
  406. break;
  407. }
  408. // Scroll right
  409. case GLUT_WHEEL_RIGHT:
  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. int mod = glutGetModifiers();
  517. switch(key)
  518. {
  519. // ESC
  520. case char(27):
  521. rebar.save(REBAR_NAME);
  522. // ^C
  523. case char(3):
  524. exit(0);
  525. case 'z':
  526. case 'Z':
  527. if(mod & GLUT_ACTIVE_COMMAND)
  528. {
  529. if(mod & GLUT_ACTIVE_SHIFT)
  530. {
  531. redo();
  532. }else
  533. {
  534. undo();
  535. }
  536. break;
  537. }else
  538. {
  539. push_undo();
  540. igl::snap_to_canonical_view_quat<double>(
  541. s.camera.rotation,
  542. 1.0,
  543. s.camera.rotation);
  544. break;
  545. }
  546. case ' ':
  547. render_to_tga_on_next = !render_to_tga_on_next;
  548. break;
  549. default:
  550. if(!TwEventKeyboardGLUT(key,mouse_x,mouse_y))
  551. {
  552. cout<<"Unknown key command: "<<key<<" "<<int(key)<<endl;
  553. }
  554. }
  555. }
  556. int main(int argc, char * argv[])
  557. {
  558. using namespace std;
  559. using namespace Eigen;
  560. using namespace igl;
  561. string filename = "../shared/beast.obj";
  562. if(argc < 2)
  563. {
  564. cerr<<"Usage:"<<endl<<" ./example input.obj"<<endl;
  565. cout<<endl<<"Opening default mesh..."<<endl;
  566. }else
  567. {
  568. // Read and prepare mesh
  569. filename = argv[1];
  570. }
  571. // print key commands
  572. cout<<"[Click] and [drag] Rotate model using trackball."<<endl;
  573. cout<<"[Z,z] Snap rotation to canonical view."<<endl;
  574. cout<<"[⌘ Z] Undo."<<endl;
  575. cout<<"[⇧ ⌘ Z] Redo."<<endl;
  576. cout<<"[^C,ESC] Exit."<<endl;
  577. // dirname, basename, extension and filename
  578. string d,b,ext,f;
  579. pathinfo(filename,d,b,ext,f);
  580. // Convert extension to lower case
  581. transform(ext.begin(), ext.end(), ext.begin(), ::tolower);
  582. vector<vector<double > > vV,vN,vTC;
  583. vector<vector<int > > vF,vFTC,vFN;
  584. if(ext == "obj")
  585. {
  586. // Convert extension to lower case
  587. if(!igl::readOBJ(filename,vV,vTC,vN,vF,vFTC,vFN))
  588. {
  589. return 1;
  590. }
  591. }else if(ext == "off")
  592. {
  593. // Convert extension to lower case
  594. if(!igl::readOFF(filename,vV,vF,vN))
  595. {
  596. return 1;
  597. }
  598. }else if(ext == "wrl")
  599. {
  600. // Convert extension to lower case
  601. if(!igl::readWRL(filename,vV,vF))
  602. {
  603. return 1;
  604. }
  605. //}else
  606. //{
  607. // // Convert extension to lower case
  608. // MatrixXi T;
  609. // if(!igl::readMESH(filename,V,T,F))
  610. // {
  611. // return 1;
  612. // }
  613. // //if(F.size() > T.size() || F.size() == 0)
  614. // {
  615. // boundary_faces(T,F);
  616. // }
  617. }
  618. if(vV.size() > 0)
  619. {
  620. if(!list_to_matrix(vV,V))
  621. {
  622. return 1;
  623. }
  624. triangulate(vF,F);
  625. }
  626. init_relative();
  627. // Init glut
  628. glutInit(&argc,argv);
  629. if( !TwInit(TW_OPENGL, NULL) )
  630. {
  631. // A fatal error occured
  632. fprintf(stderr, "AntTweakBar initialization failed: %s\n", TwGetLastError());
  633. return 1;
  634. }
  635. // Create a tweak bar
  636. rebar.TwNewBar("TweakBar");
  637. rebar.TwAddVarCB("camera_rotation", TW_TYPE_QUAT4D, set_camera_rotation,get_camera_rotation, NULL, "open");
  638. TwEnumVal RotationTypesEV[NUM_ROTATION_TYPES] =
  639. {
  640. {ROTATION_TYPE_IGL_TRACKBALL,"igl trackball"},
  641. {ROTATION_TYPE_TWO_AXIS_VALUATOR_FIXED_UP,"two a... fixed up"},
  642. };
  643. TwType RotationTypeTW =
  644. ReTwDefineEnum(
  645. "RotationType",
  646. RotationTypesEV,
  647. NUM_ROTATION_TYPES);
  648. rebar.TwAddVarRW( "rotation_type", RotationTypeTW, &rotation_type,"keyIncr=] keyDecr=[");
  649. rebar.TwAddVarRW( "x",TW_TYPE_DOUBLE, &x,"");
  650. rebar.TwAddVarRW( "y",TW_TYPE_DOUBLE, &y,"");
  651. rebar.TwAddVarRW( "z",TW_TYPE_DOUBLE, &z,"");
  652. rebar.TwAddVarRW( "eyes_visible",TW_TYPE_BOOLCPP, &eyes_visible,"key=e");
  653. rebar.load(REBAR_NAME);
  654. // Init antweakbar
  655. glutInitDisplayString( "rgba depth double samples>=8 ");
  656. glutInitWindowSize(glutGet(GLUT_SCREEN_WIDTH)/2.0,glutGet(GLUT_SCREEN_HEIGHT)/2.0);
  657. glutCreateWindow("upright");
  658. glutDisplayFunc(display);
  659. glutReshapeFunc(reshape);
  660. glutKeyboardFunc(key);
  661. glutMouseFunc(mouse);
  662. glutMotionFunc(mouse_drag);
  663. glutPassiveMotionFunc((GLUTmousemotionfun)TwEventMouseMotionGLUT);
  664. // Init flares
  665. lens_flare_load_textures(shine_ids,flare_ids);
  666. const float RED[3] = {1,0,0};
  667. const float GREEN[3] = {0,1,0};
  668. const float BLUE[3] = {0,0,1};
  669. //lens_flare_create(RED,GREEN,BLUE,flares);
  670. flares.resize(4);
  671. flares[0] = Flare(-1, 1.0f, 1.*0.1f, RED, 1.0);
  672. flares[1] = Flare(-1, 1.0f, 1.*0.15f, GREEN, 1.0);
  673. flares[2] = Flare(-1, 1.0f, 1.*0.35f, BLUE, 1.0);
  674. flares[3] = Flare( 2, 1.0f, 1.*0.1f, BLUE, 0.4);
  675. glutMainLoop();
  676. return 0;
  677. }