Article     Discussion     Modifier     Historique     Forums     Salon IRC

OpenGL:Glow

Un article de Games Creators Network.

Effets de glow en OpenGL
Effets de glow en OpenGL

Dans cet article, nous allons traiter d'une technique coûteuse mais gratifiante : l'effet de halo, ou glow.

Pour ce faire, nous utiliserons l'extension GLU, l'API Win32, ainsi que le compilateur de l'IDE Dev-C++. Néanmoins, cet exemple pourra être utilisé avec n'importe quel autre gestionnaire de fenêtre, ou compilateur, sous réserve d'y apporter quelques modifications.

Le modèle de base de notre application est extrait du site NeHe. Pour plus d'explications sur ce type d'application OpenGL avec Win32, consultez NeHe.gamedev.net.

Nous utiliserons aussi la bibliothèque de chargement de fichier Targa de Nate Miller pour nos textures.

Un exemple du rendu de notre programme est visible sur l'image de droite. Avec un cube texturé blanc, et un cube texturé avec un effet de glow en couleur.

Sommaire

[modifier] Avant toute chose

Nous devons définir les bibliothèques que nous allons utiliser, y compris celle de chargement des fichiers Targa.

/*****************************************************
*               FICHIERS EN-TETE                     *
******************************************************/
#include <windows.h>		// Windows
#include <gl\gl.h>		// OpenGL
#include <gl\glu.h>		// OpenGL Utility
#include "tga.h"

Nous allons aussi déclarer une variable float Rot, qui nous servira à faire tourner notre cube, pour mieux apprécier l'effet. Nous déclarons aussi une variable de type entier textureGlow, qui contiendra l'identifiant de la texture de glow.

/*****************************************************
*             DECLARATIONS DES VARIABLES             *
******************************************************/
float Rot = 0;        // rotation du cube
int textureGlow;      // identifiant de la texture de glow

Nous allons aussi en profiter pour pré-déclarer nos fonctions

LRESULT	CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
GLuint EmptyTexture( void );
void RenderToTexture( void );
void RenderGlow( int times );
void RenderCube( void );

[modifier] Initialisation d'OpenGL

Commençons notre article en analysant notre initialisation d'OpenGL. Il n'y a aucune nouveauté, si ce n'est que nous chargeons une texture pour notre cube, et une autre pour notre texture de glow.

int InitGL(GLvoid) {
	glShadeModel(GL_SMOOTH);
	glClearColor(0.0f, 0.0f, 0.0f, 0.5f);
	glClearDepth(1.0f);
	glEnable(GL_DEPTH_TEST);
	glDepthFunc(GL_LEQUAL);
	glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
 
	loadTGA("GCN.tga",1);     // Chargement de la texture du cube
	textureGlow = EmptyTexture();
 
	return TRUE;
}

[modifier] Création de la texture

Pour stocket notre texture de glow, il va d'abord falloir la créer, voici donc le but de cette fonction.

GLuint EmptyTexture( void ) {
	GLuint txtnumber;
	unsigned int* data;
        // On alloue de la place pour notre texture de 512x512
	data = (unsigned int*)new GLuint[((512 * 512)* 4 * sizeof(unsigned int))];
        // On nettoie les données en les remplissant de 0
	ZeroMemory(data,((512 * 512)* 4 * sizeof(unsigned int)));
 
	glGenTextures(1, &txtnumber); // On génère un identifiant
        glEnable(GL_TEXTURE_2D);
	glBindTexture(GL_TEXTURE_2D, txtnumber);
        // On effectue la première passe
	glTexImage2D(GL_TEXTURE_2D, 0, 4, 512, 512, 0, GL_RGBA, GL_UNSIGNED_BYTE, data);
	glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
	glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
 
	delete [] data;
 
        glDisable(GL_TEXTURE_2D);
 
	return txtnumber;
}

[modifier] Génération de la texture de glow

Il va maintenant falloir commencer à se pencher sur l'effet de glow.

En fait, cet effet est assez simple, le but est de copié le contenu de l'écran dans une texture, puis ensuite de plaquer cette texture de nombreuses fois à l'écran, tout en la grossissant, et en la rendant transparente.

Nous allons donc ici copié le contenu de l'écran vers notre texture grace à la fonction glCopyTexImage2D.

void RenderToTexture( void ) {
    RenderCube(  );                            //On dessine notre cube
    glEnable(GL_TEXTURE_2D);
    glBindTexture(GL_TEXTURE_2D, textureGlow); //On selectionne notre texture de glow
    // Et on copie le contenu de l'écran vers la texture
    glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 0, 0, 512, 512, 0);
 
    glClearColor(0., 0., 0., 0.);              // On efface l'écran avec du noir
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);	
 
    glDisable(GL_TEXTURE_2D);                  //On deselectionne notre texture
}

[modifier] Dessin du glow

Maintenant que nous avons notre "texture de scène", il va falloir la plaquer sur l'écran. C'est le but de cette fonction.

void RenderGlow( int times ) {
 
        //On se projette en vision orthogonale (2D)
	glMatrixMode(GL_PROJECTION);
	glPushMatrix();
	glLoadIdentity();
	glOrtho( 0, 512 , 0, 512, -1, 1 );
	glMatrixMode(GL_MODELVIEW);
	glPushMatrix();
	glLoadIdentity();
 
	glEnable(GL_TEXTURE_2D);	
	glBindTexture(GL_TEXTURE_2D,textureGlow);            // On selectionne notre texture
	glEnable(GL_BLEND);
	glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);   // activation de la transparence
 
	glBegin(GL_QUADS);
        for (int i=0; i<times; i++) {
	    glColor4f(1., 1., 1., 0.3/(float)i); //Transparence croissante (amusez vous avec)
 
            glTexCoord2f(0+((float)i/75.f),0+((float)i/75.f)); // on "écarte" notre 
	    glVertex2f(0,0);                                   // texture progressivement
 
            glTexCoord2f(0+((float)i/75.f),1-((float)i/75.f));
	    glVertex2f(0,512);
 
            glTexCoord2f(1-((float)i/75.f),1-((float)i/75.f));
	    glVertex2f(512,512);
 
            glTexCoord2f(1-((float)i/75.f),0+((float)i/75.f));
	    glVertex2f(512,0);
        }
	glEnd();
 
        // On repasse en vision en perspective 
	glMatrixMode( GL_PROJECTION );
	glPopMatrix();
	glMatrixMode( GL_MODELVIEW );
	glPopMatrix();
        glDisable(GL_BLEND);
	glEnable(GL_DEPTH_TEST);
	glDisable(GL_TEXTURE_2D);
	glBindTexture(GL_TEXTURE_2D,0);
}

[modifier] Rendu de notre cube

Cette fonction se passe de commentaires, nous dessinons notre cube texturé, lui ajoutons quelques dégradés de couleurs, et le faisons tourner.

void RenderCube( void ) {
     glPushMatrix();
     glEnable(GL_DEPTH_TEST);
     glRotatef(Rot,1,1,0);
     glScalef(10,10,10);
     glEnable(GL_TEXTURE_2D);
     glBindTexture(GL_TEXTURE_2D, 1);              
 
     glBegin( GL_QUADS );
              //FACE 1
              glColor4f(0.,1.,1.,1.);
              glTexCoord2d(1,1);
              glVertex3i(1,1,1);
 
              glColor4f(1.,0.,1.,1.);
              glTexCoord2d(1,0);
              glVertex3i(1,-1,1);
 
              glColor4f(1.,1.,0.,1.);
              glTexCoord2d(0,0);
              glVertex3i(-1,-1,1);
 
              glColor4f(1.,0.,1.,1.);
              glTexCoord2d(0,1);
              glVertex3i(-1,1,1);
 
              //FACE 2
              glColor4f(0.,1.,1.,1.);
              glTexCoord2d(0,0);
              glVertex3i(1,1,-1);
 
              glColor4f(1.,0.,1.,1.);
              glTexCoord2d(1,0);
              glVertex3i(1,-1,-1);
 
              glColor4f(1.,1.,0.,1.);
              glTexCoord2d(1,1);
              glVertex3i(-1,-1,-1);
 
              glColor4f(1.,0.,1.,1.);
              glTexCoord2d(0,1);
              glVertex3i(-1,1,-1);
 
              //FACE 3
              glColor4f(0.,1.,1.,1.);
              glTexCoord2d(0,0);
              glVertex3i(1,1,1);
 
              glColor4f(1.,0.,1.,1.);
              glTexCoord2d(1,0);
              glVertex3i(1,-1,1);
 
              glColor4f(1.,1.,0.,1.);
              glTexCoord2d(1,1);
              glVertex3i(1,-1,-1);
 
              glColor4f(1.,0.,1.,1.);
              glTexCoord2d(0,1);
              glVertex3i(1,1,-1);
 
              //FACE 4
              glColor4f(0.,1.,1.,1.);
              glTexCoord2d(0,0);
              glVertex3i(-1,1,1);
 
              glColor4f(1.,0.,1.,1.);
              glTexCoord2d(0,1);
              glVertex3i(-1,-1,1);
 
              glColor4f(1.,1.,0.,1.);
              glTexCoord2d(1,1);
              glVertex3i(-1,-1,-1);
 
              glColor4f(1.,0.,1.,1.);
              glTexCoord2d(1,0);
              glVertex3i(-1,1,-1);
 
              //FACE 5
              glColor4f(0.,1.,1.,1.);
              glTexCoord2d(0,0);
              glVertex3i(-1,1,-1);
 
              glColor4f(1.,0.,1.,1.);
              glTexCoord2d(1,0);
              glVertex3i(-1,1,1);
 
              glColor4f(1.,1.,0.,1.);
              glTexCoord2d(1,1);
              glVertex3i(1,1,1);
 
              glColor4f(1.,0.,1.,1.);
              glTexCoord2d(0,1);
              glVertex3i(1,1,-1);
 
              //FACE 6
              glColor4f(0.,1.,1.,1.);
              glTexCoord2d(0,0);
              glVertex3i(-1,-1,-1);
 
              glColor4f(1.,0.,1.,1.);
              glTexCoord2d(1,0);
              glVertex3i(-1,-1,1);
 
              glColor4f(1.,1.,0.,1.);
              glTexCoord2d(1,1);
              glVertex3i(1,-1,1);
 
              glColor4f(1.,0.,1.,1.);
              glTexCoord2d(0,1);
              glVertex3i(1,-1,-1);
     glEnd();
     glDisable(GL_TEXTURE_2D);
 
     glPopMatrix();
 
     Rot += 1;
}

[modifier] Rendu de la scène

Nous pouvons maintenant rendre notre scène simplement en appelent RenderToTexture puis RenderGlow avec comme paramètre le nombre de passes du glow.

int DrawGLScene(GLvoid) {
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
	glLoadIdentity();
	gluLookAt(75,75,75,0,0,0,0,1,0);
        RenderToTexture();
        RenderGlow(20);
	return TRUE;
}


[modifier] Téléchargements

Télécharger les sources

Télécharger l'exécutable

Télécharger les sources + l'exécutable


--NewbiZ 25 aoû 2005 à 01:39 (CEST)

 

Rechercher
Installer l'extension de recherche Plus d'informations

 

Comprendre
Tu me dis, j'oublie. Tu m'enseignes, je me souviens. Tu m'impliques, j'apprends. - Benjamin Franklin

 

Partager
La connaissance est la seule chose qui s'accroit lorsqu'on la partage. - Sacha Boudjema

 

Créer
L'imagination est plus importante que la connaissance. - Albert Einstein

 

 

Le wiki en images Le wiki en images Image du mois: «Snowball: un prototype de jeu développé avec NeL.