#include <windows.h>

#include <gl\gl.h>
#include <gl\glu.h>
#include <gl\glaux.h>

#include <math.h>
#include <stdio.h>
#include <fstream>
#include <vector>
#include <algorithm>

#include "Motor3d\DirectInput\Input.h"
#include "Motor3d\Ventana\Ventana.h"

extern VentanaGL		*g_ventanaGL;

COGLDInput				 g_InputGL;									// Objeto para manejo de teclado y ratón

using namespace std;

/*********************************ESTRUCTURAS DEL JUEGO***********************/
enum {VIVO,EXPLOTANDO,MUERTO};

//Estructura que se utiliza para la gestion de colisiones, ademas de para seleccionar 
//regiones en un textura para definir sprites
struct Caja
{
	GLfloat abajo;
	GLfloat izquierda;
	GLfloat arriba;
	GLfloat derecha;
};


//Estructura y variables de los disparos del juego
#define VELOCIDAD_LASER 0.5
#define VELOCIDAD_LASER_MALO 0.7

struct Disparo
{ 
	float PosX;
	float PosY;
};

Caja CajaColisionDisparoMalo = { -22,-17,-4,-7 };
Caja CajaColisionDisparoBueno = { 10,10,24,17 };

//Estructura y variables de la nave protagonista
#define VELOCIDAD_PROTAGONISTA 0.25

struct Protagonista
{
	int Estado;
	int Frame;
	float PosX,PosY;
	float Inclinacion;
	float MomentoExplosion;
	vector<Disparo> Disparos;
	Caja Tex;
	Caja Quad;
};

Caja CajaColisionProtagonista={30,20,90,60};


Protagonista protagonista;


//Estructura y variables de las naves malas
#define VELOCIDAD_MALO 0.1

#define COLUMNAS 6
#define FILAS    3

struct Malo
{
	int Estado;
	int Frame;
	float PosX,PosY;
	float MomentoExplosion;
	Caja Tex;
	Caja Quad;
};

float PosInicialX,PosInicialY;

Malo malo[FILAS][COLUMNAS];

vector<Disparo> DisparosMalos;

Caja CajaColisionMalos[3]={ -80,-80,-30,-10,    // ALIEN_FIGHTER
                            -90,-60,-30,-10,    // ALIEN_CALAMAR
                            -100,-60,-30,-10 };  // ALIEN_ROJO


//Variables globales del juego
#define DERECHA   0
#define IZQUIERDA 1

int g_Muertos=0;
int g_Nivel=1;

int TiempoInicio,tActual;

bool Presentacion=true;

//Identificadores de las texturas
GLuint idTexturaProtagonista[20];
GLuint idTexturaMalo[3];
GLuint idTexturaExplosionProtagonista[7];
GLuint idTexturaExplosionMalo[10];
GLuint idTexturaLaserProtagonista;
GLuint idTexturaLaserMalo;
GLuint idTexturaFondo;
GLuint idTexturaPresentacion;
GLuint idTexturaFinal;

//Identificadores de las mascaras
GLuint MidTexturaProtagonista[20];
GLuint MidTexturaMalo[3];
GLuint MidTexturaExplosionProtagonista[7];
GLuint MidTexturaExplosionMalo[10];
GLuint MidTexturaLaserProtagonista;
GLuint MidTexturaLaserMalo;

//Texturas 
AUX_RGBImageRec *TexturaProtagonista[20];
AUX_RGBImageRec *TexturaMalo[3];
AUX_RGBImageRec *TexturaExplosionProtagonista[7];
AUX_RGBImageRec *TexturaExplosionMalo[10];
AUX_RGBImageRec *TexturaLaserProtagonista;
AUX_RGBImageRec *TexturaLaserMalo;
AUX_RGBImageRec *TexturaFondo;
AUX_RGBImageRec *TexturaPresentacion;
AUX_RGBImageRec *TexturaFinal;

//Mascaras de las texturas
AUX_RGBImageRec *MTexturaProtagonista[20];
AUX_RGBImageRec *MTexturaMalo[3];
AUX_RGBImageRec *MTexturaExplosionProtagonista[7];
AUX_RGBImageRec *MTexturaExplosionMalo[10];
AUX_RGBImageRec *MTexturaLaserProtagonista;
AUX_RGBImageRec *MTexturaLaserMalo;

/*********************************CARGA DE TEXTURAS***************************/

AUX_RGBImageRec *CargarBMP(char *nArchivo)
{
	FILE *fp;
	char temp[256];

	if((fp=fopen(nArchivo,"r"))==NULL)
	{
		sprintf("Error al abrir el archivo %s",nArchivo);

		MessageBox(NULL,temp,"Error",MB_OK);
	}
	else
	{
		fclose(fp);

		return auxDIBImageLoad(nArchivo);
	}
}


//******************************TEXTO EN OPENGL******************************************//
GLuint	base;				

GLvoid IniciaFuente(GLvoid)								// Build Our Bitmap Font
{
	HFONT	font;										// Windows Font ID
	HFONT	oldfont;									// Used For Good House Keeping

	base = glGenLists(96);								// Storage For 96 Characters

	font = CreateFont(	-20,							// Height Of Font
						0,								// Width Of Font
						0,								// Angle Of Escapement
						0,								// Orientation Angle
						FW_BOLD,						// Font Weight
						FALSE,							// Italic
						FALSE,							// Underline
						FALSE,							// Strikeout
						ANSI_CHARSET,					// Character Set Identifier
						OUT_TT_PRECIS,					// Output Precision
						CLIP_DEFAULT_PRECIS,			// Clipping Precision
						ANTIALIASED_QUALITY,			// Output Quality
						FF_DONTCARE|DEFAULT_PITCH,		// Family And Pitch
						"Courier New");					// Font Name

	oldfont = (HFONT)SelectObject(g_ventanaGL->m_hDC, font);           // Selects The Font We Want
	wglUseFontBitmaps(g_ventanaGL->m_hDC, 32, 96, base);				// Builds 96 Characters Starting At Character 32
	SelectObject(g_ventanaGL->m_hDC, oldfont);							// Selects The Font We Want
	DeleteObject(font);									// Delete The Font
}

GLvoid DestruyeFuente(GLvoid)									// Delete The Font List
{
	glDeleteLists(base, 96);							// Delete All 96 Characters
}

GLvoid glPrint(const char *fmt, ...)					// Custom GL "Print" Routine
{
	char		text[256];								// Holds Our String
	va_list		ap;										// Pointer To List Of Arguments

	if (fmt == NULL)									// If There's No Text
		return;											// Do Nothing

	va_start(ap, fmt);									// Parses The String For Variables
	    vsprintf(text, fmt, ap);						// And Converts Symbols To Actual Numbers
	va_end(ap);											// Results Are Stored In Text

	glPushAttrib(GL_LIST_BIT);							// Pushes The Display List Bits
	glListBase(base - 32);								// Sets The Base Character to 32
	glCallLists(strlen(text), GL_UNSIGNED_BYTE, text);	// Draws The Display List Text
	glPopAttrib();										// Pops The Display List Bits
}



/*********************************INICIALIZACION******************************/
void IniciaDirectInput()
{
	g_InputGL.Iniciar(g_ventanaGL->m_hWnd);
}

void IniciaOpengl()
{
	glClearColor(1.0,1.0,1.0,1.0);
	
	glEnable(GL_TEXTURE_2D);
}

void CargaSprites()
{
	int i=0;

	char strArchivoProtagonista[20][22]={"Marcianitos/tux00.BMP","Marcianitos/tux01.BMP","Marcianitos/tux02.BMP","Marcianitos/tux03.BMP","Marcianitos/tux04.BMP","Marcianitos/tux05.BMP","Marcianitos/tux06.BMP",
										"Marcianitos/tux07.BMP","Marcianitos/tux08.BMP","Marcianitos/tux09.BMP","Marcianitos/tux10.BMP","Marcianitos/tux11.BMP","Marcianitos/tux12.BMP","Marcianitos/tux13.BMP",
										"Marcianitos/tux14.BMP","Marcianitos/tux15.BMP","Marcianitos/tux16.BMP","Marcianitos/tux17.BMP","Marcianitos/tux18.BMP","Marcianitos/tux19.BMP"};

	char strArchivoMalo[3][23]={"Marcianitos/alien0.BMP","Marcianitos/alien1.BMP","Marcianitos/alien2.BMP"};
	char strArchivoExplosionProtagonista[7][28]={"Marcianitos/explonave00.BMP","Marcianitos/explonave01.BMP","Marcianitos/explonave02.BMP","Marcianitos/explonave03.BMP","Marcianitos/explonave04.BMP","Marcianitos/explonave05.BMP","Marcianitos/explonave06.BMP"};
	char strArchivoExplosionMalo[10][28]={"Marcianitos/explosion00.BMP","Marcianitos/explosion01.BMP","Marcianitos/explosion02.BMP","Marcianitos/explosion03.BMP","Marcianitos/explosion04.BMP","Marcianitos/explosion05.BMP","Marcianitos/explosion06.BMP","Marcianitos/explosion07.BMP","Marcianitos/explosion08.BMP","Marcianitos/explosion09.BMP"};
	char strArchivoLaserProtagonista[22]="Marcianitos/Laser.BMP";
	char strArchivoLaserMalo[27]="Marcianitos/LaserMalos.BMP";
	char strArchivoFondo[22]="Marcianitos/Fondo.BMP";
	char strArchivoPresentacion[29]="Marcianitos/Presentacion.BMP";
	char strArchivoFinal[25]="Marcianitos/GameOver.BMP";

	char MstrArchivoProtagonista[20][22]={"Mascaras/Mtux00.BMP","Mascaras/Mtux01.BMP","Mascaras/Mtux02.BMP","Mascaras/Mtux03.BMP","Mascaras/Mtux04.BMP","Mascaras/Mtux05.BMP","Mascaras/Mtux06.BMP",
										"Mascaras/Mtux07.BMP","Mascaras/Mtux08.BMP","Mascaras/Mtux09.BMP","Mascaras/Mtux10.BMP","Mascaras/Mtux11.BMP","Mascaras/Mtux12.BMP","Mascaras/Mtux13.BMP",
										"Mascaras/Mtux14.BMP","Mascaras/Mtux15.BMP","Mascaras/Mtux16.BMP","Mascaras/Mtux17.BMP","Mascaras/Mtux18.BMP","Mascaras/Mtux19.BMP"};

	char MstrArchivoMalo[3][23]={"Mascaras/Malien0.BMP","Mascaras/Malien1.BMP","Mascaras/Malien2.BMP"};
	char MstrArchivoExplosionProtagonista[7][28]={"Mascaras/Mexplonave00.BMP","Mascaras/Mexplonave01.BMP","Mascaras/Mexplonave02.BMP","Mascaras/Mexplonave03.BMP","Mascaras/Mexplonave04.BMP","Mascaras/Mexplonave05.BMP","Mascaras/Mexplonave06.BMP"};
	char MstrArchivoExplosionMalo[10][28]={"Mascaras/Mexplosion00.BMP","Mascaras/Mexplosion01.BMP","Mascaras/Mexplosion02.BMP","Mascaras/Mexplosion03.BMP","Mascaras/Mexplosion04.BMP","Mascaras/Mexplosion05.BMP","Mascaras/Mexplosion06.BMP","Mascaras/Mexplosion07.BMP","Mascaras/Mexplosion08.BMP","Mascaras/Mexplosion09.BMP"};
	char MstrArchivoLaserProtagonista[22]="Mascaras/MLaser.BMP";
	char MstrArchivoLaserMalo[27]="Mascaras/MLaserMalos.BMP";

	memset(TexturaProtagonista,0,sizeof(void*)*7);
	memset(TexturaMalo,0,sizeof(void*)*3);
	memset(TexturaExplosionProtagonista,0,sizeof(void*)*7);
	memset(TexturaExplosionMalo,0,sizeof(void*)*10);
	memset(MTexturaProtagonista,0,sizeof(void*)*7);
	memset(MTexturaMalo,0,sizeof(void*)*3);
	memset(MTexturaExplosionProtagonista,0,sizeof(void*)*7);
	memset(MTexturaExplosionMalo,0,sizeof(void*)*10);


	for(i=0;i<20;i++)
	{
		TexturaProtagonista[i]=CargarBMP(strArchivoProtagonista[i]);
		MTexturaProtagonista[i]=CargarBMP(MstrArchivoProtagonista[i]);
	}

	for(i=0;i<3;i++)
	{
		TexturaMalo[i]=CargarBMP(strArchivoMalo[i]);
		MTexturaMalo[i]=CargarBMP(MstrArchivoMalo[i]);
	}

	for(i=0;i<7;i++)
	{
		TexturaExplosionProtagonista[i]=CargarBMP(strArchivoExplosionProtagonista[i]);
		MTexturaExplosionProtagonista[i]=CargarBMP(MstrArchivoExplosionProtagonista[i]);
	}


	for(i=0;i<10;i++)
	{
		TexturaExplosionMalo[i]=CargarBMP(strArchivoExplosionMalo[i]);
		MTexturaExplosionMalo[i]=CargarBMP(MstrArchivoExplosionMalo[i]);
	}


	TexturaLaserProtagonista=CargarBMP(strArchivoLaserProtagonista);
	TexturaLaserMalo=CargarBMP(strArchivoLaserMalo);
	TexturaFondo=CargarBMP(strArchivoFondo);
	TexturaPresentacion=CargarBMP(strArchivoPresentacion);
	TexturaFinal=CargarBMP(strArchivoFinal);

	MTexturaLaserProtagonista=CargarBMP(MstrArchivoLaserProtagonista);
	MTexturaLaserMalo=CargarBMP(MstrArchivoLaserMalo);
	
	//Subimos las texturas y las mascaras de la nave del protagonista
	glGenTextures(20,&idTexturaProtagonista[0]);
	glGenTextures(20,&MidTexturaProtagonista[0]);
	
	for(i=0;i<20;i++)
	{
		glBindTexture(GL_TEXTURE_2D,idTexturaProtagonista[i]);
		glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
		glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
		glTexImage2D(GL_TEXTURE_2D,0,3,TexturaProtagonista[i]->sizeX,TexturaProtagonista[i]->sizeY,0,GL_RGB,GL_UNSIGNED_BYTE,TexturaProtagonista[i]->data);

		glBindTexture(GL_TEXTURE_2D,MidTexturaProtagonista[i]);
		glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
		glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
		glTexImage2D(GL_TEXTURE_2D,0,3,MTexturaProtagonista[i]->sizeX,MTexturaProtagonista[i]->sizeY,0,GL_RGB,GL_UNSIGNED_BYTE,MTexturaProtagonista[i]->data);
	}

	//Subimos las texturas y las mascaras de la nave de las naves malas
	glGenTextures(3,&idTexturaMalo[0]);
	glGenTextures(3,&MidTexturaMalo[0]);

	for(i=0;i<3;i++)
	{
		glBindTexture(GL_TEXTURE_2D,idTexturaMalo[i]);
		glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
		glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
		glTexImage2D(GL_TEXTURE_2D,0,3,TexturaMalo[i]->sizeX,TexturaMalo[i]->sizeY,0,GL_RGB,GL_UNSIGNED_BYTE,TexturaMalo[i]->data);

		glBindTexture(GL_TEXTURE_2D,MidTexturaMalo[i]);
		glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
		glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
		glTexImage2D(GL_TEXTURE_2D,0,3,MTexturaMalo[i]->sizeX,MTexturaMalo[i]->sizeY,0,GL_RGB,GL_UNSIGNED_BYTE,MTexturaMalo[i]->data);
	}

	//Subimos las texturas y las mascaras de las explosiones del protagonista
	glGenTextures(7,&idTexturaExplosionProtagonista[0]);
	glGenTextures(7,&MidTexturaExplosionProtagonista[0]);
	
	for(i=0;i<7;i++)
	{
		glBindTexture(GL_TEXTURE_2D,idTexturaExplosionProtagonista[i]);
		glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
		glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
		glTexImage2D(GL_TEXTURE_2D,0,3,TexturaExplosionProtagonista[i]->sizeX,TexturaExplosionProtagonista[i]->sizeY,0,GL_RGB,GL_UNSIGNED_BYTE,TexturaExplosionProtagonista[i]->data);

		glBindTexture(GL_TEXTURE_2D,MidTexturaExplosionProtagonista[i]);
		glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
		glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
		glTexImage2D(GL_TEXTURE_2D,0,3,MTexturaExplosionProtagonista[i]->sizeX,MTexturaExplosionProtagonista[i]->sizeY,0,GL_RGB,GL_UNSIGNED_BYTE,MTexturaExplosionProtagonista[i]->data);
	}

	//Subimos las texturas y las mascaras de las explosiones de los malos
	glGenTextures(10,&idTexturaExplosionMalo[0]);
	glGenTextures(10,&MidTexturaExplosionMalo[0]);

	for(i=0;i<10;i++)
	{
		glBindTexture(GL_TEXTURE_2D,idTexturaExplosionMalo[i]);
		glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
		glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
		glTexImage2D(GL_TEXTURE_2D,0,3,TexturaExplosionMalo[i]->sizeX,TexturaExplosionMalo[i]->sizeY,0,GL_RGB,GL_UNSIGNED_BYTE,TexturaExplosionMalo[i]->data);

		glBindTexture(GL_TEXTURE_2D,MidTexturaExplosionMalo[i]);
		glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
		glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
		glTexImage2D(GL_TEXTURE_2D,0,3,MTexturaExplosionMalo[i]->sizeX,MTexturaExplosionMalo[i]->sizeY,0,GL_RGB,GL_UNSIGNED_BYTE,MTexturaExplosionMalo[i]->data);
	}

	//Subimos la textura y la mascara del laser del protagonista
	glGenTextures(1,&idTexturaLaserProtagonista);

	glBindTexture(GL_TEXTURE_2D,idTexturaLaserProtagonista);
	glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
	glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
	glTexImage2D(GL_TEXTURE_2D,0,3,TexturaLaserProtagonista->sizeX,TexturaLaserProtagonista->sizeY,0,GL_RGB,GL_UNSIGNED_BYTE,TexturaLaserProtagonista->data);

	glGenTextures(1,&MidTexturaLaserProtagonista);

	glBindTexture(GL_TEXTURE_2D,MidTexturaLaserProtagonista);
	glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
	glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
	glTexImage2D(GL_TEXTURE_2D,0,3,MTexturaLaserProtagonista->sizeX,MTexturaLaserProtagonista->sizeY,0,GL_RGB,GL_UNSIGNED_BYTE,MTexturaLaserProtagonista->data);

	//Subimos la textura y las mascara del laser de las naves malas
	glGenTextures(1,&idTexturaLaserMalo);
	
	glBindTexture(GL_TEXTURE_2D,idTexturaLaserMalo);
	glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
	glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
	glTexImage2D(GL_TEXTURE_2D,0,3,TexturaLaserMalo->sizeX,TexturaLaserMalo->sizeY,0,GL_RGB,GL_UNSIGNED_BYTE,TexturaLaserMalo->data);

	glGenTextures(1,&MidTexturaLaserMalo);
	
	glBindTexture(GL_TEXTURE_2D,MidTexturaLaserMalo);
	glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
	glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
	glTexImage2D(GL_TEXTURE_2D,0,3,MTexturaLaserMalo->sizeX,MTexturaLaserMalo->sizeY,0,GL_RGB,GL_UNSIGNED_BYTE,MTexturaLaserMalo->data);

	//Subimos la textura del fondo del nivel 1
	glGenTextures(1,&idTexturaFondo);

	glBindTexture(GL_TEXTURE_2D,idTexturaFondo);
	glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
	glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
	glTexImage2D(GL_TEXTURE_2D,0,3,TexturaFondo->sizeX,TexturaFondo->sizeY,0,GL_RGB,GL_UNSIGNED_BYTE,TexturaFondo->data);

	//Subimos la textura del fondo del nivel 1
	glGenTextures(1,&idTexturaPresentacion);

	glBindTexture(GL_TEXTURE_2D,idTexturaPresentacion);
	glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
	glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
	glTexImage2D(GL_TEXTURE_2D,0,3,TexturaPresentacion->sizeX,TexturaPresentacion->sizeY,0,GL_RGB,GL_UNSIGNED_BYTE,TexturaPresentacion->data);

	//Subimos la textura del fondo del nivel 1
	glGenTextures(1,&idTexturaFinal);

	glBindTexture(GL_TEXTURE_2D,idTexturaFinal);
	glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
	glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
	glTexImage2D(GL_TEXTURE_2D,0,3,TexturaFinal->sizeX,TexturaFinal->sizeY,0,GL_RGB,GL_UNSIGNED_BYTE,TexturaFinal->data);

	for(i=0;i<20;i++)
	{
		if(TexturaProtagonista[i])
		{
			if(TexturaProtagonista[i]->data)
				free(TexturaProtagonista[i]->data);

			free(TexturaProtagonista[i]);
		}

		if(MTexturaProtagonista[i])
		{
			if(MTexturaProtagonista[i]->data)
				free(MTexturaProtagonista[i]->data);

			free(MTexturaProtagonista[i]);
		}
	}

	for(i=0;i<3;i++)
	{
		if(TexturaMalo[i])
		{
			if(TexturaMalo[i]->data)
				free(TexturaMalo[i]->data);

			free(TexturaMalo[i]);
		}

		if(MTexturaMalo[i])
		{
			if(MTexturaMalo[i]->data)
				free(MTexturaMalo[i]->data);

			free(MTexturaMalo[i]);
		}
	}

	for(i=0;i<7;i++)
	{
		if(TexturaExplosionProtagonista[i])
		{
			if(TexturaExplosionProtagonista[i]->data)
				free(TexturaExplosionProtagonista[i]->data);

			free(TexturaExplosionProtagonista[i]);
		}
		
		if(MTexturaExplosionProtagonista[i])
		{
			if(MTexturaExplosionProtagonista[i]->data)
				free(MTexturaExplosionProtagonista[i]->data);

			free(MTexturaExplosionProtagonista[i]);
		}
	}

	for(i=0;i<10;i++)
	{
		if(TexturaExplosionMalo[i])
		{
			if(TexturaExplosionMalo[i]->data)
				free(TexturaExplosionMalo[i]->data);

			free(TexturaExplosionMalo[i]);
		}

		if(MTexturaExplosionMalo[i])
		{
			if(MTexturaExplosionMalo[i]->data)
				free(MTexturaExplosionMalo[i]->data);

			free(MTexturaExplosionMalo[i]);
		}
	}

	if(TexturaLaserProtagonista)
	{
		if(TexturaLaserProtagonista->data)
			free(TexturaLaserProtagonista->data);

		free(TexturaLaserProtagonista);
	}

	if(MTexturaLaserProtagonista)
	{
		if(MTexturaLaserProtagonista->data)
			free(MTexturaLaserProtagonista->data);

		free(MTexturaLaserProtagonista);
	}

	if(TexturaLaserMalo)
	{
		if(TexturaLaserMalo->data)
			free(TexturaLaserMalo->data);

		free(TexturaLaserMalo);
	}

	if(MTexturaLaserMalo)
	{
		if(MTexturaLaserMalo->data)
			free(MTexturaLaserMalo->data);

		free(MTexturaLaserMalo);
	}

	if(TexturaFondo)
	{
		if(TexturaFondo->data)
			free(TexturaFondo->data);

		free(TexturaFondo);
	}

	if(TexturaPresentacion)
	{
		if(TexturaPresentacion->data)
			free(TexturaPresentacion->data);

		free(TexturaPresentacion);
	}

	if(TexturaFinal)
	{
		if(TexturaFinal->data)
			free(TexturaFinal->data);

		free(TexturaFinal);
	}
}

void CargarNivel(char *nombreArchivo)
{
	ifstream canalEntrada(nombreArchivo);

	PosInicialX=100.0;
	PosInicialY=g_ventanaGL->m_alto;

	for( int fila = 0; fila < FILAS; fila++ )
		for( int columna = 0; columna < COLUMNAS; columna++ )
		{
			malo[fila][columna].PosX = ( float )( PosInicialX + 80.0 * columna );
			malo[fila][columna].PosY = ( float )( PosInicialY - 80.0 * fila );
			
			canalEntrada >> malo[fila][columna].Frame;
			
			malo[fila][columna].MomentoExplosion=0.0;
			malo[fila][columna].Estado = VIVO;
		}

	protagonista.PosX=0;
	protagonista.PosY=0;
	protagonista.Estado=VIVO;
	protagonista.Frame=10;
	protagonista.Inclinacion=0.0;
	protagonista.MomentoExplosion=0.0;
}

void TocaSonido(char *nArchivo)
{
	PlaySound(nArchivo, NULL, SND_ASYNC);
}

void Inicializacion()
{
	TiempoInicio=(float)GetTickCount();
	
	IniciaDirectInput();
	IniciaOpengl();
	IniciaFuente();
	CargarNivel("Niveles/nivel1.txt");
	CargaSprites();
}


bool SalePorArriba(Disparo disparo)
{
	return (disparo.PosY>g_ventanaGL->m_alto);
}

void MoverProtagonista(float delta)
{
	static bool EspacioSoltado=true;
	static bool ESoltado=true;
	static int f=0,g=0;

	switch(protagonista.Estado)
	{
		case VIVO:
		{
			if(g_InputGL.TeclaPulsada(DIK_1))
				CargarNivel("Niveles/nivel1.txt");
			if(g_InputGL.TeclaPulsada(DIK_2))
				CargarNivel("Niveles/nivel2.txt");
			if(g_InputGL.TeclaPulsada(DIK_3))
				CargarNivel("Niveles/nivel3.txt");
			if(g_InputGL.TeclaPulsada(DIK_3))
				CargarNivel("Niveles/nivel3.txt");
			if(g_InputGL.TeclaPulsada(DIK_4))
				CargarNivel("Niveles/nivel4.txt");
			if(g_InputGL.TeclaPulsada(DIK_5))
				CargarNivel("Niveles/nivel5.txt");
			if(g_InputGL.TeclaPulsada(DIK_6))
				CargarNivel("Niveles/nivel6.txt");
			if(g_InputGL.TeclaPulsada(DIK_7))
				CargarNivel("Niveles/nivel7.txt");
			if(g_InputGL.TeclaPulsada(DIK_8))
				CargarNivel("Niveles/nivel8.txt");
			if(g_InputGL.TeclaPulsada(DIK_9))
				CargarNivel("Niveles/nivel9.txt");
			
			if(g_Muertos==FILAS*COLUMNAS)
			{
				switch(g_Nivel)
				{
				case 1:
					g_Muertos=0;
					g_Nivel=2;
					CargarNivel("Niveles/nivel2.txt");
					break;
				case 2:
					g_Muertos=0;
					g_Nivel=3;
					CargarNivel("Niveles/nivel3.txt");
					break;
				case 3:
					g_Muertos=0;
					g_Nivel=4;
					CargarNivel("Niveles/nivel4.txt");
					break;
				case 4:
					g_Muertos=0;
					g_Nivel=5;
					CargarNivel("Niveles/nivel5.txt");
					break;
				case 5:
					g_Muertos=0;
					g_Nivel=6;
					CargarNivel("Niveles/nivel6.txt");
					break;
				case 6:
					g_Muertos=0;
					g_Nivel=7;
					CargarNivel("Niveles/nivel7.txt");
					break;
				case 7:
					g_Muertos=0;
					g_Nivel=8;
					CargarNivel("Niveles/nivel8.txt");
					break;
				case 8:
					g_Muertos=0;
					g_Nivel=9;
					CargarNivel("Niveles/nivel9.txt");
					break;
				case 9:
					g_Muertos=0;
					g_Nivel=10;
					CargarNivel("Niveles/nivel10.txt");
					break;
				}
			}

			if(g_InputGL.TeclaPulsada(DIK_LEFT)) 
			{
				protagonista.PosX-=delta*VELOCIDAD_PROTAGONISTA;

				if(protagonista.Inclinacion > -80)
					protagonista.Inclinacion-=2*delta*VELOCIDAD_PROTAGONISTA;		
			}
			if(protagonista.PosX<0.0)
				protagonista.PosX=0.0;

			if(g_InputGL.TeclaPulsada(DIK_RIGHT)) 
			{
				protagonista.PosX+=delta*VELOCIDAD_PROTAGONISTA;

				if(protagonista.Inclinacion<80)
					protagonista.Inclinacion+=2*delta*VELOCIDAD_PROTAGONISTA;		
			}
			if(protagonista.PosX>g_ventanaGL->m_ancho-70)
				protagonista.PosX=g_ventanaGL->m_ancho-70;

			if(g_InputGL.TeclaPulsada(DIK_LEFT) && g_InputGL.TeclaPulsada(DIK_A)) 
			{
				protagonista.PosX-=delta*VELOCIDAD_PROTAGONISTA;

				if(protagonista.Inclinacion > -80)
					protagonista.Inclinacion-=delta*VELOCIDAD_PROTAGONISTA;		
			}

			if(g_InputGL.TeclaPulsada(DIK_RIGHT) && g_InputGL.TeclaPulsada(DIK_A)) 
			{
				protagonista.PosX+=delta*VELOCIDAD_PROTAGONISTA;

				if(protagonista.Inclinacion<80)
					protagonista.Inclinacion+=delta*VELOCIDAD_PROTAGONISTA;		
			}

			if(g_InputGL.TeclaPulsada(DIK_SPACE) && EspacioSoltado)
			{
				TocaSonido("Marcianitos/fx38.wav");

				Disparo NuevoDisparo;
				
				NuevoDisparo.PosX=protagonista.PosX+25;
				NuevoDisparo.PosY=protagonista.PosY+80;

				protagonista.Disparos.push_back(NuevoDisparo);

				EspacioSoltado=false;
			}

			if(!g_InputGL.TeclaPulsada(DIK_SPACE))
				EspacioSoltado=true;

			if( ( !g_InputGL.TeclaPulsada(DIK_LEFT) && !g_InputGL.TeclaPulsada(DIK_RIGHT) ) ||
				(  g_InputGL.TeclaPulsada(DIK_LEFT) &&  g_InputGL.TeclaPulsada(DIK_RIGHT) ) );
			{
				if(protagonista.Inclinacion<0)
					protagonista.Inclinacion+=delta*VELOCIDAD_PROTAGONISTA;
				else if(protagonista.Inclinacion>0)
					protagonista.Inclinacion-=delta*VELOCIDAD_PROTAGONISTA;
			}

			if(protagonista.Inclinacion<-75) protagonista.Frame=0;
			else if(protagonista.Inclinacion<-70) protagonista.Frame=1;
			else if(protagonista.Inclinacion<-65) protagonista.Frame=2;
			else if(protagonista.Inclinacion<-60) protagonista.Frame=3;
			else if(protagonista.Inclinacion<-55) protagonista.Frame=4;
			else if(protagonista.Inclinacion<-45) protagonista.Frame=5;
			else if(protagonista.Inclinacion<-35) protagonista.Frame=6;
			else if(protagonista.Inclinacion<-30) protagonista.Frame=7;
			else if(protagonista.Inclinacion<-25) protagonista.Frame=8;
			else if(protagonista.Inclinacion<-20) protagonista.Frame=9;
			else if(protagonista.Inclinacion<-15) protagonista.Frame=10;
			else if(protagonista.Inclinacion<15) protagonista.Frame=11;
			else if(protagonista.Inclinacion<20) protagonista.Frame=12;
			else if(protagonista.Inclinacion<25) protagonista.Frame=13;
			else if(protagonista.Inclinacion<30) protagonista.Frame=14;
			else if(protagonista.Inclinacion<35) protagonista.Frame=15;
			else if(protagonista.Inclinacion<45) protagonista.Frame=16;
			else if(protagonista.Inclinacion<50) protagonista.Frame=17;
			else if(protagonista.Inclinacion<55) protagonista.Frame=18;
			else protagonista.Frame=19;
		}break;

		case EXPLOTANDO:
		{
		
			protagonista.MomentoExplosion+=delta;
			if(protagonista.MomentoExplosion<200) protagonista.Frame=0;
			else if(protagonista.MomentoExplosion<400) protagonista.Frame=1;
			else if(protagonista.MomentoExplosion<600) protagonista.Frame=2;
			else if(protagonista.MomentoExplosion<800) protagonista.Frame=3;
			else if(protagonista.MomentoExplosion<1000) protagonista.Frame=4;
			else if(protagonista.MomentoExplosion<1200) protagonista.Frame=5;
			else if(protagonista.MomentoExplosion<1400) protagonista.Frame=6;
			else protagonista.Estado=MUERTO;
		
		}break;

		case MUERTO:
		{
				
			if(g_InputGL.TeclaPulsada(DIK_V))
				protagonista.Estado=VIVO;
		
		}break;
	}
	

	// Movemos los disparos de nuestro protagonista para arriba
	for (int indice = 0; indice < protagonista.Disparos.size(); indice++ )
	{
	   protagonista.Disparos[indice].PosY += delta * VELOCIDAD_LASER;
	}

	// Eliminamos los disparos que se salen por arriba
	vector<Disparo>::iterator separador;
	separador = remove_if( protagonista.Disparos.begin(), protagonista.Disparos.end(), SalePorArriba );
	protagonista.Disparos.erase( separador, protagonista.Disparos.end());

}

bool ChocaDerecha()
{
	for( int columna = 0; columna < COLUMNAS; columna++ )
		for( int fila = 0; fila < FILAS; fila++ )
			if ( malo[fila][columna].PosX > g_ventanaGL->m_ancho-10 )
				return true;

	return false;
}

bool ChocaIzquierda()
{
	for( int columna = 0; columna < COLUMNAS; columna++ )
		for( int fila = 0; fila < FILAS; fila++ )
			if ( malo[fila][columna].PosX < 80)
				return true;

	return false;
}

bool SalePorAbajo(Disparo disparo)
{
	return (disparo.PosY<0.0);
}

void MoverMalos(float delta)
{
	int i,fila,columna;

	static bool direccion = DERECHA;
	static bool bajando = false;

	if ( ( direccion == DERECHA ) && ( !bajando ) )
	{
		if ( ChocaDerecha() ) 
		{
			direccion = IZQUIERDA;
			bajando = true;
		}

		for ( columna = 0; columna < COLUMNAS; columna++ )
			for ( fila = 0; fila < FILAS; fila++ )
				malo[fila][columna].PosX += delta * VELOCIDAD_MALO;
	}

	if ( ( direccion == IZQUIERDA ) && ( !bajando ) )
	{
		if ( ChocaIzquierda() )
		{
			direccion = DERECHA;
			bajando = true;
		}

		for ( columna = 0; columna < COLUMNAS; columna++ )
			for ( fila = 0; fila < FILAS; fila++ )
				malo[fila][columna].PosX -= delta * VELOCIDAD_MALO;
	}

	if ( bajando )
	{
		static float totalBajado = 0;
		float bajarEsteFrame = delta * VELOCIDAD_MALO;
		totalBajado += bajarEsteFrame;

		if ( totalBajado > 10 )
		{
			bajarEsteFrame -= (totalBajado - 10);
			bajando = false;
			totalBajado = 0;
		}

		for( columna = 0; columna < COLUMNAS; columna++ )
			for( fila = 0; fila < FILAS; fila++ )
				malo[fila][columna].PosY -= bajarEsteFrame;
	}


	for( columna = 0; columna < COLUMNAS; columna++ )		
		for( fila = 0; fila < FILAS; fila++ )
		{
			if ( ( malo[fila][columna].Estado == VIVO ) && 
				( rand() % 10000 ) < delta )		
			{
				Disparo nuevoDisparo;
				nuevoDisparo.PosX = malo[fila][columna].PosX-25;
				nuevoDisparo.PosY = malo[fila][columna].PosY-50;
				DisparosMalos.push_back( nuevoDisparo );
			}

			if ( malo[fila][columna].Estado == EXPLOTANDO )		
			{
				Malo *alien = &malo[fila][columna];
				alien->MomentoExplosion += delta;
				if ( alien->MomentoExplosion < 50) alien->Frame = 0;
				else if ( alien->MomentoExplosion < 100 ) alien->Frame = 1;
				else if ( alien->MomentoExplosion < 150 ) alien->Frame = 2;
				else if ( alien->MomentoExplosion < 200 ) alien->Frame = 3;
				else if ( alien->MomentoExplosion < 250 ) alien->Frame = 4;
				else if ( alien->MomentoExplosion < 300 ) alien->Frame = 5;
				else if ( alien->MomentoExplosion < 350 ) alien->Frame = 6;
				else if ( alien->MomentoExplosion < 400 ) alien->Frame = 7;
				else if ( alien->MomentoExplosion < 450 ) alien->Frame = 8;
				else if ( alien->MomentoExplosion < 500 ) alien->Frame = 9;
				else { alien->Estado = MUERTO; g_Muertos++; }
			}
		}

	for ( i = 0; i < DisparosMalos.size(); i++ )	
		DisparosMalos[i].PosY -= delta * VELOCIDAD_LASER_MALO;
	
	vector <Disparo>::iterator separador;								
	separador = remove_if( DisparosMalos.begin(), DisparosMalos.end(), SalePorAbajo );
	DisparosMalos.erase( separador, DisparosMalos.end());
}

bool Colisiona(Malo alien,Disparo disparo)
{
	if( (disparo.PosX+CajaColisionDisparoBueno.izquierda<alien.PosX+CajaColisionMalos[alien.Frame].derecha) &&
		(disparo.PosX+CajaColisionDisparoBueno.derecha>alien.PosX+CajaColisionMalos[alien.Frame].izquierda) && 
		(disparo.PosY+CajaColisionDisparoBueno.arriba>alien.PosY+CajaColisionMalos[alien.Frame].abajo) &&
		(disparo.PosY+CajaColisionDisparoBueno.abajo<alien.PosY+CajaColisionMalos[alien.Frame].arriba) )
			return true;
			
	return false;
}

bool Colisiona(Protagonista prota,Disparo disparo)
{
	if( (disparo.PosX+CajaColisionDisparoMalo.izquierda<prota.PosX+CajaColisionProtagonista.derecha) &&
		(disparo.PosX+CajaColisionDisparoMalo.derecha>prota.PosX+CajaColisionProtagonista.izquierda) &&
		(disparo.PosY+CajaColisionDisparoMalo.abajo<prota.PosY+CajaColisionProtagonista.arriba) &&
		(disparo.PosY+CajaColisionDisparoMalo.arriba>prota.PosY+CajaColisionProtagonista.abajo) ) 
			return true;

	return false;
}

void GestionarColisiones()
{
	int i;

	//Colisiones de los disparos del protagonista con los enemigos
	for(i=0;i<protagonista.Disparos.size();i++)
	{
		for( int columna = 0; columna < COLUMNAS; columna++ )		
		{
			for( int fila = 0; fila < FILAS; fila++ )
			{
				if(malo[fila][columna].Estado==VIVO)
				{
					if(Colisiona(malo[fila][columna],protagonista.Disparos[i]))
					{
						malo[fila][columna].Estado = EXPLOTANDO;	
						protagonista.Disparos.erase( protagonista.Disparos.begin() + i );
						TocaSonido("Marcianitos/gun5.wav");
					}
				}
			}
		}
	}

	//Colisiones de los disparos de los enemigos con el protagonista
	if(protagonista.Estado==VIVO)
	{
		for(i=0;i<DisparosMalos.size();i++)
		{
			if(Colisiona(protagonista,DisparosMalos[i]))
			{
				protagonista.Estado=EXPLOTANDO;
				TocaSonido("Marcianitos/exp0.wav");
			}
		}
	}
}

void CapturaTeclas()
{
	g_InputGL.Actualizar();

	/********************CALCULO DEL DELTA DE TIEMPO ENTRE FRAMES*********/
	static DWORD Tiempo = timeGetTime();
	DWORD tActual = timeGetTime(); 
	float delta = ( float )( tActual - Tiempo );
	Tiempo = tActual;

	if(delta>60)
		delta=60;

	/**************************COMPORTAMIENTO PROTAGONISTA****************/
	MoverProtagonista(delta);

	/**************************COMPORTAMIENTO NAVES ENEMIGAS**************/
	MoverMalos(delta);

	/**************************GESTION DE LAS COLISIONES******************/
	GestionarColisiones();

	/****************************FIN DE LA APLICACION********************/
	if(g_InputGL.TeclaPulsada(DIK_ESCAPE))
		g_ventanaGL->cerrar();
}

void RenderizaSprite64x64(int idMascara,int idSprite,GLfloat posX,GLfloat posY,bool Rotado)
{
	glEnable(GL_BLEND);
	glDisable(GL_DEPTH_TEST);

	glBlendFunc(GL_DST_COLOR,GL_ZERO);

	glPushMatrix();
		glTranslatef(posX,posY,0.0);
		
		if(Rotado) glRotatef(180,0.0,0.0,1.0);

		glBindTexture(GL_TEXTURE_2D,idMascara);

		glBegin(GL_QUADS);
			glTexCoord2f(0.0,0.0);glVertex3f(0.0,0.0,-2.0);
			glTexCoord2f(1.0,0.0);glVertex3f(100.0,0.0,-2.0);
			glTexCoord2f(1.0,1.0);glVertex3f(100.0,100.0,-2.0);
			glTexCoord2f(0.0,1.0);glVertex3f(0.0,100.0,-2.0);
		glEnd();

		glBlendFunc(GL_ONE, GL_ONE);

		glBindTexture(GL_TEXTURE_2D,idSprite);

		glBegin(GL_QUADS);
			glTexCoord2f(0.0,0.0);glVertex3f(0.0,0.0,-2.0);
			glTexCoord2f(1.0,0.0);glVertex3f(100.0,0.0,-2.0);
			glTexCoord2f(1.0,1.0);glVertex3f(100.0,100.0,-2.0);
			glTexCoord2f(0.0,1.0);glVertex3f(0.0,100.0,-2.0);
		glEnd();

	glPopMatrix();

	glEnable(GL_DEPTH_TEST);						
	glDisable(GL_BLEND);
}

void RenderizaSprite32x32(int idMascara,int idSprite,GLfloat posX,GLfloat posY,bool Rotado)
{
	glEnable(GL_BLEND);
	glDisable(GL_DEPTH_TEST);

	glBlendFunc(GL_DST_COLOR,GL_ZERO);

	glPushMatrix();
		glTranslatef(posX,posY,0.0);
		
		if(Rotado) glRotatef(180,0.0,0.0,1.0);

		glBindTexture(GL_TEXTURE_2D,idMascara);

		glBegin(GL_QUADS);
			glTexCoord2f(0.0,0.0);glVertex3f(0.0,0.0,-2.0);
			glTexCoord2f(1.0,0.0);glVertex3f(25.0,0.0,-2.0);
			glTexCoord2f(1.0,1.0);glVertex3f(25.0,25.0,-2.0);
			glTexCoord2f(0.0,1.0);glVertex3f(0.0,25.0,-2.0);
		glEnd();

		glBlendFunc(GL_ONE, GL_ONE);

		glBindTexture(GL_TEXTURE_2D,idSprite);

		glBegin(GL_QUADS);
			glTexCoord2f(0.0,0.0);glVertex3f(0.0,0.0,-2.0);
			glTexCoord2f(1.0,0.0);glVertex3f(25.0,0.0,-2.0);
			glTexCoord2f(1.0,1.0);glVertex3f(25.0,25.0,-2.0);
			glTexCoord2f(0.0,1.0);glVertex3f(0.0,25.0,-2.0);
		glEnd();

	glPopMatrix();

	glEnable(GL_DEPTH_TEST);						
	glDisable(GL_BLEND);
}

void RenderizaFondo()
{
	glBindTexture(GL_TEXTURE_2D,idTexturaFondo);
	
	glBegin(GL_QUADS);
		glTexCoord2f(0.0,0.35);glVertex3f(0.0,0.0,0.0);
		glTexCoord2f(1.0,0.35);glVertex3f(g_ventanaGL->m_ancho+100,0.0,0.0);
		glTexCoord2f(1.0,1.0);glVertex3f(g_ventanaGL->m_ancho+100,g_ventanaGL->m_alto,0.0);
		glTexCoord2f(0.0,1.0);glVertex3f(0.0,g_ventanaGL->m_alto,0.0);
	glEnd();
}

void RenderizaPresentacion()
{
	glBindTexture(GL_TEXTURE_2D,idTexturaPresentacion);
	
	glBegin(GL_QUADS);
		glTexCoord2f(0.0,0.0);glVertex3f(0.0,0.0,0.0);
		glTexCoord2f(1.0,0.0);glVertex3f(g_ventanaGL->m_ancho,0.0,0.0);
		glTexCoord2f(1.0,1.0);glVertex3f(g_ventanaGL->m_ancho,g_ventanaGL->m_alto,0.0);
		glTexCoord2f(0.0,1.0);glVertex3f(0.0,g_ventanaGL->m_alto,0.0);
	glEnd();
}

void RenderizaGameOver()
{
	glBindTexture(GL_TEXTURE_2D,idTexturaFinal);
	
	glBegin(GL_QUADS);
		glTexCoord2f(0.0,0.0);glVertex3f(0.0,0.0,0.0);
		glTexCoord2f(1.0,0.0);glVertex3f(g_ventanaGL->m_ancho,0.0,0.0);
		glTexCoord2f(1.0,1.0);glVertex3f(g_ventanaGL->m_ancho,g_ventanaGL->m_alto,0.0);
		glTexCoord2f(0.0,1.0);glVertex3f(0.0,g_ventanaGL->m_alto,0.0);
	glEnd();
}

void RenderizaProtagonista()
{
	if(protagonista.Estado==VIVO)
		RenderizaSprite64x64(MidTexturaProtagonista[protagonista.Frame],idTexturaProtagonista[protagonista.Frame],protagonista.PosX,protagonista.PosY,false);
	else if(protagonista.Estado==EXPLOTANDO)
		RenderizaSprite64x64(MidTexturaExplosionProtagonista[protagonista.Frame],idTexturaExplosionProtagonista[protagonista.Frame],protagonista.PosX,protagonista.PosY,false);
}

void RenderizaMalos()
{
	for(int fila=0;fila<FILAS;fila++)
	{
		for(int columna=0;columna<COLUMNAS;columna++)
		{
			if(malo[fila][columna].Estado==VIVO)
			{				
				RenderizaSprite64x64(MidTexturaMalo[malo[fila][columna].Frame],idTexturaMalo[malo[fila][columna].Frame],malo[fila][columna].PosX,malo[fila][columna].PosY,true);
			}
			else if(malo[fila][columna].Estado==EXPLOTANDO)
			{
				RenderizaSprite64x64(MidTexturaExplosionMalo[malo[fila][columna].Frame],idTexturaExplosionMalo[malo[fila][columna].Frame],malo[fila][columna].PosX,malo[fila][columna].PosY,true);
			}
		}
	}
}

void RenderizaDisparos()
{
	int i;

	for(i=0;i<protagonista.Disparos.size();i++)
		RenderizaSprite32x32(MidTexturaLaserProtagonista,idTexturaLaserProtagonista,protagonista.Disparos[i].PosX-0.05,protagonista.Disparos[i].PosY+0.1,false);

	for(i=0;i<DisparosMalos.size();i++)
		RenderizaSprite32x32(MidTexturaLaserMalo,idTexturaLaserMalo,DisparosMalos[i].PosX,DisparosMalos[i].PosY,true);
}

void RenderizaDebug()
{
	glDisable(GL_DEPTH_TEST);
	glDisable(GL_BLEND);

	int i;

	for(i=0;i<DisparosMalos.size();i++)
	{
		glBegin(GL_QUADS);
			glVertex3f(DisparosMalos[i].PosX+CajaColisionDisparoMalo.izquierda,DisparosMalos[i].PosY+CajaColisionDisparoMalo.abajo,0.0);
			glVertex3f(DisparosMalos[i].PosX+CajaColisionDisparoMalo.derecha,DisparosMalos[i].PosY+CajaColisionDisparoMalo.abajo,0.0);
			glVertex3f(DisparosMalos[i].PosX+CajaColisionDisparoMalo.derecha,DisparosMalos[i].PosY+CajaColisionDisparoMalo.arriba,0.0);
			glVertex3f(DisparosMalos[i].PosX+CajaColisionDisparoMalo.izquierda,DisparosMalos[i].PosY+CajaColisionDisparoMalo.arriba,0.0);
		glEnd();
	}

	for(i=0;i<protagonista.Disparos.size();i++)
	{
		glBegin(GL_QUADS);
			glVertex3f(protagonista.Disparos[i].PosX+CajaColisionDisparoBueno.izquierda,protagonista.Disparos[i].PosY+CajaColisionDisparoBueno.abajo,0.0);
			glVertex3f(protagonista.Disparos[i].PosX+CajaColisionDisparoBueno.derecha,protagonista.Disparos[i].PosY+CajaColisionDisparoBueno.abajo,0.0);
			glVertex3f(protagonista.Disparos[i].PosX+CajaColisionDisparoBueno.derecha,protagonista.Disparos[i].PosY+CajaColisionDisparoBueno.arriba,0.0);
			glVertex3f(protagonista.Disparos[i].PosX+CajaColisionDisparoBueno.izquierda,protagonista.Disparos[i].PosY+CajaColisionDisparoBueno.arriba,0.0);
		glEnd();
	}

	for(int fila=0;fila<FILAS;fila++)
	{
		for(int columna=0;columna<COLUMNAS;columna++)
		{
			if(malo[fila][columna].Estado==VIVO)
			{				
				glBegin(GL_QUADS);
					glVertex3f(malo[fila][columna].PosX+CajaColisionMalos[malo[fila][columna].Frame].izquierda,malo[fila][columna].PosY+CajaColisionMalos[malo[fila][columna].Frame].abajo,0.0);
					glVertex3f(malo[fila][columna].PosX+CajaColisionMalos[malo[fila][columna].Frame].derecha,malo[fila][columna].PosY+CajaColisionMalos[malo[fila][columna].Frame].abajo,0.0);
					glVertex3f(malo[fila][columna].PosX+CajaColisionMalos[malo[fila][columna].Frame].derecha,malo[fila][columna].PosY+CajaColisionMalos[malo[fila][columna].Frame].arriba,0.0);
					glVertex3f(malo[fila][columna].PosX+CajaColisionMalos[malo[fila][columna].Frame].izquierda,malo[fila][columna].PosY+CajaColisionMalos[malo[fila][columna].Frame].arriba,0.0);
				glEnd();
			}
		}
	}

	glBegin(GL_QUADS);
		glVertex3f(protagonista.PosX+CajaColisionProtagonista.izquierda,protagonista.PosY+CajaColisionProtagonista.abajo,0.0);
		glVertex3f(protagonista.PosX+CajaColisionProtagonista.derecha,protagonista.PosY+CajaColisionProtagonista.abajo,0.0);
		glVertex3f(protagonista.PosX+CajaColisionProtagonista.derecha,protagonista.PosY+CajaColisionProtagonista.arriba,0.0);
		glVertex3f(protagonista.PosX+CajaColisionProtagonista.izquierda,protagonista.PosY+CajaColisionProtagonista.arriba,0.0);
	glEnd();
}

//#define DEBUG 

void RenderScene()
{
	tActual=GetTickCount()-TiempoInicio;

	if(tActual<=3500)
	{
		RenderizaPresentacion();
	}
	else if(tActual<=6000)
	{
		glClearColor(sin(tActual*0.001),sin(tActual*0.001),sin(tActual*0.001),0.0);
		glRasterPos2f(350.0,300.0);
		glPrint("PRESENTA");
	}
	else if(tActual<=15000)
	{
		glRasterPos2f(10.0,500.0);
		glPrint("Hace mucho tiempo, en una galaxia muy  lejana,  se   celebraba");
		glRasterPos2f(10.0,450.0);
		glPrint("la onceaba edicion de    una  party  llamada  Arroutada, en el");
		glRasterPos2f(10.0,400.0);
		glPrint("susodicho evento a las 6 de    la   tarde   los  organizadores");
		glRasterPos2f(10.0,350.0);
		glPrint("decidieron tocar la marrana a los  concursantes proponiendoles");
		glRasterPos2f(10.0,300.0);
		glPrint("hacer un juego en el que tendria que   salir como protagonista");
		glRasterPos2f(10.0,250.0);
		glPrint("principal un pinguino, animal vulgarmente conocido como pajaro");
		glRasterPos2f(10.0,200.0);
		glPrint("bobo, como uno de los participantes apodado KneDa ya no queria");
		glRasterPos2f(10.0,150.0);
		glPrint("bajarse mas porno de la lan pues decidio   crear uno, y lo que");
		glRasterPos2f(10.0,100.0);
		glPrint("salio fue esto XDDDDDDD");
	}
	else if(tActual<=18000)
		glClearColor(cos(tActual*0.005),cos(tActual*0.005),cos(tActual*0.005),0.0);
	else
	{
		if(tActual<=20000)
		{
			glDisable(GL_TEXTURE_2D);
			glPushMatrix();
			glRasterPos2f(250.0,300.0);
			glColor3f(1.0,0.0,0.0);
			glScalef(20.0,20.0,20.0);
			glPrint("-=========READY=========-");
			glPopMatrix();
			glEnable(GL_TEXTURE_2D);

			glColor3f(1.0,1.0,1.0);

			if(protagonista.Estado==VIVO)
			{
				RenderizaFondo();
				RenderizaMalos();

				RenderizaProtagonista();
				RenderizaDisparos();
			}
			else if(protagonista.Estado==MUERTO)
			{
				RenderizaGameOver();
			}
		}
		else if(tActual<=22000)
		{
			glDisable(GL_TEXTURE_2D);
			glPushMatrix();
			glRasterPos2f(250.0,300.0);
			glColor3f(0.0,1.0,0.0);
			glPrint("-=========GOOOOOOOOOOO=========-");
			glPopMatrix();
			glEnable(GL_TEXTURE_2D);

			glColor3f(1.0,1.0,1.0);

			if(protagonista.Estado==VIVO)
			{
				RenderizaFondo();
				RenderizaMalos();

				RenderizaProtagonista();
				RenderizaDisparos();
			}
			else if(protagonista.Estado==MUERTO)
			{
				RenderizaGameOver();
			}
		}
		else
		{
			glColor3f(1.0,1.0,1.0);

			if(protagonista.Estado==VIVO)
			{
				RenderizaFondo();
				RenderizaMalos();

				RenderizaProtagonista();
				RenderizaDisparos();
			}
			else if(protagonista.Estado==MUERTO)
			{
				RenderizaGameOver();
			}
		}
	}

}
