gKit2 light
tuto_cubemap.cpp
Go to the documentation of this file.
1 
3 
4 #include <memory>
5 
6 #include "wavefront.h"
7 #include "texture.h"
8 
9 #include "orbiter.h"
10 #include "program.h"
11 #include "uniforms.h"
12 #include "draw.h"
13 
14 #include "app_camera.h" // classe Application a deriver
15 
17 GLuint read_cubemap( const int unit, const char *filename, const GLenum texel_type = GL_RGBA )
18 {
19  // les 6 faces sur une croix
20  ImageData image= read_image_data(filename);
21  if(image.pixels.empty())
22  return 0;
23 
24  int w= image.width / 4;
25  int h= image.height / 3;
26  assert(w == h);
27 
28  GLenum data_format;
29  GLenum data_type= GL_UNSIGNED_BYTE;
30  if(image.channels == 3)
31  data_format= GL_RGB;
32  else // par defaut
33  data_format= GL_RGBA;
34 
35  // creer la texture
36  GLuint texture= 0;
37  glGenTextures(1, &texture);
38  glActiveTexture(GL_TEXTURE0 + unit);
39  glBindTexture(GL_TEXTURE_CUBE_MAP, texture);
40 
41  // creer les 6 faces
42  // chaque face de la cubemap est un rectangle [image.width/4 x image.height/3] dans l'image originale
43  struct { int x, y; } faces[]= {
44  {0, 1}, // X+
45  {2, 1}, // X-
46  {1, 2}, // Y+
47  {1, 0}, // Y-
48  {1, 1}, // Z+
49  {3, 1}, // Z-
50  };
51 
52  for(int i= 0; i < 6; i++)
53  {
54  ImageData face= flipX(flipY(copy(image, faces[i].x*w, faces[i].y*h, w, h)));
55 
56  glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X +i, 0,
57  texel_type, w, h, 0,
58  data_format, data_type, face.data());
59  }
60 
61  // parametres de filtrage
62  glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
63  glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
64  glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
65  glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
66  glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
67 
68  glGenerateMipmap(GL_TEXTURE_CUBE_MAP);
69 
70  // filtrage "correct" sur les bords du cube...
71  glEnable(GL_TEXTURE_CUBE_MAP_SEAMLESS);
72  //~ glDisable(GL_TEXTURE_CUBE_MAP_SEAMLESS);
73 
74  printf(" cubemap faces %dx%d\n", w, h);
75 
76  return texture;
77 }
78 
79 class TP : public AppCamera
80 {
81 public:
82  // constructeur : donner les dimensions de l'image, et eventuellement la version d'openGL.
83  TP( ) : AppCamera(1024, 640) {}
84 
85  // creation des objets de l'application
86  int init( )
87  {
88  //~ m_objet= read_mesh("data/cube.obj");
89  m_objet= read_mesh("data/bigguy.obj");
90  // m_objet= read_mesh("data/ccbigguy.obj");
91 
92  m_texture= read_cubemap(0, "tutos/cubemap_debug_cross.png");
93  // m_texture= read_cubemap(0, "canyon2.jpg");
94 
95  m_program_draw= read_program("tutos/draw_cubemap.glsl");
96  program_print_errors(m_program_draw);
97  m_program= read_program("tutos/cubemap.glsl");
98  program_print_errors(m_program);
99 
100  // init camera
101  Point pmin, pmax;
102  m_objet.bounds(pmin, pmax);
103  camera().lookat(pmin, pmax);
104 
105  // etat openGL par defaut
106  glGenVertexArrays(1, &m_vao);
107 
108  glClearColor(0.2f, 0.2f, 0.2f, 1.f); // couleur par defaut de la fenetre
109 
110  glClearDepth(1.f); // profondeur par defaut
111  glDepthFunc(GL_LEQUAL); // ztest, conserver l'intersection la plus proche de la camera
112  glEnable(GL_DEPTH_TEST); // activer le ztest
113 
114  return 0; // ras, pas d'erreur
115  }
116 
117  // destruction des objets de l'application
118  int quit( )
119  {
120  m_objet.release();
121  release_program(m_program_draw);
122  release_program(m_program);
123  glDeleteVertexArrays(1, &m_vao);
124  glDeleteTextures(1, &m_texture);
125  return 0;
126  }
127 
128  // dessiner une nouvelle image
129  int render( )
130  {
131  glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
132 
133  Transform model= Identity();
134  Transform view= camera().view();
135  Transform projection= camera().projection();
136  Transform viewport= camera().viewport();
137  Transform mvp= projection * view * model;
138 
139  Transform viewInv= Inverse(view);
140  Point camera_position= viewInv(Point(0, 0, 0)); // coordonnees de la camera, dans le repere camera... c'est l'origine
141 
142  // etape 1 : affiche l'objet, utilise la cubemap pour calculer les reflets
143  glUseProgram(m_program);
144  program_uniform(m_program, "mvpMatrix", mvp);
145  program_uniform(m_program, "modelMatrix", model);
146  program_uniform(m_program, "camera_position", camera_position);
147 
148  glBindTexture(GL_TEXTURE_CUBE_MAP, m_texture);
149  program_uniform(m_program, "texture0", int(0));
150 
151  // dessine l'objet, les attributs position et normale sont necessaires a l'execution du shader.
152  m_objet.draw(m_program, /* position */ true, /* texcoord */ false, /* normal */ true, /* color */ false, /* material */ false);
153 
154  // etape 2 : affiche la cube map
155  // inverse de la composition des transformations repere monde vers repere image
156  Transform inv= Inverse(viewport * projection * view);
157 
158  glUseProgram(m_program_draw);
159  glBindVertexArray(m_vao);
160  program_uniform(m_program_draw, "invMatrix", inv);
161  program_uniform(m_program_draw, "camera_position", camera_position);
162 
163  glBindTexture(GL_TEXTURE_CUBE_MAP, m_texture);
164  program_uniform(m_program_draw, "texture0", int(0));
165 
166  glDrawArrays(GL_TRIANGLES, 0, 3);
167 
168  // nettoyage
169  glBindTexture(GL_TEXTURE_CUBE_MAP, 0);
170  glUseProgram(0);
171  glBindVertexArray(0);
172 
173  if(key_state('r'))
174  {
175  clear_key_state('r');
176 
177  reload_program(m_program_draw, "tutos/draw_cubemap.glsl");
178  program_print_errors(m_program_draw);
179  reload_program(m_program, "tutos/cubemap.glsl");
180  program_print_errors(m_program);
181  }
182 
183  if(key_state('s'))
184  {
185  clear_key_state('s');
186  static int calls= 0;
187  screenshot("cubemap_brdf", ++calls);
188  printf("screenshot %d\n", calls);
189  }
190 
191  return 1;
192  }
193 
194 protected:
195  Mesh m_objet;
196  GLuint m_texture;
197  GLuint m_program_draw;
198  GLuint m_program;
199  GLuint m_vao;
200 };
201 
202 
203 int main( int argc, char **argv )
204 {
205  // il ne reste plus qu'a creer un objet application et la lancer
206  TP tp;
207  tp.run();
208 
209  return 0;
210 }
classe application.
Definition: app_camera.h:19
const Orbiter & camera() const
renvoie l'orbiter gere par l'application.
Definition: app_camera.h:37
int run()
execution de l'application.
Definition: app.cpp:36
representation d'un objet / maillage.
Definition: mesh.h:112
void bounds(Point &pmin, Point &pmax) const
renvoie min et max les coordonnees des extremites des positions des sommets de l'objet (boite engloba...
Definition: mesh.cpp:503
void draw(const GLuint program, const bool use_position, const bool use_texcoord, const bool use_normal, const bool use_color, const bool use_material_index)
dessine l'objet avec un shader program.
Definition: mesh.cpp:770
void release()
detruit les objets openGL.
Definition: mesh.cpp:64
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:83
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:47
Transform view() const
renvoie la transformation vue.
Definition: orbiter.cpp:40
Definition: alpha.cpp:59
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:48
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:42
ImageData read_image_data(const char *filename)
charge les donnees d'un fichier png. renvoie une image initialisee par defaut en cas d'echec.
Definition: image_io.cpp:216
Image flipY(const Image &image)
retourne l'image
Definition: image_io.cpp:295
Image flipX(const Image &image)
retourne l'image
Definition: image_io.cpp:312
Image copy(const Image &image, const int xmin, const int ymin, const int width, const int height)
renvoie un bloc de l'image
Definition: image_io.cpp:328
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
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:188
GLuint read_program(const char *filename, const char *definitions)
Definition: program.cpp:204
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.
Definition: uniforms.cpp:94
int program_print_errors(const GLuint program)
affiche les erreurs de compilation.
Definition: program.cpp:432
int release_program(const GLuint program)
detruit les shaders et le program.
Definition: program.cpp:211
stockage temporaire des donnees d'une image.
Definition: image_io.h:38
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
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.