#include "nitrito.h"
#include <SDL/SDL_image.h>
#include <math.h>
PFNGLACTIVETEXTUREARBPROC glActiveTextureARB = NULL;
PFNGLMULTITEXCOORD2FARBPROC glMultiTexCoord2fARB = NULL;
PFNGLCLIENTACTIVETEXTUREARBPROC glClientActiveTextureARB = NULL;
PFNGLGENFRAMEBUFFERSEXTPROC glGenFramebuffersEXT = NULL;
PFNGLBINDFRAMEBUFFEREXTPROC glBindFramebufferEXT = NULL;
PFNGLFRAMEBUFFERTEXTURE2DEXTPROC glFramebufferTexture2DEXT = NULL;
PFNGLCHECKFRAMEBUFFERSTATUSEXTPROC glCheckFramebufferStatusEXT = NULL;
PFNGLBLENDCOLORPROC glBlendColor = NULL;
GLfloat negro[] = {0,0,0,0};
GLfloat blanco[] = {1,1,1,1};
GLfloat gris[] = {0.5,0.5,0.5,0.5};
GLuint texture[100];
GLuint cursor_tex;
//Size of shadow map
const int shadowMapSize=1024;
//Textures
GLuint shadow_map_texture;
GLuint shadow_map_fb;
int render_pass = 0;
int num_textures = 71;
char tex_name[71][13] =
{
{"hierba00.jpg"}, //0
{"asfalt00.jpg"},
{"cielo_up.jpg"},
{"cielo_dn.jpg"},
{"cielo_lf.jpg"},
{"cielo_rt.jpg"}, //5
{"cielo_bk.jpg"},
{"cielo_ft.jpg"},
{"rueda_ba.jpg"},
{"rueda_pr.jpg"},
{"furgohpp.jpg"}, //10
{"asfalt01.jpg"},
{"asfalt02.jpg"},
{"asfalt03.jpg"},
{"asfalt04.jpg"},
{"curvdr00.jpg"}, //15
{"curvdr01.jpg"},
{"curvdr02.jpg"},
{"curvdr03.jpg"},
{"curvdl00.jpg"},
{"curvdl01.jpg"}, //20
{"curvdl02.jpg"},
{"curvdl03.jpg"},
{"curvur00.jpg"},
{"curvur01.jpg"},
{"curvur02.jpg"}, //25
{"curvur03.jpg"},
{"curvul00.jpg"},
{"curvul01.jpg"},
{"curvul02.jpg"},
{"curvul03.jpg"}, //30
{"cemwall0.jpg"},
{"cemwall1.jpg"},
{"fondmenu.jpg"},
{"hierba01.jpg"},
{"hierba02.jpg"}, //35
{"hierba03.jpg"},
{"hierba04.jpg"},
{"techo_00.jpg"},
{"jaspa_00.jpg"},
{"madera00.jpg"}, //40
{"cruce_00.jpg"},
{"cruce_01.jpg"},
{"cruce_02.jpg"},
{"cruce_03.jpg"},
{"noche_up.jpg"}, //45
{"noche_dn.jpg"},
{"noche_lf.jpg"},
{"noche_rt.jpg"},
{"noche_bk.jpg"},
{"noche_ft.jpg"}, //50
{"pelota00.jpg"},
{"brick_00.jpg"},
{"brick_01.jpg"},
{"brick_02.jpg"},
{"brick_03.jpg"}, //55
{"brick_04.jpg"},
{"brick_05.jpg"},
{"brick_06.jpg"},
{"asfalt06.jpg"},
{"asfalt05.jpg"}, //60
{"bandera0.jpg"},
{"bandera1.jpg"},
{"madera01.jpg"},
{"cajatex0.jpg"},
{"hierba05.jpg"}, //65
{"valla_00.png"},
{"asfalt07.jpg"},
{"asfalt08.jpg"},
{"asfalt09.jpg"},
{"asfalt10.jpg"} //70
//{"hierba00.jpg"}
};
bool resize_texture(SDL_Surface *image,float factor)
{
int new_w = (int)(image->w*factor);
int new_h = (int)(image->h*factor);
if(new_w <= 64 || new_h <=64) return false;
unsigned char* scaled_data = new unsigned char[new_h * new_w * 4];
if(image->format->BitsPerPixel == 32)
{
if (gluScaleImage(GL_RGBA, image->w, image->h, GL_UNSIGNED_BYTE, image->pixels, new_w, new_h, GL_UNSIGNED_BYTE, scaled_data) != 0)
{
delete[] scaled_data;
return false;
}
}
else
{
if (gluScaleImage(GL_RGB, image->w, image->h, GL_UNSIGNED_BYTE, image->pixels, new_w, new_h, GL_UNSIGNED_BYTE, scaled_data) != 0)
{
delete[] scaled_data;
return false;
}
}
//printf("%dx%d -> %dx%d\n",image->w,image->h,new_w,new_h);
//delete image->pixels;
image->pixels = scaled_data;
image->w = new_w;
image->h = new_h;
return true;
}
SDL_Surface* mirror_surface(const SDL_Surface* const psurface)
{
SDL_Surface* psNew = NULL;
int h, iBytesPerRow;
char* pPixelDest;
char* pPixelSrc;
if (SDL_MUSTLOCK( psurface ))
SDL_LockSurface( const_cast<SDL_Surface*>(psurface) );
psNew = SDL_CreateRGBSurface(
SDL_SWSURFACE,
psurface->w,
psurface->h,
psurface->format->BitsPerPixel,
psurface->format->Rmask,
psurface->format->Gmask,
psurface->format->Bmask,
psurface->format->Amask );
SDL_LockSurface( psNew );
iBytesPerRow = psurface->w * psurface->format->BytesPerPixel;
pPixelDest = (char*)psNew->pixels;
pPixelSrc = (char*)psurface->pixels + ((psurface->h-1) * iBytesPerRow);
for ( h = psurface->h-1; h >= 0; h-- )
{
memcpy( pPixelDest, pPixelSrc, iBytesPerRow );
pPixelDest += iBytesPerRow;
pPixelSrc -= iBytesPerRow;
}
SDL_UnlockSurface( psNew );
if (SDL_MUSTLOCK( psurface ))
SDL_UnlockSurface( const_cast<SDL_Surface*>(psurface) );
return psNew;
}
int load_texture_2(GLuint &tex,const char *filename)
{
/* Status indicator */
int Status = FALSE;
bool alpha = 0;
// estructura secreta de sdl para leer texturas de la memoria
SDL_RWops *rw;
SDL_Surface *TextureImage[1];
rw = SDL_RWFromZZIP(filename, "rb");
if ( (TextureImage[0] = IMG_Load_RW( rw , 0)) )
{
if(TextureImage[0]->format->BitsPerPixel == 32) alpha=1;
/* Set the status to true */
Status = TRUE;
TextureImage[0] = mirror_surface(TextureImage[0]);
//resize_texture(TextureImage[0],0.25);
/* Create The Texture */
glGenTextures( 1, &tex );
/* Typical Texture Generation Using Data From The Bitmap */
glBindTexture( GL_TEXTURE_2D, tex );
if(alpha) glTexImage2D( GL_TEXTURE_2D, 0, 4, TextureImage[0]->w,
TextureImage[0]->h, 0, GL_RGBA, GL_UNSIGNED_BYTE, TextureImage[0]->pixels );
else glTexImage2D( GL_TEXTURE_2D, 0, 3, TextureImage[0]->w,
TextureImage[0]->h, 0, GL_RGB, GL_UNSIGNED_BYTE, TextureImage[0]->pixels );
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
/* Linear Filtering */
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
}
else console.printf("Error al cargar textura. (%s).",filename);
/* Free up any memory we may have used */
if ( TextureImage[0] )
SDL_FreeSurface( TextureImage[0] );
SDL_FreeRW(rw);
return Status;
}
int load_texture(int n,const char *filename)
{
/* Status indicator */
int Status = FALSE;
bool alpha = 0;
// estructura secreta de sdl para leer texturas de la memoria
SDL_RWops *rw;
SDL_Surface *TextureImage[1];
rw = SDL_RWFromZZIP(filename, "rb");
if ( (TextureImage[0] = IMG_Load_RW( rw , 0)) )
{
if(TextureImage[0]->format->BitsPerPixel == 32) alpha=1;
//printf("%s ----- alpha = %d\n",filename,alpha);
/* Set the status to true */
Status = TRUE;
TextureImage[0] = mirror_surface(TextureImage[0]);
if(options.texture_quality == 2) resize_texture(TextureImage[0],0.5);
else if(options.texture_quality == 3) resize_texture(TextureImage[0],0.25);
/* Create The Texture */
glGenTextures( 1, &texture[n] );
/* Typical Texture Generation Using Data From The Bitmap */
glBindTexture( GL_TEXTURE_2D, texture[n] );
if((n>= 2 && n<=7) || (n>= 45 && n<=50))
{
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
}
if(options.mipmaps==TRUE)// && n!=66)
{
if(alpha) gluBuild2DMipmaps(GL_TEXTURE_2D, GL_RGBA, TextureImage[0]->w,
TextureImage[0]->h, GL_RGBA, GL_UNSIGNED_BYTE, TextureImage[0]->pixels);
else gluBuild2DMipmaps(GL_TEXTURE_2D, GL_RGB, TextureImage[0]->w,
TextureImage[0]->h, GL_RGB, GL_UNSIGNED_BYTE, TextureImage[0]->pixels);
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_LINEAR );
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
}
else
{
if(alpha) glTexImage2D( GL_TEXTURE_2D, 0, 4, TextureImage[0]->w,
TextureImage[0]->h, 0, GL_RGBA, GL_UNSIGNED_BYTE, TextureImage[0]->pixels );
else glTexImage2D( GL_TEXTURE_2D, 0, 3, TextureImage[0]->w,
TextureImage[0]->h, 0, GL_RGB, GL_UNSIGNED_BYTE, TextureImage[0]->pixels );
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
//glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
}
}
else console.printf("Error al cargar textura. (%s).",filename);
/* Free up any memory we may have used */
if ( TextureImage[0] )
SDL_FreeSurface( TextureImage[0] );
SDL_FreeRW(rw);
//zzip_close(file);
return Status;
}
void load_textures()
{
int i;
for(i = 0; i<num_textures ; i++)
{
string str = add_data_path("textures/");
str.append(tex_name[i]);
load_texture(i,str.c_str());
}
load_texture_2(cursor_tex,add_data_path("textures/flecha00.png"));
if(options.shadows)
{
//Create the shadow map texture
glGenTextures(1, &shadow_map_texture);
glBindTexture(GL_TEXTURE_2D, shadow_map_texture);
glTexImage2D( GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT24, shadowMapSize, shadowMapSize, 0,
GL_DEPTH_COMPONENT, GL_UNSIGNED_BYTE, NULL);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
//Use the color as the ambient and diffuse material
glColorMaterial(GL_FRONT, GL_AMBIENT_AND_DIFFUSE);
glEnable(GL_COLOR_MATERIAL);
//White specular material color, shininess 16
glMaterialfv(GL_FRONT, GL_SPECULAR, blanco);
glMaterialf(GL_FRONT, GL_SHININESS, 16.0f);
// create fbo and attach texture to ti
glGenFramebuffersEXT (1, &shadow_map_fb);
glBindFramebufferEXT (GL_FRAMEBUFFER_EXT, shadow_map_fb);
glFramebufferTexture2DEXT (GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_TEXTURE_2D, shadow_map_texture, 0);
glDrawBuffer (GL_FALSE);
glReadBuffer (GL_FALSE);
// verify all is well and restore state
GLenum status = glCheckFramebufferStatusEXT (GL_FRAMEBUFFER_EXT);
switch (status)
{
case GL_FRAMEBUFFER_COMPLETE_EXT:
console.printf("FBO no problemo");
break;
case GL_FRAMEBUFFER_UNSUPPORTED_EXT:
console.printf("FBO configuracion no soportada");
default:
console.printf("Desactivando sombras.");
options.shadows=0;
}
glBindFramebufferEXT (GL_FRAMEBUFFER_EXT, 0);
}
}
void setTransform (const float pos[3], const float R[12])
{
GLfloat matrix[16];
matrix[0]=R[0];
matrix[1]=R[4];
matrix[2]=R[8];
matrix[3]=0;
matrix[4]=R[1];
matrix[5]=R[5];
matrix[6]=R[9];
matrix[7]=0;
matrix[8]=R[2];
matrix[9]=R[6];
matrix[10]=R[10];
matrix[11]=0;
matrix[12]=pos[0];
matrix[13]=pos[1];
matrix[14]=pos[2];
matrix[15]=1;
glPushMatrix();
glMultMatrixf (matrix);
}
GLvoid ReSizeGLScene(GLsizei width, GLsizei height) // Resize And Initialize The GL Window
{
if (height==0) // Prevent A Divide By Zero By
{
height=1; // Making Height Equal One
}
glViewport(0,0,width,height); // Reset The Current Viewport
glMatrixMode(GL_PROJECTION); // Select The Projection Matrix
glLoadIdentity(); // Reset The Projection Matrix
// Calculate The Aspect Ratio Of The Window
gluPerspective(45.0f,(GLfloat)width/(GLfloat)height,0.1f,options.view_far);
glMatrixMode(GL_MODELVIEW); // Select The Modelview Matrix
glLoadIdentity(); // Reset The Modelview Matrix
}
void set_opengl_ambient()
{
switch(options.weather)
{
case W_CLEAR:
{
glClearColor(0.0f,0.0f,0.0f,0.0f);
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
float ambientLight[] = { 0.5f, 0.5f, 0.5f, 0.0f };
float diffuseLight[] = { 0.7f, 0.7f, 0.7f, 0.0f };
float specularLight[] = { 0.1f, 0.1f, 0.1f, 0.0f };
float position[] = { -1.0f, 0.0f, -1.0f, 0.0f };
glLightfv(GL_LIGHT0, GL_AMBIENT, ambientLight);
glLightfv(GL_LIGHT0, GL_DIFFUSE, diffuseLight);
glLightfv(GL_LIGHT0, GL_SPECULAR, specularLight);
glLightfv(GL_LIGHT0, GL_POSITION, position);
glEnable(GL_COLOR_MATERIAL);
glColorMaterial(GL_FRONT, GL_DIFFUSE);
glDisable(GL_FOG);
}
break;
case W_FOG:
{
glClearColor(0.5f,0.5f,0.5f,0.0f);
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
float ambientLight[] = { 0.6f, 0.6f, 0.6f, 0.0f };
float diffuseLight[] = { 0.3f, 0.3f, 0.3f, 0.0f };
float specularLight[] = { 0.1f, 0.1f, 0.1f, 0.0f };
float position[] = { 0.0f, 0.0f, 1.0f, 0.0f };
glLightfv(GL_LIGHT0, GL_AMBIENT, ambientLight);
glLightfv(GL_LIGHT0, GL_DIFFUSE, diffuseLight);
glLightfv(GL_LIGHT0, GL_SPECULAR, specularLight);
glLightfv(GL_LIGHT0, GL_POSITION, position);
glEnable(GL_COLOR_MATERIAL);
glColorMaterial(GL_FRONT, GL_DIFFUSE);
GLfloat fogColor[4]= {0.5f, 0.5f, 0.5f, 0.0f}; // Fog Color
glFogi(GL_FOG_MODE, GL_EXP2); // Fog Mode
glFogfv(GL_FOG_COLOR, fogColor); // Set Fog Color
glFogf(GL_FOG_DENSITY, 0.015f); // How Dense Will The Fog Be
glHint(GL_FOG_HINT, GL_DONT_CARE); // Fog Hint Value
glFogf(GL_FOG_START, 1.0f); // Fog Start Depth
glFogf(GL_FOG_END, 2.0f); // Fog End Depth
glEnable(GL_FOG);
}
break;
case W_DENSE_FOG:
{
glClearColor(0.5f,0.5f,0.5f,0.0f);
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
float ambientLight[] = { 0.6f, 0.6f, 0.6f, 0.0f };
float diffuseLight[] = { 0.3f, 0.3f, 0.3f, 00.0f };
float specularLight[] = { 0.1f, 0.1f, 0.1f, 0.0f };
float position[] = { 0.0f, 0.0f, 1.0f, 0.0f };
glLightfv(GL_LIGHT0, GL_AMBIENT, ambientLight);
glLightfv(GL_LIGHT0, GL_DIFFUSE, diffuseLight);
glLightfv(GL_LIGHT0, GL_SPECULAR, specularLight);
glLightfv(GL_LIGHT0, GL_POSITION, position);
glEnable(GL_COLOR_MATERIAL);
glColorMaterial(GL_FRONT, GL_DIFFUSE);
GLfloat fogColor[4]= {0.5f, 0.5f, 0.5f, 0.0f}; // Fog Color
glFogi(GL_FOG_MODE, GL_EXP2); // Fog Mode
glFogfv(GL_FOG_COLOR, fogColor); // Set Fog Color
glFogf(GL_FOG_DENSITY, 0.1f); // How Dense Will The Fog Be
glHint(GL_FOG_HINT, GL_DONT_CARE); // Fog Hint Value
glFogf(GL_FOG_START, 1.0f); // Fog Start Depth
glFogf(GL_FOG_END, 2.0f); // Fog End Depth
glEnable(GL_FOG);
}
break;
case W_NIGHT:
{
glClearColor(0.0f,0.0f,0.0f,1.0f);
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
float ambientLight[] = { 0.5f, 0.4f, 0.4f, 0.0f };
float diffuseLight[] = { 0.3f, 0.3f, 0.3f, 0.0f };
float specularLight[] = { 0.1f, 0.1f, 0.1f, 0.0f };
float position[] = { 0.5f, 0.5f, 1.0f, 0.0f };
glLightfv(GL_LIGHT0, GL_AMBIENT, ambientLight);
glLightfv(GL_LIGHT0, GL_DIFFUSE, diffuseLight);
glLightfv(GL_LIGHT0, GL_SPECULAR, specularLight);
glLightfv(GL_LIGHT0, GL_POSITION, position);
glEnable(GL_COLOR_MATERIAL);
glColorMaterial(GL_FRONT, GL_DIFFUSE);
GLfloat fogColor[4]= {0.0f, 0.0f, 0.0f, 0.0f}; // Fog Color
glFogi(GL_FOG_MODE, GL_EXP2); // Fog Mode
glFogfv(GL_FOG_COLOR, fogColor); // Set Fog Color
glFogf(GL_FOG_DENSITY, 0.05f); // How Dense Will The Fog Be
glHint(GL_FOG_HINT, GL_DONT_CARE); // Fog Hint Value
glFogf(GL_FOG_START, 1.0f); // Fog Start Depth
glFogf(GL_FOG_END, 2.0f); // Fog End Depth
glEnable(GL_FOG);
}
break;
}
}
void Camera::reset ()
{
x=0;
y=0;
z=0;
h=0;
p=0;
r=0;
x2=0;
y2=0;
z2=0;
h2=0;
p2=0;
r2=0;
xs=0;
ys=0;
zs=0;
hs=0;
ps=0;
rs=0;
}
void Camera::set (float cx, float cy, float cz, float ch, float cp, float cr)
{
while(ch<-180) ch+=360;
while(ch> 180) ch-=360;
x=cx;
y=cy;
z=cz;
h=ch;
p=cp;
r=cr;
glMatrixMode (GL_MODELVIEW);
glLoadIdentity();
glRotatef (cr, 1,0,0);
glRotatef (cp, 0,1,0);
glRotatef (ch, 0,0,1);
glTranslatef (-cx,-cy,-cz);
glGetFloatv(GL_MODELVIEW_MATRIX, view_matrix);
}
void Camera::move (float cx, float cy, float cz, float ch, float cp, float cr)
{
x+=cx;
y+=cy;
z+=cz;
h+=ch;
p+=cp;
r+=cr;
set(x,y,z,h,p,r);
}
void Camera::move2 (float cx, float cy, float cz, float ch, float cp, float cr)
{
x+=(cy*sin(h/180.0*M_PI))+(cx*cos(h/180.0*M_PI));
y+=(cy*cos(h/180.0*M_PI))+(cx*-sin(h/180.0*M_PI));;
z+=cz;
h+=ch;
p+=cp;
r+=cr;
set(x,y,z,h,p,r);
}
void Camera::set_mode (int mode)
{
const dReal *m;
const dReal *pos;
m = dBodyGetRotation(coche[0].body[0]);
pos = dBodyGetPosition(coche[0].body[0]);
switch (mode)
{
case 0:
break;
case 1:
float a,b;
x2=pos[0]-m[0]*1.0;
y2=pos[1]-m[4]*1.0;
z2=pos[2]+20;
a=(x-pos[0]);
b=(y-pos[1]);
h2=-atan2(a,-b)*180/M_PI;
p2=0;
r2=0;
break;
case 2: //camara trasera muy cerca
{
float a,b;
x2=pos[0]-m[0]*2.0;
y2=pos[1]-m[4]*2.0;
z2=pos[2]+1;
a=(x-pos[0]);
b=(y-pos[1]);
h2=-atan2(a,-b)*180/M_PI;
p2=0;
r2=-90;
break;
}
case 3: //camara trasera cerca
{
float a,b;
x2=pos[0]-m[0]*5.0;
y2=pos[1]-m[4]*5.0;
z2=pos[2]+1;
a=(x-pos[0]);
b=(y-pos[1]);
h2=-atan2(a,-b)*180/M_PI;
p2=0;
r2=-90;
}
break;
case 4: //camara traera lejos
{
float a,b;
x2=pos[0]-m[0]*10.0;
y2=pos[1]-m[4]*10.0;
z2=pos[2]+2;
a=(x-pos[0]);
b=(y-pos[1]);
h2=-atan2(a,-b)*180/M_PI;
p2=0;
r2=-90;
}
break;
case 5: //camara lateral derecha
{
float a,b;
x2=pos[0]+m[4]*5.0;
y2=pos[1]-m[0]*5.0;
z2=pos[2]-0.5;
a=(x-pos[0]);
b=(y-pos[1]);
h2=-atan2(a,-b)*180/M_PI;
p2=0;
r2=-90;
}
break;
case 6: //camara TV
{
static float a,b,c,d;
if(c>30)
{
x=pos[0]+m[0]*10.0;
y=pos[1]-m[4]*10.0;
z=pos[2]+5;
x2=x;y2=y;z2=z;
a=(x-pos[0]);
b=(y-pos[1]);
c=sqrt(a*a+b*b);
d=(z-cam->z);
h=-atan2(a,-b)*180/M_PI;
p=0;
r=90-atan2(d,-c)*180/M_PI;
}
a=(x-pos[0]);
b=(y-pos[1]);
c=sqrt(a*a+b*b);
d=(z-pos[3]);
h2=-atan2(a,-b)*180/M_PI;
p2=0;
r2=90-atan2(d,-c)*180/M_PI;
}
break;
case 7: //camara especial
{
float a,b;
x2=pos[0]+m[4]*5.0;
y2=pos[1]-m[0]*5.0;
z2=pos[2]-2;
a=(x-pos[0]);
b=(y-pos[1]);
h2=-atan2(a,-b)*180/M_PI;
p2=0;
r2=-90;
}
default:
break;
}
xs=(x2-x)*world->step_size*3;
ys=(y2-y)*world->step_size*3;
zs=(z2-z)*world->step_size*3;
hs=(h2-h)*world->real_step_size*5;
if(h2<-90 && h> 90) hs=((h2+360)-h)/10;
if(h2> 90 && h<-90) hs=(h2-(h+360))/10;
ps=(p2-p)*world->real_step_size*5;
if(p2<-90 && p> 90) ps=((p2+360)-p)/10;
if(p2> 90 && p<-90) ps=(p2-(p+360))/10;
rs=(r2-r)*world->real_step_size*5;
if(r2<-90 && r> 90) rs=((r2+360)-r)/10;
if(r2> 90 && r<-90) rs=(r2-(r+360))/10;
set(x+xs,y+ys,z+zs,h+hs,p+ps,r+rs);
}
void motion_blur()
{
static int accum_clear = FALSE;
if(options.tiempo_bala)
{
if(accum_clear) glAccum(GL_ACCUM,1);
glAccum(GL_MULT,0.85);
glAccum(GL_ACCUM,1-0.85);
glAccum(GL_RETURN,1.0);
accum_clear = FALSE;
}
else if(!accum_clear)
{
glClear(GL_ACCUM_BUFFER_BIT);
accum_clear = TRUE;
}
}
void draw_cursor()
{
int x,y;
const int size = 30;
SDL_GetMouseState(&x, &y);
y=options.screen_h-y;
glDisable(GL_LIGHTING);
glEnable(GL_TEXTURE_2D);
glDisable(GL_DEPTH_TEST);
glEnable(GL_BLEND);
glColor3f(1,1,1);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glBindTexture( GL_TEXTURE_2D, cursor_tex);
glBegin(GL_QUADS);
glTexCoord2f( 0.0f, 0.0f ); glVertex2f( x, y-size );
glTexCoord2f( 1.0f, 0.0f ); glVertex2f( x+size, y-size );
glTexCoord2f( 1.0f, 1.0f ); glVertex2f( x+size, y );
glTexCoord2f( 0.0f, 1.0f ); glVertex2f( x, y );
glEnd();
glDisable(GL_BLEND);
glEnable(GL_DEPTH_TEST);
glBlendFunc(GL_ONE, GL_ZERO);
}
void draw_cocheworld()
{
float position[] = { 0.0f,0.0f, 1.0f, 0.0f };
glPushMatrix ();
glLightfv(GL_LIGHT0, GL_POSITION, position);
glPopMatrix ();
world->draw();
coche[0].draw();
}
Matrix4x4 lightProjectionMatrix, lightViewMatrix;
int draw_scene(GLvoid) // Here's Where We Do All The Drawing
{
glEnable(GL_LIGHTING);
if(options.shadows)
{
//Calculate & save matrices
glPushMatrix();
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
gluPerspective(45.f, (float)options.screen_w/options.screen_h, 1.0f, options.view_far);
glGetFloatv(GL_MODELVIEW_MATRIX, cam->proj_matrix);
glLoadIdentity();
glRotatef (cam->r, 1,0,0);
glRotatef (cam->p, 0,1,0);
glRotatef (cam->h, 0,0,1);
glTranslatef (-cam->x,-cam->y,-cam->z);
glPopMatrix();
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
//const dReal *waka = dBodyGetPosition(coche[0].body[0]);
GLfloat map_c = world->map.length*5-5;
glTranslatef(-map_c,-map_c,-100);
//glTranslatef(-waka[0],-waka[1],-100);
glGetFloatv(GL_MODELVIEW_MATRIX, lightViewMatrix);
glLoadIdentity();
//gluPerspective(30.f, 1.0f, 90.0f, 110.0f);
map_c+=10;
glOrtho(-map_c,map_c,-map_c,map_c,90,102);
//glOrtho(-20,20,-20,20,90,110);
glGetFloatv(GL_MODELVIEW_MATRIX, lightProjectionMatrix);
glLoadIdentity();
glMatrixMode(GL_PROJECTION);
glLoadMatrixf(lightProjectionMatrix);
//glLoadMatrixf(cameraProjectionMatrix);
glMatrixMode(GL_MODELVIEW);
glLoadMatrixf(lightViewMatrix);
//glLoadMatrixf(cameraViewMatrix);
//Draw back faces into the shadow map
glCullFace(GL_FRONT);
glShadeModel(GL_FLAT);
glColorMask(0, 0, 0, 0);
glDisable(GL_TEXTURE_2D);
//glTranslatef(0,0,0.1);
glBindFramebufferEXT (GL_FRAMEBUFFER_EXT, shadow_map_fb);
glViewport(0, 0, shadowMapSize, shadowMapSize);
glClear(GL_DEPTH_BUFFER_BIT);
render_pass = RENDER_PASS_SHADOW_MAP;
draw_cocheworld();
glBindFramebufferEXT (GL_FRAMEBUFFER_EXT, 0);
//Read the depth buffer into the shadow map texture
//glBindTexture(GL_TEXTURE_2D, shadow_map_texture);
//glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, shadowMapSize, shadowMapSize);
//restore states
glCullFace(GL_BACK);
//2nd pass - Draw from camera's point of view
glMatrixMode(GL_PROJECTION);
glLoadMatrixf(cam->proj_matrix);
glMatrixMode(GL_MODELVIEW);
glLoadMatrixf(cam->view_matrix);
glViewport(0, 0, options.screen_w, options.screen_h);
render_pass = RENDER_PASS_NORMAL;
draw_cocheworld();
glEnable(GL_TEXTURE_2D);
glShadeModel(GL_SMOOTH);
glColorMask(1, 1, 1, 1);
//3rd pass
static Matrix4x4 biasMatrix(0.5f, 0.0f, 0.0f, 0.0f,
0.0f, 0.5f, 0.0f, 0.0f,
0.0f, 0.0f, 0.5f, 0.0f,
0.5f, 0.5f, 0.5f, 1.0f); //bias from [-1, 1] to [0, 1]
Matrix4x4 textureMatrix=biasMatrix*lightProjectionMatrix*lightViewMatrix;
GLfloat textureMatrixRow[4];
glActiveTextureARB(GL_TEXTURE1_ARB);
textureMatrixRow[0]=textureMatrix.data[0];
textureMatrixRow[1]=textureMatrix.data[4];
textureMatrixRow[2]=textureMatrix.data[8];
textureMatrixRow[3]=textureMatrix.data[12];
glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
glTexGenfv(GL_S, GL_EYE_PLANE, textureMatrixRow);
glEnable(GL_TEXTURE_GEN_S);
textureMatrixRow[0]=textureMatrix.data[1];
textureMatrixRow[1]=textureMatrix.data[5];
textureMatrixRow[2]=textureMatrix.data[9];
textureMatrixRow[3]=textureMatrix.data[13];
glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
glTexGenfv(GL_T, GL_EYE_PLANE, textureMatrixRow);
glEnable(GL_TEXTURE_GEN_T);
textureMatrixRow[0]=textureMatrix.data[2];
textureMatrixRow[1]=textureMatrix.data[6];
textureMatrixRow[2]=textureMatrix.data[10];
textureMatrixRow[3]=textureMatrix.data[14];
glTexGeni(GL_R, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
glTexGenfv(GL_R, GL_EYE_PLANE, textureMatrixRow);
glEnable(GL_TEXTURE_GEN_R);
textureMatrixRow[0]=textureMatrix.data[3];
textureMatrixRow[1]=textureMatrix.data[7];
textureMatrixRow[2]=textureMatrix.data[11];
textureMatrixRow[3]=textureMatrix.data[15];
glTexGeni(GL_Q, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
glTexGenfv(GL_Q, GL_EYE_PLANE, textureMatrixRow);
glEnable(GL_TEXTURE_GEN_Q);
//Bind & enable shadow map texture
glBindTexture(GL_TEXTURE_2D, shadow_map_texture);
glEnable(GL_TEXTURE_2D);
//Enable shadow comparison
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE_ARB, GL_COMPARE_R_TO_TEXTURE);
//Shadow comparison should be true (ie not in shadow) if r<=texture
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC_ARB, GL_LEQUAL);
//Shadow comparison should generate an INTENSITY result
glTexParameteri(GL_TEXTURE_2D, GL_DEPTH_TEXTURE_MODE_ARB, GL_LUMINANCE);
glActiveTextureARB(GL_TEXTURE0_ARB);
render_pass = RENDER_PASS_SHADOW;
draw_cocheworld();
glActiveTextureARB(GL_TEXTURE1_ARB);
glDisable(GL_TEXTURE_2D);
glDisable(GL_ALPHA_TEST);
glDisable(GL_TEXTURE_GEN_S);
glDisable(GL_TEXTURE_GEN_T);
glDisable(GL_TEXTURE_GEN_R);
glDisable(GL_TEXTURE_GEN_Q);
//
glActiveTextureARB(GL_TEXTURE0_ARB);
/*glPushMatrix();
glLoadIdentity();
glPushAttrib(GL_TRANSFORM_BIT);
GLint viewport[4];
glGetIntegerv(GL_VIEWPORT, viewport);
glMatrixMode(GL_PROJECTION);
glPushMatrix();
glLoadIdentity();
gluOrtho2D(viewport[0],viewport[2],viewport[1],viewport[3]);
glPopAttrib();
char text[50];
sprintf(text, "%.3f %.3f",gvar_1,gvar_2);
freetype::print(font_big,10,10 , text);
glPushAttrib(GL_TRANSFORM_BIT);
glMatrixMode(GL_PROJECTION);
glPopMatrix();
glPopAttrib();
glPopMatrix(); */
}
else draw_cocheworld();
if(options.motion_blur) motion_blur();
return TRUE; // Keep Going
}