#include <stdlib.h>
#include <math.h>
#include <limits.h>
#include <GL/glut.h>
const float PI2 = 2.0f*3.1415926535;
GLenum runMode = GL_TRUE;
GLenum shadeModel = GL_FLAT;
GLenum polygonMode = GL_LINE;
float RotX = 0.0f;
float RotY=0.0f;
float RotIncrementX = 0.0;
float RotIncrementY = 0.0;
const float RotIncFactor = 1.5;
int NumWraps = 10;
int NumPerWrap = 8;
float MajorRadius = 3.0;
float MinorRadius = 1.0;
int QuadMode = 1;
GLenum LocalMode = GL_TRUE;
int Light0Flag = 1;
int Light1Flag = 1;
int Light2Flag = 1;
float ambientLight[4] = {0.0, 1.0, 0.0, 1.0};
float Lt0amb[4] = {0.0, 0.0, 1.0, 1.0};
float Lt0diff[4] = {0.0, 1.0, 1.0, 1.0};
float Lt0spec[4] = {1.0, 1.0, 1.0, 1.0};
float Lt0pos[4] = {1.7*(3.0+1.0), 0.0, 0.0, 1.0};
float Lt1amb[4] = {1.0, 1.0, 0.0, 1.0};
float Lt1diff[4] = {1.0, 0.0, 1.0, 1.0};
float Lt1spec[4] = {1.0, 1.0, 0.0, 1.0};
float Lt1pos[4] = {0.0, 1.2*(3.0+1.0), 0.0, 1.0};
float Lt2amb[4] = {0.0, 1.0, 1.0, 1.0};
float Lt2diff[4] = {1.0, 1.0, 0.0, 1.0};
float Lt2spec[4] = {1.0, 0.0, 1.0, 1.0};
float Lt2pos[4] = {1.0,1.0*(3.0+1.0), 0.0, 1.0};
float Noemit[4] = {0.0, 0.0, 0.0, 1.0};
float Matspec[4] = {0.3, 0.3, 0.3, 1.0};
float Matnonspec[4] = {0.4, 0.4, 0.4, 1.0};
float Matshiny = 16.0;
// A texture
int TextureWrapVert=6;
int TextureWrapHoriz=6;
int textureFlag = 1;
#define stripeImageWidth 32
GLubyte stripeImage[4*stripeImageWidth];
#ifdef GL_VERSION_1_1
static GLuint texName;
#endif
void makeStripeImage(void)
{
int j;
for (j = 0; j < stripeImageWidth; j++) {
stripeImage[4*j] = (GLubyte) ((j<=4) ? 255 : 0);
stripeImage[4*j+1] = (GLubyte) ((j>4) ? 255 : 0);
stripeImage[4*j+2] = (GLubyte) 0;
stripeImage[4*j+3] = (GLubyte) 255;
}
}
static GLfloat xequalzero[] = {1.0, 0.0, 0.0, 0.0};
static GLfloat slanted[] = {1.0, 1.0, 1.0, 0.0};
static GLfloat *currentCoeff;
static GLenum currentPlane;
static GLint currentGenMode;
void ResetAnimation() {
RotX = RotY = RotIncrementX = RotIncrementY = 0.0;
}
void ZeroRotation() {
RotIncrementX = RotIncrementY = 0.0;
}
void ShadeModelToggle() {
if ( shadeModel == GL_FLAT ) {
shadeModel = GL_SMOOTH;
}
else {
shadeModel = GL_FLAT;
}
}
void FillModeToggle() {
if ( polygonMode == GL_LINE ) {
polygonMode = GL_FILL;
}
else {
polygonMode = GL_LINE;
}
}
void QuadTriangleToggle() {
QuadMode = 1-QuadMode;
}
void LocalToggle() {
LocalMode = !LocalMode;
if ( LocalMode ) {
Lt0pos[3] = Lt1pos[3] = 1.0;
}
else {
Lt0pos[3] = Lt1pos[3] = 0.0;
}
}
void Light0Toggle() {
Light0Flag = 1-Light0Flag;
}
void Light1Toggle() {
Light1Flag = 1-Light1Flag;
}
void Light2Toggle() {
Light2Flag = 1-Light2Flag;
}
void WrapMore() {
NumWraps++;
}
void WrapLess() {
if (NumWraps>4) {
NumWraps--;
}
}
void NumPerWrapMore() {
NumPerWrap++;
}
// Decrement number segments per wrap
void NumPerWrapLess() {
if (NumPerWrap>4) {
NumPerWrap--;
}
}
void putVertTexture(int i, int j) {
float wrapFrac = (j%NumPerWrap)/(float)NumPerWrap;
float wrapFracTex = (float)j/(float)NumPerWrap;
float phi = PI2*wrapFrac;
float thetaFrac = ((float)(i%NumWraps)+wrapFracTex)/(float)NumWraps;
float thetaFracTex = ((float)i+wrapFracTex)/(float)NumWraps;
float theta = PI2*thetaFrac;
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;
glTexCoord2f( wrapFracTex*(float)TextureWrapVert, thetaFracTex*(float)TextureWrapHoriz );
glNormal3f(sintheta*cosphi, sinphi, costheta*cosphi);
glVertex3f(x,y,z);
}
int i,j;
void updateScene( void )
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glShadeModel( shadeModel );
glPolygonMode(GL_FRONT_AND_BACK, polygonMode);
glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, LocalMode);
glDisable( GL_TEXTURE_2D );
if ( Light0Flag==1 || Light1Flag==1 ) {
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, 50.0);
}
if ( Light0Flag==1 ) {
glPushMatrix();
glTranslatef(Lt0pos[0], Lt0pos[1], Lt0pos[2]);
glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, Lt0diff);
glutSolidSphere(0.5,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, Lt1diff);
glutSolidSphere(0.3,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);
if ( textureFlag ) {
glEnable( GL_TEXTURE_2D );
}
glPushMatrix();
// 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
for (i=0; i<NumWraps; i++ ) {
glBegin( QuadMode ? GL_QUAD_STRIP : GL_TRIANGLE_STRIP);
for ( j=0; j<=NumPerWrap; j++) {
putVertTexture(i, j);
putVertTexture(i+1,j);
}
glEnd();
}
// Draw a reference sphere
glDisable( GL_TEXTURE_2D );
glTranslatef( -MajorRadius-MinorRadius-0.3, 0.0, 0.0);
glColor3f( 1.0f, 0.0f, 0.0f );
glutWireSphere( 0.2f, 5, 5 );
glPopMatrix();
#ifdef GL_VERSION_1_1
glBindTexture(GL_TEXTURE_1D, texName);
#endif
glFlush();
glutSwapBuffers();
}
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 'e':
exit(1);
case 'r': // Reset the animation (resets everything)
ResetAnimation();
break;
case 'z': // 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
LocalToggle();
break;
case '0': // Toggle light #0 on and off
Light0Toggle();
break;
case '1': // Toggle light #1 on and off
Light1Toggle();
break;
case '2': // Toggle light #2 on and off
Light2Toggle();
break;
case 't':
textureFlag = !textureFlag;
break;
}
}
void KeyUp() {
if ( RotIncrementX == 0.0 ) {
RotIncrementX = -0.1;
}
else if ( RotIncrementX < 0.0f) {
RotIncrementX *= RotIncFactor;
}
else {
RotIncrementX /= RotIncFactor;
}
}
void KeyDown() {
if ( RotIncrementX == 0.0 ) {
RotIncrementX = 0.1;
}
else if ( RotIncrementX > 0.0f) {
RotIncrementX *= RotIncFactor;
}
else {
RotIncrementX /= RotIncFactor;
}
}
void KeyLeft() {
if ( RotIncrementY == 0.0 ) {
RotIncrementY = -0.1;
}
else if ( RotIncrementY < 0.0) {
RotIncrementY *= RotIncFactor;
}
else {
RotIncrementY /= RotIncFactor;
}
}
void KeyRight()
{
if ( RotIncrementY == 0.0 ) {
RotIncrementY = 0.1;
}
else if ( RotIncrementY > 0.0) {
RotIncrementY *= RotIncFactor;
}
else {
RotIncrementY /= RotIncFactor;
}
}
void mySpecialKeyFunc( int key, int x, int y )
{
switch ( key ) {
case GLUT_KEY_UP:
KeyUp();
break;
case GLUT_KEY_DOWN:
KeyDown();
break;
case GLUT_KEY_LEFT:
KeyLeft();
break;
case GLUT_KEY_RIGHT:
KeyRight();
break;
}
}
void initRendering()
{
glEnable( GL_DEPTH_TEST );
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
glEnable(GL_LIGHT1);
glLightModelfv(GL_LIGHT_MODEL_AMBIENT, ambientLight);
// 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);
// Light 2 (Position is set in updateScene)
glLightfv(GL_LIGHT1, GL_AMBIENT, Lt2amb);
glLightfv(GL_LIGHT1, GL_DIFFUSE, Lt2diff);
glLightfv(GL_LIGHT1, GL_SPECULAR, Lt2spec);
// Load the texture
makeStripeImage();
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
#ifdef GL_VERSION_1_1
glGenTextures(1, &texName);
glBindTexture(GL_TEXTURE_1D, texName);
#endif
glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
#ifdef GL_VERSION_1_1
glTexImage1D(GL_TEXTURE_1D, 0, GL_RGBA, stripeImageWidth, 0,
GL_RGBA, GL_UNSIGNED_BYTE, stripeImage);
#else
glTexImage1D(GL_TEXTURE_1D, 0, 4, stripeImageWidth, 0,
GL_RGBA, GL_UNSIGNED_BYTE, stripeImage);
#endif
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
currentCoeff = xequalzero;
currentGenMode = GL_OBJECT_LINEAR;
currentPlane = GL_OBJECT_PLANE;
glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, currentGenMode);
glTexGenfv(GL_S, currentPlane, currentCoeff);
glEnable(GL_TEXTURE_GEN_S);
glEnable(GL_TEXTURE_1D);
//glTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE );
}
void resizeWindow(int w, int h)
{
float aspectRatio;
glViewport( 0, 0, w, h );
h = (w == 0) ? 1 : h;
aspectRatio = (float)w/(float)h;
glMatrixMode( GL_PROJECTION );
glLoadIdentity();
gluPerspective( 60.0, aspectRatio, 1.0, 30.0 );
glMatrixMode( GL_MODELVIEW );
glLoadIdentity();
glTranslatef(0.0, 0.0, -10.0);
glRotatef(25.0, 1.0,0.0,0.0);
}
int main( int argc, char** argv )
{
glutInit(&argc,argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH );
glutInitWindowPosition( 10, 60 );
glutInitWindowSize( 1200, 1400 );
glutCreateWindow( "TextureTorus" );
initRendering();
resizeWindow(1200,1400);
glutKeyboardFunc( myKeyboardFunc );
glutSpecialFunc( mySpecialKeyFunc );
glutReshapeFunc( resizeWindow );
glutIdleFunc( updateScene );
glutDisplayFunc( updateScene );
glutMainLoop( );
return(0);
}
Plz can u explain each function that are used in the program
ReplyDelete