home *** CD-ROM | disk | FTP | other *** search
/ SGI Developer Toolbox 6.1 / SGI Developer Toolbox 6.1 - Disc 1.iso / toolbox / src / tutorials / custEducation / opengl2 / examples / sgi_extensions / fog_offset.c < prev    next >
Encoding:
C/C++ Source or Header  |  1996-11-11  |  9.0 KB  |  421 lines

  1. /*
  2.  * Copyright 1996, Silicon Graphics, Inc.
  3.  * All Rights Reserved.
  4.  *
  5.  * This is UNPUBLISHED PROPRIETARY SOURCE CODE of Silicon Graphics, Inc.;
  6.  * the contents of this file may not be disclosed to third parties, copied or
  7.  * duplicated in any form, in whole or in part, without the prior written
  8.  * permission of Silicon Graphics, Inc.
  9.  *
  10.  * RESTRICTED RIGHTS LEGEND:
  11.  * Use, duplication or disclosure by the Government is subject to restrictions
  12.  * as set forth in subdivision (c)(1)(ii) of the Rights in Technical Data
  13.  * and Computer Software clause at DFARS 252.227-7013, and/or in similar or
  14.  * successor clauses in the FAR, DOD or NASA FAR Supplement. Unpublished -
  15.  * rights reserved under the Copyright Laws of the United States.
  16.  */
  17.  
  18. /* fog_offset.c
  19.  *    This program demonstrates using fog offset to make a fogged
  20.  *    object appear brighter. 
  21.  *
  22.  *    If the fog mode is GL_EXP or GL_EXP2, pressing the up and down 
  23.  *    arrow keys adjusts the density value.
  24.  *
  25.  *    If the fog mode is GL_LINEAR, pressing the up and down 
  26.  *    arrow keys adjusts the end value for linear fog. The start value 
  27.  *    for the linear fog is fixed.
  28.  *
  29.  *    Escape key    - exit the program
  30.  *    <o> key        - toggle fog offset
  31.  *    <f> key        - change the fog blend function
  32.  *    UP Arrow Key    - increase the fog density or end value
  33.  *    DOWN Arrow Key    - decrease the fog density or end value
  34.  */
  35. #include <GL/gl.h>
  36. #include <GL/glu.h>
  37. #include <GL/glut.h>
  38.  
  39. #include <math.h>
  40. #include <stdio.h>
  41. #include <stdlib.h>
  42.  
  43. /* Function Prototypes */
  44.  
  45. GLvoid  initgfx( GLvoid );
  46. GLvoid  drawScene( GLvoid );
  47. GLvoid  reshape( GLsizei, GLsizei );
  48. GLvoid  keyboard( GLubyte, GLint, GLint );
  49. GLvoid  specialkeys( GLint, GLint, GLint );
  50.  
  51. GLvoid cycleFog( GLvoid );
  52. GLvoid inc( GLvoid );
  53. GLvoid dec( GLvoid );
  54. GLvoid toggleFogOffsetEnable( GLvoid );
  55.  
  56. void printHelp( char * );
  57.  
  58. /* Global Definitions */
  59.  
  60. #define PROJ_LEFT       0.0
  61. #define PROJ_RIGHT      511.0
  62. #define PROJ_BOTTOM     0.0
  63. #define PROJ_TOP        511.0
  64.  
  65. #define KEY_ESC    27    /* ascii value for the escape key */
  66.  
  67. /* Global Variables */
  68.  
  69. static GLint    fogMode;
  70. static GLfloat    fogDensity;
  71. static GLfloat    fogStart = 5.0;
  72. static GLfloat    fogEnd = 11.0;
  73. GLfloat     fogColor[4] = { 0.0, 0.0, 1.0, 1.0 };
  74.  
  75. static GLboolean fogOffsetSupported = GL_TRUE;
  76. static GLboolean fogOffsetEnable = GL_FALSE;
  77. static GLfloat fogOffset[4];
  78.  
  79.  
  80. static float projNearTolerance, projFarTolerance;
  81.  
  82. static GLfloat x, y;
  83.  
  84. static GLfloat angle = 80.0;
  85.  
  86. void
  87. main( int argc, char *argv[] )
  88. {
  89.     GLsizei     width, height;
  90.  
  91.     glutInit( &argc, argv );
  92.  
  93.     width = glutGet( GLUT_SCREEN_WIDTH );
  94.     height = glutGet( GLUT_SCREEN_HEIGHT );
  95.     glutInitWindowPosition( width/4, height/4 );
  96.     glutInitWindowSize( width/2, height/2 );
  97.     glutInitDisplayMode( GLUT_RGBA | GLUT_DEPTH | GLUT_DOUBLE );
  98.     glutCreateWindow( argv[0] );
  99.  
  100.     initgfx();
  101.  
  102.     glutKeyboardFunc( keyboard );
  103.     glutSpecialFunc( specialkeys );
  104.     glutReshapeFunc( reshape );
  105.     glutDisplayFunc( drawScene );
  106.  
  107.     printHelp( argv[0] );
  108.     printf("\nFog mode is GL_EXP, density = %4.2f\n", fogDensity);
  109.  
  110.     if (!glutExtensionSupported("GL_SGIS_fog_func")) {
  111.         fogOffsetSupported = GL_FALSE;
  112.         fprintf( stderr,
  113.            "GL_SGIS_fog_offset not supported on this machine\n");
  114.     }
  115.     glutMainLoop();
  116. }
  117.  
  118. GLvoid
  119. printHelp( char *progname )
  120. {
  121.     fprintf(stdout,"\n%s - demonstrates fog\n\n"\
  122.         "Escape key        - exit the program\n"
  123.         "<f> key            - change fog blend function\n"
  124.         "<o> key        - toggle fog offset\n"
  125.         "UP Arrow Key        - increase fog density or end value\n"
  126.         "DOWN Arrow Key        - decrease fog density or end value\n",
  127.         progname);
  128. }
  129.  
  130. /* Initialize lighting and materials, enable depth buffer, and set
  131.  * initial fog parameters.
  132.  */
  133. GLvoid
  134. initgfx( GLvoid )
  135. {
  136.  
  137.     /* set the fog function and density */
  138.     fogMode = GL_EXP;
  139.     fogDensity = 0.25;
  140.  
  141.     /* setup and enable fog */
  142.     glFogi( GL_FOG_MODE, fogMode );
  143.     glHint( GL_FOG_HINT, GL_DONT_CARE );
  144. }
  145.  
  146. GLvoid
  147. cycleFog( GLvoid )
  148. {
  149.     if (fogMode == GL_EXP) {
  150.         fogMode = GL_EXP2;
  151.         printf( "Fog mode is GL_EXP2\n" );
  152.     } else if (fogMode == GL_EXP2) {
  153.         fogMode = GL_LINEAR;
  154.         printf( "Fog mode is GL_LINEAR\n" );
  155.     } else if (fogMode == GL_LINEAR) {
  156.         fogMode = GL_EXP;
  157.         printf( "Fog mode is GL_EXP\n" );
  158.     }
  159.     glFogi( GL_FOG_MODE, fogMode );
  160. }
  161.  
  162. GLvoid
  163. dec( GLvoid )
  164. {
  165.     if (fogMode == GL_LINEAR) {
  166.         fogEnd -= 0.5;
  167.         if (fogEnd < fogStart) fogEnd = fogStart;
  168.         glFogf( GL_FOG_END, fogEnd );
  169.         printf( "Fog end = %4.2f\n", fogEnd );
  170.     } else {
  171.         fogDensity -= 0.05;
  172.         if (fogDensity < 0.0) fogDensity = 0.0;
  173.         glFogf( GL_FOG_DENSITY, fogDensity );
  174.         printf( "Fog density = %4.2f\n", fogDensity );
  175.     }
  176. }
  177.  
  178. GLvoid
  179. inc( GLvoid )
  180. {
  181.     if (fogMode == GL_LINEAR) {
  182.         fogEnd += 0.5;
  183.         if (fogEnd > 12.0) fogEnd = 12.0;
  184.         glFogf( GL_FOG_END, fogEnd );
  185.         printf( "Fog end = %4.2f\n", fogEnd );
  186.     } else {
  187.         fogDensity += 0.05;
  188.         if (fogDensity > 1.0) fogDensity = 1.0;
  189.         glFogf (GL_FOG_DENSITY, fogDensity);
  190.         printf ("Fog density = %4.2f\n", fogDensity);
  191.     }
  192. }
  193.  
  194. GLvoid 
  195. specialkeys( GLint key, GLint x, GLint y )
  196. {
  197.     switch (key) {
  198.     case GLUT_KEY_UP:    /* increase fog density or end */
  199.         inc();
  200.         break;
  201.     case GLUT_KEY_DOWN:    /* decrease fog density or end */
  202.         dec();
  203.         break;
  204.     }
  205.     glutPostRedisplay();
  206. }
  207.  
  208. void toggleFogOffsetEnable( GLvoid )
  209. {
  210.     if (fogOffsetSupported) {
  211.         fogOffsetEnable = !fogOffsetEnable;
  212.         printf("Fog offset %s\n", 
  213.             (fogOffsetEnable? "Enabled":"Disabled"));
  214.     } else 
  215.         printf("GL_SGIX_fog_offset not supported\n");
  216. }
  217.  
  218. GLvoid 
  219. keyboard( GLubyte key, GLint x, GLint y )
  220. {
  221.     switch (key) {
  222.     case 'f':    /* cycle fog mode */
  223.         cycleFog();
  224.         glutPostRedisplay();
  225.         break;
  226.     case 'o':    /* toggle fog offset enable */
  227.         toggleFogOffsetEnable();
  228.         glutPostRedisplay();
  229.         break;
  230.     case KEY_ESC:    /* Exit whenever the Escape key is pressed */
  231.         exit(0);
  232.     }
  233. }
  234.  
  235. GLvoid
  236. reshape( GLsizei width, GLsizei height )
  237. {
  238.     GLdouble    aspect;
  239.  
  240.     glViewport( 0, 0, width, height );
  241.  
  242.     aspect = (GLdouble) width / (GLdouble) height;
  243. }
  244.  
  245. #define DBG2        0
  246.  
  247. #define FOG_STEP        0.05
  248.  
  249. #define EPSILON         0.999999
  250. #define TOLERANCE       1
  251.  
  252. #define X_STEP          12.0
  253. #define Y_STEP          12.0
  254.  
  255. static void setProjectionAndFog(GLfloat dist)
  256. {
  257.  
  258.     glMatrixMode(GL_PROJECTION);
  259.     glLoadIdentity();
  260.  
  261.     glOrtho(PROJ_LEFT, PROJ_RIGHT, PROJ_BOTTOM, PROJ_TOP, -dist, dist);
  262.  
  263.     projNearTolerance = (-dist > 0) ? - -dist * (1.0 + EPSILON) : 0;
  264.     projFarTolerance = - dist * EPSILON;
  265.  
  266.     glFogf(GL_FOG_END, dist);
  267. }
  268.  
  269. static void setFogOffsetEnable(int enable)
  270. {
  271.     if (!fogOffsetSupported) return;
  272.  
  273.     fogOffsetEnable = enable;
  274. #ifdef    GL_SGIX_fog_offset
  275.     if (fogOffsetEnable)
  276.         glEnable(GL_FOG_OFFSET_SGIX);
  277.     else
  278.         glDisable(GL_FOG_OFFSET_SGIX);
  279. #else
  280.     printf("GL_SGIX_fog_offset not supported\n");
  281. #endif
  282. }
  283.  
  284. static void setFogOffsetValue(float value)
  285. {
  286.     if (!fogOffsetSupported) return;
  287.  
  288.     fogOffset[3] =  value;
  289. #ifdef    GL_SGIX_fog_offset
  290.     glFogfv(GL_FOG_OFFSET_VALUE_SGIX, fogOffset);
  291. #else
  292.     printf("GL_SGIX_fog_offset not supported\n");
  293. #endif
  294. }
  295.  
  296. static void doPoint(GLfloat z)
  297. {
  298.     glBegin(GL_POINTS);
  299.     glVertex3d(x, y, z);
  300.     glEnd();
  301. }
  302.  
  303. static GLfloat zFromF(GLfloat f)
  304. {
  305.     GLfloat z;
  306.  
  307.     z = f * (fogEnd - fogStart) - fogEnd;
  308.  
  309.     if (z < projFarTolerance)
  310.         z = projFarTolerance;
  311.     if (z > projNearTolerance)
  312.         z = projNearTolerance;
  313.  
  314.     if (z > 0)
  315.         z = 0;
  316. #if DBG2
  317.     fprintf(stderr, "f %f z %f \n", f, z);
  318. #endif
  319.     return(z);
  320. }
  321.  
  322. static void draw(void)
  323. {
  324.     GLfloat f;
  325.  
  326.     x = PROJ_LEFT + X_STEP;
  327.     f = 1.0;
  328.     while(f > 0.0){
  329.         doPoint(zFromF(f));
  330.         f -= FOG_STEP;
  331.         x += X_STEP;
  332.     }
  333.     doPoint(zFromF(0.0));
  334.     y += Y_STEP;
  335. }
  336.  
  337. GLvoid
  338. drawScene( GLvoid )
  339. {
  340.     GLfloat fOff;
  341.  
  342.     glClearColor(0.2, 0.2, 0.2, 0.2);
  343.     glClear(GL_COLOR_BUFFER_BIT);
  344.  
  345.     glPointSize(10.0);
  346.     glColor4f(1.0, 1.0, 1.0, 1.0);
  347.  
  348.     glEnable(GL_FOG);
  349.     glFogfv(GL_FOG_COLOR, fogColor);
  350.     glFogi(GL_FOG_MODE, GL_LINEAR);
  351.     fogStart = 0.0;
  352.     glFogf(GL_FOG_START, fogStart);
  353.  
  354.     glMatrixMode(GL_MODELVIEW);
  355.     glLoadIdentity();
  356.  
  357.     fogOffsetEnable = 0;
  358.     fogOffset[0] = 0;
  359.     fogOffset[1] = 0;
  360.     fogOffset[2] = -1.0;
  361.     fogOffset[3] = 0.0;
  362.  
  363.     y = PROJ_BOTTOM + Y_STEP;
  364.  
  365.     /* set projection matrix; fog offset disable */
  366.     setProjectionAndFog(100.0);
  367.  
  368.     /* set fog offset value; fog offset disable */
  369.     setFogOffsetValue(19.0);
  370.     draw();
  371.  
  372.     /* enalbe fog offset */
  373.     setFogOffsetEnable(1);
  374.     draw();
  375.  
  376.     /* modify fog offset value; fog offset enable */
  377.     setFogOffsetValue(30.0);
  378.     draw();
  379.  
  380.     /* disable fog offset */
  381.     setFogOffsetEnable(0);
  382.     draw();
  383.  
  384.     /* modify projection matrix; fog offset disable */
  385.     setProjectionAndFog(500.0);
  386.     draw();
  387.     /* enable  fog offset after projection matrix had been modified */
  388.     setFogOffsetEnable(1);
  389.     draw();
  390.     /* modify projection matrix; fog offset enable */
  391.     setProjectionAndFog(1000.0);
  392.     draw();
  393.     /* modify fog offset value; fog offset enable */
  394.     setFogOffsetValue(150.0);
  395.     draw();
  396.     /* modify fog offset value; fog offset enable */
  397.     setFogOffsetValue(250.0);
  398.     draw();
  399.     /*disable fog, modify projection matrix, enable fog; fog offset enable*/
  400.     glDisable(GL_FOG);
  401.     setProjectionAndFog(10000.0);
  402.     glEnable(GL_FOG);
  403.     draw();
  404.     /* disable fog offset */
  405.     setFogOffsetEnable(0);
  406.     draw();
  407.     /* modify fog offset value to 0.0 and enable fog offset */
  408.     setFogOffsetEnable(1);
  409.     setFogOffsetValue(0.0);
  410.     draw();
  411.     for (fOff = 50.0; fOff <= 20000.0; fOff *= 1.7){
  412.         setFogOffsetValue(fOff);
  413.         draw();
  414.     }
  415.     setFogOffsetEnable(0);
  416.  
  417.     glutSwapBuffers();
  418.  
  419.     checkError("drawScene");
  420. }
  421.