//------------------------------------------------------------------------------
// Includes
//------------------------------------------------------------------------------
#include <windows.h> // Header pour les Applications Windows
#include <stdlib.h>
#include <stdio.h> // Header d'Entrée/Sortie Standard
#include <GL/glut.h> // Header OpenGL Utility Toolkit (GLUT)
#include <string.h> // Header pour sprintf
//------------------------------------------------------------------------------
// Constantes
//------------------------------------------------------------------------------
#define EXIT {fclose(fichier);return -1;} // ferme un fichier
#define CTOI(C) (*(int*)&C) // récupère en int un nombre pointé par un char*
//------------------------------------------------------------------------------
// Variables
//------------------------------------------------------------------------------
double a=0; // pour la rotation
int id_tex=1, id_a1=4, id_a2=1, id_b1=1, id_b2=1, id_d=3;
GLenum TabAlpha[8] = {GL_NEVER, GL_LESS, GL_EQUAL, GL_LEQUAL, GL_GREATER, GL_NOTEQUAL, GL_GEQUAL, GL_ALWAYS};
GLenum TabBlend[9] = {GL_ZERO, GL_ONE, GL_DST_COLOR, GL_ONE_MINUS_DST_COLOR, GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_DST_ALPHA, GL_ONE_MINUS_DST_ALPHA, GL_SRC_ALPHA_SATURATE};
GLenum TabDepth[8] = {GL_NEVER, GL_LESS, GL_EQUAL, GL_LEQUAL, GL_GREATER, GL_NOTEQUAL, GL_GEQUAL, GL_ALWAYS};
char *TabTexName[7] = {"grille.tga", "shotgun.tga", "sky.tga", "sol2.tga", "crosshd.tga", "fireboule.tga", "fireboule2.tga" };
char *TabAlphaName[8] = {"GL_NEVER", "GL_LESS", "GL_EQUAL", "GL_LEQUAL", "GL_GREATER", "GL_NOTEQUAL", "GL_GEQUAL", "GL_ALWAYS"};
char *TabBlendName[9] = {"GL_ZERO", "GL_ONE", "GL_DST_COLOR", "GL_ONE_MINUS_DST_COLOR", "GL_SRC_ALPHA", "GL_ONE_MINUS_SRC_ALPHA", "GL_DST_ALPHA", "GL_ONE_MINUS_DST_ALPHA", "GL_SRC_ALPHA_SATURATE"};
char *TabDepthName[8] = {"GL_NEVER", "GL_LESS", "GL_EQUAL", "GL_LEQUAL", "GL_GREATER", "GL_NOTEQUAL", "GL_GEQUAL", "GL_ALWAYS"};
GLuint Name[50];
int DepthOn=1, BlendOn=1, AlphaOn=1;
// Gestion du temps
struct TEMPS
{
int tps; // temps depuis le début
float non_ecoule; // temps non ecoulé pendant la pause
float ecart; // ecart de temps entre deux frames
long int frame; // nombre de frames depuis le début
int frame_fps; // nombre réinitialisé pour les FPS
int base; // temps réinitialisé pour les FPS
int pause; // pause du temps
float fps; // nombre de FPS
};
struct TEMPS temps;
//------------------------------------------------------------------------------
// Charge une image TGA 32 bits non compressée
//------------------------------------------------------------------------------
int LoadTGA(char *filename, int nb) // Loads A TGA File Into Memory
{
GLubyte TGAheader[12]={0,0,2,0,0,0,0,0,0,0,0,0};// Uncompressed TGA Header
GLubyte TGAcompare[12]; // Used To Compare TGA Header
GLubyte header[6]; // First 6 Useful Bytes From The Header
int imageSize; // Used To Store The Image Size When Setting Aside Ram
int type; // Set The Default GL Mode To RBGA (32 BPP)
GLubyte *imageData; // Données de l'image, jusqu'à 32 bits
int bpp; // Bits Par Pixel de l'image
int Width, Height; // Taille de l'image
// Lit le fichier et son header
FILE *fichier = fopen(filename, "rb"); // Open The TGA File
if (fread(TGAcompare,1,sizeof(TGAcompare),fichier)!=sizeof(TGAcompare)) EXIT; // Are There 12 Bytes To Read?
if (memcmp(TGAheader,TGAcompare,sizeof(TGAheader))!=0) EXIT; // Does The Header Match What We Want?
if (fread(header,1,sizeof(header),fichier)!=sizeof(header)) EXIT; // If So Read Next 6 Header Bytes
// Récupère les infos de l'image
Width = header[1] * 256 + header[0]; // Determine The TGA Width (highbyte*256+lowbyte)
Height = header[3] * 256 + header[2]; // Determine The TGA Height (highbyte*256+lowbyte)
bpp = header[4]; // Grab The TGA's Bits Per Pixel (24 or 32)
if (bpp==24) type=GL_RGB; // If So Set The 'type' To GL_RGB
else type=GL_RGBA; // If So Set The 'type' To GL_RGBA
imageSize = Width*Height*bpp/8; // Calculate The Memory Required For The TGA Data
// Charge l'image
imageData=(GLubyte *)malloc(imageSize); // Reserve Memory To Hold The TGA Data
if (fread(imageData, 1, imageSize, fichier)!=imageSize) // Does The Image Size Match The Memory Reserved?
{
free ( imageData );
EXIT;
}
fclose (fichier); // Close The File
// Inverse R et B
int t, i;
for(i=0; i<imageSize;i+=bpp/8) // Loop Through The Image Data
{ // Swaps The 1st And 3rd Bytes ('R'ed and 'B'lue)
t=imageData[i]; // Temporarily Store The Value At Image Data 'i'
imageData[i]=imageData[i+2]; // Set The 1st Byte To The Value Of The 3rd Byte
imageData[i+2]=t; // Set The 3rd Byte To The Value In 'temp' (1st Byte Value)
}
// Build A Texture From The Data
glPixelStorei(GL_UNPACK_ALIGNMENT,1);
glGenTextures(nb, &Name[nb]); // Generate OpenGL texture IDs
glBindTexture(GL_TEXTURE_2D, Name[nb]); // Bind Our Texture
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_REPEAT);
glTexImage2D(GL_TEXTURE_2D, 0, type, Width, Height, 0, type, GL_UNSIGNED_BYTE, imageData);
// target, mipmap lvl, nb coul, larg, haut, large bord, type coul, code compo, img)
return Name[nb];
}
//------------------------------------------------------------------------------
// Fonction de redimensionnement
//------------------------------------------------------------------------------
void Reshape(int w,int h)
{
glViewport(0,0,w,h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(45,(float)(w)/(float)(h),1,100);
}
//------------------------------------------------------------------------------
// Fonction d'initialisation
//------------------------------------------------------------------------------
void InitGL()
{
glClearColor(0.0f, 0.0f, 0.0f, 0.0f); // Arrière Plan Noir
glClearDepth(1.0f); // Configuration de la profondeur du buffer
glAlphaFunc(TabAlpha[id_a1],id_a2*0.1);
if (AlphaOn) glEnable(GL_ALPHA_TEST);
else glDisable(GL_ALPHA_TEST);
glBlendFunc(TabBlend[id_b1], TabBlend[id_b2]);
if (BlendOn) glEnable(GL_BLEND);
else glDisable(GL_BLEND);
glDepthFunc(TabDepth[id_d]);
if (DepthOn) glEnable(GL_DEPTH_TEST);
else glDisable(GL_DEPTH_TEST);
glShadeModel(GL_SMOOTH); // Smooth Shading Activé, il doit lisser les formes (?)
glEnable(GL_TEXTURE_2D); // Textures 2D activées
glHint(GL_FOG_HINT,GL_NICEST);
glHint(GL_LINE_SMOOTH_HINT,GL_NICEST);
glHint(GL_PERSPECTIVE_CORRECTION_HINT,GL_NICEST);
glHint(GL_POINT_SMOOTH_HINT,GL_NICEST);
glHint(GL_POLYGON_SMOOTH_HINT,GL_NICEST);
}
//------------------------------------------------------------------------------
// Modifie le titre de la fenêtre
//------------------------------------------------------------------------------
void Titre ( )
{
char title[255];
sprintf(title, "Tex = %s (%d)", TabTexName[id_tex-1], id_tex);
if (AlphaOn)
sprintf(title, "%s | Alpha = %s (%d) - %0.1f", title, TabAlphaName[id_a1], id_a1, id_a2*0.1);
if (BlendOn)
sprintf(title, "%s | Blend = %s (%d) - %s (%d)", title, TabBlendName[id_b1], id_b1, TabBlendName[id_b2], id_b2);
if (DepthOn)
sprintf(title, "%s | Depth = %s (%d)", title, TabDepthName[id_d], id_d);
if ( temps.tps - temps.base > 83 ) // Si ca fait une seconde
{
temps.fps = temps.frame_fps * 1000.0 / ( temps.tps - temps.base );
temps.base = temps.tps; // Le temps de base est actualisé
temps.frame_fps = 0; // On recommence à compter
sprintf ( title, "%s | FPS : %4.2f", title, temps.fps );
}
glutSetWindowTitle(title);
InitGL();
}
//------------------------------------------------------------------------------
// Gestion des touches standard
//------------------------------------------------------------------------------
void GestionClavier(unsigned char key, int x, int y)
{
switch (key)
{
//-----------------------------
case 'a' : // activation ou désactivation APLHA
AlphaOn = 1-AlphaOn;
Titre();
break;
case 'z' : // 1er paramètre ALPHA modifié
if (id_a1 < 7) id_a1++; else id_a1=0;
Titre();
break;
case 'e' : // 2è paramètre ALPHA modifié
if (id_a2 < 10) id_a2++; else id_a2=0;
Titre();
break;
//-----------------------------
case 'b' : // activation ou désactivation BLEND
BlendOn = 1-BlendOn;
Titre();
break;
case 'v' : // 1er paramètre BLEND modifié
if (id_b1 < 8) id_b1++; else id_b1=0;
Titre();
break;
case 'n' : // 2è paramètre BLEND modifié
if (id_b2 < 8) id_b2++; else id_b2=0;
Titre();
break;
case 32 : // 1er et 2è paramètre BLEND modifiés
id_b2++;
if (id_b2 == 9) { id_b2 = 0; id_b1++; }
if (id_b1 == 8) { id_b2 = 0; id_b1 = 0; }
Titre();
break;
//-----------------------------
case 'd' : // activation ou désactivation DEPTH
DepthOn = 1-DepthOn;
Titre();
break;
case 'f' : // 2è paramètre DEPTH modifié
if (id_d < 7) id_d++; else id_d=0;
Titre();
break;
//-----------------------------
case 13 : // modification de la texture
if (id_tex < 7) id_tex++; else id_tex=1;
Titre();
break;
//-----------------------------
case 27 : // quitter
exit(0);
break;
default :
Titre();
break;
}
}
//------------------------------------------------------------------------------
// Fonction de dessin
//------------------------------------------------------------------------------
void Draw()
{
// Mise à jour du temps avec glut
temps.frame++;
temps.frame_fps++;
temps.ecart = (double)(( glutGet ( GLUT_ELAPSED_TIME ) - temps.tps - 0.0001) / 1000);
temps.tps = glutGet ( GLUT_ELAPSED_TIME );
glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
glMatrixMode(GL_MODELVIEW);
a+=temps.ecart*100;
// cube
glLoadIdentity();
gluLookAt(3,2,3,0,0,0,0,1,0);
glRotated(a,0,1,0);
glEnable(GL_TEXTURE_2D);
glDisable(GL_COLOR);
glBindTexture(GL_TEXTURE_2D, id_tex);
glBegin(GL_QUADS);
glTexCoord2i(0,0);glVertex3i(-1,-1,-1);
glTexCoord2i(1,0);glVertex3i(+1,-1,-1);
glTexCoord2i(1,1);glVertex3i(+1,+1,-1);
glTexCoord2i(0,1);glVertex3i(-1,+1,-1);
glTexCoord2i(0,0);glVertex3i(-1,-1,+1);
glTexCoord2i(1,0);glVertex3i(+1,-1,+1);
glTexCoord2i(1,1);glVertex3i(+1,+1,+1);
glTexCoord2i(0,1);glVertex3i(-1,+1,+1);
glTexCoord2i(0,0);glVertex3i(+1,-1,-1);
glTexCoord2i(1,0);glVertex3i(+1,-1,+1);
glTexCoord2i(1,1);glVertex3i(+1,+1,+1);
glTexCoord2i(0,1);glVertex3i(+1,+1,-1);
glTexCoord2i(0,0);glVertex3i(-1,-1,-1);
glTexCoord2i(1,0);glVertex3i(-1,-1,+1);
glTexCoord2i(1,1);glVertex3i(-1,+1,+1);
glTexCoord2i(0,1);glVertex3i(-1,+1,-1);
glTexCoord2i(0,0);glVertex3i(-1,+1,-1);
glTexCoord2i(1,0);glVertex3i(+1,+1,-1);
glTexCoord2i(1,1);glVertex3i(+1,+1,+1);
glTexCoord2i(0,1);glVertex3i(-1,+1,+1);
glTexCoord2i(0,0);glVertex3i(-1,-1,+1);
glTexCoord2i(1,0);glVertex3i(+1,-1,+1);
glTexCoord2i(1,1);glVertex3i(+1,-1,-1);
glTexCoord2i(0,1);glVertex3i(-1,-1,-1);
glEnd();
glDisable(GL_TEXTURE_2D);
glEnable(GL_COLOR);
glBegin(GL_QUADS);
// derrière
glColor3f(0,0,0); glVertex3f(-0.1,0.1,-0.1);
glColor3f(1,0,0); glVertex3f(0.1,0.1,-0.1);
glColor3f(1,1,0); glVertex3f(0.1,-0.1,-0.1);
glColor3f(0,1,0); glVertex3f(-0.1,-0.1,-0.1);
// devant
glColor3f(0,0,1); glVertex3f(-0.1,0.1,0.1);
glColor3f(1,0,1); glVertex3f(0.1,0.1,0.1);
glColor3f(1,1,1); glVertex3f(0.1,-0.1,0.1);
glColor3f(0,1,1); glVertex3f(-0.1,-0.1,0.1);
// gauche
glColor3f(0,0,0); glVertex3f(-0.1,0.1,-0.1);
glColor3f(0,1,0); glVertex3f(-0.1,-0.1,-0.1);
glColor3f(0,1,1); glVertex3f(-0.1,-0.1,0.1);
glColor3f(0,0,1); glVertex3f(-0.1,0.1,0.1);
// droite
glColor3f(1,0,0); glVertex3f(0.1,0.1,-0.1);
glColor3f(1,1,0); glVertex3f(0.1,-0.1,-0.1);
glColor3f(1,1,1); glVertex3f(0.1,-0.1,0.1);
glColor3f(1,0,1); glVertex3f(0.1,0.1,0.1);
// haut
glColor3f(0,0,0); glVertex3f(-0.1,0.1,-0.1);
glColor3f(1,0,0); glVertex3f(0.1,0.1,-0.1);
glColor3f(1,0,1); glVertex3f(0.1,0.1,0.1);
glColor3f(0,0,1); glVertex3f(-0.1,0.1,0.1);
// bas
glColor3f(0,1,0); glVertex3f(-0.1,-0.1,-0.1);
glColor3f(1,1,0); glVertex3f(0.1,-0.1,-0.1);
glColor3f(1,1,1); glVertex3f(0.1,-0.1,0.1);
glColor3f(0,1,1); glVertex3f(-0.1,-0.1,0.1);
glEnd();
glColor3f(1,1,1);
glutSwapBuffers();
glutPostRedisplay();
}
//------------------------------------------------------------------------------
// Fonction Principale
//------------------------------------------------------------------------------
int main( int argc, char *argv[ ], char *envp[ ] )
{
glutInit(&argc,argv);
glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE | GLUT_DEPTH);
glutInitWindowSize(640,480);
glutInitWindowPosition(50,50);
glutCreateWindow("");
Titre();
InitGL();
LoadTGA("grille.tga", 1);
LoadTGA("shotgun.tga", 1);
LoadTGA("sky.tga", 1);
LoadTGA("sol2.tga", 1);
LoadTGA("crosshd.tga", 1);
LoadTGA("fireboule.tga", 1);
LoadTGA("fireboule2.tga", 1);
glutReshapeFunc(Reshape);
glutDisplayFunc(Draw);
glutKeyboardFunc(GestionClavier);
glutMainLoop();
return 0;
}
//------------------------------------------------------------------------------
// THE END
//------------------------------------------------------------------------------