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 <iostream>
#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