Help!! Cube 3D + texture

lee137 Messages postés 4 Date d'inscription dimanche 31 octobre 2010 Statut Membre Dernière intervention 16 décembre 2011 - 16 déc. 2011 à 00:05
lee137 Messages postés 4 Date d'inscription dimanche 31 octobre 2010 Statut Membre Dernière intervention 16 décembre 2011 - 16 déc. 2011 à 12:47
Bonsoir!
En fait j'essaye de faire une cube 3D qui tourne, avec sur chaque face une texture.

En effet je suis débutante en programmation 3D et je pense que je il pourrait y avoir des erreurs stupides dans mon code qui empêchent mon cube de s'afficher.

voici le code

#include
#include <glut.h>
#include <gl.h>
#include "math.h"
#include "fstream"

using namespace std;

#define ABS(x) (((x) < 0) ? -(x) : (x))
#define EPSILON 0.1
const int W=800, H=600;
const int w=512, h=512; //lena
float hh = 0.f, d=-20.f;

struct Vertex {
float x,y,z;
Vertex(float _x,float _y, float _z):x(_x),y(_y),z(_z){}
Vertex():x(.0f),y(.0f),z(.0f){}
};

float depthCentre = -27.f;
Vertex axe;


void rotate(Vertex& b, Vertex a, Vertex axe, float angle)
{
float x=a.x, y=a.y, z=a.z-depthCentre;
float UxUy = axe.x*axe.y;
float UxUz = axe.x*axe.z;
float UyUz = axe.y*axe.z;
float Ux2 = axe.x*axe.x;
float Uy2 = axe.y*axe.y;
float Uz2 = axe.z*axe.z;
float c = cosf(angle);
float s = sinf(angle);
float c1 = 1.f-c;

b.x = x*(Ux2+(1-Ux2)*c) + y*(UxUy*c1-axe.z*s) + z*(UxUz*c1+axe.y*s);
b.y = x*(UxUy*c1+axe.z*s) + y*(Uy2+(1-Uy2)*c) + z*(UyUz*c1-axe.x*s);
b.z = x*(UxUz*c1-axe.y*s) + y*(UyUz*c1+axe.x*s) + z*(Uz2+(1-Uz2)*c) + depthCentre;
}


void proj(float &X, float &Y, Vertex v)
{
if (v.z>d)
return;
float rapport = ABS(d/v.z);
X = rapport * v.x;
Y = rapport * v.y;
}


struct pixel{
float r, g, b;
pixel(float _r,float _g, float _b):r(_r),g(_g),b(_b){}
pixel():r(0),g(0),b(0){}
};
pixel* image;

void raw2im(pixel *image, char *name){
ifstream f(name,ios::in|ios::binary);
f.read((char*)image,(w*h*3));
}

struct pixelb{
unsigned char r, g, b;
pixelb(unsigned char _r,unsigned char _g, unsigned char _b):r(_r),g(_g),b(_b){}
pixelb():r(0),g(0),b(0){}
};

struct Vect2D {
float x,y;
Vect2D(float _x,float _y):x(_x),y(_y){}
Vect2D():x(0),y(0){}
bool operator ==(Vect2D const &a){return (ABS(this->x-a.x)<=EPSILON && ABS(this->y-a.y)<=EPSILON);}
};






void plot(float x, float y, pixel c)
{
glColor3f(c.r, c.g, c.b);
glBegin(GL_POINTS);
glVertex2f(x, y);
glEnd();
}

void plot(float x, float y)
{
glBegin(GL_POINTS);
glVertex2f(x, y);
glEnd();
}

inline float dist2(float x1, float y1, float x2, float y2)
{
return (x2-x1)*(x2-x1)+(y2-y1)*(y2-y1);
}



void drawLine(Vertex v1, Vertex v2)
{
float X1,Y1,X2,Y2;
proj(X1, Y1, v1);
proj(X2, Y2, v2);

float a=v1.z-depthCentre, b=v2.z-depthCentre;
a/=2.f; b/=2.f;

glBegin(GL_LINES);
glColor3f(a, a, a);
glVertex2f(X1,Y1);

glColor3f(b, b, b);;
glVertex2f(X2,Y2);
glEnd();
}

void drawLine(Vect2D v1, Vect2D v2)
{
glBegin(GL_LINES);
glColor3f(0.0, 0.0, 1.0);
glVertex2f(v1.x,v1.y);
glColor3f(1.0, 1.0, 0.0);
glVertex2f(v2.x,v2.y);
glEnd();
}


void fillTriangleRec(Vect2D A, Vect2D B, Vect2D C, pixel cA, pixel cB, pixel cC)
{
Vect2D c1 = Vect2D(.5f*(A.x+B.x),.5f*(A.y+B.y));
Vect2D c2 = Vect2D(.5f*(B.x+C.x),.5f*(B.y+C.y));
Vect2D c3 = Vect2D(.5f*(A.x+C.x),.5f*(A.y+C.y));

pixel col1 = pixel(.5f*(cA.r+cB.r), .5f*(cA.g+cB.g), .5f*(cA.b+cB.b));
pixel col2 = pixel(.5f*(cB.r+cC.r), .5f*(cB.g+cC.g), .5f*(cB.b+cC.b));
pixel col3 = pixel(.5f*(cA.r+cC.r), .5f*(cA.g+cC.g), .5f*(cA.b+cC.b));

if ((c1==c2) && (c1==c3))
{
plot(c1.x, c1.y, col1);
return;
}

fillTriangleRec(A, c1, c3, cA, col1, col3);
fillTriangleRec(B, c1, c2, cB, col1, col2);
fillTriangleRec(C, c3, c2, cC, col3, col2);
fillTriangleRec(c1, c2, c3, col1, col2, col3);
}

void colorFromImage(pixel &n, pixel* img, Vect2D pt)
{
int index = (int)(h-pt.y)*w+(int)(pt.x);
n=img[index];
}

void fillTexTriangle(Vect2D A, Vect2D B, Vect2D C, Vect2D uA, Vect2D uB, Vect2D uC)
{
Vect2D c1 = Vect2D(.5f*(A.x+B.x),.5f*(A.y+B.y));
Vect2D c2 = Vect2D(.5f*(B.x+C.x),.5f*(B.y+C.y));
Vect2D c3 = Vect2D(.5f*(A.x+C.x),.5f*(A.y+C.y));

Vect2D uc1 = Vect2D(.5f*(uA.x+uB.x),.5f*(uA.y+uB.y));
Vect2D uc2 = Vect2D(.5f*(uB.x+uC.x),.5f*(uB.y+uC.y));
Vect2D uc3 = Vect2D(.5f*(uA.x+uC.x),.5f*(uA.y+uC.y));

if ((c1==c2) && (c1==c3))
{
pixel coul;
colorFromImage(coul, image, uc1);
plot(c1.x, c1.y, coul);
return;
}

fillTexTriangle(A, c1, c3, uA, uc1, uc3);
fillTexTriangle(B, c1, c2, uB, uc1, uc2);
fillTexTriangle(C, c3, c2, uC, uc3, uc2);
fillTexTriangle(c1, c2, c3, uc1, uc2, uc3);
}

void add(pixel &col1, pixel col2)
{ col1.r+=col2.r; col1.g+=col2.g; col1.b+=col2.b; }

void mult(pixel &col1, pixel col2)
{ col1.r*=col2.r; col1.g*=col2.g; col1.b*=col2.b; }

void clip(pixel &col)
{
if (col.r>1.f)
col.r=1.f;
else
if (col.r<0.f)
col.r=0.f;
if (col.g>1.f)
col.g=1.f;
else
if (col.g<0.f)
col.g=0.f;
if (col.b>1.f)
col.b=1.f;
else
if (col.b<0.f)
col.b=0.f;
}

void fillTexTriangle(Vect2D A, Vect2D B, Vect2D C, Vect2D uA, Vect2D uB, Vect2D uC, pixel cA, pixel cB, pixel cC, void(*func)(pixel&, pixel))
{
Vect2D c1 = Vect2D(.5f*(A.x+B.x),.5f*(A.y+B.y));
Vect2D c2 = Vect2D(.5f*(B.x+C.x),.5f*(B.y+C.y));
Vect2D c3 = Vect2D(.5f*(A.x+C.x),.5f*(A.y+C.y));

pixel col1 = pixel(.5f*(cA.r+cB.r), .5f*(cA.g+cB.g), .5f*(cA.b+cB.b));
pixel col2 = pixel(.5f*(cB.r+cC.r), .5f*(cB.g+cC.g), .5f*(cB.b+cC.b));
pixel col3 = pixel(.5f*(cA.r+cC.r), .5f*(cA.g+cC.g), .5f*(cA.b+cC.b));

Vect2D uc1 = Vect2D(.5f*(uA.x+uB.x),.5f*(uA.y+uB.y));
Vect2D uc2 = Vect2D(.5f*(uB.x+uC.x),.5f*(uB.y+uC.y));
Vect2D uc3 = Vect2D(.5f*(uA.x+uC.x),.5f*(uA.y+uC.y));

if ((c1==c2) && (c1==c3))
{
pixel coul;
colorFromImage(coul, image, uc1);
func(coul, col1);
clip(coul);
plot(c1.x, c1.y, coul);
return;
}

fillTexTriangle(A, c1, c3, uA, uc1, uc3, cA, col1, col3, func);
fillTexTriangle(B, c1, c2, uB, uc1, uc2, cB, col1, col2, func);
fillTexTriangle(C, c3, c2, uC, uc3, uc2, cC, col3, col2, func);
fillTexTriangle(c1, c2, c3, uc1, uc2, uc3, col1, col2, col3, func);
}

void rotate(Vertex& b, Vertex a, float angle)
{
float c=cosf(angle),s=sinf(angle);
b.x = a.x*c - a.y*s;
b.y = a.x*s + a.y*c;
b.z = a.z;
}



void display()
{
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
glClear(GL_COLOR_BUFFER_BIT);


Vertex sommetsCarre[] = {
Vertex(-1,1,-1),
Vertex(1,1,-1),
Vertex(-1,-1,-1),
Vertex(1,-1,-1),
Vertex(-1,-1,1),
Vertex(1,-1,1),
Vertex(-1,1,1),
Vertex(1,1,1)};


drawLine(sommetsCarre[0], sommetsCarre[1]);
drawLine(sommetsCarre[0], sommetsCarre[2]);
drawLine(sommetsCarre[0], sommetsCarre[4]);
drawLine(sommetsCarre[1], sommetsCarre[3]);
drawLine(sommetsCarre[1], sommetsCarre[5]);
drawLine(sommetsCarre[2], sommetsCarre[3]);
drawLine(sommetsCarre[2], sommetsCarre[6]);
drawLine(sommetsCarre[3], sommetsCarre[7]);
drawLine(sommetsCarre[4], sommetsCarre[5]);
drawLine(sommetsCarre[4], sommetsCarre[6]);
drawLine(sommetsCarre[5], sommetsCarre[7]);
drawLine(sommetsCarre[6], sommetsCarre[7]);


Vect2D Vect2Dp[8];

//Pour chaque vertex(sommet du carre), on effectue une rotation, puis on projette et on stocke le resultat dans un tableau Vect2Dp

for(int i=0;i<8;i++)
{
Vertex tmp;
rotate(tmp, sommetsCarre[i], axe, hh);
sommetsCarre[i]=tmp;
float X,Y;
proj(X, Y, tmp);
Vect2Dp[i]=Vect2D(X,Y);
}


hh+=0.0000001f;

if (hh>360) {

hh=0.f;
}


//tableau qui stocke les sommets du cadre

Vect2D sommetsCadre[]={
Vect2D(0,0),
Vect2D(1,0),
Vect2D(1,1),
Vect2D(0,1)};

pixel *image0=new pixel[w*h];
pixel *image1=new pixel[w*h];
pixel *image2=new pixel[w*h];
pixel *image3=new pixel[w*h];
pixel *image4=new pixel[w*h];
pixel *image5=new pixel[w*h];

pixel *texture[6];
texture[0]=image0;
texture[1]=image1;
texture[2]=image2;
texture[3]=image3;
texture[4]=image4;
texture[5]=image5;

for(int i=0;i<6;i++)
{
raw2im(texture[i],"lena.raw");
}

//tableau qui prend comme 3 premiers indices 3 sommets du cube(projette), les 3 indices suivants representent les 3 point du carre
//le dernier indice represente la texture qu'on veut appliquer


int sept[12][7] = {
{0,1,2,0,1,2,0},
{0,2,3,0,2,3,0},
{1,5,6,0,1,2,1},
{1,6,2,0,2,3,1},
{5,4,7,0,1,2,2},
{0,1,2,0,1,2,0},
{0,1,2,0,1,2,0},
{0,1,2,0,1,2,0},
{0,1,2,0,1,2,0},
{0,1,2,0,1,2,0},
{0,1,2,0,1,2,0},
{0,1,2,0,1,2,0}};


//on parcourt toutes les lignes du tableau
for(int i=0;i<12;i++)
{
Vect2D A=Vect2Dp[sept[i][0]];
Vect2D B=Vect2Dp[sept[i][1]];
Vect2D C=Vect2Dp[sept[i][2]];

//Si le détérminant est positif appliquer la fonction fillTexTriangle
if(A.x*B.y-A.y*B.x>0)
{
Vect2D a=sommetsCadre[sept[i][3]];
Vect2D b=sommetsCadre[sept[i][4]];
Vect2D c=sommetsCadre[sept[i][5]];
pixel *image=texture[sept[i][6]];
fillTexTriangle(A, B, C,a, b, c);

}
}

glFlush();

}


void LoadTextureRAW()
{
image = new pixel[w*h];
ifstream f;
f.open("lena.raw", ios::in | ios::binary);
pixelb p;
if (f.is_open())
{
for (int i=0; i<w*h; i++)
{
f.read(((char *)&p), sizeof(pixelb));
pixel col(p.r/255.f,p.g/255.f,p.b/255.f);
image[i]=col;
}
}
f.close();
}

int main (int argc, char * argv[])
{

axe.x=0.577350269189626;
axe.y=0.577350269189626;
axe.z=0.577350269189626;
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_SINGLE|GLUT_RGB);
glutInitWindowSize(W, H);
glutInitWindowPosition(50, 10);
glutCreateWindow("ESIB");
//glOrtho(0, W-1, 0, H-1, 0, 1);
glOrtho(-6, 6, -4.5, 4.5, 0, 1);
glPointSize(1.f);
glutDisplayFunc(display);
glutIdleFunc(display);
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
glClear(GL_COLOR_BUFFER_BIT);
LoadTextureRAW();
glutMainLoop();
return 0;
}





Merci pour chacun qui aura la patience de lire tout ça
Si c'est possible de me donner une réponse avant demain ce serait super

3 réponses

BunoCS Messages postés 15472 Date d'inscription lundi 11 juillet 2005 Statut Modérateur Dernière intervention 25 mars 2024 103
16 déc. 2011 à 09:27
Hello,
Pour un code assez long, il aurait été préférable d'utiliser les balises "code" (3e icone à droite, juste au-dessus de la zone de texte).
Pour la base en développement 3D, je te conseille le site de Nehe, la référence dans le domaine.

Si c'est possible de me donner une réponse avant demain ce serait super

Tout le monde ici est bénévole et volontaire. Il ne faut donc pas s'attendre forcément à une réponse rapide

@+
Buno, Admin CS
L'urgent est fait, l'impossible est en cours. Pour les miracles, prévoir un délai...
0
jhon512 Messages postés 15 Date d'inscription jeudi 1 décembre 2011 Statut Membre Dernière intervention 24 janvier 2012
16 déc. 2011 à 11:35
Bonjour,

- Je rejoins l'avis de buno pour ce qui est de la balise code.
- L'utilisation de la librairie GLUT est à prohiber. Utiliser freeglut ou autre à la place.
- A noter que tu cast des double dans ton code pour des variables de type float (peut être que le compilateur est intelligent et remet tout en ordre à la compile, je sais pas).. A moins d'avoir besoin d'une précision extrême, je te conseillerais d'utiliser des floats. axe.x=0.577350269189626; (axe.x = float, 0.12345= double, 0.123456f = float).
- C'est difficile de lire ton code :)(ce n'est pas pour être désagréable). Les tuto de Nehe sont bien réalisé, tu devrais te baser sur ceux là (ou des autres).

Je pratique L'utilisation d'opengl depuis quelques années, mais j'ai du mal à comprendre le fonctionnement de ton code. peut être à cause de la colorisation syntaxique absente mais aussi car je pense que tu te casse la tête pour afficher un bête cube avec une texture sur chaque faces. Ta démarche est appréciable, mais tu t'embrouille pour rien avec tout ce code :)

A+, quand tu auras des problèmes avec les tutos de nehe ou des autres ;)
0
lee137 Messages postés 4 Date d'inscription dimanche 31 octobre 2010 Statut Membre Dernière intervention 16 décembre 2011
16 déc. 2011 à 12:47
Merci pour vos réponses! Je tiendrais compte de toutes vos remarques.

Buno, je penserais à donner du temps aux miracles pour pourvoir s'accomplir:P

La structure de mon code est en fait le résultat d'un cours (ceci est un devoir) le prof veut qu'on sache "programmer" ce qu'on veut faire, avant d'utiliser les fonctionnalités d'OpenGL

Merci encore!
0
Rejoignez-nous