Rendu sur texture [opengl] [vc++]

Description

Voilà un petit exemple utilisant la GLUT (pour la création de la fenêtre) qui va vous permettre de créer toutes sortes d'effets spéciaux. En fait le rendu sur texture c'est simplement rendre une image (que l'on affiche pas à l'écran) et copier cette image dans une texture que l'on affichera dans une scène. cela peut vous servir à réaliser une caméra embarqué dans un véhicule, un écran d'ordinateur ou tout autre chose qui aurait besoin d'une texture qui change et en 3D !
Le tout est commenté allègrement !
@+

Source / Exemple :


Le ZIP ou :

#include <gl/glut.h>	// Header pour la GLUT (incluant les headers window.h, glu.h et gl.h)
#include <gl/glaux.h>	// Header pour les fonctions GL auxiliares (chargement texture bitmap, ...)

typedef unsigned short int USHORT;

float rot = 0.0;		// Variable pour la rotation

unsigned int textures[1] = {0};	// Stock la texture

USHORT screenWidth = 300;		// Largeur de notre fenêtre
USHORT screenHeight = 300;		// Hauteur de notre fenêtre
USHORT viewportSize = 256;		// Taille de notre texture (on donnera cette taille
								// a glViewport() afin de copier l'écran dans la texture vide 
								// qui possède cette taille)

void createEmptyTexture(unsigned int textureArray[], int size, int channels, int type, int textureID)										
{
	// Déclare et initialise une variable qui sera capable d'héberger momentanément 
	// les données de l'image de texture
	unsigned int *pTexture = NULL;
	pTexture = new unsigned int [size * size * channels];
	memset(pTexture, 0, size * size * channels * sizeof(unsigned int));

	glGenTextures(1, &textureArray[textureID]);				// Génére un nom de texture							
	glBindTexture(GL_TEXTURE_2D, textureArray[textureID]);	// Active la texture que nous venons de générer
	
	// Définit une texture 2D avec une seule résolution (0)
	glTexImage2D(GL_TEXTURE_2D, 0, channels, size, size, 0, type, GL_UNSIGNED_INT, pTexture);						
	
	//Définit les paramètres du traitement de la texture
	glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
	glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
	
	// La texture est maintenant stocké dans la amémoire de la carte graphique, 
	// nous pouvons donc la supprimer
	delete [] pTexture;
}

void affichage ()										// Affiche la scène
{
	rot+=0.5;	//Incrémente la variable de rotation
	
	glClearColor(0.0f, 0.0f, 0.0f, 0.5);				// Couleur d'arrière-plan du rendu sur texture

	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);	// Efface le tampon chromatique et le tampon de profondeur
	glLoadIdentity();

	glTranslatef(0.0, 0.0, -2.0);

	glClearColor(0.0f, 0.0f, 1.0f, 1.0);				// Couleur d'arrière-plan de la scène
	

	/* Cette partie va nous permettre de dessiner la scène qui sera ensuite copier dans notre texture vide.
	Le principe est de redimensionner la surface de rendu de OpenGL (glViewport()) à la taille de notre 
	texture pour que la surface entière puisse être copiée entièrement dans notre texture vide. 
	Nous copions le rendu vers la texture à l'aide de :

		glCopyTexImage2D(GLenum target, GLint level, GLint internalFormat, GLsizei width,
		GLsizei height, Glint border, GLenum format, GLenum type, const GLvoid *texels)

		target : positionné avec les constantes GL_TEXTURE_2D ou GL_PROXY_TEXTURE_2D
		level : nombre de résolutions de la texture (pour une seule mettre 0)
		internalFormat : indique les composants RVBA, valeurs de luminance ou d'intensité pour
			la description des texels d'une image. Il existe 38 constantes symboliques :
				-GL_ALPHAx (x = rien, 4, 8, 12, 16)
				-GL_LUMINANCEx ( x= rien, 4, 8, 12, 16)
				-GL_LUMINANCEx_ALPHAx (x = rien, 4, 8, 12, 16)
				-GL_LUMINANCE6_ALPHA2, GL_LUMINANCE12_ALPHA4
				-GL_INTENSITYx (x = rien, 4, 8, 12, 16)
				-GL_RGB, GL_R3_G3_B2, GL_RGB4, GL_RGB5, GL_RGB8, GL_RGB10, GL_RGB12, GL_RGB16
				-GL_RGBAx (x = rien, 2, 4, 8, 12, 16)
				-GL_RGB5_A1, GL_RGB10_A2
			ex : GL_R3_G3_B2 demande que les texels soient composés de 3 bites de vert
						, 3 bits de rouge et 2 bits de bleu mais OpenGL peut ne pas vous 
						donner satisfaction car il est uniquement obligé de choisir une représentation 
						interne se rapprochant le plus possible de ce qu'on lui demande.
						Ainsi Gl_LUMINANCE, GL_RGBA, .. sont sympathique dans la mesure où ils ne 
						nous demandent pas de spécifier une résolution
		width et height : fournissent les dimensions de l'image de texture
		border : indique la largeur de la bordure (soit 1 ou 0)
		format et type : décrivent  le format et le type de donnée des données de l'image de texture
			Voici les constantes symboliques que prend format : 
				-GL_COLOR_INDEX, GL_RGB, GL_RGBA, GL_RED, GL_GREEN, GL_BLUE, GL_ALPHA, GL_LUMINANCE, GL_LUMINANCE_ALPHA
			Voici les constantes pour type : 
				GL_BYTE, GL_UNSIGNES_BYTE, GL_SHORT, GL_UNSIGNED_SHORT, GL_INT, GL_UNSIGNED_INT
				GL_FLOAT, GL_BITMAP ou un type de données pixel compactés.
		texels : héberge les données de l'image de texture en décrivant la texture et la bordure

		Ensuite nous redimensionnont la surface de rendu de OpenGL à notre écran.
		Voilà nous disposons de notre rendu sur texture.
		Ici l'exemple est simple mais vous pouvez faire d'autres effets que nous verrons plus tard
		dans d'autres tutoriaux ...

  • /
glPushMatrix(); glRotatef(rot, 0.4f, 0.1f, 1.0f); glViewport(0, 0, viewportSize, viewportSize); glDisable(GL_TEXTURE_2D); glutSolidCube(1.0); glEnable(GL_TEXTURE_2D); glBindTexture(GL_TEXTURE_2D,textures[0]); glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 0, 0, viewportSize, viewportSize, 0); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glViewport(0, 0, screenWidth , screenHeight ); glPopMatrix(); // Ici nous créons un ensemble de 4 polygones carrés afin de rendre la texture que nous avons 'fabriquée' précédemment glPushMatrix(); glTranslatef(0.0, 0.0, 2.0); glRotatef(rot, 0.0f, 1.0f, 0.0f); glTranslatef(0.0, 0.0, -2.0); glBindTexture(GL_TEXTURE_2D, textures[0]); for (USHORT i = 1; i <= 4; i++) { glTranslatef(0.0, 0.0, 2.0); glRotatef(90.0, 0.0f, 1.0f, 0.0f); glTranslatef(0.0, 0.0, -2.0); glBegin(GL_QUADS); glTexCoord2f( 1, 0.0f); glVertex3f(-1, -1, 0); glTexCoord2f( 1, 1); glVertex3f(-1, 1, 0); glTexCoord2f(0.0f, 1); glVertex3f( 1, 1, 0); glTexCoord2f(0.0f, 0.0f); glVertex3f( 1, -1, 0); glEnd(); } glPopMatrix(); glutSwapBuffers(); // Echange des tampons image // (celui sur lequel on a dessiné s'affiche // pendant nous dessinerons sur l'autre) } void redimension (int w, int h) // Notre fonction de redimension de la fenêtre { screenWidth = w; screenHeight = h; glViewport(0, 0, w, h); // Nous ordonnons a OpenGL d'utiliser toutes la surface de la fenêtre pour afficher glMatrixMode(GL_PROJECTION); // Sélection de la matrice de projection glLoadIdentity(); // Initialise la matrice de projection if (h==0) // Calcul de la perspective gluPerspective(80, (float) w, 1.0, 30.0); else gluPerspective(65, (float) w / (float) h, 1.0, 30.0); glMatrixMode(GL_MODELVIEW); // Sélection de la matrice de modélisation-visualisation glLoadIdentity(); // Initialise la matrice de modélisation-visualisation } void clavier (unsigned char key, int x, int y) // Fonction de gestion du clavier { switch (key) { case 27: // Touche 'ESCAPE' exit (0); // Sort de notre programme break; } } void init() { // Paramètre la lumière 0 float lightAmbient[] = {1.0, 1.0, 1.0, 1.0}; glLightfv(GL_LIGHT0, GL_AMBIENT, lightAmbient); float lightDiffuse[] = {1.0, 1.0, 1.0, 1.0}; glLightfv(GL_LIGHT0, GL_DIFFUSE, lightDiffuse); float lightPosition[] = {0.0, 0.0, 0.0, 1.0}; glLightfv(GL_LIGHT0, GL_POSITION, lightPosition); glEnable(GL_LIGHT0); // Active la lumière 0 glEnable(GL_LIGHTING); // Active la gestion de l'éclairage glEnable (GL_DEPTH_TEST); // Active le test de profondeur glEnable (GL_TEXTURE_2D); // Active la gestion des textures createEmptyTexture(textures, viewportSize, 3, GL_RGB, 0);// NOUVEAU : Crée notre texture vide } void main (int argc, char** argv) // Fonction principale (première fonction appelée) { glutInit (&argc, argv); // Initialisation de la GLUT glutInitDisplayMode (GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH); // Affichage en mode RGBAlpha, double tampon image et un tampon de profondeur glutInitWindowSize (300, 300); // Taille de la fenêtre glutCreateWindow ("Rendu sur texture avec OpenGL"); // Titre de la fenêtre (ou argv[0]) init (); glutDisplayFunc (affichage); // Spécifie la fonction avec laquelle on veut afficher glutReshapeFunc (redimension); // Spécifie la fonction avec laquelle on veut redimensionner la fenêtre glutKeyboardFunc (clavier); // Spécifie la fonction avec laquelle on veut gérer les entrés au clavier glutIdleFunc (affichage); // Spécifie la fonction à exécuter si aucun autre événement n'est en attente glutMainLoop (); // Démarre la GLUT en entrant dans une boucle infinie }

Conclusion :


La connaissance appartient à tous !

Codes Sources

A voir également

Vous n'êtes pas encore membre ?

inscrivez-vous, c'est gratuit et ça prend moins d'une minute !

Les membres obtiennent plus de réponses que les utilisateurs anonymes.

Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.

Le fait d'être membre vous permet d'avoir des options supplémentaires.