Advertisement
Guest User

Untitled

a guest
May 11th, 2011
100
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 11.14 KB | None | 0 0
  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. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement