summaryrefslogtreecommitdiff
path: root/progs/demos/shadowtex.c
diff options
context:
space:
mode:
authorEric Anholt <eric@anholt.net>2010-05-21 09:32:38 -0700
committerEric Anholt <eric@anholt.net>2010-05-21 12:20:39 -0700
commit68fc4b415e322f6744299e39864fbc377c6eff74 (patch)
tree4bafffd8b0105174f3c5c0ae327a005be9145990 /progs/demos/shadowtex.c
parente4f4489e3fc0b36d72821b55794fb843b2b7fa5f (diff)
Remove demos that have moved to git+ssh://git.freedesktop.org/git/mesa/demos.
The remaining programs are ones I've had difficulty finding a build environment for to make the build system or are unit tests that should probably live next to their code instead. Hopefully people can bring over the build for remaining pieces they care about.
Diffstat (limited to 'progs/demos/shadowtex.c')
-rw-r--r--progs/demos/shadowtex.c1039
1 files changed, 0 insertions, 1039 deletions
diff --git a/progs/demos/shadowtex.c b/progs/demos/shadowtex.c
deleted file mode 100644
index 677a42104f..0000000000
--- a/progs/demos/shadowtex.c
+++ /dev/null
@@ -1,1039 +0,0 @@
-/*
- * Shadow demo using the GL_ARB_depth_texture, GL_ARB_shadow and
- * GL_ARB_shadow_ambient extensions.
- *
- * Brian Paul
- * 19 Feb 2001
- *
- * Added GL_EXT_shadow_funcs support on 23 March 2002
- * Added GL_EXT_packed_depth_stencil support on 15 March 2006.
- * Added GL_EXT_framebuffer_object support on 27 March 2006.
- * Removed old SGIX extension support on 5 April 2006.
- * Added vertex / fragment program support on 7 June 2007 (Ian Romanick).
- *
- * Copyright (C) 1999-2006 Brian Paul All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included
- * in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
- * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- */
-
-#include <assert.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <math.h>
-#include <GL/glew.h>
-#include <GL/glut.h>
-
-#define DEG_TO_RAD (3.14159 / 180.0)
-
-static GLint WindowWidth = 450, WindowHeight = 300;
-static GLfloat Xrot = 15, Yrot = 0, Zrot = 0;
-
-static GLfloat Red[4] = {1, 0, 0, 1};
-static GLfloat Green[4] = {0, 1, 0, 1};
-static GLfloat Blue[4] = {0, 0, 1, 1};
-static GLfloat Yellow[4] = {1, 1, 0, 1};
-
-static GLfloat LightDist = 10;
-static GLfloat LightLatitude = 45.0;
-static GLfloat LightLongitude = 45.0;
-static GLfloat LightPos[4];
-static GLfloat SpotDir[3];
-static GLfloat SpotAngle = 40.0 * DEG_TO_RAD;
-static GLfloat ShadowNear = 4.0, ShadowFar = 24.0;
-static GLint ShadowTexWidth = 256, ShadowTexHeight = 256;
-
-static GLboolean LinearFilter = GL_FALSE;
-
-static GLfloat Bias = -0.06;
-
-static GLboolean Anim = GL_TRUE;
-
-static GLboolean NeedNewShadowMap = GL_FALSE;
-static GLuint ShadowTexture, GrayTexture;
-static GLuint ShadowFBO;
-
-static GLfloat lightModelview[16];
-static GLfloat lightProjection[16];
-
-static GLuint vert_prog;
-static GLuint frag_progs[3];
-static GLuint curr_frag = 0;
-static GLuint max_frag = 1;
-
-#define NUM_FRAG_MODES 3
-static const char *FragProgNames[] = {
- "fixed-function",
- "program without \"OPTION ARB_fragment_program_shadow\"",
- "program with \"OPTION ARB_fragment_program_shadow\"",
-};
-
-static GLboolean HaveShadow = GL_FALSE;
-static GLboolean HaveFBO = GL_FALSE;
-static GLboolean UseFBO = GL_FALSE;
-static GLboolean HaveVP = GL_FALSE;
-static GLboolean HaveFP = GL_FALSE;
-static GLboolean HaveFP_Shadow = GL_FALSE;
-static GLboolean UseVP = GL_FALSE;
-static GLboolean HavePackedDepthStencil = GL_FALSE;
-static GLboolean UsePackedDepthStencil = GL_FALSE;
-static GLboolean HaveEXTshadowFuncs = GL_FALSE;
-static GLboolean HaveShadowAmbient = GL_FALSE;
-
-static GLint Operator = 0;
-static const GLenum OperatorFunc[8] = {
- GL_LEQUAL, GL_LESS, GL_GEQUAL, GL_GREATER,
- GL_EQUAL, GL_NOTEQUAL, GL_ALWAYS, GL_NEVER };
-static const char *OperatorName[8] = {
- "GL_LEQUAL", "GL_LESS", "GL_GEQUAL", "GL_GREATER",
- "GL_EQUAL", "GL_NOTEQUAL", "GL_ALWAYS", "GL_NEVER" };
-
-
-static GLuint DisplayMode;
-#define SHOW_SHADOWS 0
-#define SHOW_DEPTH_IMAGE 1
-#define SHOW_DEPTH_MAPPING 2
-#define SHOW_DISTANCE 3
-
-
-
-#define MAT4_MUL(dest_vec, src_mat, src_vec) \
- "DP4 " dest_vec ".x, " src_mat "[0], " src_vec ";\n" \
- "DP4 " dest_vec ".y, " src_mat "[1], " src_vec ";\n" \
- "DP4 " dest_vec ".z, " src_mat "[2], " src_vec ";\n" \
- "DP4 " dest_vec ".w, " src_mat "[3], " src_vec ";\n"
-
-#define MAT3_MUL(dest_vec, src_mat, src_vec) \
- "DP3 " dest_vec ".x, " src_mat "[0], " src_vec ";\n" \
- "DP3 " dest_vec ".y, " src_mat "[1], " src_vec ";\n" \
- "DP3 " dest_vec ".z, " src_mat "[2], " src_vec ";\n"
-
-#define NORMALIZE(dest, src) \
- "DP3 " dest ".w, " src ", " src ";\n" \
- "RSQ " dest ".w, " dest ".w;\n" \
- "MUL " dest ", " src ", " dest ".w;\n"
-
-/**
- * Vertex program for shadow mapping.
- */
-static const char vert_code[] =
- "!!ARBvp1.0\n"
- "ATTRIB iPos = vertex.position;\n"
- "ATTRIB iNorm = vertex.normal;\n"
-
- "PARAM mvinv[4] = { state.matrix.modelview.invtrans };\n"
- "PARAM mvp[4] = { state.matrix.mvp };\n"
- "PARAM mv[4] = { state.matrix.modelview };\n"
- "PARAM texmat[4] = { state.matrix.texture[0] };\n"
- "PARAM lightPos = state.light[0].position;\n"
- "PARAM ambientCol = state.lightprod[0].ambient;\n"
- "PARAM diffuseCol = state.lightprod[0].diffuse;\n"
-
- "TEMP n, lightVec;\n"
- "ALIAS V = lightVec;\n"
- "ALIAS NdotL = n;\n"
-
- "OUTPUT oPos = result.position;\n"
- "OUTPUT oColor = result.color;\n"
- "OUTPUT oTex = result.texcoord[0];\n"
-
- /* Transform the vertex to clip coordinates. */
- MAT4_MUL("oPos", "mvp", "iPos")
-
- /* Transform the vertex to eye coordinates. */
- MAT4_MUL("V", "mv", "iPos")
-
- /* Transform the vertex to projected light coordinates. */
- MAT4_MUL("oTex", "texmat", "iPos")
-
- /* Transform the normal to eye coordinates. */
- MAT3_MUL("n", "mvinv", "iNorm")
-
- /* Calculate the vector from the vertex to the light in eye
- * coordinates.
- */
- "SUB lightVec, lightPos, V;\n"
- NORMALIZE("lightVec", "lightVec")
-
- /* Compute diffuse lighting coefficient.
- */
- "DP3 NdotL.x, n, lightVec;\n"
- "MAX NdotL.x, NdotL.x, {0.0};\n"
- "MIN NdotL.x, NdotL.x, {1.0};\n"
-
- /* Accumulate color contributions.
- */
- "MOV oColor, diffuseCol;\n"
- "MAD oColor.xyz, NdotL.x, diffuseCol, ambientCol;\n"
- "END\n"
- ;
-
-static const char frag_code[] =
- "!!ARBfp1.0\n"
-
- "TEMP shadow, temp;\n"
-
- "TXP shadow, fragment.texcoord[0], texture[0], 2D;\n"
- "RCP temp.x, fragment.texcoord[0].w;\n"
- "MUL temp.x, temp.x, fragment.texcoord[0].z;\n"
- "SGE shadow, shadow.x, temp.x;\n"
- "MUL result.color.rgb, fragment.color, shadow.x;\n"
- "MOV result.color.a, fragment.color;\n"
- "END\n"
- ;
-
-static const char frag_shadow_code[] =
- "!!ARBfp1.0\n"
- "OPTION ARB_fragment_program_shadow;\n"
-
- "TEMP shadow;\n"
-
- "TXP shadow, fragment.texcoord[0], texture[0], SHADOW2D;\n"
- "MUL result.color.rgb, fragment.color, shadow.x;\n"
- "MOV result.color.a, fragment.color.a;\n"
- "END\n"
- ;
-
-static void
-DrawScene(void)
-{
- GLfloat k = 6;
-
- /* sphere */
- glPushMatrix();
- glTranslatef(1.6, 2.2, 2.7);
- glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, Green);
- glColor4fv(Green);
- glutSolidSphere(1.5, 15, 15);
- glPopMatrix();
- /* dodecahedron */
- glPushMatrix();
- glTranslatef(-2.0, 1.2, 2.1);
- glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, Red);
- glColor4fv(Red);
- glutSolidDodecahedron();
- glPopMatrix();
- /* icosahedron */
- glPushMatrix();
- glTranslatef(-0.6, 1.3, -0.5);
- glScalef(1.5, 1.5, 1.5);
- glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, Yellow);
- glColor4fv(Red);
- glutSolidIcosahedron();
- glPopMatrix();
- /* a plane */
- glPushMatrix();
- glTranslatef(0, -1.1, 0);
- glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, Blue);
- glColor4fv(Blue);
- glNormal3f(0, 1, 0);
- glBegin(GL_POLYGON);
- glVertex3f(-k, 0, -k);
- glVertex3f( k, 0, -k);
- glVertex3f( k, 0, k);
- glVertex3f(-k, 0, k);
- glEnd();
- glPopMatrix();
-}
-
-
-/**
- * Calculate modelview and project matrices for the light
- *
- * Stores the results in \c lightProjection (projection matrix) and
- * \c lightModelview (modelview matrix).
- */
-static void
-MakeShadowMatrix(const GLfloat lightPos[4], const GLfloat spotDir[3],
- GLfloat spotAngle, GLfloat shadowNear, GLfloat shadowFar)
-{
- /* compute frustum to enclose spot light cone */
- const GLfloat d = shadowNear * tan(spotAngle);
-
- glMatrixMode(GL_PROJECTION);
- glPushMatrix();
- glLoadIdentity();
- glFrustum(-d, d, -d, d, shadowNear, shadowFar);
- glGetFloatv(GL_PROJECTION_MATRIX, lightProjection);
- glPopMatrix();
-
- glMatrixMode(GL_MODELVIEW);
- glPushMatrix();
- glLoadIdentity();
- gluLookAt(lightPos[0], lightPos[1], lightPos[2],
- lightPos[0] + spotDir[0],
- lightPos[1] + spotDir[1],
- lightPos[2] + spotDir[2],
- 0.0, 1.0, 0.0);
- glGetFloatv(GL_MODELVIEW_MATRIX, lightModelview);
- glPopMatrix();
-}
-
-
-/**
- * Load \c GL_TEXTURE matrix with light's MVP matrix.
- */
-static void SetShadowTextureMatrix(void)
-{
- static const GLfloat biasMatrix[16] = {
- 0.5, 0.0, 0.0, 0.0,
- 0.0, 0.5, 0.0, 0.0,
- 0.0, 0.0, 0.5, 0.0,
- 0.5, 0.5, 0.5, 1.0,
- };
-
- glMatrixMode(GL_TEXTURE);
- glLoadMatrixf(biasMatrix);
- glTranslatef(0.0, 0.0, Bias);
- glMultMatrixf(lightProjection);
- glMultMatrixf(lightModelview);
- glMatrixMode(GL_MODELVIEW);
-}
-
-
-static void
-EnableIdentityTexgen(void)
-{
- /* texgen so that texcoord = vertex coord */
- static GLfloat sPlane[4] = { 1, 0, 0, 0 };
- static GLfloat tPlane[4] = { 0, 1, 0, 0 };
- static GLfloat rPlane[4] = { 0, 0, 1, 0 };
- static GLfloat qPlane[4] = { 0, 0, 0, 1 };
-
- glTexGenfv(GL_S, GL_EYE_PLANE, sPlane);
- glTexGenfv(GL_T, GL_EYE_PLANE, tPlane);
- glTexGenfv(GL_R, GL_EYE_PLANE, rPlane);
- glTexGenfv(GL_Q, GL_EYE_PLANE, qPlane);
- glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
- glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
- glTexGeni(GL_R, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
- glTexGeni(GL_Q, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
-
- glEnable(GL_TEXTURE_GEN_S);
- glEnable(GL_TEXTURE_GEN_T);
- glEnable(GL_TEXTURE_GEN_R);
- glEnable(GL_TEXTURE_GEN_Q);
-}
-
-
-/*
- * Setup 1-D texgen so that the distance from the light source, between
- * the near and far planes maps to s=0 and s=1. When we draw the scene,
- * the grayness will indicate the fragment's distance from the light
- * source.
- */
-static void
-EnableDistanceTexgen(const GLfloat lightPos[4], const GLfloat lightDir[3],
- GLfloat lightNear, GLfloat lightFar)
-{
- GLfloat m, d;
- GLfloat sPlane[4];
- GLfloat nearPoint[3];
-
- m = sqrt(lightDir[0] * lightDir[0] +
- lightDir[1] * lightDir[1] +
- lightDir[2] * lightDir[2]);
-
- d = lightFar - lightNear;
-
- /* nearPoint = point on light direction vector which intersects the
- * near plane of the light frustum.
- */
- nearPoint[0] = lightPos[0] + lightDir[0] / m * lightNear;
- nearPoint[1] = lightPos[1] + lightDir[1] / m * lightNear;
- nearPoint[2] = lightPos[2] + lightDir[2] / m * lightNear;
-
- sPlane[0] = lightDir[0] / d / m;
- sPlane[1] = lightDir[1] / d / m;
- sPlane[2] = lightDir[2] / d / m;
- sPlane[3] = -(sPlane[0] * nearPoint[0]
- + sPlane[1] * nearPoint[1]
- + sPlane[2] * nearPoint[2]);
-
- glTexGenfv(GL_S, GL_EYE_PLANE, sPlane);
- glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
- glEnable(GL_TEXTURE_GEN_S);
-}
-
-
-static void
-DisableTexgen(void)
-{
- glDisable(GL_TEXTURE_GEN_S);
- glDisable(GL_TEXTURE_GEN_T);
- glDisable(GL_TEXTURE_GEN_R);
- glDisable(GL_TEXTURE_GEN_Q);
-}
-
-
-static void
-ComputeLightPos(GLfloat dist, GLfloat latitude, GLfloat longitude,
- GLfloat pos[4], GLfloat dir[3])
-{
-
- pos[0] = dist * sin(longitude * DEG_TO_RAD);
- pos[1] = dist * sin(latitude * DEG_TO_RAD);
- pos[2] = dist * cos(latitude * DEG_TO_RAD) * cos(longitude * DEG_TO_RAD);
- pos[3] = 1;
- dir[0] = -pos[0];
- dir[1] = -pos[1];
- dir[2] = -pos[2];
-}
-
-
-/**
- * Render the shadow map / depth texture.
- * The result will be in the texture object named ShadowTexture.
- */
-static void
-RenderShadowMap(void)
-{
- GLenum depthFormat; /* GL_DEPTH_COMPONENT or GL_DEPTH_STENCIL_EXT */
- GLenum depthType; /* GL_UNSIGNED_INT_24_8_EXT or GL_UNSIGNED_INT */
-
- if (WindowWidth >= 1024 && WindowHeight >= 1024) {
- ShadowTexWidth = ShadowTexHeight = 1024;
- }
- else if (WindowWidth >= 512 && WindowHeight >= 512) {
- ShadowTexWidth = ShadowTexHeight = 512;
- }
- else if (WindowWidth >= 256 && WindowHeight >= 256) {
- ShadowTexWidth = ShadowTexHeight = 256;
- }
- else {
- ShadowTexWidth = ShadowTexHeight = 128;
- }
- printf("Rendering %d x %d depth texture\n", ShadowTexWidth, ShadowTexHeight);
-
- if (UsePackedDepthStencil) {
- depthFormat = GL_DEPTH_STENCIL_EXT;
- depthType = GL_UNSIGNED_INT_24_8_EXT;
- }
- else {
- depthFormat = GL_DEPTH_COMPONENT;
- depthType = GL_UNSIGNED_INT;
- }
-
- glMatrixMode(GL_PROJECTION);
- glLoadMatrixf(lightProjection);
-
- glMatrixMode(GL_MODELVIEW);
- glLoadMatrixf(lightModelview);
-
- if (UseFBO) {
- GLenum fbo_status;
-
- glTexImage2D(GL_TEXTURE_2D, 0, depthFormat,
- ShadowTexWidth, ShadowTexHeight, 0,
- depthFormat, depthType, NULL);
-
- /* Set the filter mode so that the texture is texture-complete.
- * Otherwise it will cause the framebuffer to fail the framebuffer
- * completeness test.
- */
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
-
- glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, ShadowFBO);
- glDrawBuffer(GL_NONE);
- glReadBuffer(GL_NONE);
-
- fbo_status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT);
- if (fbo_status != GL_FRAMEBUFFER_COMPLETE_EXT) {
- fprintf(stderr, "FBO not complete! status = 0x%04x\n", fbo_status);
- assert(fbo_status == GL_FRAMEBUFFER_COMPLETE_EXT);
- }
- }
-
- assert(!glIsEnabled(GL_TEXTURE_1D));
- assert(!glIsEnabled(GL_TEXTURE_2D));
-
- glViewport(0, 0, ShadowTexWidth, ShadowTexHeight);
- glClear(GL_DEPTH_BUFFER_BIT);
- glEnable(GL_DEPTH_TEST);
- DrawScene();
-
- if (UseFBO) {
- /* all done! */
- glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
- }
- else {
- /*
- * copy depth buffer into the texture map
- */
- if (DisplayMode == SHOW_DEPTH_MAPPING) {
- /* load depth image as gray-scale luminance texture */
- GLuint *depth = (GLuint *)
- malloc(ShadowTexWidth * ShadowTexHeight * sizeof(GLuint));
- assert(depth);
- glReadPixels(0, 0, ShadowTexWidth, ShadowTexHeight,
- depthFormat, depthType, depth);
- glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE,
- ShadowTexWidth, ShadowTexHeight, 0,
- GL_LUMINANCE, GL_UNSIGNED_INT, depth);
- free(depth);
- }
- else {
- /* The normal shadow case - a real depth texture */
- glCopyTexImage2D(GL_TEXTURE_2D, 0, depthFormat,
- 0, 0, ShadowTexWidth, ShadowTexHeight, 0);
- if (UsePackedDepthStencil) {
- /* debug check */
- GLint intFormat;
- glGetTexLevelParameteriv(GL_TEXTURE_2D, 0,
- GL_TEXTURE_INTERNAL_FORMAT, &intFormat);
- assert(intFormat == GL_DEPTH_STENCIL_EXT);
- }
- }
- }
-}
-
-
-/**
- * Show the shadow map as a grayscale image.
- */
-static void
-ShowShadowMap(void)
-{
- glClear(GL_COLOR_BUFFER_BIT);
-
- glMatrixMode(GL_TEXTURE);
- glLoadIdentity();
-
- glMatrixMode(GL_PROJECTION);
- glLoadIdentity();
- glOrtho(0, WindowWidth, 0, WindowHeight, -1, 1);
-
- glMatrixMode(GL_MODELVIEW);
- glLoadIdentity();
-
- glDisable(GL_DEPTH_TEST);
- glDisable(GL_LIGHTING);
-
- glEnable(GL_TEXTURE_2D);
-
- DisableTexgen();
-
- /* interpret texture's depth values as luminance values */
- if (HaveShadow) {
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE_ARB, GL_NONE);
- }
-
- glTexParameteri(GL_TEXTURE_2D, GL_DEPTH_TEXTURE_MODE_ARB, GL_LUMINANCE);
- glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
-
- glBegin(GL_POLYGON);
- glTexCoord2f(0, 0); glVertex2f(0, 0);
- glTexCoord2f(1, 0); glVertex2f(ShadowTexWidth, 0);
- glTexCoord2f(1, 1); glVertex2f(ShadowTexWidth, ShadowTexHeight);
- glTexCoord2f(0, 1); glVertex2f(0, ShadowTexHeight);
- glEnd();
-
- glDisable(GL_TEXTURE_2D);
- glEnable(GL_DEPTH_TEST);
- glEnable(GL_LIGHTING);
-}
-
-
-/**
- * Redraw window image
- */
-static void
-Display(void)
-{
- GLenum error;
-
- ComputeLightPos(LightDist, LightLatitude, LightLongitude,
- LightPos, SpotDir);
-
- if (NeedNewShadowMap) {
- MakeShadowMatrix(LightPos, SpotDir, SpotAngle, ShadowNear, ShadowFar);
- RenderShadowMap();
- NeedNewShadowMap = GL_FALSE;
- }
-
- glViewport(0, 0, WindowWidth, WindowHeight);
- if (DisplayMode == SHOW_DEPTH_IMAGE) {
- ShowShadowMap();
- }
- else {
- /* prepare to draw scene from camera's view */
- const GLfloat ar = (GLfloat) WindowWidth / (GLfloat) WindowHeight;
-
- glMatrixMode(GL_PROJECTION);
- glLoadIdentity();
- glFrustum(-ar, ar, -1.0, 1.0, 4.0, 50.0);
-
- glMatrixMode(GL_MODELVIEW);
- glLoadIdentity();
- glTranslatef(0.0, 0.0, -22.0);
- glRotatef(Xrot, 1, 0, 0);
- glRotatef(Yrot, 0, 1, 0);
- glRotatef(Zrot, 0, 0, 1);
-
- glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
-
- glLightfv(GL_LIGHT0, GL_POSITION, LightPos);
-
- if (LinearFilter) {
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
- }
- else {
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
- }
-
- if (DisplayMode == SHOW_DEPTH_MAPPING) {
- if (HaveShadow) {
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE_ARB, GL_NONE);
- }
- glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
- glEnable(GL_TEXTURE_2D);
-
- SetShadowTextureMatrix();
- EnableIdentityTexgen();
- }
- else if (DisplayMode == SHOW_DISTANCE) {
- glMatrixMode(GL_TEXTURE);
- glLoadIdentity();
- glMatrixMode(GL_MODELVIEW);
- EnableDistanceTexgen(LightPos, SpotDir, ShadowNear+Bias, ShadowFar);
- glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
- glEnable(GL_TEXTURE_1D);
- assert(!glIsEnabled(GL_TEXTURE_2D));
- }
- else {
- assert(DisplayMode == SHOW_SHADOWS);
- if (HaveShadow) {
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE_ARB,
- GL_COMPARE_R_TO_TEXTURE_ARB);
- }
-
- if (curr_frag > 0) {
- glEnable(GL_FRAGMENT_PROGRAM_ARB);
- }
- else {
- glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
- }
- glEnable(GL_TEXTURE_2D);
-
- SetShadowTextureMatrix();
-
- if (UseVP) {
- glEnable(GL_VERTEX_PROGRAM_ARB);
- }
- else {
- glEnable(GL_LIGHTING);
- EnableIdentityTexgen();
- }
- }
-
- DrawScene();
-
- if (UseVP) {
- glDisable(GL_VERTEX_PROGRAM_ARB);
- }
- else {
- DisableTexgen();
- glDisable(GL_LIGHTING);
- }
-
- if (curr_frag > 0) {
- glDisable(GL_FRAGMENT_PROGRAM_ARB);
- }
-
- glDisable(GL_TEXTURE_1D);
- glDisable(GL_TEXTURE_2D);
- }
-
- glutSwapBuffers();
-
- error = glGetError();
- if (error) {
- printf("GL Error: %s\n", (char *) gluErrorString(error));
- }
-}
-
-
-static void
-Reshape(int width, int height)
-{
- WindowWidth = width;
- WindowHeight = height;
- NeedNewShadowMap = GL_TRUE;
-}
-
-
-static void
-Idle(void)
-{
- static double t0 = -1.;
- double dt, t = glutGet(GLUT_ELAPSED_TIME) / 1000.0;
- if (t0 < 0.0)
- t0 = t;
- dt = t - t0;
- t0 = t;
- Yrot += 75.0 * dt;
- /*LightLongitude -= 5.0;*/
- glutPostRedisplay();
-}
-
-
-static void
-Key(unsigned char key, int x, int y)
-{
- const GLfloat step = 3.0;
- (void) x;
- (void) y;
- switch (key) {
- case 'a':
- Anim = !Anim;
- if (Anim)
- glutIdleFunc(Idle);
- else
- glutIdleFunc(NULL);
- break;
- case 'b':
- Bias -= 0.01;
- printf("Bias %g\n", Bias);
- break;
- case 'B':
- Bias += 0.01;
- printf("Bias %g\n", Bias);
- break;
- case 'd':
- DisplayMode = SHOW_DISTANCE;
- break;
- case 'f':
- LinearFilter = !LinearFilter;
- printf("%s filtering\n", LinearFilter ? "Bilinear" : "Nearest");
- break;
- case 'i':
- DisplayMode = SHOW_DEPTH_IMAGE;
- break;
- case 'm':
- DisplayMode = SHOW_DEPTH_MAPPING;
- break;
- case 'M':
- curr_frag = (1 + curr_frag) % max_frag;
- if (!HaveShadow && (curr_frag == 0)) {
- curr_frag = 1;
- }
-
- printf("Using fragment %s\n", FragProgNames[curr_frag]);
-
- if (HaveFP) {
- glBindProgramARB(GL_FRAGMENT_PROGRAM_ARB, frag_progs[curr_frag]);
- }
- break;
- case 'n':
- case 's':
- case ' ':
- DisplayMode = SHOW_SHADOWS;
- break;
- case 'o':
- if (HaveEXTshadowFuncs) {
- Operator++;
- if (Operator >= 8)
- Operator = 0;
- printf("Operator: %s\n", OperatorName[Operator]);
- if (HaveShadow) {
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC_ARB,
- OperatorFunc[Operator]);
- }
- }
- break;
- case 'p':
- UsePackedDepthStencil = !UsePackedDepthStencil;
- if (UsePackedDepthStencil && !HavePackedDepthStencil) {
- printf("Sorry, GL_EXT_packed_depth_stencil not supported\n");
- UsePackedDepthStencil = GL_FALSE;
- }
- else {
- printf("Use GL_DEPTH_STENCIL_EXT: %d\n", UsePackedDepthStencil);
- /* Don't really need to regenerate shadow map texture, but do so
- * to exercise more code more often.
- */
- NeedNewShadowMap = GL_TRUE;
- }
- break;
- case 'v':
- UseVP = !UseVP && HaveVP;
- printf("Using vertex %s mode.\n",
- UseVP ? "program" : "fixed-function");
- break;
- case 'z':
- Zrot -= step;
- break;
- case 'Z':
- Zrot += step;
- break;
- case 27:
- exit(0);
- break;
- }
- fflush(stdout);
- glutPostRedisplay();
-}
-
-
-static void
-SpecialKey(int key, int x, int y)
-{
- const GLfloat step = 3.0;
- const int mod = glutGetModifiers();
- (void) x;
- (void) y;
- switch (key) {
- case GLUT_KEY_UP:
- if (mod)
- LightLatitude += step;
- else
- Xrot += step;
- break;
- case GLUT_KEY_DOWN:
- if (mod)
- LightLatitude -= step;
- else
- Xrot -= step;
- break;
- case GLUT_KEY_LEFT:
- if (mod)
- LightLongitude += step;
- else
- Yrot += step;
- break;
- case GLUT_KEY_RIGHT:
- if (mod)
- LightLongitude -= step;
- else
- Yrot -= step;
- break;
- }
- if (mod)
- NeedNewShadowMap = GL_TRUE;
-
- glutPostRedisplay();
-}
-
-
-/* A helper for finding errors in program strings */
-static int FindLine( const char *program, int position )
-{
- int i, line = 1;
- for (i = 0; i < position; i++) {
- if (program[i] == '\n')
- line++;
- }
- return line;
-}
-
-
-static GLuint
-compile_program(GLenum target, const char *code)
-{
- GLuint p;
- GLint errorPos;
-
-
- glGenProgramsARB(1, & p);
-
- glBindProgramARB(target, p);
- glProgramStringARB(target, GL_PROGRAM_FORMAT_ASCII_ARB,
- strlen(code), code);
- glGetIntegerv(GL_PROGRAM_ERROR_POSITION_ARB, &errorPos);
- if (glGetError() != GL_NO_ERROR || errorPos != -1) {
- int l = FindLine(code, errorPos);
- printf("Fragment Program Error (pos=%d line=%d): %s\n", errorPos, l,
- (char *) glGetString(GL_PROGRAM_ERROR_STRING_ARB));
- exit(0);
- }
-
- glBindProgramARB(target, 0);
- return p;
-}
-
-static void
-Init(void)
-{
- static const GLfloat borderColor[4] = {1.0, 0.0, 0.0, 0.0};
-
- if (!glutExtensionSupported("GL_ARB_depth_texture")) {
- printf("Sorry, this demo requires the GL_ARB_depth_texture extension\n");
- exit(1);
- }
-
- HaveShadow = glutExtensionSupported("GL_ARB_shadow");
- HaveVP = glutExtensionSupported("GL_ARB_vertex_program");
- HaveFP = glutExtensionSupported("GL_ARB_fragment_program");
- HaveFP_Shadow = glutExtensionSupported("GL_ARB_fragment_program_shadow");
-
- if (!HaveShadow && !HaveFP) {
- printf("Sorry, this demo requires either the GL_ARB_shadow extension "
- "or the GL_ARB_fragment_program extension\n");
- exit(1);
- }
-
- printf("Using GL_ARB_depth_texture\n");
- if (HaveShadow) {
- printf("and GL_ARB_shadow\n");
- }
-
- if (HaveFP) {
- printf("and GL_ARB_fragment_program\n");
- }
-
- HaveShadowAmbient = glutExtensionSupported("GL_ARB_shadow_ambient");
- if (HaveShadowAmbient) {
- printf("and GL_ARB_shadow_ambient\n");
- }
-
- HaveEXTshadowFuncs = glutExtensionSupported("GL_EXT_shadow_funcs");
-
- HavePackedDepthStencil = glutExtensionSupported("GL_EXT_packed_depth_stencil");
- UsePackedDepthStencil = HavePackedDepthStencil;
-
-#if defined(GL_EXT_framebuffer_object)
- HaveFBO = glutExtensionSupported("GL_EXT_framebuffer_object");
- UseFBO = HaveFBO;
- if (UseFBO) {
- printf("Using GL_EXT_framebuffer_object\n");
- }
-#endif
-
- /*
- * Set up the 2D shadow map texture
- */
- glGenTextures(1, &ShadowTexture);
- glBindTexture(GL_TEXTURE_2D, ShadowTexture);
- glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, borderColor);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
-
- if (HaveShadow) {
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE_ARB,
- GL_COMPARE_R_TO_TEXTURE_ARB);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC_ARB, GL_LEQUAL);
- }
-
- if (HaveShadowAmbient) {
- glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FAIL_VALUE_ARB, 0.3);
- }
-
-#if defined(GL_EXT_framebuffer_object)
- if (UseFBO) {
- glGenFramebuffersEXT(1, &ShadowFBO);
- glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, ShadowFBO);
- glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT,
- GL_COLOR_ATTACHMENT0_EXT,
- GL_RENDERBUFFER_EXT, 0);
- glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT,
- GL_TEXTURE_2D, ShadowTexture, 0);
-
- glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
- }
-#endif
-
- /*
- * Setup 1-D grayscale texture image for SHOW_DISTANCE mode
- */
- glGenTextures(1, &GrayTexture);
- glBindTexture(GL_TEXTURE_1D, GrayTexture);
- glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_WRAP_S, GL_CLAMP);
- glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
- glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
- {
- GLuint i;
- GLubyte image[256];
- for (i = 0; i < 256; i++)
- image[i] = i;
- glTexImage1D(GL_TEXTURE_1D, 0, GL_LUMINANCE,
- 256, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, image);
- }
-
- if (HaveVP) {
- vert_prog = compile_program(GL_VERTEX_PROGRAM_ARB, vert_code);
- glBindProgramARB(GL_VERTEX_PROGRAM_ARB, vert_prog);
- }
-
- max_frag = 1;
- frag_progs[0] = 0;
-
- if (HaveFP) {
- frag_progs[1] = compile_program(GL_FRAGMENT_PROGRAM_ARB, frag_code);
- max_frag = 2;
- }
-
- if (HaveFP && HaveFP_Shadow) {
- frag_progs[2] = compile_program(GL_FRAGMENT_PROGRAM_ARB,
- frag_shadow_code);
- max_frag = 3;
- }
-
- if (!HaveShadow) {
- curr_frag = 1;
- glBindProgramARB(GL_FRAGMENT_PROGRAM_ARB, frag_progs[curr_frag]);
- }
-
- glEnable(GL_DEPTH_TEST);
- glEnable(GL_LIGHTING);
- glEnable(GL_LIGHT0);
-}
-
-
-static void
-PrintHelp(void)
-{
- printf("Keys:\n");
- printf(" a = toggle animation\n");
- printf(" i = show depth texture image\n");
- printf(" m = show depth texture mapping\n");
- printf(" d = show fragment distance from light source\n");
- printf(" n = show normal, shadowed image\n");
- printf(" f = toggle nearest/bilinear texture filtering\n");
- printf(" b/B = decrease/increase shadow map Z bias\n");
- printf(" p = toggle use of packed depth/stencil\n");
- printf(" M = cycle through fragment program modes\n");
- printf(" v = toggle vertex program modes\n");
- printf(" cursor keys = rotate scene\n");
- printf(" <shift> + cursor keys = rotate light source\n");
- if (HaveEXTshadowFuncs)
- printf(" o = cycle through comparison modes\n");
- fflush(stdout);
-}
-
-
-int
-main(int argc, char *argv[])
-{
- glutInitWindowSize(WindowWidth, WindowHeight);
- glutInit(&argc, argv);
- glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH | GLUT_STENCIL);
- glutCreateWindow(argv[0]);
- glewInit();
- glutReshapeFunc(Reshape);
- glutKeyboardFunc(Key);
- glutSpecialFunc(SpecialKey);
- glutDisplayFunc(Display);
- if (Anim)
- glutIdleFunc(Idle);
- Init();
- PrintHelp();
- glutMainLoop();
- return 0;
-}