bhelial
24/05/2007, 01h03
Boujour,
J'essaie de coder un moteur3D assez simplifié sur GBA.
Pour l'instant j'arrive à partir d'un tableau qui contient les coordonnées en 3d d'un cube à calculer ses coordonnées en 2D,à l'afficher en fil de fer et à faire fonctioner la rotation de mon cube.
Le problème survient au niveau du remplissage des polygones. Je crée un tableau contenant pour chaque polygone les coordonnées x de départ et de fin pour chaque ligne puis je génère l'affichage de ces lignes. Lorsque j'initialise mon tableau pour mon polygone, le tableau contenant mes coordonnées en 2D renvoie des données compètement illogiques alors que si je me contente d'afficher mon cube en fil de fer, tout va bien. En résumé dès que je fais une opération après l'affichage, mes variables sont corrompues
Je me demande si je ne depasse pas la taille de la mémoire (pourtant avec seulement 8 points, celà me semble pas énorme). Je suis également relativement débutant en C et en C++ et je me demande si l'allocation de mes variables est correcte...
Dans tous les cas, un peu d'aide serait la bienvenue.
Merci par avance.:)
Voici mon code. Je développe sous Visual Ham :
#include <mygba.h>
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#define REG_DISPCNT *(volatile unsigned long*)0x4000000
#define RGB(r,g,b) ((r)+((g)<<5)+((b)<<10))
MULTIBOOT
//************************************************** **************************************
u8 vbl_count = 0;
int xa,ya,za = 0;
typedef struct Coordonnees Coordonnees;
struct Coordonnees
{
long x;
long y;
};
typedef struct point3D point3D;
struct point3D
{
int x,y,z;
};
typedef struct point2D point2D;
struct point2D
{
int x,y;
};
typedef struct polygones polygones;
struct polygones
{
int a,b,c;
};
typedef struct fillpolygones fillpolygones;
struct fillpolygones
{
int y, startx, endx;
};
point3D Sommet[8]; /* les sommets du cube */
point3D Point3D[8]; /* les sommets apres rotation */
point2D Point2D[8]; /* les sommets apres projection */
polygones Poly[12]; /* les polygones à remplir à partir des coordonnées des points*/
fillpolygones fillpoly[200];
int Nb_points = 8;
// position par rapport à l'écran
int Xoff = 0;//160
int Yoff = 0;//100
int Zoff = -145;//-125 //600
static float Sin[360],Cos[360]; /* Tableaux precalcules de sinus et cosinus */
static float matrice[3][3]; /* Matrice de rotation 3*3 */
/************************************************** **************************/
/* Init_Sinus() : precalcul les tables de sinus et cosinus */
/************************************************** **************************/
float** Init_Sinus(float *Sin, float *Cos)
{
int i;
for(i=0;i<360;i++)
{
Sin[i]=sin(i * 3.1415927 / 180);
Cos[i]=cos(i * 3.1415927 / 180);
}
return (float**)Sin;
return (float**)Cos;
}
/************************************************** **************************/
/* Initialiser() : initialise les coordonnees des sommets du cube */
/* ainsi que les polygones à remplir */
/************************************************** **************************/
point3D** Initialiser(point3D *Sommet)
{
Sommet[0].x = -25; Sommet[0].y = -25; Sommet[0].z = -25;
Sommet[1].x = 25; Sommet[1].y = -25; Sommet[1].z = -25;
Sommet[2].x = 25; Sommet[2].y = 25; Sommet[2].z = -25;
Sommet[3].x = -25; Sommet[3].y = 25; Sommet[3].z = -25;
Sommet[4].x = 25; Sommet[4].y = -25; Sommet[4].z = 25;
Sommet[5].x = -25; Sommet[5].y = -25; Sommet[5].z = 25;
Sommet[6].x = -25; Sommet[6].y = 25; Sommet[6].z = 25;
Sommet[7].x = 25; Sommet[7].y = 25; Sommet[7].z = 25;
return (point3D**)Sommet;
}
polygones** Initialiser2(polygones *Poly)
{
Poly[0].a = 5; Poly[0].b = 6; Poly[0].c = 7;
Poly[1].a = 5; Poly[1].b = 4; Poly[1].c = 7;
Poly[2].a = 0; Poly[2].b = 1; Poly[2].c = 2;
Poly[3].a = 0; Poly[3].b = 2; Poly[3].c = 3;
Poly[4].a = 5; Poly[4].b = 0; Poly[4].c = 1;
Poly[5].a = 5; Poly[5].b = 4; Poly[5].c = 1;
Poly[6].a = 6; Poly[6].b = 3; Poly[6].c = 2;
Poly[7].a = 6; Poly[7].b = 7; Poly[7].c = 2;
Poly[8].a = 6; Poly[8].b = 5; Poly[8].c = 0;
Poly[9].a = 6; Poly[9].b = 3; Poly[9].c = 0;
Poly[10].a = 7; Poly[10].b = 4; Poly[10].c = 1;
Poly[11].a = 7; Poly[11].b = 2; Poly[11].c = 1;
return (polygones**)Poly;
}
/************************************************** **************************/
/* Rotation() : effectue la rotation des points Sommet -> Point3D */
/************************************************** **************************/
point3D** Rotation(point3D *Point3D, int Xa, int Ya, int Za)
{
int i;
/* Calcul de la matrice de rotation 3*3 */
matrice[0][0] = Cos[Za]*Cos[Ya];
matrice[1][0] = Sin[Za]*Cos[Ya];
matrice[2][0] = -Sin[Ya];
matrice[0][1] = Cos[Za]*Sin[Ya]*Sin[Xa] - Sin[Za]*Cos[Xa];
matrice[1][1] = Sin[Za]*Sin[Ya]*Sin[Xa] + Cos[Xa]*Cos[Za];
matrice[2][1] = Sin[Xa]*Cos[Ya];
matrice[0][2] = Cos[Za]*Sin[Ya]*Cos[Xa] + Sin[Za]*Sin[Xa];
matrice[1][2] = Sin[Za]*Sin[Ya]*Cos[Xa] - Cos[Za]*Sin[Xa];
matrice[2][2] = Cos[Xa]*Cos[Ya];
/* Rotation des sommets de l'objet */
for(i=0; i<Nb_points; i++)
{
Point3D[i].x = (int) (matrice[0][0]*Sommet[i].x
+ matrice[1][0]*Sommet[i].y
+ matrice[2][0]*Sommet[i].z);
Point3D[i].y = (int) (matrice[0][1]*Sommet[i].x
+ matrice[1][1]*Sommet[i].y
+ matrice[2][1]*Sommet[i].z);
Point3D[i].z = (int) (matrice[0][2]*Sommet[i].x
+ matrice[1][2]*Sommet[i].y
+ matrice[2][2]*Sommet[i].z);
}
return (point3D**)Point3D;
}
/************************************************** **************************/
/* Projection() : convertit les points 3D en 2D après la rotation */
/************************************************** **************************/
point2D** Projection(point2D *Point2D)
{
int i;
float fx;
float fy;
int x, y;
for(i=0;i<Nb_points;i++)
{
fx = (Point3D[i].x * 256 ) / (Point3D[i].z + Zoff) + Xoff ;
fy = (Point3D[i].y * 256 ) / (Point3D[i].z + Zoff) + Yoff ;
// partie entière des coordonnées
x = (int) floor(fx);
y = (int) floor(fy);
// génération du tableau 2D
Point2D[i].x = x;
Point2D[i].y = y;
}
return (point2D**)Point2D;
}
/************************************************** **************************/
/* translation() : fait en sorte que le point (0,0) soit au centre de */
/* l'écran */
/************************************************** **************************/
void translation(int x, int y) {
unsigned short *VideoBuffer = (unsigned short *) 0x6000000;
// Passer en mode 3:
REG_DISPCNT= (0x3 | 0x400);
x = x + 120;
y = 80 - y;
VideoBuffer[y * 240 + x] = RGB(20,20,20);
}
/************************************************** **************************/
/* axex() : génération des axes après translation */
/************************************************** **************************/
void axes(void) {
int x2;
int y2;
for (x2= -120; x2< 120; x2= x2+1) {
translation(x2,0);
}
for (y2=-80; y2<160; y2++) {
translation(0,y2);
}
}
/************************************************** **************************/
/* Afficher() : dessine la scene a l'ecran */
/************************************************** **************************/
void Afficher(int couleur)
{
int i;
for (i=0;i<8;i++)
{
translation(Point2D[i].x,Point2D[i].y);
}
}
/************************************************** **************************/
/* Line() : trace une ligne entre deux points */
/************************************************** **************************/
void Line(int x1,int y1, int x2,int y2)
{
int xx,yy;
int Dx,Dy;
int xincr,yincr;
int erreur;
int i;
/* On initialise les variables */
Dx = abs(x2-x1);
Dy = abs(y2-y1);
/* On détermine dans quel sens varie la droite */
if(x1<x2)
xincr = 1;
else
xincr = -1;
if(y1<y2)
yincr = 1;
else
yincr = -1;
/* Trace de ligne */
xx = x1;
yy = y1;
if(Dx>Dy)
{
erreur = Dx/2;
for(i=0;i<Dx;i++)
{
xx += xincr;
erreur += Dy;
if(erreur>Dx)
{
erreur -= Dx;
yy += yincr;
}
translation(xx,yy);
}
}
else
{
erreur = Dy/2;
for(i=0;i<Dy;i++)
{
yy += yincr;
erreur += Dx;
if(erreur>Dy)
{
erreur -= Dy;
xx += xincr;
}
translation(xx,yy);
}
}
}
/************************************************** **************************/
/* Afficher() : dessine la scene a l'ecran */
/************************************************** **************************/
void fildefer(point2D *Point2D) {
for (int aze =0; aze<12; aze++) {
Line (Point2D[Poly[aze].a].x, Point2D[Poly[aze].a].y, Point2D[Poly[aze].b].x, Point2D[Poly[aze].b].y);
Line (Point2D[Poly[aze].a].x, Point2D[Poly[aze].a].y, Point2D[Poly[aze].c].x, Point2D[Poly[aze].c].y);
Line (Point2D[Poly[aze].b].x, Point2D[Poly[aze].b].y, Point2D[Poly[aze].c].x, Point2D[Poly[aze].c].y);
}
}
/************************************************** ************************************************** ************************************************** *****/
/************************************************** ************************************************** ************************************************** *****/
fillpolygones** Initialiserfillpoly(fillpolygones *fillpoly)
{
//fillpolygones fillpoly[200];
for (signed int i=-100; i<100;i++) {
fillpoly[i].y = i;
fillpoly[i].startx = -16000;
fillpoly[i].endx = -16000;
}
return (fillpolygones**)fillpoly;
}
void InitSegment(int x1, int y1, int x2,int y2)
{
int temp,y;
long x,pas;
if(y2!=y1)
{
if(y2<y1)
{
temp=y1;
y1=y2;
y2=temp;
temp=x1;
x1=x2;
x2=temp;
}
x = x1<<8;
pas= ((x2-x1)<<8)/(y2-y1);
x+=pas;
y1++;
//if(y1<miny) miny=y1;
//if(y2>maxy) maxy=y2;
for(y=y1;y<=y2;y++)
{
if (y>= -80) {
//if((y>=-80) /*&& (y<Ymax)*/) l'axe des ordonnées va de -80 à 80
if(fillpoly[y].startx == -16000) {
fillpoly[y].startx = x>>8;
} else {
fillpoly[y].endx = x>>8;
}
}
x+=pas;
}
}
}
void Hline()
{
int x1, x2;
//unsigned short *VideoBuffer = (unsigned short *) 0x6000000;
// Passer en mode 3:
//REG_DISPCNT= (0x3 | 0x400);
for (int i=-100; i<100; i++) {
if (fillpoly[i].startx != -16000 && fillpoly[i].endx != -16000) {
if (fillpoly[i].startx < fillpoly[i].endx) {
x1 = fillpoly[i].startx;
x2 = fillpoly[i].endx;
}
else
{
x1 = fillpoly[i].endx;
x2 = fillpoly[i].startx;
}
for (int ii=x1; ii<=x2; ii++)
{
//VideoBuffer[y * 240 + x] = RGB(20,20,20);
translation(ii,fillpoly[i].y);
}
}
}
}
/************************************************** ************************************************** ************************************************** *****/
/************************************************** ************************************************** ************************************************** *****/
void fildefer2(point2D *Point2D) {
for (int aze =0; aze<12; aze++) {
Line (Point2D[Poly[aze].a].x, Point2D[Poly[aze].a].y, Point2D[Poly[aze].b].x, Point2D[Poly[aze].b].y);
Line (Point2D[Poly[aze].a].x, Point2D[Poly[aze].a].y, Point2D[Poly[aze].c].x, Point2D[Poly[aze].c].y);
Line (Point2D[Poly[aze].b].x, Point2D[Poly[aze].b].y, Point2D[Poly[aze].c].x, Point2D[Poly[aze].c].y);
}
}
/************************************************** **************************/
/* reset_screen() : efface l'écran */
/************************************************** **************************/
void reset_screen() {
unsigned short *VideoBuffer = (unsigned short *) 0x6000000;
// Passer en mode 3:
REG_DISPCNT= (0x3 | 0x400);
int xx = 0;
int yy = 0;
for (yy=0; yy <160; yy++) {
for (xx=0; xx<240; xx++) {
VideoBuffer[yy * 240 + xx] = RGB(90,90,90);
}
}
}
/************************************************** **************************/
/*** MAIN ***/
/************************************************** **************************/
int main(void)
{
//ham_Init();
unsigned short *VideoBuffer = (unsigned short *) 0x6000000;
//Passer en mode 3:
REG_DISPCNT= (0x3 | 0x400);
while(true)
{
int xa,ya,za;
axes();
bool bouton_presse = 0;
// Initialisations
Initialiserfillpoly(fillpoly);
Init_Sinus(Sin, Cos);
Initialiser(Sommet);
Initialiser2(Poly);
xa=ya=za=0;
Rotation(Point3D,0,0,0);
delete[] Sommet;
Projection(Point2D);
delete[] Point3D;
Afficher(100);
fildefer(Point2D);
int aze = 0;
Initialiserfillpoly(fillpoly);
InitSegment (Point2D[Poly[aze].a].x, Point2D[Poly[aze].a].y, Point2D[Poly[aze].b].x, Point2D[Poly[aze].b].y);
InitSegment (Point2D[Poly[aze].a].x, Point2D[Poly[aze].a].y, Point2D[Poly[aze].c].x, Point2D[Poly[aze].c].y);
InitSegment (Point2D[Poly[aze].b].x, Point2D[Poly[aze].b].y, Point2D[Poly[aze].c].x, Point2D[Poly[aze].c].y);
Hline();
//Afficher(100);
//fildefer(Point2D);
/*
Initialiserfillpoly();
InitSegment (-53, -53, 53, -53);
InitSegment (-53, -53, -53, 53);
InitSegment (53, -53, -53, 53);
Hline();
*/
while (bouton_presse == 0) {
if (F_CTRLINPUT_UP_PRESSED)
{
bouton_presse = 1;
reset_screen();
axes();
ya = ya + 10;
if (ya >= 360) {
ya = 0;
}
Rotation(Point3D,xa,ya,za);
Projection(Point2D);
Afficher(100);
fildefer(Point2D);
bouton_presse = 0;
}
if (F_CTRLINPUT_DOWN_PRESSED)
{
reset_screen();
axes();
ya = ya - 10;
if (ya <= 0) {
ya = 360;
}
Rotation(Point3D,xa,ya,za);
Projection(Point2D);
Afficher(100);
fildefer(Point2D);
}
if (F_CTRLINPUT_LEFT_PRESSED)
{
reset_screen();
axes();
za = za - 10;
if (za <= 0) {
za = 360;
}
Rotation(Point3D,xa,ya,za);
Projection(Point2D);
Afficher(100);
fildefer(Point2D);
}
if (F_CTRLINPUT_RIGHT_PRESSED) // Pour la droite
{
reset_screen();
axes();
za = za + 10;
if (za >= 360) {
za = 0;
}
Rotation(Point3D,xa,ya,za);
Projection(Point2D);
Afficher(100);
fildefer(Point2D);
}
} // while
while (bouton_presse == 1) {
if ( F_CTRLINPUT_UP_PRESSED
|| F_CTRLINPUT_DOWN_PRESSED
|| F_CTRLINPUT_LEFT_PRESSED
|| F_CTRLINPUT_RIGHT_PRESSED)
{
axes();
bouton_presse = 0;
}
} // while
}
return 0;
}
/* END OF FILE */
J'essaie de coder un moteur3D assez simplifié sur GBA.
Pour l'instant j'arrive à partir d'un tableau qui contient les coordonnées en 3d d'un cube à calculer ses coordonnées en 2D,à l'afficher en fil de fer et à faire fonctioner la rotation de mon cube.
Le problème survient au niveau du remplissage des polygones. Je crée un tableau contenant pour chaque polygone les coordonnées x de départ et de fin pour chaque ligne puis je génère l'affichage de ces lignes. Lorsque j'initialise mon tableau pour mon polygone, le tableau contenant mes coordonnées en 2D renvoie des données compètement illogiques alors que si je me contente d'afficher mon cube en fil de fer, tout va bien. En résumé dès que je fais une opération après l'affichage, mes variables sont corrompues
Je me demande si je ne depasse pas la taille de la mémoire (pourtant avec seulement 8 points, celà me semble pas énorme). Je suis également relativement débutant en C et en C++ et je me demande si l'allocation de mes variables est correcte...
Dans tous les cas, un peu d'aide serait la bienvenue.
Merci par avance.:)
Voici mon code. Je développe sous Visual Ham :
#include <mygba.h>
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#define REG_DISPCNT *(volatile unsigned long*)0x4000000
#define RGB(r,g,b) ((r)+((g)<<5)+((b)<<10))
MULTIBOOT
//************************************************** **************************************
u8 vbl_count = 0;
int xa,ya,za = 0;
typedef struct Coordonnees Coordonnees;
struct Coordonnees
{
long x;
long y;
};
typedef struct point3D point3D;
struct point3D
{
int x,y,z;
};
typedef struct point2D point2D;
struct point2D
{
int x,y;
};
typedef struct polygones polygones;
struct polygones
{
int a,b,c;
};
typedef struct fillpolygones fillpolygones;
struct fillpolygones
{
int y, startx, endx;
};
point3D Sommet[8]; /* les sommets du cube */
point3D Point3D[8]; /* les sommets apres rotation */
point2D Point2D[8]; /* les sommets apres projection */
polygones Poly[12]; /* les polygones à remplir à partir des coordonnées des points*/
fillpolygones fillpoly[200];
int Nb_points = 8;
// position par rapport à l'écran
int Xoff = 0;//160
int Yoff = 0;//100
int Zoff = -145;//-125 //600
static float Sin[360],Cos[360]; /* Tableaux precalcules de sinus et cosinus */
static float matrice[3][3]; /* Matrice de rotation 3*3 */
/************************************************** **************************/
/* Init_Sinus() : precalcul les tables de sinus et cosinus */
/************************************************** **************************/
float** Init_Sinus(float *Sin, float *Cos)
{
int i;
for(i=0;i<360;i++)
{
Sin[i]=sin(i * 3.1415927 / 180);
Cos[i]=cos(i * 3.1415927 / 180);
}
return (float**)Sin;
return (float**)Cos;
}
/************************************************** **************************/
/* Initialiser() : initialise les coordonnees des sommets du cube */
/* ainsi que les polygones à remplir */
/************************************************** **************************/
point3D** Initialiser(point3D *Sommet)
{
Sommet[0].x = -25; Sommet[0].y = -25; Sommet[0].z = -25;
Sommet[1].x = 25; Sommet[1].y = -25; Sommet[1].z = -25;
Sommet[2].x = 25; Sommet[2].y = 25; Sommet[2].z = -25;
Sommet[3].x = -25; Sommet[3].y = 25; Sommet[3].z = -25;
Sommet[4].x = 25; Sommet[4].y = -25; Sommet[4].z = 25;
Sommet[5].x = -25; Sommet[5].y = -25; Sommet[5].z = 25;
Sommet[6].x = -25; Sommet[6].y = 25; Sommet[6].z = 25;
Sommet[7].x = 25; Sommet[7].y = 25; Sommet[7].z = 25;
return (point3D**)Sommet;
}
polygones** Initialiser2(polygones *Poly)
{
Poly[0].a = 5; Poly[0].b = 6; Poly[0].c = 7;
Poly[1].a = 5; Poly[1].b = 4; Poly[1].c = 7;
Poly[2].a = 0; Poly[2].b = 1; Poly[2].c = 2;
Poly[3].a = 0; Poly[3].b = 2; Poly[3].c = 3;
Poly[4].a = 5; Poly[4].b = 0; Poly[4].c = 1;
Poly[5].a = 5; Poly[5].b = 4; Poly[5].c = 1;
Poly[6].a = 6; Poly[6].b = 3; Poly[6].c = 2;
Poly[7].a = 6; Poly[7].b = 7; Poly[7].c = 2;
Poly[8].a = 6; Poly[8].b = 5; Poly[8].c = 0;
Poly[9].a = 6; Poly[9].b = 3; Poly[9].c = 0;
Poly[10].a = 7; Poly[10].b = 4; Poly[10].c = 1;
Poly[11].a = 7; Poly[11].b = 2; Poly[11].c = 1;
return (polygones**)Poly;
}
/************************************************** **************************/
/* Rotation() : effectue la rotation des points Sommet -> Point3D */
/************************************************** **************************/
point3D** Rotation(point3D *Point3D, int Xa, int Ya, int Za)
{
int i;
/* Calcul de la matrice de rotation 3*3 */
matrice[0][0] = Cos[Za]*Cos[Ya];
matrice[1][0] = Sin[Za]*Cos[Ya];
matrice[2][0] = -Sin[Ya];
matrice[0][1] = Cos[Za]*Sin[Ya]*Sin[Xa] - Sin[Za]*Cos[Xa];
matrice[1][1] = Sin[Za]*Sin[Ya]*Sin[Xa] + Cos[Xa]*Cos[Za];
matrice[2][1] = Sin[Xa]*Cos[Ya];
matrice[0][2] = Cos[Za]*Sin[Ya]*Cos[Xa] + Sin[Za]*Sin[Xa];
matrice[1][2] = Sin[Za]*Sin[Ya]*Cos[Xa] - Cos[Za]*Sin[Xa];
matrice[2][2] = Cos[Xa]*Cos[Ya];
/* Rotation des sommets de l'objet */
for(i=0; i<Nb_points; i++)
{
Point3D[i].x = (int) (matrice[0][0]*Sommet[i].x
+ matrice[1][0]*Sommet[i].y
+ matrice[2][0]*Sommet[i].z);
Point3D[i].y = (int) (matrice[0][1]*Sommet[i].x
+ matrice[1][1]*Sommet[i].y
+ matrice[2][1]*Sommet[i].z);
Point3D[i].z = (int) (matrice[0][2]*Sommet[i].x
+ matrice[1][2]*Sommet[i].y
+ matrice[2][2]*Sommet[i].z);
}
return (point3D**)Point3D;
}
/************************************************** **************************/
/* Projection() : convertit les points 3D en 2D après la rotation */
/************************************************** **************************/
point2D** Projection(point2D *Point2D)
{
int i;
float fx;
float fy;
int x, y;
for(i=0;i<Nb_points;i++)
{
fx = (Point3D[i].x * 256 ) / (Point3D[i].z + Zoff) + Xoff ;
fy = (Point3D[i].y * 256 ) / (Point3D[i].z + Zoff) + Yoff ;
// partie entière des coordonnées
x = (int) floor(fx);
y = (int) floor(fy);
// génération du tableau 2D
Point2D[i].x = x;
Point2D[i].y = y;
}
return (point2D**)Point2D;
}
/************************************************** **************************/
/* translation() : fait en sorte que le point (0,0) soit au centre de */
/* l'écran */
/************************************************** **************************/
void translation(int x, int y) {
unsigned short *VideoBuffer = (unsigned short *) 0x6000000;
// Passer en mode 3:
REG_DISPCNT= (0x3 | 0x400);
x = x + 120;
y = 80 - y;
VideoBuffer[y * 240 + x] = RGB(20,20,20);
}
/************************************************** **************************/
/* axex() : génération des axes après translation */
/************************************************** **************************/
void axes(void) {
int x2;
int y2;
for (x2= -120; x2< 120; x2= x2+1) {
translation(x2,0);
}
for (y2=-80; y2<160; y2++) {
translation(0,y2);
}
}
/************************************************** **************************/
/* Afficher() : dessine la scene a l'ecran */
/************************************************** **************************/
void Afficher(int couleur)
{
int i;
for (i=0;i<8;i++)
{
translation(Point2D[i].x,Point2D[i].y);
}
}
/************************************************** **************************/
/* Line() : trace une ligne entre deux points */
/************************************************** **************************/
void Line(int x1,int y1, int x2,int y2)
{
int xx,yy;
int Dx,Dy;
int xincr,yincr;
int erreur;
int i;
/* On initialise les variables */
Dx = abs(x2-x1);
Dy = abs(y2-y1);
/* On détermine dans quel sens varie la droite */
if(x1<x2)
xincr = 1;
else
xincr = -1;
if(y1<y2)
yincr = 1;
else
yincr = -1;
/* Trace de ligne */
xx = x1;
yy = y1;
if(Dx>Dy)
{
erreur = Dx/2;
for(i=0;i<Dx;i++)
{
xx += xincr;
erreur += Dy;
if(erreur>Dx)
{
erreur -= Dx;
yy += yincr;
}
translation(xx,yy);
}
}
else
{
erreur = Dy/2;
for(i=0;i<Dy;i++)
{
yy += yincr;
erreur += Dx;
if(erreur>Dy)
{
erreur -= Dy;
xx += xincr;
}
translation(xx,yy);
}
}
}
/************************************************** **************************/
/* Afficher() : dessine la scene a l'ecran */
/************************************************** **************************/
void fildefer(point2D *Point2D) {
for (int aze =0; aze<12; aze++) {
Line (Point2D[Poly[aze].a].x, Point2D[Poly[aze].a].y, Point2D[Poly[aze].b].x, Point2D[Poly[aze].b].y);
Line (Point2D[Poly[aze].a].x, Point2D[Poly[aze].a].y, Point2D[Poly[aze].c].x, Point2D[Poly[aze].c].y);
Line (Point2D[Poly[aze].b].x, Point2D[Poly[aze].b].y, Point2D[Poly[aze].c].x, Point2D[Poly[aze].c].y);
}
}
/************************************************** ************************************************** ************************************************** *****/
/************************************************** ************************************************** ************************************************** *****/
fillpolygones** Initialiserfillpoly(fillpolygones *fillpoly)
{
//fillpolygones fillpoly[200];
for (signed int i=-100; i<100;i++) {
fillpoly[i].y = i;
fillpoly[i].startx = -16000;
fillpoly[i].endx = -16000;
}
return (fillpolygones**)fillpoly;
}
void InitSegment(int x1, int y1, int x2,int y2)
{
int temp,y;
long x,pas;
if(y2!=y1)
{
if(y2<y1)
{
temp=y1;
y1=y2;
y2=temp;
temp=x1;
x1=x2;
x2=temp;
}
x = x1<<8;
pas= ((x2-x1)<<8)/(y2-y1);
x+=pas;
y1++;
//if(y1<miny) miny=y1;
//if(y2>maxy) maxy=y2;
for(y=y1;y<=y2;y++)
{
if (y>= -80) {
//if((y>=-80) /*&& (y<Ymax)*/) l'axe des ordonnées va de -80 à 80
if(fillpoly[y].startx == -16000) {
fillpoly[y].startx = x>>8;
} else {
fillpoly[y].endx = x>>8;
}
}
x+=pas;
}
}
}
void Hline()
{
int x1, x2;
//unsigned short *VideoBuffer = (unsigned short *) 0x6000000;
// Passer en mode 3:
//REG_DISPCNT= (0x3 | 0x400);
for (int i=-100; i<100; i++) {
if (fillpoly[i].startx != -16000 && fillpoly[i].endx != -16000) {
if (fillpoly[i].startx < fillpoly[i].endx) {
x1 = fillpoly[i].startx;
x2 = fillpoly[i].endx;
}
else
{
x1 = fillpoly[i].endx;
x2 = fillpoly[i].startx;
}
for (int ii=x1; ii<=x2; ii++)
{
//VideoBuffer[y * 240 + x] = RGB(20,20,20);
translation(ii,fillpoly[i].y);
}
}
}
}
/************************************************** ************************************************** ************************************************** *****/
/************************************************** ************************************************** ************************************************** *****/
void fildefer2(point2D *Point2D) {
for (int aze =0; aze<12; aze++) {
Line (Point2D[Poly[aze].a].x, Point2D[Poly[aze].a].y, Point2D[Poly[aze].b].x, Point2D[Poly[aze].b].y);
Line (Point2D[Poly[aze].a].x, Point2D[Poly[aze].a].y, Point2D[Poly[aze].c].x, Point2D[Poly[aze].c].y);
Line (Point2D[Poly[aze].b].x, Point2D[Poly[aze].b].y, Point2D[Poly[aze].c].x, Point2D[Poly[aze].c].y);
}
}
/************************************************** **************************/
/* reset_screen() : efface l'écran */
/************************************************** **************************/
void reset_screen() {
unsigned short *VideoBuffer = (unsigned short *) 0x6000000;
// Passer en mode 3:
REG_DISPCNT= (0x3 | 0x400);
int xx = 0;
int yy = 0;
for (yy=0; yy <160; yy++) {
for (xx=0; xx<240; xx++) {
VideoBuffer[yy * 240 + xx] = RGB(90,90,90);
}
}
}
/************************************************** **************************/
/*** MAIN ***/
/************************************************** **************************/
int main(void)
{
//ham_Init();
unsigned short *VideoBuffer = (unsigned short *) 0x6000000;
//Passer en mode 3:
REG_DISPCNT= (0x3 | 0x400);
while(true)
{
int xa,ya,za;
axes();
bool bouton_presse = 0;
// Initialisations
Initialiserfillpoly(fillpoly);
Init_Sinus(Sin, Cos);
Initialiser(Sommet);
Initialiser2(Poly);
xa=ya=za=0;
Rotation(Point3D,0,0,0);
delete[] Sommet;
Projection(Point2D);
delete[] Point3D;
Afficher(100);
fildefer(Point2D);
int aze = 0;
Initialiserfillpoly(fillpoly);
InitSegment (Point2D[Poly[aze].a].x, Point2D[Poly[aze].a].y, Point2D[Poly[aze].b].x, Point2D[Poly[aze].b].y);
InitSegment (Point2D[Poly[aze].a].x, Point2D[Poly[aze].a].y, Point2D[Poly[aze].c].x, Point2D[Poly[aze].c].y);
InitSegment (Point2D[Poly[aze].b].x, Point2D[Poly[aze].b].y, Point2D[Poly[aze].c].x, Point2D[Poly[aze].c].y);
Hline();
//Afficher(100);
//fildefer(Point2D);
/*
Initialiserfillpoly();
InitSegment (-53, -53, 53, -53);
InitSegment (-53, -53, -53, 53);
InitSegment (53, -53, -53, 53);
Hline();
*/
while (bouton_presse == 0) {
if (F_CTRLINPUT_UP_PRESSED)
{
bouton_presse = 1;
reset_screen();
axes();
ya = ya + 10;
if (ya >= 360) {
ya = 0;
}
Rotation(Point3D,xa,ya,za);
Projection(Point2D);
Afficher(100);
fildefer(Point2D);
bouton_presse = 0;
}
if (F_CTRLINPUT_DOWN_PRESSED)
{
reset_screen();
axes();
ya = ya - 10;
if (ya <= 0) {
ya = 360;
}
Rotation(Point3D,xa,ya,za);
Projection(Point2D);
Afficher(100);
fildefer(Point2D);
}
if (F_CTRLINPUT_LEFT_PRESSED)
{
reset_screen();
axes();
za = za - 10;
if (za <= 0) {
za = 360;
}
Rotation(Point3D,xa,ya,za);
Projection(Point2D);
Afficher(100);
fildefer(Point2D);
}
if (F_CTRLINPUT_RIGHT_PRESSED) // Pour la droite
{
reset_screen();
axes();
za = za + 10;
if (za >= 360) {
za = 0;
}
Rotation(Point3D,xa,ya,za);
Projection(Point2D);
Afficher(100);
fildefer(Point2D);
}
} // while
while (bouton_presse == 1) {
if ( F_CTRLINPUT_UP_PRESSED
|| F_CTRLINPUT_DOWN_PRESSED
|| F_CTRLINPUT_LEFT_PRESSED
|| F_CTRLINPUT_RIGHT_PRESSED)
{
axes();
bouton_presse = 0;
}
} // while
}
return 0;
}
/* END OF FILE */