File: fullscreen.c/*
fullscreen.c
A basic test of fullscreen rendering. Creates a fullscreen
window and renders a tunnel.
Options:
'esc' - exit
'w' - wrieframe
'?' - toggle help screen on/off
up/down arrow keys - speed up / slow down rotation
Grats: I used Romka's tunnel demo as a basis for this. Thanks dude.
http://romka.demonews.com/opengl/demos/
fun: turn off all the lights, crank up the rotation and have a trash
can ready.
*/
#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 char buf[1000];
/* some texture filenames and thier data holders */
static char * filename1 = "textures/tunneltexture.bmp";
static CpwImage image1;
static bool wireframe = false;
static bool fog = false;
static bool help = true;
#define pi 3.141592654f
typedef struct
{
float x,y,z;
} PCoord; /* Polygon Coordinates */
typedef struct
{
float u,v;
} TCoord; /* Texture Coordinates */
static PCoord imgArray[36][36];
static TCoord texcord[36][36];
static float rot = 0, rotspeed = 1;
GLuint xloop,yloop;
GLfloat FogColour[4] = { 0.0f , 0.0f , 0.0f , 1.0f };
void init_fog()
{
glFogi(GL_FOG_MODE, GL_LINEAR);
glFogfv(GL_FOG_COLOR, FogColour);
glFogf(GL_FOG_DENSITY, 0.25f);
glHint(GL_FOG_HINT, GL_NICEST);
glFogf(GL_FOG_START, 0);
glFogf(GL_FOG_END, 30);
}
/****************************************************/
/* 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( 45, (float)windowInfo.width / (float)windowInfo.height, 1, 100 );
glMatrixMode( GL_MODELVIEW );
glLoadIdentity();
}
/****************************************************/
/* Draw Help */
/****************************************************/
void drawHelp( pCpw cpw )
{
float ypos = (float)(windowInfo.height * .9);
set2DMatrix();
glPushMatrix();
glDisable( GL_TEXTURE_2D );
glEnable( GL_BLEND );
glColor3d( 1.0, 0.6, 0.0 );
sprintf( buf, "'esc' - exit" );
glRasterPos2d( 10, ypos );
cpwDrawFont( cpw, font, buf, 1 );
sprintf( buf, "'w' - toggle wireframe / texturing" );
ypos = ypos - 20;
glRasterPos2d( 10, ypos );
cpwDrawFont( cpw, font, buf, 1 );
sprintf( buf, "'?' - toggle help screen" );
ypos = ypos - 20;
glRasterPos2d( 10, ypos );
cpwDrawFont( cpw, font, buf, 1 );
sprintf( buf, "'up/dn' - alter rotation speed" );
ypos = ypos - 20;
glRasterPos2d( 10, ypos );
cpwDrawFont( cpw, font, buf, 1 );
glDisable( GL_BLEND );
glPopMatrix();
}
/****************************************************/
/* Draw Window One */
/****************************************************/
void drawSceneOne( pCpw cpw, uint_32 winid )
{
int i,j;
glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
glColor3f( 1.0, 1.0, 1.0 );
set3DMatrix();
glPushMatrix();
glTranslated( 0.0, 0.0, -4.0 );
for (i=0; i<33; i++)
{
for (j=0; j<33; j++)
{
texcord[i][j].u = (float) (i / 16.0 + cos( ( rot + 8.0 * j ) / 60 ) / 2 );
texcord[i][j].v = (float) (j / 16.0 + ( (rot*2) + j ) / 120 );
}
}
glEnable(GL_FOG);
if ( wireframe ) {
glDisable( GL_TEXTURE_2D );
} else {
glEnable( GL_TEXTURE_2D );
}
for (xloop=0; xloop<32; xloop++)
{
if ( wireframe ) {
glBegin(GL_LINES);
} else {
glBegin(GL_QUADS);
}
for (yloop=0; yloop<32; yloop++)
{
glTexCoord2f (texcord[xloop][yloop].u, texcord[xloop][yloop].v);
glVertex3f (imgArray[xloop ][yloop ].x,imgArray[xloop ][yloop ].y,imgArray[xloop ][yloop ].z);
glTexCoord2f (texcord[xloop+1][yloop ].u, texcord[xloop+1][yloop ].v);
glVertex3f (imgArray[xloop+1][yloop ].x,imgArray[xloop+1][yloop ].y,imgArray[xloop ][yloop ].z);
glTexCoord2f (texcord[xloop+1][yloop+1].u, texcord[xloop+1][yloop+1].v);
glVertex3f (imgArray[xloop+1][yloop+1].x,imgArray[xloop+1][yloop+1].y,imgArray[xloop ][yloop+1].z);
glTexCoord2f (texcord[xloop ][yloop+1].u, texcord[xloop ][yloop+1].v);
glVertex3f (imgArray[xloop ][yloop+1].x,imgArray[xloop ][yloop+1].y,imgArray[xloop ][yloop+1].z);
}
glEnd();
}
glPopMatrix();
if ( help )
drawHelp( cpw );
cpwSwapWindowBuffers( cpw, winid );
}
/****************************************************/
/* Window Create / Destroy Event callback */
/****************************************************/
void window( pCpw cpw, uint_32 winid, bool flag )
{
int i, j;
/* creation event */
if ( flag == true ) {
glEnable(GL_TEXTURE_2D);
glShadeModel(GL_SMOOTH);
glClearColor(0.0, 0.0, 0.0, 1.0);
glClearDepth(1.0);
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LEQUAL);
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
for (i=0; i<33; i++)
{
for (j=0; j<33; j++)
{
imgArray[i][j].x = (float) (3.0 - j/12.0)* (float) (cos(2.0*pi/32*i));
imgArray[i][j].y = (float) (3.0 - j/12.0)* (float) (sin(2.0*pi/32*i));
imgArray[i][j].z = (float) (-j);
}
}
init_fog();
return;
}
/* window close event */
if ( flag == false ) {
cpwDestroyWindow( cpw, winid );
return;
}
}
/****************************************************/
/* 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;
glViewport( 0, 0, width, height );
}
/****************************************************/
/* Timer Event Callback */
/****************************************************/
void timer( pCpw cpw, uint_32 id )
{
rot = rot + (float)rotspeed;
cpwPostWindowRedisplay( cpw, 1 );
}
/****************************************************/
/* 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;
switch( key ) {
case 'w': /* wireframe */
wireframe = !wireframe;
break;
case '?': /* help overlay */
help = !help;
break;
};
cpwPostWindowRedisplay( cpw, 1 );
}
void syskey( pCpw cpw, uint_32 id, uint_32 key, uint_32 state, uint_32 x, uint_32 y )
{
if ( key == CPW_KEY_ESCAPE )
cpwBreakMainLoop( cpw );
if ( key == CPW_KEY_UP )
rotspeed = rotspeed + (float).2;
if ( key == CPW_KEY_DOWN )
rotspeed = rotspeed - (float).2;
}
/****************************************************/
/* Create Texture Object Helper */
/****************************************************/
void registerTexture( CpwImage * image, uint_32 textureId )
{
GLenum format;
if ( image->depth == 3 )
format = GL_RGB;
else if ( image->depth == 4 )
format = GL_RGBA;
else return;
glBindTexture( GL_TEXTURE_2D, textureId );
glTexImage2D( GL_TEXTURE_2D,
0, /* no mipmaps */
image->depth,
image->width,
image->height,
0, /* no border */
format,
GL_UNSIGNED_BYTE,
image->data );
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR_MIPMAP_NEAREST);
gluBuild2DMipmaps(GL_TEXTURE_2D, 3, image->width, image->height, GL_RGB, GL_UNSIGNED_BYTE, image->data );
return;
}
/****************************************************/
/* Main */
/****************************************************/
int main(int argc, char* argv[])
{
pCpw cpw = null;
/****************************************************/
/* Init */
/****************************************************/
cpwInitContext( &cpw );
/****************************************************/
/* Creaing Windows */
/****************************************************/
windowInfo.id =
cpwCreateFullscreenWindow( cpw );
/*windowInfo.id =
cpwCreateWindowEx( cpw, "Images", windowInfo.x, windowInfo.y,
windowInfo.width, windowInfo.height );*/
/****************************************************/
/* Event Callbacks */
/****************************************************/
cpwCreateCallback( cpw, window );
cpwDisplayCallback( cpw, drawSceneOne );
cpwReshapeCallback( cpw, reshape );
cpwKeyboardCallback( cpw, keyboard );
cpwSystemKeyboardCallback( cpw, syskey );
cpwTimerCallback( cpw, 20, 1, true, timer );
/****************************************************/
/* Image Loading */
/****************************************************/
if ( !cpwLoadImage( cpw, &image1, CPW_IMAGEFORMAT_BMP, filename1, false ) ) {
printf( "File not found: %s\n", filename1 );
goto exithis;
}
/****************************************************/
/* 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, 18 );
cpwFontMode( cpw, CPW_FONTOPT_PIXELMAP_GLFORMAT, GL_RGBA );
cpwFontMode( cpw, CPW_FONTOPT_LAYOUTDEBUG, 0 );
font = cpwLoadFont( cpw, "arial.ttf", CPW_FONTLOC_HOST, "", "" );
/****************************************************/
/* OpenGL Texture Object Creation */
/****************************************************/
registerTexture( &image1, 1 );
/****************************************************/
/* MainLoop */
/****************************************************/
cpwMainLoop( cpw );
/****************************************************/
/* Exit and Free */
/****************************************************/
cpwFreeImage( cpw, &image1 );
exithis:
cpwFreeContext( &cpw );
return 0;
}