Le source : RasterisationTriangle.cpp
/* Un programme OpenGL de rasterisation */
/* d'un triangle */
/* */
/* Auteur: Nicolas JANEY */
/* nicolas.janey@univ-fcomte.fr */
/* Novembre 2009 */
#include <stdlib.h>
#include <stdio.h>
#include <GL/glut.h>
#include <GL/gl.h>
#include <GL/glu.h>
typedef struct position2D {
int x;
int y;
int w; } position2D;
typedef struct triangle {
position2D p1;
position2D p2;
position2D p3; } triangle;
static int scn = 0;
static triangle t1 =
{ { -20, 110 },
{ -100, -10 },
{ 90, -90 } };
static triangle t2 =
{ { -20, 110 },
{ -100, -90 },
{ 90, -30 } };
static triangle t = t1;
/* Scene dessinee */
void ligne(position2D *pi,position2D *pf) {
int i,cumul;
int x = pi->x;
int y = pi->y;
int dx = pf->x - pi->x;
int dy = pf->y - pi->y;
int xinc = ( dx > 0 ) ? 1 : -1;
int yinc = ( dy > 0 ) ? 1 : -1;
dx = abs(dx);
dy = abs(dy);
glBegin(GL_POINTS);
glVertex2i(x,y);
if ( dx > dy ) {
cumul = dx>>1;
for ( i = 1 ; i <= dx ; i++ ) {
x += xinc;
cumul += dy;
if (cumul >= dx) {
cumul -= dx;
y += yinc; }
glVertex2i(x,y); } }
else {
cumul = dy / 2;
for ( i = 1 ; i <= dy ; i++ ) {
y += yinc;
cumul += dx;
if ( cumul >= dy ) {
cumul -= dy;
x += xinc; }
glVertex2i(x,y); } }
glEnd();
}
void scene1(void) {
glPushMatrix();
glColor3f(1.0F,0.0F,0.0F);
ligne(&t.p1,&t.p2);
glColor3f(0.0F,1.0F,0.0F);
ligne(&t.p2,&t.p3);
glColor3f(0.0F,0.0F,1.0F);
ligne(&t.p3,&t.p1);
glPopMatrix();
}
void tourneSensMontre(triangle *t) {
position2D p = t->p1;
t->p1 = t->p2;
t->p2 = t->p3;
t->p3 = p;
}
void tourneInverseSensMontre(triangle *t) {
position2D p = t->p1;
t->p1 = t->p3;
t->p3 = t->p2;
t->p2 = p;
}
void ordonne(triangle *t) {
if ( ( t->p1.y <= t->p2.y ) && ( t->p1.y <= t->p3.y ) )
return;
if ( t->p2.y <= t->p3.y )
tourneSensMontre(t);
else
tourneInverseSensMontre(t);
}
void bord(int *tx,int ymin,position2D *pi,position2D *pf) {
int i,cumul;
int x = pi->x;
int y = pi->y;
int dx = pf->x - pi->x;
int dy = pf->y - pi->y;
int xinc = ( dx > 0 ) ? 1 : -1;
int yinc = ( dy > 0 ) ? 1 : -1;
dx = abs(dx);
dy = abs(dy);
tx[y-ymin] = x;
if ( dx > dy ) {
cumul = dx>>1;
for ( i = 1 ; i <= dx ; i++ ) {
x += xinc;
cumul += dy;
if (cumul >= dx) {
cumul -= dx;
y += yinc; }
tx[y-ymin] = x; } }
else {
cumul = dy / 2;
for ( i = 1 ; i <= dy ; i++ ) {
y += yinc;
cumul += dx;
if ( cumul >= dy ) {
cumul -= dy;
x += xinc; }
tx[y-ymin] = x; } }
}
void triangle(triangle *t) {
ordonne(t);
int ymin = t->p1.y;
int ymax;
int type;
if ( t->p2.y > t->p3.y ) {
ymax = t->p2.y;
type = 0; }
else {
ymax = t->p3.y;
type = 1; }
int ydim = ymax-ymin+1;
//printf("%d %d\n",t->p1.x,t->p1.y);
//printf("%d %d\n",t->p2.x,t->p2.y);
//printf("%d %d\n",t->p3.x,t->p3.y);
//printf("%d\n",ymin);
//printf("%d\n",ymax);
//printf("%d\n",type);
int *bd =(int *) calloc(ydim,sizeof(int));
int *bg =(int *) calloc(ydim,sizeof(int));
switch (type) {
case 0 :
bord(bd,ymin,&t->p1,&t->p2);
bord(bg,ymin,&t->p2,&t->p3);
bord(bg,ymin,&t->p3,&t->p1);
break;
case 1 :
bord(bd,ymin,&t->p1,&t->p2);
bord(bd,ymin,&t->p2,&t->p3);
bord(bg,ymin,&t->p3,&t->p1);
break; }
//for ( int i = 0 ; i < ydim ; i++ )
// printf("%4d %4d %4d\n",i,bg[i],bd[i]);
glBegin(GL_LINES);
for ( int y = ymin ; y <= ymax ; y++ ) {
glVertex2i(bg[y-ymin],y);
glVertex2i(bd[y-ymin],y); }
glEnd();
free(bg);
free(bd);
}
void scene2(void) {
glPushMatrix();
glColor3f(0.5F,0.5F,0.5F);
triangle(&t);
glPopMatrix();
}
/* Fonction executee lors d'un rafraichissement */
/* de la fenetre de dessin */
void display(void) {
glClearColor(1.0F,1.0F,1.0F,1.0F);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glPushMatrix();
if ( scn == 0 )
scene1();
else
scene2();
glPopMatrix();
glFlush();
glutSwapBuffers();
}
/* Fonction executee lors d'un changement */
/* de la taille de la fenetre OpenGL */
void reshape(int x,int y) {
glViewport(0,0,x,y);
glMatrixMode(GL_PROJECTION) ;
glLoadIdentity() ;
glOrtho(-x/2,-x/2+x,-y/2,-y/2+y,-300.0,300.0) ;
glMatrixMode(GL_MODELVIEW) ;
glLoadIdentity() ;
}
/* Fonction executee lors de l'appui */
/* d'une touche alphanumerique du clavier */
void keyboard(unsigned char key,int x,int y) {
switch (key) {
case 0x20 :
{ static int tr = 0;
tr = (tr+1)%2;
if ( tr == 1 )
t = t2;
else
t = t1; }
glutPostRedisplay();
break;
case 0x0D :
scn = !scn;
glutPostRedisplay();
break;
case 0x1B :
exit(0);
break; }
}
/* Fonction principale */
int main(int argc,char **argv) {
glutInit(&argc,argv);
glutInitDisplayMode(GLUT_RGBA|GLUT_DEPTH|GLUT_DOUBLE);
glutInitWindowSize(240,240);
glutInitWindowPosition(50,50);
glutCreateWindow("Rasterisation d'un triangle");
glutKeyboardFunc(keyboard);
glutReshapeFunc(reshape);
glutDisplayFunc(display);
glutMainLoop();
return(0);
}