25 #define EPSILON 0.00001f
34 Ray(
const Point origine,
const Point extremite ) : o(origine), d(
Vector(origine, extremite)), tmax(1) {}
35 Ray(
const Point origine,
const Vector direction ) : o(origine), d(direction), tmax(FLT_MAX) {}
37 Point operator( ) (
const float t )
const {
return o + t * d; }
47 Hit( ) : p(), n(), t(FLT_MAX), u(0), v(0), object_id(-1) {}
63 bool intersect(
const Ray &ray,
const float htmax,
float &rt,
float &ru,
float&rv )
const
71 float det=
dot(ab, pvec);
72 if(det > -EPSILON && det < EPSILON)
75 float inv_det= 1.0f / det;
81 float u=
dot(tvec, pvec) * inv_det;
82 if(u < 0.0f || u > 1.0f)
89 float v=
dot(ray.d, qvec) * inv_det;
90 if(v < 0.0f || u + v > 1.0f)
94 rt=
dot(ac, qvec) * inv_det;
99 return (rt < htmax && rt > EPSILON);
106 float w= 1.f - u - v;
114 float w= 1.f - u - v;
137 if(n.z < -0.9999999f)
144 float a= 1.f / (1.f + n.z);
145 float d= -n.x * n.y * a;
146 t=
Vector(1.f - n.x * n.x * a, d, -n.x);
147 b=
Vector(d, 1.f - n.y * n.y * a, -n.y);
153 return local.x * t + local.y * b + local.z * n;
162 GLuint
make_texture(
const int unit,
const int width,
const int height )
165 glGenTextures(1, &texture);
166 glActiveTexture(GL_TEXTURE0 + unit);
167 glBindTexture(GL_TEXTURE_2D, texture);
169 glTexImage2D(GL_TEXTURE_2D, 0,
170 GL_RGB32F, width, height, 0,
171 GL_RGBA, GL_FLOAT, NULL);
174 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0);
175 glGenerateMipmap(GL_TEXTURE_2D);
183 IS(
const char *filename ) :
App(1024, 640)
195 m_mesh.
bounds(pmin, pmax);
196 m_camera.
lookat(pmin, pmax);
213 glGenVertexArrays(1, &m_vao);
214 glBindVertexArray(m_vao);
220 glClearColor(0.2f, 0.2f, 0.2f, 1.f);
223 glDepthFunc(GL_LESS);
224 glEnable(GL_DEPTH_TEST);
231 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
236 reload_program(m_program,
"tutos/M2/is.glsl");
244 m_mesh.
bounds(pmin, pmax);
245 m_camera.
lookat(pmin, pmax);
250 unsigned int mb= SDL_GetRelativeMouseState(&mx, &my);
251 if(mb & SDL_BUTTON(1))
253 else if(mb & SDL_BUTTON(3))
255 else if(mb & SDL_BUTTON(2))
270 SDL_GetMouseState(&mx, &my);
273 printf(
"pixel %f %f\n", pixel.x, pixel.y);
278 m_camera.
frame(0, d0, dx0, dy0);
282 m_camera.
frame(1, d1, dx1, dy1);
285 Point o= d0 + pixel.x*dx0 + pixel.y*dy0;
286 Point e= d1 + pixel.x*dx1 + pixel.y*dy1;
293 if(intersect(ray, hit))
299 #pragma omp parallel for schedule(dynamic, 16)
300 for(
int y= 0; y < m_hitp.
height(); y++)
301 for(
int x= 0; x < m_hitp.
width(); x++)
304 m_hitp(x, y)=
Black();
305 m_hitn(x, y)=
Black();
306 m_hitv(x, y)=
Black();
308 Point o= d0 + x*dx0 + y*dy0;
309 Point e= d1 + x*dx1 + y*dy1;
313 if(intersect(ray, hit))
315 m_hitp(x, y)=
Color(hit.p.x, hit.p.y, hit.p.z);
316 m_hitn(x, y)=
Color(hit.n.x, hit.n.y, hit.n.z);
318 Ray shadow(hit.p + hit.n * 0.001f, point + normal * 0.001f);
321 if(intersect(shadow, shadow_hit))
324 m_hitv(x, y)=
Color(v, v, v);
329 glActiveTexture(GL_TEXTURE0);
330 glBindTexture(GL_TEXTURE_2D, m_ptexture);
331 glTexSubImage2D(GL_TEXTURE_2D, 0,
333 GL_RGBA, GL_FLOAT, m_hitp.
data());
335 glActiveTexture(GL_TEXTURE0 +1);
336 glBindTexture(GL_TEXTURE_2D, m_ntexture);
337 glTexSubImage2D(GL_TEXTURE_2D, 0,
339 GL_RGBA, GL_FLOAT, m_hitn.
data());
341 glActiveTexture(GL_TEXTURE0 +2);
342 glBindTexture(GL_TEXTURE_2D, m_vtexture);
343 glTexSubImage2D(GL_TEXTURE_2D, 0,
345 GL_RGBA, GL_FLOAT, m_hitv.
data());
352 glBindVertexArray(m_vao);
353 glUseProgram(m_program);
361 glActiveTexture(GL_TEXTURE0);
362 glBindTexture(GL_TEXTURE_2D, m_ptexture);
363 glActiveTexture(GL_TEXTURE0 +1);
364 glBindTexture(GL_TEXTURE_2D, m_ntexture);
365 glActiveTexture(GL_TEXTURE0 +2);
366 glBindTexture(GL_TEXTURE_2D, m_vtexture);
368 glDrawArrays(GL_TRIANGLES, 0, 3);
372 draw(m_mesh, m_camera);
381 sprintf(tmp,
"screenshot%02d.png", n++);
382 printf(
"writing %s...\n", tmp);
409 printf(
"%d sources.\n", (
int) m_sources.size());
410 return (
int) m_sources.size();
413 bool direct(
const Ray& ray )
415 for(
size_t i= 0; i < m_sources.size(); i++)
418 if(m_sources[i].intersect(ray, ray.tmax, t, u, v))
427 int build_triangles( )
432 printf(
"%d triangles.\n", (
int) m_triangles.size());
433 return (
int) m_triangles.size();
438 bool intersect(
const Ray& ray,
Hit& hit )
441 for(
size_t i= 0; i < m_triangles.size(); i++)
444 if(m_triangles[i].intersect(ray, hit.t, t, u, v))
451 hit.n= m_triangles[i].normal(u, v);
457 return (hit.object_id != -1);
464 std::vector<Triangle> m_triangles;
465 std::vector<Source> m_sources;
480 int main(
int argc,
char **argv )
482 const char *filename=
"cornell.obj";
App(const int width, const int height, const int major=3, const int minor=3, const int samples=0)
constructeur, dimensions de la fenetre et version d'openGL.
representation d'une image.
int height() const
renvoie la hauteur de l'image.
const void * data() const
renvoie un pointeur sur le stockage des couleurs des pixels.
int width() const
renvoie la largeur de l'image.
representation d'un objet / maillage.
void bounds(Point &pmin, Point &pmax) const
renvoie min et max les coordonnees des extremites des positions des sommets de l'objet (boite engloba...
Mesh & triangle(const unsigned int a, const unsigned int b, const unsigned int c)
int triangle_count() const
renvoie le nombre de triangles.
const Material & triangle_material(const unsigned int id) const
renvoie la matiere d'un triangle.
void release()
detruit les objets openGL.
representation de la camera, type orbiter, placee sur une sphere autour du centre de l'objet.
void lookat(const Point ¢er, const float size)
observe le point center a une distance size.
void frame(const float z, Point &dO, Vector &dx, Vector &dy) const
int read_orbiter(const char *filename)
relit la position de l'orbiter depuis un fichier texte.
void move(const float z)
rapproche / eloigne la camera du centre.
Transform projection(const int width, const int height, const float fov)
fixe la projection reglee pour une image d'aspect width / height, et une demi ouverture de fov degres...
void translation(const float x, const float y)
deplace le centre / le point observe.
void rotation(const float x, const float y)
change le point de vue / la direction d'observation.
int window_height()
renvoie la hauteur de la fenetre de l'application.
void clear_key_state(const SDL_Keycode key)
desactive une touche du clavier.
void printf(Text &text, const int px, const int py, const char *format,...)
affiche un texte a la position x, y. meme utilisation que printf().
int key_state(const SDL_Keycode key)
renvoie l'etat d'une touche du clavier. cf la doc SDL2 pour les codes.
int window_width()
renvoie la largeur de la fenetre de l'application.
Color Black()
utilitaire. renvoie une couleur noire.
float dot(const Vector &u, const Vector &v)
renvoie le produit scalaire de 2 vecteurs.
Vector cross(const Vector &u, const Vector &v)
renvoie le produit vectoriel de 2 vecteurs.
Mesh read_mesh(const char *filename)
charge un fichier wavefront .obj et renvoie un mesh compose de triangles non indexes....
GLuint make_texture(const int unit, const int width, const int height, const GLenum texel_type, const GLenum data_format, const GLenum data_type)
creation de textures filtrables / mipmaps
int screenshot(const char *filename)
enregistre le contenu de la fenetre dans un fichier. doit etre de type .png / .bmp
GLuint read_program(const char *filename, const char *definitions)
void program_uniform(const GLuint program, const char *uniform, const std::vector< unsigned > &v)
affecte un tableau de valeurs a un uniform du shader program.
int program_print_errors(const GLuint program)
affiche les erreurs de compilation.
representation d'une couleur (rgba) transparente ou opaque.
intersection avec un triangle.
int render()
a deriver pour afficher les objets. renvoie 1 pour continuer, 0 pour fermer l'application.
int init()
a deriver pour creer les objets openGL. renvoie -1 pour indiquer une erreur, 0 sinon.
int quit()
a deriver pour detruire les objets openGL. renvoie -1 pour indiquer une erreur, 0 sinon.
Color emission
pour une source de lumiere.
representation d'un point 3d.
representation d'un triangle.
triangle pour le bvh, cf fonction bounds() et intersect().
Point point(const float u, const float v) const
Vector normal(const float u, const float v) const
representation d'un vecteur 3d.
vecteur generique, utilitaire.