diff options
Diffstat (limited to 'progs/demos')
| -rw-r--r-- | progs/demos/.gitignore | 7 | ||||
| -rw-r--r-- | progs/demos/Makefile | 8 | ||||
| -rw-r--r-- | progs/demos/SConscript | 10 | ||||
| -rw-r--r-- | progs/demos/dinoshade.c | 912 | ||||
| -rw-r--r-- | progs/demos/fbotexture.c | 621 | ||||
| -rw-r--r-- | progs/demos/glslnoise.c | 201 | ||||
| -rw-r--r-- | progs/demos/glutfx.c | 189 | ||||
| -rw-r--r-- | progs/demos/occlude.c | 234 | ||||
| -rw-r--r-- | progs/demos/projtex.c | 1028 | ||||
| -rw-r--r-- | progs/demos/streaming_rect.c | 327 | ||||
| -rw-r--r-- | progs/demos/texdown.c | 477 | ||||
| -rw-r--r-- | progs/demos/texobj.c | 284 | 
12 files changed, 2572 insertions, 1726 deletions
diff --git a/progs/demos/.gitignore b/progs/demos/.gitignore index d59d175212..f3c7091bcc 100644 --- a/progs/demos/.gitignore +++ b/progs/demos/.gitignore @@ -5,10 +5,12 @@ bounce  clearspd  copypix  cubemap +dinoshade  drawpix  engine  extfuncs.h  fbo_firecube +fbotexture  fire  fogcoord  fplight @@ -27,11 +29,9 @@ isosurf  lodbias  morph3d  multiarb -occlude -osdemo  paltex -pixeltex  pointblast +projtex  rain  ray  readpix @@ -61,4 +61,5 @@ trispd  tunnel  tunnel2  vao_demo +Windows  winpos diff --git a/progs/demos/Makefile b/progs/demos/Makefile index 32c6072123..c17595ec79 100644 --- a/progs/demos/Makefile +++ b/progs/demos/Makefile @@ -19,9 +19,11 @@ PROGS = \  	clearspd \  	copypix \  	cubemap \ +	dinoshade \  	drawpix \  	engine \  	fbo_firecube \ +	fbotexture \  	fire \  	fogcoord \  	fplight \ @@ -32,9 +34,7 @@ PROGS = \  	geartrain \  	glinfo \  	gloss \ -	glslnoise \  	gltestperf \ -	glutfx \  	isosurf \  	ipers \  	lodbias \ @@ -42,6 +42,7 @@ PROGS = \  	multiarb \  	paltex \  	pointblast \ +	projtex \  	rain \  	ray \  	readpix \ @@ -49,7 +50,6 @@ PROGS = \  	renormal \  	shadowtex \  	singlebuffer \ -	streaming_rect \  	spectex \  	spriteblast \  	stex3d \ @@ -57,9 +57,7 @@ PROGS = \  	terrain \  	tessdemo \  	texcyl \ -	texdown \  	texenv \ -	texobj \  	textures \  	trispd \  	tunnel \ diff --git a/progs/demos/SConscript b/progs/demos/SConscript index bc166dd789..f851870bcf 100644 --- a/progs/demos/SConscript +++ b/progs/demos/SConscript @@ -39,11 +39,9 @@ progs = [  	'geartrain',  	'glinfo',  	'gloss', -	'glslnoise',  	'gltestperf', -	'glutfx', -	'isosurf',  	'ipers', +	'isosurf',  	'lodbias',  	'morph3d',  	'multiarb', @@ -55,7 +53,6 @@ progs = [  	'renormal',  	'shadowtex',  	'singlebuffer', -	'streaming_rect',  	'spectex',  	'spriteblast',  	'stex3d', @@ -63,15 +60,16 @@ progs = [  	'terrain',  	'tessdemo',  	'texcyl', -	'texdown',  	'texenv', -	'texobj',  	'textures',  	'trispd',  	'tunnel',  	'tunnel2',  	'vao_demo',  	'winpos', +        'dinoshade', +        'fbotexture', +        'projtex',  ]  for prog in progs: diff --git a/progs/demos/dinoshade.c b/progs/demos/dinoshade.c new file mode 100644 index 0000000000..451da2ec89 --- /dev/null +++ b/progs/demos/dinoshade.c @@ -0,0 +1,912 @@ + +/* Copyright (c) Mark J. Kilgard, 1994, 1997.  */ + +/* This program is freely distributable without licensing fees  +   and is provided without guarantee or warrantee expressed or  +   implied. This program is -not- in the public domain. */ + +/* Example for PC game developers to show how to *combine* texturing, +   reflections, and projected shadows all in real-time with OpenGL. +   Robust reflections use stenciling.  Robust projected shadows +   use both stenciling and polygon offset.  PC game programmers +   should realize that neither stenciling nor polygon offset are  +   supported by Direct3D, so these real-time rendering algorithms +   are only really viable with OpenGL.  +    +   The program has modes for disabling the stenciling and polygon +   offset uses.  It is worth running this example with these features +   toggled off so you can see the sort of artifacts that result. +    +   Notice that the floor texturing, reflections, and shadowing +   all co-exist properly. */ + +/* When you run this program:  Left mouse button controls the +   view.  Middle mouse button controls light position (left & +   right rotates light around dino; up & down moves light +   position up and down).  Right mouse button pops up menu. */ + +/* Check out the comments in the "redraw" routine to see how the +   reflection blending and surface stenciling is done.  You can +   also see in "redraw" how the projected shadows are rendered, +   including the use of stenciling and polygon offset. */ + +/* This program is derived from glutdino.c */ + +/* Compile: cc -o dinoshade dinoshade.c -lglut -lGLU -lGL -lXmu -lXext -lX11 -lm */ + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <math.h>       /* for cos(), sin(), and sqrt() */ +#include <stddef.h>	/* for ptrdiff_t, referenced by GL.h when GL_GLEXT_LEGACY defined */ +#ifdef _WIN32 +#include <windows.h> +#endif +#define GL_GLEXT_LEGACY +#include <GL/glew.h>    /* OpenGL Utility Toolkit header */ +#include <GL/glut.h>    /* OpenGL Utility Toolkit header */ + +/* Some <math.h> files do not define M_PI... */ +#ifndef M_PI +#define M_PI 3.14159265358979323846 +#endif + +/* Variable controlling various rendering modes. */ +static int stencilReflection = 1, stencilShadow = 1, offsetShadow = 1; +static int renderShadow = 1, renderDinosaur = 1, renderReflection = 1; +static int linearFiltering = 0, useMipmaps = 0, useTexture = 1; +static int reportSpeed = 0; +static int animation = 1; +static GLboolean lightSwitch = GL_TRUE; +static int directionalLight = 1; +static int forceExtension = 0; + +/* Time varying or user-controled variables. */ +static float jump = 0.0; +static float lightAngle = 0.0, lightHeight = 20; +GLfloat angle = -150;   /* in degrees */ +GLfloat angle2 = 30;   /* in degrees */ + +int moving, startx, starty; +int lightMoving = 0, lightStartX, lightStartY; + +enum { +  MISSING, EXTENSION, ONE_DOT_ONE +}; +int polygonOffsetVersion; + +static GLdouble bodyWidth = 3.0; +/* *INDENT-OFF* */ +static GLfloat body[][2] = { {0, 3}, {1, 1}, {5, 1}, {8, 4}, {10, 4}, {11, 5}, +  {11, 11.5}, {13, 12}, {13, 13}, {10, 13.5}, {13, 14}, {13, 15}, {11, 16}, +  {8, 16}, {7, 15}, {7, 13}, {8, 12}, {7, 11}, {6, 6}, {4, 3}, {3, 2}, +  {1, 2} }; +static GLfloat arm[][2] = { {8, 10}, {9, 9}, {10, 9}, {13, 8}, {14, 9}, {16, 9}, +  {15, 9.5}, {16, 10}, {15, 10}, {15.5, 11}, {14.5, 10}, {14, 11}, {14, 10}, +  {13, 9}, {11, 11}, {9, 11} }; +static GLfloat leg[][2] = { {8, 6}, {8, 4}, {9, 3}, {9, 2}, {8, 1}, {8, 0.5}, {9, 0}, +  {12, 0}, {10, 1}, {10, 2}, {12, 4}, {11, 6}, {10, 7}, {9, 7} }; +static GLfloat eye[][2] = { {8.75, 15}, {9, 14.7}, {9.6, 14.7}, {10.1, 15}, +  {9.6, 15.25}, {9, 15.25} }; +static GLfloat lightPosition[4]; +static GLfloat lightColor[] = {0.8, 1.0, 0.8, 1.0}; /* green-tinted */ +static GLfloat skinColor[] = {0.1, 1.0, 0.1, 1.0}, eyeColor[] = {1.0, 0.2, 0.2, 1.0}; +/* *INDENT-ON* */ + +/* Nice floor texture tiling pattern. */ +static char *circles[] = { +  "....xxxx........", +  "..xxxxxxxx......", +  ".xxxxxxxxxx.....", +  ".xxx....xxx.....", +  "xxx......xxx....", +  "xxx......xxx....", +  "xxx......xxx....", +  "xxx......xxx....", +  ".xxx....xxx.....", +  ".xxxxxxxxxx.....", +  "..xxxxxxxx......", +  "....xxxx........", +  "................", +  "................", +  "................", +  "................", +}; + +static void +makeFloorTexture(void) +{ +  GLubyte floorTexture[16][16][3]; +  GLubyte *loc; +  int s, t; + +  /* Setup RGB image for the texture. */ +  loc = (GLubyte*) floorTexture; +  for (t = 0; t < 16; t++) { +    for (s = 0; s < 16; s++) { +      if (circles[t][s] == 'x') { +	/* Nice green. */ +        loc[0] = 0x1f; +        loc[1] = 0x8f; +        loc[2] = 0x1f; +      } else { +	/* Light gray. */ +        loc[0] = 0xaa; +        loc[1] = 0xaa; +        loc[2] = 0xaa; +      } +      loc += 3; +    } +  } + +  glPixelStorei(GL_UNPACK_ALIGNMENT, 1); + +  if (useMipmaps) { +    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, +      GL_LINEAR_MIPMAP_LINEAR); +    gluBuild2DMipmaps(GL_TEXTURE_2D, 3, 16, 16, +      GL_RGB, GL_UNSIGNED_BYTE, floorTexture); +  } else { +    if (linearFiltering) { +      glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); +    } else { +      glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); +    } +    glTexImage2D(GL_TEXTURE_2D, 0, 3, 16, 16, 0, +      GL_RGB, GL_UNSIGNED_BYTE, floorTexture); +  } +} + +enum { +  X, Y, Z, W +}; +enum { +  A, B, C, D +}; + +/* Create a matrix that will project the desired shadow. */ +static void +shadowMatrix(GLfloat shadowMat[4][4], +  GLfloat groundplane[4], +  GLfloat lightpos[4]) +{ +  GLfloat dot; + +  /* Find dot product between light position vector and ground plane normal. */ +  dot = groundplane[X] * lightpos[X] + +    groundplane[Y] * lightpos[Y] + +    groundplane[Z] * lightpos[Z] + +    groundplane[W] * lightpos[W]; + +  shadowMat[0][0] = dot - lightpos[X] * groundplane[X]; +  shadowMat[1][0] = 0.f - lightpos[X] * groundplane[Y]; +  shadowMat[2][0] = 0.f - lightpos[X] * groundplane[Z]; +  shadowMat[3][0] = 0.f - lightpos[X] * groundplane[W]; + +  shadowMat[X][1] = 0.f - lightpos[Y] * groundplane[X]; +  shadowMat[1][1] = dot - lightpos[Y] * groundplane[Y]; +  shadowMat[2][1] = 0.f - lightpos[Y] * groundplane[Z]; +  shadowMat[3][1] = 0.f - lightpos[Y] * groundplane[W]; + +  shadowMat[X][2] = 0.f - lightpos[Z] * groundplane[X]; +  shadowMat[1][2] = 0.f - lightpos[Z] * groundplane[Y]; +  shadowMat[2][2] = dot - lightpos[Z] * groundplane[Z]; +  shadowMat[3][2] = 0.f - lightpos[Z] * groundplane[W]; + +  shadowMat[X][3] = 0.f - lightpos[W] * groundplane[X]; +  shadowMat[1][3] = 0.f - lightpos[W] * groundplane[Y]; +  shadowMat[2][3] = 0.f - lightpos[W] * groundplane[Z]; +  shadowMat[3][3] = dot - lightpos[W] * groundplane[W]; + +} + +/* Find the plane equation given 3 points. */ +static void +findPlane(GLfloat plane[4], +  GLfloat v0[3], GLfloat v1[3], GLfloat v2[3]) +{ +  GLfloat vec0[3], vec1[3]; + +  /* Need 2 vectors to find cross product. */ +  vec0[X] = v1[X] - v0[X]; +  vec0[Y] = v1[Y] - v0[Y]; +  vec0[Z] = v1[Z] - v0[Z]; + +  vec1[X] = v2[X] - v0[X]; +  vec1[Y] = v2[Y] - v0[Y]; +  vec1[Z] = v2[Z] - v0[Z]; + +  /* find cross product to get A, B, and C of plane equation */ +  plane[A] = vec0[Y] * vec1[Z] - vec0[Z] * vec1[Y]; +  plane[B] = -(vec0[X] * vec1[Z] - vec0[Z] * vec1[X]); +  plane[C] = vec0[X] * vec1[Y] - vec0[Y] * vec1[X]; + +  plane[D] = -(plane[A] * v0[X] + plane[B] * v0[Y] + plane[C] * v0[Z]); +} + +static void +extrudeSolidFromPolygon(GLfloat data[][2], unsigned int dataSize, +  GLdouble thickness, GLuint side, GLuint edge, GLuint whole) +{ +  static GLUtriangulatorObj *tobj = NULL; +  GLdouble vertex[3], dx, dy, len; +  int i; +  int count = (int) (dataSize / (2 * sizeof(GLfloat))); + +  if (tobj == NULL) { +    tobj = gluNewTess();  /* create and initialize a GLU +                             polygon tesselation object */ +    gluTessCallback(tobj, GLU_BEGIN, glBegin); +    gluTessCallback(tobj, GLU_VERTEX, glVertex2fv);  /* semi-tricky */ +    gluTessCallback(tobj, GLU_END, glEnd); +  } +  glNewList(side, GL_COMPILE); +  glShadeModel(GL_SMOOTH);  /* smooth minimizes seeing +                               tessellation */ +  gluBeginPolygon(tobj); +  for (i = 0; i < count; i++) { +    vertex[0] = data[i][0]; +    vertex[1] = data[i][1]; +    vertex[2] = 0; +    gluTessVertex(tobj, vertex, data[i]); +  } +  gluEndPolygon(tobj); +  glEndList(); +  glNewList(edge, GL_COMPILE); +  glShadeModel(GL_FLAT);  /* flat shade keeps angular hands +                             from being "smoothed" */ +  glBegin(GL_QUAD_STRIP); +  for (i = 0; i <= count; i++) { +#if 1 /* weird, but seems to be legal */ +    /* mod function handles closing the edge */ +    glVertex3f(data[i % count][0], data[i % count][1], 0.0); +    glVertex3f(data[i % count][0], data[i % count][1], thickness); +    /* Calculate a unit normal by dividing by Euclidean +       distance. We * could be lazy and use +       glEnable(GL_NORMALIZE) so we could pass in * arbitrary +       normals for a very slight performance hit. */ +    dx = data[(i + 1) % count][1] - data[i % count][1]; +    dy = data[i % count][0] - data[(i + 1) % count][0]; +    len = sqrt(dx * dx + dy * dy); +    glNormal3f(dx / len, dy / len, 0.0); +#else /* the nice way of doing it */ +    /* Calculate a unit normal by dividing by Euclidean +       distance. We * could be lazy and use +       glEnable(GL_NORMALIZE) so we could pass in * arbitrary +       normals for a very slight performance hit. */ +    dx = data[i % count][1] - data[(i - 1 + count) % count][1]; +    dy = data[(i - 1 + count) % count][0] - data[i % count][0]; +    len = sqrt(dx * dx + dy * dy); +    glNormal3f(dx / len, dy / len, 0.0); +    /* mod function handles closing the edge */ +    glVertex3f(data[i % count][0], data[i % count][1], 0.0); +    glVertex3f(data[i % count][0], data[i % count][1], thickness); +#endif +  } +  glEnd(); +  glEndList(); +  glNewList(whole, GL_COMPILE); +  glFrontFace(GL_CW); +  glCallList(edge); +  glNormal3f(0.0, 0.0, -1.0);  /* constant normal for side */ +  glCallList(side); +  glPushMatrix(); +  glTranslatef(0.0, 0.0, thickness); +  glFrontFace(GL_CCW); +  glNormal3f(0.0, 0.0, 1.0);  /* opposite normal for other side */ +  glCallList(side); +  glPopMatrix(); +  glEndList(); +} + +/* Enumerants for refering to display lists. */ +typedef enum { +  RESERVED, BODY_SIDE, BODY_EDGE, BODY_WHOLE, ARM_SIDE, ARM_EDGE, ARM_WHOLE, +  LEG_SIDE, LEG_EDGE, LEG_WHOLE, EYE_SIDE, EYE_EDGE, EYE_WHOLE +} displayLists; + +static void +makeDinosaur(void) +{ +  extrudeSolidFromPolygon(body, sizeof(body), bodyWidth, +    BODY_SIDE, BODY_EDGE, BODY_WHOLE); +  extrudeSolidFromPolygon(arm, sizeof(arm), bodyWidth / 4, +    ARM_SIDE, ARM_EDGE, ARM_WHOLE); +  extrudeSolidFromPolygon(leg, sizeof(leg), bodyWidth / 2, +    LEG_SIDE, LEG_EDGE, LEG_WHOLE); +  extrudeSolidFromPolygon(eye, sizeof(eye), bodyWidth + 0.2, +    EYE_SIDE, EYE_EDGE, EYE_WHOLE); +} + +static void +drawDinosaur(void) + +{ +  glPushMatrix(); +  /* Translate the dinosaur to be at (0,8,0). */ +  glTranslatef(-8, 0, -bodyWidth / 2); +  glTranslatef(0.0, jump, 0.0); +  glMaterialfv(GL_FRONT, GL_DIFFUSE, skinColor); +  glCallList(BODY_WHOLE); +  glTranslatef(0.0, 0.0, bodyWidth); +  glCallList(ARM_WHOLE); +  glCallList(LEG_WHOLE); +  glTranslatef(0.0, 0.0, -bodyWidth - bodyWidth / 4); +  glCallList(ARM_WHOLE); +  glTranslatef(0.0, 0.0, -bodyWidth / 4); +  glCallList(LEG_WHOLE); +  glTranslatef(0.0, 0.0, bodyWidth / 2 - 0.1); +  glMaterialfv(GL_FRONT, GL_DIFFUSE, eyeColor); +  glCallList(EYE_WHOLE); +  glPopMatrix(); +} + +static GLfloat floorVertices[4][3] = { +  { -20.0, 0.0, 20.0 }, +  { 20.0, 0.0, 20.0 }, +  { 20.0, 0.0, -20.0 }, +  { -20.0, 0.0, -20.0 }, +}; + +/* Draw a floor (possibly textured). */ +static void +drawFloor(void) +{ +  glDisable(GL_LIGHTING); + +  if (useTexture) { +    glEnable(GL_TEXTURE_2D); +  } + +  glBegin(GL_QUADS); +    glTexCoord2f(0.0, 0.0); +    glVertex3fv(floorVertices[0]); +    glTexCoord2f(0.0, 16.0); +    glVertex3fv(floorVertices[1]); +    glTexCoord2f(16.0, 16.0); +    glVertex3fv(floorVertices[2]); +    glTexCoord2f(16.0, 0.0); +    glVertex3fv(floorVertices[3]); +  glEnd(); + +  if (useTexture) { +    glDisable(GL_TEXTURE_2D); +  } + +  glEnable(GL_LIGHTING); +} + +static GLfloat floorPlane[4]; +static GLfloat floorShadow[4][4]; + +static void +redraw(void) +{ +  int start, end; + +  if (reportSpeed) { +    start = glutGet(GLUT_ELAPSED_TIME); +  } + +  /* Clear; default stencil clears to zero. */ +  if ((stencilReflection && renderReflection) || (stencilShadow && renderShadow)) { +    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); +  } else { +    /* Avoid clearing stencil when not using it. */ +    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); +  } + +  /* Reposition the light source. */ +  lightPosition[0] = 12*cos(lightAngle); +  lightPosition[1] = lightHeight; +  lightPosition[2] = 12*sin(lightAngle); +  if (directionalLight) { +    lightPosition[3] = 0.0; +  } else { +    lightPosition[3] = 1.0; +  } + +  shadowMatrix(floorShadow, floorPlane, lightPosition); + +  glPushMatrix(); +    /* Perform scene rotations based on user mouse input. */ +    glRotatef(angle2, 1.0, 0.0, 0.0); +    glRotatef(angle, 0.0, 1.0, 0.0); +      +    /* Tell GL new light source position. */ +    glLightfv(GL_LIGHT0, GL_POSITION, lightPosition); + +    if (renderReflection) { +      if (stencilReflection) { +        /* We can eliminate the visual "artifact" of seeing the "flipped" +  	   dinosaur underneath the floor by using stencil.  The idea is +	   draw the floor without color or depth update but so that  +	   a stencil value of one is where the floor will be.  Later when +	   rendering the dinosaur reflection, we will only update pixels +	   with a stencil value of 1 to make sure the reflection only +	   lives on the floor, not below the floor. */ + +        /* Don't update color or depth. */ +        glDisable(GL_DEPTH_TEST); +        glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE); + +        /* Draw 1 into the stencil buffer. */ +        glEnable(GL_STENCIL_TEST); +        glStencilOp(GL_REPLACE, GL_REPLACE, GL_REPLACE); +        glStencilFunc(GL_ALWAYS, 1, 0xffffffff); + +        /* Now render floor; floor pixels just get their stencil set to 1. */ +        drawFloor(); + +        /* Re-enable update of color and depth. */  +        glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); +        glEnable(GL_DEPTH_TEST); + +        /* Now, only render where stencil is set to 1. */ +        glStencilFunc(GL_EQUAL, 1, 0xffffffff);  /* draw if ==1 */ +        glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP); +      } + +      glPushMatrix(); + +        /* The critical reflection step: Reflect dinosaur through the floor +           (the Y=0 plane) to make a relection. */ +        glScalef(1.0, -1.0, 1.0); + +	/* Reflect the light position. */ +        glLightfv(GL_LIGHT0, GL_POSITION, lightPosition); + +        /* To avoid our normals getting reversed and hence botched lighting +	   on the reflection, turn on normalize.  */ +        glEnable(GL_NORMALIZE); +        glCullFace(GL_FRONT); + +        /* Draw the reflected dinosaur. */ +        drawDinosaur(); + +        /* Disable noramlize again and re-enable back face culling. */ +        glDisable(GL_NORMALIZE); +        glCullFace(GL_BACK); + +      glPopMatrix(); + +      /* Switch back to the unreflected light position. */ +      glLightfv(GL_LIGHT0, GL_POSITION, lightPosition); + +      if (stencilReflection) { +        glDisable(GL_STENCIL_TEST); +      } +    } + +    /* Back face culling will get used to only draw either the top or the +       bottom floor.  This let's us get a floor with two distinct +       appearances.  The top floor surface is reflective and kind of red. +       The bottom floor surface is not reflective and blue. */ + +    /* Draw "bottom" of floor in blue. */ +    glFrontFace(GL_CW);  /* Switch face orientation. */ +    glColor4f(0.1, 0.1, 0.7, 1.0); +    drawFloor(); +    glFrontFace(GL_CCW); + +    if (renderShadow) { +      if (stencilShadow) { +	/* Draw the floor with stencil value 3.  This helps us only  +	   draw the shadow once per floor pixel (and only on the +	   floor pixels). */ +        glEnable(GL_STENCIL_TEST); +        glStencilFunc(GL_ALWAYS, 3, 0xffffffff); +        glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE); +      } +    } + +    /* Draw "top" of floor.  Use blending to blend in reflection. */ +    glEnable(GL_BLEND); +    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); +    glColor4f(0.7, 0.0, 0.0, 0.3); +    glColor4f(1.0, 1.0, 1.0, 0.3); +    drawFloor(); +    glDisable(GL_BLEND); + +    if (renderDinosaur) { +      /* Draw "actual" dinosaur, not its reflection. */ +      drawDinosaur(); +    } + +    if (renderShadow) { + +      /* Render the projected shadow. */ + +      if (stencilShadow) { + +        /* Now, only render where stencil is set above 2 (ie, 3 where +	   the top floor is).  Update stencil with 2 where the shadow +	   gets drawn so we don't redraw (and accidently reblend) the +	   shadow). */ +        glStencilFunc(GL_LESS, 2, 0xffffffff);  /* draw if ==1 */ +        glStencilOp(GL_REPLACE, GL_REPLACE, GL_REPLACE); +      } + +      /* To eliminate depth buffer artifacts, we use polygon offset +	 to raise the depth of the projected shadow slightly so +	 that it does not depth buffer alias with the floor. */ +      if (offsetShadow) { +	switch (polygonOffsetVersion) { +	case EXTENSION: +#ifdef GL_EXT_polygon_offset +	  glEnable(GL_POLYGON_OFFSET_EXT); +	  break; +#endif +#ifdef GL_VERSION_1_1 +	case ONE_DOT_ONE: +          glEnable(GL_POLYGON_OFFSET_FILL); +	  break; +#endif +	case MISSING: +	  /* Oh well. */ +	  break; +	} +      } + +      /* Render 50% black shadow color on top of whatever the +         floor appareance is. */ +      glEnable(GL_BLEND); +      glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); +      glDisable(GL_LIGHTING);  /* Force the 50% black. */ +      glColor4f(0.0, 0.0, 0.0, 0.5); + +      glPushMatrix(); +	/* Project the shadow. */ +        glMultMatrixf((GLfloat *) floorShadow); +        drawDinosaur(); +      glPopMatrix(); + +      glDisable(GL_BLEND); +      glEnable(GL_LIGHTING); + +      if (offsetShadow) { +	switch (polygonOffsetVersion) { +#ifdef GL_EXT_polygon_offset +	case EXTENSION: +	  glDisable(GL_POLYGON_OFFSET_EXT); +	  break; +#endif +#ifdef GL_VERSION_1_1 +	case ONE_DOT_ONE: +          glDisable(GL_POLYGON_OFFSET_FILL); +	  break; +#endif +	case MISSING: +	  /* Oh well. */ +	  break; +	} +      } +      if (stencilShadow) { +        glDisable(GL_STENCIL_TEST); +      } +    } + +    glPushMatrix(); +    glDisable(GL_LIGHTING); +    glColor3f(1.0, 1.0, 0.0); +    if (directionalLight) { +      /* Draw an arrowhead. */ +      glDisable(GL_CULL_FACE); +      glTranslatef(lightPosition[0], lightPosition[1], lightPosition[2]); +      glRotatef(lightAngle * -180.0 / M_PI, 0, 1, 0); +      glRotatef(atan(lightHeight/12) * 180.0 / M_PI, 0, 0, 1); +      glBegin(GL_TRIANGLE_FAN); +	glVertex3f(0, 0, 0); +	glVertex3f(2, 1, 1); +	glVertex3f(2, -1, 1); +	glVertex3f(2, -1, -1); +	glVertex3f(2, 1, -1); +	glVertex3f(2, 1, 1); +      glEnd(); +      /* Draw a white line from light direction. */ +      glColor3f(1.0, 1.0, 1.0); +      glBegin(GL_LINES); +	glVertex3f(0, 0, 0); +	glVertex3f(5, 0, 0); +      glEnd(); +      glEnable(GL_CULL_FACE); +    } else { +      /* Draw a yellow ball at the light source. */ +      glTranslatef(lightPosition[0], lightPosition[1], lightPosition[2]); +      glutSolidSphere(1.0, 5, 5); +    } +    glEnable(GL_LIGHTING); +    glPopMatrix(); + +  glPopMatrix(); + +  if (reportSpeed) { +    glFinish(); +    end = glutGet(GLUT_ELAPSED_TIME); +    printf("Speed %.3g frames/sec (%d ms)\n", 1000.0/(end-start), end-start); +  } + +  glutSwapBuffers(); +} + +/* ARGSUSED2 */ +static void +mouse(int button, int state, int x, int y) +{ +  if (button == GLUT_LEFT_BUTTON) { +    if (state == GLUT_DOWN) { +      moving = 1; +      startx = x; +      starty = y; +    } +    if (state == GLUT_UP) { +      moving = 0; +    } +  } +  if (button == GLUT_MIDDLE_BUTTON) { +    if (state == GLUT_DOWN) { +      lightMoving = 1; +      lightStartX = x; +      lightStartY = y; +    } +    if (state == GLUT_UP) { +      lightMoving = 0; +    } +  } +} + +/* ARGSUSED1 */ +static void +motion(int x, int y) +{ +  if (moving) { +    angle = angle + (x - startx); +    angle2 = angle2 + (y - starty); +    startx = x; +    starty = y; +    glutPostRedisplay(); +  } +  if (lightMoving) { +    lightAngle += (x - lightStartX)/40.0; +    lightHeight += (lightStartY - y)/20.0; +    lightStartX = x; +    lightStartY = y; +    glutPostRedisplay(); +  } +} + +/* Advance time varying state when idle callback registered. */ +static void +idle(void) +{ +  static float time = 0.0; + +  time = glutGet(GLUT_ELAPSED_TIME) / 500.0; + +  jump = 4.0 * fabs(sin(time)*0.5); +  if (!lightMoving) { +    lightAngle += 0.03; +  } +  glutPostRedisplay(); +} + +enum { +  M_NONE, M_MOTION, M_LIGHT, M_TEXTURE, M_SHADOWS, M_REFLECTION, M_DINOSAUR, +  M_STENCIL_REFLECTION, M_STENCIL_SHADOW, M_OFFSET_SHADOW, +  M_POSITIONAL, M_DIRECTIONAL, M_PERFORMANCE +}; + +static void +controlLights(int value) +{ +  switch (value) { +  case M_NONE: +    return; +  case M_MOTION: +    animation = 1 - animation; +    if (animation) { +      glutIdleFunc(idle); +    } else { +      glutIdleFunc(NULL); +    } +    break; +  case M_LIGHT: +    lightSwitch = !lightSwitch; +    if (lightSwitch) { +      glEnable(GL_LIGHT0); +    } else { +      glDisable(GL_LIGHT0); +    } +    break; +  case M_TEXTURE: +    useTexture = !useTexture; +    break; +  case M_SHADOWS: +    renderShadow = 1 - renderShadow; +    break; +  case M_REFLECTION: +    renderReflection = 1 - renderReflection; +    break; +  case M_DINOSAUR: +    renderDinosaur = 1 - renderDinosaur; +    break; +  case M_STENCIL_REFLECTION: +    stencilReflection = 1 - stencilReflection; +    break; +  case M_STENCIL_SHADOW: +    stencilShadow = 1 - stencilShadow; +    break; +  case M_OFFSET_SHADOW: +    offsetShadow = 1 - offsetShadow; +    break; +  case M_POSITIONAL: +    directionalLight = 0; +    break; +  case M_DIRECTIONAL: +    directionalLight = 1; +    break; +  case M_PERFORMANCE: +    reportSpeed = 1 - reportSpeed; +    break; +  } +  glutPostRedisplay(); +} + +/* When not visible, stop animating.  Restart when visible again. */ +static void  +visible(int vis) +{ +  if (vis == GLUT_VISIBLE) { +    if (animation) +      glutIdleFunc(idle); +  } else { +    if (!animation) +      glutIdleFunc(NULL); +  } +} + +/* Press any key to redraw; good when motion stopped and +   performance reporting on. */ +/* ARGSUSED */ +static void +key(unsigned char c, int x, int y) +{ +  if (c == 27) { +    exit(0);  /* IRIS GLism, Escape quits. */ +  } +  glutPostRedisplay(); +} + +/* Press any key to redraw; good when motion stopped and +   performance reporting on. */ +/* ARGSUSED */ +static void +special(int k, int x, int y) +{ +  glutPostRedisplay(); +} + +static int +supportsOneDotOne(void) +{ +  const char *version; +  int major, minor; + +  version = (char *) glGetString(GL_VERSION); +  if (sscanf(version, "%d.%d", &major, &minor) == 2) +    return major * 10 + minor >= 11; +  return 0;            /* OpenGL version string malformed! */ +} + +int +main(int argc, char **argv) +{ +  int i; + +  glutInit(&argc, argv); + +  for (i=1; i<argc; i++) { +    if (!strcmp("-linear", argv[i])) { +      linearFiltering = 1; +    } else if (!strcmp("-mipmap", argv[i])) { +      useMipmaps = 1; +    } else if (!strcmp("-ext", argv[i])) { +      forceExtension = 1; +    } +  } + +  glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH | GLUT_STENCIL); + +#if 0 +  /* In GLUT 4.0, you'll be able to do this an be sure to +     get 2 bits of stencil if the machine has it for you. */ +  glutInitDisplayString("samples stencil>=2 rgb double depth"); +#endif + +  glutCreateWindow("Shadowy Leapin' Lizards"); +  glewInit(); + +  if (glutGet(GLUT_WINDOW_STENCIL_SIZE) <= 1) { +    printf("dinoshade: Sorry, I need at least 2 bits of stencil.\n"); +    exit(1); +  } + +  /* Register GLUT callbacks. */ +  glutDisplayFunc(redraw); +  glutMouseFunc(mouse); +  glutMotionFunc(motion); +  glutVisibilityFunc(visible); +  glutKeyboardFunc(key); +  glutSpecialFunc(special); + +  glutCreateMenu(controlLights); + +  glutAddMenuEntry("Toggle motion", M_MOTION); +  glutAddMenuEntry("-----------------------", M_NONE); +  glutAddMenuEntry("Toggle light", M_LIGHT); +  glutAddMenuEntry("Toggle texture", M_TEXTURE); +  glutAddMenuEntry("Toggle shadows", M_SHADOWS); +  glutAddMenuEntry("Toggle reflection", M_REFLECTION); +  glutAddMenuEntry("Toggle dinosaur", M_DINOSAUR); +  glutAddMenuEntry("-----------------------", M_NONE); +  glutAddMenuEntry("Toggle reflection stenciling", M_STENCIL_REFLECTION); +  glutAddMenuEntry("Toggle shadow stenciling", M_STENCIL_SHADOW); +  glutAddMenuEntry("Toggle shadow offset", M_OFFSET_SHADOW); +  glutAddMenuEntry("----------------------", M_NONE); +  glutAddMenuEntry("Positional light", M_POSITIONAL); +  glutAddMenuEntry("Directional light", M_DIRECTIONAL); +  glutAddMenuEntry("-----------------------", M_NONE); +  glutAddMenuEntry("Toggle performance", M_PERFORMANCE); +  glutAttachMenu(GLUT_RIGHT_BUTTON); +  makeDinosaur(); + +#ifdef GL_VERSION_1_1 +  if (supportsOneDotOne() && !forceExtension) { +    polygonOffsetVersion = ONE_DOT_ONE; +    glPolygonOffset(-2.0, -9.0); +  } else +#endif +  { +#ifdef GL_EXT_polygon_offset +  /* check for the polygon offset extension */ +  if (glutExtensionSupported("GL_EXT_polygon_offset")) { +    polygonOffsetVersion = EXTENSION; +    glPolygonOffsetEXT(-2.0, -0.002); +  } else  +#endif +    { +      polygonOffsetVersion = MISSING; +      printf("\ndinoshine: Missing polygon offset.\n"); +      printf("           Expect shadow depth aliasing artifacts.\n\n"); +    } +  } + +  glEnable(GL_CULL_FACE); +  glEnable(GL_DEPTH_TEST); +  glEnable(GL_TEXTURE_2D); +  glLineWidth(3.0); + +  glMatrixMode(GL_PROJECTION); +  gluPerspective( /* field of view in degree */ 40.0, +  /* aspect ratio */ 1.0, +    /* Z near */ 20.0, /* Z far */ 100.0); +  glMatrixMode(GL_MODELVIEW); +  gluLookAt(0.0, 8.0, 60.0,  /* eye is at (0,8,60) */ +    0.0, 8.0, 0.0,      /* center is at (0,8,0) */ +    0.0, 1.0, 0.);      /* up is in postivie Y direction */ + +  glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, 1); +  glLightfv(GL_LIGHT0, GL_DIFFUSE, lightColor); +  glLightf(GL_LIGHT0, GL_CONSTANT_ATTENUATION, 0.1); +  glLightf(GL_LIGHT0, GL_LINEAR_ATTENUATION, 0.05); +  glEnable(GL_LIGHT0); +  glEnable(GL_LIGHTING); + +  makeFloorTexture(); + +  /* Setup floor plane for projected shadow calculations. */ +  findPlane(floorPlane, floorVertices[1], floorVertices[2], floorVertices[3]); + +  glutMainLoop(); +  return 0;             /* ANSI C requires main to return int. */ +} diff --git a/progs/demos/fbotexture.c b/progs/demos/fbotexture.c new file mode 100644 index 0000000000..50a4b00afc --- /dev/null +++ b/progs/demos/fbotexture.c @@ -0,0 +1,621 @@ +/* + * Test GL_EXT_framebuffer_object render-to-texture + * + * Draw a teapot into a texture image with stenciling. + * Then draw a textured quad using that texture. + * + * Brian Paul + * 18 Apr 2005 + */ + + +#include <GL/glew.h> +#include <GL/glut.h> +#include <assert.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <math.h> + +/* For debug */ +#define DEPTH 1 +#define STENCIL 1 +#define DRAW 1 + + +static int Win = 0; +static int Width = 400, Height = 400; + +#if 1 +static GLenum TexTarget = GL_TEXTURE_2D; +static int TexWidth = 512, TexHeight = 512; +static GLenum TexIntFormat = GL_RGB; /* either GL_RGB or GL_RGBA */ +#else +static GLenum TexTarget = GL_TEXTURE_RECTANGLE_ARB; +static int TexWidth = 200, TexHeight = 200; +static GLenum TexIntFormat = GL_RGB5; /* either GL_RGB or GL_RGBA */ +#endif +static GLuint TextureLevel = 0;  /* which texture level to render to */ + +static GLuint MyFB; +static GLuint TexObj; +static GLuint DepthRB = 0, StencilRB = 0; +static GLboolean Anim = GL_FALSE; +static GLfloat Rot = 0.0; +static GLboolean UsePackedDepthStencil = GL_FALSE; +static GLboolean UsePackedDepthStencilBoth = GL_FALSE; +static GLboolean Use_ARB_fbo = GL_FALSE; +static GLboolean Cull = GL_FALSE; +static GLboolean Wireframe = GL_FALSE; + + +static void +CheckError(int line) +{ +   GLenum err = glGetError(); +   if (err) { +      printf("GL Error 0x%x at line %d\n", (int) err, line); +   } +} + + +static void +Idle(void) +{ +   Rot = glutGet(GLUT_ELAPSED_TIME) * 0.1; +   glutPostRedisplay(); +} + + +static void +RenderTexture(void) +{ +   GLenum status; + +   glMatrixMode(GL_PROJECTION); +   glLoadIdentity(); +   glOrtho(-1.0, 1.0, -1.0, 1.0, 5.0, 25.0); +   glMatrixMode(GL_MODELVIEW); +   glLoadIdentity(); +   glTranslatef(0.0, 0.0, -15.0); + +   /* draw to texture image */ +   glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, MyFB); + +   status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT); +   if (status != GL_FRAMEBUFFER_COMPLETE_EXT) { +      printf("Framebuffer incomplete!!!\n"); +   } + +   glViewport(0, 0, TexWidth, TexHeight); + +   glClearColor(0.5, 0.5, 1.0, 0.0); +   glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); +   CheckError(__LINE__); + +#if DEPTH +   glEnable(GL_DEPTH_TEST); +#endif + +#if STENCIL +   glEnable(GL_STENCIL_TEST); +   glStencilFunc(GL_NEVER, 1, ~0); +   glStencilOp(GL_REPLACE, GL_KEEP, GL_REPLACE); +#endif + +   CheckError(__LINE__); + +#if DEPTH || STENCIL +   /* draw diamond-shaped stencil pattern */ +   glColor3f(0, 1, 0); +   glBegin(GL_POLYGON); +   glVertex2f(-0.2,  0.0); +   glVertex2f( 0.0, -0.2); +   glVertex2f( 0.2,  0.0); +   glVertex2f( 0.0,  0.2); +   glEnd(); +#endif + +   /* draw teapot where stencil != 1 */ +#if STENCIL +   glStencilFunc(GL_NOTEQUAL, 1, ~0); +   glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP); +#endif + +   CheckError(__LINE__); + +   if (Wireframe) { +      glPolygonMode(GL_FRONT, GL_LINE); +   } +   else { +      glPolygonMode(GL_FRONT, GL_FILL); +   } + +   if (Cull) { +      /* cull back */ +      glCullFace(GL_BACK); +      glEnable(GL_CULL_FACE); +   } +   else { +      glDisable(GL_CULL_FACE); +   } + +#if 0 +   glBegin(GL_POLYGON); +   glColor3f(1, 0, 0); +   glVertex2f(-1, -1); +   glColor3f(0, 1, 0); +   glVertex2f(1, -1); +   glColor3f(0, 0, 1); +   glVertex2f(0, 1); +   glEnd(); +#else +   glEnable(GL_LIGHTING); +   glEnable(GL_LIGHT0); +   glPushMatrix(); +   glRotatef(0.5 * Rot, 1.0, 0.0, 0.0); +   glFrontFace(GL_CW); /* Teapot patches backward */ +   glutSolidTeapot(0.5); +   glFrontFace(GL_CCW); +   glPopMatrix(); +   glDisable(GL_LIGHTING); +   /* +   PrintStencilHistogram(TexWidth, TexHeight); +   */ +#endif + +   glDisable(GL_DEPTH_TEST); +   glDisable(GL_STENCIL_TEST); +   glDisable(GL_CULL_FACE); +   glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); + +#if DRAW +   /* Bind normal framebuffer */ +   glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); +#endif + +   CheckError(__LINE__); +} + + + +static void +Display(void) +{ +   float ar = (float) Width / (float) Height; + +   RenderTexture(); + +   /* draw textured quad in the window */ +#if DRAW +   glMatrixMode(GL_PROJECTION); +   glLoadIdentity(); +   glFrustum(-ar, ar, -1.0, 1.0, 5.0, 25.0); +   glMatrixMode(GL_MODELVIEW); +   glLoadIdentity(); +   glTranslatef(0.0, 0.0, -7.0); + +   glViewport(0, 0, Width, Height); + +   glClearColor(0.25, 0.25, 0.25, 0); +   glClear(GL_COLOR_BUFFER_BIT); + +   glPushMatrix(); +   glRotatef(Rot, 0, 1, 0); +   glEnable(TexTarget); +   glBindTexture(TexTarget, TexObj); +   glBegin(GL_POLYGON); +   glColor3f(0.25, 0.25, 0.25); +   if (TexTarget == GL_TEXTURE_2D) { +      glTexCoord2f(0, 0); +      glVertex2f(-1, -1); +      glTexCoord2f(1, 0); +      glVertex2f(1, -1); +      glColor3f(1.0, 1.0, 1.0); +      glTexCoord2f(1, 1); +      glVertex2f(1, 1); +      glTexCoord2f(0, 1); +      glVertex2f(-1, 1); +   } +   else { +      assert(TexTarget == GL_TEXTURE_RECTANGLE_ARB); +      glTexCoord2f(0, 0); +      glVertex2f(-1, -1); +      glTexCoord2f(TexWidth, 0); +      glVertex2f(1, -1); +      glColor3f(1.0, 1.0, 1.0); +      glTexCoord2f(TexWidth, TexHeight); +      glVertex2f(1, 1); +      glTexCoord2f(0, TexHeight); +      glVertex2f(-1, 1); +   } +   glEnd(); +   glPopMatrix(); +   glDisable(TexTarget); +#endif + +   glutSwapBuffers(); +   CheckError(__LINE__); +} + + +static void +Reshape(int width, int height) +{ +   glViewport(0, 0, width, height); +   Width = width; +   Height = height; +} + + +static void +CleanUp(void) +{ +#if DEPTH +   glDeleteRenderbuffersEXT(1, &DepthRB); +#endif +#if STENCIL +   glDeleteRenderbuffersEXT(1, &StencilRB); +#endif +   glDeleteFramebuffersEXT(1, &MyFB); + +   glDeleteTextures(1, &TexObj); + +   glutDestroyWindow(Win); + +   exit(0); +} + + +static void +Key(unsigned char key, int x, int y) +{ +   (void) x; +   (void) y; +   switch (key) { +   case 'a': +      Anim = !Anim; +      if (Anim) +         glutIdleFunc(Idle); +      else +         glutIdleFunc(NULL); +      break; +   case 'c': +      Cull = !Cull; +      break; +   case 'w': +      Wireframe = !Wireframe; +      break; +   case 's': +      Rot += 2.0; +      break; +   case 'S': +      Rot -= 2.0; +      break; +   case 27: +      CleanUp(); +      break; +   } +   glutPostRedisplay(); +} + + +/** + * Attach depth and stencil renderbuffer(s) to the given framebuffer object. + * \param tryDepthStencil  if true, try to use a combined depth+stencil buffer + * \param bindDepthStencil  if true, and tryDepthStencil is true, bind with + *                          the GL_DEPTH_STENCIL_ATTACHMENT target. + * \return GL_TRUE for success, GL_FALSE for failure + */ +static GLboolean +AttachDepthAndStencilBuffers(GLuint fbo, +                             GLsizei width, GLsizei height, +                             GLboolean tryDepthStencil, +                             GLboolean bindDepthStencil, +                             GLuint *depthRbOut, GLuint *stencilRbOut) +{ +   GLenum status; + +   *depthRbOut = *stencilRbOut = 0; + +   glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fbo); + +   if (tryDepthStencil) { +      GLuint rb; + +      glGenRenderbuffersEXT(1, &rb); +      glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, rb); +      glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, +                               GL_DEPTH24_STENCIL8_EXT, +                               width, height); +      if (glGetError()) +         return GL_FALSE; + +      if (bindDepthStencil) { +         /* attach to both depth and stencil at once */ +         glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, +                                      GL_DEPTH_STENCIL_ATTACHMENT, +                                      GL_RENDERBUFFER_EXT, rb); +         if (glGetError()) +            return GL_FALSE; +      } +      else { +         /* attach to depth attachment point */ +         glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, +                                      GL_DEPTH_ATTACHMENT_EXT, +                                      GL_RENDERBUFFER_EXT, rb); +         if (glGetError()) +            return GL_FALSE; + +         /* and attach to stencil attachment point */ +         glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, +                                      GL_STENCIL_ATTACHMENT_EXT, +                                      GL_RENDERBUFFER_EXT, rb); +         if (glGetError()) +            return GL_FALSE; +      } + +      status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT); +      if (status != GL_FRAMEBUFFER_COMPLETE_EXT) +         return GL_FALSE; + +      *depthRbOut = *stencilRbOut = rb; +      return GL_TRUE; +   } + +   /* just depth renderbuffer */ +   { +      GLuint rb; + +      glGenRenderbuffersEXT(1, &rb); +      glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, rb); +      glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, +                               GL_DEPTH_COMPONENT, +                               width, height); +      if (glGetError()) +         return GL_FALSE; + +      /* attach to depth attachment point */ +      glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, +                                   GL_DEPTH_ATTACHMENT_EXT, +                                   GL_RENDERBUFFER_EXT, rb); +      if (glGetError()) +         return GL_FALSE; + +      status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT); +      if (status != GL_FRAMEBUFFER_COMPLETE_EXT) +         return GL_FALSE; + +      *depthRbOut = rb; +   } + +   /* just stencil renderbuffer */ +   { +      GLuint rb; + +      glGenRenderbuffersEXT(1, &rb); +      glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, rb); +      glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, +                               GL_STENCIL_INDEX, +                               width, height); +      if (glGetError()) +         return GL_FALSE; + +      /* attach to depth attachment point */ +      glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, +                                   GL_STENCIL_ATTACHMENT_EXT, +                                   GL_RENDERBUFFER_EXT, rb); +      if (glGetError()) +         return GL_FALSE; + +      status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT); +      if (status != GL_FRAMEBUFFER_COMPLETE_EXT) { +         glDeleteRenderbuffersEXT(1, depthRbOut); +         *depthRbOut = 0; +         glDeleteRenderbuffersEXT(1, &rb); +         return GL_FALSE; +      } + +      *stencilRbOut = rb; +   } + +   return GL_TRUE; +} + + +static void +ParseArgs(int argc, char *argv[]) +{ +   GLint i; +   for (i = 1; i < argc; i++) { +      if (strcmp(argv[i], "-ds") == 0) { +         if (!glutExtensionSupported("GL_EXT_packed_depth_stencil")) { +            printf("GL_EXT_packed_depth_stencil not found!\n"); +            exit(0); +         } +         UsePackedDepthStencil = GL_TRUE; +         printf("Using GL_EXT_packed_depth_stencil\n"); +      } +      else if (strcmp(argv[i], "-ds2") == 0) { +         if (!glutExtensionSupported("GL_EXT_packed_depth_stencil")) { +            printf("GL_EXT_packed_depth_stencil not found!\n"); +            exit(0); +         } +         if (!glutExtensionSupported("GL_ARB_framebuffer_object")) { +            printf("GL_ARB_framebuffer_object not found!\n"); +            exit(0); +         } +         UsePackedDepthStencilBoth = GL_TRUE; +         printf("Using GL_EXT_packed_depth_stencil and GL_DEPTH_STENCIL attachment point\n"); +      } +      else if (strcmp(argv[i], "-arb") == 0) { +         if (!glutExtensionSupported("GL_ARB_framebuffer_object")) { +            printf("Sorry, GL_ARB_framebuffer object not supported!\n"); +         } +         else { +            Use_ARB_fbo = GL_TRUE; +         } +      } +      else { +         printf("Unknown option: %s\n", argv[i]); +      } +   } +} + + +/* + * Make FBO to render into given texture. + */ +static GLuint +MakeFBO_RenderTexture(GLuint TexObj) +{ +   GLuint fb; +   GLint sizeFudge = 0; + +   glGenFramebuffersEXT(1, &fb); +   glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fb); +   /* Render color to texture */ +   glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, +                             TexTarget, TexObj, TextureLevel); + +   if (Use_ARB_fbo) { +      /* use a smaller depth buffer to see what happens */ +      sizeFudge = 90; +   } + +   /* Setup depth and stencil buffers */ +   { +      GLboolean b; +      b = AttachDepthAndStencilBuffers(fb, +                                       TexWidth - sizeFudge, +                                       TexHeight - sizeFudge, +                                       UsePackedDepthStencil, +                                       UsePackedDepthStencilBoth, +                                       &DepthRB, &StencilRB); +      if (!b) { +         /* try !UsePackedDepthStencil */ +         b = AttachDepthAndStencilBuffers(fb, +                                          TexWidth - sizeFudge, +                                          TexHeight - sizeFudge, +                                          !UsePackedDepthStencil, +                                          UsePackedDepthStencilBoth, +                                          &DepthRB, &StencilRB); +      } +      if (!b) { +         printf("Unable to create/attach depth and stencil renderbuffers " +                " to FBO!\n"); +         exit(1); +      } +   } + +   /* queries */ +   { +      GLint bits, w, h; + +      glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, DepthRB); +      glGetRenderbufferParameterivEXT(GL_RENDERBUFFER_EXT, +                                      GL_RENDERBUFFER_WIDTH_EXT, &w); +      glGetRenderbufferParameterivEXT(GL_RENDERBUFFER_EXT, +                                      GL_RENDERBUFFER_HEIGHT_EXT, &h); +      printf("Color/Texture size: %d x %d\n", TexWidth, TexHeight); +      printf("Depth buffer size: %d x %d\n", w, h); + +      glGetRenderbufferParameterivEXT(GL_RENDERBUFFER_EXT, +                                      GL_RENDERBUFFER_DEPTH_SIZE_EXT, &bits); +      printf("Depth renderbuffer size = %d bits\n", bits); + +      glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, StencilRB); +      glGetRenderbufferParameterivEXT(GL_RENDERBUFFER_EXT, +                                      GL_RENDERBUFFER_STENCIL_SIZE_EXT, &bits); +      printf("Stencil renderbuffer size = %d bits\n", bits); +   } + +   /* bind the regular framebuffer */ +   glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); + +   return fb; +} + + +static void +Init(void) +{ +   if (!glutExtensionSupported("GL_EXT_framebuffer_object")) { +      printf("GL_EXT_framebuffer_object not found!\n"); +      exit(0); +   } + +   printf("GL_RENDERER = %s\n", (char *) glGetString(GL_RENDERER)); + +   /* lighting */ +   { +      static const GLfloat mat[4] = { 1.0, 0.5, 0.5, 1.0 }; +      glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, mat); +   } + +   /* +    * Make texture object/image (we'll render into this texture) +    */ +   { +      glGenTextures(1, &TexObj); +      glBindTexture(TexTarget, TexObj); + +      /* make two image levels */ +      glTexImage2D(TexTarget, 0, TexIntFormat, TexWidth, TexHeight, 0, +                   GL_RGBA, GL_UNSIGNED_BYTE, NULL); +      if (TexTarget == GL_TEXTURE_2D) { +         glTexImage2D(TexTarget, 1, TexIntFormat, TexWidth/2, TexHeight/2, 0, +                      GL_RGBA, GL_UNSIGNED_BYTE, NULL); +         TexWidth = TexWidth >> TextureLevel; +         TexHeight = TexHeight >> TextureLevel; +         glTexParameteri(TexTarget, GL_TEXTURE_MAX_LEVEL, TextureLevel); +      } + +      glTexParameteri(TexTarget, GL_TEXTURE_MIN_FILTER, GL_NEAREST); +      glTexParameteri(TexTarget, GL_TEXTURE_MAG_FILTER, GL_NEAREST); +      glTexParameteri(TexTarget, GL_TEXTURE_BASE_LEVEL, TextureLevel); +      glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); +   } + +   MyFB = MakeFBO_RenderTexture(TexObj); +} + + +static void +Usage(void) +{ +   printf("Usage:\n"); +   printf("  -ds  Use combined depth/stencil renderbuffer\n"); +   printf("  -arb Try GL_ARB_framebuffer_object's mismatched buffer sizes\n"); +   printf("  -ds2 Try GL_ARB_framebuffer_object's GL_DEPTH_STENCIL_ATTACHMENT\n"); +   printf("Keys:\n"); +   printf("  a    Toggle animation\n"); +   printf("  s/s  Step/rotate\n"); +   printf("  c    Toggle back-face culling\n"); +   printf("  w    Toggle wireframe mode (front-face only)\n"); +   printf("  Esc  Exit\n"); +} + + +int +main(int argc, char *argv[]) +{ +   glutInit(&argc, argv); +   glutInitWindowPosition(0, 0); +   glutInitWindowSize(Width, Height); +   glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE); +   Win = glutCreateWindow(argv[0]); +   glewInit(); +   glutReshapeFunc(Reshape); +   glutKeyboardFunc(Key); +   glutDisplayFunc(Display); +   if (Anim) +      glutIdleFunc(Idle); + +   ParseArgs(argc, argv); +   Init(); +   Usage(); + +   glutMainLoop(); +   return 0; +} diff --git a/progs/demos/glslnoise.c b/progs/demos/glslnoise.c deleted file mode 100644 index e972b62673..0000000000 --- a/progs/demos/glslnoise.c +++ /dev/null @@ -1,201 +0,0 @@ -/* - * GLSL noise demo. - * - * Michal Krol - * 20 February 2006 - * - * Based on the original demo by: - * Stefan Gustavson (stegu@itn.liu.se) 2004, 2005 - */ - -#ifdef WIN32 -#include <windows.h> -#endif - -#include <stdio.h> -#include <stdlib.h> -#include <GL/gl.h> -#include <GL/glut.h> -#include <GL/glext.h> - -#ifdef WIN32 -#define GETPROCADDRESS(F) wglGetProcAddress(F) -#else -#define GETPROCADDRESS(F) glutGetProcAddress(F) -#endif - -static GLhandleARB fragShader; -static GLhandleARB vertShader; -static GLhandleARB program; - -static GLint uTime; - -static GLint t0 = 0; -static GLint frames = 0; - -static GLfloat u_time = 0.0f; - -static PFNGLCREATESHADEROBJECTARBPROC glCreateShaderObjectARB = NULL; -static PFNGLSHADERSOURCEARBPROC glShaderSourceARB = NULL; -static PFNGLCOMPILESHADERARBPROC glCompileShaderARB = NULL; -static PFNGLCREATEPROGRAMOBJECTARBPROC glCreateProgramObjectARB = NULL; -static PFNGLATTACHOBJECTARBPROC glAttachObjectARB = NULL; -static PFNGLLINKPROGRAMARBPROC glLinkProgramARB = NULL; -static PFNGLUSEPROGRAMOBJECTARBPROC glUseProgramObjectARB = NULL; -static PFNGLGETUNIFORMLOCATIONARBPROC glGetUniformLocationARB = NULL; -static PFNGLUNIFORM1FARBPROC glUniform1fARB = NULL; - -static void Redisplay (void) -{ -   GLint t; - -	glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - -	glUniform1fARB (uTime, 0.5f * u_time); - -	glPushMatrix (); -	glutSolidSphere (2.0, 20, 10); -	glPopMatrix (); - -	glutSwapBuffers(); -   frames++; - -   t = glutGet (GLUT_ELAPSED_TIME); -   if (t - t0 >= 5000) { -      GLfloat seconds = (GLfloat) (t - t0) / 1000.0f; -      GLfloat fps = frames / seconds; -      printf ("%d frames in %6.3f seconds = %6.3f FPS\n", frames, seconds, fps); -      fflush(stdout); -      t0 = t; -      frames = 0; -   } -} - -static void Idle (void) -{ -	u_time += 0.1f; -	glutPostRedisplay (); -} - -static void Reshape (int width, int height) -{ -	glViewport (0, 0, width, height); -	glMatrixMode (GL_PROJECTION); -	glLoadIdentity (); -	glFrustum (-1.0, 1.0, -1.0, 1.0, 5.0, 25.0); -	glMatrixMode (GL_MODELVIEW); -	glLoadIdentity (); -	glTranslatef (0.0f, 0.0f, -15.0f); -} - -static void Key (unsigned char key, int x, int y) -{ -	(void) x; -	(void) y; - -	switch (key) -	{ -	case 27: -		exit(0); -		break; -	} -	glutPostRedisplay (); -} - -static void Init (void) -{ -   static const char *fragShaderText = -      "uniform float time;\n" -      "varying vec3 position;\n" -      "void main () {\n" -      "   gl_FragColor = vec4 (vec3 (0.5 + 0.5 * noise1 (vec4 (position, time))), 1.0);\n" -      "}\n" -   ; -   static const char *vertShaderText = -      "varying vec3 position;\n" -      "void main () {\n" -      "   gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;\n" -      "   position = 4.0 * gl_Vertex.xyz;\n" -      "}\n" -   ; - -	if (!glutExtensionSupported ("GL_ARB_fragment_shader")) -	{ -		printf ("Sorry, this demo requires GL_ARB_fragment_shader\n"); -		exit(1); -	} -	if (!glutExtensionSupported ("GL_ARB_shader_objects")) -	{ -		printf ("Sorry, this demo requires GL_ARB_shader_objects\n"); -		exit(1); -	} -	if (!glutExtensionSupported ("GL_ARB_shading_language_100")) -	{ -		printf ("Sorry, this demo requires GL_ARB_shading_language_100\n"); -		exit(1); -	} -	if (!glutExtensionSupported ("GL_ARB_vertex_shader")) -	{ -		printf ("Sorry, this demo requires GL_ARB_vertex_shader\n"); -		exit(1); -	} - -	glCreateShaderObjectARB = (PFNGLCREATESHADEROBJECTARBPROC) -		GETPROCADDRESS("glCreateShaderObjectARB"); - 	glShaderSourceARB = (PFNGLSHADERSOURCEARBPROC) -		GETPROCADDRESS("glShaderSourceARB"); - 	glCompileShaderARB = (PFNGLCOMPILESHADERARBPROC) -		GETPROCADDRESS("glCompileShaderARB"); - 	glCreateProgramObjectARB = (PFNGLCREATEPROGRAMOBJECTARBPROC) -		GETPROCADDRESS("glCreateProgramObjectARB"); - 	glAttachObjectARB = (PFNGLATTACHOBJECTARBPROC) -		GETPROCADDRESS("glAttachObjectARB"); - 	glLinkProgramARB = (PFNGLLINKPROGRAMARBPROC) -		GETPROCADDRESS ("glLinkProgramARB"); - 	glUseProgramObjectARB = (PFNGLUSEPROGRAMOBJECTARBPROC) -		GETPROCADDRESS("glUseProgramObjectARB");           - -	glGetUniformLocationARB = (PFNGLGETUNIFORMLOCATIONARBPROC) -		GETPROCADDRESS("glGetUniformLocationARB"); -	glUniform1fARB = (PFNGLUNIFORM1FARBPROC) -		GETPROCADDRESS("glUniform1fARB"); - -	fragShader = glCreateShaderObjectARB (GL_FRAGMENT_SHADER_ARB); -	glShaderSourceARB (fragShader, 1, &fragShaderText, NULL); -	glCompileShaderARB (fragShader); - -	vertShader = glCreateShaderObjectARB (GL_VERTEX_SHADER_ARB); -	glShaderSourceARB (vertShader, 1, &vertShaderText, NULL); -	glCompileShaderARB (vertShader); - -	program = glCreateProgramObjectARB (); -	glAttachObjectARB (program, fragShader); -	glAttachObjectARB (program, vertShader); -	glLinkProgramARB (program); -	glUseProgramObjectARB (program); - -	uTime = glGetUniformLocationARB (program, "time"); - -	glClearColor (0.0f, 0.1f, 0.3f, 1.0f); -	glEnable (GL_CULL_FACE); -	glEnable (GL_DEPTH_TEST); - -	printf ("GL_RENDERER = %s\n", (const char *) glGetString (GL_RENDERER)); -} - -int main (int argc, char *argv[]) -{ -	glutInit (&argc, argv); -	glutInitWindowPosition ( 0, 0); -	glutInitWindowSize (200, 200); -	glutInitDisplayMode (GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH); -	glutCreateWindow (argv[0]); -	glutReshapeFunc (Reshape); -	glutKeyboardFunc (Key); -	glutDisplayFunc (Redisplay); -	glutIdleFunc (Idle); -	Init (); -	glutMainLoop (); -	return 0; -} - diff --git a/progs/demos/glutfx.c b/progs/demos/glutfx.c deleted file mode 100644 index 8bf5582389..0000000000 --- a/progs/demos/glutfx.c +++ /dev/null @@ -1,189 +0,0 @@ - -/* - * Example of how one might use GLUT with the 3Dfx driver in full-screen mode. - * Note: this only works with X since we're using Mesa's GLX "hack" for - * using Glide. - * - * Goals: - *   easy setup and input event handling with GLUT - *   use 3Dfx hardware - *   automatically set MESA environment variables - *   don't lose mouse input focus - * - * Brian Paul   This file is in the public domain. - */ - - -#include <stdio.h> -#include <stdlib.h> -#include <math.h> -#include <GL/glut.h> - - -#define WIDTH 640 -#define HEIGHT 480 - - -static int Window = 0; -static int ScreenWidth, ScreenHeight; -static GLuint Torus = 0; -static GLfloat Xrot = 0.0, Yrot = 0.0; - - - -static void Display( void ) -{ -   static GLfloat blue[4] = {0.2, 0.2, 1.0, 1.0}; -   static GLfloat red[4] = {1.0, 0.2, 0.2, 1.0}; -   static GLfloat green[4] = {0.2, 1.0, 0.2, 1.0}; - -   glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT ); - -   glPushMatrix(); -   glRotatef(Xrot, 1, 0, 0); -   glRotatef(Yrot, 0, 1, 0); - -   glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, blue); -   glCallList(Torus); - -   glRotatef(90.0, 1, 0, 0); -   glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, red); -   glCallList(Torus); - -   glRotatef(90.0, 0, 1, 0); -   glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, green); -   glCallList(Torus); - -   glPopMatrix(); - -   glutSwapBuffers(); -} - - -static void Reshape( int width, int height ) -{ -   float ratio = (float) width / (float) height; - -   ScreenWidth = width; -   ScreenHeight = height; - -   /* -    * The 3Dfx driver is limited to 640 x 480 but the X window may be larger. -    * Enforce that here. -    */ -   if (width > WIDTH) -      width = WIDTH; -   if (height > HEIGHT) -      height = HEIGHT; - -   glViewport( 0, 0, width, height ); -   glMatrixMode( GL_PROJECTION ); -   glLoadIdentity(); -   glFrustum( -ratio, ratio, -1.0, 1.0, 5.0, 30.0 ); -   glMatrixMode( GL_MODELVIEW ); -   glLoadIdentity(); -   glTranslatef( 0.0, 0.0, -20.0 ); -} - - -static void Key( unsigned char key, int x, int y ) -{ -   (void) x; -   (void) y; -   switch (key) { -      case 27: -         glutDestroyWindow(Window); -         exit(0); -         break; -   } -   glutPostRedisplay(); -} - - -static void SpecialKey( int key, int x, int y ) -{ -   (void) x; -   (void) y; -   switch (key) { -      case GLUT_KEY_UP: -         break; -      case GLUT_KEY_DOWN: -         break; -      case GLUT_KEY_LEFT: -         break; -      case GLUT_KEY_RIGHT: -         break; -   } -   glutPostRedisplay(); -} - - -static void MouseMove( int x, int y ) -{ -   Xrot = y - ScreenWidth / 2; -   Yrot = x - ScreenHeight / 2; -   glutPostRedisplay(); -} - - -static void Init( void ) -{ -   Torus = glGenLists(1); -   glNewList(Torus, GL_COMPILE); -   glutSolidTorus(0.5, 2.0, 10, 20); -   glEndList(); - -   glEnable(GL_LIGHTING); -   glEnable(GL_LIGHT0); - -   glEnable(GL_DEPTH_TEST); -   glEnable(GL_CULL_FACE); -} - - -int main( int argc, char *argv[] ) -{ -#ifndef _WIN32 -   printf("NOTE: if you've got 3Dfx VooDoo hardware you must run this"); -   printf(" program as root.\n\n"); -   printf("Move the mouse.  Press ESC to exit.\n\n"); -#endif - -   /* Tell Mesa GLX to use 3Dfx driver in fullscreen mode. */ -   putenv("MESA_GLX_FX=fullscreen"); - -   /* Disable 3Dfx Glide splash screen */ -   putenv("FX_GLIDE_NO_SPLASH="); - -   /* Give an initial size and position so user doesn't have to place window */ -   glutInitWindowPosition(0, 0); -   glutInitWindowSize(WIDTH, HEIGHT); -   glutInit( &argc, argv ); - -   glutInitDisplayMode( GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH ); - -   Window = glutCreateWindow(argv[0]); -   if (!Window) { -      printf("Error, couldn't open window\n"); -      exit(1); -   } - -   /* -    * Want the X window to fill the screen so that we don't have to -    * worry about losing the mouse input focus. -    * Note that we won't actually see the X window since we never draw -    * to it, hence, the original X screen's contents aren't disturbed. -    */ -   glutFullScreen(); - -   Init(); - -   glutReshapeFunc( Reshape ); -   glutKeyboardFunc( Key ); -   glutSpecialFunc( SpecialKey ); -   glutDisplayFunc( Display ); -   glutPassiveMotionFunc( MouseMove ); - -   glutMainLoop(); -   return 0; -} diff --git a/progs/demos/occlude.c b/progs/demos/occlude.c deleted file mode 100644 index 8f7b90984e..0000000000 --- a/progs/demos/occlude.c +++ /dev/null @@ -1,234 +0,0 @@ -/* - * GL_HP_occlustion_test demo - * - * Brian Paul - * 31 March 2000 - * - * Copyright (C) 2000  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 <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <math.h> -#include <GL/glut.h> -#include <GL/glext.h> - - -static GLfloat Xpos = 0; -static GLboolean Anim = GL_TRUE; - - -static void -PrintString(const char *s) -{ -   while (*s) { -      glutBitmapCharacter(GLUT_BITMAP_8_BY_13, (int) *s); -      s++; -   } -} - - - -static void Idle(void) -{ -   static int lastTime = 0; -   static int sign = +1; -   int time = glutGet(GLUT_ELAPSED_TIME); -   float step; - -   if (lastTime == 0) -      lastTime = time; -   else if (time - lastTime < 20)  /* 50Hz update */ -      return; - -   step = (time - lastTime) / 1000.0 * sign; -   lastTime = time; - -   Xpos += step; - -   if (Xpos > 2.5) { -      Xpos = 2.5; -      sign = -1; -   } -   else if (Xpos < -2.5) { -      Xpos = -2.5; -      sign = +1; -   } -   glutPostRedisplay(); -} - - -static void Display( void ) -{ -   GLboolean result; - -   glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT ); - -   glMatrixMode( GL_PROJECTION ); -   glLoadIdentity(); -   glFrustum( -1.0, 1.0, -1.0, 1.0, 5.0, 25.0 ); -   glMatrixMode( GL_MODELVIEW ); -   glLoadIdentity(); -   glTranslatef( 0.0, 0.0, -15.0 ); - -   /* draw the occluding polygons */ -   glColor3f(0, 0.6, 0.8); -   glBegin(GL_QUADS); -   glVertex2f(-1.6, -1.5); -   glVertex2f(-0.4, -1.5); -   glVertex2f(-0.4,  1.5); -   glVertex2f(-1.6,  1.5); - -   glVertex2f( 0.4, -1.5); -   glVertex2f( 1.6, -1.5); -   glVertex2f( 1.6,  1.5); -   glVertex2f( 0.4,  1.5); -   glEnd(); - -   /* draw the test polygon with occlusion testing */ -   glPushMatrix(); -   glTranslatef(Xpos, 0, -0.5); -   glScalef(0.3, 0.3, 1.0); -   glRotatef(-90.0 * Xpos, 0, 0, 1); - -   glEnable(GL_OCCLUSION_TEST_HP);  /* NOTE: enabling the occlusion test */ -                                    /* doesn't clear the result flag! */ -   glColorMask(0, 0, 0, 0); -   glDepthMask(GL_FALSE); -   /* this call clear's the result flag.  Not really needed for this demo. */ -   glGetBooleanv(GL_OCCLUSION_TEST_RESULT_HP, &result); - -   glBegin(GL_POLYGON); -   glVertex3f(-1, -1, 0); -   glVertex3f( 1, -1, 0); -   glVertex3f( 1,  1, 0); -   glVertex3f(-1,  1, 0); -   glEnd(); - -   glGetBooleanv(GL_OCCLUSION_TEST_RESULT_HP, &result); -   /* turn off occlusion testing */ -   glDisable(GL_OCCLUSION_TEST_HP); -   glColorMask(1, 1, 1, 1); -   glDepthMask(GL_TRUE); - -   /* draw the green rect, so we can see what's going on */ -   glColor3f(0.8, 0.5, 0); -   glBegin(GL_POLYGON); -   glVertex3f(-1, -1, 0); -   glVertex3f( 1, -1, 0); -   glVertex3f( 1,  1, 0); -   glVertex3f(-1,  1, 0); -   glEnd(); - -   glPopMatrix(); - - -   /* Print result message */ -   glMatrixMode( GL_PROJECTION ); -   glLoadIdentity(); -   glOrtho( -1.0, 1.0, -1.0, 1.0, -1.0, 1.0 ); -   glMatrixMode( GL_MODELVIEW ); -   glLoadIdentity(); - -   glColor3f(1, 1, 1); -   glRasterPos3f(-0.25, -0.7, 0); - -   if (result) -      PrintString("   Visible"); -   else -      PrintString("Fully Occluded"); - -   glutSwapBuffers(); -} - - -static void Reshape( int width, int height ) -{ -   glViewport( 0, 0, width, height ); -} - - -static void Key( unsigned char key, int x, int y ) -{ -   (void) x; -   (void) y; -   switch (key) { -      case 'a': -         Anim = !Anim; -         if (Anim) -            glutIdleFunc( Idle ); -         else -            glutIdleFunc( NULL ); -         break; -      case 27: -         exit(0); -         break; -   } -   glutPostRedisplay(); -} - - -static void SpecialKey( int key, int x, int y ) -{ -   const GLfloat step = 0.1; -   (void) x; -   (void) y; -   switch (key) { -      case GLUT_KEY_LEFT: -         Xpos -= step; -         break; -      case GLUT_KEY_RIGHT: -         Xpos += step; -         break; -   } -   glutPostRedisplay(); -} - - -static void Init( void ) -{ -   const char *ext = (const char *) glGetString(GL_EXTENSIONS); -   if (!strstr(ext, "GL_HP_occlusion_test")) { -      printf("Sorry, this demo requires the GL_HP_occlusion_test extension\n"); -      exit(-1); -   } - -   glEnable(GL_DEPTH_TEST); -} - - -int main( int argc, char *argv[] ) -{ -   glutInit( &argc, argv ); -   glutInitWindowPosition( 0, 0 ); -   glutInitWindowSize( 400, 400 ); -   glutInitDisplayMode( GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH ); -   glutCreateWindow(argv[0]); -   glutReshapeFunc( Reshape ); -   glutKeyboardFunc( Key ); -   glutSpecialFunc( SpecialKey ); -   glutIdleFunc( Idle ); -   glutDisplayFunc( Display ); -   Init(); -   glutMainLoop(); -   return 0; -} diff --git a/progs/demos/projtex.c b/progs/demos/projtex.c new file mode 100644 index 0000000000..99154d7bdc --- /dev/null +++ b/progs/demos/projtex.c @@ -0,0 +1,1028 @@ + +/* projtex.c - by David Yu and David Blythe, SGI */ + +/** + ** Demonstrates simple projective texture mapping. + ** + ** Button1 changes view, Button2 moves texture. + ** + ** (See: Segal, Korobkin, van Widenfelt, Foran, and Haeberli + **  "Fast Shadows and Lighting Effects Using Texture Mapping", SIGGRAPH '92) + ** + ** 1994,1995 -- David G Yu + ** + ** cc -o projtex projtex.c texture.c -lglut -lGLU -lGL -lX11 -lm + **/ + +#include <assert.h> +#include <stdio.h> +#include <stdlib.h> +#include <math.h> +#include <GL/glew.h> +#include <GL/glut.h> +#include "readtex.h" + + +/* Some <math.h> files do not define M_PI... */ +#ifndef M_PI +#define M_PI 3.14159265358979323846 +#endif + +#define MAX_TEX 4 +int NumTextures = 1; + +int winWidth, winHeight; + +GLboolean redrawContinuously = GL_FALSE; + +float angle, axis[3]; +enum MoveModes { +  MoveNone, MoveView, MoveObject, MoveTexture +}; +enum MoveModes mode = MoveNone; + +GLfloat objectXform[4][4]; +GLfloat textureXform[MAX_TEX][4][4]; + +void (*drawObject) (void); +void (*loadTexture) (void); +GLboolean textureEnabled = GL_TRUE; +GLboolean showProjection = GL_TRUE; +GLboolean linearFilter = GL_TRUE; + +char *texFilename[MAX_TEX] = { +   "../images/girl.rgb", +   "../images/tile.rgb", +   "../images/bw.rgb", +   "../images/reflect.rgb" +}; + + +GLfloat zoomFactor = 1.0; + +/*****************************************************************/ + + +static void +ActiveTexture(int i) +{ +   glActiveTextureARB(i); +} + + +/* matrix = identity */ +static void +matrixIdentity(GLfloat matrix[16]) +{ +  matrix[0] = 1.0; +  matrix[1] = 0.0; +  matrix[2] = 0.0; +  matrix[3] = 0.0; +  matrix[4] = 0.0; +  matrix[5] = 1.0; +  matrix[6] = 0.0; +  matrix[7] = 0.0; +  matrix[8] = 0.0; +  matrix[9] = 0.0; +  matrix[10] = 1.0; +  matrix[11] = 0.0; +  matrix[12] = 0.0; +  matrix[13] = 0.0; +  matrix[14] = 0.0; +  matrix[15] = 1.0; +} + +/* matrix2 = transpose(matrix1) */ +static void +matrixTranspose(GLfloat matrix2[16], GLfloat matrix1[16]) +{ +  matrix2[0] = matrix1[0]; +  matrix2[1] = matrix1[4]; +  matrix2[2] = matrix1[8]; +  matrix2[3] = matrix1[12]; + +  matrix2[4] = matrix1[1]; +  matrix2[5] = matrix1[5]; +  matrix2[6] = matrix1[9]; +  matrix2[7] = matrix1[13]; + +  matrix2[8] = matrix1[2]; +  matrix2[9] = matrix1[6]; +  matrix2[10] = matrix1[10]; +  matrix2[11] = matrix1[14]; + +  matrix2[12] = matrix1[3]; +  matrix2[13] = matrix1[7]; +  matrix2[14] = matrix1[14]; +  matrix2[15] = matrix1[15]; +} + +/*****************************************************************/ + +/* load SGI .rgb image (pad with a border of the specified width and color) */ +#if 0 +static void +imgLoad(char *filenameIn, int borderIn, GLfloat borderColorIn[4], +  int *wOut, int *hOut, GLubyte ** imgOut) +{ +  int border = borderIn; +  int width, height; +  int w, h; +  GLubyte *image, *img, *p; +  int i, j, components; + +  image = (GLubyte *) read_texture(filenameIn, &width, &height, &components); +  w = width + 2 * border; +  h = height + 2 * border; +  img = (GLubyte *) calloc(w * h, 4 * sizeof(unsigned char)); + +  p = img; +  for (j = -border; j < height + border; ++j) { +    for (i = -border; i < width + border; ++i) { +      if (0 <= j && j <= height - 1 && 0 <= i && i <= width - 1) { +        p[0] = image[4 * (j * width + i) + 0]; +        p[1] = image[4 * (j * width + i) + 1]; +        p[2] = image[4 * (j * width + i) + 2]; +        p[3] = 0xff; +      } else { +        p[0] = borderColorIn[0] * 0xff; +        p[1] = borderColorIn[1] * 0xff; +        p[2] = borderColorIn[2] * 0xff; +        p[3] = borderColorIn[3] * 0xff; +      } +      p += 4; +    } +  } +  free(image); +  *wOut = w; +  *hOut = h; +  *imgOut = img; +} +#endif + + +/*****************************************************************/ + +/* Load the image file specified on the command line as the current texture */ +static void +loadImageTextures(void) +{ +  GLfloat borderColor[4] = +  {1.0, 1.0, 1.0, 1.0}; +  int tex; + +  for (tex = 0; tex < NumTextures; tex++) { +     GLubyte *image, *texData3, *texData4; +     GLint imgWidth, imgHeight; +     GLenum imgFormat; +     int i, j; + +     printf("loading %s\n", texFilename[tex]); +     image = LoadRGBImage(texFilename[tex], &imgWidth, &imgHeight, &imgFormat); +     if (!image) { +        printf("can't find %s\n", texFilename[tex]); +        exit(1); +     } +     assert(imgFormat == GL_RGB); + +     /* scale to 256x256 */ +     texData3 = malloc(256 * 256 * 4); +     texData4 = malloc(256 * 256 * 4); +     assert(texData3); +     assert(texData4); +     gluScaleImage(imgFormat, imgWidth, imgHeight, GL_UNSIGNED_BYTE, image, +                   256, 256, GL_UNSIGNED_BYTE, texData3); + +     /* convert to rgba */ +     for (i = 0; i < 256 * 256; i++) { +        texData4[i*4+0] = texData3[i*3+0]; +        texData4[i*4+1] = texData3[i*3+1]; +        texData4[i*4+2] = texData3[i*3+2]; +        texData4[i*4+3] = 128; +     } + +     /* put transparent border around image */ +     for (i = 0; i < 256; i++) { +        texData4[i*4+0] = 255; +        texData4[i*4+1] = 255; +        texData4[i*4+2] = 255; +        texData4[i*4+3] = 0; +     } +     j = 256 * 255 * 4; +     for (i = 0; i < 256; i++) { +        texData4[j + i*4+0] = 255; +        texData4[j + i*4+1] = 255; +        texData4[j + i*4+2] = 255; +        texData4[j + i*4+3] = 0; +     } +     for (i = 0; i < 256; i++) { +        j = i * 256 * 4; +        texData4[j+0] = 255; +        texData4[j+1] = 255; +        texData4[j+2] = 255; +        texData4[j+3] = 0; +     } +     for (i = 0; i < 256; i++) { +        j = i * 256 * 4 + 255 * 4; +        texData4[j+0] = 255; +        texData4[j+1] = 255; +        texData4[j+2] = 255; +        texData4[j+3] = 0; +     } + +     ActiveTexture(GL_TEXTURE0_ARB + tex); +     glBindTexture(GL_TEXTURE_2D, tex + 1); + +     glPixelStorei(GL_UNPACK_ALIGNMENT, 1); +     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 256, 256, 0, +                  GL_RGBA, GL_UNSIGNED_BYTE, texData4); + +     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); +     } +     glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, borderColor); +  } +} + +/* Create a simple spotlight pattern and make it the current texture */ +static void +loadSpotlightTexture(void) +{ +  static int texWidth = 64, texHeight = 64; +  static GLubyte *texData; +  GLfloat borderColor[4] = +  {0.1, 0.1, 0.1, 1.0}; + +  if (!texData) { +    GLubyte *p; +    int i, j; + +    texData = (GLubyte *) malloc(texWidth * texHeight * 4 * sizeof(GLubyte)); + +    p = texData; +    for (j = 0; j < texHeight; ++j) { +      float dy = (texHeight * 0.5 - j + 0.5) / (texHeight * 0.5); + +      for (i = 0; i < texWidth; ++i) { +        float dx = (texWidth * 0.5 - i + 0.5) / (texWidth * 0.5); +        float r = cos(M_PI / 2.0 * sqrt(dx * dx + dy * dy)); +        float c; + +        r = (r < 0) ? 0 : r * r; +        c = 0xff * (r + borderColor[0]); +        p[0] = (c <= 0xff) ? c : 0xff; +        c = 0xff * (r + borderColor[1]); +        p[1] = (c <= 0xff) ? c : 0xff; +        c = 0xff * (r + borderColor[2]); +        p[2] = (c <= 0xff) ? c : 0xff; +        c = 0xff * (r + borderColor[3]); +        p[3] = (c <= 0xff) ? c : 0xff; +        p += 4; +      } +    } +  } +  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); +  } +  glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, borderColor); +  gluBuild2DMipmaps(GL_TEXTURE_2D, 4, texWidth, texHeight, +    GL_RGBA, GL_UNSIGNED_BYTE, texData); +} + +/*****************************************************************/ + +static void +checkErrors(void) +{ +  GLenum error; +  while ((error = glGetError()) != GL_NO_ERROR) { +    fprintf(stderr, "Error: %s\n", (char *) gluErrorString(error)); +  } +} + +static void +drawCube(void) +{ +  glBegin(GL_QUADS); + +  glNormal3f(-1.0, 0.0, 0.0); +  glColor3f(0.80, 0.50, 0.50); +  glVertex3f(-0.5, -0.5, -0.5); +  glVertex3f(-0.5, -0.5, 0.5); +  glVertex3f(-0.5, 0.5, 0.5); +  glVertex3f(-0.5, 0.5, -0.5); + +  glNormal3f(1.0, 0.0, 0.0); +  glColor3f(0.50, 0.80, 0.50); +  glVertex3f(0.5, 0.5, 0.5); +  glVertex3f(0.5, -0.5, 0.5); +  glVertex3f(0.5, -0.5, -0.5); +  glVertex3f(0.5, 0.5, -0.5); + +  glNormal3f(0.0, -1.0, 0.0); +  glColor3f(0.50, 0.50, 0.80); +  glVertex3f(-0.5, -0.5, -0.5); +  glVertex3f(0.5, -0.5, -0.5); +  glVertex3f(0.5, -0.5, 0.5); +  glVertex3f(-0.5, -0.5, 0.5); + +  glNormal3f(0.0, 1.0, 0.0); +  glColor3f(0.50, 0.80, 0.80); +  glVertex3f(0.5, 0.5, 0.5); +  glVertex3f(0.5, 0.5, -0.5); +  glVertex3f(-0.5, 0.5, -0.5); +  glVertex3f(-0.5, 0.5, 0.5); + +  glNormal3f(0.0, 0.0, -1.0); +  glColor3f(0.80, 0.50, 0.80); +  glVertex3f(-0.5, -0.5, -0.5); +  glVertex3f(-0.5, 0.5, -0.5); +  glVertex3f(0.5, 0.5, -0.5); +  glVertex3f(0.5, -0.5, -0.5); + +  glNormal3f(0.0, 0.0, 1.0); +  glColor3f(1.00, 0.80, 0.50); +  glVertex3f(0.5, 0.5, 0.5); +  glVertex3f(-0.5, 0.5, 0.5); +  glVertex3f(-0.5, -0.5, 0.5); +  glVertex3f(0.5, -0.5, 0.5); +  glEnd(); +} + +static void +drawDodecahedron(void) +{ +#define A (0.5 * 1.61803)  /* (sqrt(5) + 1) / 2 */ +#define B (0.5 * 0.61803)  /* (sqrt(5) - 1) / 2 */ +#define C (0.5 * 1.0) +  GLfloat vertexes[20][3] = +  { +    {-A, 0.0, B}, +    {-A, 0.0, -B}, +    {A, 0.0, -B}, +    {A, 0.0, B}, +    {B, -A, 0.0}, +    {-B, -A, 0.0}, +    {-B, A, 0.0}, +    {B, A, 0.0}, +    {0.0, B, -A}, +    {0.0, -B, -A}, +    {0.0, -B, A}, +    {0.0, B, A}, +    {-C, -C, C}, +    {-C, -C, -C}, +    {C, -C, -C}, +    {C, -C, C}, +    {-C, C, C}, +    {-C, C, -C}, +    {C, C, -C}, +    {C, C, C}, +  }; +#undef A +#undef B +#undef C +  GLint polygons[12][5] = +  { +    {0, 12, 10, 11, 16}, +    {1, 17, 8, 9, 13}, +    {2, 14, 9, 8, 18}, +    {3, 19, 11, 10, 15}, +    {4, 14, 2, 3, 15}, +    {5, 12, 0, 1, 13}, +    {6, 17, 1, 0, 16}, +    {7, 19, 3, 2, 18}, +    {8, 17, 6, 7, 18}, +    {9, 14, 4, 5, 13}, +    {10, 12, 5, 4, 15}, +    {11, 19, 7, 6, 16}, +  }; +  int i; + +  glColor3f(0.75, 0.75, 0.75); +  for (i = 0; i < 12; ++i) { +    GLfloat *p0, *p1, *p2, d; +    GLfloat u[3], v[3], n[3]; + +    p0 = &vertexes[polygons[i][0]][0]; +    p1 = &vertexes[polygons[i][1]][0]; +    p2 = &vertexes[polygons[i][2]][0]; + +    u[0] = p2[0] - p1[0]; +    u[1] = p2[1] - p1[1]; +    u[2] = p2[2] - p1[2]; + +    v[0] = p0[0] - p1[0]; +    v[1] = p0[1] - p1[1]; +    v[2] = p0[2] - p1[2]; + +    n[0] = u[1] * v[2] - u[2] * v[1]; +    n[1] = u[2] * v[0] - u[0] * v[2]; +    n[2] = u[0] * v[1] - u[1] * v[0]; + +    d = 1.0 / sqrt(n[0] * n[0] + n[1] * n[1] + n[2] * n[2]); +    n[0] *= d; +    n[1] *= d; +    n[2] *= d; + +    glBegin(GL_POLYGON); +    glNormal3fv(n); +    glVertex3fv(p0); +    glVertex3fv(p1); +    glVertex3fv(p2); +    glVertex3fv(vertexes[polygons[i][3]]); +    glVertex3fv(vertexes[polygons[i][4]]); +    glEnd(); +  } +} + +static void +drawSphere(void) +{ +  int numMajor = 24; +  int numMinor = 32; +  float radius = 0.8; +  double majorStep = (M_PI / numMajor); +  double minorStep = (2.0 * M_PI / numMinor); +  int i, j; + +  glColor3f(0.50, 0.50, 0.50); +  for (i = 0; i < numMajor; ++i) { +    double a = i * majorStep; +    double b = a + majorStep; +    double r0 = radius * sin(a); +    double r1 = radius * sin(b); +    GLfloat z0 = radius * cos(a); +    GLfloat z1 = radius * cos(b); + +    glBegin(GL_TRIANGLE_STRIP); +    for (j = 0; j <= numMinor; ++j) { +      double c = j * minorStep; +      GLfloat x = cos(c); +      GLfloat y = sin(c); + +      glNormal3f((x * r0) / radius, (y * r0) / radius, z0 / radius); +      glTexCoord2f(j / (GLfloat) numMinor, i / (GLfloat) numMajor); +      glVertex3f(x * r0, y * r0, z0); + +      glNormal3f((x * r1) / radius, (y * r1) / radius, z1 / radius); +      glTexCoord2f(j / (GLfloat) numMinor, (i + 1) / (GLfloat) numMajor); +      glVertex3f(x * r1, y * r1, z1); +    } +    glEnd(); +  } +} + +/*****************************************************************/ + +float xmin = -0.035, xmax = 0.035; +float ymin = -0.035, ymax = 0.035; +float nnear = 0.1; +float ffar = 1.9; +float distance = -1.0; + +static void +loadTextureProjection(int texUnit, GLfloat m[16]) +{ +  GLfloat mInverse[4][4]; + +  /* Should use true inverse, but since m consists only of rotations, we can +     just use the transpose. */ +  matrixTranspose((GLfloat *) mInverse, m); + +  ActiveTexture(GL_TEXTURE0_ARB + texUnit); +  glMatrixMode(GL_TEXTURE); +  glLoadIdentity(); +  glTranslatef(0.5, 0.5, 0.0); +  glScalef(0.5, 0.5, 1.0); +  glFrustum(xmin, xmax, ymin, ymax, nnear, ffar); +  glTranslatef(0.0, 0.0, distance); +  glMultMatrixf((GLfloat *) mInverse); +  glMatrixMode(GL_MODELVIEW); +} + +static void +drawTextureProjection(void) +{ +  float t = ffar / nnear; +  GLfloat n[4][3]; +  GLfloat f[4][3]; + +  n[0][0] = xmin; +  n[0][1] = ymin; +  n[0][2] = -(nnear + distance); + +  n[1][0] = xmax; +  n[1][1] = ymin; +  n[1][2] = -(nnear + distance); + +  n[2][0] = xmax; +  n[2][1] = ymax; +  n[2][2] = -(nnear + distance); + +  n[3][0] = xmin; +  n[3][1] = ymax; +  n[3][2] = -(nnear + distance); + +  f[0][0] = xmin * t; +  f[0][1] = ymin * t; +  f[0][2] = -(ffar + distance); + +  f[1][0] = xmax * t; +  f[1][1] = ymin * t; +  f[1][2] = -(ffar + distance); + +  f[2][0] = xmax * t; +  f[2][1] = ymax * t; +  f[2][2] = -(ffar + distance); + +  f[3][0] = xmin * t; +  f[3][1] = ymax * t; +  f[3][2] = -(ffar + distance); + +  glColor3f(1.0, 1.0, 0.0); +  glBegin(GL_LINE_LOOP); +  glVertex3fv(n[0]); +  glVertex3fv(n[1]); +  glVertex3fv(n[2]); +  glVertex3fv(n[3]); +  glVertex3fv(f[3]); +  glVertex3fv(f[2]); +  glVertex3fv(f[1]); +  glVertex3fv(f[0]); +  glVertex3fv(n[0]); +  glVertex3fv(n[1]); +  glVertex3fv(f[1]); +  glVertex3fv(f[0]); +  glVertex3fv(f[3]); +  glVertex3fv(f[2]); +  glVertex3fv(n[2]); +  glVertex3fv(n[3]); +  glEnd(); +} + +/*****************************************************************/ + +static void +initialize(void) +{ +  GLfloat light0Pos[4] = +  {0.3, 0.3, 0.0, 1.0}; +  GLfloat matAmb[4] = +  {0.01, 0.01, 0.01, 1.00}; +  GLfloat matDiff[4] = +  {0.65, 0.65, 0.65, 1.00}; +  GLfloat matSpec[4] = +  {0.30, 0.30, 0.30, 1.00}; +  GLfloat matShine = 10.0; +  GLfloat eyePlaneS[] = +  {1.0, 0.0, 0.0, 0.0}; +  GLfloat eyePlaneT[] = +  {0.0, 1.0, 0.0, 0.0}; +  GLfloat eyePlaneR[] = +  {0.0, 0.0, 1.0, 0.0}; +  GLfloat eyePlaneQ[] = +  {0.0, 0.0, 0.0, 1.0}; +  int i; + +  /* Setup Misc.  */ +  glClearColor(0.41, 0.41, 0.31, 0.0); + +  glEnable(GL_DEPTH_TEST); + +  /*  glLineWidth(2.0);*/ + +  glCullFace(GL_FRONT); +  glEnable(GL_CULL_FACE); + +  glMatrixMode(GL_PROJECTION); +  glFrustum(-0.5, 0.5, -0.5, 0.5, 1, 3); +  glMatrixMode(GL_MODELVIEW); +  glTranslatef(0, 0, -2); + +  matrixIdentity((GLfloat *) objectXform); +  for (i = 0; i < NumTextures; i++) { +     matrixIdentity((GLfloat *) textureXform[i]); +  } + +  glMatrixMode(GL_PROJECTION); +  glPushMatrix(); +  glLoadIdentity(); +  glOrtho(0, 1, 0, 1, -1, 1); +  glMatrixMode(GL_MODELVIEW); +  glPushMatrix(); +  glLoadIdentity(); + +  glRasterPos2i(0, 0); + +  glPopMatrix(); +  glMatrixMode(GL_PROJECTION); +  glPopMatrix(); +  glMatrixMode(GL_MODELVIEW); + +  /* Setup Lighting */ +  glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, matAmb); +  glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, matDiff); +  glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, matSpec); +  glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, matShine); + +  glEnable(GL_COLOR_MATERIAL); + +  glLightfv(GL_LIGHT0, GL_POSITION, light0Pos); +  glEnable(GL_LIGHT0); + +  glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, GL_TRUE); +  glEnable(GL_LIGHTING); + +  /* Setup Texture */ + +  (*loadTexture) (); + + +  for (i = 0; i < NumTextures; i++) { +     ActiveTexture(GL_TEXTURE0_ARB + i); + +     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP); +     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP); +     glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); + +     glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR); +     glTexGenfv(GL_S, GL_EYE_PLANE, eyePlaneS); + +     glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR); +     glTexGenfv(GL_T, GL_EYE_PLANE, eyePlaneT); + +     glTexGeni(GL_R, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR); +     glTexGenfv(GL_R, GL_EYE_PLANE, eyePlaneR); + +     glTexGeni(GL_Q, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR); +     glTexGenfv(GL_Q, GL_EYE_PLANE, eyePlaneQ); +  } +} + +static void +display(void) +{ +  int i; + +  glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + +  if (textureEnabled) { +    if (mode == MoveTexture || mode == MoveView) { +      /* Have OpenGL compute the new transformation (simple but slow). */ +      for (i = 0; i < NumTextures; i++) { +        glPushMatrix(); +        glLoadIdentity(); +#if 0 +        if (i & 1) +           glRotatef(angle, axis[0], axis[1], axis[2]); +        else +#endif +           glRotatef(angle*(i+1), axis[0], axis[1], axis[2]); + +        glMultMatrixf((GLfloat *) textureXform[i]); +        glGetFloatv(GL_MODELVIEW_MATRIX, (GLfloat *) textureXform[i]); +        glPopMatrix(); +      } +    } +    for (i = 0; i < NumTextures; i++) { +       loadTextureProjection(i, (GLfloat *) textureXform[i]); +    } + +    if (showProjection) { +      for (i = 0; i < NumTextures; i++) { +        ActiveTexture(GL_TEXTURE0_ARB + i); +        glPushMatrix(); +        glMultMatrixf((GLfloat *) textureXform[i]); +        glDisable(GL_LIGHTING); +        drawTextureProjection(); +        glEnable(GL_LIGHTING); +        glPopMatrix(); +      } +    } +    for (i = 0; i < NumTextures; i++) { +      ActiveTexture(GL_TEXTURE0_ARB + i); +      glEnable(GL_TEXTURE_2D); +      glEnable(GL_TEXTURE_GEN_S); +      glEnable(GL_TEXTURE_GEN_T); +      glEnable(GL_TEXTURE_GEN_R); +      glEnable(GL_TEXTURE_GEN_Q); +    } +  } +  if (mode == MoveObject || mode == MoveView) { +    /* Have OpenGL compute the new transformation (simple but slow). */ +    glPushMatrix(); +    glLoadIdentity(); +    glRotatef(angle, axis[0], axis[1], axis[2]); +    glMultMatrixf((GLfloat *) objectXform); +    glGetFloatv(GL_MODELVIEW_MATRIX, (GLfloat *) objectXform); +    glPopMatrix(); +  } +  glPushMatrix(); +  glMultMatrixf((GLfloat *) objectXform); +  (*drawObject) (); +  glPopMatrix(); + +  for (i = 0; i < NumTextures; i++) { +    ActiveTexture(GL_TEXTURE0_ARB + i); +    glDisable(GL_TEXTURE_2D); +    glDisable(GL_TEXTURE_GEN_S); +    glDisable(GL_TEXTURE_GEN_T); +    glDisable(GL_TEXTURE_GEN_R); +    glDisable(GL_TEXTURE_GEN_Q); +  } + +  if (zoomFactor > 1.0) { +    glDisable(GL_DEPTH_TEST); +    glCopyPixels(0, 0, winWidth / zoomFactor, winHeight / zoomFactor, GL_COLOR); +    glEnable(GL_DEPTH_TEST); +  } +  glFlush(); +  glutSwapBuffers(); +  checkErrors(); +} + +/*****************************************************************/ + +/* simple trackball-like motion control */ +static float lastPos[3]; +static int lastTime; + +static void +ptov(int x, int y, int width, int height, float v[3]) +{ +  float d, a; + +  /* project x,y onto a hemi-sphere centered within width, height */ +  v[0] = (2.0 * x - width) / width; +  v[1] = (height - 2.0 * y) / height; +  d = sqrt(v[0] * v[0] + v[1] * v[1]); +  v[2] = cos((M_PI / 2.0) * ((d < 1.0) ? d : 1.0)); +  a = 1.0 / sqrt(v[0] * v[0] + v[1] * v[1] + v[2] * v[2]); +  v[0] *= a; +  v[1] *= a; +  v[2] *= a; +} + +static void +startMotion(int x, int y, int but, int time) +{ +  if (but == GLUT_LEFT_BUTTON) { +    mode = MoveView; +  } else if (but == GLUT_MIDDLE_BUTTON) { +    mode = MoveTexture; +  } else { +    return; +  } + +  lastTime = time; +  ptov(x, y, winWidth, winHeight, lastPos); +} + +static void +animate(void) +{ +  glutPostRedisplay(); +} + +static void +vis(int visible) +{ +  if (visible == GLUT_VISIBLE) { +    if (redrawContinuously) +      glutIdleFunc(animate); +  } else { +    if (redrawContinuously) +      glutIdleFunc(NULL); +  } +} + +static void +stopMotion(int but, int time) +{ +  if ((but == GLUT_LEFT_BUTTON && mode == MoveView) || +    (but == GLUT_MIDDLE_BUTTON && mode == MoveTexture)) { +  } else { +    return; +  } + +  if (time == lastTime) { +     /*    redrawContinuously = GL_TRUE;*/ +    glutIdleFunc(animate); +  } else { +    angle = 0.0; +    redrawContinuously = GL_FALSE; +    glutIdleFunc(0); +  } +  if (!redrawContinuously) { +    mode = MoveNone; +  } +} + +static void +trackMotion(int x, int y) +{ +  float curPos[3], dx, dy, dz; + +  ptov(x, y, winWidth, winHeight, curPos); + +  dx = curPos[0] - lastPos[0]; +  dy = curPos[1] - lastPos[1]; +  dz = curPos[2] - lastPos[2]; +  angle = 90.0 * sqrt(dx * dx + dy * dy + dz * dz); + +  axis[0] = lastPos[1] * curPos[2] - lastPos[2] * curPos[1]; +  axis[1] = lastPos[2] * curPos[0] - lastPos[0] * curPos[2]; +  axis[2] = lastPos[0] * curPos[1] - lastPos[1] * curPos[0]; + +  lastTime = glutGet(GLUT_ELAPSED_TIME); +  lastPos[0] = curPos[0]; +  lastPos[1] = curPos[1]; +  lastPos[2] = curPos[2]; +  glutPostRedisplay(); +} + +/*****************************************************************/ + +static void +object(void) +{ +  static int object; + +  object++; +  object %= 3; +  switch (object) { +  case 0: +    drawObject = drawCube; +    break; +  case 1: +    drawObject = drawDodecahedron; +    break; +  case 2: +    drawObject = drawSphere; +    break; +  default: +    break; +  } +} + +static void +nop(void) +{ +} + +static void +texture(void) +{ +  static int texture = 0; + +  texture++; +  texture %= 3; +  if (texture == 1 && texFilename == NULL) { +    /* Skip file texture if not loaded. */ +    texture++; +  } +  switch (texture) { +  case 0: +    loadTexture = nop; +    textureEnabled = GL_FALSE; +    break; +  case 1: +    loadTexture = loadImageTextures; +    (*loadTexture) (); +    textureEnabled = GL_TRUE; +    break; +  case 2: +    loadTexture = loadSpotlightTexture; +    (*loadTexture) (); +    textureEnabled = GL_TRUE; +    break; +  default: +    break; +  } +} + +static void +help(void) +{ +  printf("'h'   - help\n"); +  printf("'l'   - toggle linear/nearest filter\n"); +  printf("'s'   - toggle projection frustum\n"); +  printf("'t'   - toggle projected texture\n"); +  printf("'o'   - toggle object\n"); +  printf("'z'   - increase zoom factor\n"); +  printf("'Z'   - decrease zoom factor\n"); +  printf("left mouse     - move view\n"); +  printf("middle mouse   - move projection\n"); +} + +/* ARGSUSED1 */ +static void +key(unsigned char key, int x, int y) +{ +  switch (key) { +  case '\033': +    exit(0); +    break; +  case 'l': +    linearFilter = !linearFilter; +    (*loadTexture) (); +    break; +  case 's': +    showProjection = !showProjection; +    break; +  case 't': +    texture(); +    break; +  case 'o': +    object(); +    break; +  case 'z': +    zoomFactor += 1.0; +    glPixelZoom(zoomFactor, zoomFactor); +    glViewport(0, 0, winWidth / zoomFactor, winHeight / zoomFactor); +    break; +  case 'Z': +    zoomFactor -= 1.0; +    if (zoomFactor < 1.0) +      zoomFactor = 1.0; +    glPixelZoom(zoomFactor, zoomFactor); +    glViewport(0, 0, winWidth / zoomFactor, winHeight / zoomFactor); +    break; +  case 'h': +    help(); +    break; +  } +  glutPostRedisplay(); +} + +static void +mouse(int button, int state, int x, int y) +{ +  if (state == GLUT_DOWN) +    startMotion(x, y, button, glutGet(GLUT_ELAPSED_TIME)); +  else if (state == GLUT_UP) +    stopMotion(button, glutGet(GLUT_ELAPSED_TIME)); +  glutPostRedisplay(); +} + +static void +reshape(int w, int h) +{ +  winWidth = w; +  winHeight = h; +  glViewport(0, 0, w / zoomFactor, h / zoomFactor); +} + + +static void +menu(int selection) +{ +  if (selection == 666) { +    exit(0); +  } +  key((unsigned char) selection, 0, 0); +} + +int +main(int argc, char **argv) +{ +  glutInit(&argc, argv); + +  if (argc > 1) { +     NumTextures = atoi(argv[1]); +  } +  assert(NumTextures <= MAX_TEX); + +  glutInitDisplayMode(GLUT_RGBA | GLUT_DEPTH | GLUT_DOUBLE); +  glutInitWindowSize(500,500); +  (void) glutCreateWindow("projtex"); +  glewInit(); + +  loadTexture = loadImageTextures; +  drawObject = drawCube; +  initialize(); +  glutDisplayFunc(display); +  glutKeyboardFunc(key); +  glutReshapeFunc(reshape); +  glutMouseFunc(mouse); +  glutMotionFunc(trackMotion); +  glutVisibilityFunc(vis); +  glutCreateMenu(menu); +  glutAddMenuEntry("Toggle showing projection", 's'); +  glutAddMenuEntry("Switch texture", 't'); +  glutAddMenuEntry("Switch object", 'o'); +  glutAddMenuEntry("Toggle filtering", 'l'); +  glutAddMenuEntry("Quit", 666); +  glutAttachMenu(GLUT_RIGHT_BUTTON); +  texture(); +  glutMainLoop(); +  return 0;             /* ANSI C requires main to return int. */ +} diff --git a/progs/demos/streaming_rect.c b/progs/demos/streaming_rect.c deleted file mode 100644 index f65ac4ce36..0000000000 --- a/progs/demos/streaming_rect.c +++ /dev/null @@ -1,327 +0,0 @@ -/* - * GL_ARB_pixel_buffer_object test - * - * Command line options: - *    -w WIDTH -h HEIGHT   sets window size - * - */ - -#include <math.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <GL/glew.h> -#include <GL/glut.h> - -#include "readtex.h" - - -#define ANIMATE 10 -#define PBO 11 -#define QUIT 100 - -static GLuint DrawPBO; - -static GLboolean Animate = GL_TRUE; -static GLboolean use_pbo = 1; -static GLboolean whole_rect = 1; - -static GLfloat Drift = 0.0; -static GLfloat drift_increment = 1/255.0; -static GLfloat Xrot = 20.0, Yrot = 30.0; - -static GLuint Width = 1024; -static GLuint Height = 512; - - -static void Idle( void ) -{ -   if (Animate) { - -      Drift += drift_increment; -      if (Drift >= 1.0) -         Drift = 0.0; - -      glutPostRedisplay(); -   } -} - -/*static int max( int a, int b ) { return a > b ? a : b; }*/ - -#ifndef min -static int min( int a, int b ) { return a < b ? a : b; } -#endif - -static void DrawObject() -{ -   GLint size = Width * Height * 4; -    -   if (use_pbo) { -      /* XXX: This is extremely important - semantically makes the buffer -       * contents undefined, but in practice means that the driver can -       * release the old copy of the texture and allocate a new one -       * without waiting for outstanding rendering to complete. -       */ -      glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_EXT, DrawPBO); -      glBufferDataARB(GL_PIXEL_UNPACK_BUFFER_EXT, size, NULL, GL_STREAM_DRAW_ARB); - -      { -	 char *image = glMapBufferARB(GL_PIXEL_UNPACK_BUFFER_EXT, GL_WRITE_ONLY_ARB); -       -	 printf("char %d\n", (unsigned char)(Drift * 255)); - -	 memset(image, (unsigned char)(Drift * 255), size); -       -	 glUnmapBufferARB(GL_PIXEL_UNPACK_BUFFER_EXT); -      } -    - -      /* BGRA is required for most hardware paths: -       */ -      glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGBA, Width, Height, 0, -		   GL_BGRA, GL_UNSIGNED_BYTE, NULL); -   } -   else { -      static char *image = NULL; - -      if (image == NULL)  -	 image = malloc(size); - -      glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_EXT, 0); - -      memset(image, (unsigned char)(Drift * 255), size); - -      /* BGRA should be the fast path for regular uploads as well. -       */ -      glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGBA, Width, Height, 0, -		   GL_BGRA, GL_UNSIGNED_BYTE, image); -   } - -   { -      int x,y,w,h; - -      if (whole_rect) { -	 x = y = 0; -	 w = Width; -	 h = Height; -      } -      else { -	 x = y = 0; -	 w = min(10, Width); -	 h = min(10, Height); -      } - -      glBegin(GL_QUADS); - -      glTexCoord2f( x, y); -      glVertex2f( x, y ); - -      glTexCoord2f( x, y + h); -      glVertex2f( x, y + h); - -      glTexCoord2f( x + w + .5, y + h); -      glVertex2f( x + w, y + h ); - -      glTexCoord2f( x + w, y + .5); -      glVertex2f( x + w, y ); - -      glEnd(); -   } -} - - - -static void Display( void ) -{ -   static GLint T0 = 0; -   static GLint Frames = 0; -   GLint t; - -   glClear( GL_COLOR_BUFFER_BIT ); - -   glPushMatrix(); -      DrawObject(); -   glPopMatrix(); - -   glutSwapBuffers(); - -   Frames++; - -   t = glutGet(GLUT_ELAPSED_TIME); -   if (t - T0 >= 1000) { -      GLfloat seconds = (t - T0) / 1000.0; - -      GLfloat fps = Frames / seconds; -      printf("%d frames in %6.3f seconds = %6.3f FPS\n", Frames, seconds, fps); -      fflush(stdout); - -      drift_increment = 2.2 * seconds / Frames; -      T0 = t; -      Frames = 0; -   } -} - - -static void Reshape( int width, int height ) -{ -   glViewport( 0, 0, width, height ); -   glMatrixMode( GL_PROJECTION ); -   glLoadIdentity(); -/*    glFrustum( -1.0, 1.0, -1.0, 1.0, 10.0, 100.0 ); */ -   gluOrtho2D( 0, width, height, 0 ); -   glMatrixMode( GL_MODELVIEW ); -   glLoadIdentity(); -   glTranslatef(0.375, 0.375, 0); -} - - -static void ModeMenu(int entry) -{ -   if (entry==ANIMATE) { -      Animate = !Animate; -   } -   else if (entry==PBO) { -      use_pbo = !use_pbo; -   } -   else if (entry==QUIT) { -      exit(0); -   } - -   glutPostRedisplay(); -} - - -static void Key( unsigned char key, int x, int y ) -{ -   (void) x; -   (void) y; -   switch (key) { -      case 27: -         exit(0); -         break; -   } -   glutPostRedisplay(); -} - - -static void SpecialKey( int key, int x, int y ) -{ -   float step = 3.0; -   (void) x; -   (void) y; - -   switch (key) { -      case GLUT_KEY_UP: -         Xrot += step; -         break; -      case GLUT_KEY_DOWN: -         Xrot -= step; -         break; -      case GLUT_KEY_LEFT: -         Yrot += step; -         break; -      case GLUT_KEY_RIGHT: -         Yrot -= step; -         break; -   } -   glutPostRedisplay(); -} - - -static void Init( int argc, char *argv[] ) -{ -   const char *exten = (const char *) glGetString(GL_EXTENSIONS); -   GLuint texObj; -   GLint size; - - -   if (!strstr(exten, "GL_ARB_pixel_buffer_object")) { -      printf("Sorry, GL_ARB_pixel_buffer_object not supported by this renderer.\n"); -      exit(1); -   } - -   glGetIntegerv(GL_MAX_TEXTURE_SIZE, &size); -   printf("%d x %d max texture size\n", size, size); - -   glPixelStorei(GL_UNPACK_ALIGNMENT, 1); - -   /* allocate two texture objects */ -   glGenTextures(1, &texObj); - -   /* setup the texture objects */ -   glActiveTextureARB(GL_TEXTURE0_ARB); -   glBindTexture(GL_TEXTURE_RECTANGLE_ARB, texObj); - -   glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER, GL_NEAREST); -   glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - -   glGenBuffersARB(1, &DrawPBO); - -   glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_EXT, DrawPBO); -   glBufferDataARB(GL_PIXEL_UNPACK_BUFFER_EXT, -		   Width * Height * 4, NULL, GL_STREAM_DRAW); - -   glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); - -   glEnable(GL_TEXTURE_RECTANGLE_ARB); - -   glShadeModel(GL_SMOOTH); -   glClearColor(0.3, 0.3, 0.4, 1.0); - -   if (argc > 1 && strcmp(argv[1], "-info")==0) { -      printf("GL_RENDERER   = %s\n", (char *) glGetString(GL_RENDERER)); -      printf("GL_VERSION    = %s\n", (char *) glGetString(GL_VERSION)); -      printf("GL_VENDOR     = %s\n", (char *) glGetString(GL_VENDOR)); -      printf("GL_EXTENSIONS = %s\n", (char *) glGetString(GL_EXTENSIONS)); -   } -} - - -int main( int argc, char *argv[] ) -{ -   GLint i; - -   glutInit( &argc, argv ); - -   for (i = 1; i < argc; i++) { -      if (strcmp(argv[i], "-w") == 0) { -         Width = atoi(argv[i+1]); -         if (Width <= 0) { -            printf("Error, bad width\n"); -            exit(1); -         } -         i++; -      } -      else if (strcmp(argv[i], "-h") == 0) { -         Height = atoi(argv[i+1]); -         if (Height <= 0) { -            printf("Error, bad height\n"); -            exit(1); -         } -         i++; -      } -   } - -   glutInitWindowSize( Width, Height ); -   glutInitWindowPosition( 0, 0 ); -   glutInitDisplayMode( GLUT_RGB | GLUT_DOUBLE ); -   glutCreateWindow(argv[0] ); -   glewInit(); - -   Init( argc, argv ); - -   glutReshapeFunc( Reshape ); -   glutKeyboardFunc( Key ); -   glutSpecialFunc( SpecialKey ); -   glutDisplayFunc( Display ); -   glutIdleFunc( Idle ); - -   glutCreateMenu(ModeMenu); -   glutAddMenuEntry("Toggle Animation", ANIMATE); -   glutAddMenuEntry("Toggle PBO", PBO); -   glutAddMenuEntry("Quit", QUIT); -   glutAttachMenu(GLUT_RIGHT_BUTTON); - -   glutMainLoop(); -   return 0; -} diff --git a/progs/demos/texdown.c b/progs/demos/texdown.c deleted file mode 100644 index 7e46045832..0000000000 --- a/progs/demos/texdown.c +++ /dev/null @@ -1,477 +0,0 @@ - -/* - * Copyright (C) 1999  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. - */ - - -/* - * texdown - * - * Measure texture download speed. - * Use keyboard to change texture size, format, datatype, scale/bias, - * subimageload, etc. - * - * Brian Paul  28 January 2000 - */ - - -#include <stdio.h> -#include <stdlib.h> -#include <math.h> -#include <GL/glut.h> - - -static GLsizei MaxSize = 2048; -static GLsizei TexWidth = 1024, TexHeight = 1024, TexBorder = 0; -static GLboolean ScaleAndBias = GL_FALSE; -static GLboolean SubImage = GL_FALSE; -static GLdouble DownloadRate = 0.0;  /* texels/sec */ - -static GLuint Mode = 0; - - -/* Try and avoid L2 cache effects by cycling through a small number of - * textures. - *  - * At the initial size of 1024x1024x4 == 4mbyte, say 8 textures will - * keep us out of most caches at 32mb total. - * - * This turns into a fairly interesting question of what exactly you - * expect to be in cache in normal usage, and what you think should be - * outside.  There's no rules for this, no reason to favour one usage - * over another except what the application you care about happens to - * resemble most closely. - * - * - Should the client texture image be in L2 cache?  Has it just been - *   generated or read from disk? - * - Does the application really use >1 texture, or is it constantly  - *   updating one image in-place? - * - * Different answers will favour different texture upload mechanisms. - * To upload an image that is purely outside of cache, a DMA-based - * upload will probably win, whereas for small, in-cache textures, - * copying looks good. - */ -#define NR_TEXOBJ 4 -static GLuint TexObj[NR_TEXOBJ]; - - -struct FormatRec { -   GLenum Format; -   GLenum Type; -   GLenum IntFormat; -   GLint TexelSize; -}; - - -static const struct FormatRec FormatTable[] = { -  /* Format   Type                         IntFormat   TexelSize */ -   { GL_BGRA, GL_UNSIGNED_BYTE,            GL_RGBA,        4    }, -   { GL_RGB,  GL_UNSIGNED_BYTE,            GL_RGB,         3    }, -   { GL_RGBA, GL_UNSIGNED_BYTE,            GL_RGBA,        4    }, -   { GL_RGBA, GL_UNSIGNED_BYTE,            GL_RGB,         4    }, -   { GL_RGB,  GL_UNSIGNED_SHORT_5_6_5,     GL_RGB,         2    }, -   { GL_LUMINANCE, GL_UNSIGNED_BYTE,       GL_LUMINANCE,   1    }, -   { GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, GL_LUMINANCE_ALPHA,   2    }, -   { GL_ALPHA, GL_UNSIGNED_BYTE,           GL_ALPHA,       1    }, -}; -static GLint Format; - -#define NUM_FORMATS (sizeof(FormatTable)/sizeof(FormatTable[0])) - -static int -BytesPerTexel(GLint format) -{ -   return FormatTable[format].TexelSize; -} - - -static const char * -FormatStr(GLenum format) -{ -   switch (format) { -      case GL_RGB: -         return "GL_RGB"; -      case GL_RGBA: -         return "GL_RGBA"; -      case GL_BGRA: -         return "GL_BGRA"; -      case GL_LUMINANCE: -         return "GL_LUMINANCE"; -      case GL_LUMINANCE_ALPHA: -         return "GL_LUMINANCE_ALPHA"; -      case GL_ALPHA: -         return "GL_ALPHA"; -      default: -         return ""; -   } -} - - -static const char * -TypeStr(GLenum type) -{ -   switch (type) { -      case GL_UNSIGNED_BYTE: -         return "GL_UNSIGNED_BYTE"; -      case GL_UNSIGNED_SHORT: -         return "GL_UNSIGNED_SHORT"; -      case GL_UNSIGNED_SHORT_5_6_5: -         return "GL_UNSIGNED_SHORT_5_6_5"; -      case GL_UNSIGNED_SHORT_5_6_5_REV: -         return "GL_UNSIGNED_SHORT_5_6_5_REV"; -      default: -         return ""; -   } -} - -/* On x86, there is a performance cliff for memcpy to texture memory - * for sources below 64 byte alignment.  We do our best with this in - * the driver, but it is better if the images are correctly aligned to - * start with: - */ -#define ALIGN (1<<12) - -static unsigned long align(unsigned long value, unsigned long a) -{ -   return (value + a - 1) & ~(a-1); -} - -static void -MeasureDownloadRate(void) -{ -   const int w = TexWidth + 2 * TexBorder; -   const int h = TexHeight + 2 * TexBorder; -   const int image_bytes = align(w * h * BytesPerTexel(Format), ALIGN); -   const int bytes = image_bytes * NR_TEXOBJ; -   GLubyte *orig_texImage, *orig_getImage; -   GLubyte *texImage, *getImage; -   GLdouble t0, t1, time; -   int count; -   int i; -   int offset = 0; -   GLdouble total = 0;		/* ints will tend to overflow */ - -   printf("allocating %d bytes for %d %dx%d images\n", -	  bytes, NR_TEXOBJ, w, h); - -   orig_texImage = (GLubyte *) malloc(bytes + ALIGN); -   orig_getImage = (GLubyte *) malloc(image_bytes + ALIGN); -   if (!orig_texImage || !orig_getImage) { -      DownloadRate = 0.0; -      return; -   } - -   printf("alloc %p %p\n", orig_texImage, orig_getImage); - -   texImage = (GLubyte *)align((unsigned long)orig_texImage, ALIGN); -   getImage = (GLubyte *)align((unsigned long)orig_getImage, ALIGN);    - -   for (i = 1; !(((unsigned long)texImage) & i); i<<=1) -      ; -   printf("texture image alignment: %d bytes (%p)\n", i, texImage); -       -   for (i = 0; i < bytes; i++) { -      texImage[i] = i & 0xff; -   } - -   glPixelStorei(GL_UNPACK_ALIGNMENT, 1); -   glPixelStorei(GL_PACK_ALIGNMENT, 1); - -   if (ScaleAndBias) { -      glPixelTransferf(GL_RED_SCALE, 0.5); -      glPixelTransferf(GL_GREEN_SCALE, 0.5); -      glPixelTransferf(GL_BLUE_SCALE, 0.5); -      glPixelTransferf(GL_RED_BIAS, 0.5); -      glPixelTransferf(GL_GREEN_BIAS, 0.5); -      glPixelTransferf(GL_BLUE_BIAS, 0.5); -   } -   else { -      glPixelTransferf(GL_RED_SCALE, 1.0); -      glPixelTransferf(GL_GREEN_SCALE, 1.0); -      glPixelTransferf(GL_BLUE_SCALE, 1.0); -      glPixelTransferf(GL_RED_BIAS, 0.0); -      glPixelTransferf(GL_GREEN_BIAS, 0.0); -      glPixelTransferf(GL_BLUE_BIAS, 0.0); -   } - -   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); -   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); -   glEnable(GL_TEXTURE_2D); - -   count = 0; -   t0 = glutGet(GLUT_ELAPSED_TIME) * 0.001; -   do { -      int img = count%NR_TEXOBJ; -      GLubyte *img_ptr = texImage + img * image_bytes; - -      glBindTexture(GL_TEXTURE_2D, TexObj[img]); - -      if (SubImage && count > 0) { -	 /* Only update a portion of the image each iteration.  This -	  * is presumably why you'd want to use texsubimage, otherwise -	  * you may as well just call teximage again. -	  * -	  * A bigger question is whether to use a pointer that moves -	  * with each call, ie does the incoming data come from L2 -	  * cache under normal circumstances, or is it pulled from -	  * uncached memory?   -	  *  -	  * There's a good argument to say L2 cache, ie you'd expect -	  * the data to have been recently generated.  It's possible -	  * that it could have come from a file read, which may or may -	  * not have gone through the cpu. -	  */ -         glTexSubImage2D(GL_TEXTURE_2D, 0,  -			 -TexBorder,  -			 -TexBorder + offset * h/8,  -			 w,  -			 h/8, -                         FormatTable[Format].Format, -                         FormatTable[Format].Type,  -#if 1 -			 texImage /* likely in L2$ */ -#else -			 img_ptr + offset * bytes/8 /* unlikely in L2$ */ -#endif -	    ); -	 offset += 1; -	 offset %= 8; -	 total += w * h / 8; -      } -      else { -         glTexImage2D(GL_TEXTURE_2D, 0, -                      FormatTable[Format].IntFormat, w, h, TexBorder, -                      FormatTable[Format].Format, -                      FormatTable[Format].Type,  -		      img_ptr); -	 total += w*h; -      } - -      /* draw a tiny polygon to force texture into texram */ -      glBegin(GL_TRIANGLES); -      glTexCoord2f(0, 0);     glVertex2f(1, 1); -      glTexCoord2f(1, 0);     glVertex2f(3, 1); -      glTexCoord2f(0.5, 1);   glVertex2f(2, 3); -      glEnd(); - -      t1 = glutGet(GLUT_ELAPSED_TIME) * 0.001; -      time = t1 - t0; -      count++; -   } while (time < 3.0); - -   glDisable(GL_TEXTURE_2D); - -   printf("total texels=%f  time=%f\n", total, time); -   DownloadRate = total / time; - - -   free(orig_texImage);  -   free(orig_getImage);  - -   { -      GLint err = glGetError(); -      if (err) -         printf("GL error %d\n", err); -   } -} - - -static void -PrintString(const char *s) -{ -   while (*s) { -      glutBitmapCharacter(GLUT_BITMAP_8_BY_13, (int) *s); -      s++; -   } -} - - -static void -Display(void) -{ -   const int w = TexWidth + 2 * TexBorder; -   const int h = TexHeight + 2 * TexBorder; -   char s[1000]; - -   glClear(GL_COLOR_BUFFER_BIT); - -   glRasterPos2i(10, 80); -   sprintf(s, "Texture size[cursor]: %d x %d  Border[b]: %d", w, h, TexBorder); -   PrintString(s); - -   glRasterPos2i(10, 65); -   sprintf(s, "Format[f]: %s  Type: %s  IntFormat: %s", -           FormatStr(FormatTable[Format].Format), -           TypeStr(  FormatTable[Format].Type), -           FormatStr(FormatTable[Format].IntFormat)); -   PrintString(s); - -   glRasterPos2i(10, 50); -   sprintf(s, "Pixel Scale&Bias[p]: %s   TexSubImage[s]: %s", -           ScaleAndBias ? "Yes" : "No", -           SubImage ? "Yes" : "No"); -   PrintString(s); - -   if (Mode == 0) { -      glRasterPos2i(200, 10); -      sprintf(s, "...Measuring..."); -      PrintString(s); -      glutSwapBuffers(); -      glutPostRedisplay(); -      Mode++; -   } -   else if (Mode == 1) { -      MeasureDownloadRate(); -      glutPostRedisplay(); -      Mode++; -   } -   else { -      /* show results */ -      glRasterPos2i(10, 10); -      sprintf(s, "Download rate: %g Mtexels/second  %g MB/second", -              DownloadRate / 1000000.0, -              DownloadRate * BytesPerTexel(Format) / 1000000.0); -      PrintString(s); -      { -         GLint r, g, b, a, l, i; -         glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_RED_SIZE, &r); -         glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_GREEN_SIZE, &g); -         glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_BLUE_SIZE, &b); -         glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_ALPHA_SIZE, &a); -         glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_LUMINANCE_SIZE, &l); -         glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_INTENSITY_SIZE, &i); -         sprintf(s, "TexelBits: R=%d G=%d B=%d A=%d L=%d I=%d", r, g, b, a, l, i); -         glRasterPos2i(10, 25); -         PrintString(s); -      } - -      glutSwapBuffers(); -   } -} - - -static void -Reshape(int width, int height) -{ -   glViewport( 0, 0, width, height ); -   glMatrixMode( GL_PROJECTION ); -   glLoadIdentity(); -   glOrtho(0, width, 0, height, -1, 1); -   glMatrixMode( GL_MODELVIEW ); -   glLoadIdentity(); -} - - - -static void -Key(unsigned char key, int x, int y) -{ -   (void) x; -   (void) y; -   switch (key) { -      case ' ': -         Mode = 0; -         break; -      case 'b': -         /* toggle border */ -         TexBorder = 1 - TexBorder; -         Mode = 0; -         break; -      case 'f': -         /* change format */ -         Format = (Format + 1) % NUM_FORMATS; -         Mode = 0; -         break; -      case 'F': -         /* change format */ -         Format = (Format - 1) % NUM_FORMATS; -         Mode = 0; -         break; -      case 'p': -         /* toggle border */ -         ScaleAndBias = !ScaleAndBias; -         Mode = 0; -         break; -      case 's': -         SubImage = !SubImage; -         Mode = 0; -         break; -      case 27: -         exit(0); -         break; -   } -   glutPostRedisplay(); -} - - -static void -SpecialKey(int key, int x, int y) -{ -   (void) x; -   (void) y; -   switch (key) { -      case GLUT_KEY_UP: -         if (TexHeight < MaxSize) -            TexHeight *= 2; -         break; -      case GLUT_KEY_DOWN: -         if (TexHeight > 1) -            TexHeight /= 2; -         break; -      case GLUT_KEY_LEFT: -         if (TexWidth > 1) -            TexWidth /= 2; -         break; -      case GLUT_KEY_RIGHT: -         if (TexWidth < MaxSize) -            TexWidth *= 2; -         break; -   } -   Mode = 0; -   glutPostRedisplay(); -} - - -static void -Init(void) -{ -   printf("GL_VENDOR = %s\n", (const char *) glGetString(GL_VENDOR)); -   printf("GL_VERSION = %s\n", (const char *) glGetString(GL_VERSION)); -   printf("GL_RENDERER = %s\n", (const char *) glGetString(GL_RENDERER)); -} - - -int -main(int argc, char *argv[]) -{ -   glutInit( &argc, argv ); -   glutInitWindowPosition( 0, 0 ); -   glutInitWindowSize( 600, 100 ); -   glutInitDisplayMode( GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH ); -   glutCreateWindow(argv[0]); -   glutReshapeFunc( Reshape ); -   glutKeyboardFunc( Key ); -   glutSpecialFunc( SpecialKey ); -   glutDisplayFunc( Display ); -   Init(); -   glutMainLoop(); -   return 0; -} diff --git a/progs/demos/texobj.c b/progs/demos/texobj.c deleted file mode 100644 index 40bce6e569..0000000000 --- a/progs/demos/texobj.c +++ /dev/null @@ -1,284 +0,0 @@ - -/* - * Example of using the 1.1 texture object functions. - * Also, this demo utilizes Mesa's fast texture map path. - * - * Brian Paul   June 1996   This file is in the public domain. - */ - -#include <assert.h> -#include <math.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include "GL/glut.h" - -static GLuint Window = 0; - -static GLuint TexObj[2]; -static GLfloat Angle = 0.0f; -static GLboolean UseObj = GL_FALSE; - - -#if defined(GL_VERSION_1_1) || defined(GL_VERSION_1_2) -#  define TEXTURE_OBJECT 1 -#elif defined(GL_EXT_texture_object) -#  define TEXTURE_OBJECT 1 -#  define glBindTexture(A,B)     glBindTextureEXT(A,B) -#  define glGenTextures(A,B)     glGenTexturesEXT(A,B) -#  define glDeleteTextures(A,B)  glDeleteTexturesEXT(A,B) -#endif - - - - -static void draw( void ) -{ -   glClear( GL_COLOR_BUFFER_BIT ); - -   glColor3f( 1.0, 1.0, 1.0 ); - -   /* draw first polygon */ -   glPushMatrix(); -   glTranslatef( -1.0, 0.0, 0.0 ); -   glRotatef( Angle, 0.0, 0.0, 1.0 ); -   if (UseObj) { -#ifdef TEXTURE_OBJECT -      glBindTexture( GL_TEXTURE_2D, TexObj[0] ); -#endif -   } -   else { -      glCallList( TexObj[0] ); -   } -   glBegin( GL_POLYGON ); -   glTexCoord2f( 0.0, 0.0 );   glVertex2f( -1.0, -1.0 ); -   glTexCoord2f( 1.0, 0.0 );   glVertex2f(  1.0, -1.0 ); -   glTexCoord2f( 1.0, 1.0 );   glVertex2f(  1.0,  1.0 ); -   glTexCoord2f( 0.0, 1.0 );   glVertex2f( -1.0,  1.0 ); -   glEnd(); -   glPopMatrix(); - -   /* draw second polygon */ -   glPushMatrix(); -   glTranslatef( 1.0, 0.0, 0.0 ); -   glRotatef( Angle-90.0, 0.0, 1.0, 0.0 ); -   if (UseObj) { -#ifdef TEXTURE_OBJECT -      glBindTexture( GL_TEXTURE_2D, TexObj[1] ); -#endif -   } -   else { -      glCallList( TexObj[1] ); -   } -   glBegin( GL_POLYGON ); -   glTexCoord2f( 0.0, 0.0 );   glVertex2f( -1.0, -1.0 ); -   glTexCoord2f( 1.0, 0.0 );   glVertex2f(  1.0, -1.0 ); -   glTexCoord2f( 1.0, 1.0 );   glVertex2f(  1.0,  1.0 ); -   glTexCoord2f( 0.0, 1.0 );   glVertex2f( -1.0,  1.0 ); -   glEnd(); -   glPopMatrix(); - -   glutSwapBuffers(); -} - - - -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; -   Angle += 120.0*dt; -   glutPostRedisplay(); -} - - - -/* change view Angle, exit upon ESC */ -static void key(unsigned char k, int x, int y) -{ -   (void) x; -   (void) y; -   switch (k) { -      case 27: -#ifdef TEXTURE_OBJECT -         glDeleteTextures( 2, TexObj ); -#endif -         glutDestroyWindow(Window); -         exit(0); -   } -} - - - -/* new window size or exposure */ -static void reshape( int width, int height ) -{ -   glViewport(0, 0, (GLint)width, (GLint)height); -   glMatrixMode(GL_PROJECTION); -   glLoadIdentity(); -   /*   glOrtho( -3.0, 3.0, -3.0, 3.0, -10.0, 10.0 );*/ -   glFrustum( -2.0, 2.0, -2.0, 2.0, 6.0, 20.0 ); -   glMatrixMode(GL_MODELVIEW); -   glLoadIdentity(); -   glTranslatef( 0.0, 0.0, -8.0 ); -} - - -static void init( void ) -{ -   static int width=8, height=8; -   static GLubyte tex1[] = { -     0, 0, 0, 0, 0, 0, 0, 0, -     0, 0, 0, 0, 1, 0, 0, 0, -     0, 0, 0, 1, 1, 0, 0, 0, -     0, 0, 0, 0, 1, 0, 0, 0, -     0, 0, 0, 0, 1, 0, 0, 0, -     0, 0, 0, 0, 1, 0, 0, 0, -     0, 0, 0, 1, 1, 1, 0, 0, -     0, 0, 0, 0, 0, 0, 0, 0 }; - -   static GLubyte tex2[] = { -     0, 0, 0, 0, 0, 0, 0, 0, -     0, 0, 0, 2, 2, 0, 0, 0, -     0, 0, 2, 0, 0, 2, 0, 0, -     0, 0, 0, 0, 0, 2, 0, 0, -     0, 0, 0, 0, 2, 0, 0, 0, -     0, 0, 0, 2, 0, 0, 0, 0, -     0, 0, 2, 2, 2, 2, 0, 0, -     0, 0, 0, 0, 0, 0, 0, 0 }; - -   GLubyte tex[64][3]; -   GLint i, j; - - -   glDisable( GL_DITHER ); - -   /* Setup texturing */ -   glEnable( GL_TEXTURE_2D ); -   glTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL ); -   glHint( GL_PERSPECTIVE_CORRECTION_HINT, GL_FASTEST ); - - -   /* generate texture object IDs */ -   if (UseObj) { -#ifdef TEXTURE_OBJECT -      glGenTextures( 2, TexObj ); -#endif -   } -   else { -      TexObj[0] = glGenLists(2); -      TexObj[1] = TexObj[0]+1; -   } - -   /* setup first texture object */ -   if (UseObj) { -#ifdef TEXTURE_OBJECT -      glBindTexture( GL_TEXTURE_2D, TexObj[0] ); -      assert(glIsTexture(TexObj[0])); -#endif -   } -   else { -      glNewList( TexObj[0], GL_COMPILE ); -   } -   /* red on white */ -   for (i=0;i<height;i++) { -      for (j=0;j<width;j++) { -         int p = i*width+j; -         if (tex1[(height-i-1)*width+j]) { -            tex[p][0] = 255;   tex[p][1] = 0;     tex[p][2] = 0; -         } -         else { -            tex[p][0] = 255;   tex[p][1] = 255;   tex[p][2] = 255; -         } -      } -   } - -   glTexImage2D( GL_TEXTURE_2D, 0, 3, width, height, 0, -                 GL_RGB, GL_UNSIGNED_BYTE, tex ); -   glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST ); -   glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST ); -   glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT ); -   glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT ); -   if (!UseObj) { -      glEndList(); -   } -   /* end of texture object */ - -   /* setup second texture object */ -   if (UseObj) { -#ifdef TEXTURE_OBJECT -      glBindTexture( GL_TEXTURE_2D, TexObj[1] ); -      assert(glIsTexture(TexObj[1])); -#endif -      assert(!glIsTexture(TexObj[1] + 999)); -   } -   else { -      glNewList( TexObj[1], GL_COMPILE ); -   } -   /* green on blue */ -   for (i=0;i<height;i++) { -      for (j=0;j<width;j++) { -         int p = i*width+j; -         if (tex2[(height-i-1)*width+j]) { -            tex[p][0] = 0;     tex[p][1] = 255;   tex[p][2] = 0; -         } -         else { -            tex[p][0] = 0;     tex[p][1] = 0;     tex[p][2] = 255; -         } -      } -   } -   glTexImage2D( GL_TEXTURE_2D, 0, 3, width, height, 0, -                 GL_RGB, GL_UNSIGNED_BYTE, tex ); -   glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST ); -   glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST ); -   glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT ); -   glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT ); -   if (!UseObj) { -      glEndList(); -   } -   /* end texture object */ - -} - - - -int main( int argc, char *argv[] ) -{ -   glutInit(&argc, argv); -   glutInitWindowPosition(0, 0); -   glutInitWindowSize(300, 300); -   glutInitDisplayMode( GLUT_RGB | GLUT_DEPTH | GLUT_DOUBLE ); - -   Window = glutCreateWindow("Texture Objects"); -   if (!Window) { -      exit(1); -   } - -   /* check that renderer has the GL_EXT_texture_object extension -    * or supports OpenGL 1.1 -    */ -#ifdef TEXTURE_OBJECT -   { -      char *exten = (char *) glGetString( GL_EXTENSIONS ); -      char *version = (char *) glGetString( GL_VERSION ); -      if (   strstr( exten, "GL_EXT_texture_object" ) -          || strncmp( version, "1.1", 3 )==0 -          || strncmp( version, "1.2", 3 )==0 ) { -         UseObj = GL_TRUE; -      } -   } -#endif - -   init(); - -   glutReshapeFunc( reshape ); -   glutKeyboardFunc( key ); -   glutIdleFunc( idle ); -   glutDisplayFunc( draw ); -   glutMainLoop(); -   return 0; -}  | 
