xenocara/dist/Mesa/progs/demos/fogcoord.c

427 lines
10 KiB
C
Raw Normal View History

2006-11-25 11:56:37 -07:00
/*
* EXT_fog_coord.
*
* Based on glutskel.c by Brian Paul
* and NeHe's Volumetric fog tutorial!
*
* Daniel Borca
*/
2007-11-24 10:25:28 -07:00
#define GL_GLEXT_PROTOTYPES
2006-11-25 11:56:37 -07:00
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <GL/glut.h>
2007-11-24 10:25:28 -07:00
#define DEPTH 5.0f
2006-11-25 11:56:37 -07:00
2007-11-24 10:25:28 -07:00
static PFNGLFOGCOORDFEXTPROC glFogCoordf_ext;
static PFNGLFOGCOORDPOINTEREXTPROC glFogCoordPointer_ext;
2006-11-25 11:56:37 -07:00
static GLboolean have_fog_coord;
static GLfloat camz;
static GLint fogMode;
static GLboolean fogCoord;
static GLfloat fogDensity = 0.75;
2007-11-24 10:25:28 -07:00
static GLfloat fogStart = 1.0, fogEnd = DEPTH;
2006-11-25 11:56:37 -07:00
static GLfloat fogColor[4] = {0.6f, 0.3f, 0.0f, 1.0f};
2007-11-24 10:25:28 -07:00
static const char *ModeStr = NULL;
static GLboolean Arrays = GL_FALSE;
static GLboolean Texture = GL_TRUE;
2006-11-25 11:56:37 -07:00
2007-11-24 10:25:28 -07:00
static void
Reset(void)
2006-11-25 11:56:37 -07:00
{
2007-11-24 10:25:28 -07:00
fogMode = 1;
fogCoord = 1;
fogDensity = 0.75;
fogStart = 1.0;
fogEnd = DEPTH;
Arrays = GL_FALSE;
Texture = GL_TRUE;
2006-11-25 11:56:37 -07:00
}
2007-11-24 10:25:28 -07:00
static void APIENTRY
glFogCoordf_nop (GLfloat f)
2006-11-25 11:56:37 -07:00
{
2007-11-24 10:25:28 -07:00
(void)f;
}
2006-11-25 11:56:37 -07:00
2007-11-24 10:25:28 -07:00
static void
PrintString(const char *s)
{
while (*s) {
glutBitmapCharacter(GLUT_BITMAP_8_BY_13, (int) *s);
s++;
2006-11-25 11:56:37 -07:00
}
2007-11-24 10:25:28 -07:00
}
2006-11-25 11:56:37 -07:00
2007-11-24 10:25:28 -07:00
static void
PrintInfo(void)
{
char s[100];
glDisable(GL_FOG);
glColor3f(0, 1, 1);
sprintf(s, "Mode(m): %s Start(s/S): %g End(e/E): %g Density(d/D): %g",
ModeStr, fogStart, fogEnd, fogDensity);
glWindowPos2iARB(5, 20);
PrintString(s);
sprintf(s, "Arrays(a): %s glFogCoord(c): %s EyeZ(z/z): %g",
(Arrays ? "Yes" : "No"),
(fogCoord ? "Yes" : "No"),
camz);
glWindowPos2iARB(5, 5);
PrintString(s);
2006-11-25 11:56:37 -07:00
}
2007-11-24 10:25:28 -07:00
static int
SetFogMode(GLint fogMode)
2006-11-25 11:56:37 -07:00
{
fogMode &= 3;
switch (fogMode) {
case 0:
2007-11-24 10:25:28 -07:00
ModeStr = "Off";
2006-11-25 11:56:37 -07:00
glDisable(GL_FOG);
break;
case 1:
2007-11-24 10:25:28 -07:00
ModeStr = "GL_LINEAR";
2006-11-25 11:56:37 -07:00
glEnable(GL_FOG);
glFogi(GL_FOG_MODE, GL_LINEAR);
glFogf(GL_FOG_START, fogStart);
glFogf(GL_FOG_END, fogEnd);
break;
case 2:
2007-11-24 10:25:28 -07:00
ModeStr = "GL_EXP";
2006-11-25 11:56:37 -07:00
glEnable(GL_FOG);
glFogi(GL_FOG_MODE, GL_EXP);
glFogf(GL_FOG_DENSITY, fogDensity);
break;
case 3:
2007-11-24 10:25:28 -07:00
ModeStr = "GL_EXP2";
2006-11-25 11:56:37 -07:00
glEnable(GL_FOG);
glFogi(GL_FOG_MODE, GL_EXP2);
glFogf(GL_FOG_DENSITY, fogDensity);
break;
}
return fogMode;
}
2007-11-24 10:25:28 -07:00
static GLboolean
SetFogCoord(GLboolean fogCoord)
2006-11-25 11:56:37 -07:00
{
glFogCoordf_ext = glFogCoordf_nop;
if (!have_fog_coord) {
return GL_FALSE;
}
if (fogCoord) {
2007-11-24 10:25:28 -07:00
glFogCoordf_ext = (PFNGLFOGCOORDFEXTPROC)glutGetProcAddress("glFogCoordfEXT");
2006-11-25 11:56:37 -07:00
glFogi(GL_FOG_COORDINATE_SOURCE_EXT, GL_FOG_COORDINATE_EXT);
2007-11-24 10:25:28 -07:00
}
else {
2006-11-25 11:56:37 -07:00
glFogi(GL_FOG_COORDINATE_SOURCE_EXT, GL_FRAGMENT_DEPTH_EXT);
}
return fogCoord;
}
/* could reuse vertices */
static GLuint vertex_index[] = {
/* Back */
0, 1, 2, 3,
/* Floor */
4, 5, 6, 7,
/* Roof */
8, 9, 10, 11,
/* Right */
12, 13, 14, 15,
/* Left */
16, 17, 18, 19
};
static GLfloat vertex_pointer[][3] = {
/* Back */
2007-11-24 10:25:28 -07:00
{-1.0f,-1.0f,-DEPTH}, { 1.0f,-1.0f,-DEPTH}, { 1.0f, 1.0f,-DEPTH}, {-1.0f, 1.0f,-DEPTH},
2006-11-25 11:56:37 -07:00
/* Floor */
2007-11-24 10:25:28 -07:00
{-1.0f,-1.0f,-DEPTH}, { 1.0f,-1.0f,-DEPTH}, { 1.0f,-1.0f, 0.0}, {-1.0f,-1.0f, 0.0},
2006-11-25 11:56:37 -07:00
/* Roof */
2007-11-24 10:25:28 -07:00
{-1.0f, 1.0f,-DEPTH}, { 1.0f, 1.0f,-DEPTH}, { 1.0f, 1.0f, 0.0}, {-1.0f, 1.0f, 0.0},
2006-11-25 11:56:37 -07:00
/* Right */
2007-11-24 10:25:28 -07:00
{ 1.0f,-1.0f, 0.0}, { 1.0f, 1.0f, 0.0}, { 1.0f, 1.0f,-DEPTH}, { 1.0f,-1.0f,-DEPTH},
2006-11-25 11:56:37 -07:00
/* Left */
2007-11-24 10:25:28 -07:00
{-1.0f,-1.0f, 0.0}, {-1.0f, 1.0f, 0.0}, {-1.0f, 1.0f,-DEPTH}, {-1.0f,-1.0f,-DEPTH}
2006-11-25 11:56:37 -07:00
};
static GLfloat texcoord_pointer[][2] = {
/* Back */
{0.0f, 0.0f}, {1.0f, 0.0f}, {1.0f, 1.0f}, {0.0f, 1.0f},
/* Floor */
2007-11-24 10:25:28 -07:00
{0.0f, 0.0f}, {1.0f, 0.0f}, {1.0f, DEPTH}, {0.0f, DEPTH},
2006-11-25 11:56:37 -07:00
/* Roof */
2007-11-24 10:25:28 -07:00
{1.0f, 0.0f}, {0.0f, 0.0f}, {0.0f, DEPTH}, {1.0f, DEPTH},
2006-11-25 11:56:37 -07:00
/* Right */
2007-11-24 10:25:28 -07:00
{0.0f, 1.0f}, {0.0f, 0.0f}, {DEPTH, 0.0f}, {DEPTH, 1.0f},
2006-11-25 11:56:37 -07:00
/* Left */
2007-11-24 10:25:28 -07:00
{0.0f, 0.0f}, {0.0f, 1.0f}, {DEPTH, 1.0f}, {DEPTH, 0.0f}
2006-11-25 11:56:37 -07:00
};
2007-11-24 10:25:28 -07:00
static GLfloat fogcoord_pointer[] = {
2006-11-25 11:56:37 -07:00
/* Back */
2007-11-24 10:25:28 -07:00
DEPTH, DEPTH, DEPTH, DEPTH,
2006-11-25 11:56:37 -07:00
/* Floor */
2007-11-24 10:25:28 -07:00
DEPTH, DEPTH, 0.0, 0.0,
2006-11-25 11:56:37 -07:00
/* Roof */
2007-11-24 10:25:28 -07:00
DEPTH, DEPTH, 0.0, 0.0,
2006-11-25 11:56:37 -07:00
/* Right */
2007-11-24 10:25:28 -07:00
0.0, 0.0, DEPTH, DEPTH,
2006-11-25 11:56:37 -07:00
/* Left */
2007-11-24 10:25:28 -07:00
0.0, 0.0, DEPTH, DEPTH
2006-11-25 11:56:37 -07:00
};
2007-11-24 10:25:28 -07:00
static void
Display( void )
2006-11-25 11:56:37 -07:00
{
glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity ();
2007-11-24 10:25:28 -07:00
glTranslatef(0.0f, 0.0f, -camz);
2006-11-25 11:56:37 -07:00
2007-11-24 10:25:28 -07:00
SetFogMode(fogMode);
2006-11-25 11:56:37 -07:00
2007-11-24 10:25:28 -07:00
glColor3f(1, 1, 1);
2006-11-25 11:56:37 -07:00
2007-11-24 10:25:28 -07:00
if (Texture)
glEnable(GL_TEXTURE_2D);
2006-11-25 11:56:37 -07:00
2007-11-24 10:25:28 -07:00
if (Arrays) {
glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glDrawElements(GL_QUADS, sizeof(vertex_index) / sizeof(vertex_index[0]),
GL_UNSIGNED_INT, vertex_index);
glDisableClientState(GL_VERTEX_ARRAY);
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
}
else {
/* Back */
glBegin(GL_QUADS);
glFogCoordf_ext(DEPTH); glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0f,-1.0f,-DEPTH);
glFogCoordf_ext(DEPTH); glTexCoord2f(1.0f, 0.0f); glVertex3f( 1.0f,-1.0f,-DEPTH);
glFogCoordf_ext(DEPTH); glTexCoord2f(1.0f, 1.0f); glVertex3f( 1.0f, 1.0f,-DEPTH);
glFogCoordf_ext(DEPTH); glTexCoord2f(0.0f, 1.0f); glVertex3f(-1.0f, 1.0f,-DEPTH);
glEnd();
/* Floor */
glBegin(GL_QUADS);
glFogCoordf_ext(DEPTH); glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0f,-1.0f,-DEPTH);
glFogCoordf_ext(DEPTH); glTexCoord2f(1.0f, 0.0f); glVertex3f( 1.0f,-1.0f,-DEPTH);
glFogCoordf_ext(0.0f); glTexCoord2f(1.0f, DEPTH); glVertex3f( 1.0f,-1.0f,0.0);
glFogCoordf_ext(0.0f); glTexCoord2f(0.0f, DEPTH); glVertex3f(-1.0f,-1.0f,0.0);
glEnd();
/* Roof */
glBegin(GL_QUADS);
glFogCoordf_ext(DEPTH); glTexCoord2f(1.0f, 0.0f); glVertex3f(-1.0f, 1.0f,-DEPTH);
glFogCoordf_ext(DEPTH); glTexCoord2f(0.0f, 0.0f); glVertex3f( 1.0f, 1.0f,-DEPTH);
glFogCoordf_ext(0.0f); glTexCoord2f(0.0f, DEPTH); glVertex3f( 1.0f, 1.0f,0.0);
glFogCoordf_ext(0.0f); glTexCoord2f(1.0f, DEPTH); glVertex3f(-1.0f, 1.0f,0.0);
glEnd();
/* Right */
glBegin(GL_QUADS);
glFogCoordf_ext(0.0f); glTexCoord2f(0.0f, 1.0f); glVertex3f( 1.0f,-1.0f,0.0);
glFogCoordf_ext(0.0f); glTexCoord2f(0.0f, 0.0f); glVertex3f( 1.0f, 1.0f,0.0);
glFogCoordf_ext(DEPTH); glTexCoord2f(DEPTH, 0.0f); glVertex3f( 1.0f, 1.0f,-DEPTH);
glFogCoordf_ext(DEPTH); glTexCoord2f(DEPTH, 1.0f); glVertex3f( 1.0f,-1.0f,-DEPTH);
glEnd();
/* Left */
glBegin(GL_QUADS);
glFogCoordf_ext(0.0f); glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0f,-1.0f,0.0);
glFogCoordf_ext(0.0f); glTexCoord2f(0.0f, 1.0f); glVertex3f(-1.0f, 1.0f,0.0);
glFogCoordf_ext(DEPTH); glTexCoord2f(DEPTH, 1.0f); glVertex3f(-1.0f, 1.0f,-DEPTH);
glFogCoordf_ext(DEPTH); glTexCoord2f(DEPTH, 0.0f); glVertex3f(-1.0f,-1.0f,-DEPTH);
glEnd();
}
2006-11-25 11:56:37 -07:00
2007-11-24 10:25:28 -07:00
glDisable(GL_TEXTURE_2D);
PrintInfo();
2006-11-25 11:56:37 -07:00
glutSwapBuffers();
}
2007-11-24 10:25:28 -07:00
static void
Reshape( int width, int height )
2006-11-25 11:56:37 -07:00
{
glViewport(0, 0, width, height);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
2007-11-24 10:25:28 -07:00
glFrustum(-1, 1, -1, 1, 1.0, 100);
2006-11-25 11:56:37 -07:00
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}
2007-11-24 10:25:28 -07:00
static void
Key( unsigned char key, int x, int y )
2006-11-25 11:56:37 -07:00
{
(void) x;
(void) y;
switch (key) {
2007-11-24 10:25:28 -07:00
case 'a':
Arrays = !Arrays;
break;
2006-11-25 11:56:37 -07:00
case 'f':
2007-11-24 10:25:28 -07:00
case 'm':
2006-11-25 11:56:37 -07:00
fogMode = SetFogMode(fogMode + 1);
break;
2007-11-24 10:25:28 -07:00
case 'D':
fogDensity += 0.05;
2006-11-25 11:56:37 -07:00
SetFogMode(fogMode);
break;
2007-11-24 10:25:28 -07:00
case 'd':
2006-11-25 11:56:37 -07:00
if (fogDensity > 0.0) {
fogDensity -= 0.05;
}
SetFogMode(fogMode);
break;
case 's':
if (fogStart > 0.0) {
2007-11-24 10:25:28 -07:00
fogStart -= 0.25;
2006-11-25 11:56:37 -07:00
}
SetFogMode(fogMode);
break;
case 'S':
2007-11-24 10:25:28 -07:00
if (fogStart < 100.0) {
fogStart += 0.25;
2006-11-25 11:56:37 -07:00
}
SetFogMode(fogMode);
break;
case 'e':
2007-11-24 10:25:28 -07:00
if (fogEnd > 0.0) {
fogEnd -= 0.25;
2006-11-25 11:56:37 -07:00
}
SetFogMode(fogMode);
break;
case 'E':
if (fogEnd < 100.0) {
2007-11-24 10:25:28 -07:00
fogEnd += 0.25;
2006-11-25 11:56:37 -07:00
}
SetFogMode(fogMode);
break;
case 'c':
fogCoord = SetFogCoord(fogCoord ^ GL_TRUE);
break;
2007-11-24 10:25:28 -07:00
case 't':
Texture = !Texture;
break;
case 'z':
camz -= 0.1;
break;
case 'Z':
camz += 0.1;
break;
case 'r':
Reset();
break;
2006-11-25 11:56:37 -07:00
case 27:
exit(0);
break;
}
glutPostRedisplay();
}
2007-11-24 10:25:28 -07:00
static void
Init(void)
2006-11-25 11:56:37 -07:00
{
2007-11-24 10:25:28 -07:00
static const GLubyte teximage[2][2][4] = {
{ { 255, 255, 255, 255}, { 128, 128, 128, 255} },
{ { 128, 128, 128, 255}, { 255, 255, 255, 255} }
};
2006-11-25 11:56:37 -07:00
2007-11-24 10:25:28 -07:00
printf("GL_RENDERER = %s\n", (char *) glGetString(GL_RENDERER));
2006-11-25 11:56:37 -07:00
have_fog_coord = glutExtensionSupported("GL_EXT_fog_coord");
2007-11-24 10:25:28 -07:00
if (!have_fog_coord) {
printf("GL_EXT_fog_coord not supported!\n");
2006-11-25 11:56:37 -07:00
}
2007-11-24 10:25:28 -07:00
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 2, 2, 0,
GL_RGBA, GL_UNSIGNED_BYTE, teximage);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glClearColor(0.1f, 0.1f, 0.1f, 0.0f);
2006-11-25 11:56:37 -07:00
glDepthFunc(GL_LEQUAL);
glEnable(GL_DEPTH_TEST);
glShadeModel(GL_SMOOTH);
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
glFogfv(GL_FOG_COLOR, fogColor);
glHint(GL_FOG_HINT, GL_NICEST);
fogCoord = SetFogCoord(GL_TRUE); /* try to enable fog_coord */
2007-11-24 10:25:28 -07:00
fogMode = SetFogMode(1);
2006-11-25 11:56:37 -07:00
glEnableClientState(GL_VERTEX_ARRAY);
glVertexPointer(3, GL_FLOAT, 0, vertex_pointer);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glTexCoordPointer(2, GL_FLOAT, 0, texcoord_pointer);
if (have_fog_coord) {
2007-11-24 10:25:28 -07:00
glFogCoordPointer_ext = (PFNGLFOGCOORDPOINTEREXTPROC)glutGetProcAddress("glFogCoordPointerEXT");
2006-11-25 11:56:37 -07:00
glEnableClientState(GL_FOG_COORDINATE_ARRAY_EXT);
glFogCoordPointer_ext(GL_FLOAT, 0, fogcoord_pointer);
}
2007-11-24 10:25:28 -07:00
Reset();
2006-11-25 11:56:37 -07:00
}
2007-11-24 10:25:28 -07:00
int
main( int argc, char *argv[] )
2006-11-25 11:56:37 -07:00
{
glutInit( &argc, argv );
2007-11-24 10:25:28 -07:00
glutInitWindowSize( 600, 600 );
2006-11-25 11:56:37 -07:00
glutInitDisplayMode( GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH );
glutCreateWindow(argv[0]);
glutReshapeFunc( Reshape );
glutKeyboardFunc( Key );
glutDisplayFunc( Display );
Init();
glutMainLoop();
return 0;
}