
NeoFab
|
Le compilateur c'est Borland Turbo C++ v3.0, les switch jamais entendu parler, et le code source c'est:
#include <mem.h> #include <math.h> #include <time.h> #include <conio.h> #include <stdio.h> #include <stdlib.h>
//----------------------------------------------------------------------// // Types personalises // //----------------------------------------------------------------------//
typedef struct _2D // Pour contenir les informations sur un { // sommet d'un polygone int x,y; };
typedef struct TScan // Structure pour le remplissage de polygones { long gauche,droite; };
//----------------------------------------------------------------------// // Variables globales // //----------------------------------------------------------------------//
int miny,maxy; // Hauteur des polygones TScan scanline[200]; // Largeur des lignes des polys char *ecran = (char *) (0xA0000000L); // Pointeur sur RAM video
//----------------------------------------------------------------------// // setmode - Appelle le mode passer en parametre // //----------------------------------------------------------------------// void setmode(unsigned int mode) { asm { MOV AX, [mode] INT 0x10 } }
//----------------------------------------------------------------------// // cls - vide l'ecran // //----------------------------------------------------------------------// void cls() { memset(ecran,0,64000L); }
//----------------------------------------------------------------------// // putpixel - Affiche un pixel directement dans la memoire // //----------------------------------------------------------------------// void putpixel (int x, int y, unsigned char coul) { ecran[(y*320)+x] = coul; }
//----------------------------------------------------------------------// // hline - Dessine une ligne horizontale // //----------------------------------------------------------------------// void hline(int x1, int x2, int y, unsigned char coul) { memset(ecran+x1+(y*320),coul,(x2-x1)); }
//----------------------------------------------------------------------// // Line - Dessine une ligne selon l'algorithme de Bresenham // //----------------------------------------------------------------------// void line(int x1, int y1, int x2, int y2, unsigned char coul) { int x_chan, y_chan; // Pour le changement dans x et y int offset = (y1<<8)+(y1<<6) + x1; // Calcule l'offset dans la RAM int ydiff = y2-y1; // Calcule la difference entre y2 et y1 int deviation = 0; // Initialise la deviation a 0;
if (ydiff < 0) // Si la ligne va dans un direction - { ydiff = -ydiff; y_chan = -320; } else y_chan = 320;
int xdiff = x2-x1; // Calcule la difference entre x2 et x1
if (xdiff < 0) // Si la ligne va dans un direction + { xdiff = -xdiff; x_chan = -1; }
else x_chan = 1;
if (xdiff > ydiff) // si la difference est + grande { // sur l'axe X int longueur = xdiff+1; for(int i = 0; i < longueur; i++) { ecran[offset] = coul; offset+=x_chan; deviation+=ydiff; if (deviation>xdiff) // Est-ce le temps de changer Y? { deviation-=xdiff; offset+=y_chan; } } } else // Difference + grande sur Y { int longueur = ydiff+1; for(int i = 0; i < longueur; i++) { ecran[offset] = coul; offset+=y_chan; deviation+=xdiff; if (deviation>0) // Est-ce le temps de changer X? { deviation-=ydiff; offset+=x_chan; } } } }
//----------------------------------------------------------------------// // sinline - Affiche des lignes sinuosidales // //----------------------------------------------------------------------// void sinline(int y, int hauteur, float freq, unsigned char coul) { float courbe = 0; int point;
for (int i=0; i<319; i++) { point = ((sin(courbe)*hauteur)+y); courbe += freq; ecran[(point*320)+i]=coul; } }
//----------------------------------------------------------------------// // circle() - Dessine un cercle avec l'algorithme de Bresenham // //----------------------------------------------------------------------// void circle(int cx, int cy, int r, unsigned char coul) { int x,y; for(x=-r; x<r; x++) { y=sqrt(r*r - x*x); ecran[(cy+y)*320+x+cx]=coul; ecran[(cy-y)*320+x+cx]=coul; } }
//----------------------------------------------------------------------// // Swap - Effectue l'echange entre 2 variables float // //----------------------------------------------------------------------// void Swap(float &x,float &y) { float temp = x; x = y; y = temp; }
//----------------------------------------------------------------------// // Scan - Trouve le minX et maxX d'un cote d'un polygone // //----------------------------------------------------------------------// void scan(float x1, float y1, float x2, float y2) { if (y1==y2) return; // Check pour la div/0 if (y2<y1) {Swap (y1,y2); Swap (x1,x2);} // Dans le bon sens...
double Xinc = (x2-x1) / (y2-y1); // Regression lineaire double x = x1 += Xinc; // pente m = (dx/dy) // on saute par dessus le premier if(y1<miny) miny=y1; // pixel if(y2>maxy) maxy=y2;
for (int y=y1;y<y2;y++) // On scan la ligne de haut en bas { if (x < scanline[y].gauche) scanline[y].gauche = x; if (x > scanline[y].droite) scanline[y].droite = x; x+=Xinc; } }
//----------------------------------------------------------------------// // dessinepoly - Dessine un polygone avec liste de points(listesommet) // //----------------------------------------------------------------------// void dessinepoly(_2D *listesommet, int nbcotes, unsigned char coul) { // On declare deux pointeurs sur des sommets. Ils seront utilises // pour progresser dans la liste des sommets. _2D *ptrcour, *ptrsuiv;
// Initialisation de la liste chainee ptrcour = listesommet; ptrsuiv = listesommet+1;
// Reinisialisation des valeurs extremes miny=200; maxy=0; for (int i=0;i<200;i++) { scanline[i].gauche = 32000; scanline[i].droite = -32000; } // On parcours la liste des polygones et on trouve les extremites for (i = 1; i < nbcotes; i++) { scan(ptrcour->x, ptrcour->y, ptrsuiv->x, ptrsuiv->y); ptrcour++; ptrsuiv++; } // Il ne faut pas oublier de fermer le polygone ptrsuiv = listesommet; scan(ptrcour->x, ptrcour->y, ptrsuiv->x, ptrsuiv->y); // on parcours le tableau de scanline et on dessine nos lignes horizontales for (int y=miny;y<maxy;y++) hline (scanline[y].gauche,scanline[y].droite,y,coul); }
//----------------------------------------------------------------------// // testlignes() - Affiche des lignes de longueurs et couleurs aleatoires// //----------------------------------------------------------------------// void testligne() { int x1,y1,x2,y2; unsigned char coul; printf("TEST DE L'ALGORITHME DE LIGNE BRESENHAM"); do { x1 = random(320); x2 = random(320); y1 = random(190)+10; y2 = random(190)+10; coul = random(256); line(x1,y1,x2,y2,coul); } while (!kbhit()); }
//----------------------------------------------------------------------// // testsinus() - Affiche des lignes sinus de hauteur differentes // //----------------------------------------------------------------------// void testsinus() { short wave = 1; short hauteur = 30;
cls(); gotoxy(8,1);printf("TEST DE LIGNES SINUOSIDALES"); do { for (unsigned int ralenti=0;ralenti<65500;ralenti++) {}
line(0,100,319,100,190); sinline(100,hauteur,0.03,0); if (hauteur == 60) wave =- 1; if (hauteur == -60) wave =+ 1; hauteur += wave; sinline(100,hauteur,0.03,50); } while (!kbhit()); }
//----------------------------------------------------------------------// // testcercle() - Affiche des cercles de rayons differents // //----------------------------------------------------------------------// void testcercle() { int x,y,rayon; unsigned char coul;
cls(); gotoxy(1,1);printf("TEST DE L'ALGORITHME DE CERCLE BRESENHAM"); do { x = random(320); y = random(100)+60; rayon = random(40); coul = random(256); circle(x,y,rayon,coul); } while(!kbhit()); }
//----------------------------------------------------------------------// // testpoly() - Dessine des polygones convexes (triangle et rectangle) // //----------------------------------------------------------------------// void testpoly() { unsigned char coul; unsigned long tri, tempdeb, tempfin;
cls(); gotoxy(4,1);printf("TEST DE L'ALGORITHME DE POLYGONES");
_2D triangle[3]; _2D rectangle[4];
// Definition d'un triangle triangle[0].x = 20; triangle[0].y = 20; triangle[1].x = 100; triangle[1].y = 70; triangle[2].x = 20; triangle[2].y = 70;
// Definition d'un rectangle rectangle[0].x = 180; rectangle[0].y = 40; rectangle[1].x = 300; rectangle[1].y = 50; rectangle[2].x = 180; rectangle[2].y = 170; rectangle[3].x = 120; rectangle[3].y = 180;
do { dessinepoly(triangle,3,40); // Dessine un triangle dessinepoly(rectangle,4,50); // Dessine un rectangle } while(!kbhit());
//-------- TEST DE VITESSE ---------// getch(); cls();
tri=0; tempdeb = clock(); // clock() retourne le temps de debut do { for (int s=0;s<3;s++) { triangle[s].x = random(320); triangle[s].y = random(200); coul = random(256); dessinepoly(triangle,3,coul); tri++; // incremente le compteur de triangle } } while(!kbhit());
tempfin = clock(); // clock() pour le temps de fin setmode(0x03); printf("Triangles par seconde: %.2f\n", (tri / ((tempfin - tempdeb) / CLK_TCK))); printf("\nShaun Dore\ndores@videotron.ca\nhttp://pages.infinit.net/shaun/"); }
//----------------------------------------------------------------------// // Fonction MAIN // //----------------------------------------------------------------------//
void main() { randomize(); setmode(0x13); testligne(); getch(); testsinus(); getch(); testcercle(); getch(); testpoly(); }
|