Pb de FRONT et BACK buffer avec texture

Résolu
gastoudou Messages postés 17 Date d'inscription lundi 23 décembre 2002 Statut Membre Dernière intervention 12 novembre 2004 - 23 oct. 2004 à 21:16
gastoudou Messages postés 17 Date d'inscription lundi 23 décembre 2002 Statut Membre Dernière intervention 12 novembre 2004 - 4 nov. 2004 à 16:44
Bonjour à tous,

Je suis en train de faire un projet en OpenGL pour l'école sur un puzzle 2D. Il y a 16 cases mélangées et on doit les remettre à leur place pour gagner.

Le problème, c'est que quand je clique sur un carré, il me trouve une valeur de pixel dans le BACK buffer complètement en vrac, comme s'il avait gardé la texture en mémoire alors que je fais un nouveau display.
Du coup, la recherche du carré cliqué avorte et rien ne marche.

Si quelqu'un pouvait m'aider, ça serait bien sympa ;)

...Gast...

Voici le code :

***** LE HEADER.H ************************************
#include<stdio.h>
#include<glut.h>
#include<math.h>
#include<stdlib.h>
#include<string.h>
#include<time.h>

#define EXIT {fclose(fichier);return -1;}
#define CTOI(C) (*(int*)&C) //récupère en int un nombre pointé par un char*

// STRUCTURES
struct PUZZLE
{
int x,y;
int R,V,B;
};

struct StructTex
{
GLint NbCouleurs; //Components
GLsizei Largeur; //Width
GLsizei Hauteur; //Height
GLenum TypeCouleurs; //format
GLenum CodageCouleurs; //codage des couleurs
unsigned char* Data; //Tableau des données
};

// VARIABLES
GLuint Nom;
double a=0;

struct StructTex UneTexture[1];
GLuint TextureName[3];

int X_j;
int Y_j;
int carre_sel=16;
int carre_inv=16;
int selection=0;

// Tableaux de structure représentants le puzzle
struct PUZZLE t_puzzle[16];
struct PUZZLE t_puzzle_init[16];

void ActiveTexture(int No);
void AfficheSoluce();
void clavier(unsigned char touche, int x, int y);
void display();
void display_couleur();
void display_soluce();
void highlight(int num_carre);
void init_puzzle();
void InitGL();
void Inverse();
int LoadBMP(char *File, struct StructTex* UneTexture);
void melange_puzzle();
int recherche_carre(int Rr, int Vr, int Br);
void reshape(int largeur, int hauteur);
void souris(int bouton, int etat, int x, int y);
bool verification();

**** LE MAIN.CPP *************************************

#include"header.h"

void main(int argc, char** argv)
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_RGBA|GLUT_DOUBLE);

// on charge l'image "bois" en mémoire
Nom = LoadBMP("peche24b.bmp", UneTexture);

X_j=500;
Y_j=500;
// INIT DE LA FENETRE
glutInitWindowSize(X_j,Y_j);
glutInitWindowPosition(100,100);
glutCreateWindow("Puzzle");

// FONCTIONS PERSOS
srand(time(NULL));
init_puzzle();
melange_puzzle();

// CALLBACKS
glutDisplayFunc(display);
glutReshapeFunc(reshape);
glutMouseFunc(souris);
glutKeyboardFunc(clavier);

glutMainLoop();
}

/*** CALLBACKS *********************************************************************************/

/*** display ***********************************************************************************/
void display()
{
float Y_t;

glClearColor(0,0,0,0.0);
glClear(GL_COLOR_BUFFER_BIT);
glEnable(GL_TEXTURE_2D);

glBindTexture(GL_TEXTURE_2D, TextureName[0]);
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);
ActiveTexture(0);

if(verification())
{
glClearColor(0,0,0,0.0);
glClear(GL_COLOR_BUFFER_BIT);
// Affichage du texte du gagnant
char *c;
glRasterPos2f(-3,0);
for(c="BRAVO !";*c!='\0';c++)
glutBitmapCharacter(GLUT_BITMAP_HELVETICA_18,*c);
}
else
{
glColor3ub(255,255,255);
for(int i=0;i<16;i++)
{
switch(i/4+1)
{
case 1:
Y_t=0.75;
break;
case 2:
Y_t=0.5;
break;
case 3:
Y_t=0.25;
break;
case 4:
Y_t=0.0;
break;
}
glBegin(GL_QUADS);
glTexCoord2f((i+1)*0.25-0.25,Y_t);
glVertex2f(t_puzzle[i].x-4,t_puzzle[i].y);
glTexCoord2f((i+1)*0.25,Y_t);
glVertex2f(t_puzzle[i].x,t_puzzle[i].y);
glTexCoord2f((i+1)*0.25,Y_t+0.25);
glVertex2f(t_puzzle[i].x,t_puzzle[i].y+4);
glTexCoord2f((i+1)*0.25-0.25,Y_t+0.25);
glVertex2f(t_puzzle[i].x-4,t_puzzle[i].y+4);
glEnd();
}
if(carre_sel<16)
highlight(carre_sel);
}
// Affichage du copyright ;)
char *c;
glColor3ub(255,0,0);
glRasterPos2f(5,14);
for(c="Par Gaetan SOPPE - CSII2005";*c!='\0';c++)
glutBitmapCharacter(GLUT_BITMAP_HELVETICA_10,*c);

glutSwapBuffers();
}
void display_couleur()////////////////////////////////////////////////////////////////////////////
{
glClearColor(0.0,0.0,0.0,0.0);
glClear(GL_COLOR_BUFFER_BIT);

for(int i=0;i<16;i++)
{
glColor3ub(t_puzzle[i].R,t_puzzle[i].V,t_puzzle[i].B);
glBegin(GL_QUADS);
glVertex2f(t_puzzle[i].x,t_puzzle[i].y);
glVertex2f(t_puzzle[i].x-4,t_puzzle[i].y);
glVertex2f(t_puzzle[i].x-4,t_puzzle[i].y+4);
glVertex2f(t_puzzle[i].x,t_puzzle[i].y+4);
glEnd();
}
}
void display_soluce()/////////////////////////////////////////////////////////////////////////////
{
glClearColor(0.3,0.3,0.3,0.0);
glClear(GL_COLOR_BUFFER_BIT);
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, TextureName[0]);
ActiveTexture(0);
glBegin(GL_QUADS);
glTexCoord2i(0,0);
glVertex2f(-8,-8);
glTexCoord2i(1,0);
glVertex2f(8,-8);
glTexCoord2i(1,1);
glVertex2f(8,8);
glTexCoord2i(0,1);
glVertex2f(-8,8);
glEnd();
glutSwapBuffers();
}

/*** reshape ***********************************************************************************/
void reshape(int largeur, int hauteur)
{
glViewport(0,0,largeur,hauteur);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluOrtho2D(-16,16,-16,16);
}

void reshape_soluce(int largeur, int hauteur)
{
glViewport(0,0,largeur,hauteur);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluOrtho2D(-16,16,-16,16);
}

/*** souris ************************************************************************************/
void souris(int bouton, int etat, int x, int y)
{
display_couleur();

GLint viewport[4];
glGetIntegerv(GL_VIEWPORT, viewport);
GLubyte *Pixels;

if((bouton==0)&&(etat==0))
{
Pixels=(GLubyte *) calloc(3*10, sizeof(GLubyte));
glReadBuffer(GL_BACK);
glReadPixels(x,viewport[3]-y,1,1,GL_RGB,GL_UNSIGNED_BYTE,Pixels);

if(selection!=1)
{
carre_sel=recherche_carre(*Pixels, *(Pixels+1), *(Pixels+2));
printf("carre_sel : %d\n",carre_sel);
selection=1;
}
else
{
carre_inv=recherche_carre(*Pixels, *(Pixels+1), *(Pixels+2));
printf("carre_inv : %d\n",carre_inv);
// Inversion des carrés
Inverse();
selection=0;
}
}
// REPAINT DE LA FENETRE
glutPostRedisplay();
}

/*** FONCTIONS *********************************************************************************/

/*** init_puzzle *******************************************************************************/
void init_puzzle()
{
t_puzzle[0].x=-4;
t_puzzle[0].y=4;
t_puzzle[0].R=10;
t_puzzle[0].V=10;
t_puzzle[0].B=10;

t_puzzle[1].x=0;
t_puzzle[1].y=4;
t_puzzle[1].R=20;
t_puzzle[1].V=20;
t_puzzle[1].B=20;

t_puzzle[2].x=4;
t_puzzle[2].y=4;
t_puzzle[2].R=30;
t_puzzle[2].V=30;
t_puzzle[2].B=30;

t_puzzle[3].x=8;
t_puzzle[3].y=4;
t_puzzle[3].R=40;
t_puzzle[3].V=40;
t_puzzle[3].B=40;

t_puzzle[4].x=-4;
t_puzzle[4].y=0;
t_puzzle[4].R=50;
t_puzzle[4].V=50;
t_puzzle[4].B=50;

t_puzzle[5].x=0;
t_puzzle[5].y=0;
t_puzzle[5].R=60;
t_puzzle[5].V=60;
t_puzzle[5].B=60;

t_puzzle[6].x=4;
t_puzzle[6].y=0;
t_puzzle[6].R=70;
t_puzzle[6].V=70;
t_puzzle[6].B=70;

t_puzzle[7].x=8;
t_puzzle[7].y=0;
t_puzzle[7].R=80;
t_puzzle[7].V=80;
t_puzzle[7].B=80;

t_puzzle[8].x=-4;
t_puzzle[8].y=-4;
t_puzzle[8].R=90;
t_puzzle[8].V=90;
t_puzzle[8].B=90;

t_puzzle[9].x=0;
t_puzzle[9].y=-4;
t_puzzle[9].R=100;
t_puzzle[9].V=100;
t_puzzle[9].B=100;

t_puzzle[10].x=4;
t_puzzle[10].y=-4;
t_puzzle[10].R=110;
t_puzzle[10].V=110;
t_puzzle[10].B=110;

t_puzzle[11].x=8;
t_puzzle[11].y=-4;
t_puzzle[11].R=120;
t_puzzle[11].V=120;
t_puzzle[11].B=120;

t_puzzle[12].x=-4;
t_puzzle[12].y=-8;
t_puzzle[12].R=130;
t_puzzle[12].V=130;
t_puzzle[12].B=130;

t_puzzle[13].x=0;
t_puzzle[13].y=-8;
t_puzzle[13].R=140;
t_puzzle[13].V=140;
t_puzzle[13].B=140;

t_puzzle[14].x=4;
t_puzzle[14].y=-8;
t_puzzle[14].R=150;
t_puzzle[14].V=150;
t_puzzle[14].B=150;

t_puzzle[15].x=8;
t_puzzle[15].y=-8;
t_puzzle[15].R=160;
t_puzzle[15].V=160;
t_puzzle[15].B=160;

for(int i=0;i<15;i++)
t_puzzle_init[i]=t_puzzle[i];
}

/*** highlight *********************************************************************************/
void highlight(int num_carre)
{
if(selection==1)
{
glColor3ub(255,0,0);
glLineWidth(2);
glBegin(GL_LINES);
glVertex2f(t_puzzle[num_carre].x,t_puzzle[num_carre].y);
glVertex2f(t_puzzle[num_carre].x-4,t_puzzle[num_carre].y);

glVertex2f(t_puzzle[num_carre].x-4,t_puzzle[num_carre].y);
glVertex2f(t_puzzle[num_carre].x-4,t_puzzle[num_carre].y+4);

glVertex2f(t_puzzle[num_carre].x-4,t_puzzle[num_carre].y+4);
glVertex2f(t_puzzle[num_carre].x,t_puzzle[num_carre].y+4);

glVertex2f(t_puzzle[num_carre].x,t_puzzle[num_carre].y+4);
glVertex2f(t_puzzle[num_carre].x,t_puzzle[num_carre].y);
glEnd();
}
}

/*** recherche_carre ***************************************************************************/
int recherche_carre(int Rr, int Vr, int Br)
{
int carre=16, cpt=0;
bool trouve=false;

while((!trouve)&&(cpt<16))
{
if( (t_puzzle[cpt].R-10==Rr)&&(t_puzzle[cpt].V-10==Vr)&&(t_puzzle[cpt].B-10==Br) )
{
trouve=true;
carre=cpt;
}
else
cpt++;
}
return carre;
}

/*** ActiveTexture ******************************************************************************/
void ActiveTexture(int No)
{
glTexImage2D
(
GL_TEXTURE_2D, //target
0, //mipmap level
UneTexture[No].NbCouleurs, //nb couleurs
UneTexture[No].Largeur, //largeur
UneTexture[No].Hauteur, //hauteur
0, //largeur du bord
UneTexture[No].TypeCouleurs, //type des couleurs
UneTexture[No].CodageCouleurs, //codage de chaque composante
UneTexture[No].Data //Image BMP
);
}

/*** melange_puzzle *****************************************************************************/
void melange_puzzle()
{
// Mélange des carrés
int cpt=0;
int inv=rand()%8+8;
char t_inv[15]={' '};
do
{
if(inv==cpt || t_inv[cpt]=='X' || t_inv[inv]=='X')
{
inv=rand()%8+8;
}
else
{
t_inv[inv]=t_inv[cpt]='X';
int tempx=t_puzzle[cpt].x;
int tempy=t_puzzle[cpt].y;
t_puzzle[cpt].x=t_puzzle[inv].x;
t_puzzle[cpt].y=t_puzzle[inv].y;
t_puzzle[inv].x=tempx;
t_puzzle[inv].y=tempy;
cpt++;
inv=rand()%8+8;
}
}while(cpt<8);
}

/*** verification *******************************************************************************/
bool verification()
{
for(int i=0;i<15;i++)
if(t_puzzle[i].x!=t_puzzle_init[i].x
|| t_puzzle[i].y!=t_puzzle_init[i].y)
return false;
return true;
}

/*** clavier ************************************************************************************/
void clavier(unsigned char touche, int x, int y)
{
switch(touche)
{
case 27:
exit(0);
break;
case 9:
AfficheSoluce();
break;
}
glutPostRedisplay();
}

/*** clavier_soluce *****************************************************************************/
void clavier_soluce(unsigned char touche, int x, int y)
{
switch(touche)
{
case 9:
glutDestroyWindow(glutGetWindow());
break;
}
}

/*** AfficheSoluce ******************************************************************************/
void AfficheSoluce()
{
glutInitWindowSize(X_j,Y_j);
glutInitWindowPosition(400,100);
glutCreateWindow("Solution du puzzle");
glutDisplayFunc(display_soluce);
glutReshapeFunc(reshape_soluce);
glutKeyboardFunc(clavier_soluce);
}

/*** Inverse ************************************************************************************/
void Inverse()
{
int tempx,tempy;

tempx=t_puzzle[carre_sel].x;
tempy=t_puzzle[carre_sel].y;
t_puzzle[carre_sel].x=t_puzzle[carre_inv].x;
t_puzzle[carre_sel].y=t_puzzle[carre_inv].y;
t_puzzle[carre_inv].x=tempx;
t_puzzle[carre_inv].y=tempy;
}

***** LOADER_BMP.CPP ********************************
#include <stdio.h>
#include <string.h>
#include <gl/glut.h>
#include "loader_bmp.h"

////////////////////////////////////////////////
// Loader BMP : charge une image 24bpp
// la taille de l'image doit être du type 2^n
////////////////////////////////////////////////

#define EXIT {fclose(fichier);return -1;}
#define CTOI(C) (*(int*)&C) //récupère en int un nombre pointé par un char*

int LoadBMP(char *File, struct StructTex* UneTexture)
{
unsigned char *Data;
FILE *fichier;
unsigned char Header[0x36];
GLuint DataPos,DataSize;
GLint Components;
GLsizei Width,Height;
GLenum Format,Type;
//GLuint Name[1];

//Lit le fichier et son header
fichier = fopen(File,"rb");if (!fichier) return -1;
if (fread(Header,1,0x36,fichier)!=0x36) EXIT;
if (Header[0]!='B' || Header[1]!='M') EXIT;
if (CTOI(Header[0x1E])!=0) EXIT;
if (CTOI(Header[0x1C])!=24) EXIT;

//Récupère les infos du fichier
DataPos = CTOI(Header[0x0A]);
DataSize = CTOI(Header[0x22]);
//Récupère les infos de l'image
Width = CTOI(Header[0x12]);
Height = CTOI(Header[0x16]);
Type = GL_UNSIGNED_BYTE;
Format = GL_RGB;
Components = 3;

//!!!!
if (DataSize==0) DataSize=Width*Height*Components;
if (DataPos==0) DataPos=0x36;

//Charge l'image
fseek(fichier,DataPos,0);
Data = new unsigned char[DataSize];
if (!Data) EXIT;

if (fread(Data,1,DataSize,fichier)!=DataSize)
{
delete Data;
fclose(fichier);
return -1;
}

fclose(fichier);

//Inverse R et B
unsigned char t;
for (int x=0;x<Width*Height;x++)
{
t=Data[x*3];
Data[x*3]=Data[x*3+2];
Data[x*3+2]=t;
}

//Envoie la texture à OpenGL
UneTexture->NbCouleurs = Components;
UneTexture->Largeur = Width;
UneTexture->Hauteur = Height;
UneTexture->TypeCouleurs = Format;
UneTexture->CodageCouleurs = Type;
UneTexture->Data = Data;

return 1;
}

2 réponses

gastoudou Messages postés 17 Date d'inscription lundi 23 décembre 2002 Statut Membre Dernière intervention 12 novembre 2004
4 nov. 2004 à 16:44
il me manquait un glDisable(GL_TEXTURE_2D) en fait

...Gast...
3
luhtor Messages postés 2023 Date d'inscription mardi 24 septembre 2002 Statut Membre Dernière intervention 28 juillet 2008 6
2 nov. 2004 à 20:05
Pourquoi as tu besoin de chercher la valeur d'un pixel pour un puzzle ? C'est indigeste d'analyser un code source :)

Mais il me semble qu'à partir des coordonnées de la souris, tu trouves facilement quel est le carré pointé. Rechercher la valeur du carré pointé par le pixel me parait du bricolage, meme si c'est ce que beaucoup de gens font. ^^
0
Rejoignez-nous