Img_Slide.cpp
上传用户:sz83729876
上传日期:2013-03-07
资源大小:4140k
文件大小:11k
源码类别:

OpenGL

开发平台:

Windows_Unix

  1. #include "../../main.h"
  2. #define RADIUS  0.05
  3. #define STEP_LONGITUDE  22.5 /* 22.5 makes 8 bands like original Boing */
  4. #define STEP_LATITUDE  22.5
  5. #define DIST_BALL (RADIUS * 10 + RADIUS+10 * 0.1)
  6. #define BOUNCE_HEIGHT (RADIUS * 101.1)
  7. #define BOUNCE_WIDTH (RADIUS * 10.1)
  8. #define WALL_L_OFFSET -4.95
  9. #define WALL_R_OFFSET 5.2
  10. ///// A virer
  11. #define GRID_SIZE (RADIUS * 6.5) /* length (width) of grid */
  12. #define SHADOW_OFFSET_X -6.0
  13. #define SHADOW_OFFSET_Y  6.0
  14. #define SHADOW_OFFSET_Z   0.0
  15. #define RGB_BROWN 0.7, 0.35, 0.2
  16. #define RGB_GRAY 0.55, 0.55, 0.55
  17. #define RGB_GREEN 0.05, 0.9, 0.05
  18. #define RGB_PURPLE 0.6, 0.1, 0.6
  19. #define RGB_RED 0.8, 0.1, 0.1
  20. #define RGB_BLUE 0.1, 0.1, 0.8
  21. #define RGB_SKYBLUE 0.2, 0.6, 0.99
  22. #define RGB_SHADOW 0.35, 0.35, 0.35
  23. #define RGB_WHITE 0.95, 0.95, 0.95
  24. typedef unsigned char uchar;
  25. typedef unsigned int uint;
  26. #ifndef M_PI
  27. #define M_PI           3.14159265358979323846  /* pi */
  28. #endif
  29. #ifndef FALSE
  30. #define FALSE 0
  31. #define TRUE  1
  32. #endif
  33. #ifndef max
  34. #define max(a,b) ((a > b) ? (a) : (b))
  35. #define min(a,b) ((a < b) ? (a) : (b))
  36. #endif
  37. #ifndef MAX
  38. #define MAX(a,b) ((a > b) ? (a) : (b))
  39. #define MIN(a,b) ((a < b) ? (a) : (b))
  40. #endif
  41. #define STREQ(a,b) (strcmp((a),(b))==0)
  42. #define STRNE(a,b) (strcmp((a),(b))!=0)
  43. /*
  44.  * For full-speed (ie no delay), set this to 1.
  45.  */
  46. #define TIMER_MSECS 80
  47. enum DRAW_BALL_ENUM { DRAW_BALL, DRAW_BALL_SHADOW };
  48. struct vertex_t
  49. {
  50.    GLfloat x;
  51.    GLfloat y;
  52.    GLfloat z;
  53. };
  54. #define random() rand()
  55. #define srandom() srand()
  56. GLfloat deg_rot_y = 0.0;
  57. GLfloat deg_rot_y_inc = 6.0;
  58. GLfloat ball_x = -RADIUS;
  59. GLfloat ball_y = -RADIUS;
  60. GLfloat ball_x_inc = 1.0;
  61. GLfloat ball_y_inc = 6.0;
  62. DRAW_BALL_ENUM drawBallHow;
  63. /*****************************************************************************
  64.  * Truncate a degree.
  65.  *****************************************************************************/
  66. GLfloat TruncateDeg( GLfloat deg )
  67. {
  68.    if ( deg >= 360.0 )
  69.       return (deg - 360.0);
  70.    else
  71.       return deg;
  72. }
  73. /*****************************************************************************
  74.  * Convert a degree (360-based) into a radian.
  75.  * 360' = 2 * PI
  76.  *****************************************************************************/
  77. double deg2rad( double deg )
  78. {
  79.     return deg / 360 * (2 * M_PI);
  80. }
  81. /*****************************************************************************
  82.  * 360' sin().
  83.  *****************************************************************************/
  84. double sin_deg( double deg )
  85. {
  86.    return sin( deg2rad( deg ) );
  87. }
  88. /*****************************************************************************
  89.  * 360' cos().
  90.  *****************************************************************************/
  91. double cos_deg( double deg )
  92. {
  93.    return cos( deg2rad( deg ) );
  94. }
  95. // Compute a cross product (for a normal vector).
  96. // c = a x b
  97. void CrossProduct( vertex_t& a, vertex_t& b, vertex_t& c, vertex_t& n )
  98. {
  99.    GLfloat u1, u2, u3;
  100.    GLfloat v1, v2, v3;
  101.    u1 = b.x - a.x;
  102.    u2 = b.y - a.y;
  103.    u3 = b.y - a.z;
  104.    v1 = c.x - a.x;
  105.    v2 = c.y - a.y;
  106.    v3 = c.z - a.z;
  107.    n.x = u2 * v3 - v2 * v3;
  108.    n.y = u3 * v1 - v3 * u1;
  109.    n.z = u1 * v2 - v1 * u2;
  110. }
  111. namespace Amiga
  112. {
  113. void init()
  114. {
  115.    glShadeModel( GL_FLAT );
  116. }
  117. void Draw()
  118. {
  119. glPushMatrix();
  120. glTranslatef(0.0,0.0, -0.8);
  121. drawBallHow = DRAW_BALL;
  122. DrawBoingBall();
  123. glPopMatrix();
  124.    return;
  125. }
  126. void DrawBoingBall()
  127. {
  128.    GLfloat lon_deg; /* degree of longitude */
  129.    glPushMatrix();
  130.    glMatrixMode( GL_MODELVIEW );
  131.    BounceBall();
  132.   /*
  133.    * Tilt the ball.
  134.    */
  135.    glRotatef( -20.0, 0.0, 0.0, 1.0 );
  136.   /*
  137.    * Continually rotate ball around Y axis.
  138.    */
  139.    glRotatef( deg_rot_y, 0.0, 1.0, 0.0 );
  140.    deg_rot_y = TruncateDeg( deg_rot_y + deg_rot_y_inc );
  141.   /*
  142.    * Set OpenGL state for Boing ball.
  143.    */
  144.    glCullFace( GL_FRONT );
  145.    glEnable( GL_CULL_FACE );
  146.    glEnable( GL_NORMALIZE );
  147.   /*
  148.    * Build a faceted latitude slice of the Boing ball,
  149.    * stepping same-sized vertical bands of the sphere.
  150.    */
  151.    for ( lon_deg = 0;
  152.          lon_deg < 180;
  153.          lon_deg += STEP_LONGITUDE )
  154.    {
  155.      /*
  156.       * Draw a latitude circle at this longitude.
  157.       */
  158.       DrawBoingBallBand( lon_deg,
  159.                          lon_deg + STEP_LONGITUDE );
  160.    }
  161.    glDisable( GL_CULL_FACE );
  162.    glDisable( GL_NORMALIZE );
  163.    
  164.    glPopMatrix();
  165.    return;
  166. }
  167. /*****************************************************************************
  168.  * Bounce the ball.
  169.  *****************************************************************************/
  170. void BounceBall()
  171. {
  172.    GLfloat sign;
  173.    GLfloat deg;
  174.    if ( ball_x >  (BOUNCE_WIDTH/2 + WALL_R_OFFSET ) )
  175.    {
  176.       ball_x_inc = -0.5 - 0.75 * (GLfloat)random() / (GLfloat)RAND_MAX;
  177.       deg_rot_y_inc = -deg_rot_y_inc;
  178.    }
  179.    if ( ball_x < -(BOUNCE_HEIGHT/2 + WALL_L_OFFSET) )
  180.    {
  181.       ball_x_inc =  0.5 + 0.75 * (GLfloat)random() / (GLfloat)RAND_MAX;
  182.       deg_rot_y_inc = -deg_rot_y_inc;
  183.    }
  184.    ball_x += ball_x_inc/60; // test /10
  185.    
  186.    glTranslatef( ball_x/10, 0.0, 0.0 );
  187.    if ( ball_y >  BOUNCE_HEIGHT/2      ) ball_y_inc = -0.75 - 1.0 * (GLfloat)random() / (GLfloat)RAND_MAX;
  188.    if ( ball_y < -BOUNCE_HEIGHT/2*0.85 ) ball_y_inc =  0.75 + 1.0 * (GLfloat)random() / (GLfloat)RAND_MAX;
  189.    ball_y += ball_y_inc/60; // test /10
  190.    glTranslatef( 0.0, ball_y/10, 0.0 );
  191.   /*
  192.    * Simulate the effects of gravity on Y movement.
  193.    */
  194.    if ( ball_y_inc < 0 ) sign = -1.0; else sign = 1.0;
  195.    deg = (ball_y + BOUNCE_HEIGHT/2) * 90 / BOUNCE_HEIGHT;
  196.    if ( deg > 80 ) deg = 80;
  197.    if ( deg < 10 ) deg = 10;
  198.    ball_y_inc = sign * 4.0 * sin_deg( deg );
  199.   /*
  200.    * Offset the shadow.
  201.    */
  202.    if ( drawBallHow == DRAW_BALL_SHADOW )
  203.    {
  204.       glTranslatef( SHADOW_OFFSET_X, SHADOW_OFFSET_Y, SHADOW_OFFSET_Z );
  205.    }
  206. }
  207. /*****************************************************************************
  208.  * Draw a faceted latitude band of the Boing ball.
  209.  *
  210.  * Parms: long_lo, long_hi
  211.  * Low and high longitudes of slice, resp.
  212.  *****************************************************************************/
  213. void DrawBoingBallBand( GLfloat long_lo,
  214.                         GLfloat long_hi )
  215. {
  216.    vertex_t vert_ne; /* "ne" means south-east, so on */
  217.    vertex_t vert_nw;
  218.    vertex_t vert_sw;
  219.    vertex_t vert_se;
  220.    vertex_t vert_norm;
  221.    GLfloat lat_deg;
  222.    static int colorToggle = 0;
  223.   /*
  224.    * Iterate thru the points of a latitude circle.
  225.    * A latitude circle is a 2D set of X,Z points.
  226.    */
  227.    for ( lat_deg = 0;
  228.          lat_deg <= (360 - STEP_LATITUDE);
  229.          lat_deg += STEP_LATITUDE )
  230.    {
  231.      /*
  232.       * Color this polygon with red or white.
  233.       */
  234.       if ( colorToggle )
  235.          glColor3f( RGB_RED );
  236.       else
  237.          glColor3f( RGB_WHITE );
  238. #if 0
  239.       if ( lat_deg >= 180 )
  240.          if ( colorToggle )
  241.             glColor3f( 0.1, 0.8, 0.1 );
  242.          else
  243.             glColor3f( 0.5, 0.5, 0.95 );
  244. #endif
  245.       colorToggle = ! colorToggle;
  246.      /*
  247.       * Change color if drawing shadow.
  248.       */
  249.       if ( drawBallHow == DRAW_BALL_SHADOW )
  250.          glColor3f( RGB_SHADOW );
  251.      /*
  252.       * Assign each Y.
  253.       */
  254.       vert_ne.y = vert_nw.y = cos_deg(long_hi) * RADIUS;
  255.       vert_sw.y = vert_se.y = cos_deg(long_lo) * RADIUS;
  256.      /*
  257.       * Assign each X,Z with sin,cos values scaled by latitude radius indexed by longitude.
  258.       * Eg, long=0 and long=180 are at the poles, so zero scale is sin(longitude),
  259.       * while long=90 (sin(90)=1) is at equator.
  260.       */
  261.       vert_ne.x = cos_deg( lat_deg                 ) * (RADIUS * sin_deg( long_lo + STEP_LONGITUDE ));
  262.       vert_se.x = cos_deg( lat_deg                 ) * (RADIUS * sin_deg( long_lo                  ));
  263.       vert_nw.x = cos_deg( lat_deg + STEP_LATITUDE ) * (RADIUS * sin_deg( long_lo + STEP_LONGITUDE ));
  264.       vert_sw.x = cos_deg( lat_deg + STEP_LATITUDE ) * (RADIUS * sin_deg( long_lo                  ));
  265.       vert_ne.z = sin_deg( lat_deg                 ) * (RADIUS * sin_deg( long_lo + STEP_LONGITUDE ));
  266.       vert_se.z = sin_deg( lat_deg                 ) * (RADIUS * sin_deg( long_lo                  ));
  267.       vert_nw.z = sin_deg( lat_deg + STEP_LATITUDE ) * (RADIUS * sin_deg( long_lo + STEP_LONGITUDE ));
  268.       vert_sw.z = sin_deg( lat_deg + STEP_LATITUDE ) * (RADIUS * sin_deg( long_lo                  ));
  269.      /*
  270.       * Draw the facet.
  271.       */
  272.       glBegin( GL_POLYGON );
  273.       CrossProduct( vert_ne, vert_nw, vert_sw, vert_norm );
  274.       glNormal3f( vert_norm.x, vert_norm.y, vert_norm.z );
  275.       glVertex3f( vert_ne.x, vert_ne.y, vert_ne.z );
  276.       glVertex3f( vert_nw.x, vert_nw.y, vert_nw.z );
  277.       glVertex3f( vert_sw.x, vert_sw.y, vert_sw.z );
  278.       glVertex3f( vert_se.x, vert_se.y, vert_se.z );
  279.       glEnd();
  280.    }
  281.   /*
  282.    * Toggle color so that next band will opposite red/white colors than this one.
  283.    */
  284.    colorToggle = ! colorToggle;
  285.   /*
  286.    * This circular band is done.
  287.    */
  288.    return;
  289. }
  290. /*****************************************************************************
  291.  * Draw the purple grid of lines, behind the Boing ball.
  292.  * When the Workbench is dropped to the bottom, Boing shows 12 rows.
  293.  *****************************************************************************/
  294. void DrawGrid()
  295. {
  296.    int row, col;
  297.    const int rowTotal = 12; /* must be divisible by 2 */
  298.    const int colTotal = rowTotal; /* must be same as rowTotal */
  299.    const GLfloat widthLine = 2.0; /* should be divisible by 2 */
  300.    const GLfloat sizeCell = GRID_SIZE / rowTotal;
  301.    const GLfloat z_offset = -40.0;
  302.    GLfloat xl, xr;
  303.    GLfloat yt, yb;
  304.    glPushMatrix();
  305.    glDisable( GL_CULL_FACE );
  306.   /*
  307.    * Another relative Z translation to separate objects.
  308.    */
  309.    glTranslatef( 0.0, 0.0, DIST_BALL/10 );
  310.   /*
  311.    * Draw vertical lines (as skinny 3D rectangles).
  312.    */
  313.    for ( col = 0; col <= colTotal; col++ )
  314.    {
  315.      /*
  316.       * Compute co-ords of line.
  317.       */
  318.       xl = -GRID_SIZE / 2 + col * sizeCell;
  319.       xr = xl + widthLine;
  320.       yt =  GRID_SIZE / 2;
  321.       yb = -GRID_SIZE / 2 - widthLine;
  322.       glBegin( GL_POLYGON );
  323.       glColor3f( RGB_PURPLE ); /* purple */
  324.       glVertex3f( xr, yt, z_offset ); /* NE */
  325.       glVertex3f( xl, yt, z_offset ); /* NW */
  326.       glVertex3f( xl, yb, z_offset ); /* SW */
  327.       glVertex3f( xr, yb, z_offset ); /* SE */
  328.       glEnd();
  329.    }
  330.   /*
  331.    * Draw horizontal lines (as skinny 3D rectangles).
  332.    */
  333.    for ( row = 0; row <= rowTotal; row++ )
  334.    {
  335.      /*
  336.       * Compute co-ords of line.
  337.       */
  338.       yt = GRID_SIZE / 2 - row * sizeCell;
  339.       yb = yt - widthLine;
  340.       xl = -GRID_SIZE / 2;
  341.       xr =  GRID_SIZE / 2 + widthLine;
  342.       glBegin( GL_POLYGON );
  343.       glColor3f( RGB_PURPLE ); /* purple */
  344.       glVertex3f( xr, yt, z_offset ); /* NE */
  345.       glVertex3f( xl, yt, z_offset ); /* NW */
  346.       glVertex3f( xl, yb, z_offset ); /* SW */
  347.       glVertex3f( xr, yb, z_offset ); /* SE */
  348.       glEnd();
  349.    }
  350.    glPopMatrix();
  351.    return;
  352. }
  353. }