home *** CD-ROM | disk | FTP | other *** search
/ Magazyn Exec 5 / CD_Magazyn_EXEC_nr_5.iso / eXec / MiniGL / gears.c next >
C/C++ Source or Header  |  2000-11-30  |  18KB  |  806 lines

  1. /*
  2.     W komentarzach jest straszny baîagan: czëôê pochodzi z oryginaîu (po
  3.     angielsku), pozostaîe - dotyczâce róûnic miëdzy MGL i GLUT - sâ moje
  4.     (po polsku).
  5. */
  6.  
  7.  
  8.  
  9.  
  10. #include <stdlib.h>
  11. #include <string.h>
  12.  
  13. #ifdef __USE_GLUT__
  14. #include <gl/glut.h>
  15. #else
  16. #include <mgl/gl.h>
  17. #endif
  18.  
  19. #include <math.h>
  20. /* Some <math.h> files do not define M_PI... */
  21. #ifndef M_PI
  22. #define M_PI 3.14159265
  23. #endif
  24. #include <stdio.h>
  25.  
  26. /* For portability... */
  27. #undef fcos
  28. #undef fsin
  29. #undef fsqrt
  30. #define fcos  cos
  31. #define fsin  sin
  32. #define fsqrt sqrt
  33.  
  34.  
  35.  
  36.  
  37. static double d_near = 1.0;
  38. static double d_far = 2000;
  39.  
  40.  
  41. int show = 1;
  42.  
  43.  
  44. typedef struct {
  45.   float rad, wid;
  46. } Profile;
  47.  
  48.  
  49. int circle_subdiv;
  50. #define MIN_SUBDIV 30
  51.  
  52.  
  53. GLboolean bEnvMap = GL_TRUE;
  54.  
  55.  
  56.  
  57.  
  58. void flat_face( float ir, float or, float wd );
  59. void draw_inside( float w1, float w2, float rad );
  60. void draw_outside( float w1, float w2, float rad );
  61. void tooth_side( int nt, float ir, float or, float tp, float tip, float wd );
  62.  
  63.  
  64.  
  65.  
  66. #ifndef __USE_GLUT__
  67. /*  MiniGL wymaga doîâczenia do kaûdego programu funkcji 'kprintf'.
  68.     Powinna ona wypisywaê tekst do portu szeregowego (lub Sushi, jeûeli
  69.     jest uruchomiony). W tym programiku jest to zupelnie niepotrzebne.  */
  70.  
  71. int kprintf( char *format, ... )
  72. {
  73.   return 1;
  74. }
  75. #endif
  76.  
  77.  
  78.  
  79.  
  80. GLubyte *LoadPPM( char *name, GLint *w, GLint *h )
  81. {
  82.   int i;
  83.   unsigned long x, y;
  84.   FILE *f;
  85.   GLubyte *where;
  86.  
  87.   f = fopen( name, "r" );
  88.   if( !f )
  89.   {
  90.     *w = 0; *h=0;
  91.     return NULL;
  92.   }
  93.   #ifndef __STORM__
  94.   i = fscanf( f, "P6\n%ld %ld\n255\n",&x, &y );
  95.   #else
  96.   i = fscanf( f, "P6\n%ld\n%ld\n255\n", &x, &y );
  97.   #endif
  98.  
  99.   if( i!= 2 )
  100.   {
  101.     printf( "Error scanning PPM header\n" );
  102.     fclose( f );
  103.     *w = 0; *h = 0;
  104.     return NULL;
  105.   }
  106.  
  107.   *w = x;
  108.   *h = y;
  109.  
  110.   where = malloc( x * y * 4 );
  111.   if( !where )
  112.   {
  113.     printf( "Error out of Memory\n" );
  114.     fclose( f );
  115.     *w = 0; *h = 0;
  116.     return NULL;
  117.   }
  118.  
  119.   i = fread( where, 1, x * y * 3, f );
  120.   fclose(f);
  121.  
  122.   if( i != x * y * 3 )
  123.   {
  124.     printf( "Error while reading file\n" );
  125.     free( where );
  126.     *w = 0; *h = 0;
  127.     return NULL;
  128.   }
  129.  
  130.   return where;
  131. }
  132.  
  133.  
  134.  
  135.  
  136. GLboolean TexInit( char *name )
  137. {
  138.   GLubyte *tmap;
  139.   GLint x,y;
  140.  
  141.   /*  Te dwie funkcje nie sâ konieczne w przypadku uûywania GLUT,
  142.       bo wartoôci domyôlne (UN)PACK_ALIGNMENT sâ ok. Jeûeli nie
  143.       bëdzie ich w programie uûywajâcym MiniGL to moûemy zamiast
  144.       tekstury dostaê ômieci. */
  145.   glPixelStorei( GL_UNPACK_ALIGNMENT, 1 );
  146.   glPixelStorei( GL_PACK_ALIGNMENT, 1 );
  147.  
  148.   if( !name )
  149.   {
  150.     tmap = LoadPPM( "chrome.ppm",&x, &y );
  151.   }
  152.   else
  153.   {
  154.     tmap = LoadPPM( name, &x, &y );
  155.   }
  156.  
  157.   if( !tmap )
  158.     return GL_FALSE;
  159.  
  160.   glBindTexture( GL_TEXTURE_2D, 1 );
  161.   glTexImage2D( GL_TEXTURE_2D,
  162.                 0,
  163.                 3,
  164.                 x, y,
  165.                 0,
  166.                 GL_RGB,
  167.                 GL_UNSIGNED_BYTE, tmap );
  168.   free(tmap);
  169.  
  170.   glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
  171.   glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
  172.  
  173.   glEnable( GL_TEXTURE_2D );
  174.   glEnable( GL_TEXTURE_GEN_S );
  175.   glEnable( GL_TEXTURE_GEN_T );
  176.   glTexGeni( GL_S, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP );
  177.   glTexGeni( GL_T, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP );
  178.  
  179.   return GL_TRUE;
  180. }
  181.  
  182.  
  183.  
  184.  
  185. void gear( int nt, float wd, float ir, float or, float tp, float tip, int ns, Profile *ip )
  186. {
  187.   /**
  188.    * nt - number of teeth 
  189.    * wd - width of gear at teeth
  190.    * ir - inside radius absolute scale
  191.    * or - radius at outside of wheel (tip of tooth) ratio of ir
  192.    * tp - ratio of tooth in slice of circle (0..1] (1 = teeth are touching at base)
  193.    * tip - ratio of tip of tooth (0..tp] (cant be wider that base of tooth)
  194.    * ns - number of elements in wheel width profile
  195.    * *ip - list of float pairs {start radius, width, ...} (width is ratio to wd)
  196.    *
  197.    */
  198.  
  199.   /* gear lying on xy plane, z for width. all normals calulated (normalized) */
  200.  
  201.   float prev;
  202.   int k, t;
  203.  
  204.   /* estimat # times to divide circle */
  205.   if( nt <= 0 )
  206.     circle_subdiv = MIN_SUBDIV;
  207.   else
  208.   {
  209.     /* lowest multiple of number of teeth */
  210.     circle_subdiv = nt;
  211.     while( circle_subdiv < MIN_SUBDIV )
  212.       circle_subdiv += nt;
  213.   }
  214.  
  215.   /* --- draw wheel face --- */
  216.  
  217.   /* draw horzontal, vertical faces for each section. if first
  218.      section radius not zero, use wd for 0.. first if ns == 0
  219.      use wd for whole face. last width used to edge.  */
  220.  
  221.   if( ns <= 0 )
  222.   {
  223.     flat_face( 0.0, ir, wd );
  224.   }
  225.   else
  226.   {
  227.     /* draw first flat_face, then continue in loop */
  228.     if( ip[0].rad > 0.0 )
  229.     {
  230.       flat_face( 0.0, ip[0].rad * ir, wd );
  231.       prev = wd;
  232.       t = 0;
  233.     }
  234.     else
  235.     {
  236.       flat_face( 0.0, ip[1].rad * ir, ip[0].wid * wd );
  237.       prev = ip[0].wid;
  238.       t = 1;
  239.     }
  240.     for( k = t ; k < ns ; k++ )
  241.     {
  242.       if( prev < ip[k].wid )
  243.       {
  244.         draw_inside( prev * wd, ip[k].wid * wd, ip[k].rad * ir );
  245.       }
  246.       else
  247.       {
  248.         draw_outside( prev * wd, ip[k].wid * wd, ip[k].rad * ir );
  249.       }
  250.       prev = ip[k].wid;
  251.       /* - draw to edge of wheel, add final face if needed - */
  252.       if( k == ns - 1 )
  253.       {
  254.         flat_face( ip[k].rad * ir, ir, ip[k].wid * wd );
  255.  
  256.         /* now draw side to match tooth rim */
  257.         if( ip[k].wid < 1.0 )
  258.         {
  259.           draw_inside( ip[k].wid * wd, wd, ir );
  260.         }
  261.         else
  262.         {
  263.           draw_outside( ip[k].wid * wd, wd, ir );
  264.         }
  265.       }
  266.       else
  267.       {
  268.         flat_face( ip[k].rad * ir, ip[k + 1].rad * ir, ip[k].wid * wd );
  269.       }
  270.     }
  271.   }
  272.  
  273.   /* --- tooth side faces --- */
  274.   tooth_side( nt, ir, or, tp, tip, wd );
  275.  
  276.   /* --- tooth hill surface --- */
  277. }
  278.  
  279.  
  280.  
  281.  
  282. void tooth_side( int nt, float ir, float or, float tp, float tip, float wd )
  283. {
  284.   float i;
  285.   float end = 2.0 * M_PI / nt;
  286.   float x[6], y[6];
  287.   float s[3], c[3];
  288.  
  289.   or = or * ir;         /* or is really a ratio of ir */
  290.   for( i = 0 ; i < 2.0 * M_PI - end / 4.0 ; i += end )
  291.   {
  292.     c[0] = fcos( i );
  293.     s[0] = fsin( i );
  294.     c[1] = fcos( i + end * (0.5 - tip / 2) );
  295.     s[1] = fsin( i + end * (0.5 - tip / 2) );
  296.     c[2] = fcos( i + end * (0.5 + tp / 2) );
  297.     s[2] = fsin( i + end * (0.5 + tp / 2) );
  298.  
  299.     x[0] = ir * c[0];
  300.     y[0] = ir * s[0];
  301.     x[5] = ir * fcos( i + end );
  302.     y[5] = ir * fsin( i + end );
  303.     /* ---treat veritices 1,4 special to match strait edge of face */
  304.     x[1] = x[0] + (x[5] - x[0]) * (0.5 - tp / 2);
  305.     y[1] = y[0] + (y[5] - y[0]) * (0.5 - tp / 2);
  306.     x[4] = x[0] + (x[5] - x[0]) * (0.5 + tp / 2);
  307.     y[4] = y[0] + (y[5] - y[0]) * (0.5 + tp / 2);
  308.     x[2] = or * fcos( i + end * (0.5 - tip / 2) );
  309.     y[2] = or * fsin( i + end * (0.5 - tip / 2) );
  310.     x[3] = or * fcos( i + end * (0.5 + tip / 2) );
  311.     y[3] = or * fsin( i + end * (0.5 + tip / 2) );
  312.  
  313.     /* draw face trapezoids as 2 tmesh */
  314.     glNormal3f( 0.0, 0.0, 1.0 );
  315.     glBegin( GL_TRIANGLE_STRIP );
  316.     glVertex3f( x[2], y[2], wd / 2 );
  317.     glVertex3f( x[1], y[1], wd / 2 );
  318.     glVertex3f( x[3], y[3], wd / 2 );
  319.     glVertex3f( x[4], y[4], wd / 2 );
  320.     glEnd();
  321.  
  322.     glNormal3f( 0.0, 0.0, -1.0 );
  323.     glBegin( GL_TRIANGLE_STRIP );
  324.     glVertex3f( x[2], y[2], -wd / 2 );
  325.     glVertex3f( x[1], y[1], -wd / 2 );
  326.     glVertex3f( x[3], y[3], -wd / 2 );
  327.     glVertex3f( x[4], y[4], -wd / 2 );
  328.     glEnd();
  329.  
  330.     /* draw inside rim pieces */
  331.     glNormal3f( c[0], s[0], 0.0 );
  332.     glBegin( GL_TRIANGLE_STRIP );
  333.     glVertex3f( x[0], y[0], -wd / 2 );
  334.     glVertex3f( x[1], y[1], -wd / 2 );
  335.     glVertex3f( x[0], y[0], wd / 2 );
  336.     glVertex3f( x[1], y[1], wd / 2 );
  337.     glEnd();
  338.  
  339.     /* draw up hill side */
  340.     {
  341.       float a, b, n;
  342.       /* calculate normal of face */
  343.       a = x[2] - x[1];
  344.       b = y[2] - y[1];
  345.       n = 1.0 / fsqrt( a * a + b * b );
  346.       a = a * n;
  347.       b = b * n;
  348.       glNormal3f( b, -a, 0.0 );
  349.     }
  350.     glBegin( GL_TRIANGLE_STRIP);
  351.     glVertex3f( x[1], y[1], -wd / 2 );
  352.     glVertex3f( x[2], y[2], -wd / 2 );
  353.     glVertex3f( x[1], y[1], wd / 2 );
  354.     glVertex3f( x[2], y[2], wd / 2 );
  355.     glEnd();
  356.     /* draw top of hill */
  357.     glNormal3f( c[1], s[1], 0.0 );
  358.     glBegin( GL_TRIANGLE_STRIP );
  359.     glVertex3f( x[2], y[2], -wd / 2 );
  360.     glVertex3f( x[3], y[3], -wd / 2 );
  361.     glVertex3f( x[2], y[2], wd / 2 );
  362.     glVertex3f( x[3], y[3], wd / 2 );
  363.     glEnd();
  364.  
  365.     /* draw down hill side */
  366.     {
  367.       float a, b, c;
  368.       /* calculate normal of face */
  369.       a = x[4] - x[3];
  370.       b = y[4] - y[3];
  371.       c = 1.0 / fsqrt( a * a + b * b );
  372.       a = a * c;
  373.       b = b * c;
  374.       glNormal3f( b, -a, 0.0 );
  375.     }
  376.     glBegin( GL_TRIANGLE_STRIP );
  377.     glVertex3f( x[3], y[3], -wd / 2 );
  378.     glVertex3f( x[4], y[4], -wd / 2 );
  379.     glVertex3f( x[3], y[3], wd / 2 );
  380.     glVertex3f( x[4], y[4], wd / 2 );
  381.     glEnd();
  382.     /* inside rim part */
  383.     glNormal3f( c[2], s[2], 0.0 );
  384.     glBegin( GL_TRIANGLE_STRIP );
  385.     glVertex3f( x[4], y[4], -wd / 2 );
  386.     glVertex3f( x[5], y[5], -wd / 2 );
  387.     glVertex3f( x[4], y[4], wd / 2 );
  388.     glVertex3f( x[5], y[5], wd / 2 );
  389.     glEnd();
  390.   }
  391. }
  392.  
  393.  
  394.  
  395.  
  396. void flat_face( float ir, float or, float wd )
  397. {
  398.   int i;
  399.   float c, s;
  400.   float w;
  401.  
  402.   /* draw each face (top & bottom ) * */
  403.  
  404.   if( wd == 0.0 )
  405.     return;
  406.   for( w = wd / 2 ; w > -wd ; w -= wd )
  407.   {
  408.     if(w > 0.0)
  409.       glNormal3f( 0.0, 0.0, 1.0 );
  410.     else
  411.       glNormal3f( 0.0, 0.0, -1.0 );
  412.  
  413.     if( ir == 0.0 )
  414.     {
  415.       /* draw as t-fan */
  416.       glBegin( GL_TRIANGLE_FAN );
  417.       glVertex3f( 0.0, 0.0, w );  /* center */
  418.       glVertex3f( or, 0.0, w );
  419.       for( i = 1 ; i < circle_subdiv ; i++ )
  420.       {
  421.         glVertex3f( fcos( 2.0 * M_PI * i / (float)circle_subdiv ) * or,
  422.                     fsin( 2.0 * M_PI * i / (float)circle_subdiv ) * or,
  423.                     w );
  424.       }
  425.       glVertex3f( or, 0.0, w );
  426.       glEnd();
  427.     }
  428.     else
  429.     {
  430.       /* draw as tmesh */
  431.       glBegin( GL_TRIANGLE_STRIP );
  432.       glVertex3f( or, 0.0, w );
  433.       glVertex3f( ir, 0.0, w );
  434.       for( i = 1 ; i < circle_subdiv ; i++)
  435.       {
  436.         s = fsin( 2.0 * M_PI * i / (float)circle_subdiv );
  437.         c = fcos( 2.0 * M_PI * i / (float)circle_subdiv );
  438.         glVertex3f( c * or, s * or, w );
  439.         glVertex3f( c * ir, s * ir, w );
  440.       }
  441.       glVertex3f( or, 0.0, w );
  442.       glVertex3f( ir, 0.0, w );
  443.       glEnd();
  444.     }
  445.   }
  446. }
  447.  
  448.  
  449.  
  450.  
  451. void draw_inside( float w1, float w2, float rad )
  452. {
  453.   int i, j;
  454.   float c, s;
  455.   if( w1 == w2 )
  456.     return;
  457.  
  458.   w1 = w1 / 2;
  459.   w2 = w2 / 2;
  460.   for( j = 0 ; j < 2 ; j++ )
  461.   {
  462.     if( j == 1 )
  463.     {
  464.        w1 = -w1;
  465.        w2 = -w2;
  466.     }
  467.     glBegin( GL_TRIANGLE_STRIP );
  468.     glNormal3f( -1.0, 0.0, 0.0 );
  469.     glVertex3f( rad, 0.0, w1 );
  470.     glVertex3f( rad, 0.0, w2 );
  471.     for( i = 1 ; i < circle_subdiv ; i++ )
  472.     {
  473.       c = fcos( 2.0 * M_PI * i / circle_subdiv );
  474.       s = fsin( 2.0 * M_PI * i / circle_subdiv );
  475.       glNormal3f( -c, -s, 0.0 );
  476.       glVertex3f( c * rad, s * rad, w1 );
  477.       glVertex3f( c * rad, s * rad, w2 );
  478.     }
  479.     glNormal3f( -1.0, 0.0, 0.0 );
  480.     glVertex3f( rad, 0.0, w1 );
  481.     glVertex3f( rad, 0.0, w2 );
  482.     glEnd();
  483.   }
  484. }
  485.  
  486.  
  487.  
  488.  
  489. void draw_outside( float w1, float w2, float rad )
  490. {
  491.   int i, j;
  492.   float c, s;
  493.   if( w1 == w2 )
  494.     return;
  495.  
  496.   w1 = w1 / 2;
  497.   w2 = w2 / 2;
  498.   for( j = 0 ; j < 2 ; j++ )
  499.   {
  500.     if( j == 1 )
  501.     {
  502.       w1 = -w1;
  503.       w2 = -w2;
  504.     }
  505.     glBegin( GL_TRIANGLE_STRIP );
  506.     glNormal3f( 1.0, 0.0, 0.0 );
  507.     glVertex3f( rad, 0.0, w1 );
  508.     glVertex3f( rad, 0.0, w2 );
  509.     for( i = 1 ; i < circle_subdiv ; i++ )
  510.     {
  511.       c = fcos( 2.0 * M_PI * i / (float)circle_subdiv );
  512.       s = fsin( 2.0 * M_PI * i / (float)circle_subdiv );
  513.       glNormal3f( c, s, 0.0 );
  514.       glVertex3f( c * rad, s * rad, w1 );
  515.       glVertex3f( c * rad, s * rad, w2 );
  516.     }
  517.     glNormal3f( 1.0, 0.0, 0.0 );
  518.     glVertex3f( rad, 0.0, w1 );
  519.     glVertex3f( rad, 0.0, w2 );
  520.     glEnd();
  521.   }
  522. }
  523.  
  524.  
  525.  
  526.  
  527. Profile gear_profile[] =
  528. {
  529.   { 0.000, 0.0 },
  530.   { 0.300, 7.0 },
  531.   { 0.340, 0.4 },
  532.   { 0.550, 0.64 },
  533.   { 0.600, 0.4 },
  534.   { 0.950, 1.0 }
  535. };
  536.  
  537. float a1 = 27.0;
  538. float a2 = 67.0;
  539. float a3 = 47.0;
  540. float a4 = 87.0;
  541. float i1 = 1.2;
  542. float i2 = 3.1;
  543. float i3 = 2.3;
  544. float i4 = 1.1;
  545.  
  546. void oneFrame( void )
  547. {
  548.   #ifndef __USE_GLUT__
  549.   /*  Jeûeli uûywamy MiniGL, to konieczne jest zatroszczenie sië o 
  550.       blokowanie dostëpu do ukîadu 3D. W przypadku OpenGL/StormMESY
  551.       jest to robione automatycznie  */
  552.   mglLockDisplay();
  553.   #endif
  554.   glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
  555.  
  556.   if( show & 1 )
  557.   {
  558.     glPushMatrix();
  559.     glTranslatef( 0.0, 0.0, -4.0 );
  560.     glRotatef( a3, 1.0, 1.0, 1.0 );
  561.     glRotatef( a4, 0.0, 0.0, -1.0 );
  562.     glTranslatef( 0.14, 0.2, 0.0 );
  563.     glTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE );
  564.     gear( 40,
  565.           0.4, 2.0, 1.1,
  566.           0.8, 0.4,
  567.           sizeof(gear_profile) / sizeof(Profile), gear_profile);
  568.     glPopMatrix();
  569.   }
  570.  
  571.   if( show & 2 )
  572.   {
  573.     glPushMatrix();
  574.     glTranslatef( 0.1, 0.2, -3.8 );
  575.     glRotatef( a2, -4.0, 2.0, -1.0 );
  576.     glRotatef( a1, 1.0, -3.0, 1.0 );
  577.     glTranslatef( 0.0, -0.2, 0.0 );
  578.     glTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE );
  579.     glColor3f( 1.0, 0.8, 0.0 );
  580.     gear( 36,
  581.           0.4, 2.0, 1.1,
  582.           0.7, 0.2,
  583.           sizeof(gear_profile) / sizeof(Profile), gear_profile);
  584.     glPopMatrix();
  585.   }
  586.  
  587.   a1 += i1;
  588.   if( a1 > 360.0 )
  589.     a1 -= 360.0;
  590.   if( a1 < 0.0 )
  591.     a1 -= 360.0;
  592.   a2 += i2;
  593.   if( a2 > 360.0 )
  594.     a2 -= 360.0;
  595.   if( a2 < 0.0 )
  596.     a2 -= 360.0;
  597.   a3 += i3;
  598.   if( a3 > 360.0 )
  599.     a3 -= 360.0;
  600.   if( a3 < 0.0 )
  601.     a3 -= 360.0;
  602.   a4 += i4;
  603.   if( a4 > 360.0 )
  604.     a4 -= 360.0;
  605.   if( a4 < 0.0 )
  606.     a4 -= 360.0;
  607.  
  608.   /*  Po narysowaniu caîej klatki animacji wyôwietlamy jâ
  609.       i w przypadku MiniGL odblokowujemy ukîad 3D  */
  610.   #ifdef __USE_GLUT__
  611.   glutSwapBuffers();
  612.   #else
  613.   mglUnlockDisplay();
  614.   mglSwitchDisplay();
  615.   #endif
  616. }
  617.  
  618.  
  619.  
  620.  
  621. #ifdef __USE_GLUT__
  622. void idle( void )
  623. {
  624.   glutPostRedisplay();
  625. }
  626. #endif
  627.  
  628.  
  629.  
  630.  
  631. void myReshape( int w, int h )
  632. {
  633.   glViewport( 0, 0, w, h );
  634.   glMatrixMode( GL_PROJECTION );
  635.   glLoadIdentity();
  636.   glFrustum( -1.0, 1.0, -1.0, 1.0, d_near, d_far );
  637.   glMatrixMode( GL_MODELVIEW );
  638.   glLoadIdentity();
  639.   glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
  640. }
  641.  
  642.  
  643.  
  644.  
  645. void myinit( int w, int h )
  646. {
  647.   glClearColor( 0.0, 0.0, 0.0, 0.0 );
  648.   myReshape( w, h );
  649.   glEnable( GL_DEPTH_TEST );
  650.   glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
  651. }
  652.  
  653.  
  654.  
  655.  
  656. /*  Funkcja obsîugi klawiatury w MiniGL róûni sië nieco
  657.     w stosunku do GLUT, na szczeôcie kody klawiszy sâ takie same  */
  658.  
  659. #ifdef __USE_GLUT__
  660. void keys( unsigned char c, int x, int y )
  661. #else
  662. void keys( char c )
  663. #endif
  664. {
  665.   switch( c )
  666.   {
  667.     case 27:  {
  668.                 /*  W przypadku GLUT moûemy zrobiê po prostu 'exit'
  669.                     - biblioteka sama zatroszczy sië o zamkniëcia okna,
  670.                     usuniëcie kontekstu itd. W MiniGL uûywamy 'mglExit'
  671.                     sprzâtamy po sobie (zobacz na koïcu funkcji 'main').  */
  672.                 #ifdef __USE_GLUT__
  673.                 exit( 0 );
  674.                 #else
  675.                 mglExit();
  676.                 #endif
  677.               };
  678.  
  679.     case '1': show = 1; break;
  680.  
  681.     case '2': show = 2; break;
  682.  
  683.     case '3': show = 3; break;
  684.  
  685.     case 'e': if( bEnvMap == GL_TRUE )
  686.               {
  687.                 bEnvMap = GL_FALSE;
  688.                 glDisable( GL_TEXTURE_GEN_S );
  689.                 glDisable( GL_TEXTURE_GEN_T );
  690.               }
  691.               else
  692.               {
  693.                 bEnvMap = GL_TRUE;
  694.                 glEnable( GL_TEXTURE_GEN_S );
  695.                 glEnable( GL_TEXTURE_GEN_T );
  696.               };
  697.               break;
  698.     case 's': {
  699.                 /*  Zapis obrazka do pliku 'screenshot.ppm',
  700.                     funkcja ta jest dostëpna tylko w MiniGL  */
  701.                 #ifndef __USE_GLUT__
  702.                 mglWriteShotPPM( "screenshot.ppm" );
  703.                 #endif
  704.               };
  705.               break;
  706.   }
  707. }
  708.  
  709.  
  710.  
  711.  
  712. int main( int argc, char *argv[] )
  713. {
  714.   GLint width = 640; GLint height = 480;
  715.   int i;
  716.   char *name = 0;
  717.   GLboolean windowmode = GL_FALSE;
  718.  
  719.   for( i = 1 ; i < argc ; i++)
  720.   {
  721.     if( 0 == stricmp( argv[i], "-width" ) )
  722.     {
  723.       i++;
  724.       width = atoi( argv[i] );
  725.     }
  726.     else
  727.       if( 0 == stricmp( argv[i], "-height" ) )
  728.       {
  729.         i++;
  730.         height = atoi( argv[i] );
  731.       }
  732.       else
  733.         if( 0 == stricmp( argv[i], "-envmap" ) )
  734.         {
  735.           i++;
  736.           name = argv[i];
  737.         }
  738.         else
  739.           if( 0 == stricmp( argv[i], "-window" ) )
  740.           {
  741.             windowmode = GL_TRUE;
  742.           };
  743.   };
  744.  
  745.   /*  Inicjalizacja biblioteki, utworzenie kontekstu i okna.
  746.       To widoczne sâ najistotniejsze róûnice miëdzy MiniGL
  747.       a OpenGL/GLUT  */
  748.   #ifndef __USE_GLUT__
  749.   MGLInit();
  750.   mglChooseWindowMode( windowmode );
  751.   mglChooseVertexBufferSize( 1000 );
  752.   mglChooseNumberOfBuffers( 3 );
  753.   mglChoosePixelDepth( 16 );
  754.   mglCreateContext( 0, 0, width, height );
  755.   mglEnableSync( GL_FALSE );
  756.   #else
  757.   glutInit( &argc, argv );
  758.   glutInitDisplayMode( GLUT_RGB | GLUT_DEPTH | GLUT_DOUBLE );
  759.   if( !windowmode )
  760.     glutEnterGameMode();
  761.   else
  762.   {
  763.     glutInitWindowSize( width, height );
  764.     glutCreateWindow( "" );
  765.   };
  766.   #endif
  767.  
  768.   if( TexInit(name) )
  769.   {
  770.     glClearColor( 0.0, 0.0, 0.0, 1.0 );
  771.     glDisable( GL_CULL_FACE );
  772.  
  773.     /*  Dostëpne tylko w MiniGL, wymusza uûycie szybszej
  774.         procedury mnoûenia wektora przez macierz  */
  775.     #ifndef __USE_GLUT__
  776.     glHint( MGL_W_ONE_HINT, GL_FASTEST );
  777.     #endif
  778.  
  779.     myinit( width, height );
  780.  
  781.     /*  Definiowanie callback functions i rozpoczëcie gîównej pëtli  */
  782.     #ifdef __USE_GLUT__
  783.     glutDisplayFunc( oneFrame );
  784.     glutReshapeFunc( myReshape );
  785.     glutIdleFunc( idle );
  786.     glutKeyboardFunc( keys );
  787.     glutMainLoop();
  788.     #else
  789.     mglLockMode( MGL_LOCK_MANUAL );
  790.     mglIdleFunc( oneFrame );
  791.     mglKeyFunc( keys );
  792.     mglMainLoop();
  793.     #endif
  794.   }
  795.   else
  796.     printf("Can't find texture %s\n", name);
  797.  
  798.   /*  Koïcowe porzâdki - konieczne tylko w MiniGL  */
  799.   #ifndef __USE_GLUT__
  800.   mglDeleteContext();
  801.   MGLTerm();
  802.   #endif
  803.  
  804.   return 0;             /* ANSI C requires main to return int. */
  805. }
  806.