File: heightmap.c/****************************************************/
/* Height Mapping Demo using font buffers */
/****************************************************/
/*
Cpw link options:
#define CPW_EXTERN - link to the static lib
#define CPWDLL_EXTERN - link to the release dll's stub
#define CPWDLLDBG_EXTERN - link to the debug dll's stub
#define CPWEXTDLL_EXTERN - link to the release dll with cpw addons
*/
#define CPWDLL_EXTERN
#include <cpw.h>
/* handy window characteristics holder */
static CpwWindowInfo windowInfo = { 0,100,100,300,300 }; /* id,posx,posy,w,h */
static CpwFontFace font;
static CpwFontBuffer fontbuf;
static char* fontstring = "CPW";
static int_32 rot = 0;
static float_32 colormod[256][3];
static GLenum mode = GL_POINTS;
static GLuint listid = 0;
static GLuint list = 0;
/****************************************************/
/* OpenGL 2D Matrix Setup */
/****************************************************/
void set2DMatrix( void )
{
glMatrixMode( GL_PROJECTION );
glLoadIdentity();
gluOrtho2D( 0, windowInfo.width, 0, windowInfo.height );
glMatrixMode( GL_MODELVIEW );
glLoadIdentity();
}
/****************************************************/
/* OpenGL 3D Matrix Setup */
/****************************************************/
void set3DMatrix( void )
{
glMatrixMode( GL_PROJECTION );
glLoadIdentity();
gluPerspective( 60, (float)windowInfo.width / (float)windowInfo.height, 1, 1000 );
glMatrixMode( GL_MODELVIEW );
glLoadIdentity();
}
/****************************************************/
/* Window Draw Event callback */
/****************************************************/
void draw( pCpw cpw, uint_32 winid )
{
//glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
glClear( GL_COLOR_BUFFER_BIT );
set3DMatrix();
glTranslatef( 0, 0, -210 );
glPushMatrix();
glRotatef( rot, 1, 1, 1 );
/* draw the axis */
glPushMatrix();
glLineWidth( 1 );
/* x axis */
glColor3f( 0, 0, 1 );
glBegin( GL_LINES );
glVertex3f( -100, 0, 0 );
glVertex3f( 100, 0, 0 );
glEnd();
/* y axis */
glColor3f( 1, 0, 0 );
glBegin( GL_LINES );
glVertex3f( 0, -100, 0 );
glVertex3f( 0, 100, 0 );
glEnd();
/* z axis */
glColor3f( 1, 1, 0 );
glBegin( GL_LINES );
glVertex3f( 0, 0, 1 );
glVertex3f( 0, 0, 100 );
glEnd();
glLineWidth( 1 );
glPopMatrix();
/* center the texture on the origin */
glPushMatrix();
glTranslatef( (fontbuf.w*2) * -.5, (fontbuf.h*2) * -.5, 0 );
/* draw the hightmap */
glCallList( list );
glPopMatrix();
glPopMatrix();
/* blit the texture */
//set2DMatrix();
//glRasterPos2d( 1, 1 );
//glDrawPixels( fontbuf.w, fontbuf.h, fontbuf.glformat, GL_UNSIGNED_BYTE, fontbuf.data );
cpwSwapWindowBuffers( cpw, winid );
}
/****************************************************/
/* Window Create / Destroy Event callback */
/****************************************************/
void window( pCpw cpw, uint_32 winid, bool flag )
{
/* creation event */
if ( flag == true ) {
glShadeModel( GL_SMOOTH );
glDepthFunc( GL_LEQUAL );
glEnable( GL_DEPTH );
glHint( GL_PERSPECTIVE_CORRECTION_HINT, GL_FASTEST );
//glEnable( GL_LINE_SMOOTH );
//glEnable(GL_BLEND);
//glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glPolygonMode( GL_FRONT_AND_BACK, GL_LINE );
//glEnable( GL_POINT_SMOOTH );
//glEnable( GL_POLYGON_SMOOTH );
glClearColor( 0.0, 0.0, 0.0, 1.0 );
glPointSize( 1 );
return;
}
/* window close event */
if ( flag == false ) {
cpwDestroyWindow( cpw, winid );
return;
}
}
/****************************************************/
/* Timer Event callback */
/****************************************************/
void timer( pCpw cpw, uint_32 id )
{
rot = rot + 1;
cpwPostRedisplay( cpw );
}
/****************************************************/
/* Window Resize Event callback */
/****************************************************/
void reshape( pCpw cpw, uint_32 winid, uint_32 width, uint_32 height )
{
if ( height == 0 ) { height = 1; }
if ( width == 0 ) { width = 1; }
windowInfo.width = width;
windowInfo.height = height;
set3DMatrix();
glViewport( 0, 0, width, height );
}
/****************************************************/
/* Window Key Event callback */
/****************************************************/
void keyboard( pCpw cpw, uint_32 id, uint_32 key, uint_32 state, uint_32 x, uint_32 y )
{
if ( state == CPW_KEYMOD_UP ) return;
if ( key == 'p' || key == 'P' ) list = listid;
if ( key == 'l' || key == 'L' ) list = listid+1;
if ( key == 'q' || key == 'Q' ) list = listid+2;
cpwPostRedisplay( cpw );
}
void createDisplayList( GLuint list, GLint mode )
{
float_32 x, y, z;
glNewList( list, GL_COMPILE );
/* draw the hightmap */
for ( y = 0; y < fontbuf.h-1; y++ )
for ( x = 0; x < fontbuf.w-1; x++ ) /* iterate across the luminance buffer width */
{
glBegin( mode );
/* draw a quad in counter clockwise order */
/* origin */
z = (float_32)( ( (unsigned char)
*( fontbuf.data + (int_32)((y * fontbuf.w) + x ) ) ) );
glColor3f( colormod[(int_32)z][0], colormod[(int_32)z][1], colormod[(int_32)z][2] );
glVertex3f( x*2, y*2, z*.2 );
/* right */
z = (float_32)( ( (unsigned char)
*( fontbuf.data + (int_32)((y * fontbuf.w) + (x+1) ) ) ) );
glColor3f( colormod[(int_32)z][0], colormod[(int_32)z][1], colormod[(int_32)z][2] );
glVertex3f( (x+1)*2, y*2, z*.2 );
/* right top */
z = (float_32)( ( (unsigned char)
*( fontbuf.data + (int_32)(((y+1) * fontbuf.w) + (x+1) ) ) ) );
glColor3f( colormod[(int_32)z][0], colormod[(int_32)z][1], colormod[(int_32)z][2] );
glVertex3f( (x+1)*2, (y+1)*2, z*.2 );
/* top */
z = (float_32)( ( (unsigned char)
*( fontbuf.data + (int_32)(((y+1) * fontbuf.w) + x ) ) ) );
glColor3f( colormod[(int_32)z][0], colormod[(int_32)z][1], colormod[(int_32)z][2] );
glVertex3f( x*2, (y+1)*2, z*.2 );
glEnd();
}
glEndList();
}
/****************************************************/
/* Main */
/****************************************************/
#ifdef _WINDOWS
int APIENTRY WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nCmdShow)
#elif _CONSOLE
int main(int argc, char* argv[])
#endif
{
int_32 i;
pCpw cpw = null;
/****************************************************/
/* Init */
/****************************************************/
cpwInitContext( &cpw );
/****************************************************/
/* Creaing Windows */
/****************************************************/
windowInfo.id =
cpwCreateWindowEx( cpw, "Press q, p, l", windowInfo.x, windowInfo.y,
windowInfo.width, windowInfo.height );
/****************************************************/
/* Event Callbacks */
/****************************************************/
cpwCreateCallback( cpw, window );
cpwDisplayCallback( cpw, draw );
cpwReshapeCallback( cpw, reshape );
cpwTimerCallback( cpw, 20, 1, true, timer );
cpwKeyboardCallback( cpw, keyboard );
/****************************************************/
/* Fonts */
/****************************************************/
glPixelStorei( GL_UNPACK_LSB_FIRST, GL_FALSE );
glPixelStorei( GL_UNPACK_ALIGNMENT, 1 );
cpwFontMode( cpw, CPW_FONTOPT_PIXELMAP, 0 );
cpwFontMode( cpw, CPW_FONTOPT_ALIGNLEFT, 0 );
cpwFontMode( cpw, CPW_FONTOPT_SIZE, 40 );
cpwFontMode( cpw, CPW_FONTOPT_PIXELMAP_GLFORMAT, GL_LUMINANCE );
cpwFontMode( cpw, CPW_FONTOPT_LAYOUTDEBUG, 0 );
cpwFontMode( cpw, CPW_FONTOPT_SPACING, 1 );
font = cpwLoadFont( cpw, "arial.ttf", CPW_FONTLOC_HOST, "", "" );
/* pre-render our font string into a buffer */
cpwDrawBufferedFont( cpw, font, fontstring, &fontbuf );
{
float_32 red = 0, green = 0, blue = 255;
for ( i = 0; i < 256; i++ ){
/* green: */
if ( i > 200 ) green=green+2;
if ( i > 240 ) green=green+4;
/* red: */
if ( i > 50 && i < 200 ) red=red+3;
if ( i > 200 ) red=red-1;
/* blue: */
blue--;
colormod[i][0] = red / 255;
colormod[i][1] = green / 255;
colormod[i][2] = blue / 255;
}
}
listid = glGenLists( 3 );
createDisplayList( listid, GL_POINTS );
createDisplayList( listid+1, GL_LINES );
createDisplayList( listid+2, GL_QUADS );
list = listid;
/****************************************************/
/* MainLoop */
/****************************************************/
cpwMainLoop( cpw );
/****************************************************/
/* Exit and Free */
/****************************************************/
cpwFreeBufferedFont( cpw, &fontbuf );
cpwFreeContext( &cpw );
return 0;
}