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
* \date November, 2021.
*/
*/
#include "rasterize.h"
#include <assert.h>
#if defined(_MSC_VER)
@ -13,7 +13,7 @@
#endif
#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
* la largeur du cube unitaire (-1 à 1).*/
surface_t * mk_quad(void) {
@ -44,7 +44,7 @@ surface_t * mk_quad(void) {
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).*/
surface_t * mk_cube(void) {
const float
@ -100,7 +100,7 @@ surface_t * mk_cube(void) {
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
* longitudes et \a latitudes 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.y = (theta + M_PI_2) / M_PI;
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.y = data[k].position.y;
data[k].normal.z = data[k].position.z;

View file

@ -13,7 +13,7 @@
#include "rasterize.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 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);
@ -35,22 +35,22 @@ static inline GLubyte blue(GLuint c);
static inline GLubyte alpha(GLuint c);
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;
/*!\brief la largeur de la texture courante à utiliser en cas de
/*!\brief Largeur de la texture courante à utiliser en cas de
* mapping de texture */
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 */
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;
/*!\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
* perspective */
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. */
void transform_n_rasterize(surface_t * s, float * model_view_matrix, float * projection_matrix) {
int i;
@ -61,7 +61,7 @@ void transform_n_rasterize(surface_t * s, float * model_view_matrix, float * pro
atexit(pquit);
}
/* 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;
/* le viewport est fixe ; \todo peut devenir paramétrable ... */
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 */
if(s->t[i].state & PS_TOTALLY_OUT) continue;
/* "hack" pas terrible permettant de rejeter les triangles
* partiellement out dont au moins un sommet est TOO_FAR (trop
* éloigné). Voir le fichier transformations.c pour voir comment
* améliorer ce traitement. */
* partiellement out dont au moins un sommet est TOO_FAR (trop
* éloigné). Voir le fichier transformations.c pour voir comment
* améliorer ce traitement. */
if( s->t[i].state & PS_PARTIALLY_OUT &&
( (s->t[i].v[0].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 */
void clear_depth_map(void) {
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) {
GLuint old_id = gl4dpGetTextureId(); /* au cas où */
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 */
void updatesfuncs(surface_t * s) {
int t;
@ -121,10 +121,9 @@ void updatesfuncs(surface_t * s) {
}
}
/*!\brief fonction principale de ce fichier, elle dessine un triangle
* rempli à l'écran en calculant l'ensemble des gradients
* (interpolations bilinaires des attributs du sommet).
*/
/*!\brief Dessine un triangle et le rempli en calculant l'ensemble
* des gradients avec interpolations bilinaires des attributs du sommet
* (fonction principale de ce fichier) */
inline void fill_triangle(surface_t * s, triangle_t * t) {
vertex_t * aG = NULL, * aD = NULL;
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);
}
/*!\brief utilise Br'65 pour determiner les abscisses des segments du
* triangle à remplir (par \a horizontal_line).
*/
/*!\brief Utilise Br'65 pour determiner les abscisses des segments du
* triangle à remplir (par \a horizontal_line). */
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;
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) {
int w = gl4dpGetWidth(), x, yw = vG->y * w;
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;
}
}
/*!\brief aucune couleur n'est inscrite */
/*!\brief Aucune couleur n'est inscrite */
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) {
int xt, yt, ct;
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);
}
/*!\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) {
GLubyte r, g, b, a;
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);
}
/*!\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 */
inline void shading_only_color(surface_t * s, GLuint * pcolor, vertex_t * v) {
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);
}
/*!\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 */
inline void shading_all_CM(surface_t * s, GLuint * pcolor, vertex_t * v) {
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);
}
/*!\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 */
inline void shading_all(surface_t * s, GLuint * pcolor, vertex_t * v) {
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);
}
/*!\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
* facteurs \a fa et \a fb, le tout dans \a r
* \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 * pa = (float *)&(a->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
* 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
@ -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];
}
/*!\brief meta-fonction pour appeler \a interpolate, demande
/*!\brief Meta-fonction pour appeler \a interpolate, demande
* uniquement l'interpolation des z */
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);
}
/*!\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 */
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, 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 */
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);
}
/*!\brief meta-fonction pour appeler \a interpolate, demande
/*!\brief Meta-fonction pour appeler \a interpolate, demande
* l'interpolation de l'ensemble des attributs */
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);
@ -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 */
void pquit(void) {
if(_depth) {

View file

@ -5,7 +5,7 @@
*
* \author Farès BELHADJ, amsi@up8.edu
* \date November 17, 2021.
*/
*/
#ifndef 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 surface_t surface_t;
/*!\brief états pour les sommets ou les triangles */
/*!\brief États pour les sommets ou les triangles */
enum pstate_t {
PS_NONE = 0,
PS_TOTALLY_OUT = 1,
PS_PARTIALLY_OUT = 2,
PS_CULL = 4, /* si en BACKFACE et que
SO_CULL_BACKFACES est actif */
* SO_CULL_BACKFACES est actif */
PS_TOO_FAR = 8,
PS_OUT_LEFT = 16,
PS_OUT_RIGHT = 32,
@ -45,30 +45,30 @@ enum pstate_t {
PS_OUT_FAR = 512
};
/*!\brief options pour les surfaces */
/*!\brief Options pour les surfaces */
enum soptions_t {
SO_NONE = 0, /* la surface n'a pas de rendu
"couleur" */
* "couleur" */
SO_USE_TEXTURE = 1, /* utiliser la texture pour
colorer (multiplication si
SO_USE_COLOR est actif) */
* colorer (multiplication si
* SO_USE_COLOR est actif) */
SO_USE_COLOR = 2, /* utiliser la couleur de la
surface ou des sommets pour
colorer (multiplication si
SO_USE_TEXTURE est actif) */
* surface ou des sommets pour
* colorer (multiplication si
* SO_USE_TEXTURE est actif) */
SO_COLOR_MATERIAL = 4, /* utiliser la couleur aux
sommets si actif
(nécessite aussi
l'activation de
SO_USE_COLOR) */
* sommets si actif
* (nécessite aussi
* l'activation de
* SO_USE_COLOR) */
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
propre (Gouraud sur
diffus) */
* propre (Gouraud sur
* diffus) */
SO_DEFAULT = SO_CULL_BACKFACES | SO_USE_COLOR /* comportement
par
défaut */
* par
* défaut */
};
struct vec4 {
@ -83,7 +83,7 @@ struct vec3 {
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 {
vec4 position;
vec4 color0;
@ -92,8 +92,8 @@ struct vertex_t {
vec4 icolor; /* couleur à interpoler */
float li; /* intensité de lumière (lambertien) */
float zmod; /* z après modelview, sert à corriger
l'interpolation par rapport à une projection en
perspective */
* l'interpolation par rapport à une projection en
* perspective */
float z; /* ce z représente la depth */
/* fin des données à partir desquelles on peut interpoler */
vec3 normal; /* interpolez les normales si vous implémentez Phong */
@ -101,35 +101,34 @@ struct vertex_t {
enum pstate_t state;
};
/*!\brief le triangle */
/*!\brief Triangle */
struct triangle_t {
vertex_t v[3];
vec3 normal;
enum pstate_t state;
};
/*!\brief la surface englobe plusieurs triangles et des options
* telles que le type de rendu, la couleur diffuse ou la texture.
*/
/*!\brief Surface englobe plusieurs triangles et des options
* telles que le type de rendu, la couleur diffuse ou la texture. */
struct surface_t {
int n;
triangle_t * t;
GLuint tex_id;
vec4 dcolor; /* couleur diffuse, ajoutez une couleur ambiante et
spéculaire si vous souhaitez compléter le
modèle */
* spéculaire si vous souhaitez compléter le
* modèle */
soptions_t options; /* paramétrage du rendu de la surface */
void (*interpolatefunc)(vertex_t *, vertex_t *, vertex_t *, float, float);
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 clear_depth_map(void);
extern void set_texture(GLuint screen);
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 void stransform(surface_t * s, float * model_view_matrix, float * projection_matrix, float * viewport);
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 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 snormals(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 GLuint get_texture_from_BMP(const char * filename);
/* dans geometry.c */
/* Dans geometry.c */
extern surface_t * mk_quad(void);
extern surface_t * mk_cube(void);
extern surface_t * mk_sphere(int longitudes, int latitudes);

View file

@ -5,69 +5,69 @@
*
* \author Farès BELHADJ, amsi@up8.edu
* \date November 17, 2021.
*/
*/
#include "rasterize.h"
#include <assert.h>
/*!\brief calcule le vecteur normal à un triangle */
/*!\brief Calcule le vecteur normal à un triangle */
void tnormal(triangle_t * t) {
vec3 u = {
vec3 u = {
t->v[1].position.x - t->v[0].position.x,
t->v[1].position.y - t->v[0].position.y,
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.y - t->v[0].position.y,
t->v[2].position.z - t->v[0].position.z
};
MVEC3CROSS((float *)&(t->normal), (float *)&u, (float *)&v);
MVEC3NORMALIZE((float *)&(t->normal));
};
MVEC3CROSS((float *)&(t->normal), (float *)&u, (float *)&v);
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) {
int i;
for(i = 0; i < s->n; ++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) {
int 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;
}
/*!\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) {
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) {
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) {
if(!(s->options & option))
s->options |= option;
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) {
if(s->options & option)
s->options ^= option;
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
* (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
* 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
@ -95,12 +95,12 @@ surface_t * new_surface(triangle_t * t, int n, int duplicate_triangles, int has_
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) {
free(s->t);
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 */
GLuint get_texture_from_BMP(const char * filename) {
GLuint id, old_id;

View file

@ -13,10 +13,10 @@
#include "rasterize.h"
#include <assert.h>
/* fonctions locale (static) */
/* Fonctions locale (static) */
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
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) {
@ -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_FAR;
/* "hack" pas terrible permettant d'éviter les gros triangles
partiellement hors-champ. Modifier dist pour jouer sur la taille
(une fois projetés) des triangles qu'on laisse passer (plus c'est
gros plus c'est lent avec les gros triangles). La "vraie"
solution est obtenue en calculant l'intersection exacte entre le
triangle et le cube unitaire ; attention, ceci produit
potentiellement une nouvelle liste de triangles à chaque frame,
et les attributs des sommets doivent être recalculés. */
* partiellement hors-champ. Modifier dist pour jouer sur la taille
* (une fois projetés) des triangles qu'on laisse passer (plus c'est
* gros plus c'est lent avec les gros triangles). La "vraie"
* solution est obtenue en calculant l'intersection exacte entre le
* triangle et le cube unitaire ; attention, ceci produit
* potentiellement une nouvelle liste de triangles à chaque frame,
* et les attributs des sommets doivent être recalculés. */
dist = 10.0f;
if(r2.x < -dist || r2.x > dist || r2.y < -dist || r2.y > dist || r2.z < -dist || r2.z > dist) {
v.state |= PS_TOO_FAR;
@ -52,8 +52,8 @@ vertex_t vtransform(surface_t * s, vertex_t v, float * model_view_matrix, float
/* Gouraud */
if(s->options & SO_USE_LIGHTING) {
/* la lumière est positionnelle et fixe dans la scène. \todo dans
scene.c la rendre modifiable, voire aussi pouvoir la placer par
rapport aux objets (elle subirait la matrice modèle). */
* scene.c la rendre modifiable, voire aussi pouvoir la placer par
* rapport aux objets (elle subirait la matrice modèle). */
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};
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;
}
/*!\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.
*
* 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.
*
* \see vtransform
* \see clip2_unit_cube
*/
* \see clip2_unit_cube */
void stransform(surface_t * s, float * model_view_matrix, float * projection_matrix, float * viewport) {
int i, j;
float ti_model_view_matrix[16];
triangle_t vcull;
/* calcul de la transposée de l'inverse de la matrice model-view
pour la transformation des normales et le calcul du lambertien
utilisé par le shading Gouraud dans vtransform. */
* pour la transformation des normales et le calcul du lambertien
* utilisé par le shading Gouraud dans vtransform. */
memcpy(ti_model_view_matrix, model_view_matrix, sizeof ti_model_view_matrix);
MMAT4INVERSE(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) {
/* res = res x m */
float cpy[16];
@ -124,7 +123,7 @@ void mult_matrix(float * res, float * m) {
MMAT4XMAT4(res, cpy, m);
}
/*!\brief ajoute (multiplication droite) une translation à la matrice
/*!\brief Ajoute (multiplication droite) une translation à la matrice
* \a m */
void translate(float * m, float tx, float ty, float tz) {
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);
}
/*!\brief ajoute (multiplication droite) une rotation à la matrice \a
/*!\brief Ajoute (multiplication droite) une rotation à la matrice \a
* m */
void rotate(float * m, float angle, float x, float y, float 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) {
float mat[] = { sx , 0.0f, 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);
}
/*!\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) {
float forward[3], side[3], up[3];
float mat[] = {
@ -210,7 +209,7 @@ void lookAt(float * m, float eyeX, float eyeY, float eyeZ, float centerX, float
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) */
void clip2_unit_cube(triangle_t * t) {
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;
/* le cas PARTIALLY_OUT n'est pas réellement géré. Il serait
nécessaire à partir d'ici de construire la liste des triangles
qui repésentent l'intersection entre le triangle d'origine et
le cube unitaire. Ceci permettrait de ne plus avoir besoin de
tester si le pixel produit par le raster est bien dans le
"screen" avant d'écrire ; et aussi de se passer du "hack"
PS_TOO_FAR qui est problématique. Vous pouvez vous inspirer de
ce qui est fait :
https://github.com/erich666/GraphicsGems/blob/master/gems/PolyScan/poly_clip.c
en le ramenant au cas d'un triangle.
*/
* nécessaire à partir d'ici de construire la liste des triangles
* qui repésentent l'intersection entre le triangle d'origine et
* le cube unitaire. Ceci permettrait de ne plus avoir besoin de
* tester si le pixel produit par le raster est bien dans le
* "screen" avant d'écrire ; et aussi de se passer du "hack"
* PS_TOO_FAR qui est problématique. Vous pouvez vous inspirer de
* ce qui est fait :
* https://github.com/erich666/GraphicsGems/blob/master/gems/PolyScan/poly_clip.c
* en le ramenant au cas d'un triangle. */
}