#include <windows.h>
#include <stdio.h>
#include <gl\gl.h>
#include <gl\glu.h>
#include <gl\glaux.h>
#include <math.h>
#include <time.h>
#include "MilkshapeModel.h" // Header File For Milkshape File
HDC hDC=NULL;
HGLRC hRC=NULL;
HWND hWnd=NULL;
HINSTANCE hInstance;
typedef struct {
int frame;
float xc;
float yc;
float zc;
float anc;
int gira;
int vel;
float Iox;
float Ioy;
float Ioz;
int cameratype;
} VAR;
VAR var; // Global Variables
bool keys[256];
bool active=TRUE;
bool fullscreen=TRUE;
Model *Auto = NULL; // Auto Model
Model *Ruota = NULL; // Wheel Model
GLuint texture[3];
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
// **********************************************************************VARIABLES
typedef struct
{
double x;
double y;
double z;
} Vector;
typedef struct // Car structure
{
// Car
float x;
float y;
float z;
float any;
float dany;
float velocita;
float vf;
float dvf;
// Ruote
float xruote[4];
float yruote[4];
float zruote[4];
float anruote;
float gira;
} CAR;
CAR car;
typedef struct // Smoke Structure
{
float x;
float y;
float z;
float dx;
float dy;
float dz;
float dim;
float ddim;
} PUF;
#define MAXSMOKE 64
PUF smoke[MAXSMOKE]; // Smoke Array
#define DIMX 64
#define DIMZ 64
#define SIZE 32
Vector Buf[DIMX][DIMZ]; // Terrain
// **********************************************************************MY FUNCTIONS
double VectorLength( Vector v )
{
return sqrt(v.x * v.x + v.y * v.y + v.z * v.z);
}
//-------------------------------------------------------------------
Vector VectorNormalize( Vector v )
{
Vector vresult;
double l = VectorLength( v );
vresult.x = v.x/l;
vresult.y = v.y/l;
vresult.z = v.z/l;
return vresult;
}
//-------------------------------------------------------------------
Vector VectorMultiply( Vector v1, Vector v2 )
{
Vector vresult;
vresult.x = v1.y * v2.z - v1.z * v2.y;
vresult.y = v1.z * v2.x - v1.x * v2.z;
vresult.z = v1.x * v2.y - v1.y * v2.x;
return vresult;
}
//-------------------------------------------------------------------
Vector VectorScalarMultiply( Vector v, double s )
{
Vector vresult;
vresult.x = v.x * s;
vresult.y = v.y * s;
vresult.z = v.z * s;
return vresult;
}
//-------------------------------------------------------------------
Vector VectorDiff( Vector v1, Vector v2 )
{
Vector vresult;
vresult.x = v1.x - v2.x;
vresult.y = v1.y - v2.y;
vresult.z = v1.z - v2.z;
return vresult;
}
void Luce(double x, double y, double z,double dimensione,float r,float g,float b,float iox,float ioy,float ioz,int Tex)
{
Vector Position;
Vector MyPosition;
Position.x = x;
Position.y = y;
Position.z = z;
MyPosition.x=iox;
MyPosition.y=ioy;
MyPosition.z=ioz;
Vector sight = VectorDiff(MyPosition, Position);
Vector cz;
cz.x = 0;
cz.y = 0;
cz.z = 1;
Vector cross1 = VectorMultiply( sight, cz );
Vector cross2 = VectorMultiply( sight, cross1 );
cross1 = VectorNormalize(cross1);
cross2 = VectorNormalize(cross2);
cross1 = VectorScalarMultiply(cross1, dimensione);
cross2 = VectorScalarMultiply(cross2, dimensione);
glColor3f(r,g,b);
glEnable(GL_TEXTURE_2D);
glEnable (GL_BLEND);
glBlendFunc( (1,1,1,1), (1,1,1,1));
glDepthMask (GL_FALSE);
glBindTexture( GL_TEXTURE_2D, texture[Tex] );
glBegin(GL_QUADS);
glTexCoord2d( 0.0, 0.0 );
glVertex3d( Position.x + cross1.x, Position.y + cross1.y, Position.z + cross1.z);
glTexCoord2d( 1.0, 0.0 );
glVertex3d( Position.x - cross2.x, Position.y - cross2.y, Position.z - cross2.z);
glTexCoord2d( 1.0, 1.0 );
glVertex3d( Position.x - cross1.x, Position.y - cross1.y, Position.z - cross1.z);
glTexCoord2d( 0.0, 1.0 );
glVertex3d( Position.x + cross2.x, Position.y + cross2.y, Position.z + cross2.z);
glEnd();
glDisable(GL_TEXTURE_2D);
glDisable (GL_BLEND);
glDepthMask (GL_TRUE);
}
void glPrint(char *ll,float x,float y,float z,float dim,float dir,float r,float g,float b)
{
int t;
char k;
float kx,ky,fx,fy;
fx=(float)1/16;
fy=(float)1/16;
glColor3f(r,g,b);
glEnable(GL_TEXTURE_2D);
glBindTexture( GL_TEXTURE_2D, texture[0] );
glEnable (GL_BLEND);
glBlendFunc( (1,1,1,1), (1,1,1,1));
glDepthMask (GL_FALSE);
for(t=0;t<(int)strlen(ll);t++)
{
k=*(ll+t);
if(k>=32)
{
k=k-32;
kx=(float)(k%16);
kx=kx*fx;
ky=15-(float)((int)(k/16));
ky=ky*fy;
glBegin(GL_QUADS);
glTexCoord2d( kx,ky );
glVertex3f(x,y,z);
glTexCoord2d( kx+fx, ky );
glVertex3f(x+dim,y,z);
glTexCoord2d( kx+fx,ky+fy );
glVertex3f(x+dim,y+dim,z);
glTexCoord2d( kx,ky+fy );
glVertex3f(x,y+dim,z);
glEnd();
x=x+dim;
}
}
glDisable(GL_BLEND);
glDepthMask(GL_TRUE);
glDisable(GL_TEXTURE_2D);
}
void InitBuf(void) // Init Terrain
{
int x,z,t;
double xi,zi;
for(z=0;z<DIMZ;z++)
{
zi=(double)z-((double)DIMZ/2);
zi=zi*SIZE;
for(x=0;x<DIMX;x++)
{
xi=(double)x-((double)DIMX/2);
xi=xi*SIZE;
Buf[x][z].x=xi;
if(z==0 || z==DIMZ-2 || x==0 || x==DIMX-2)
Buf[x][z].y=30;
else
Buf[x][z].y=0;
Buf[x][z].z=zi;
}
}
}
void InitSmoke(void) // Init Smoke
{
int t,k=0;
float xf,yf,zf;
for(t=0;t<MAXSMOKE;t++)
{
switch(t%4) // For each Wheel
{
case 0:
xf=2.5;
yf=0.3;
zf=4.5;
break;
case 1:
xf=-2.5;
yf=0.3;
zf=4.5;
break;
case 2:
xf=2.5;
yf=0.3;
zf=-4.5;
break;
case 3:
xf=-2.5;
yf=0.3;
zf=-4.5;
break;
}
smoke[t].x=xf;
smoke[t].y=yf;
smoke[t].z=zf;
smoke[t].dim=0;
smoke[t].ddim=0.5+(float)(rand()%100)/1000;
smoke[t].dx=0;
smoke[t].dy=0.01;
smoke[t].dz=-car.velocita;
}
}
void Init(void)
{
var.frame=0; // Frame rate calculation
// Init Terrain
InitBuf();
// Init the Wheel Smoke
InitSmoke();
// Camera
var.anc=-20;
var.gira=false; // True when the car is steering
var.vel=0; // >0 if the speed car change
var.cameratype=0;
// Car and Wheel Position
car.x=0;
car.y=0.75;
car.z=0;
car.any=0;
car.dany=0;
car.velocita=10; // Initial speed
car.vf=10;
car.dvf=0;
car.xruote[0]=2.4;
car.yruote[0]=0.2;
car.zruote[0]=-5.2;
car.xruote[1]=-2.4;
car.yruote[1]=0.2;
car.zruote[1]=-5.2;
car.xruote[2]=2.4;
car.yruote[2]=0.2;
car.zruote[2]=4.3;
car.xruote[3]=-2.4;
car.yruote[3]=0.2;
car.zruote[3]=4.3;
car.anruote=0; // Wheel Angle
car.gira=0; // Angle for car turning
// Initial Camera Position
var.Iox=car.x+50*cos((car.any+(rand()%90-rand()%90))*3.141/180);
var.Ioy=(float)(1+rand()%10);
var.Ioz=car.z+50*sin((car.any+(rand()%90-rand()%90))*3.141/180);
}
void DrawBuf(void) // Draws the Ground
{
register int x,z,ptr;
register float fk=(float)1/100;
glEnable(GL_TEXTURE_2D);
glBindTexture( GL_TEXTURE_2D, texture[1] );
for(z=0;z<DIMZ-1;z++)
{
for(x=0;x<DIMX-1;x++)
{
glBegin(GL_QUADS);
glTexCoord2d( 0.0, 0.0 );
glVertex3f(Buf[x][z].x,Buf[x][z].y,Buf[x][z].z);
glTexCoord2d( 0.0, 1.0 );
glVertex3f(Buf[x][z+1].x,Buf[x][z+1].y,Buf[x][z+1].z);
glTexCoord2d( 1.0, 1.0 );
glVertex3f(Buf[x+1][z+1].x,Buf[x+1][z+1].y,Buf[x+1][z+1].z);
glTexCoord2d( 1.0, 0.0 );
glVertex3f(Buf[x+1][z].x,Buf[x+1][z].y,Buf[x+1][z].z);
glEnd();
}
}
glDisable(GL_TEXTURE_2D);
}
void DrawSmoke(void) // Draws the Smoke
{
int t;
float xf,yf,zf,kf;
for(t=0;t<MAXSMOKE;t++)
{
kf=1-smoke[t].dim;
glPushMatrix();
glTranslatef(car.x,0,car.z);
glRotatef(car.any,0,1,0);
Luce(smoke[t].x,smoke[t].y,smoke[t].z,smoke[t].dim,kf,kf,kf,var.xc,var.yc,var.zc,2);
glPopMatrix();
smoke[t].dim+=smoke[t].ddim;
if(smoke[t].dim>=1)
{
switch(t%4)
{
case 0:
xf=2.5;
yf=0.3;
zf=4.5;
break;
ca