Total members 11895 |It is currently Thu Dec 05, 2024 7:30 am Login / Join Codemiles

Java

C/C++

PHP

C#

HTML

CSS

ASP

Javascript

JQuery

AJAX

XSD

Python

Matlab

R Scripts

Weka





LightTorus.c
Code:

/**************************************************
* LightTorus.c
*
* Program to demonstrate how to add lighting
* and material properties to a torus.
* This program extends the program WrapTorus. 
*
* The triangles or quadrilaterals are wrapped around the
* torus in a single long strip.    See figure XXX on page XXX
* in the above mentioned book.
*
*
* Author: Samuel R. Buss
*
* Software accompanying the book
*      3D Computer Graphics: A Mathematical Introduction with OpenGL,
*      by S. Buss, Cambridge University Press, 2002.
*
* Software is "as-is" and carries no warranty.  It may be used without
*   restriction, but if you modify it, please change the filenames to
*   prevent confusion between different versions.
* Bug reports: Sam Buss, [email protected].
* Web page: http://math.ucsd.edu/~sbuss/MathCG
*
* USAGES: There are a number of keyboard commands that control
* the animation.  They must be typed into the graphics window,
* and are listed below:
*
* CONTROLLING RESOLUTION OF THE TORUS MESH
*   Press "W" to increase the number wraps.
*   Press "w" to decrease the number wraps.
*   Press "N" to increase the number of segments per wrap.
*   Press "n" to decrease the number of segments per wrap.
*   Press "q" to toggle between quadrangles and triangles.
*   
* CONTROLLING THE ANIMATION:
*   Press the "a" key to toggle the animation off and on.
*   Press the "s" key to perform a single step of the animation.
*   The left and right arrow keys controls the
*      rate of rotation around the y-axis.
*   The up and down arrow keys increase and decrease the rate of
*      rotation around the x-axis.  In order to reverse rotational
*      direction you must zero or reset the torus ("0" or "r").
*   Press the "r" key to reset the torus back to initial
*      position, with no rotation.
*   Press "0" (zero) to zero the rotation rates.
*
* CONTROLLING LIGHTS
*    Press '1' or '2' to toggle the first or second light off and on.
*   Press 'f' to toggle between flat and smooth shading.
*   Press 'l' to toggle local modes on and off (local viewer and positional light,
*      or non-local viewer and directional light).
*
* COMMANDS SHOWING OPENGL FEATURES:
*   Pressing "p" toggles between wireframe and polygon mode.
*   Pressing "f" key toggles between flat and smooth shading.
*
**/

#include <stdlib.h>
#include "LightTorus.h"
#include <math.h>
#include <limits.h>
#include <GL/glut.h>   // OpenGL Graphics Utility Library

const float PI2 = 2.0f*3.1415926535;

GLenum runMode = GL_TRUE;

GLenum shadeModel = GL_FLAT;      // Toggles between GL_FLAT and GL_SMOOTH
GLenum polygonMode = GL_LINE;      // Toggles between GL_LINE and GL_FILL

// Variables controlling the animation
float RotX = 0.0f;               // Rotational position around x-axis
float RotY = 0.0f;               // Rotational position around y-axis
float RotIncrementX = 0.0;         // Rotational increment, x-axis
float RotIncrementY = 0.0;         // Rotational increment, y-axis
const float RotIncFactor = 1.5;   // Factor change in rot rate per key stroke

// Variables controlling the fineness of the polygonal mesh
int NumWraps = 10;
int NumPerWrap = 8;

// Variables controlling the size of the torus
float MajorRadius = 3.0;
float MinorRadius = 1.0;

// Mode flags
int QuadMode = 1;            // Quad/Triangle toggling
GLenum LocalMode = GL_TRUE;      // Local viewer/non-local viewer mode
int Light0Flag = 1;            // Is light #0 on?
int Light1Flag = 1;            // Is light #1 on?

// Lighting values
float ambientLight[4] = {0.6, 0.6, 0.6, 1.0};
float Lt0amb[4] = {0.8, 0.8, 0.16, 1.0};
float Lt0diff[4] = {1.0, 1.0, 0.2, 1.0};
float Lt0spec[4] = {1.0, 1.0, 0.2, 1.0};
float Lt0pos[4] = {1.7*4.0, 0.0, 0.0, 1.0};         // 4 = MajorRadius + MinorRadius

float Lt1amb[4] = {0.0, 0.0, 0.5, 1.0};
float Lt1diff[4] = {0.0, 0.0, 0.5, 1.0};
float Lt1spec[4] = {0.0, 0.0, 1.0, 1.0};
float Lt1pos[4] = {0.0, 1.2*4.0, 0.0, 1.0};

// Material values
float Noemit[4] = {0.0, 0.0, 0.0, 1.0};
float Matspec[4] = {1.0, 1.0, 1.0, 1.0};
float Matnonspec[4] = {0.4, 0.05, 0.4, 1.0};
float Matshiny = 16.0;

// glutKeyboardFunc is called below to set this function to handle
//      all "normal" key presses.
void myKeyboardFunc( unsigned char key, int x, int y )
{
   switch ( key ) {
   case 'a':
      runMode = !runMode;
      break;
   case 's':
      runMode = GL_TRUE;
      updateScene();
      runMode = GL_FALSE;
      break;
   case 27:   // Escape key
      exit(1);
   case 'r':   // Reset the animation (resets everything)
      ResetAnimation();
      break;
   case '0':   // Zero the rotation rates
      ZeroRotation();
      break;
   case 'f':   // Shade mode toggles from flat to smooth
      ShadeModelToggle();
      break;
   case 'p':   // Polygon mode toggles between fill and line
      FillModeToggle();
      break;
   case 'w':   // Decrement number of wraps around torus
      WrapLess();
      break;
   case 'W':   // Increment number of wraps around torus
      WrapMore();
      break;
   case 'n':   // Decrement number of polys per wrap
      NumPerWrapLess();
      break;
   case 'N':   // Increment number of polys per wrap
      NumPerWrapMore();
      break;
   case 'q':   // Toggle between triangles and Quadrilaterals
      QuadTriangleToggle();
      break;
   case 'l':   // Toggle between local and non-local viewer ('l' is for 'local')
      LocalToggle();
      break;
   case '1':   // Toggle light #0 on and off
      Light0Toggle();
      break;
   case '2':   // Toggle light #1 on and off
      Light1Toggle();
      break;
   }
}

// glutSpecialFunc is called below to set this function to handle
//      all "special" key presses.  See glut.h for the names of
//      special keys.
void mySpecialKeyFunc( int key, int x, int y )
{
   switch ( key ) {
   case GLUT_KEY_UP:      
      // Either increase upward rotation, or slow downward rotation
      KeyUp();
      break;
   case GLUT_KEY_DOWN:
      // Either increase downwardward rotation, or slow upward rotation
      KeyDown();
      break;
   case GLUT_KEY_LEFT:
      // Either increase left rotation, or slow down rightward rotation.
      KeyLeft();
      break;
   case GLUT_KEY_RIGHT:
      // Either increase right rotation, or slow down leftward rotation.
      KeyRight();
      break;
   }
}

// The routines below are coded so that the only way to change from
//   one direction of rotation to the opposite direction is to first
//  reset the animation,

void KeyUp() {
    if ( RotIncrementX == 0.0 ) {
      RotIncrementX = -0.1;      // Initially, one-tenth degree rotation per update
   }
   else if ( RotIncrementX < 0.0f) {
      RotIncrementX *= RotIncFactor;
   }
   else {
      RotIncrementX /= RotIncFactor;
   }   
}

void KeyDown() {
    if ( RotIncrementX == 0.0 ) {
      RotIncrementX = 0.1;      // Initially, one-tenth degree rotation per update
   }
   else if ( RotIncrementX > 0.0f) {
      RotIncrementX *= RotIncFactor;
   }
   else {
      RotIncrementX /= RotIncFactor;
   }   
}

void KeyLeft() {
    if ( RotIncrementY == 0.0 ) {
      RotIncrementY = -0.1;      // Initially, one-tenth degree rotation per update
   }
   else if ( RotIncrementY < 0.0) {
      RotIncrementY *= RotIncFactor;
   }
   else {
      RotIncrementY /= RotIncFactor;
   }   
}

void KeyRight()
{
    if ( RotIncrementY == 0.0 ) {
      RotIncrementY = 0.1;      // Initially, one-tenth degree rotation per update
   }
   else if ( RotIncrementY > 0.0) {
      RotIncrementY *= RotIncFactor;
   }
   else {
      RotIncrementY /= RotIncFactor;
   }   
}


// Resets position and sets rotation rate back to zero.
void ResetAnimation() {
   RotX = RotY = RotIncrementX = RotIncrementY = 0.0;
}

// Sets rotation rates back to zero.
void ZeroRotation() {
   RotIncrementX = RotIncrementY = 0.0;
}

// Toggle between smooth and flat shading
void ShadeModelToggle() {
   if ( shadeModel == GL_FLAT ) {
      shadeModel = GL_SMOOTH;
   }
   else {
      shadeModel = GL_FLAT;
   }
}

// Toggle between line mode and fill mode for polygons.
void FillModeToggle() {
   if ( polygonMode == GL_LINE ) {
      polygonMode = GL_FILL;
   }
   else {
      polygonMode = GL_LINE;
   }
}

// Toggle quadrilaterial and triangle mode
void QuadTriangleToggle() {
   QuadMode = 1-QuadMode;
}

// Toggle from local to global mode
void LocalToggle() {
   LocalMode = !LocalMode;
   if ( LocalMode ) {
      Lt0pos[3] = Lt1pos[3] = 1.0;   // Put lights back at finite location.
   }
   else {
      Lt0pos[3] = Lt1pos[3] = 0.0;   // Put lights at infinity too.
   }
}

// The next two routines toggle the lights on and off
void Light0Toggle() {
   Light0Flag = 1-Light0Flag;
}

void Light1Toggle() {
   Light1Flag = 1-Light1Flag;
}


// Increment number of wraps
void WrapMore() {
   NumWraps++;
}

// Decrement number of wraps
void WrapLess() {
   if (NumWraps>4) {
      NumWraps--;
   }
}

// Increment number of segments per wrap
void NumPerWrapMore() {
   NumPerWrap++;   
}

// Decrement number segments per wrap
void NumPerWrapLess() {
   if (NumPerWrap>4) {
      NumPerWrap--;
   }
}

/*
* issue vertex command for segment number j of wrap number i.
*/
void putVert(int i, int j) {
   float wrapFrac = (j%NumPerWrap)/(float)NumPerWrap;
   float phi = PI2*wrapFrac;
   float theta = PI2*(i%NumWraps+wrapFrac)/(float)NumWraps;
   float sinphi = sin(phi);
   float cosphi = cos(phi);
   float sintheta = sin(theta);
   float costheta = cos(theta);
   float y = MinorRadius*sinphi;
   float r = MajorRadius + MinorRadius*cosphi;
   float x = sintheta*r;
   float z = costheta*r;
   glNormal3f(sintheta*cosphi, sinphi, costheta*cosphi);
   glVertex3f(x,y,z);
}


void updateScene( void )
{
   int i,j;

   // Clear the redering window
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

   glShadeModel( shadeModel );   // Set the shading to flat or smooth.
   glPolygonMode(GL_FRONT_AND_BACK, polygonMode);   // Set to be "wire" or "solid"
   glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, LocalMode);

   // Set up lights
   if ( Light0Flag==1 || Light1Flag==1 ) {
      // Emissive spheres have no other color.
      glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, Noemit);
      glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, Noemit);
      glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, 0.0);
   }
   if ( Light0Flag==1 ) {
      glPushMatrix();
      glTranslatef(Lt0pos[0], Lt0pos[1], Lt0pos[2]);
      glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, Lt0spec);
      glutSolidSphere(0.2,5,5);
      glPopMatrix();
      glEnable(GL_LIGHT0);
      glLightfv(GL_LIGHT0, GL_POSITION, Lt0pos);
   }
   else {
      glDisable(GL_LIGHT0);
   }
   if ( Light1Flag==1 ) {
      glPushMatrix();
      glTranslatef(Lt1pos[0], Lt1pos[1], Lt1pos[2]);
      glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, Lt1spec);
      glutSolidSphere(0.2,5,5);
      glPopMatrix();
      glEnable(GL_LIGHT1);
      glLightfv(GL_LIGHT1, GL_POSITION, Lt1pos);
   }
   else {
      glDisable(GL_LIGHT1);
   }

   // Torus Materials
   glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, Matnonspec);
   glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, Matspec);
   glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, Matshiny);
   glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, Noemit);

   glPushMatrix();      // Save to use again next time.

   // Update the orientation of the torus, if the animation is running.
   if ( runMode ) {
      RotY += RotIncrementY;
      if ( fabs(RotY)>360.0 ) {
         RotY -= 360.0*((int)(RotY/360.0));
      }
      RotX += RotIncrementX;
      if ( fabs(RotX)>360.0 ) {
         RotX -= 360.0*((int)(RotX/360.0));
      }
   }
   // Set the orientation.
   glRotatef( RotX, 1.0, 0.0, 0.0);
   glRotatef( RotY, 0.0, 1.0, 0.0);

   // Draw the torus
   glColor3f( 1.0, 0.5, 1.0 );

   glBegin( QuadMode==1 ? GL_QUAD_STRIP : GL_TRIANGLE_STRIP );

   for (i=0; i<NumWraps; i++ ) {
      for (j=0; j<NumPerWrap; j++) {
         putVert(i,j);
         putVert(i+1,j);
      }
   }
   putVert(0,0);
   putVert(1,0);

   glEnd();


   // Draw the reference pyramid
   glTranslatef( -MajorRadius-MinorRadius-0.3, 0.0, 0.0);
   glScalef( 0.2f, 0.2f, 0.2f );
   glColor3f( 1.0f, 1.0f, 0.0f );
   glBegin(GL_TRIANGLE_STRIP);
   glVertex3f( -0.5, 0.0, sqrt(3.0)*0.5 );
   glVertex3f( -0.5, 0.0, -sqrt(3.0)*0.5 );
   glVertex3f( 1.0, 0.0, 0.0);
   glVertex3f( 0.0, sqrt(2.0), 0.0);
   glVertex3f( -0.5, 0.0, sqrt(3.0)*0.5 );
   glVertex3f( -0.5, 0.0, -sqrt(3.0)*0.5 );
   glEnd();

   glPopMatrix();      // Restore to original matrix as set in resizeWindow()

   // Flush the pipeline, swap the buffers
    glFlush();
    glutSwapBuffers();
}

// Initialize OpenGL
void initRendering()
{
    glEnable( GL_DEPTH_TEST );

   glEnable(GL_LIGHTING);      // Enable lighting calculations
   glEnable(GL_LIGHT0);      // Turn on lights (unnecessary here, since also in Animate()
   glEnable(GL_LIGHT1);
   glLightModelfv(GL_LIGHT_MODEL_AMBIENT, ambientLight);   // Ambient light

   // Light 0 (Position is set in updateScene)
   glLightfv(GL_LIGHT0, GL_AMBIENT, Lt0amb);
   glLightfv(GL_LIGHT0, GL_DIFFUSE, Lt0diff);
   glLightfv(GL_LIGHT0, GL_SPECULAR, Lt0spec);

   // Light 1 (Position is set in updateScene)
   glLightfv(GL_LIGHT1, GL_AMBIENT, Lt1amb);
   glLightfv(GL_LIGHT1, GL_DIFFUSE, Lt1diff);
   glLightfv(GL_LIGHT1, GL_SPECULAR, Lt1spec);

}

// Called when the window is resized
//      Sets up the projection view matrix (somewhat poorly, however)
void resizeWindow(int w, int h)
{
    float aspectRatio;
   glViewport( 0, 0, w, h );   // View port uses whole window
   h = (w == 0) ? 1 : h;
   aspectRatio = (float)w/(float)h;

   // Set up the proection view matrix
    glMatrixMode( GL_PROJECTION );
    glLoadIdentity();
    gluPerspective( 60.0, aspectRatio, 1.0, 30.0 );

   glMatrixMode( GL_MODELVIEW );
   glLoadIdentity();
   // Move system 10 units away to be able to view from the origin.
   glTranslatef(0.0, 0.0, -10.0);

   // Tilt system 15 degrees downward in order to view from above
   //   the xy-plane.
   glRotatef(15.0, 1.0,0.0,0.0);   
}


// Main routine
// Set up OpenGL, hook up callbacks, and start the main loop
int main( int argc, char** argv )
{
   glutInit(&argc,argv);
    glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH );

   // Window position (from top corner), and size (width and hieght)
    glutInitWindowPosition( 10, 60 );
    glutInitWindowSize( 620, 160 );
    glutCreateWindow( "Light Torus demo" );

   // Initialize OpenGL rendering modes
    initRendering();
   resizeWindow(620,160);

   // Set up callback functions for key presses
   glutKeyboardFunc( myKeyboardFunc );
   glutSpecialFunc( mySpecialKeyFunc );

   // Set up the callback function for resizing windows
    glutReshapeFunc( resizeWindow );

   // Call this for background processing
   glutIdleFunc( updateScene );
   // Call this whenever window needs redrawing
    glutDisplayFunc( updateScene );
   
   // Start the main loop.  glutMainLoop never returns.
   glutMainLoop(  );

    return(0);   // This line is never reached.
}



LightTorus.h:
Code:
/*
* LightTorus.h
*
* Author: Samuel R. Buss
*
* Software accompanying the book
*      3D Computer Graphics: A Mathematical Introduction with OpenGL,
*      by S. Buss, Cambridge University Press, 2002.
*
* Software is "as-is" and carries no warranty.  It may be used without
*   restriction, but if you modify it, please change the filenames to
*   prevent confusion between different versions.
* Bug reports: Sam Buss, [email protected].
* Web page: http://math.ucsd.edu/~sbuss/MathCG
*/

// Function prototypes

void myKeyboardFunc( unsigned char key, int x, int y );
void mySpecialKeyFunc( int key, int x, int y );

void updateScene( void );

void initRendering();
void resizeWindow(int w, int h);

void KeyUp();
void KeyDown();
void KeyLeft();
void KeyRight();
void ResetAnimation();
void ZeroRotation();
void ShadeModelToggle();
void FillModeToggle();
void QuadTriangleToggle();
void LocalToggle();
void Light0Toggle();
void Light1Toggle();
void WrapMore();
void WrapLess();
void NumPerWrapMore();
void NumPerWrapLess();

// Torus specific routines.
void putVert(int i, int j);








Attachments:
untitled.GIF
untitled.GIF [ 6.52 KiB | Viewed 8797 times ]

_________________
M. S. Rakha, Ph.D.
Queen's University
Canada
Author:
Mastermind
User avatar Posts: 2715
Have thanks: 74 time
Post new topic Reply to topic  [ 1 post ] 

  Related Posts  to : demonstrate how to add lighting and material properties
 add lighting to teapot 3d     -  
 Turn on-off lighting effects     -  
 Adding lighting to a solid sphere     -  
 material of jsp and servlets     -  
 need simple material to lear c++     -  
 Material Handling Equipment     -  
 Change the properties of div tag     -  
 links CSS properties     -  
 Java properties utility     -  



Topic Tags

C++ Graphics






Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group
All copyrights reserved to codemiles.com 2007-2011
mileX v1.0 designed by codemiles team
Codemiles.com is a participant in the Amazon Services LLC Associates Program, an affiliate advertising program designed to provide a means for sites to earn advertising fees by advertising and linking to Amazon.com