gKit2 light
Loading...
Searching...
No Matches
tuto_cubemap.cpp
Go to the documentation of this file.
1
3
4#include <memory>
5#include <random>
6#include <chrono>
7
8#include "wavefront.h"
9#include "texture.h"
10
11#include "orbiter.h"
12#include "program.h"
13#include "uniforms.h"
14#include "draw.h"
15
16#include "app_camera.h" // classe Application a deriver
17
18
19// creation d'une grille + axes du repere
20Mesh make_grid( const int n= 10 )
21{
22 Mesh grid= Mesh(GL_LINES);
23
24 // grille
25 grid.color(White());
26 float w= float(n-1) / 2;
27 for(int x= 0; x < n; x++)
28 {
29 grid.vertex(x -w, 0, -w);
30 grid.vertex(x -w, 0, w);
31 }
32 for(int z= 0; z < n; z++)
33 {
34 grid.vertex(-w, 0, z -w);
35 grid.vertex( w, 0, z -w);
36 }
37
38 // axes XYZ
39 grid.color(Red());
40 grid.vertex(Point(0, .1, 0));
41 grid.vertex(Point(1, .1, 0));
42
43 grid.color(Green());
44 grid.vertex(Point(0, .1, 0));
45 grid.vertex(Point(0, 1, 0));
46
47 grid.color(Blue());
48 grid.vertex(Point(0, .1, 0));
49 grid.vertex(Point(0, .1, 1));
50
51 glLineWidth(2);
52
53 return grid;
54}
55
57GLuint read_cubemap( const int unit, const char *filename, const GLenum texel_type = GL_RGBA )
58{
59 ImageData image= read_image_data(filename);
60 if(image.pixels.empty())
61 return 0;
62
63 // les 6 faces sur une colonne
64 //~ int w= image.width;
65 //~ int h= image.height / 6;
66 // les 6 faces sur une croix
67 int w= image.width / 4;
68 int h= image.height / 3;
69 assert(w == h);
70
71 GLenum data_format;
72 GLenum data_type= GL_UNSIGNED_BYTE;
73 if(image.channels == 3)
74 data_format= GL_RGB;
75 else // par defaut
76 data_format= GL_RGBA;
77
78 // creer la texture
79 GLuint texture= 0;
80 glGenTextures(1, &texture);
81 glActiveTexture(GL_TEXTURE0 + unit);
82 glBindTexture(GL_TEXTURE_CUBE_MAP, texture);
83
84 // creer les 6 faces
85 // chaque face de la cubemap est un rectangle [image.width/4 x image.height/3] dans l'image originale
86 struct { int x, y; } faces[]= {
87 {0, 1}, // X+
88 {2, 1}, // X-
89 {1, 2}, // Y+
90 {1, 0}, // Y-
91 {1, 1}, // Z+
92 {3, 1}, // Z-
93 };
94 //~ struct { int x, y; } faces[]= {
95 //~ {0, 4}, // Z+
96 //~ {0, 5}, // Z-
97 //~ {0, 3}, // Y-
98 //~ {0, 2}, // Y+
99 //~ {0, 0}, // X+
100 //~ {0, 1}, // X-
101 //~ };
102
103 // face de test / rouge
104 ImageData red(w, h, image.channels);
105 for(unsigned y= 0; y < red.height; y++)
106 for(unsigned x= 0; x < red.width; x++)
107 {
108 unsigned char *pixel= red.pixels.data() + red.offset(x, y);
109 pixel[0]= 255;
110 pixel[1]= 0;
111 pixel[2]= 0;
112 if(red.channels > 3)
113 pixel[3]= 255;
114 }
115
116 for(int i= 0; i < 6; i++)
117 {
118 ImageData face= flipX(flipY(copy(image, faces[i].x*w, faces[i].y*h, w, h)));
119
120 //~ if(i == 5) // remplace par la face test...
121 //~ face= red;
122
123 glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X +i, 0,
124 texel_type, w, h, 0,
125 data_format, data_type, face.data());
126 }
127
128 // parametres de filtrage
129 glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
130 glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
131 glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
132 glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
133 glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
134
135 glGenerateMipmap(GL_TEXTURE_CUBE_MAP);
136
137 // filtrage "correct" sur les bords du cube...
138 glEnable(GL_TEXTURE_CUBE_MAP_SEAMLESS);
139 //~ glDisable(GL_TEXTURE_CUBE_MAP_SEAMLESS);
140
141 printf(" cubemap faces %dx%d\n", w, h);
142
143 return texture;
144}
145
146
147GLuint make_cubemap( const unsigned unit, const std::vector<Image>& faces, GLenum texel_type= GL_RGBA )
148{
149 if(faces.empty())
150 return 0;
151
152 for(unsigned i= 1; i < faces.size(); i++)
153 if( faces[i].width() != faces[0].width()
154 || faces[i].height() != faces[0].height() )
155 return 0;
156
157 // creer la texture
158 GLuint texture= 0;
159 glGenTextures(1, &texture);
160 glActiveTexture(GL_TEXTURE0 + unit);
161 glBindTexture(GL_TEXTURE_CUBE_MAP, texture);
162
163 Image red( faces[0].width(), faces[0].height(), Red() );
164
165 // cree les 6 faces
166 for(unsigned i= 0; i < 6; i++)
167 {
168 //~ if(i == 5) // remplace par la face test...
169 //~ face= red;
170
171 glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X +i, 0,
172 texel_type, faces[i].width(), faces[i].height(), 0,
173 GL_RGBA, GL_FLOAT, faces[i].data());
174 }
175
176 // parametres de filtrage
177 glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
178 glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
179 glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
180 glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
181 glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
182
183 glGenerateMipmap(GL_TEXTURE_CUBE_MAP);
184
185 // filtrage "correct" sur les bords du cube...
186 glEnable(GL_TEXTURE_CUBE_MAP_SEAMLESS);
187 //~ glDisable(GL_TEXTURE_CUBE_MAP_SEAMLESS);
188
189 printf(" cubemap faces %dx%d\n", faces[0].width(), faces[0].height());
190 return texture;
191}
192
193std::vector<Image> read_envmap( const char *filename )
194{
195 Image image= linear( read_image( filename ) );
196 if(image.size() == 0)
197 return {};
198
199 int w= image.width() / 4;
200 int h= image.height() / 3;
201 assert(w == h);
202
203 // creer les 6 faces
204 // chaque face de la cubemap est un rectangle [image.width/4 x image.height/3] dans l'image originale
205 struct { int x, y; } cells[]= {
206 {0, 1}, // X+
207 {2, 1}, // X-
208 {1, 2}, // Y+
209 {1, 0}, // Y-
210 {1, 1}, // Z+
211 {3, 1}, // Z-
212 };
213
214 std::vector<Image> faces;
215 for(int i= 0; i < 6; i++)
216 faces.emplace_back( flipX(flipY(copy(image, cells[i].x*w, cells[i].y*h, w, h))) );
217
218 return faces;
219}
220
221// mapping direction vers texel [0 .. 1]x[0 .. 1]
222// reproduit la convention openGL.
223vec3 envmap_texel( const Vector& d )
224{
225 int face= -1;
226 float sm, tm;
227
228 const vec3 m= { std::abs(d.x), std::abs(d.y), std::abs(d.z) };
229 if(m.x > m.y && m.x > m.z)
230 {
231 // X
232 if(d.x > 0)
233 {
234 face= 0;
235 sm= -d.z / m.x;
236 tm= -d.y / m.x;
237 }
238 else
239 {
240 face= 1;
241 sm= d.z / m.x;
242 tm= -d.y / m.x;
243 }
244 }
245 else if(m.y > m.z)
246 {
247 // Y
248 if(d.y > 0)
249 {
250 face= 2;
251 sm= d.x / m.y;
252 tm= d.z / m.y;
253 }
254 else
255 {
256 face= 3;
257 sm= d.x / m.y;
258 tm= -d.z / m.y;
259 }
260 }
261 else
262 {
263 // Z
264 if(d.z > 0)
265 {
266 face= 4;
267 sm= d.x / m.z;
268 tm= -d.y / m.z;
269 }
270 else
271 {
272 face= 5;
273 sm= -d.x / m.z;
274 tm= -d.y / m.z;
275 }
276 }
277
278 assert(face != -1);
279 float s= (sm +1) / 2;
280 float t= (tm +1) / 2;
281 return { face, s, t };
282}
283
284vec3 envmap_direction( const int face, const float s, const float t )
285{
286 // retrouve le point sur le cube [-1 .. 1]
287 float sm= 2 * s -1;
288 float tm= 2 * t -1;
289 if(face == 0)
290 {
291 // X+
292 // sm= -d.z / m.x;
293 // tm= -d.y / m.x;
294 return { 1, -tm, -sm };
295 }
296 else if(face == 1)
297 {
298 // X-
299 // sm= d.z / m.x;
300 // tm= -d.y / m.x;
301 return { -1, -tm, sm };
302 }
303 else if(face == 2)
304 {
305 // Y+
306 // sm= d.x / m.y;
307 // tm= d.z / m.y;
308 return { sm, 1, tm };
309 }
310 else if(face == 3)
311 {
312 // Y-
313 // sm= d.x / m.y;
314 // tm= -d.z / m.y;
315 return { sm, -1, -tm };
316 }
317 else if(face == 4)
318 {
319 // Z+
320 // sm= d.x / m.z;
321 // tm= -d.y / m.z;
322 return { sm, -tm, 1 };
323 }
324 else // if(face == 5)
325 {
326 // Z-
327 // sm= -d.x / m.z;
328 // tm= -d.y / m.z;
329 return { -sm, -tm, -1 };
330 }
331}
332
333struct World
334{
335 World( ) : t(), b(), n() {}
336
337 World( const Vector& _n ) : n(_n)
338 {
339 float s= std::copysign(float(1), n.z); // s= 1 ou -1
340 float a= -1 / (s + n.z);
341 float d= n.x * n.y * a;
342 t= Vector(1 + s * n.x * n.x * a, s * d, -s * n.x);
343 b= Vector(d, s + n.y * n.y * a, -n.y);
344 }
345
346 // transforme le vecteur du repere local vers le repere du monde
347 Vector operator( ) ( const Vector& local ) const { return local.x * t + local.y * b + local.z * n; }
348
349 // transforme le vecteur du repere du monde vers le repere local
350 Vector local( const Vector& global ) const { return Vector(dot(global, t), dot(global, b), dot(global, n)); }
351
352 Vector t; // x
353 Vector b; // y
354 Vector n; // z
355};
356
357float frsplit( const Vector& v, const float ns )
358{
359 // n= Z
360 // o= Z
361 assert(v.z >= 0);
362
363 Vector h= normalize( Vector(0, 0, 1) + v );
364 return (8 + ns) / float(8*M_PI) * std::pow( std::max(float(0), h.z), ns );
365}
366
367
369{
370 GLuint diffuse_texture;
371 GLuint glossy_texture;
372};
373
374splitsum splitsum_cubemap( const int unit, const char *filename, const GLenum texel_type = GL_RGBA )
375{
376 std::vector<Image> faces= read_envmap(filename);
377 if(faces.size() == 0)
378 return {};
379
380 const unsigned size= 16;
381 const unsigned samples= 4096;
382 std::vector<Image> diffuse;
383 for(unsigned i= 0; i < 6; i++)
384 diffuse.emplace_back( size, size, Black() );
385
386 unsigned size0= std::max( faces[0].width(), faces[0].height() );
387 unsigned levels= miplevels( faces[0].width(), faces[0].height() );
388 std::vector< std::vector<Image> > glossy(6);
389 for(unsigned i= 0; i < 6; i++)
390 {
391 for(unsigned k= 0; k < levels; k++)
392 {
393 unsigned ksize= std::max(unsigned(1), size0 >> k);
394 glossy[i].emplace_back( ksize, ksize, Black() );
395 }
396 }
397 printf("\n");
398
399 std::chrono::high_resolution_clock::time_point start= std::chrono::high_resolution_clock::now();
400
401 for(unsigned face= 0; face < diffuse.size(); face++)
402 {
403 #pragma omp parallel for schedule(dynamic, 1)
404 for(unsigned y= 0; y < size; y++)
405 {
406 std::random_device hwseed;
407 std::default_random_engine rng( hwseed() );
408 std::uniform_real_distribution<float> uniform;
409
410 for(unsigned x= 0; x < size; x++)
411 {
412 Vector n= envmap_direction( face, float(x) / float(size), float(y) / float(size) );
413 World world( n );
414
415 // diffuse
416 Color color;
417 for(unsigned i= 0; i < samples; i++)
418 {
419 float cos_theta= std::sqrt( uniform( rng ) );
420 float sin_theta= std::sqrt(1 - cos_theta * cos_theta);
421 float phi= uniform( rng ) * float(2 * M_PI);
422 float pdf= cos_theta / float(M_PI);
423
424 Vector v= world( { std::cos(phi) * sin_theta, std::sin(phi) * sin_theta, cos_theta} );
425
426 vec3 fuv= envmap_texel(v);
427 color= color + faces[fuv.x].texture(fuv.y, fuv.z) / float(M_PI) * cos_theta / pdf;
428 }
429
430 diffuse[face](x, y)= Color(color / float(samples), 1);
431 }
432 }
433 }
434
435 std::chrono::high_resolution_clock::time_point stop= std::chrono::high_resolution_clock::now();
436 printf("splitsum %dms\n", int( std::chrono::duration_cast<std::chrono::milliseconds>(stop - start).count() ));
437
438 // glossy
439 for(unsigned face= 0; face < glossy.size(); face++)
440 {
441 unsigned ksamples= 256;
442 unsigned ksize= 256;
443 //~ unsigned ksize= std::max( glossy[face][0].width(), glossy[face][0].height() );
444 glossy[face][0]= Image(ksize, ksize);
445
446 #pragma omp parallel for schedule(dynamic, 1)
447 for(unsigned y= 0; y < ksize; y++)
448 {
449 std::random_device hwseed;
450 std::default_random_engine rng( hwseed() );
451 std::uniform_real_distribution<float> uniform;
452
453 for(unsigned x= 0; x < ksize; x++)
454 {
455 Vector n= envmap_direction( face, float(x) / float(ksize), float(y) / float(ksize) );
456 World world( n );
457
458 float ns= 100;
459
460 Color color;
461 for(unsigned i= 0; i < ksamples; i++)
462 {
463 // repere local, n= 0 0 1 et o= 0 0 1
464 float cos_theta_h= std::min( float(1), std::pow( uniform( rng ), float(1) / float(ns+1) ) );
465 float sin_theta_h= std::sqrt( 1 - cos_theta_h * cos_theta_h );
466 float phi_h= uniform( rng ) * float(2 * M_PI);
467
468 Vector h= { std::cos(phi_h) * sin_theta_h, std::sin(phi_h) * sin_theta_h, cos_theta_h };
469 Vector v= 2*h.z * h - Vector(0, 0, 1); // reflect(o, h)
470 float pdf_h= float(ns +1) / float(2 * M_PI) * std::pow(cos_theta_h, ns);
471 float pdf= float(1) / float(4 * h.z) * pdf_h;
472
473 float cos_theta= v.z;
474 if(cos_theta > 0)
475 {
476 vec3 fuv= envmap_texel( world(v) );
477 color= color + faces[fuv.x].texture(fuv.y, fuv.z) * frsplit(v, ns) * cos_theta / pdf;
478 }
479 }
480
481 glossy[face][0](x, y)= Color(color / float(samples), 1);
482
483 if(face == 0 && y == 0)
484 printf("%u %f\n", x, color.max() / float(samples));
485 }
486 }
487 }
488
489 std::chrono::high_resolution_clock::time_point stop2= std::chrono::high_resolution_clock::now();
490 printf("splitsum %dms\n", int( std::chrono::duration_cast<std::chrono::milliseconds>(stop2 - stop).count() ));
491
492 std::vector<Image> tmp_glossy;
493 for(unsigned i= 0; i < glossy.size(); i++)
494 tmp_glossy.emplace_back( glossy[i][0] );
495
496 Image band(tmp_glossy[0].width(), tmp_glossy[0].width()*6);
497 for(unsigned i= 0; i < 6; i++)
498 blit(band, 0, i * tmp_glossy[0].width(), tmp_glossy[i]);
499 //~ Image band(diffuse[0].width(), diffuse[0].width()*6);
500 //~ for(unsigned i= 0; i < 6; i++)
501 //~ blit(band, 0, i * diffuse[0].width(), diffuse[i]);
502
503 write_image(band, "env.png");
504
505 return { make_cubemap(0, diffuse), make_cubemap(0, tmp_glossy) };
506}
507
508
509class TP : public AppCamera
510{
511public:
512 // constructeur : donner les dimensions de l'image, et eventuellement la version d'openGL.
513 TP( ) : AppCamera(1024, 640) {}
514
515 // creation des objets de l'application
516 int init( )
517 {
518 //~ m_objet= read_mesh("data/cube.obj");
519 //~ m_objet= read_mesh("data/bigguy.obj");
520 m_objet= read_mesh("data/ccbigguy.obj");
521 //~ m_objet= make_grid(3);
522 if(m_objet.vertex_count() == 0)
523 return -1;
524
525 //~ m_texture= read_cubemap(0, "gkit2_tutos/cubemap_debug_cross.png");
526 splitsum textures= splitsum_cubemap(0, "canyon2.jpg");
527 //~ m_texture= textures.diffuse_texture;
528 m_texture= textures.glossy_texture;
529 if(m_texture == 0)
530 return -1;
531
532 //~ m_texture= read_cubemap(0, "canyon2.jpg");
533 //~ m_texture= read_cubemap(0, "faces.png");
534 //~ m_texture= read_cubemap(0, "studio.png");
535 //~ m_texture= read_texture(0, "studio_latlong.png");
536 //~ m_texture= read_texture(0, "latlong.png");
537
538 m_program_draw= read_program("gkit2_tutos/draw_cubemap.glsl");
539 program_print_errors(m_program_draw);
540 m_program= read_program("gkit2_tutos/cubemap.glsl");
541 program_print_errors(m_program);
542
543 // init camera
544 Point pmin, pmax;
545 m_objet.bounds(pmin, pmax);
546 camera().lookat(pmin, pmax);
547
548 // etat openGL par defaut
549 glGenVertexArrays(1, &m_vao);
550
551 glEnable(GL_FRAMEBUFFER_SRGB);
552 glClearColor(0.1, 0.1, 0.1, 1); // couleur par defaut de la fenetre
553
554 glClearDepth(1); // profondeur par defaut
555 glDepthFunc(GL_LEQUAL); // ztest, conserver l'intersection la plus proche de la camera
556 glEnable(GL_DEPTH_TEST); // activer le ztest
557
558 return 0; // ras, pas d'erreur
559 }
560
561 // destruction des objets de l'application
562 int quit( )
563 {
564 m_objet.release();
565 release_program(m_program_draw);
566 release_program(m_program);
567 glDeleteVertexArrays(1, &m_vao);
568 glDeleteTextures(1, &m_texture);
569 return 0;
570 }
571
572 // dessiner une nouvelle image
573 int render( )
574 {
575 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
576
577 static Transform model= Identity();
578 if(key_state(SDLK_LEFT))
579 model= model * RotationY(-2);
580 if(key_state(SDLK_RIGHT))
581 model= model * RotationY(2);
582
583 Transform view= camera().view();
584 Transform projection= camera().projection();
585 Transform viewport= camera().viewport();
586 Transform mvp= projection * view * model;
587
588 Transform viewInv= Inverse(view);
589 Point camera_position= viewInv(Point(0, 0, 0)); // coordonnees de la camera, dans le repere camera... c'est l'origine
590
591 // etape 1 : affiche l'objet, utilise la cubemap pour calculer les reflets
592 glUseProgram(m_program);
593 program_uniform(m_program, "mvpMatrix", mvp);
594 program_uniform(m_program, "modelMatrix", model);
595 program_uniform(m_program, "camera_position", camera_position);
596
597 glActiveTexture(GL_TEXTURE0);
598 glBindTexture(GL_TEXTURE_CUBE_MAP, m_texture);
599
600 //~ glBindTexture(GL_TEXTURE_2D, m_texture);
601 program_uniform(m_program, "texture0", 0);
602
603 // dessine l'objet.
604 m_objet.draw(m_program);
605
606 // etape 2 : affiche la cube map
607 // inverse de la composition des transformations repere monde vers repere image
608 Transform inv= Inverse(viewport * projection * view);
609
610 glUseProgram(m_program_draw);
611 glBindVertexArray(m_vao);
612 program_uniform(m_program_draw, "invMatrix", inv);
613 program_uniform(m_program_draw, "camera_position", camera_position);
614
615 glBindTexture(GL_TEXTURE_CUBE_MAP, m_texture);
616 //~ glBindTexture(GL_TEXTURE_2D, m_texture);
617 program_uniform(m_program_draw, "texture0", int(0));
618
619 glDrawArrays(GL_TRIANGLES, 0, 3);
620
621 // nettoyage
622 glBindTexture(GL_TEXTURE_2D, 0);
623 glBindTexture(GL_TEXTURE_CUBE_MAP, 0);
624 glUseProgram(0);
625 glBindVertexArray(0);
626
627 if(key_state('r'))
628 {
629 clear_key_state('r');
630
631 reload_program(m_program_draw, "gkit2_tutos/draw_cubemap.glsl");
632 program_print_errors(m_program_draw);
633 reload_program(m_program, "gkit2_tutos/cubemap.glsl");
634 program_print_errors(m_program);
635 }
636
637 if(key_state('s'))
638 {
639 clear_key_state('s');
640 static int calls= 0;
641 screenshot("cubemap_brdf", ++calls);
642 printf("screenshot %d\n", calls);
643 }
644
645 return 1;
646 }
647
648protected:
649 Mesh m_objet;
650 GLuint m_texture;
651 GLuint m_program_draw;
652 GLuint m_program;
653 GLuint m_vao;
654};
655
656
657int main( int argc, char **argv )
658{
659 // il ne reste plus qu'a creer un objet application et la lancer
660 TP tp;
661 tp.run();
662
663 return 0;
664}
classe application.
Definition app_camera.h:19
const Orbiter & camera() const
renvoie l'orbiter gere par l'application.
Definition app_camera.h:37
AppCamera(const int width, const int height, const int major=3, const int minor=3)
constructeur, dimensions de la fenetre et version d'openGL.
Definition app_camera.cpp:5
int run()
execution de l'application.
Definition app.cpp:36
representation d'une image.
Definition image.h:21
representation d'un objet / maillage.
Definition mesh.h:121
unsigned int vertex(const vec3 &p)
insere un sommet de position p, et ses attributs (s'ils sont definis par color(), texcoord(),...
Definition mesh.cpp:97
Mesh & color(const vec4 &c)
definit la couleur du prochain sommet.
Definition mesh.cpp:66
void lookat(const Point &center, const float size)
observe le point center a une distance size.
Definition orbiter.cpp:7
Transform viewport() const
renvoie la transformation viewport actuelle. doit etre initialise par projection(width,...
Definition orbiter.cpp:84
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...
Definition orbiter.cpp:48
Transform view() const
renvoie la transformation vue.
Definition orbiter.cpp:41
Definition alpha.cpp:58
int render()
a deriver pour afficher les objets. renvoie 1 pour continuer, 0 pour fermer l'application.
int quit()
a deriver pour detruire les objets openGL. renvoie -1 pour indiquer une erreur, 0 sinon.
int init()
a deriver pour creer les objets openGL. renvoie -1 pour indiquer une erreur, 0 sinon.
void clear_key_state(const SDL_Keycode key)
desactive une touche du clavier.
Definition window.cpp:59
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().
Definition text.cpp:140
int key_state(const SDL_Keycode key)
renvoie l'etat d'une touche du clavier. cf la doc SDL2 pour les codes.
Definition window.cpp:53
Color Red()
utilitaire. renvoie une couleur rouge.
Definition color.cpp:28
Color Blue()
utilitaire. renvoie une couleur bleue.
Definition color.cpp:38
Color Black()
utilitaire. renvoie une couleur noire.
Definition color.cpp:18
Image & blit(Image &image, const unsigned xmin, const unsigned ymin, const Image &pixels)
remplace un bout d'image par une autre. copie l'image pixels dans image [xmin, xmin+pixels....
Definition image_io.cpp:162
Image flipY(const Image &image)
retourne l'image
Definition image_io.cpp:113
Image flipX(const Image &image)
retourne l'image
Definition image_io.cpp:130
Image read_image(const char *filename, const bool flipY)
Definition image_io.cpp:191
Color Green()
utilitaire. renvoie une couleur verte.
Definition color.cpp:33
Color White()
utilitaire. renvoie une couleur blanche.
Definition color.cpp:23
ImageData read_image_data(const void *buffer, const unsigned size, const bool flipY)
charge les donnees d'un fichier png stocke en memoire. renvoie une image initialisee par defaut en ca...
Definition image_io.cpp:335
bool write_image(const Image &image, const char *filename, const bool flipY)
enregistre une image au format .png
Definition image_io.cpp:245
Image copy(const Image &image, const unsigned xmin, const unsigned ymin, const unsigned width, const unsigned height)
renvoie un bloc de l'image
Definition image_io.cpp:146
int miplevels(const int width, const int height)
renvoie le nombre de mipmap d'une image width x height.
Definition image_io.cpp:537
Transform Inverse(const Transform &m)
renvoie l'inverse de la matrice.
Definition mat.cpp:197
Transform Identity()
construit la transformation identite.
Definition mat.cpp:187
Transform RotationY(const float a)
renvoie la matrice representation une rotation de a degree autour de l'axe Y.
Definition mat.cpp:242
float dot(const Vector &u, const Vector &v)
renvoie le produit scalaire de 2 vecteurs.
Definition vec.cpp:181
Vector normalize(const Vector &v)
renvoie un vecteur unitaire / longueur == 1.
Definition vec.cpp:167
Mesh read_mesh(const char *filename)
charge un fichier wavefront .obj et renvoie un mesh compose de triangles non indexes....
Definition wavefront.cpp:14
int screenshot(const char *filename)
enregistre le contenu de la fenetre dans un fichier. doit etre de type .png / .bmp
Definition texture.cpp:178
GLuint read_program(const char *filename, const char *definitions)
Definition program.cpp:217
int program_print_errors(const GLuint program, const char *filename)
affiche les erreurs de compilation.
Definition program.cpp:461
int release_program(const GLuint program)
detruit les shaders et le program.
Definition program.cpp:240
representation d'une couleur (rgba) transparente ou opaque.
Definition color.h:14
stockage temporaire des donnees d'une image.
Definition image_io.h:55
representation d'un point 3d.
Definition vec.h:21
representation d'une transformation, une matrice 4x4, organisee par ligne / row major.
Definition mat.h:21
representation d'un vecteur 3d.
Definition vec.h:67
vecteur generique, utilitaire.
Definition vec.h:169
GLuint read_cubemap(const int unit, const char *filename, const GLenum texel_type=GL_RGBA)
charge une image, decoupe les 6 faces et renvoie une texture cubemap.