Update comments

This commit is contained in:
Mylloon 2021-12-31 14:48:24 +01:00
parent a8dad88046
commit e5c9b0d795
Signed by: Anri
GPG key ID: A82D63DFF8D1317F
5 changed files with 118 additions and 123 deletions

View file

@ -5,7 +5,7 @@
* *
* \author Farès BELHADJ, amsi@up8.edu * \author Farès BELHADJ, amsi@up8.edu
* \date November, 2021. * \date November, 2021.
*/ */
#include "rasterize.h" #include "rasterize.h"
#include <assert.h> #include <assert.h>
#if defined(_MSC_VER) #if defined(_MSC_VER)
@ -13,7 +13,7 @@
#endif #endif
#include <math.h> #include <math.h>
/*!\brief fabrique et renvoie une surface représentant un /*!\brief Fabrique et renvoie une surface représentant un
* quadrilatère "debout" et à la profondeur 0. Il fait la hauteur et * quadrilatère "debout" et à la profondeur 0. Il fait la hauteur et
* la largeur du cube unitaire (-1 à 1).*/ * la largeur du cube unitaire (-1 à 1).*/
surface_t * mk_quad(void) { surface_t * mk_quad(void) {
@ -44,7 +44,7 @@ surface_t * mk_quad(void) {
return s; return s;
} }
/*!\brief fabrique et renvoie une surface représentant un /*!\brief Fabrique et renvoie une surface représentant un
* cube unitaire (de -1 à 1).*/ * cube unitaire (de -1 à 1).*/
surface_t * mk_cube(void) { surface_t * mk_cube(void) {
const float const float
@ -100,7 +100,7 @@ surface_t * mk_cube(void) {
return s; return s;
} }
/*!\brief fabrique et renvoie une surface représentant une sphère /*!\brief Fabrique et renvoie une surface représentant une sphère
* centrée en zéro et de rayon 1. Elle est découpée en \a longitudes * centrée en zéro et de rayon 1. Elle est découpée en \a longitudes
* longitudes et \a latitudes latitudes. */ * longitudes et \a latitudes latitudes. */
surface_t * mk_sphere(int longitudes, int latitudes) { surface_t * mk_sphere(int longitudes, int latitudes) {
@ -130,7 +130,7 @@ surface_t * mk_sphere(int longitudes, int latitudes) {
data[k].texCoord.x = phi / (2.0 * M_PI); data[k].texCoord.x = phi / (2.0 * M_PI);
data[k].texCoord.y = (theta + M_PI_2) / M_PI; data[k].texCoord.y = (theta + M_PI_2) / M_PI;
data[k].color0 = color0; data[k].color0 = color0;
/* gcc 7.5 et plus abusent : data[k].normal = *(vec3 *)&(data[k].position); */ /* gcc 7.5 et plus abusent : data[k].normal = *(vec3 *)&(data[k].position); */
data[k].normal.x = data[k].position.x; data[k].normal.x = data[k].position.x;
data[k].normal.y = data[k].position.y; data[k].normal.y = data[k].position.y;
data[k].normal.z = data[k].position.z; data[k].normal.z = data[k].position.z;

View file

@ -13,7 +13,7 @@
#include "rasterize.h" #include "rasterize.h"
#include <assert.h> #include <assert.h>
/* bloc de fonctions locales (static) */ /* Fonctions locales (static) */
static inline void fill_triangle(surface_t * s, triangle_t * t); static inline void fill_triangle(surface_t * s, triangle_t * t);
static inline void abscisses(surface_t * s, vertex_t * p0, vertex_t * p1, vertex_t * absc, int replace); static inline void abscisses(surface_t * s, vertex_t * p0, vertex_t * p1, vertex_t * absc, int replace);
static inline void horizontal_line(surface_t * s, vertex_t * vG, vertex_t * vD); static inline void horizontal_line(surface_t * s, vertex_t * vG, vertex_t * vD);
@ -35,22 +35,22 @@ static inline GLubyte blue(GLuint c);
static inline GLubyte alpha(GLuint c); static inline GLubyte alpha(GLuint c);
static void pquit(void); static void pquit(void);
/*!\brief la texture courante à utiliser en cas de mapping de texture */ /*!\brief Texture courante à utiliser en cas de mapping de texture */
static GLuint * _tex = NULL; static GLuint * _tex = NULL;
/*!\brief la largeur de la texture courante à utiliser en cas de /*!\brief Largeur de la texture courante à utiliser en cas de
* mapping de texture */ * mapping de texture */
static GLuint _texW = 0; static GLuint _texW = 0;
/*!\brief la hauteur de la texture courante à utiliser en cas de /*!\brief Hauteur de la texture courante à utiliser en cas de
* mapping de texture */ * mapping de texture */
static GLuint _texH = 0; static GLuint _texH = 0;
/*!\brief un buffer de depth pour faire le z-test */ /*!\brief Buffer de prodondeur pour faire le z-test */
static float * _depth = NULL; static float * _depth = NULL;
/*!\brief flag pour savoir s'il faut ou non corriger l'interpolation /*!\brief Flag pour savoir s'il faut ou non corriger l'interpolation
* par rapport à la profondeur en cas de projection en * par rapport à la profondeur en cas de projection en
* perspective */ * perspective */
static int _perpective_correction = 0; static int _perpective_correction = 0;
/*!\brief transforme et rastérise l'ensemble des triangles de la /*!\brief Transforme et rastérise l'ensemble des triangles de la
* surface. */ * surface. */
void transform_n_rasterize(surface_t * s, float * model_view_matrix, float * projection_matrix) { void transform_n_rasterize(surface_t * s, float * model_view_matrix, float * projection_matrix) {
int i; int i;
@ -61,7 +61,7 @@ void transform_n_rasterize(surface_t * s, float * model_view_matrix, float * pro
atexit(pquit); atexit(pquit);
} }
/* si projection_matrix[15] est à 1, c'est une projection orthogonale, pas /* si projection_matrix[15] est à 1, c'est une projection orthogonale, pas
* besoin de correction de perspective */ * besoin de correction de perspective */
_perpective_correction = projection_matrix[15] == 1.0f ? 0 : 1; _perpective_correction = projection_matrix[15] == 1.0f ? 0 : 1;
/* le viewport est fixe ; \todo peut devenir paramétrable ... */ /* le viewport est fixe ; \todo peut devenir paramétrable ... */
float viewport[] = { 0.0f, 0.0f, (float)gl4dpGetWidth(), (float)gl4dpGetHeight() }; float viewport[] = { 0.0f, 0.0f, (float)gl4dpGetWidth(), (float)gl4dpGetHeight() };
@ -75,9 +75,9 @@ void transform_n_rasterize(surface_t * s, float * model_view_matrix, float * pro
/* on rejette aussi les triangles complètement out */ /* on rejette aussi les triangles complètement out */
if(s->t[i].state & PS_TOTALLY_OUT) continue; if(s->t[i].state & PS_TOTALLY_OUT) continue;
/* "hack" pas terrible permettant de rejeter les triangles /* "hack" pas terrible permettant de rejeter les triangles
* partiellement out dont au moins un sommet est TOO_FAR (trop * partiellement out dont au moins un sommet est TOO_FAR (trop
* éloigné). Voir le fichier transformations.c pour voir comment * éloigné). Voir le fichier transformations.c pour voir comment
* améliorer ce traitement. */ * améliorer ce traitement. */
if( s->t[i].state & PS_PARTIALLY_OUT && if( s->t[i].state & PS_PARTIALLY_OUT &&
( (s->t[i].v[0].state & PS_TOO_FAR) || ( (s->t[i].v[0].state & PS_TOO_FAR) ||
(s->t[i].v[1].state & PS_TOO_FAR) || (s->t[i].v[1].state & PS_TOO_FAR) ||
@ -88,7 +88,7 @@ void transform_n_rasterize(surface_t * s, float * model_view_matrix, float * pro
} }
} }
/*!\brief effacer le buffer de profondeur (à chaque frame) pour /*!\brief Efface le buffer de profondeur (à chaque frame) pour
* réaliser le z-test */ * réaliser le z-test */
void clear_depth_map(void) { void clear_depth_map(void) {
if(_depth) { if(_depth) {
@ -96,7 +96,7 @@ void clear_depth_map(void) {
} }
} }
/*!\brief met en place une texture pour être mappée sur la surface en cours */ /*!\brief Met en place une texture pour être mappée sur la surface en cours */
void set_texture(GLuint screen) { void set_texture(GLuint screen) {
GLuint old_id = gl4dpGetTextureId(); /* au cas où */ GLuint old_id = gl4dpGetTextureId(); /* au cas où */
gl4dpSetScreen(screen); gl4dpSetScreen(screen);
@ -108,7 +108,7 @@ void set_texture(GLuint screen) {
} }
/*!\brief met à jour la fonction d'interpolation et de coloriage /*!\brief Met-à-jour la fonction d'interpolation et de coloriage
* (shadingfunc) de la surface en fonction de ses options */ * (shadingfunc) de la surface en fonction de ses options */
void updatesfuncs(surface_t * s) { void updatesfuncs(surface_t * s) {
int t; int t;
@ -121,10 +121,9 @@ void updatesfuncs(surface_t * s) {
} }
} }
/*!\brief fonction principale de ce fichier, elle dessine un triangle /*!\brief Dessine un triangle et le rempli en calculant l'ensemble
* rempli à l'écran en calculant l'ensemble des gradients * des gradients avec interpolations bilinaires des attributs du sommet
* (interpolations bilinaires des attributs du sommet). * (fonction principale de ce fichier) */
*/
inline void fill_triangle(surface_t * s, triangle_t * t) { inline void fill_triangle(surface_t * s, triangle_t * t) {
vertex_t * aG = NULL, * aD = NULL; vertex_t * aG = NULL, * aD = NULL;
int bas, median, haut, n, signe, i, h = gl4dpGetHeight(); int bas, median, haut, n, signe, i, h = gl4dpGetHeight();
@ -196,9 +195,8 @@ inline void fill_triangle(surface_t * s, triangle_t * t) {
free(aD); free(aD);
} }
/*!\brief utilise Br'65 pour determiner les abscisses des segments du /*!\brief Utilise Br'65 pour determiner les abscisses des segments du
* triangle à remplir (par \a horizontal_line). * triangle à remplir (par \a horizontal_line). */
*/
inline void abscisses(surface_t * s, vertex_t * p0, vertex_t * p1, vertex_t * absc, int replace) { inline void abscisses(surface_t * s, vertex_t * p0, vertex_t * p1, vertex_t * absc, int replace) {
int u = p1->x - p0->x, v = p1->y - p0->y, pasX = u < 0 ? -1 : 1, pasY = v < 0 ? -1 : 1; int u = p1->x - p0->x, v = p1->y - p0->y, pasX = u < 0 ? -1 : 1, pasY = v < 0 ? -1 : 1;
float dmax = sqrtf(u * u + v * v), p; float dmax = sqrtf(u * u + v * v), p;
@ -257,7 +255,7 @@ inline void abscisses(surface_t * s, vertex_t * p0, vertex_t * p1, vertex_t * ab
} }
} }
/*!\brief remplissage par droite horizontale entre deux abscisses */ /*!\brief Remplissage par droite horizontale entre deux abscisses */
inline void horizontal_line(surface_t * s, vertex_t * vG, vertex_t * vD) { inline void horizontal_line(surface_t * s, vertex_t * vG, vertex_t * vD) {
int w = gl4dpGetWidth(), x, yw = vG->y * w; int w = gl4dpGetWidth(), x, yw = vG->y * w;
GLuint * image = gl4dpGetPixels(); GLuint * image = gl4dpGetPixels();
@ -272,12 +270,12 @@ inline void horizontal_line(surface_t * s, vertex_t * vG, vertex_t * vD) {
_depth[yw + x] = v.z; _depth[yw + x] = v.z;
} }
} }
/*!\brief aucune couleur n'est inscrite */ /*!\brief Aucune couleur n'est inscrite */
inline void shading_none(surface_t * s, GLuint * pcolor, vertex_t * v) { inline void shading_none(surface_t * s, GLuint * pcolor, vertex_t * v) {
//vide pour l'instant, à prévoir le z-buffer // vide pour l'instant, à prévoir le z-buffer
} }
/*!\brief la couleur du pixel est tirée uniquement de la texture */ /*!\brief Couleur du pixel tirée uniquement de la texture */
inline void shading_only_tex(surface_t * s, GLuint * pcolor, vertex_t * v) { inline void shading_only_tex(surface_t * s, GLuint * pcolor, vertex_t * v) {
int xt, yt, ct; int xt, yt, ct;
GLubyte r, g, b, a; GLubyte r, g, b, a;
@ -302,7 +300,7 @@ inline void shading_only_tex(surface_t * s, GLuint * pcolor, vertex_t * v) {
*pcolor = rgba(r, g, b, a); *pcolor = rgba(r, g, b, a);
} }
/*!\brief la couleur du pixel est tirée de la couleur interpolée */ /*!\brief Couleur du pixel tirée de la couleur interpolée */
inline void shading_only_color_CM(surface_t * s, GLuint * pcolor, vertex_t * v) { inline void shading_only_color_CM(surface_t * s, GLuint * pcolor, vertex_t * v) {
GLubyte r, g, b, a; GLubyte r, g, b, a;
r = (GLubyte)(v->li * v->icolor.x * (255 + EPSILON)); r = (GLubyte)(v->li * v->icolor.x * (255 + EPSILON));
@ -312,7 +310,7 @@ inline void shading_only_color_CM(surface_t * s, GLuint * pcolor, vertex_t * v)
*pcolor = rgba(r, g, b, a); *pcolor = rgba(r, g, b, a);
} }
/*!\brief la couleur du pixel est tirée de la couleur diffuse de la /*!\brief Couleur du pixel tirée de la couleur diffuse de la
* surface */ * surface */
inline void shading_only_color(surface_t * s, GLuint * pcolor, vertex_t * v) { inline void shading_only_color(surface_t * s, GLuint * pcolor, vertex_t * v) {
GLubyte r, g, b, a; GLubyte r, g, b, a;
@ -323,7 +321,7 @@ inline void shading_only_color(surface_t * s, GLuint * pcolor, vertex_t * v) {
*pcolor = rgba(r, g, b, a); *pcolor = rgba(r, g, b, a);
} }
/*!\brief la couleur du pixel est le produit de la couleur interpolée /*!\brief Couleur du pixel = produit de la couleur interpolée
* et de la texture */ * et de la texture */
inline void shading_all_CM(surface_t * s, GLuint * pcolor, vertex_t * v) { inline void shading_all_CM(surface_t * s, GLuint * pcolor, vertex_t * v) {
GLubyte r, g, b, a; GLubyte r, g, b, a;
@ -348,7 +346,7 @@ inline void shading_all_CM(surface_t * s, GLuint * pcolor, vertex_t * v) {
*pcolor = rgba(r, g, b, a); *pcolor = rgba(r, g, b, a);
} }
/*!\brief la couleur du pixel est le produit de la couleur diffuse /*!\brief Couleur du pixel = produit de la couleur diffuse
* de la surface et de la texture */ * de la surface et de la texture */
inline void shading_all(surface_t * s, GLuint * pcolor, vertex_t * v) { inline void shading_all(surface_t * s, GLuint * pcolor, vertex_t * v) {
GLubyte r, g, b, a; GLubyte r, g, b, a;
@ -373,7 +371,7 @@ inline void shading_all(surface_t * s, GLuint * pcolor, vertex_t * v) {
*pcolor = rgba(r, g, b, a); *pcolor = rgba(r, g, b, a);
} }
/*!\brief interpolation de plusieurs floattants (entre \a s et \a e) /*!\brief Interpolation de plusieurs floattants (entre \a s et \a e)
* de la structure vertex_t en utilisant \a a et \a b, les * de la structure vertex_t en utilisant \a a et \a b, les
* facteurs \a fa et \a fb, le tout dans \a r * facteurs \a fa et \a fb, le tout dans \a r
* \todo un pointeur de fonction pour éviter un test s'il faut * \todo un pointeur de fonction pour éviter un test s'il faut
@ -383,7 +381,7 @@ inline void interpolate(vertex_t * r, vertex_t * a, vertex_t * b, float fa, floa
float * pr = (float *)&(r->texCoord); float * pr = (float *)&(r->texCoord);
float * pa = (float *)&(a->texCoord); float * pa = (float *)&(a->texCoord);
float * pb = (float *)&(b->texCoord); float * pb = (float *)&(b->texCoord);
/* Correction de l'interpolation par rapport à la perspective, le z /* correction de l'interpolation par rapport à la perspective, le z
* joue un rôle dans les distances, il est nécessaire de le * joue un rôle dans les distances, il est nécessaire de le
* réintégrer en modifiant les facteurs de proportion. * réintégrer en modifiant les facteurs de proportion.
* lien utile : https://www.scratchapixel.com/lessons/3d-basic-rendering/rasterization-practical-implementation/perspective-correct-interpolation-vertex-attributes * lien utile : https://www.scratchapixel.com/lessons/3d-basic-rendering/rasterization-practical-implementation/perspective-correct-interpolation-vertex-attributes
@ -400,26 +398,26 @@ inline void interpolate(vertex_t * r, vertex_t * a, vertex_t * b, float fa, floa
pr[i] = fa * pa[i] + fb * pb[i]; pr[i] = fa * pa[i] + fb * pb[i];
} }
/*!\brief meta-fonction pour appeler \a interpolate, demande /*!\brief Meta-fonction pour appeler \a interpolate, demande
* uniquement l'interpolation des z */ * uniquement l'interpolation des z */
inline void metainterpolate_none(vertex_t * r, vertex_t * a, vertex_t * b, float fa, float fb) { inline void metainterpolate_none(vertex_t * r, vertex_t * a, vertex_t * b, float fa, float fb) {
interpolate(r, a, b, fa, fb, 6, 8); interpolate(r, a, b, fa, fb, 6, 8);
} }
/*!\brief meta-fonction pour appeler \a interpolate, demande /*!\brief Meta-fonction pour appeler \a interpolate, demande
* uniquement l'interpolation des coord. de texture et les z */ * uniquement l'interpolation des coord. de texture et les z */
inline void metainterpolate_only_tex(vertex_t * r, vertex_t * a, vertex_t * b, float fa, float fb) { inline void metainterpolate_only_tex(vertex_t * r, vertex_t * a, vertex_t * b, float fa, float fb) {
interpolate(r, a, b, fa, fb, 0, 1); interpolate(r, a, b, fa, fb, 0, 1);
interpolate(r, a, b, fa, fb, 6, 8); interpolate(r, a, b, fa, fb, 6, 8);
} }
/*!\brief meta-fonction pour appeler \a interpolate, demande /*!\brief Meta-fonction pour appeler \a interpolate, demande
* uniquement l'interpolation des couleurs et les z */ * uniquement l'interpolation des couleurs et les z */
inline void metainterpolate_only_color(vertex_t * r, vertex_t * a, vertex_t * b, float fa, float fb) { inline void metainterpolate_only_color(vertex_t * r, vertex_t * a, vertex_t * b, float fa, float fb) {
interpolate(r, a, b, fa, fb, 2, 8); interpolate(r, a, b, fa, fb, 2, 8);
} }
/*!\brief meta-fonction pour appeler \a interpolate, demande /*!\brief Meta-fonction pour appeler \a interpolate, demande
* l'interpolation de l'ensemble des attributs */ * l'interpolation de l'ensemble des attributs */
inline void metainterpolate_all(vertex_t * r, vertex_t * a, vertex_t * b, float fa, float fb) { inline void metainterpolate_all(vertex_t * r, vertex_t * a, vertex_t * b, float fa, float fb) {
interpolate(r, a, b, fa, fb, 0, 8); interpolate(r, a, b, fa, fb, 0, 8);
@ -446,7 +444,7 @@ GLubyte alpha(GLuint c) {
} }
/*!\brief au moment de quitter le programme désallouer la mémoire /*!\brief Désalloue la mémoire au moment de quitter le programme
* utilisée pour _depth */ * utilisée pour _depth */
void pquit(void) { void pquit(void) {
if(_depth) { if(_depth) {

View file

@ -5,7 +5,7 @@
* *
* \author Farès BELHADJ, amsi@up8.edu * \author Farès BELHADJ, amsi@up8.edu
* \date November 17, 2021. * \date November 17, 2021.
*/ */
#ifndef RASTERIZE_H_SEEN #ifndef RASTERIZE_H_SEEN
# define RASTERIZE_H_SEEN # define RASTERIZE_H_SEEN
@ -29,13 +29,13 @@ typedef struct vertex_t vertex_t;
typedef struct triangle_t triangle_t; typedef struct triangle_t triangle_t;
typedef struct surface_t surface_t; typedef struct surface_t surface_t;
/*!\brief états pour les sommets ou les triangles */ /*!\brief États pour les sommets ou les triangles */
enum pstate_t { enum pstate_t {
PS_NONE = 0, PS_NONE = 0,
PS_TOTALLY_OUT = 1, PS_TOTALLY_OUT = 1,
PS_PARTIALLY_OUT = 2, PS_PARTIALLY_OUT = 2,
PS_CULL = 4, /* si en BACKFACE et que PS_CULL = 4, /* si en BACKFACE et que
SO_CULL_BACKFACES est actif */ * SO_CULL_BACKFACES est actif */
PS_TOO_FAR = 8, PS_TOO_FAR = 8,
PS_OUT_LEFT = 16, PS_OUT_LEFT = 16,
PS_OUT_RIGHT = 32, PS_OUT_RIGHT = 32,
@ -45,30 +45,30 @@ enum pstate_t {
PS_OUT_FAR = 512 PS_OUT_FAR = 512
}; };
/*!\brief options pour les surfaces */ /*!\brief Options pour les surfaces */
enum soptions_t { enum soptions_t {
SO_NONE = 0, /* la surface n'a pas de rendu SO_NONE = 0, /* la surface n'a pas de rendu
"couleur" */ * "couleur" */
SO_USE_TEXTURE = 1, /* utiliser la texture pour SO_USE_TEXTURE = 1, /* utiliser la texture pour
colorer (multiplication si * colorer (multiplication si
SO_USE_COLOR est actif) */ * SO_USE_COLOR est actif) */
SO_USE_COLOR = 2, /* utiliser la couleur de la SO_USE_COLOR = 2, /* utiliser la couleur de la
surface ou des sommets pour * surface ou des sommets pour
colorer (multiplication si * colorer (multiplication si
SO_USE_TEXTURE est actif) */ * SO_USE_TEXTURE est actif) */
SO_COLOR_MATERIAL = 4, /* utiliser la couleur aux SO_COLOR_MATERIAL = 4, /* utiliser la couleur aux
sommets si actif * sommets si actif
(nécessite aussi * (nécessite aussi
l'activation de * l'activation de
SO_USE_COLOR) */ * SO_USE_COLOR) */
SO_CULL_BACKFACES = 8, /* active le fait de cacher SO_CULL_BACKFACES = 8, /* active le fait de cacher
les faces arrières */ * les faces arrières */
SO_USE_LIGHTING = 16, /* active le calcul d'ombre SO_USE_LIGHTING = 16, /* active le calcul d'ombre
propre (Gouraud sur * propre (Gouraud sur
diffus) */ * diffus) */
SO_DEFAULT = SO_CULL_BACKFACES | SO_USE_COLOR /* comportement SO_DEFAULT = SO_CULL_BACKFACES | SO_USE_COLOR /* comportement
par * par
défaut */ * défaut */
}; };
struct vec4 { struct vec4 {
@ -83,7 +83,7 @@ struct vec3 {
float x /* r */, y/* g */, z/* b */; float x /* r */, y/* g */, z/* b */;
}; };
/*!\brief le sommet et l'ensemble de ses attributs */ /*!\brief Sommet et l'ensemble de ses attributs */
struct vertex_t { struct vertex_t {
vec4 position; vec4 position;
vec4 color0; vec4 color0;
@ -92,8 +92,8 @@ struct vertex_t {
vec4 icolor; /* couleur à interpoler */ vec4 icolor; /* couleur à interpoler */
float li; /* intensité de lumière (lambertien) */ float li; /* intensité de lumière (lambertien) */
float zmod; /* z après modelview, sert à corriger float zmod; /* z après modelview, sert à corriger
l'interpolation par rapport à une projection en * l'interpolation par rapport à une projection en
perspective */ * perspective */
float z; /* ce z représente la depth */ float z; /* ce z représente la depth */
/* fin des données à partir desquelles on peut interpoler */ /* fin des données à partir desquelles on peut interpoler */
vec3 normal; /* interpolez les normales si vous implémentez Phong */ vec3 normal; /* interpolez les normales si vous implémentez Phong */
@ -101,35 +101,34 @@ struct vertex_t {
enum pstate_t state; enum pstate_t state;
}; };
/*!\brief le triangle */ /*!\brief Triangle */
struct triangle_t { struct triangle_t {
vertex_t v[3]; vertex_t v[3];
vec3 normal; vec3 normal;
enum pstate_t state; enum pstate_t state;
}; };
/*!\brief la surface englobe plusieurs triangles et des options /*!\brief Surface englobe plusieurs triangles et des options
* telles que le type de rendu, la couleur diffuse ou la texture. * telles que le type de rendu, la couleur diffuse ou la texture. */
*/
struct surface_t { struct surface_t {
int n; int n;
triangle_t * t; triangle_t * t;
GLuint tex_id; GLuint tex_id;
vec4 dcolor; /* couleur diffuse, ajoutez une couleur ambiante et vec4 dcolor; /* couleur diffuse, ajoutez une couleur ambiante et
spéculaire si vous souhaitez compléter le * spéculaire si vous souhaitez compléter le
modèle */ * modèle */
soptions_t options; /* paramétrage du rendu de la surface */ soptions_t options; /* paramétrage du rendu de la surface */
void (*interpolatefunc)(vertex_t *, vertex_t *, vertex_t *, float, float); void (*interpolatefunc)(vertex_t *, vertex_t *, vertex_t *, float, float);
void (*shadingfunc)(surface_t *, GLuint *, vertex_t *); void (*shadingfunc)(surface_t *, GLuint *, vertex_t *);
}; };
/* dans rasterize.c */ /* Dans rasterize.c */
extern void transform_n_rasterize(surface_t * s, float * model_view_matrix, float * projection_matrix); extern void transform_n_rasterize(surface_t * s, float * model_view_matrix, float * projection_matrix);
extern void clear_depth_map(void); extern void clear_depth_map(void);
extern void set_texture(GLuint screen); extern void set_texture(GLuint screen);
extern void updatesfuncs(surface_t * s); extern void updatesfuncs(surface_t * s);
/* dans vtranform.c */ /* Dans vtranform.c */
extern vertex_t vtransform(surface_t * s, vertex_t v, float * model_view_matrix, float * ti_model_view_matrix, float * projection_matrix, float * viewport); extern vertex_t vtransform(surface_t * s, vertex_t v, float * model_view_matrix, float * ti_model_view_matrix, float * projection_matrix, float * viewport);
extern void stransform(surface_t * s, float * model_view_matrix, float * projection_matrix, float * viewport); extern void stransform(surface_t * s, float * model_view_matrix, float * projection_matrix, float * viewport);
extern void mult_matrix(float * res, float * m); extern void mult_matrix(float * res, float * m);
@ -138,7 +137,7 @@ extern void rotate(float * m, float angle, float x, float y, float z);
extern void scale(float * m, float sx, float sy, float sz); extern void scale(float * m, float sx, float sy, float sz);
extern void lookAt(float * m, float eyeX, float eyeY, float eyeZ, float centerX, float centerY, float centerZ, float upX, float upY, float upZ); extern void lookAt(float * m, float eyeX, float eyeY, float eyeZ, float centerX, float centerY, float centerZ, float upX, float upY, float upZ);
/* dans surface.c */ /* Dans surface.c */
extern void tnormal(triangle_t * t); extern void tnormal(triangle_t * t);
extern void snormals(surface_t * s); extern void snormals(surface_t * s);
extern void tnormals2vertices(surface_t * s); extern void tnormals2vertices(surface_t * s);
@ -150,7 +149,7 @@ extern surface_t * new_surface(triangle_t * t, int n, int duplicateTriangles, in
extern void free_surface(surface_t * s); extern void free_surface(surface_t * s);
extern GLuint get_texture_from_BMP(const char * filename); extern GLuint get_texture_from_BMP(const char * filename);
/* dans geometry.c */ /* Dans geometry.c */
extern surface_t * mk_quad(void); extern surface_t * mk_quad(void);
extern surface_t * mk_cube(void); extern surface_t * mk_cube(void);
extern surface_t * mk_sphere(int longitudes, int latitudes); extern surface_t * mk_sphere(int longitudes, int latitudes);

View file

@ -5,69 +5,69 @@
* *
* \author Farès BELHADJ, amsi@up8.edu * \author Farès BELHADJ, amsi@up8.edu
* \date November 17, 2021. * \date November 17, 2021.
*/ */
#include "rasterize.h" #include "rasterize.h"
#include <assert.h> #include <assert.h>
/*!\brief calcule le vecteur normal à un triangle */ /*!\brief Calcule le vecteur normal à un triangle */
void tnormal(triangle_t * t) { void tnormal(triangle_t * t) {
vec3 u = { vec3 u = {
t->v[1].position.x - t->v[0].position.x, t->v[1].position.x - t->v[0].position.x,
t->v[1].position.y - t->v[0].position.y, t->v[1].position.y - t->v[0].position.y,
t->v[1].position.z - t->v[0].position.z t->v[1].position.z - t->v[0].position.z
}; };
vec3 v = { vec3 v = {
t->v[2].position.x - t->v[0].position.x, t->v[2].position.x - t->v[0].position.x,
t->v[2].position.y - t->v[0].position.y, t->v[2].position.y - t->v[0].position.y,
t->v[2].position.z - t->v[0].position.z t->v[2].position.z - t->v[0].position.z
}; };
MVEC3CROSS((float *)&(t->normal), (float *)&u, (float *)&v); MVEC3CROSS((float *)&(t->normal), (float *)&u, (float *)&v);
MVEC3NORMALIZE((float *)&(t->normal)); MVEC3NORMALIZE((float *)&(t->normal));
} }
/*!\brief calcule les vecteurs normaux aux triangles de la surface */ /*!\brief Calcule les vecteurs normaux aux triangles de la surface */
void snormals(surface_t * s) { void snormals(surface_t * s) {
int i; int i;
for(i = 0; i < s->n; ++i) for(i = 0; i < s->n; ++i)
tnormal(&(s->t[i])); tnormal(&(s->t[i]));
} }
/*!\brief affecte les normales aux triangles de la surface à ses vertices */ /*!\brief Affecte les normales aux triangles de la surface à ses vertices */
void tnormals2vertices(surface_t * s) { void tnormals2vertices(surface_t * s) {
int i; int i;
for(i = 0; i < s->n; ++i) for(i = 0; i < s->n; ++i)
s->t[i].v[0].normal = s->t[i].v[1].normal = s->t[i].v[2].normal = s->t[i].normal; s->t[i].v[0].normal = s->t[i].v[1].normal = s->t[i].v[2].normal = s->t[i].normal;
} }
/*!\brief affecte l'identifiant de texture de la surface */ /*!\brief Affecte l'identifiant de texture de la surface */
void set_texture_id(surface_t * s, GLuint tex_id) { void set_texture_id(surface_t * s, GLuint tex_id) {
s->tex_id = tex_id; s->tex_id = tex_id;
} }
/*!\brief affecte la couleur diffuse de la surface */ /*!\brief Affecte la couleur diffuse de la surface */
void set_diffuse_color(surface_t * s, vec4 dcolor) { void set_diffuse_color(surface_t * s, vec4 dcolor) {
s->dcolor = dcolor; s->dcolor = dcolor;
} }
/*!\brief active une option de la surface */ /*!\brief Active une option de la surface */
void enable_surface_option(surface_t * s, soptions_t option) { void enable_surface_option(surface_t * s, soptions_t option) {
if(!(s->options & option)) if(!(s->options & option))
s->options |= option; s->options |= option;
updatesfuncs(s); updatesfuncs(s);
} }
/*!\brief désactive une option de la surface */ /*!\brief Désactive une option de la surface */
void disable_surface_option(surface_t * s, soptions_t option) { void disable_surface_option(surface_t * s, soptions_t option) {
if(s->options & option) if(s->options & option)
s->options ^= option; s->options ^= option;
updatesfuncs(s); updatesfuncs(s);
} }
/*!\brief créé et renvoie une surface (allouée) à partir de \a n /*!\brief Créé et renvoie une surface (allouée) à partir de \a n
* triangles pointés par \a t. Quand \a duplicateTriangles est vrai * triangles pointés par \a t. Quand \a duplicateTriangles est vrai
* (1), elle alloue de la mémoire pour copier les triangles dedans, * (1), elle alloue de la mémoire pour copier les triangles dedans,
* sinon ( si faux (0) ) elle se contente de copier le pointeur * sinon (si faux [=0]) elle se contente de copier le pointeur
* (attention ce dernier doit donc correspondre à une mémoire allouée * (attention ce dernier doit donc correspondre à une mémoire allouée
* avec malloc et dont le développeur ne s'en servira pas pour autre * avec malloc et dont le développeur ne s'en servira pas pour autre
* chose ; elle sera libérée par freeSurface). Quand \a hasNormals est * chose ; elle sera libérée par freeSurface). Quand \a hasNormals est
@ -95,12 +95,12 @@ surface_t * new_surface(triangle_t * t, int n, int duplicate_triangles, int has_
return s; return s;
} }
/*!\brief libère la mémoire utilisée par la surface */ /*!\brief Libère la mémoire utilisée par la surface */
void free_surface(surface_t * s) { void free_surface(surface_t * s) {
free(s->t); free(s->t);
free(s); free(s);
} }
/*!\brief charge et fabrique un identifiant pour une texture issue /*!\brief Charge et fabrique un identifiant pour une texture issue
* d'un fichier BMP */ * d'un fichier BMP */
GLuint get_texture_from_BMP(const char * filename) { GLuint get_texture_from_BMP(const char * filename) {
GLuint id, old_id; GLuint id, old_id;

View file

@ -13,10 +13,10 @@
#include "rasterize.h" #include "rasterize.h"
#include <assert.h> #include <assert.h>
/* fonctions locale (static) */ /* Fonctions locale (static) */
static inline void clip2_unit_cube(triangle_t * t); static inline void clip2_unit_cube(triangle_t * t);
/*!\brief projette le sommet \a v à l'écran (le \a viewport) selon la /*!\brief Projette le sommet \a v à l'écran (le \a viewport) selon la
matrice de model-view \a model_view_matrix et de projection \a projection_matrix. \a matrice de model-view \a model_view_matrix et de projection \a projection_matrix. \a
ti_model_view_matrix est la transposée de l'inverse de la matrice \a model_view_matrix.*/ ti_model_view_matrix est la transposée de l'inverse de la matrice \a model_view_matrix.*/
vertex_t vtransform(surface_t * s, vertex_t v, float * model_view_matrix, float * ti_model_view_matrix, float * projection_matrix, float * viewport) { vertex_t vtransform(surface_t * s, vertex_t v, float * model_view_matrix, float * ti_model_view_matrix, float * projection_matrix, float * viewport) {
@ -37,13 +37,13 @@ vertex_t vtransform(surface_t * s, vertex_t v, float * model_view_matrix, float
if(r2.z < -dist) v.state |= PS_OUT_NEAR; if(r2.z < -dist) v.state |= PS_OUT_NEAR;
if(r2.z > dist) v.state |= PS_OUT_FAR; if(r2.z > dist) v.state |= PS_OUT_FAR;
/* "hack" pas terrible permettant d'éviter les gros triangles /* "hack" pas terrible permettant d'éviter les gros triangles
partiellement hors-champ. Modifier dist pour jouer sur la taille * partiellement hors-champ. Modifier dist pour jouer sur la taille
(une fois projetés) des triangles qu'on laisse passer (plus c'est * (une fois projetés) des triangles qu'on laisse passer (plus c'est
gros plus c'est lent avec les gros triangles). La "vraie" * gros plus c'est lent avec les gros triangles). La "vraie"
solution est obtenue en calculant l'intersection exacte entre le * solution est obtenue en calculant l'intersection exacte entre le
triangle et le cube unitaire ; attention, ceci produit * triangle et le cube unitaire ; attention, ceci produit
potentiellement une nouvelle liste de triangles à chaque frame, * potentiellement une nouvelle liste de triangles à chaque frame,
et les attributs des sommets doivent être recalculés. */ * et les attributs des sommets doivent être recalculés. */
dist = 10.0f; dist = 10.0f;
if(r2.x < -dist || r2.x > dist || r2.y < -dist || r2.y > dist || r2.z < -dist || r2.z > dist) { if(r2.x < -dist || r2.x > dist || r2.y < -dist || r2.y > dist || r2.z < -dist || r2.z > dist) {
v.state |= PS_TOO_FAR; v.state |= PS_TOO_FAR;
@ -52,8 +52,8 @@ vertex_t vtransform(surface_t * s, vertex_t v, float * model_view_matrix, float
/* Gouraud */ /* Gouraud */
if(s->options & SO_USE_LIGHTING) { if(s->options & SO_USE_LIGHTING) {
/* la lumière est positionnelle et fixe dans la scène. \todo dans /* la lumière est positionnelle et fixe dans la scène. \todo dans
scene.c la rendre modifiable, voire aussi pouvoir la placer par * scene.c la rendre modifiable, voire aussi pouvoir la placer par
rapport aux objets (elle subirait la matrice modèle). */ * rapport aux objets (elle subirait la matrice modèle). */
const vec4 lp[1] = { {0.0f, 0.0f, 1.0f} }; const vec4 lp[1] = { {0.0f, 0.0f, 1.0f} };
vec4 ld = {lp[0].x - r1.x, lp[0].y - r1.y, lp[0].z - r1.z, lp[0].w - r1.w}; vec4 ld = {lp[0].x - r1.x, lp[0].y - r1.y, lp[0].z - r1.z, lp[0].w - r1.w};
float n[4] = {v.normal.x, v.normal.y, v.normal.z, 0.0f}, res[4]; float n[4] = {v.normal.x, v.normal.y, v.normal.z, 0.0f}, res[4];
@ -75,7 +75,7 @@ vertex_t vtransform(surface_t * s, vertex_t v, float * model_view_matrix, float
return v; return v;
} }
/*!\brief projette le triangle \a t à l'écran (\a W x \a H) selon la /*!\brief Projette le triangle \a t à l'écran (\a W x \a H) selon la
* matrice de model-view \a model_view_matrix et de projection \a projection_matrix. * matrice de model-view \a model_view_matrix et de projection \a projection_matrix.
* *
* Cette fonction utilise \a vtransform sur chaque sommet de la * Cette fonction utilise \a vtransform sur chaque sommet de la
@ -83,15 +83,14 @@ vertex_t vtransform(surface_t * s, vertex_t v, float * model_view_matrix, float
* du triangle par rapport au cube unitaire. * du triangle par rapport au cube unitaire.
* *
* \see vtransform * \see vtransform
* \see clip2_unit_cube * \see clip2_unit_cube */
*/
void stransform(surface_t * s, float * model_view_matrix, float * projection_matrix, float * viewport) { void stransform(surface_t * s, float * model_view_matrix, float * projection_matrix, float * viewport) {
int i, j; int i, j;
float ti_model_view_matrix[16]; float ti_model_view_matrix[16];
triangle_t vcull; triangle_t vcull;
/* calcul de la transposée de l'inverse de la matrice model-view /* calcul de la transposée de l'inverse de la matrice model-view
pour la transformation des normales et le calcul du lambertien * pour la transformation des normales et le calcul du lambertien
utilisé par le shading Gouraud dans vtransform. */ * utilisé par le shading Gouraud dans vtransform. */
memcpy(ti_model_view_matrix, model_view_matrix, sizeof ti_model_view_matrix); memcpy(ti_model_view_matrix, model_view_matrix, sizeof ti_model_view_matrix);
MMAT4INVERSE(ti_model_view_matrix); MMAT4INVERSE(ti_model_view_matrix);
MMAT4TRANSPOSE(ti_model_view_matrix); MMAT4TRANSPOSE(ti_model_view_matrix);
@ -116,7 +115,7 @@ void stransform(surface_t * s, float * model_view_matrix, float * projection_mat
} }
} }
/*!\brief multiplie deux matrices : \a res = \a res x \a m */ /*!\brief Multiplie deux matrices : \a res = \a res x \a m */
void mult_matrix(float * res, float * m) { void mult_matrix(float * res, float * m) {
/* res = res x m */ /* res = res x m */
float cpy[16]; float cpy[16];
@ -124,7 +123,7 @@ void mult_matrix(float * res, float * m) {
MMAT4XMAT4(res, cpy, m); MMAT4XMAT4(res, cpy, m);
} }
/*!\brief ajoute (multiplication droite) une translation à la matrice /*!\brief Ajoute (multiplication droite) une translation à la matrice
* \a m */ * \a m */
void translate(float * m, float tx, float ty, float tz) { void translate(float * m, float tx, float ty, float tz) {
float mat[] = { 1.0f, 0.0f, 0.0f, tx, float mat[] = { 1.0f, 0.0f, 0.0f, tx,
@ -134,7 +133,7 @@ void translate(float * m, float tx, float ty, float tz) {
mult_matrix(m, mat); mult_matrix(m, mat);
} }
/*!\brief ajoute (multiplication droite) une rotation à la matrice \a /*!\brief Ajoute (multiplication droite) une rotation à la matrice \a
* m */ * m */
void rotate(float * m, float angle, float x, float y, float z) { void rotate(float * m, float angle, float x, float y, float z) {
float n = sqrtf(x * x + y * y + z * z); float n = sqrtf(x * x + y * y + z * z);
@ -167,7 +166,7 @@ void rotate(float * m, float angle, float x, float y, float z) {
} }
} }
/*!\brief ajoute (multiplication droite) un scale à la matrice \a m */ /*!\brief Ajoute (multiplication droite) un scale à la matrice \a m */
void scale(float * m, float sx, float sy, float sz) { void scale(float * m, float sx, float sy, float sz) {
float mat[] = { sx , 0.0f, 0.0f, 0.0f, float mat[] = { sx , 0.0f, 0.0f, 0.0f,
0.0f, sy, 0.0f, 0.0f, 0.0f, sy, 0.0f, 0.0f,
@ -176,7 +175,7 @@ void scale(float * m, float sx, float sy, float sz) {
mult_matrix(m, mat); mult_matrix(m, mat);
} }
/*!\brief simule une free camera, voir la doc de gluLookAt */ /*!\brief Simule une free-camera, voir la doc de gluLookAt */
void lookAt(float * m, float eyeX, float eyeY, float eyeZ, float centerX, float centerY, float centerZ, float upX, float upY, float upZ) { void lookAt(float * m, float eyeX, float eyeY, float eyeZ, float centerX, float centerY, float centerZ, float upX, float upY, float upZ) {
float forward[3], side[3], up[3]; float forward[3], side[3], up[3];
float mat[] = { float mat[] = {
@ -210,7 +209,7 @@ void lookAt(float * m, float eyeX, float eyeY, float eyeZ, float centerX, float
translate(m, -eyeX, -eyeY, -eyeZ); translate(m, -eyeX, -eyeY, -eyeZ);
} }
/*!\brief intersection triangle-cube unitaire, à compléter (voir le /*!\brief Intersection triangle-cube unitaire, à compléter (voir le
* todo du fichier et le commentaire dans le code) */ * todo du fichier et le commentaire dans le code) */
void clip2_unit_cube(triangle_t * t) { void clip2_unit_cube(triangle_t * t) {
int i, oleft = 0, oright = 0, obottom = 0, otop = 0, onear = 0, ofar = 0; int i, oleft = 0, oright = 0, obottom = 0, otop = 0, onear = 0, ofar = 0;
@ -230,14 +229,13 @@ void clip2_unit_cube(triangle_t * t) {
} }
t->state |= PS_PARTIALLY_OUT; t->state |= PS_PARTIALLY_OUT;
/* le cas PARTIALLY_OUT n'est pas réellement géré. Il serait /* le cas PARTIALLY_OUT n'est pas réellement géré. Il serait
nécessaire à partir d'ici de construire la liste des triangles * nécessaire à partir d'ici de construire la liste des triangles
qui repésentent l'intersection entre le triangle d'origine et * qui repésentent l'intersection entre le triangle d'origine et
le cube unitaire. Ceci permettrait de ne plus avoir besoin de * le cube unitaire. Ceci permettrait de ne plus avoir besoin de
tester si le pixel produit par le raster est bien dans le * tester si le pixel produit par le raster est bien dans le
"screen" avant d'écrire ; et aussi de se passer du "hack" * "screen" avant d'écrire ; et aussi de se passer du "hack"
PS_TOO_FAR qui est problématique. Vous pouvez vous inspirer de * PS_TOO_FAR qui est problématique. Vous pouvez vous inspirer de
ce qui est fait : * ce qui est fait :
https://github.com/erich666/GraphicsGems/blob/master/gems/PolyScan/poly_clip.c * https://github.com/erich666/GraphicsGems/blob/master/gems/PolyScan/poly_clip.c
en le ramenant au cas d'un triangle. * en le ramenant au cas d'un triangle. */
*/
} }