#include <windows.h>
#include <stdio.h>
#include <gl\gl.h>
#include <gl\glu.h>
#include <gl\glut.h>
#include "tgaload.h"//pour les textures
#include <ode\ode.h>
/* gcc -o a.exe main.cpp tgaload.cpp -l glui -l glut32 -l glu32 -l opengl32 -l winmm -l gdi32 -l stdc++ -l libode -l sdl */
#define MAX_NO_TEXTURES 4
#define CUBE_TEXTURE 0
#define FCUBE_TEXTURE 1
#define MCUBE_TEXTURE 2
GLuint texture_id[MAX_NO_TEXTURES];
GLfloat LightAmbient[]= { 0.5f, 0.5f, 0.5f, 1.0f };
GLfloat LightDiffuse[]= { 1.0f, 1.0f, 1.0f, 1.0f };
GLfloat LightPosition[]= { 0.0f, 0.0f, 2.0f, 1.0f };
GLuint filter; // pour la texture
bool light; // pour la lumière
bool blend; // l'effet transparence
bool lp; // L
bool fp; // F
bool bp; // B
float xrot;
float yrot;
float xspeed; // X
float yspeed; // Y
float ratio;
float z=-5.0f; // Depth Into The Screen
GLUquadricObj *sphere;
// les fonctions qui traitent avec les ojets : dworld,dspace,dbody,dgeom,djoint,djointgroup
//return des objets IDS :
static dWorldID world; // va identifier le monde
static dSpaceID space; // l'espace
static dGeomID sol; // pour créer un sol infini
static dJointGroupID contactgroup;
// the hinge joint id
int stop = 0,
h = 640, l = 480,
LDEmouse_x = 0, // la position X du cursor sur l'ecran en pixels
LDEmouse_y = 0, // la position Y du cursor sur l'ecran en pixels
LDEmouse_X = 0, // la force sur l'axe X du mouse
LDEmouse_Y = 0; // la force sur l'axe Y du mouse
float cam_rx = 0, cam_ry = 32;
dBodyID body_cube, body_sphere;
dGeomID geom_cube, geom_sphere;
void LDEsetM(const dReal *pos,const dReal *R)
{
//Normalement LDEFloat
float local_matrix[16];
local_matrix[0] = R[0];
local_matrix[1] = R[4];
local_matrix[2] = R[8];
local_matrix[3] = 0;
local_matrix[4] = R[1];
local_matrix[5] = R[5];
local_matrix[6] = R[9];
local_matrix[7] = 0;
local_matrix[8] = R[2];
local_matrix[9] = R[6];
local_matrix[10] = R[10];
local_matrix[11] = 0;
local_matrix[12] = pos[0];
local_matrix[13] = pos[1];
local_matrix[14] = pos[2];
local_matrix[15] = 1;
glMultMatrixf(local_matrix);
}
void LoadGLTextures (void)
{
glPixelStorei ( GL_UNPACK_ALIGNMENT, 1 );
glGenTextures (3, texture_id);
image_t temp_image;
glBindTexture ( GL_TEXTURE_2D, texture_id [0] );
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_NEAREST);
tgaLoad ( "glass.tga", &temp_image, TGA_FREE | TGA_LOW_QUALITY );
glBindTexture ( GL_TEXTURE_2D, texture_id [1] );
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
tgaLoad ( "glass.tga", &temp_image, TGA_FREE | TGA_LOW_QUALITY );
glBindTexture ( GL_TEXTURE_2D, texture_id [2] );
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR_MIPMAP_NEAREST );
tgaLoad ( "glass.tga", &temp_image, TGA_FREE | TGA_LOW_QUALITY );
glBindTexture ( GL_TEXTURE_2D, texture_id [3] );
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR_MIPMAP_NEAREST );
tgaLoad ( "ball.tga", &temp_image, TGA_FREE | TGA_LOW_QUALITY );
}
void init(void)
{
LoadGLTextures();
glEnable(GL_TEXTURE_2D);
glShadeModel(GL_SMOOTH); // Enable Smooth Shading
glClearColor(0.0f, 0.0f, 0.0f, 0.5f);
glClearDepth(1.0f); // Depth Buffer Setup
glEnable(GL_DEPTH_TEST); // Enables Depth Testing
glDepthFunc(GL_LEQUAL); // The Type Of Depth Testing To Do
ShowCursor(FALSE);
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
glLightfv(GL_LIGHT1, GL_AMBIENT, LightAmbient); // Setup The Ambient Light
glLightfv(GL_LIGHT1, GL_DIFFUSE, LightDiffuse); // Setup The Diffuse Light
glLightfv(GL_LIGHT1, GL_POSITION,LightPosition); // Position The Light
glEnable(GL_LIGHT1); // Enable Light One
glColor4f(1.0f, 1.0f, 1.0f, 0.5); // Full Brightness. 50% Alpha
glBlendFunc(GL_SRC_ALPHA,GL_ONE); // Set The Blending Function For Translucency
sphere = gluNewQuadric(); // Create A New Quadratic
gluQuadricNormals(sphere, GL_SMOOTH); // Generate Smooth Normals For The Quad
gluQuadricTexture(sphere, GL_TRUE); // Enable Texture Coords For The Quad
glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP); // Set Up Sphere Mapping
glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP); // Set Up Sphere Mapping
/// on vas initialiser ODE
world = dWorldCreate(); // on crée le monde
space = dHashSpaceCreate(0); // et on crée l'espace
dWorldSetGravity (world,0.0f, 0.0f, -9.81f); // on indique la gravité
/// on vas créer nos objets ODE (le cube ,la sphere) et le sol.
sol = dCreatePlane (space,0,1,0,0); // on crée le sol => crée un plan horizontale, equation : A*x+B*y+C*z = D
//le sol est static est garde toujours les mêmes coordonées
dMass m;
// le cube
dMassSetBox (&m,1,1,1,1);
dMassAdjust(&m,0.2); // on indique la ca masse
body_cube = dBodyCreate(world); // on crée le cube dans notre monde
dBodySetMass(body_cube,&m); //
geom_cube = dCreateBox(space,1,1,1); // on crée la géométrie
dGeomSetBody(geom_cube,body_cube); // on atache la geometrie au corp
dGeomSetPosition(geom_cube,0,4,0); // on indique sa position
// la sphere
dMassSetSphere(&m,1,1);
dMassAdjust(&m,1);
body_sphere = dBodyCreate(world);
dBodySetMass(body_sphere,&m);
geom_sphere = dCreateSphere(space,1);
dGeomSetBody(geom_sphere,body_sphere);
dBodySetPosition(body_sphere,0,7,0);
//
}
static void nearCallback(void *data, dGeomID o1, dGeomID o2)
{
int i;
// exit without doing anything if the two bodies are connected by a joint
dBodyID b1 = dGeomGetBody(o1);
dBodyID b2 = dGeomGetBody(o2);
if (b1 && b2 && dAreConnected (b1,b2)) return;
/*struct dContact {
dSurfaceParameters surface;
dContactGeom geom;
dVector3 fdir1;
};*/
dContact contact[3]; // up to 3 contacts per box
for (i=0; i<3; i++)
{
contact[i].surface.mode = dContactBounce | dContactSoftCFM;
contact[i].surface.mu = 50;
contact[i].surface.soft_cfm = 0.01;
}
if ( !dGeomGetBody(o1) & !dGeomGetBody(o2)); else
if (int numc = dCollide (o1,o2,3,&contact[0].geom,sizeof(dContact)))
{
for (i=0; i<numc; i++)
{
dJointID c = dJointCreateContact (world,contactgroup,contact+i);
dJointAttach (c,b1,b2);
}
}
}
void reshape( int w, int h )
{
// Prevent a divide by zero, when window is too short
// (you cant make a window of zero width).
if(h == 0)
h = 1;
ratio = 1.0f * w / h;
// Reset the coordinate system before modifying
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
// on fais les changements ODE
dSpaceCollide(space,0,&nearCallback);
dWorldQuickStep(world,0.01); // a chaque frame,
// Set the viewport to be the entire window
glViewport(0, 0, w, h);
// Set the clipping volume
gluPerspective(80,ratio,1,200);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glTranslatef(-dGeomGetPosition(geom_cube)[0],
-dGeomGetPosition(geom_cube)[1],
-dGeomGetPosition(geom_cube)[2]);
gluLookAt(0, 0, 30,
0,0,10,
0.0f,1.0f,0.0f);
}
void grille( void )
{
glDisable(GL_TEXTURE_2D);
glDisable(GL_LIGHTING);
glPushMatrix();
float Line = -10;
int Grid;
glBegin(GL_LINES);
for(Grid = 0; Grid <= 20; Grid += 1)
{
glColor3f(0.0f,1.0f,0.0f);
glVertex3f(Line + Grid, 0, -10);
glVertex3f(Line + Grid, 0, 10);
glVertex3f(-10, 0, Line + Grid);
glVertex3f(10, 0, Line + Grid);
}
glEnd();
glPopMatrix();
glEnable(GL_TEXTURE_2D);
glEnable(GL_LIGHTING);
}
void cube( void )
{
glPushMatrix();
glBindTexture(GL_TEXTURE_2D, texture_id[filter]);
glBegin(GL_QUADS);
// Front Face
glNormal3f( 0.0f, 0.0f, 1.0f);
glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0f, -1.0f, 1.0f);
glTexCoord2f(1.0f, 0.0f); glVertex3f( 1.0f, -1.0f, 1.0f);
glTexCoord2f(1.0f, 1.0f); glVertex3f( 1.0f, 1.0f, 1.0f);
glTexCoord2f(0.0f, 1.0f); glVertex3f(-1.0f, 1.0f, 1.0f);
// Back Face
glNormal3f( 0.0f, 0.0f,-1.0f);
glTexCoord2f(1.0f, 0.0f); glVertex3f(-1.0f, -1.0f, -1.0f);
glTexCoord2f(1.0f, 1.0f); glVertex3f(-1.0f, 1.0f, -1.0f);
glTexCoord2f(0.0f, 1.0f); glVertex3f( 1.0f, 1.0f, -1.0f);
glTexCoord2f(0.0f, 0.0f); glVertex3f( 1.0f, -1.0f, -1.0f);
// Top Face
glNormal3f( 0.0f, 1.0f, 0.0f);
glTexCoord2f(0.0f, 1.0f); glVertex3f(-1.0f, 1.0f, -1.0f);
glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0f, 1.0f, 1.0f);
glTexCoord2f(1.0f, 0.0f); glVertex3f( 1.0f, 1.0f, 1.0f);
glTexCoord2f(1.0f, 1.0f); glVertex3f( 1.0f, 1.0f, -1.0f);
// Bottom Face
glNormal3f( 0.0f,-1.0f, 0.0f);
glTexCoord2f(1.0f, 1.0f); glVertex3f(-1.0f, -1.0f, -1.0f);
glTexCoord2f(0.0f, 1.0f); glVertex3f( 1.0f, -1.0f, -1.0f);
glTexCoord2f(0.0f, 0.0f); glVertex3f( 1.0f, -1.0f, 1.0f);
glTexCoord2f(1.0f, 0.0f); glVertex3f(-1.0f, -1.0f, 1.0f);
// Right face
glNormal3f( 1.0f, 0.0f, 0.0f);
glTexCoord2f(1.0f, 0.0f); glVertex3f( 1.0f, -1.0f, -1.0f);
glTexCoord2f(1.0f, 1.0f); glVertex3f( 1.0f, 1.0f, -1.0f);
glTexCoord2f(0.0f, 1.0f); glVertex3f( 1.0f, 1.0f, 1.0f);
glTexCoord2f(0.0f, 0.0f); glVertex3f( 1.0f, -1.0f, 1.0f);
// Left Face
glNormal3f(-1.0f, 0.0f, 0.0f);
glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0f, -1.0f, -1.0f);
glTexCoord2f(1.0f, 0.0f); glVertex3f(-1.0f, -1.0f, 1.0f);
glTexCoord2f(1.0f, 1.0f); glVertex3f(-1.0f, 1.0f, 1.0f);
glTexCoord2f(0.0f, 1.0f); glVertex3f(-1.0f, 1.0f, -1.0f);
glEnd();
glPopMatrix();
}
void drawsphere(GLdouble r, GLint a, GLint b)
{
glPushMatrix();
float mat_ambient[] = { 0.8, 0.5, 0.1, 1.0 };
float mat_diffuse[] = { 0.8, 0.5, 0.1, 1.0 };
glMaterialfv(GL_FRONT, GL_AMBIENT, mat_ambient);
glMaterialfv(GL_FRONT, GL_DIFFUSE, mat_diffuse);
gluQuadricOrientation(sphere, GLU_OUTSIDE);
glBindTexture(GL_TEXTURE_2D, texture_id[3]);
gluSphere(sphere,r,a,b);
glPopMatrix();
}
void cone ( void )
{
glPushMatrix();
glDisable(GL_TEXTURE_2D);
glDisable(GL_CULL_FACE);
glRotatef(-90,1,0,0);
GLUquadricObj * sphere = gluNewQuadric();
gluQuadricOrientation(sphere, GLU_OUTSIDE);
gluCylinder(sphere,1.0,0.0,1.0,50,50);
glPopMatrix();
glEnable(GL_CULL_FACE);
glEnable(GL_TEXTURE_2D);
}
void display( void )
{
glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
glLoadIdentity ( );
gluLookAt(0,2, 9,
0,2,0,
0.0f,1.0f,0.0f);
glTranslatef ( 0.0, 0.0, z );
grille();
//cube
glPushMatrix();
LDEsetM(dBodyGetPosition(body_cube),dBodyGetRotation(body_cube));
cube();
glPopMatrix();
//sphere
glPushMatrix();
LDEsetM(dBodyGetPosition(body_sphere),dBodyGetRotation(body_sphere));
drawsphere(1,30,30);
glPopMatrix();
glutSwapBuffers();
}
void keyboard ( unsigned char key, int x, int y ) // Fonction clavier
{
switch ( key ) {
case 27: // pour quitter
exit ( 0 ); //
break;
case 'f':
fp=TRUE;
filter+=1;
if (filter>2)
{
filter=0;
}
break;
case 'l':
lp=TRUE;
light=!light;
if (!light)
{
glDisable(GL_LIGHTING);
}
else
{
glEnable(GL_LIGHTING);
}
break;
case 'b':
bp=TRUE;
blend = !blend;
if(blend)
{
glEnable(GL_BLEND); // Turn Blending On
glDisable(GL_DEPTH_TEST); // Turn Depth Testing Off
}
else
{
glDisable(GL_BLEND); // Turn Blending Off
glEnable(GL_DEPTH_TEST); // Turn Depth Testing On
}
break;
default:
break;
}
}
void arrow_keys ( int a_keys, int x, int y ) // Create Special Function (required for arrow keys)
{
switch ( a_keys ) {
case GLUT_KEY_UP:
xspeed-=0.01f;
break;
case GLUT_KEY_DOWN:
xspeed+=0.01f;
break;
case GLUT_KEY_RIGHT:
yspeed+=0.01f;
break;
case GLUT_KEY_LEFT:
yspeed-=0.01f;
break;
case GLUT_KEY_F1:
glutFullScreen ();
break;
case GLUT_KEY_F2:
glutReshapeWindow ( 500, 500 );
break;
default:
break;
}
}
int main ( int argc, char** argv ) // Create Main Function For Bringing It All Together
{
glutInit ( &argc, argv ); // Erm Just Write It =)
glutInitDisplayMode ( GLUT_DEPTH | GLUT_DOUBLE | GLUT_RGBA ); // Display Mode
glutInitWindowPosition (0,0);
glutInitWindowSize ( 500, 500 ); // If glutFullScreen wasn't called this is the window size
glutCreateWindow ( "NeHe Lesson 6- Ported by Rustad" ); // Window Title (argv[0] for current directory as title)
init ();
glutFullScreen ( ); // Put Into Full Screen
glutDisplayFunc ( display ); // Matching Earlier Functions To Their Counterparts
glutReshapeFunc ( reshape );
glutKeyboardFunc ( keyboard );
glutSpecialFunc ( arrow_keys );
glutIdleFunc ( display );
glutMainLoop ( ); // Initialize The Main Loop
dSpaceDestroy (space);
dWorldDestroy (world);
dCloseODE();
return 1;
}
Partager