This week only. Pastebin PRO Accounts Christmas Special! Don't miss out!Want more features on Pastebin? Sign Up, it's FREE!
Guest

Untitled

By: a guest on May 11th, 2011  |  syntax: C  |  size: 11.14 KB  |  views: 41  |  expires: Never
download  |  raw  |  embed  |  report abuse  |  print
This paste has a previous version, view the difference. Text below is selected. Please press Ctrl+C to copy to your clipboard. (⌘+C on Mac)
  1. #include <math.h>
  2. #include <stdio.h>
  3. #include <GL/glut.h>
  4. #include "GluCylinders.h"
  5.  
  6. // There's no real need to comment includes.
  7. // What a include supplies normally is obvious from the file name
  8.  
  9.  
  10. void animate(float t, float&, float&, float&);
  11.  
  12. void renderCylinder(float x1, float y1, float z1,
  13.                     float x2,float y2, float z2,
  14.                     float radius, int subdivisions,
  15.                     GLUquadricObj *quadric);
  16.  
  17. void renderCylinder_convenient(float x1, float y1, float z1,
  18.                                float x2,float y2, float z2,
  19.                                float radius,int subdivisions);
  20.  
  21. // The next global variable controls the animation's state and speed.
  22. float RotateAngle = 0.0f;               // Angle in degrees of rotation around y-axis
  23. float Azimuth = 0.0;                    // Rotated up or down by this amount
  24. float AngleStepSize = 3.0f;             // Step three degrees at a time
  25. const float AngleStepMax = 10.0f;
  26. const float AngleStepMin = 0.1f;
  27.  
  28. int WireFrameOn = 1;                    // == 1 for wire frame mode
  29.  
  30. //points
  31. // I would not call this geometry but control points...
  32. float Geometry[9][3] = {
  33.         { 4,2.0,0},
  34.         { 4,2.0,0},     // Point1
  35.         {-1.5,0.2,0},                            
  36.  
  37.         {-2,0.3,0},                              
  38.         {-2.5,0.6,0},
  39.  
  40.         {-3,0.8,0},                              
  41.    
  42.         {-3.5,1.0,0},
  43.         { -5.5,1.8,0}, //point 2
  44.         { -5.5,1.8,0}
  45.        
  46. };
  47.  
  48. int x2[5],y2[5],z2[5];
  49.  
  50. // LOD? Level of Detail? Length of Delay?
  51. // This is a case where a comment makes sense: Explaining abbreviations.
  52. // unsigned int LOD=20;
  53.  
  54. void myKeyboardFunc( unsigned char key, int x, int y )
  55. {
  56.         switch ( key ) {
  57.         case 'w':
  58.                 WireFrameOn = 1-WireFrameOn;
  59.                 glutPostRedisplay();
  60.                 break;
  61.         case 'R':
  62.                 AngleStepSize *= 1.5;
  63.                 if (AngleStepSize>AngleStepMax ) {
  64.                         AngleStepSize = AngleStepMax;
  65.                 }
  66.                 break;
  67.         case 'r':
  68.                 AngleStepSize /= 1.5;
  69.                 if (AngleStepSize<AngleStepMin ) {
  70.                         AngleStepSize = AngleStepMin;
  71.                 }
  72.                 break;
  73.         case 27:        // Escape key
  74.                 exit(1);
  75.         }
  76. }
  77.  
  78. // glutSpecialFunc is called below to set this function to handle
  79. //              all "special" key presses.  See glut.h for the names of
  80. //              special keys.
  81. void mySpecialKeyFunc( int key, int x, int y )
  82. {
  83.         switch ( key ) {
  84.         case GLUT_KEY_UP:              
  85.                 Azimuth += AngleStepSize;
  86.                 if ( Azimuth>80.0f ) {
  87.                         Azimuth = 80.0f;
  88.                 }
  89.                 break;
  90.         case GLUT_KEY_DOWN:
  91.                 Azimuth -= AngleStepSize;
  92.                 if ( Azimuth < -80.0f ) {
  93.                         Azimuth = -80.0f;
  94.                 }
  95.                 break;
  96.         case GLUT_KEY_LEFT:
  97.                 RotateAngle += AngleStepSize;
  98.                 if ( RotateAngle > 180.0f ) {
  99.                         RotateAngle -= 360.0f;
  100.                 }
  101.                 break;
  102.         case GLUT_KEY_RIGHT:
  103.                
  104.                 RotateAngle -= AngleStepSize;
  105.                 if ( RotateAngle < -180.0f ) {
  106.                         RotateAngle += 360.0f;
  107.                        
  108.                 }
  109.                 break;
  110.         }
  111.         glutPostRedisplay();
  112.  
  113. }
  114. /*
  115.  * drawScene() handles the animation and the redrawing of the
  116.  *              graphics window contents.
  117.  */
  118. void drawScene(void)
  119. {
  120.         // Those should not be a drawScene static, but part of
  121.         // a scene management structure. Which your code lacks,
  122.         // unfortunately, and I'm not gonna introduce one.
  123.         static float animation_time = 0.;
  124.         static int j = 1; // why 1 indexed? This is not Lua
  125.  
  126.         if ( WireFrameOn ) {
  127.                 glPolygonMode ( GL_FRONT_AND_BACK, GL_LINE ); // Just show wireframes
  128.         } else {
  129.                 glPolygonMode ( GL_FRONT_AND_BACK, GL_FILL ); // Show solid polygons
  130.         }
  131.  
  132.         glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
  133.         glEnable(GL_DEPTH_TEST);
  134.  
  135.        
  136.         glMatrixMode( GL_MODELVIEW );
  137.         glLoadIdentity();
  138.  
  139.         glTranslatef( -0.5, 0.0, -35.0 );
  140.         glRotatef( RotateAngle, 0.0, 1.0, 0.0 );
  141.         glRotatef( Azimuth, 1.0, 0.0, 0.0 );
  142.  
  143. // Please, don't /code/ your geometry, it's ugly and unmaintainable. I omit that code here
  144. // (...)
  145.  
  146.  
  147.         // Okay, I can just guess here, but it looks like you're intending to draw
  148.         // a trace of the sphere as it moves around. I have no idea what that j
  149.         // loop is meant for, though. But I guess you want to show the control points,
  150.         // one after another. This another case _FOR_ comments: Explaining the idea of
  151.         // the overall scheme. Don't write in a comment what a single statement does. I
  152.         // can see that from the statement.
  153.  
  154.         // use the parametric time value 0 to current animation time.
  155.         float x3, y3, z3;
  156.  
  157.         // first draw the trace
  158.         glBegin(GL_LINE_STRIP);
  159.         for(float t = 0; t < animation_time; t+=0.05) {
  160.                 animate(t, x3, y3, z3);
  161.                 glVertex3f( x3,y3,z3 );
  162.         }
  163.         glEnd();
  164.  
  165.         // Then draw the control point markers
  166.         glColor3f(1,1,0);
  167.         for(float t = 0; t < animation_time; t+=0.05) {
  168.                 animate(t, x3, y3, z3);
  169.                 renderCylinder_convenient(
  170.                         Geometry[j][0],Geometry[j][1],Geometry[j][2],
  171.                         x3,y3,z3,
  172.                         0.3, 32);
  173.         }
  174.  
  175.         // Last but not least draw sphere at the position for animation_time.
  176.         animate(animation_time, x3, y3, z3);
  177.         glutDrawSphere(...);
  178.  
  179.         // now, we want to play that animation a few times in
  180.         // succession, but with different control points visible
  181.         // or so I presume so after each animation time has reached 1
  182.         // we increment the control point counter. And after that hit
  183.         // its maximum we stop advancing the animation
  184.  
  185.         if(j<3) {
  186.                 if(animation_time < 1.0) {
  187.                         // Animation step should be a measured
  188.                         // value. However in case of your simple
  189.                         // graphics and in the case of v-synced
  190.                         // buffer swap, and the prevalence of LCD
  191.                         // screens updating at 60Hz we can make this
  192.                         // a constant:
  193.                         // One frame is 1/60th of a second and we
  194.                         // want to take the animation 5 seconds to
  195.                         // play:
  196.                         float animation_step = (1./60.) / (5.);
  197.  
  198.                         animation_time += animation_step;
  199.                 } else {
  200.                         animation_time = 0.;
  201.                         j++;
  202.                 }
  203.         }
  204.  
  205.         glutSwapBuffers();
  206. }
  207.  
  208.  
  209. // Called when the window is resized
  210. //              w, h - width and height of the window in pixels.
  211. void resizeWindow(int w, int h)
  212. {
  213.         double aspectRatio;
  214.  
  215.         // Technically all this should be done in the display function!
  216.  
  217.         // Define the portion of the window used for OpenGL rendering.
  218.         glViewport( 0, 0, w, h );       // View port uses whole window
  219.  
  220.         // Set up the projection view matrix: perspective projection
  221.         // Determine the min and max values for x and y that should appear in the window.
  222.         // The complication is that the aspect ratio of the window may not match the
  223.         //              aspect ratio of the scene we want to view.
  224.         w = (w==0) ? 1 : w;
  225.         h = (h==0) ? 1 : h;
  226.         aspectRatio = (double)w / (double)h;
  227.  
  228.         glMatrixMode( GL_PROJECTION );
  229.         glLoadIdentity();
  230.         gluPerspective( 15.0, aspectRatio, 25.0, 45.0 );
  231.  
  232. }
  233.  
  234.  
  235. // Main routine
  236. // Set up OpenGL, define the callbacks and start the main loop
  237. int main( int argc, char** argv )
  238. {
  239.         glutInit(&argc, argv);
  240.  
  241.         glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH );
  242.  
  243.         glutInitWindowPosition( 10, 60 );
  244.         glutInitWindowSize( 360, 360 );
  245.         glutCreateWindow( "GluCylinders" );
  246.  
  247.         glutKeyboardFunc( myKeyboardFunc );
  248.         glutSpecialFunc( mySpecialKeyFunc );
  249.  
  250.         glutReshapeFunc( resizeWindow );
  251.  
  252.         glutIdleFunc( glutPostRedisplay ); // when idle -> redraw
  253.  
  254.         glutDisplayFunc( drawScene );
  255.  
  256.         fprintf(stdout, "Arrow keys control viewpoint.\n");
  257.         fprintf(stdout, "Press \"w\" to toggle wireframe mode.\n");
  258.         fprintf(stdout, "Press \"R\" or \"r\" to increase or decrease rate of movement (respectively).\n");
  259.        
  260.         // Start the main loop.  glutMainLoop never returns.
  261.         glutMainLoop(  );
  262.  
  263.         return 0;
  264. }
  265.  
  266. GLUquadricObj* myReusableQuadric = 0;
  267.  
  268. void drawGluCylinder( double height, double radius, int slices, int stacks ) {
  269.         drawGluSlantCylinder( height, radius, radius, slices, stacks );
  270. }
  271.  
  272. void drawGluSlantCylinder( double height, double radiusBase, double radiusTop, int slices, int stacks )
  273. {
  274.         if ( ! myReusableQuadric ) {
  275.                 myReusableQuadric = gluNewQuadric();  
  276.                 // Should (but don't) check if pointer is still null --- to catch memory allocation errors.
  277.                 gluQuadricNormals( myReusableQuadric, GL_TRUE );
  278.         }
  279.         // Draw the cylinder.
  280.         gluCylinder( myReusableQuadric, radiusBase, radiusTop, height, slices, stacks );
  281. }
  282.  
  283.  
  284. void drawGluCylinderWithCaps( double height, double radius, int slices, int stacks ) {
  285.         drawGluSlantCylinderWithCaps( height, radius, radius, slices, stacks );
  286. }
  287.  
  288.  
  289. // animate shall calculate the new position for the next
  290. // render iteration. Don't do delays, busy loops and drawing
  291. // stuff here.
  292. void animate(float t, float &x3, float &y3, float &z3)
  293. {
  294.         // I don't see it in this mess, but I
  295.         // assume this is some kind of spline
  296.         // interpolation, right?
  297.  
  298.         x3 = 0.5*((-Geometry[j-1][0] + 3*Geometry[j][0]  -3*Geometry[j+1][0] + Geometry[j+2][0])*t*t*t + (2*Geometry[j-1][0] -5*Geometry[j][0] +4*Geometry[j+1][0] -Geometry[j+2][0])*t*t + (-Geometry[j-1][0] + Geometry[j+1][0])*t + 2*Geometry[j][0]);
  299.  
  300.         y3 = 0.5*((-Geometry[j-1][1] + 3*Geometry[j][1]  -3*Geometry[j+1][1] + Geometry[j+2][1])*t*t*t+ (2*Geometry[j-1][1] -5*Geometry[j][1] +4*Geometry[j+1][1] -Geometry[j+2][1])*t*t +(-Geometry[j-1][1] + Geometry[j+1][1])*t + 2*Geometry[j][1]);
  301.  
  302.                        
  303.  
  304.         z3 = 0.5*((-Geometry[j-1][2] + 3*Geometry[j][2]  -3*Geometry[j+1][2] + Geometry[j+2][2])*t*t*t + (2*Geometry[j-1][2] -5*Geometry[j][2] +4*Geometry[j+1][2] -Geometry[j+2][2])*t*t +(-Geometry[j-1][2] + Geometry[j+1][2])*t + 2*Geometry[j][2]);
  305.  
  306. }
  307.  
  308. void renderCylinder(float x1, float y1, float z1, float x2,float y2, float z2, float radius,int subdivisions,GLUquadricObj *quadric)
  309. {
  310.         float v,rx,ry,ax,vx = x2-x1;  
  311.         float vy = y2-y1;  
  312.         float vz = z2-z1;   //handle the degenerate case of z1 == z2 with an approximation  
  313.  
  314.         if(vz == 0)      
  315.                 vz =.00000001;  
  316.  
  317.         v = sqrt( vx*vx + vy*vy + vz*vz );  
  318.         ax = 57.2957795*acos( vz/v );  
  319.  
  320.         if ( vz < 0.0 )      
  321.                 ax = -ax;  
  322.        
  323.         rx = -vy*vz;  
  324.         ry = vx*vz;  
  325.  
  326.         glPushMatrix();   //draw the cylinder body  
  327.         glTranslatef( x1,y1,z1 );  
  328.         glRotatef(ax, rx, ry, 0.0);  
  329.         gluQuadricOrientation(quadric,GLU_OUTSIDE);  
  330.         gluCylinder(quadric, radius, radius, v, subdivisions, 1);   //draw the first cap  
  331.         gluQuadricOrientation(quadric,GLU_INSIDE);  
  332.         gluDisk( quadric, 0.0, radius, subdivisions, 1);  
  333.         glTranslatef( 0,0,v );   //draw the second cap  
  334.         gluQuadricOrientation(quadric,GLU_OUTSIDE);  
  335.         gluDisk( quadric, 0.0, radius, subdivisions, 1);  
  336.         glPopMatrix();
  337. }
  338.  
  339. void renderCylinder_convenient(
  340.         float x1, float y1, float z1,
  341.         float x2,float y2, float z2,
  342.         float radius,int subdivisions)
  343. {  
  344.         //the same quadric can be re-used for drawing many cylinders
  345.  
  346.         // Instead of quadrics and coding your geometry you should
  347.         // just import a 3D model and render that. It's easier and
  348.         // allows for more artistic freedom. Yes, Yes, I know, your
  349.         // teachers assigment; seriously, I'd tell a teacher demanding
  350.         // this to f*** himself.
  351.  
  352.         GLUquadricObj *quadric=gluNewQuadric();  
  353.         gluQuadricNormals(quadric, GLU_SMOOTH);  
  354.         renderCylinder(x1,y1,z1,x2,y2,z2,radius,subdivisions,quadric);  
  355.         gluDeleteQuadric(quadric);}
  356.  
  357.  
  358. void drawGluSlantCylinderWithCaps(
  359.         double height, double radiusBase, double radiusTop,
  360.         int slices, int stacks )
  361. {
  362.         // First draw the cylinder
  363.         drawGluSlantCylinder( height, radiusBase, radiusTop, slices, stacks );
  364.  
  365.         // Draw the top disk cap
  366.         glPushMatrix();
  367.         glTranslated(0.0, 0.0, height);
  368.         gluDisk( myReusableQuadric, 0.0, radiusTop, slices, stacks );
  369.         glPopMatrix();
  370.  
  371.         // Draw the bottom disk cap
  372.         glPushMatrix();
  373.         glRotated(180.0, 1.0, 0.0, 0.0);
  374.         gluDisk( myReusableQuadric, 0.0, radiusBase, slices, stacks );
  375.         glPopMatrix();
  376.  
  377. }
clone this paste RAW Paste Data