mirror of
https://github.com/nasa/trick.git
synced 2024-12-21 06:03:10 +00:00
488 lines
13 KiB
C
488 lines
13 KiB
C
/*
|
|
* The reflection code was in part taken from:
|
|
* http://nehe.gamedev.net : Lesson 26
|
|
* Other stuff I gathered from the OpenGL Programming Guide
|
|
* (a.k.a. the red book)
|
|
*
|
|
* Image textures were made with gimp
|
|
*
|
|
* Tested on Redhat 9.0 with Nvidia card
|
|
*/
|
|
|
|
#if ( __APPLE__ )
|
|
# include <GLUT/glut.h>
|
|
#else
|
|
# include <GL/glut.h>
|
|
#endif
|
|
|
|
#include <stdlib.h>
|
|
#include <stdio.h>
|
|
#include <math.h>
|
|
|
|
#include <unistd.h>
|
|
#include "texture.h"
|
|
|
|
#include "trick_utils/comm/include/tc.h"
|
|
|
|
void draw_dirt();
|
|
void draw_cannon() ;
|
|
void draw_ball() ;
|
|
void draw_wheel() ;
|
|
void draw_barrel_leg() ;
|
|
void move_ball();
|
|
|
|
GLUquadricObj *q_ball;
|
|
|
|
typedef struct {
|
|
double x ;
|
|
double y ;
|
|
double z ;
|
|
} Point ;
|
|
|
|
static GLuint texture_dirt ;
|
|
static GLuint texture_mars ;
|
|
static GLuint texture_granite ;
|
|
static GLfloat light_position[3] ;
|
|
static GLfloat camera[3] = { 5.0, 10, 4.0 } ;
|
|
|
|
GLfloat mat_ambient[4] = { 0.25, 0.25, 0.25, 1.0 };
|
|
GLfloat mat_diffuse[4] = { 0.4, 0.4, 0.4, 1.0 };
|
|
//GLfloat mat_specular[4] = {0.774597, 0.774597, 0.774597,1.0 };
|
|
GLfloat mat_specular[4] = {0.0, 0.0, 0.0, 1.0 };
|
|
GLfloat light_ambient[] = { 1.0, 1.0, 1.0, 1.0 };
|
|
GLfloat face_shininess[] = { 76.8 };
|
|
GLfloat fog_color[4] = { 0.0, 0.0, 0.0, 0.0 } ;
|
|
|
|
TCDevice listen_device ;
|
|
TCDevice connection ;
|
|
Point ball_position ;
|
|
|
|
int ball_spin_angle = 0;
|
|
|
|
void display(void)
|
|
{
|
|
static float angle = 0.0 ;
|
|
|
|
glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
|
|
|
|
glLoadIdentity();
|
|
|
|
gluLookAt (camera[0], camera[1], camera[2],
|
|
(GLdouble) ball_position.x, 0.0,
|
|
(GLdouble) ball_position.y,
|
|
0.0, 0.0, 1.0);
|
|
|
|
glLightfv(GL_LIGHT0, GL_POSITION, light_position);
|
|
glLightfv(GL_LIGHT0, GL_AMBIENT, light_ambient);
|
|
|
|
glColorMask(1,1,1,1);
|
|
glEnable(GL_LIGHTING);
|
|
glEnable(GL_BLEND);
|
|
|
|
draw_dirt();
|
|
|
|
glPushMatrix();
|
|
glTranslatef ( 2.0 , 0.0 , 0 );
|
|
draw_cannon();
|
|
glPopMatrix();
|
|
|
|
glPushMatrix();
|
|
glTranslatef ( ball_position.x , 0.0 , ball_position.y );
|
|
if ( ball_position.y > 1.0 ) {
|
|
angle++;
|
|
glRotatef (angle, 0.0f, 0.0f, 1.0f);
|
|
}
|
|
draw_ball() ;
|
|
glPopMatrix();
|
|
|
|
glutSwapBuffers();
|
|
}
|
|
|
|
void draw_ball() {
|
|
|
|
gluQuadricNormals(q_ball, GL_SMOOTH);
|
|
gluQuadricTexture(q_ball, GL_TRUE);
|
|
|
|
glEnable(GL_TEXTURE_2D);
|
|
glBindTexture(GL_TEXTURE_2D, texture_mars);
|
|
glEnable(GL_TEXTURE_2D);
|
|
gluSphere(q_ball, 0.5, 30, 30);
|
|
glDisable(GL_TEXTURE_2D);
|
|
}
|
|
|
|
void draw_cannon() {
|
|
|
|
|
|
GLUquadricObj *quadric;
|
|
quadric = gluNewQuadric();
|
|
|
|
gluQuadricDrawStyle(quadric, GLU_FILL);
|
|
gluQuadricTexture(quadric, GL_TRUE);
|
|
|
|
/* Wheel 1 */
|
|
glPushMatrix();
|
|
glTranslatef ( 0.0 , 1.0 , 0.0 );
|
|
draw_wheel() ;
|
|
glPopMatrix();
|
|
|
|
/* Wheel 2 */
|
|
glPushMatrix();
|
|
glTranslatef ( 0.0 , -1.0 , 0.0 );
|
|
draw_wheel() ;
|
|
glPopMatrix();
|
|
|
|
glEnable(GL_TEXTURE_2D);
|
|
glBindTexture(GL_TEXTURE_2D, texture_granite);
|
|
|
|
/* Barrel sits on this thing */
|
|
glPushMatrix();
|
|
glRotatef (90, 1.0, 0.0, 0.0);
|
|
glTranslatef ( -3.0 , 0.0 , -0.6 );
|
|
draw_barrel_leg() ;
|
|
glPopMatrix();
|
|
|
|
glPushMatrix();
|
|
glRotatef (90, 1.0, 0.0, 0.0);
|
|
glTranslatef ( -3.0 , 0.0 , 0.6 );
|
|
draw_barrel_leg() ;
|
|
glPopMatrix();
|
|
|
|
/* Axle */
|
|
glPushMatrix();
|
|
glRotatef (90, 1.0, 0.0, 0.0);
|
|
glTranslatef ( 0.0 , 1.0 , 0.0 );
|
|
glTranslatef ( 0.0 , 0.0 , -1.0 );
|
|
gluCylinder(quadric, 0.25, 0.25, 2.00, 30, 30);
|
|
glPopMatrix();
|
|
|
|
/* Barrel */
|
|
glEnable(GL_TEXTURE_2D);
|
|
glBindTexture(GL_TEXTURE_2D, texture_granite);
|
|
glPushMatrix();
|
|
glTranslatef ( -2.0 , 0.0 , 0.0 );
|
|
glTranslatef ( 0.0 , 0.0 , 1.0 );
|
|
glRotatef ((GLfloat) 60.0, 0.0, 1.0, 0.0);
|
|
gluCylinder(quadric, 0.5, 0.5, 3.00, 30, 30);
|
|
gluSphere(quadric, 0.52 , 30, 30);
|
|
glPopMatrix();
|
|
glDisable(GL_TEXTURE_2D);
|
|
|
|
gluDeleteQuadric(quadric);
|
|
}
|
|
|
|
void draw_barrel_leg() {
|
|
|
|
GLUquadricObj *quadric;
|
|
quadric = gluNewQuadric();
|
|
|
|
GLfloat a[3] = { 0.0, 0.0, 0.0 } ;
|
|
GLfloat b[3] = { 0.0, 0.5, 0.0 } ;
|
|
GLfloat c[3] = { 4.0, 1.75, 0.0 } ;
|
|
GLfloat d[3] = { 4.0, 1.0, 0.0 } ;
|
|
GLfloat e[3] = { 1.0, 0.0, 0.0 } ;
|
|
|
|
GLfloat a1[3] = { 0.0, 0.0, 0.2 } ;
|
|
GLfloat b1[3] = { 0.0, 0.5, 0.2 } ;
|
|
GLfloat c1[3] = { 4.0, 1.75, 0.2 } ;
|
|
GLfloat d1[3] = { 4.0, 1.0, 0.2 } ;
|
|
GLfloat e1[3] = { 1.0, 0.0, 0.2 } ;
|
|
|
|
GLfloat n0[3] = { 0.0, 0.0, -1.0 } ;
|
|
GLfloat n1[3] = { 0.0, 0.0, 1.0 } ;
|
|
GLfloat n2[3] = { 0.0, -1.0, 0.0 } ;
|
|
GLfloat n3[3] = { 0.0, 1.0, 0.0 } ;
|
|
GLfloat n4[3] = { 1.0, 0.0, 0.0 } ;
|
|
GLfloat n5[3] = { 0.0, -1.0, 0.0 } ;
|
|
GLfloat n6[3] = { 0.0, -1.0, 1.0 } ;
|
|
|
|
|
|
glBegin(GL_POLYGON) ;
|
|
glNormal3fv( n0 ) ;
|
|
glTexCoord2f(0.0, 0.0);
|
|
glTexCoord2f(0.0, 10.0);
|
|
glTexCoord2f(10.0, 10.0);
|
|
glTexCoord2f(10.0, 0.0);
|
|
glVertex3fv( a ) ;
|
|
glVertex3fv( b ) ;
|
|
glVertex3fv( c ) ;
|
|
glVertex3fv( d ) ;
|
|
glVertex3fv( e ) ;
|
|
glEnd();
|
|
|
|
glBegin(GL_POLYGON) ;
|
|
glNormal3fv( n1 ) ;
|
|
glVertex3fv( a1 ) ;
|
|
glVertex3fv( b1 ) ;
|
|
glVertex3fv( c1 ) ;
|
|
glVertex3fv( d1 ) ;
|
|
glVertex3fv( e1 ) ;
|
|
glEnd();
|
|
|
|
glBegin(GL_POLYGON) ;
|
|
glNormal3fv( n2 ) ;
|
|
glVertex3fv( a ) ;
|
|
glVertex3fv( b ) ;
|
|
glVertex3fv( b1 ) ;
|
|
glVertex3fv( a1 ) ;
|
|
glEnd();
|
|
|
|
glBegin(GL_POLYGON) ;
|
|
glNormal3fv( n3 ) ;
|
|
glVertex3fv( d ) ;
|
|
glVertex3fv( c ) ;
|
|
glVertex3fv( c1 ) ;
|
|
glVertex3fv( d1 ) ;
|
|
glEnd();
|
|
|
|
glBegin(GL_POLYGON) ;
|
|
glNormal3fv( n4 ) ;
|
|
glVertex3fv( b ) ;
|
|
glVertex3fv( b1 ) ;
|
|
glVertex3fv( c1 ) ;
|
|
glVertex3fv( c ) ;
|
|
glEnd();
|
|
|
|
glBegin(GL_POLYGON) ;
|
|
glNormal3fv( n5 ) ;
|
|
glVertex3fv( e ) ;
|
|
glVertex3fv( a ) ;
|
|
glVertex3fv( a1 ) ;
|
|
glVertex3fv( e1 ) ;
|
|
glEnd();
|
|
|
|
glBegin(GL_POLYGON) ;
|
|
glNormal3fv( n6 ) ;
|
|
glVertex3fv( d ) ;
|
|
glVertex3fv( e ) ;
|
|
glVertex3fv( e1 ) ;
|
|
glVertex3fv( d1 ) ;
|
|
glEnd();
|
|
|
|
}
|
|
|
|
void draw_wheel() {
|
|
|
|
int ii ;
|
|
int angle ;
|
|
|
|
GLUquadricObj *quadric;
|
|
|
|
quadric = gluNewQuadric();
|
|
gluQuadricDrawStyle(quadric, GLU_FILL);
|
|
gluQuadricTexture(quadric, GL_TRUE);
|
|
|
|
/* Spokes */
|
|
angle = 0 ;
|
|
for ( ii = 0 ; ii < 14 ; ii++ ) {
|
|
|
|
glEnable(GL_TEXTURE_2D);
|
|
glBindTexture(GL_TEXTURE_2D, texture_granite);
|
|
glPushMatrix();
|
|
glTranslatef ( 0.0 , 0.0 , 1.0 );
|
|
glRotatef ((GLfloat) angle, 0.0, 1.0, 0.0);
|
|
gluCylinder(quadric, 0.05, 0.05, 1.0, 10, 10);
|
|
glPopMatrix();
|
|
glDisable(GL_TEXTURE_2D);
|
|
|
|
angle += 25 ;
|
|
}
|
|
|
|
/*
|
|
* Tire and cap
|
|
*/
|
|
glEnable(GL_TEXTURE_2D);
|
|
glBindTexture(GL_TEXTURE_2D, texture_granite);
|
|
|
|
glPushMatrix();
|
|
glTranslatef ( 0.0 , 0.0 , 1.0 );
|
|
glRotatef ((GLfloat) 90, 0.0, 1.0, 0.0);
|
|
glRotatef ((GLfloat) 90, 1.0, 0.0, 0.0);
|
|
|
|
glTranslatef ( 0.0 , 0.0 , 0.1 );
|
|
gluDisk(quadric, 1.0, 1.05, 30, 30); /* Tire side */
|
|
gluDisk(quadric, 0.00, 0.25, 30, 30); /* Cap side */
|
|
|
|
glTranslatef ( 0.0 , 0.0 , -0.2 );
|
|
gluDisk(quadric, 1.0, 1.05, 30, 30); /* Tire side */
|
|
gluDisk(quadric, 0.00, 0.25, 30, 30); /* Cap side */
|
|
|
|
gluCylinder(quadric, 1.0, 1.0, 0.2, 30, 30); /* Inner Tire */
|
|
gluCylinder(quadric, 1.05, 1.05, 0.2, 30, 30); /* Tire tread */
|
|
gluCylinder(quadric, 0.25, 0.25, 0.2, 30, 30); /* Cap */
|
|
|
|
glPopMatrix();
|
|
glDisable(GL_TEXTURE_2D);
|
|
|
|
gluDeleteQuadric(quadric);
|
|
|
|
}
|
|
void draw_dirt() {
|
|
|
|
glPolygonMode(GL_FRONT, GL_FILL );
|
|
glEnable(GL_POLYGON_SMOOTH);
|
|
glEnable(GL_TEXTURE_2D);
|
|
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL);
|
|
glBindTexture(GL_TEXTURE_2D, texture_dirt);
|
|
glBegin(GL_POLYGON);
|
|
glMaterialfv(GL_FRONT, GL_AMBIENT, mat_ambient);
|
|
glMaterialfv(GL_FRONT, GL_DIFFUSE, mat_diffuse);
|
|
glMaterialfv(GL_FRONT, GL_SPECULAR, mat_specular);
|
|
glMaterialfv(GL_FRONT, GL_SHININESS, face_shininess);
|
|
glNormal3f( 0.0, 0.0, 1.0 ) ;
|
|
glTexCoord2f(0.0, 0.0) ; glVertex3f( -500.0, 500.0, -0.5 ) ;
|
|
glTexCoord2f(250.0, 0.0) ; glVertex3f( 500.0, 500.0, -0.5 ) ;
|
|
glTexCoord2f(250.0, 250.0) ; glVertex3f( 500.0, -500.0, -0.5 ) ;
|
|
glTexCoord2f(0.0, 250.0) ; glVertex3f( -500.0, -500.0, -0.5 ) ;
|
|
glEnd();
|
|
glDisable(GL_TEXTURE_2D);
|
|
}
|
|
|
|
void reshape (int w, int h)
|
|
{
|
|
glViewport (0, 0, (GLsizei) w, (GLsizei) h);
|
|
glMatrixMode (GL_PROJECTION);
|
|
glLoadIdentity ();
|
|
gluPerspective(60.0, (GLfloat) w/(GLfloat) h, 1.0, 500.0);
|
|
glMatrixMode(GL_MODELVIEW);
|
|
glLoadIdentity();
|
|
gluLookAt (camera[0], camera[1], camera[2], 0.0, 0.0, 0.0, 0.0, 1.0, 0.0);
|
|
}
|
|
|
|
void move_ball() {
|
|
int nbytes ;
|
|
|
|
if ( tc_isValid(&connection) && tc_pending(&connection) ) {
|
|
|
|
nbytes = tc_read(&connection, (char*) &ball_position.x,
|
|
sizeof(double));
|
|
nbytes = tc_read(&connection, (char*) &ball_position.y,
|
|
sizeof(double));
|
|
}
|
|
|
|
glutPostRedisplay();
|
|
}
|
|
|
|
void glInit() {
|
|
|
|
/* Init glut */
|
|
glutInitDisplayMode (GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
|
|
glutInitWindowSize (500, 500);
|
|
glutInitWindowPosition (100, 100);
|
|
glutCreateWindow ("Trick Cannon");
|
|
|
|
/* Textures */
|
|
texture_dirt = LoadBitmap("images/dirt.bmp");
|
|
texture_mars = LoadBitmap("images/MarsMap.bmp");
|
|
texture_granite = LoadBitmap("images/granite.bmp");
|
|
|
|
/* Quadric for ball */
|
|
q_ball = gluNewQuadric();
|
|
|
|
//glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL);
|
|
glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP);
|
|
glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP);
|
|
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
|
|
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
|
|
|
|
// Here is the light/shading init
|
|
light_position[0] = 4.0 ;
|
|
light_position[1] = 0.0 ;
|
|
light_position[2] = 0.0 ;
|
|
light_position[3] = 1.0 ;
|
|
GLfloat light_ambient[] = { 0.0, 0.0, 0.0, 1.0 };
|
|
|
|
glClearColor (0.0, 0.0, 0.0, 1.0);
|
|
glShadeModel (GL_SMOOTH);
|
|
|
|
glLightfv(GL_LIGHT0, GL_POSITION, light_position);
|
|
glLightfv(GL_LIGHT0, GL_AMBIENT, light_ambient);
|
|
|
|
glEnable(GL_LIGHTING);
|
|
glEnable(GL_LIGHT0);
|
|
glEnable(GL_DEPTH_TEST);
|
|
|
|
glDepthFunc(GL_LEQUAL);
|
|
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
|
|
|
|
// Fog
|
|
glEnable(GL_FOG);
|
|
glFogi(GL_FOG_MODE, GL_EXP2) ;
|
|
glFogfv(GL_FOG_COLOR, fog_color);
|
|
glFogf(GL_FOG_DENSITY, 0.005) ;
|
|
glFogf(GL_FOG_START, 10.0);
|
|
glFogf(GL_FOG_END, 10.0);
|
|
|
|
// Add specular effect -after- texturing calculations
|
|
glLightModeli(GL_LIGHT_MODEL_COLOR_CONTROL,
|
|
GL_SEPARATE_SPECULAR_COLOR);
|
|
|
|
/* Call backs */
|
|
glutDisplayFunc(display);
|
|
glutReshapeFunc(reshape);
|
|
}
|
|
|
|
void keyboard(unsigned char key, int x, int y) {
|
|
|
|
switch (key) {
|
|
case 'u':
|
|
camera[0] -= 0.5 ;
|
|
break;
|
|
case 'i':
|
|
camera[0] += 0.5 ;
|
|
break;
|
|
case 'j':
|
|
camera[1] -= 0.5 ;
|
|
break;
|
|
case 'k':
|
|
camera[1] += 0.5 ;
|
|
break;
|
|
case 'n':
|
|
camera[2] -= 0.5 ;
|
|
break;
|
|
case 'm':
|
|
camera[2] += 0.5 ;
|
|
break;
|
|
case 'x':
|
|
light_position[0] -= 0.5 ;
|
|
break;
|
|
case 'y':
|
|
light_position[1] -= 0.5 ;
|
|
break;
|
|
case 'z':
|
|
light_position[2] -= 0.5 ;
|
|
break;
|
|
case 'X':
|
|
light_position[0] += 0.5 ;
|
|
break;
|
|
case 'Y':
|
|
light_position[1] += 0.5 ;
|
|
break;
|
|
case 'Z':
|
|
light_position[2] += 0.5 ;
|
|
break;
|
|
}
|
|
}
|
|
|
|
void trickCommInit( ) {
|
|
|
|
memset(&listen_device, '\0', sizeof(TCDevice));
|
|
memset(&connection, '\0', sizeof(TCDevice));
|
|
|
|
listen_device.port = 9000 ;
|
|
connection.blockio_type = TC_COMM_NOBLOCKIO ;
|
|
tc_init(&listen_device) ;
|
|
tc_accept(&listen_device, &connection);
|
|
}
|
|
|
|
|
|
int main(int argc, char** argv)
|
|
{
|
|
glutInit(&argc, argv);
|
|
glInit();
|
|
trickCommInit();
|
|
glutIdleFunc(move_ball);
|
|
glutKeyboardFunc(keyboard);
|
|
glutMainLoop();
|
|
return 0;
|
|
}
|