home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
OS/2 Shareware BBS: 10 Tools
/
10-Tools.zip
/
local.zip
/
local.c
Wrap
Text File
|
1994-09-12
|
11KB
|
299 lines
/* OpenGL on OS/2 example, showing how to use the (local) lighting */
/* capabilities of OpenGL. The code is partially derived from the */
/* OpenGL example (sampogl.c) found in Compuserve's OS2DF2 (lib 12). */
/* */
/* The programs shows a flat polygon in the XZ plane lighted by a */
/* source moving between 0.2 and 0.9 along the Y axis. */
/* */
/* Philippe Annet, Compart Systemhaus GmbH - CIS: [100276,2650] */
#include <stdio.h>
#include "pgl.h" /* PGL calls */
#include "glu.h" /* OpenGL utilities */
#define PM_ESCAPE 0x0f
#define MSGBOXID 22
GLfloat light0position[] = { 0.0, 1.0, 0.0, 1.0 };
GLfloat light0color[] = { 1.0, 1.0, 1.0, 1.0 };
GLfloat light1position[] = { 1.0, 1.0, 1.0, 0.0 };
GLfloat light1color[] = { 0.7, 1.0, 0.7, 1.0 };
HAB hab;
/* attributes passed into pglChooseConfig */
int attriblist[] = {
PGL_DOUBLEBUFFER, /* request doublebuffered visual config */
PGL_RGBA, /* request rgb (true color) visual config */
None /* always end list with this */
};
void DispError(PSZ errstr)
{
char buffer[256];
sprintf(buffer, "Error (0x%x) in LOCAL.EXE:", WinGetLastError(hab));
WinMessageBox(HWND_DESKTOP,HWND_DESKTOP,errstr,buffer,
MSGBOXID,MB_MOVEABLE|MB_CUACRITICAL|MB_CANCEL);
exit(0);
}
void Setup()
{
glColorMask( GL_TRUE, GL_TRUE, GL_TRUE, GL_FALSE );
glDepthMask( GL_FALSE ); /* no depth buffering */
glEnable( GL_CULL_FACE ); /* remove backfaces */
glEnable( GL_LIGHTING ); /* enable lighting */
glMatrixMode( GL_PROJECTION ); /* setup projection matrix */
gluPerspective( 40, 1.0, 1.0, 50.0 );
glMatrixMode( GL_MODELVIEW ); /* switch to modelview mode */
gluLookAt( 0.0, 1.5, 2.5, /* setup viewing transform */
0.0, 0.0, 0.0,
0.0, 1.0, 0.0 );
glPushMatrix(); /* push a dummy matrix */
glLightModeli( GL_LIGHT_MODEL_LOCAL_VIEWER, 1 ); /* local lighting */
glLightfv( GL_LIGHT0, GL_POSITION, light0position ); /* light position */
glLightfv( GL_LIGHT0, GL_DIFFUSE, light0color ); /* light color */
glLightf( GL_LIGHT0, GL_CONSTANT_ATTENUATION, 1.0 );
glLightf( GL_LIGHT0, GL_LINEAR_ATTENUATION, 1.0 );
glLightfv( GL_LIGHT1, GL_POSITION, light1position ); /* light position */
glLightfv( GL_LIGHT1, GL_DIFFUSE, light1color ); /* light color */
glEnable( GL_LIGHT0 ); /* turn on the light ! */
glEnable( GL_LIGHT1 ); /* turn on the 2nd. light ! */
glShadeModel( GL_SMOOTH ); /* smooth shading */
glFrontFace( GL_CCW ); /* front faces are given counterclockwise */
}
/* create a flat surface in the XZ plane (-1.0 <= x, z <= 1.0) */
/* using n*n small polygons. */
void MakePlane( int n )
{
static GLfloat white[] = { 1.0, 1.0, 1.0, 1.0 }; /* white plane */
static GLfloat black[] = { 0.0, 0.0, 0.0, 1.0 };
GLfloat p0[3], p1[3], p2[3], p3[3];
int i, j;
glDisable( GL_LIGHT1 ); /* switch off light1, it's only for the lamp */
glMaterialfv( GL_FRONT, GL_DIFFUSE, white );
glMaterialfv( GL_FRONT, GL_AMBIENT, black );
p0[1] = p1[1] = p2[1] = p3[1] = 0.0; /* set Y to zero */
for ( i = 0; i < n; ++i )
{
p0[0] = p1[0] = -1.0 + ((2.0 * (GLfloat) i) / (GLfloat) n);
p2[0] = p3[0] = -1.0 + ((2.0 * (GLfloat) (i + 1)) / (GLfloat) n);
for ( j = 0; j < n; ++j )
{
p0[2] = p3[2] = -1.0 + ((2.0 * (GLfloat) j) / (GLfloat) n);
p1[2] = p2[2] = -1.0 + ((2.0 * (GLfloat) (j + 1)) / (GLfloat) n);
glBegin( GL_POLYGON );
glNormal3f( 0.0, 1.0, 0.0 ); /* for the shading engine */
glVertex3fv( p0 ); /* counterclockwise ! */
glVertex3fv( p1 );
glVertex3fv( p2 );
glVertex3fv( p3 );
glEnd();
}
}
glEnable( GL_LIGHT1 );
}
void MakeLamp( GLfloat height )
{
static GLfloat lampcolor[] = { 1.0, 0.0, 0.0, 1.0 }; /* red */
static GLfloat verts[][3] =
{
{ 0.0, 0.5, 0.0},
{ 0.5, 0.0, 0.5},
{-0.5, 0.0, 0.5},
{-0.5, 0.0, -0.5},
{ 0.5, 0.0, -0.5}
};
glPushMatrix();
glTranslatef( 0.0, height, 0.0 );
glScalef( 0.3, 0.3, 0.3 );
glMaterialfv( GL_FRONT, GL_DIFFUSE, lampcolor );
glBegin( GL_POLYGON );
glNormal3f( 0.0, (1.0/1.414), (1.0/1.414) );
glVertex3fv( verts[0] );
glVertex3fv( verts[2] );
glVertex3fv( verts[1] );
glEnd();
glBegin( GL_POLYGON );
glNormal3f( (1.0/1.414), (1.0/1.414), 0.0 );
glVertex3fv( verts[0] );
glVertex3fv( verts[1] );
glVertex3fv( verts[4] );
glEnd();
glBegin( GL_POLYGON );
glNormal3f( 0.0, (1.0/1.414), -(1.0/1.414) );
glVertex3fv( verts[0] );
glVertex3fv( verts[4] );
glVertex3fv( verts[3] );
glEnd();
glBegin( GL_POLYGON );
glNormal3f( -(1.0/1.414), (1.0/1.414), 0.0 );
glVertex3fv( verts[0] );
glVertex3fv( verts[3] );
glVertex3fv( verts[2] );
glEnd();
glPopMatrix();
}
MRESULT EXPENTRY WindowProc( HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2 )
{
MRESULT mresult = (MRESULT) 0;
static float inc = 0.05, t = 0.0;
static SWP clientsize;
static USHORT mycode;
static UCHAR key;
switch( msg )
{
case WM_SIZE:
WinQueryWindowPos( hwnd, &clientsize );
glViewport( 0, 0, clientsize.cx, clientsize.cy );
return( mresult );
case WM_TIMER:
WinInvalidateRect( hwnd, (RECTL *) 0, FALSE );
return( mresult );
case WM_PAINT:
glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
/* change the light's position on the Y axis */
light0position[1] += inc;
glLightfv( GL_LIGHT0, GL_POSITION, light0position );
if ( ((light0position[1] > 0.9) && (inc > 0.0)) ||
((light0position[1] < 0.2) && (inc < 0.0)) )
inc = -inc;
glPushMatrix();
t += 2.0; /* lets turn around the plane */
glRotatef( t, 0.0, 1.0, 0.0 );
MakePlane( 10 );
MakeLamp( light0position[1] );
glPopMatrix();
pglSwapBuffers( hab, hwnd );
return( mresult );
case WM_CHAR:
mycode = (USHORT)SHORT1FROMMP(mp1);
if ((mycode & KC_CHAR) && !(mycode & KC_KEYUP))
key = CHAR1FROMMP(mp2);
else if ((mycode & KC_VIRTUALKEY) && !(mycode & KC_KEYUP))
key = CHAR3FROMMP(mp2);
if (key == PM_ESCAPE)
WinPostMsg(hwnd, WM_CLOSE, (MPARAM)0, (MPARAM)0);
break;
default:
break;
}
mresult = WinDefWindowProc( hwnd, msg, mp1, mp2 );
return( mresult );
}
main( int argc, char *argv[] )
{
PVISUALCONFIG vishead; /* visual configuration */
HMQ hmq; /* message queue */
HWND hwnd;
HWND hwndFrame;
ULONG createflags = FCF_TITLEBAR |
FCF_SYSMENU |
FCF_MINMAX |
FCF_SIZEBORDER;
QMSG qmsg; /* message */
HGC hgc; /* OpenGL context */
int major, minor; /* OpenGL version */
int err;
hab = WinInitialize(0);
/* Check to see if OpenGL exists */
if (pglQueryCapability(hab)) {
pglQueryVersion(hab, &major, &minor);
/* Version 1.0 */
if ((major == 1) && (minor == 0)) {
/* Choose a visual configuration that matches desired */
/* attributes in attriblist */
vishead = pglChooseConfig(hab, attriblist);
if (!vishead)
DispError("Couldn't find a visual!\n");
hmq = WinCreateMsgQueue(hab, 0);
if (!hmq)
DispError("Couldn't create a message queue!\n");
if (WinRegisterClass(
hab,
(PSZ)"PGLtest",
WindowProc,
CS_SIZEREDRAW | CS_MOVENOTIFY, /* Need at least this! */
0))
{
hwndFrame = WinCreateStdWindow (
HWND_DESKTOP, /* Child of the desktop */
WS_VISIBLE, /* Frame style */
&createflags, /* min FCF_MENU|FCF_MINMAX */
(PSZ)"PGLtest", /* class name */
"OpenGL Sample",/* window title */
WS_VISIBLE, /* client style */
0, /* resource handle */
1, /* Resource ID */
&hwnd); /* Window handle */
if (!hwndFrame)
DispError("Couldn't create a window!\n");
/* you must set window size before you call pglMakeCurrent */
if (!WinSetWindowPos(
hwndFrame,
HWND_TOP,
150,
150,
240,
220,
SWP_ACTIVATE | SWP_SIZE | SWP_MOVE | SWP_SHOW))
DispError("Couldn't position window!\n");
hgc = pglCreateContext(hab, /* anchor block handle */
vishead, /* visual configuration */
(HGC)NULL, /* (no) shared contexts */
(BOOL)TRUE); /* direct (fast) context */
if (!hgc)
DispError("Couldn't create an OpenGL context!\n");
if(!pglMakeCurrent(hab, hgc, hwnd))
DispError("Could not bind OpenGL context to window!\n");
/* Don't subclass your window past here! */
Setup();
/* Start timer to cause WM_TIMER messages to be sent */
/* periodically. This is used to animate. */
WinStartTimer(hab, hwnd, 0L, 0L);
while (WinGetMsg(hab, &qmsg, NULLHANDLE, 0, 0))
WinDispatchMsg(hab, &qmsg);
}
}
}
}