summaryrefslogtreecommitdiffstats
path: root/progs/demos/spectex.c
diff options
context:
space:
mode:
Diffstat (limited to 'progs/demos/spectex.c')
-rw-r--r--progs/demos/spectex.c277
1 files changed, 277 insertions, 0 deletions
diff --git a/progs/demos/spectex.c b/progs/demos/spectex.c
new file mode 100644
index 00000000000..412f442e4ad
--- /dev/null
+++ b/progs/demos/spectex.c
@@ -0,0 +1,277 @@
+/* $Id: spectex.c,v 1.1 1999/08/19 00:55:40 jtg Exp $ */
+
+/*
+ * GLUT demonstration of texturing with specular highlights.
+ *
+ * When drawing a lit, textured surface one usually wants the specular
+ * highlight to override the texture colors. However, OpenGL applies
+ * texturing after lighting so the specular highlight is modulated by
+ * the texture.
+ *
+ * The solution here shown here is a two-pass algorithm:
+ * 1. Draw the textured surface without specular lighting.
+ * 2. Enable blending to add the next pass:
+ * 3. Redraw the surface with a matte white material and only the
+ * specular components of light sources enabled.
+ *
+ * Brian Paul February 1997
+ */
+
+
+/*
+ * $Log: spectex.c,v $
+ * Revision 1.1 1999/08/19 00:55:40 jtg
+ * Initial revision
+ *
+ * Revision 3.2 1999/03/28 18:22:05 brianp
+ * minor clean-up
+ *
+ * Revision 3.1 1998/02/14 18:47:48 brianp
+ * added OpenGL 1.2 separate specular interpolation support
+ *
+ * Revision 3.0 1998/02/14 18:42:29 brianp
+ * initial rev
+ *
+ */
+
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <math.h>
+#include <GL/glut.h>
+
+
+static GLUquadricObj *Quadric;
+static GLuint Sphere;
+static GLfloat LightPos[4] = {10.0, 10.0, 10.0, 1.0};
+static GLfloat Delta = 1.0;
+static GLint Mode = 0;
+
+/*static GLfloat Blue[4] = {0.0, 0.0, 1.0, 1.0};*/
+/*static GLfloat Gray[4] = {0.5, 0.5, 0.5, 1.0};*/
+static GLfloat Black[4] = {0.0, 0.0, 0.0, 1.0};
+static GLfloat White[4] = {1.0, 1.0, 1.0, 1.0};
+
+
+
+static void Idle( void )
+{
+ LightPos[0] += Delta;
+ if (LightPos[0]>15.0)
+ Delta = -1.0;
+ else if (LightPos[0]<-15.0)
+ Delta = 1.0;
+
+ glutPostRedisplay();
+}
+
+
+static void Display( void )
+{
+ glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
+
+ glLightfv(GL_LIGHT0, GL_POSITION, LightPos);
+
+ glPushMatrix();
+ glRotatef(90.0, 1.0, 0.0, 0.0);
+
+ if (Mode==0) {
+ /* Typical method: diffuse + specular + texture */
+ glEnable(GL_TEXTURE_2D);
+ glLightfv(GL_LIGHT0, GL_DIFFUSE, White); /* enable diffuse */
+ glLightfv(GL_LIGHT0, GL_SPECULAR, White); /* enable specular */
+#ifdef GL_VERSION_1_2
+ glLightModeli(GL_LIGHT_MODEL_COLOR_CONTROL, GL_SINGLE_COLOR);
+#endif
+ glCallList(Sphere);
+ }
+ else if (Mode==1) {
+ /* just specular highlight */
+ glDisable(GL_TEXTURE_2D);
+ glLightfv(GL_LIGHT0, GL_DIFFUSE, Black); /* disable diffuse */
+ glLightfv(GL_LIGHT0, GL_SPECULAR, White); /* enable specular */
+#ifdef GL_VERSION_1_2
+ glLightModeli(GL_LIGHT_MODEL_COLOR_CONTROL, GL_SINGLE_COLOR);
+#endif
+ glCallList(Sphere);
+ }
+ else if (Mode==2) {
+ /* diffuse textured */
+ glEnable(GL_TEXTURE_2D);
+ glLightfv(GL_LIGHT0, GL_DIFFUSE, White); /* enable diffuse */
+ glLightfv(GL_LIGHT0, GL_SPECULAR, Black); /* disable specular */
+#ifdef GL_VERSION_1_2
+ glLightModeli(GL_LIGHT_MODEL_COLOR_CONTROL, GL_SINGLE_COLOR);
+#endif
+ glCallList(Sphere);
+ }
+ else if (Mode==3) {
+ /* 2-pass: diffuse textured then add specular highlight*/
+ glEnable(GL_TEXTURE_2D);
+ glLightfv(GL_LIGHT0, GL_DIFFUSE, White); /* enable diffuse */
+ glLightfv(GL_LIGHT0, GL_SPECULAR, Black); /* disable specular */
+#ifdef GL_VERSION_1_2
+ glLightModeli(GL_LIGHT_MODEL_COLOR_CONTROL, GL_SINGLE_COLOR);
+#endif
+ glCallList(Sphere);
+ /* specular highlight */
+ glDepthFunc(GL_EQUAL); /* redraw same pixels */
+ glDisable(GL_TEXTURE_2D);
+ glEnable(GL_BLEND); /* add */
+ glLightfv(GL_LIGHT0, GL_DIFFUSE, Black); /* disable diffuse */
+ glLightfv(GL_LIGHT0, GL_SPECULAR, White); /* enable specular */
+ glCallList(Sphere);
+ glDepthFunc(GL_LESS);
+ glDisable(GL_BLEND);
+ }
+ else if (Mode==4) {
+ /* OpenGL 1.2's separate diffuse and specular color */
+ glEnable(GL_TEXTURE_2D);
+ glLightfv(GL_LIGHT0, GL_DIFFUSE, White); /* enable diffuse */
+ glLightfv(GL_LIGHT0, GL_SPECULAR, White); /* enable specular */
+#ifdef GL_VERSION_1_2
+ glLightModeli(GL_LIGHT_MODEL_COLOR_CONTROL, GL_SEPARATE_SPECULAR_COLOR);
+#endif
+ glCallList(Sphere);
+ }
+
+ glPopMatrix();
+
+ glutSwapBuffers();
+}
+
+
+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.0, 0.0, -12.0 );
+}
+
+
+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 )
+{
+ (void) x;
+ (void) y;
+ switch (key) {
+ case GLUT_KEY_UP:
+ break;
+ case GLUT_KEY_DOWN:
+ break;
+ }
+ glutPostRedisplay();
+}
+
+
+static void Init( void )
+{
+ int i, j;
+ GLubyte texImage[64][64][3];
+
+ glEnable(GL_LIGHTING);
+ glEnable(GL_LIGHT0);
+ glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, 0);
+ glLightModelfv(GL_LIGHT_MODEL_AMBIENT, Black);
+
+ glMaterialfv(GL_FRONT, GL_DIFFUSE, White);
+ glMaterialfv(GL_FRONT, GL_SPECULAR, White);
+ glMaterialf(GL_FRONT, GL_SHININESS, 20.0);
+
+ /* Actually, these are set again later */
+ glLightfv(GL_LIGHT0, GL_DIFFUSE, White);
+ glLightfv(GL_LIGHT0, GL_SPECULAR, White);
+
+ Quadric = gluNewQuadric();
+ gluQuadricTexture( Quadric, GL_TRUE );
+
+ Sphere= glGenLists(1);
+ glNewList( Sphere, GL_COMPILE );
+ gluSphere( Quadric, 1.0, 24, 24 );
+ glEndList();
+
+ glEnable(GL_DEPTH_TEST);
+ glEnable(GL_CULL_FACE);
+
+ for (i=0;i<64;i++) {
+ for (j=0;j<64;j++) {
+ int k = ((i>>3)&1) ^ ((j>>3)&1);
+ texImage[i][j][0] = 255*k;
+ texImage[i][j][1] = 255*(1-k);
+ texImage[i][j][2] = 0;
+ }
+ }
+
+ glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
+ glTexImage2D( GL_TEXTURE_2D,
+ 0,
+ 3,
+ 64, 64,
+ 0,
+ GL_RGB, GL_UNSIGNED_BYTE,
+ texImage );
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+ glEnable(GL_TEXTURE_2D);
+
+ glBlendFunc(GL_ONE, GL_ONE);
+}
+
+
+static void ModeMenu(int entry)
+{
+ if (entry==99)
+ exit(0);
+ Mode = entry;
+}
+
+
+int main( int argc, char *argv[] )
+{
+
+ glutInit( &argc, argv );
+ glutInitWindowPosition( 0, 0 );
+ glutInitWindowSize( 300, 300 );
+
+ glutInitDisplayMode( GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH );
+
+ glutCreateWindow( "spectex" );
+
+ Init();
+
+ glutReshapeFunc( Reshape );
+ glutKeyboardFunc( Key );
+ glutSpecialFunc( SpecialKey );
+ glutDisplayFunc( Display );
+ glutIdleFunc( Idle );
+
+ glutCreateMenu( ModeMenu );
+ glutAddMenuEntry("1-pass lighting + texturing", 0);
+ glutAddMenuEntry("specular lighting", 1);
+ glutAddMenuEntry("diffuse lighting + texturing", 2);
+ glutAddMenuEntry("2-pass lighting + texturing", 3);
+#ifdef GL_VERSION_1_2
+ glutAddMenuEntry("OpenGL 1.2 separate specular", 4);
+#endif
+ glutAddMenuEntry("Quit", 99);
+ glutAttachMenu(GLUT_RIGHT_BUTTON);
+
+ glutMainLoop();
+ return 0;
+}