/*#######################################################################
Necessary
librarys for Unix
#########################################################################*/
#include
<stdio.h>
#include
<math.h>
#include
<stdlib.h>
#include
<GL/gl.h>
#include
<GL/glu.h>
#include
"glaux.h"
#define CUBE_SIZE 1.0
#define
PI 3.1415926535
#define
GO_TO_1 1
#define
GO_TO_2 2
#define
SMOOTH 1
#define
FLAT 0
float
incr,incangle,yrot,xrot,zpos;
int
formula,wireframe,rotate,animate,pause,delaytime, morph,shading ,ani_num ;
typedef
struct {
GLfloat x,y,z;
} Vertex;
void
PolygonAnimate();
Vertex
VertexMultiply ( Vertex , Vertex);
Vertex
VertexSubtract( Vertex , Vertex);
Vertex
SmoothTransition( GLfloat,GLfloat,GLfloat,float,float,float);
Vertex
NormalTransit(GLfloat,GLfloat,GLfloat,float,float,float);
Vertex
Normalize(GLfloat,GLfloat,GLfloat);
Vertex
WireVertex(int);
void StartRotate ();
void StopRotate ();
void WireAnimate();
void DrawAxis();
void
DrawWireFrame();
void
DrawPolygon();
Vertex
ObtVertex(int,float,float);
/**********************************************************************
This function is called only once in the
very beginning.
It can initialize whatever you want.
For shaded polygon, define materials and
lights here.
***********************************************************************/
static
void Init()
{
const float
lightModelAmbient[]={0.7,0.7,0.7,1.0};
const float lightModelValue[]={0.0};
const float lightAmbient[]={0.9,0.9,0.9,1.0};
const float
lightDiffuse[]={0.5,0.5,0.5,1.0};
const float
lightSpecular[]={0.1,0.1,0.1,1.0};
const float lightShininess[]={5.0,0};
const float lightPos[]={ 5.0,5.0,-4.0, 0.0};
const float lightPos1[]={ -5.0,-5.0,-4.0,
0.0};
float matEmission[4]={0.0,0.0,0.0,1.0};
float matShininess[1]={5.0};
float matSpecular[4]={0.1,0.1,0.1,1.0};
float matDiffuse[4]={0.3,0.3,0.3,1.0};
float matAmbient[4]={0.5,0.5,0.8,1.0};
glDepthFunc(GL_LESS);
glEnable(GL_DEPTH_TEST);
glEnable(GL_NORMALIZE);
glEnable(GL_LIGHT0);
glEnable(GL_LIGHTING);
glLightModelfv(GL_LIGHT_MODEL_AMBIENT,lightModelAmbient);
glLightModelfv(GL_LIGHT_MODEL_LOCAL_VIEWER,lightModelValue);
glLightModelfv(GL_LIGHT_MODEL_TWO_SIDE,lightModelValue);
glEnable(GL_LIGHT1);
glEnable(GL_LIGHTING);
glLightfv(GL_LIGHT1,GL_AMBIENT,lightAmbient);
glLightfv(GL_LIGHT1,GL_POSITION,lightPos);
glLightfv(GL_LIGHT1,GL_DIFFUSE,lightDiffuse);
glLightfv(GL_LIGHT1,GL_SPECULAR,lightSpecular);
glLightfv(GL_LIGHT1,GL_AMBIENT,lightAmbient);
glLightfv(GL_LIGHT1,GL_POSITION,lightPos1);
glLightfv(GL_LIGHT1,GL_DIFFUSE,lightDiffuse);
glLightfv(GL_LIGHT1,GL_SPECULAR,lightSpecular);
glLightfv(GL_LIGHT1,GL_SHININESS,lightShininess);
glLightModeli(GL_LIGHT_MODEL_TWO_SIDE,
GL_TRUE);
/*set material*/
glPolygonMode(GL_FRONT_AND_BACK,
GL_FILL);
glColorMaterial(GL_FRONT_AND_BACK,GL_AMBIENT);
glEnable(GL_COLOR_MATERIAL);
glMaterialfv(GL_FRONT_AND_BACK,GL_SPECULAR,matSpecular);
glMaterialfv(GL_FRONT_AND_BACK,GL_DIFFUSE,matDiffuse);
glMaterialfv(GL_FRONT_AND_BACK,GL_EMISSION,matEmission);
glMaterialfv(GL_FRONT_AND_BACK,GL_SHININESS,matShininess);
glMaterialfv(GL_FRONT_AND_BACK,GL_AMBIENT,matAmbient);
incr = yrot = xrot = 1.0;
zpos = -50;
wireframe = 1 ;
incr = 0;
rotate=animate=pause =0;
shading = GL_FLAT;
incangle = 0.15 ;
delaytime = 2000;
ani_num = 0;
formula = 0;
}
/***********************************************************************
Main Drawing Function.
It is
called by the system to draw every next buffer with the maximum
speed
available.
************************************************************************/
static
void MainDraw()
{
glClearColor
(0.0, 0.0, 0.0, 0.0);
/*
Background color */
glClear(GL_COLOR_BUFFER_BIT |
GL_DEPTH_BUFFER_BIT);
glPushMatrix();
if
(rotate == 1){
if ( yrot >= 360)
yrot = 0 ;
else
yrot +=10 ;
}
/* This
translation is done for the visualization transformation */
glTranslatef(0.0,0.0,zpos);
/* The
following are rotations done about Y followed by rotation about X */
glRotatef(yrot,
0.0, 1.0, 0.0);
glRotatef(xrot,
1, 0.0, 0.0);
if
(animate == 1 ) {
if ( pause == 0 ) {
if
( incr <= 1){
incr += 0.05;
}
if ( incr >= 1){
incr = 0;
ani_num++;}
}
if(wireframe == 1) {
WireAnimate();
}
else
PolygonAnimate() ;
}
else {
if
( wireframe == 1)
DrawWireFrame();
else
DrawPolygon();
}
DrawAxis();
glFlush();
glPopMatrix();
auxSwapBuffers();
}
/**********************************************************************
This function defines the object(s) to be
drawn.
Now, for wire-frame drawing, only
polylines and lines are used.
***********************************************************************/
void DrawWireFrame()
{
float fi,teta = 0;
int i=1;
Vertex v;
glColor3f(0.0,0.0,1.0);
glBegin(GL_LINE_STRIP);
for(fi=0 ; fi < 2*PI; fi=fi +incangle)
{
for(teta=0
; teta < 2*PI ; teta= teta +incangle )
{
v = ObtVertex ( formula, fi, teta);
glVertex3f(v.x,v.y,v.z);
}
v
= ObtVertex ( formula,fi, 0);
glVertex3f(v.x,v.y,v.z);
}
v =
ObtVertex ( formula, 0, 0);
glVertex3f(v.x,v.y,v.z);
for(teta=
0 ; teta < 2*PI ; teta= teta +incangle)
{
for(fi=
0 ; fi < 2*PI; fi=fi +incangle)
{
v = ObtVertex ( formula, fi,
teta);
glVertex3f(v.x,v.y,v.z);
}
v = ObtVertex ( formula, 0, teta);
glVertex3f(v.x,v.y,v.z);
}
v =
ObtVertex ( formula, 0, 0);
glVertex3f(v.x,v.y,v.z);
glEnd();
}
/******************************************************************/
/* Draw
a Polygon */
/******************************************************************/
void DrawPolygon()
{
float
fi,teta = 0;
int i=1;
Vertex v,nv ;
glColor4f(0.8,0.2,0.2,1.0);
glBegin(GL_QUAD_STRIP);
glPolygonMode(GL_FRONT_AND_BACK,GL_FILL);
for(teta=
0 ; teta < 2*PI; teta=teta +incangle)
{ glBegin(GL_QUAD_STRIP);
glPolygonMode(GL_FRONT_AND_BACK,GL_FILL);
for(fi=
0 ; fi < 2*PI; fi=fi +incangle)
{
v
= ObtVertex ( formula, fi, teta);
if
(shading == GL_FLAT)
nv = NormalTransit (
v.x,v.y,v.z,incangle,fi,teta);
else
nv = SmoothTransition (
v.x,v.y,v.z,incangle,fi,teta);
nv = Normalize(nv.x,nv.y,nv.z);
glNormal3f (nv.x,nv.y,nv.z);
glVertex3f(v.x,v.y,v.z);
v = ObtVertex ( formula,
fi+incangle, teta);
if
(shading == GL_SMOOTH){
nv = SmoothTransition ( v.x,v.y,v.z,incangle,fi+incangle,teta);
nv = Normalize(nv.x,nv.y,nv.z);
glNormal3f (nv.x,nv.y,nv.z);}
else;
glVertex3f(v.x,v.y,v.z);
v =
ObtVertex ( formula, fi , teta+incangle);
if
(shading == GL_SMOOTH){
nv = SmoothTransition ( v.x,v.y,v.z,incangle,fi,teta+incangle);
nv = Normalize(nv.x,nv.y,nv.z);
glNormal3f (nv.x,nv.y,nv.z);}
else;
glVertex3f(v.x,v.y,v.z);
v
= ObtVertex ( formula, fi+incangle ,
teta+incangle);
if
(shading == GL_SMOOTH){
nv = SmoothTransition (
v.x,v.y,v.z,incangle,fi+incangle,teta+incangle);
nv = Normalize(nv.x,nv.y,nv.z);
glNormal3f (nv.x,nv.y,nv.z);}
else
;
glVertex3f(v.x,v.y,v.z);
}
glEnd();
}
}
/************************************************************************
Get
the normal for a vertex
************************************************************************/
Vertex
NormalTransit(GLfloat x, GLfloat y,GLfloat z,float incangle, float fi,float
teta)
{
Vertex v,v1,v2,v_v1,v_v2,nv;
v.x =
x;
v.y =
y;
v.z =
z;
v1 = ObtVertex ( formula, fi ,
teta+incangle);
v2 = ObtVertex ( formula, fi+incangle,
teta);
v_v1.x = v.x -v1.x;
v_v1.y = v.y -v1.y;
v_v1.z = v.z -v1.z;
v_v2.x = v.x -v2.x;
v_v2.y = v.y -v2.y;
v_v2.z = v.z -v2.z;
/*Cross product*/
nv.x =
v_v2.y*v_v1.z - v_v1.y*v_v2.z;
nv.y =
v_v1.x*v_v2.y - v_v2.x*v_v1.y;
nv.z =
v_v2.x*v_v1.y - v_v1.x*v_v2.y;
return nv;
}
/************************************************************************
Smooth Cross
************************************************************************/
Vertex
SmoothTransition( GLfloat x, GLfloat y, GLfloat z, float incangle, float fi,
float teta)
{
Vertex
ans,v,v1,v2,v3,v4,v3v,v4v,vv1,vv2,v12,v23,v34,v41;
v.x = x;
v.y = y;
v.z= z;
v1 = ObtVertex ( formula, fi,
teta-incangle);
v2 = ObtVertex ( formula, fi-incangle,
teta);
v3 = ObtVertex ( formula, fi+incangle, teta);
v4 = ObtVertex ( formula, fi+incangle,
teta);
v3v = VertexSubtract ( v3, v);
v4v = VertexSubtract ( v4, v);
vv1 = VertexSubtract ( v,v1);
vv2 = VertexSubtract ( v,v2);
v12 = VertexMultiply ( vv2,vv1);
v23 = VertexMultiply ( vv2,v3v);
v34 = VertexMultiply ( v4v,v3v);
v41 = VertexMultiply ( v4v,vv1);
ans.x =
(v12.x +v23.x+v34.x+v41.x)/4 ;
ans.y =
(v12.y +v23.y+v34.y+v41.y)/4 ;
ans.z =
(v12.z +v23.z+v34.z+v41.z)/4 ;
return ans;
}
/************************************************************************
Vertex
Subtraction
************************************************************************/
Vertex
VertexSubtract ( Vertex v, Vertex v1)
{ Vertex ans;
ans.x = v.x -v1.x;
ans.y = v.y - v1.y;
ans.z = v.z- v1.z;
return ans;
}
/************************************************************************
Vertex
Multiply
************************************************************************/
Vertex
VertexMultiply ( Vertex v , Vertex v1)
{
Vertex ans;
ans.x = v.y*v1.z - v1.y*v.z;
ans.y = v1.x*v.z - v.x*v1.z;
ans.z = v.x*v1.y - v1.x*v.y;
return ans;
}
/******************************************************************/
/* Get
the Vertices
*/
/******************************************************************/
Vertex
ObtVertex( int formula,float fi,float teta)
{
Vertex v1;
switch ( formula ) {
case 0 : v1.x = 0.1*(3*cos(teta)+0.8*cos(3*teta));
v1.y = 0.2*cos(fi)*(5+3*sin(teta)-0.8*sin(3*teta));
v1.z =
0.2*sin(fi)*(5+3*sin(teta)-0.8*sin(3*teta));
break;
case 1 : v1.x =
pow(cos(teta),3)*pow(sin(fi),5);
v1.y =
pow(sin(teta),3)*pow(sin(fi),5);
v1.z =
pow(sin(fi),5)*(cos(teta));
}
v1.x *=10;
v1.y *=10;
v1.z *=10;
return v1;
}
/************************************************************************
This function animates the WireFrame
************************************************************************/
void
WireAnimate()
{
Vertex v,v1,v2;
float i ,fi,teta ;
glColor3f(0.0,0.0,1.0);
glBegin(GL_LINE_STRIP);
i = sin(incr*PI/2) ;
for(fi= 0 ; fi <= 2*PI; fi=fi +incangle)
{
for(teta=
0 ; teta < 2*PI ; teta= teta +incangle)
{
v =
ObtVertex ( ani_num%2, fi, teta);
v1 = ObtVertex ( (ani_num+1)%2, fi, teta);
v2.x = (1-i)*v.x + i*v1.x;
v2.y
= (1-i)*v.y + i*v1.y;
v2.z
= (1-i)*v.z + i*v1.z;
glVertex3f(v2.x,v2.y,v2.z);
}
v
= ObtVertex ( ani_num%2, fi, 0);
v1 = ObtVertex ( (ani_num+1)%2, fi, 0);
v2.x = (1-i)*v.x + i*v1.x;
v2.y
= (1-i)*v.y + i*v1.y;
v2.z
= (1-i)*v.z + i*v1.z;
glVertex3f(v2.x,v2.y,v2.z);
}
for(teta= 0 ; teta <= 2*PI; teta=teta +incangle)
{
for(fi=
0 ; fi <= 2*PI ; fi= fi +incangle)
{
v =
ObtVertex ( ani_num%2, fi, teta);
v1 = ObtVertex ( (ani_num+1)%2, fi, teta);
v2.x = (1-i)*v.x + i*v1.x;
v2.y
= (1-i)*v.y + i*v1.y;
v2.z
= (1-i)*v.z + i*v1.z;
glVertex3f(v2.x,v2.y,v2.z);
// Delay(delaytime);
}
v
= ObtVertex ( ani_num%2, 0, teta);
v1 = ObtVertex ( (ani_num+1)%2, 0, teta);
v2.x = (1-i)*v.x + i*v1.x;
v2.y
= (1-i)*v.y + i*v1.y;
v2.z
= (1-i)*v.z + i*v1.z;
glVertex3f(v2.x,v2.y,v2.z);
//Delay(delaytime);
}
glEnd();
}
/************************************************************************
Polygon
Animate
************************************************************************/
void
PolygonAnimate()
{
Vertex v,v1,v2,nv;
float i ,fi,teta ;
int j,k;
glColor4f(0.8,0.2,0.2,1.0);
glBegin(GL_QUAD_STRIP);
glPolygonMode(GL_FRONT_AND_BACK,GL_FILL);
i
= sin(incr*PI/2) ;
for(teta=
0 ; teta < 2*PI; teta=teta +incangle)
{
for(fi=
0 ; fi <= 2*PI ; fi= fi +incangle)
{
glBegin(GL_QUAD_STRIP);
glPolygonMode(GL_FRONT_AND_BACK,GL_FILL);
glShadeModel(shading);
v = ObtVertex ( ani_num%2, fi, teta);
v1 = ObtVertex ( (ani_num+1)%2, fi, teta);
v2.x = (1-i)*v.x + i*v1.x;
v2.y = (1-i)*v.y +
i*v1.y;
v2.z = (1-i)*v.z +
i*v1.z;
if (shading == GL_SMOOTH)
nv = SmoothTransition ( v2.x,v2.y,v2.z,incangle,fi,teta);
else
nv = NormalTransit (
v2.x,v2.y,v2.z,incangle,fi,teta);
//v = Normalize(nv.x,nv.y,nv.z);
// 1st vertex
glNormal3f (nv.x,nv.y,nv.z);
glVertex3f(v2.x,v2.y,v2.z);
v = ObtVertex ( ani_num%2,
fi+incangle, teta);
v1 = ObtVertex ((ani_num+1)%2, fi+incangle, teta);
v2.x = (1-i)*v.x + i*v1.x;
v2.y = (1-i)*v.y +
i*v1.y;
v2.z = (1-i)*v.z +
i*v1.z;
if
(shading == GL_SMOOTH){
nv = SmoothTransition (
v2.x,v2.y,v2.z,incangle,fi+incangle,teta);
nv = Normalize(nv.x,nv.y,nv.z);
glNormal3f (nv.x,nv.y,nv.z);
}
//2nd
vertex
glVertex3f(v2.x,v2.y,v2.z);
v =
ObtVertex ( ani_num%2, fi , teta+incangle);
v1 = ObtVertex ((ani_num+1)%2, fi ,
teta+incangle);
v2.x =
(1-i)*v.x + i*v1.x;
v2.y = (1-i)*v.y +
i*v1.y;
v2.z = (1-i)*v.z +
i*v1.z;
if (shading == GL_SMOOTH){
nv = SmoothTransition (
v2.x,v2.y,v2.z,incangle,fi,teta+incangle);
nv = Normalize(nv.x,nv.y,nv.z);
glNormal3f (nv.x,nv.y,nv.z);
}
//3rd
vertex
glVertex3f(v2.x,v2.y,v2.z);
v = ObtVertex ( ani_num%2,
fi+incangle, teta+incangle);
v1 = ObtVertex ( (ani_num+1)%2, fi+incangle, teta+incangle);
v2.x = (1-i)*v.x + i*v1.x;
v2.y = (1-i)*v.y +
i*v1.y;
v2.z = (1-i)*v.z +
i*v1.z;
if (shading == GL_SMOOTH){
nv = SmoothTransition (
v2.x,v2.y,v2.z,incangle,fi+incangle,teta+incangle);
nv = Normalize(nv.x,nv.y,nv.z);
glNormal3f (nv.x,nv.y,nv.z);
}
//4th
vertex
glVertex3f(v2.x,v2.y,v2.z);
glEnd();
}
}
}
/************************************************************************
This
function draws the axis of X, Y, and Z
************************************************************************/
void
DrawAxis()
{
glEnable(GL_LIGHT1);
glEnable(GL_LIGHTING);
glBegin(GL_LINES);
glColor3f(0.0,1.0,0.0);
glVertex3f(-20.0,0.0,0.0); /*draw x-axis*/
glVertex3f(20.0,0.0,0.0);
glColor3f(0.0,0.0,1.0);
glVertex3f(0.0,-20.0,0.0); /*draw y-axis*/
glVertex3f(0.0,20.0,0.0);
glColor3f(1.0,0,0);
glVertex3f(0.0,0.0,-20.0); /*draw z-axis*/
glVertex3f(0.0,0.0,20.0);
glEnd();
}
/******************************************************************/
/* Auxillary
Functions */
/******************************************************************/
void AnimateOn()
{
animate = 1;
pause = 0;
ani_num = 0;
}
void AnimateOff()
{
animate = 1;
pause = 1;
}
void Resume(void)
{
animate = 1;
pause = 0;
}
void Close(void)
{
auxQuit();
}
void StartRotate ()
{ rotate = 1;
}
void StopRotate()
{ rotate = 0;
}
void Smooth()
{
wireframe = 0;
shading = GL_SMOOTH;
}
void Flat()
{
wireframe = 0;
shading = GL_FLAT;
}
void RotateUp()
{ xrot
+= 3;
}
void RotateDown()
{ xrot
-= 3;
}
void RotateLeft()
{ yrot
-=3;
}
void RotateRight()
{ yrot
+=3;
}
void Formula1()
{
animate = 0;
formula = 0;
}
void Formula2()
{
animate = 0;
formula = 1;
}
void Faster ()
{
delaytime -= 200;
}
void Slower ()
{
delaytime += 200;
}
void Wireframe()
{
wireframe = 1;
//animate
= 0;
}
void ZoomDown()
{
if (zpos
> -120){
zpos
-= 1;
if ( incangle < 0.5)
incangle +=0.0015;
else
incangle = incangle;
}
else{
zpos
= -120;
}
}
void ZoomUp()
{
if (zpos < -30 ){
zpos += 1;
if
( incangle > 0 )
incangle -=0.0015;
else
incangle = incangle;
}
else
zpos = -30;
}
/******************************************************************
Normalize
the vectors being passed in
*******************************************************************/
Vertex
Normalize (GLfloat x,GLfloat y, GLfloat z)
{
Vertex v;
float d = sqrt ( x*x + y*y+z*z);
v.x = x/d;
v.y = y/d;
v.z=
z/d;
return v;
}
/******************************************************************
In this
function the projection transformation is defined.
Currently,
it is perspective projection. It can be orthografic
projection
as well if you use the commented glOrtho instead of
glFrustum
*******************************************************************/
void Reshape(GLsizei w, GLsizei h)
{
glMatrixMode (GL_PROJECTION);
glLoadIdentity ();
glFrustum(-2.0,2.0,-2.0,2.0,3.0,150.0);
glMatrixMode(GL_MODELVIEW);
glViewport(0, 0, w, h);
}
/******************************************************************
This
function calls Draw if there is nothing else to call
*******************************************************************/
static
void Idle(void)
{
MainDraw();
}
/******************************************************************
This is
the main function.
It
defines the display modes, the initial window position and its
size.
It also manages all the events that can be handled by your
program.
*******************************************************************/
int
main( int argc, char *argv[] )
{
auxInitDisplayMode(AUX_DOUBLE | AUX_RGB |
AUX_DIRECT);
auxInitPosition(0, 0, 800, 800);
if(auxInitWindow("Jamie's
OpenGL") == GL_FALSE) {auxQuit();}
Init();
auxExposeFunc(Reshape);
auxReshapeFunc(Reshape);
auxKeyFunc (AUX_ESCAPE, Close);
auxKeyFunc (AUX_UP,RotateUp);
auxKeyFunc (AUX_DOWN,RotateDown);
auxKeyFunc (AUX_LEFT,RotateLeft);
auxKeyFunc (AUX_RIGHT,RotateRight);
auxKeyFunc (AUX_R | AUX_r ,StartRotate);
auxKeyFunc (AUX_T | AUX_t, StopRotate);
auxKeyFunc ( AUX_W |AUX_w , Wireframe);
auxKeyFunc ( AUX_Z , ZoomUp );
auxKeyFunc ( AUX_z , ZoomDown );
auxKeyFunc (AUX_1 , Formula1);
auxKeyFunc (AUX_2 , Formula2);
auxKeyFunc (AUX_A | AUX_a , AnimateOn);
auxKeyFunc (AUX_T | AUX_t , AnimateOff);
auxKeyFunc (AUX_C | AUX_c , Resume);
auxKeyFunc ( AUX_S | AUX_s, Slower );
auxKeyFunc ( AUX_F | AUX_f, Faster );
auxKeyFunc ( AUX_P ,Smooth );
auxKeyFunc ( AUX_p ,Flat );
auxIdleFunc(Idle);
auxMainLoop(MainDraw);
return(0);
}