#include"glut.h"
#include"math.h"
#define RADIUS 500
#define PI 3.141592654f
#define R 10.0f
#define Y_GROUND -3.0f
#define F_EXTENT 70.0f
#define F_STEP 5.0f
GLfloat Rot = 0.0f;
GLint mx = 0 , my = 0;
GLint mz = -RADIUS;
GLfloat keyStep = 0.5f;
GLfloat lightPos[] = { -20 , 30 , -10 , 1 };
GLfloat spotDir[] = { 50 , -200 , 50 };
GLfloat specular[] = { 1 , 1 , 1 , 1 };
GLfloat specref[] = { 1 , 1 , 1 , 1 };
GLfloat ambientLight[] = { 0.5 , 0.5 , 0.5 , 1 };
//void MyTimer( int value )
//{
// if( abs(Rot) >= 60 )
// step *= -1;
// Rot += step;
// glutPostRedisplay();
// glutTimerFunc( 100 , MyTimer , 0 );
//}
void init()
{
glEnable( GL_DEPTH_TEST );
glEnable( GL_BLEND );
/*glFrontFace( GL_CCW );
glEnable( GL_CULL_FACE );*/
glEnable( GL_LIGHTING );
glLightModelfv( GL_LIGHT_MODEL_AMBIENT , ambientLight );//定义一个全局光源,让所有物体都能够被看见
glLightfv( GL_LIGHT0 , GL_DIFFUSE , ambientLight );
glLightfv( GL_LIGHT0 , GL_SPECULAR , specular );
glLightfv( GL_LIGHT0 , GL_POSITION , lightPos );
//glLightfv( GL_LIGHT0 , GL_SPOT_DIRECTION , spotDir );
//glLightf( GL_LIGHT0 , GL_SPOT_CUTOFF , 90.0f );//光源点的cutoff角
glEnable( GL_LIGHT0 );
glEnable( GL_COLOR_MATERIAL );
glColorMaterial( GL_FRONT , GL_AMBIENT_AND_DIFFUSE );
glMaterialfv( GL_FRONT , GL_SPECULAR , specular );
glMateriali( GL_FRONT , GL_SHININESS , 180 );
glClearColor( 0.0f , 0.0f , 0.0f , 0.0f );
}
void DrawGround()
{
GLint iLine;
glColor4f( 0.5 , 0.5 , 0.5 , 0.6 );
glPolygonMode( GL_FRONT_AND_BACK , GL_FILL );
glBegin( GL_QUADS );
glVertex3f( -F_EXTENT , Y_GROUND-0.05 , -F_EXTENT );
glVertex3f( -F_EXTENT , Y_GROUND-0.05 , F_EXTENT );
glVertex3f( F_EXTENT , Y_GROUND-0.05 , F_EXTENT );
glVertex3f( F_EXTENT , Y_GROUND-0.05 , -F_EXTENT );
glEnd();
glColor4f( 1.0 , 1.0 , 1.0 , 0.6 );
glPolygonMode( GL_FRONT_AND_BACK , GL_LINE );
glBegin( GL_LINES );
for( iLine = -F_EXTENT; iLine <= F_EXTENT; iLine += F_STEP )
{
glVertex3f( iLine , Y_GROUND , F_EXTENT );
glVertex3f( iLine , Y_GROUND , -F_EXTENT );
glVertex3f( F_EXTENT , Y_GROUND , iLine );
glVertex3f( -F_EXTENT , Y_GROUND , iLine );
}//for
glEnd();
}
void Display()
{
GLfloat x1 , y1 , x2 , y2 , z , r , angle;
GLfloat xx1 , zz1 , xx2 , zz2;
glEnable( GL_DEPTH_TEST );
glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
//加入fog效果
GLfloat fBackColor[] = { 0.0f , 0.0f , 0.0f , 0.0f };
glEnable( GL_FOG );
glFogfv( GL_FOG_COLOR , fBackColor );
glFogf( GL_FOG_START , 5.0f );
glFogf( GL_FOG_END , 70.0f );
glFogi( GL_FOG_MODE , GL_LINEAR );
glPushMatrix();
glColor4f( 0.2 , 0.5 , 0.8 , 0.0 );
for( angle = 0; angle <= 2*PI; angle += (PI/18) )
{
glPolygonMode( GL_FRONT , GL_FILL );
glBegin( GL_TRIANGLE_STRIP );
for( z = -R; z <= R; z += 0.5 )
{
r = sqrt( R*R - z*z );
x1 = r*cos(angle);
y1 = r*sin(angle)+7;
x2 = r*cos(angle+(PI/18));
y2 = r*sin(angle+(PI/18))+7;
glVertex3f( x1 , -y1-7 , z );
glVertex3f( x2 , -y2-7 , z );
}//for
glEnd();
}//for
glDisable( GL_LIGHTING );
glEnable( GL_BLEND );
glBlendFunc( GL_SRC_ALPHA , GL_ONE_MINUS_SRC_ALPHA );
DrawGround();
glDisable( GL_BLEND );
glEnable( GL_LIGHTING );
glPopMatrix();
glPushMatrix();
//glLoadIdentity();
glLightfv( GL_LIGHT0 , GL_POSITION , lightPos );
glLightfv( GL_LIGHT0 , GL_SPOT_DIRECTION , spotDir );
glTranslatef( lightPos[0] , lightPos[1] , lightPos[2] );
glPushAttrib( GL_LIGHTING_BIT );
glDisable( GL_LIGHTING );
glColor3ub( 255 , 255 , 0 );
glPolygonMode( GL_FRONT , GL_FILL );
glutSolidSphere( 3.0f , 15 , 15 );
glPopAttrib();
glPopMatrix();
//glPolygonMode( GL_FRONT , GL_FILL );
for( angle = 0; angle <= 2*PI; angle += (PI/18) )
{
glPolygonMode( GL_FRONT , GL_FILL );
glColor3f( 0.2 , 0.5 , 0.8 );
glBegin( GL_TRIANGLE_STRIP );
for( z = -R; z <= R; z += 0.5 )
{
r = sqrt( R*R - z*z );
x1 = r*cos(angle);
y1 = r*sin(angle)+7;
x2 = r*cos(angle+(PI/18));
y2 = r*sin(angle+(PI/18))+7;
glVertex3f( x1 , y1 , z );
glVertex3f( x2 , y2 , z );
}//for
glEnd();
//画影子
glColor3f( 0.0 , 0.0 , 0.0 );
glDisable( GL_LIGHTING );
glBegin( GL_TRIANGLE_STRIP );
for( z = -R; z <= R; z += 0.5 )
{
r = sqrt( R*R - z*z );
x1 = r*cos(angle);
y1 = r*sin(angle)+7;
x2 = r*cos(angle+(PI/18));
y2 = r*sin(angle+(PI/18))+7;
xx1 = ( (x1-lightPos[0])/(y1-lightPos[1]) ) * ( Y_GROUND-lightPos[1] ) + x1;
zz1 = ( (z-lightPos[0])/(y1-lightPos[1]) ) * ( Y_GROUND-lightPos[1] ) + z;
xx2 = ( (x2-lightPos[0])/(y2-lightPos[1]) ) * ( Y_GROUND-lightPos[1] ) + x2;
zz2 = ( (z-lightPos[0])/(y2-lightPos[1]) ) * ( Y_GROUND-lightPos[1] ) + z;
glVertex3f( xx1 , Y_GROUND , zz1 );
glVertex3f( xx2 , Y_GROUND , zz2 );
}//for
glEnd();
glEnable( GL_LIGHTING );
}//for
/*glBegin( GL_POINTS );*/
//GLfloat i , j , k;
//for( i=0; i<255; i+=3 )
// for( j=0; j<255; j+=3 )
// for( k=0; k<255; k+=3 )
// {
// glColor3ub( i , j , k );
// glVertex3f( i/50 , j/50 , k/50-10 );
// }//for
/*glEnd();*/
glutSwapBuffers();
}
void Resize( int w , int h )
{
GLfloat fAspect;
if( 0 == h ) h = 1;
glViewport( 0 , 0 , w ,h );
fAspect = (GLfloat)w / (GLfloat)h;
glMatrixMode( GL_PROJECTION );
glLoadIdentity();
gluPerspective( 60.0f , fAspect , 1.0 , 400.0 );
glMatrixMode( GL_MODELVIEW );
glLoadIdentity();
glTranslatef( 0 , 0 , -30 );
::glutPostRedisplay();
}
void Key( unsigned char k , int x , int y )
{
GLfloat lastMatrix[ 16 ];
glMatrixMode( GL_MODELVIEW );
glGetFloatv( GL_MODELVIEW_MATRIX , lastMatrix );
glLoadIdentity();
switch( k )
{
case 'w':
glTranslatef( 0.0f , 0.0f , keyStep );
break;
case 'a':
glTranslatef( keyStep , 0.0f , 0.0f );
break;
case 's':
glTranslatef( 0.0f , 0.0f , -keyStep );
break;
case 'd':
glTranslatef( -keyStep , 0.0f , 0.0f );
break;
default:
break;
}//switch
glMultMatrixf( lastMatrix );
glutPostRedisplay();
}
void Motion( int x , int y )
{
GLfloat lastMatrix[ 16 ];
glMatrixMode(GL_MODELVIEW);
glGetFloatv(GL_MODELVIEW_MATRIX,lastMatrix);
glLoadIdentity();
glRotatef( (GLfloat)(y-my)/10 , 1.0f , 0.0f , 0.0f );
glRotatef( (GLfloat)(x-mx) , 0.0f , 1.0f , 0.0f );
glMultMatrixf(lastMatrix);
glutPostRedisplay();
mx = x;
my = y;
}
void Mouse( int button , int state , int x , int y )
{
if( GLUT_LEFT_BUTTON == button )
{
if( GLUT_DOWN == state )
{
mx = x;
my = y;
}//if
}//if
}
int main( int argc , char** argv )
{
glutInit( &argc , argv );
glutInitDisplayMode( GLUT_DOUBLE | GLUT_RGBA | GLUT_DEPTH | GLUT_MULTISAMPLE );
glutInitWindowSize( 800 , 600 );
glutInitWindowPosition( 200 , 100 );
glutCreateWindow( "Tom" );
init();
glutDisplayFunc( Display );
glutReshapeFunc( Resize );
glutKeyboardFunc( Key );
glutMotionFunc( Motion );
glutMouseFunc( Mouse );
//glutTimerFunc( 100 , MyTimer , 0 );
glutMainLoop();
return 0;
}