home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / local.zip / local.c
Text File  |  1994-09-12  |  11KB  |  299 lines

  1. /* OpenGL on OS/2 example, showing how to use the (local) lighting   */
  2. /* capabilities of OpenGL. The code is partially derived from the    */
  3. /* OpenGL example (sampogl.c) found in Compuserve's OS2DF2 (lib 12). */
  4. /*                                                                   */
  5. /* The programs shows a flat polygon in the XZ plane lighted by a    */
  6. /* source moving between 0.2 and 0.9 along the Y axis.               */
  7. /*                                                                   */
  8. /* Philippe Annet, Compart Systemhaus GmbH  - CIS: [100276,2650]     */
  9.  
  10. #include <stdio.h>
  11. #include "pgl.h" /* PGL calls    */
  12. #include "glu.h" /* OpenGL utilities */
  13.  
  14. #define PM_ESCAPE 0x0f
  15. #define MSGBOXID 22
  16.  
  17. GLfloat light0position[] = { 0.0, 1.0, 0.0, 1.0 };
  18. GLfloat light0color[] = { 1.0, 1.0, 1.0, 1.0 };
  19. GLfloat light1position[] = { 1.0, 1.0, 1.0, 0.0 };
  20. GLfloat light1color[] = { 0.7, 1.0, 0.7, 1.0 };
  21. HAB hab;
  22.  
  23. /* attributes passed into pglChooseConfig */
  24. int attriblist[] = {
  25.   PGL_DOUBLEBUFFER,  /* request doublebuffered visual config */
  26.   PGL_RGBA,          /* request rgb (true color) visual config */
  27.   None               /* always end list with this */
  28. };
  29.  
  30.  
  31. void DispError(PSZ errstr)
  32. {
  33.   char buffer[256];
  34.   sprintf(buffer, "Error (0x%x) in LOCAL.EXE:", WinGetLastError(hab));
  35.   WinMessageBox(HWND_DESKTOP,HWND_DESKTOP,errstr,buffer,
  36.                 MSGBOXID,MB_MOVEABLE|MB_CUACRITICAL|MB_CANCEL);
  37.   exit(0);
  38. }
  39.  
  40. void Setup()
  41. {
  42.   glColorMask( GL_TRUE, GL_TRUE, GL_TRUE, GL_FALSE );
  43.   glDepthMask( GL_FALSE ); /* no depth buffering */
  44.  
  45.   glEnable( GL_CULL_FACE );             /* remove backfaces */
  46.   glEnable( GL_LIGHTING );              /* enable lighting */
  47.  
  48.   glMatrixMode( GL_PROJECTION );        /* setup projection matrix */
  49.   gluPerspective( 40, 1.0, 1.0, 50.0 );
  50.   glMatrixMode( GL_MODELVIEW );         /* switch to modelview mode */
  51.   gluLookAt( 0.0, 1.5, 2.5,             /* setup viewing transform */
  52.              0.0, 0.0, 0.0,
  53.              0.0, 1.0, 0.0 );
  54.   glPushMatrix();                       /* push a dummy matrix */
  55.  
  56.   glLightModeli( GL_LIGHT_MODEL_LOCAL_VIEWER, 1 );      /* local lighting */
  57.  
  58.   glLightfv( GL_LIGHT0, GL_POSITION, light0position );  /* light position */
  59.   glLightfv( GL_LIGHT0, GL_DIFFUSE, light0color );      /* light color */
  60.   glLightf( GL_LIGHT0, GL_CONSTANT_ATTENUATION, 1.0 );
  61.   glLightf( GL_LIGHT0, GL_LINEAR_ATTENUATION, 1.0 );
  62.  
  63.   glLightfv( GL_LIGHT1, GL_POSITION, light1position );  /* light position */
  64.   glLightfv( GL_LIGHT1, GL_DIFFUSE, light1color );      /* light color */
  65.  
  66.   glEnable( GL_LIGHT0 );                          /* turn on the light ! */
  67.   glEnable( GL_LIGHT1 );                          /* turn on the 2nd. light ! */
  68.  
  69.   glShadeModel( GL_SMOOTH );                        /* smooth shading */
  70.   glFrontFace( GL_CCW );         /* front faces are given counterclockwise */
  71. }
  72.  
  73. /* create a flat surface in the XZ plane (-1.0 <= x, z <= 1.0) */
  74. /* using n*n small polygons.                                   */
  75. void MakePlane( int n )
  76. {
  77.     static GLfloat white[] = { 1.0, 1.0, 1.0, 1.0 }; /* white plane */
  78.     static GLfloat black[] = { 0.0, 0.0, 0.0, 1.0 };
  79.     GLfloat p0[3], p1[3], p2[3], p3[3];
  80.     int i, j;
  81.  
  82.     glDisable( GL_LIGHT1 ); /* switch off light1, it's only for the lamp */
  83.  
  84.     glMaterialfv( GL_FRONT, GL_DIFFUSE, white );
  85.     glMaterialfv( GL_FRONT, GL_AMBIENT, black );
  86.  
  87.     p0[1] = p1[1] = p2[1] = p3[1] = 0.0;   /* set Y to zero */
  88.     for ( i = 0; i < n; ++i )
  89.        {
  90.        p0[0] = p1[0] = -1.0 + ((2.0 * (GLfloat) i) / (GLfloat) n);
  91.        p2[0] = p3[0] = -1.0 + ((2.0 * (GLfloat) (i + 1)) / (GLfloat) n);
  92.  
  93.        for ( j = 0; j < n; ++j )
  94.           {
  95.           p0[2] = p3[2] = -1.0 + ((2.0 * (GLfloat) j) / (GLfloat) n);
  96.           p1[2] = p2[2] = -1.0 + ((2.0 * (GLfloat) (j + 1)) / (GLfloat) n);
  97.  
  98.           glBegin( GL_POLYGON );
  99.             glNormal3f( 0.0, 1.0, 0.0 ); /* for the shading engine */
  100.             glVertex3fv( p0 );  /* counterclockwise ! */
  101.             glVertex3fv( p1 );
  102.             glVertex3fv( p2 );
  103.             glVertex3fv( p3 );
  104.           glEnd();
  105.           }
  106.        }
  107.  
  108.     glEnable( GL_LIGHT1 );
  109. }
  110.  
  111.  
  112. void MakeLamp( GLfloat height )
  113. {
  114.     static GLfloat lampcolor[] = { 1.0, 0.0, 0.0, 1.0 }; /* red */
  115.     static GLfloat verts[][3] =
  116.      {
  117.       { 0.0, 0.5,  0.0},
  118.       { 0.5, 0.0,  0.5},
  119.       {-0.5, 0.0,  0.5},
  120.       {-0.5, 0.0, -0.5},
  121.       { 0.5, 0.0, -0.5}
  122.      };
  123.  
  124.     glPushMatrix();
  125.  
  126.     glTranslatef( 0.0, height, 0.0 );
  127.     glScalef( 0.3, 0.3, 0.3 );
  128.  
  129.     glMaterialfv( GL_FRONT, GL_DIFFUSE, lampcolor );
  130.     glBegin( GL_POLYGON );
  131.       glNormal3f( 0.0, (1.0/1.414), (1.0/1.414) );
  132.       glVertex3fv( verts[0] );
  133.       glVertex3fv( verts[2] );
  134.       glVertex3fv( verts[1] );
  135.     glEnd();
  136.  
  137.     glBegin( GL_POLYGON );
  138.       glNormal3f( (1.0/1.414), (1.0/1.414), 0.0 );
  139.       glVertex3fv( verts[0] );
  140.       glVertex3fv( verts[1] );
  141.       glVertex3fv( verts[4] );
  142.     glEnd();
  143.  
  144.     glBegin( GL_POLYGON );
  145.       glNormal3f( 0.0, (1.0/1.414), -(1.0/1.414) );
  146.       glVertex3fv( verts[0] );
  147.       glVertex3fv( verts[4] );
  148.       glVertex3fv( verts[3] );
  149.     glEnd();
  150.  
  151.     glBegin( GL_POLYGON );
  152.       glNormal3f( -(1.0/1.414), (1.0/1.414), 0.0 );
  153.       glVertex3fv( verts[0] );
  154.       glVertex3fv( verts[3] );
  155.       glVertex3fv( verts[2] );
  156.     glEnd();
  157.  
  158.     glPopMatrix();
  159. }
  160.  
  161.  
  162. MRESULT EXPENTRY WindowProc( HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2 )
  163. {
  164.     MRESULT mresult = (MRESULT) 0;
  165.  
  166.     static float inc = 0.05, t = 0.0;
  167.     static SWP clientsize;
  168.     static USHORT mycode;
  169.     static UCHAR key;
  170.  
  171.     switch( msg )
  172.        {
  173.        case WM_SIZE:
  174.           WinQueryWindowPos( hwnd, &clientsize );
  175.           glViewport( 0, 0, clientsize.cx, clientsize.cy );
  176.           return( mresult );
  177.  
  178.        case WM_TIMER:
  179.           WinInvalidateRect( hwnd, (RECTL *) 0, FALSE );
  180.           return( mresult );
  181.  
  182.        case WM_PAINT:
  183.           glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
  184.  
  185.           /* change the light's position on the Y axis */
  186.           light0position[1] += inc;
  187.           glLightfv( GL_LIGHT0, GL_POSITION, light0position );
  188.           if ( ((light0position[1] > 0.9) && (inc > 0.0)) ||
  189.                ((light0position[1] < 0.2) && (inc < 0.0)) )
  190.              inc = -inc;
  191.  
  192.           glPushMatrix();
  193.           t += 2.0;                      /* lets turn around the plane */
  194.           glRotatef( t, 0.0, 1.0, 0.0 );
  195.           MakePlane( 10 );
  196.           MakeLamp( light0position[1] );
  197.           glPopMatrix();
  198.  
  199.           pglSwapBuffers( hab, hwnd );
  200.           return( mresult );
  201.  
  202.        case WM_CHAR:
  203.           mycode = (USHORT)SHORT1FROMMP(mp1);
  204.           if ((mycode & KC_CHAR) && !(mycode & KC_KEYUP))
  205.             key = CHAR1FROMMP(mp2);
  206.           else if ((mycode & KC_VIRTUALKEY) && !(mycode & KC_KEYUP))
  207.             key = CHAR3FROMMP(mp2);
  208.           if (key == PM_ESCAPE)
  209.             WinPostMsg(hwnd, WM_CLOSE, (MPARAM)0, (MPARAM)0);
  210.           break;
  211.  
  212.        default:
  213.           break;
  214.        }
  215.  
  216. mresult = WinDefWindowProc( hwnd, msg, mp1, mp2 );
  217. return( mresult );
  218. }
  219.  
  220.  
  221. main( int argc, char *argv[] )
  222. {
  223.   PVISUALCONFIG vishead; /* visual configuration             */
  224.   HMQ hmq;               /* message queue                    */
  225.   HWND hwnd;
  226.   HWND hwndFrame;
  227.   ULONG createflags = FCF_TITLEBAR |
  228.                       FCF_SYSMENU  |
  229.                       FCF_MINMAX   |
  230.                       FCF_SIZEBORDER;
  231.   QMSG qmsg;             /* message                          */
  232.   HGC hgc;               /* OpenGL context                   */
  233.   int  major, minor;     /* OpenGL version                   */
  234.   int err;
  235.  
  236.   hab = WinInitialize(0);
  237.  
  238.   /* Check to see if OpenGL exists */
  239.   if (pglQueryCapability(hab)) {
  240.     pglQueryVersion(hab, &major, &minor);
  241.     /* Version 1.0                */
  242.     if ((major == 1) && (minor == 0)) {
  243.       /* Choose a visual configuration that matches desired  */
  244.       /* attributes in attriblist                            */
  245.       vishead = pglChooseConfig(hab, attriblist);
  246.       if (!vishead)
  247.         DispError("Couldn't find a visual!\n");
  248.       hmq = WinCreateMsgQueue(hab, 0);
  249.       if (!hmq)
  250.         DispError("Couldn't create a message queue!\n");
  251.       if (WinRegisterClass(
  252.             hab,
  253.             (PSZ)"PGLtest",
  254.             WindowProc,
  255.             CS_SIZEREDRAW | CS_MOVENOTIFY, /* Need at least this! */
  256.             0))
  257.       {
  258.         hwndFrame = WinCreateStdWindow (
  259.                       HWND_DESKTOP,   /* Child of the desktop    */
  260.                       WS_VISIBLE,     /* Frame style             */
  261.                       &createflags,   /* min FCF_MENU|FCF_MINMAX */
  262.                       (PSZ)"PGLtest", /* class name              */
  263.                       "OpenGL Sample",/* window title            */
  264.                       WS_VISIBLE,     /* client style            */
  265.                       0,              /* resource handle         */
  266.                       1,              /* Resource ID             */
  267.                       &hwnd);         /* Window handle           */
  268.         if (!hwndFrame)
  269.           DispError("Couldn't create a window!\n");
  270.         /* you must set window size before you call pglMakeCurrent */
  271.         if (!WinSetWindowPos(
  272.                hwndFrame,
  273.                HWND_TOP,
  274.                150,
  275.                150,
  276.                240,
  277.                220,
  278.                SWP_ACTIVATE | SWP_SIZE | SWP_MOVE | SWP_SHOW))
  279.           DispError("Couldn't position window!\n");
  280.         hgc = pglCreateContext(hab,  /* anchor block handle    */
  281.                  vishead,            /* visual configuration   */
  282.                  (HGC)NULL,          /* (no) shared contexts   */
  283.                  (BOOL)TRUE);        /* direct (fast) context  */
  284.         if (!hgc)
  285.           DispError("Couldn't create an OpenGL context!\n");
  286.         if(!pglMakeCurrent(hab, hgc, hwnd))
  287.           DispError("Could not bind OpenGL context to window!\n");
  288.         /* Don't subclass your window past here! */
  289.         Setup();
  290.         /* Start timer to cause WM_TIMER messages to be sent   */
  291.         /* periodically.  This is used to animate.             */
  292.         WinStartTimer(hab, hwnd, 0L, 0L);
  293.         while (WinGetMsg(hab, &qmsg, NULLHANDLE, 0, 0))
  294.           WinDispatchMsg(hab, &qmsg);
  295.       }
  296.     }
  297.   }
  298. }
  299.