summaryrefslogtreecommitdiff
path: root/progs/demos/shadowtex.c
diff options
context:
space:
mode:
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;
-}