gKit2 light
tuto3GL_reflect.cpp
Go to the documentation of this file.
1 
3 
4 #include <cstdio>
5 #include <algorithm>
6 
7 #include "window.h"
8 #include "program.h"
9 #include "mesh.h"
10 #include "wavefront.h"
11 
12 // identifiant du shader program
13 GLuint program;
14 
15 // identifiant du vertex array object
16 GLuint vao;
17 
18 // utilitaire : renvoie la chaine de caracteres pour un type glsl.
19 const char *glsl_string( const GLenum type )
20 {
21  switch(type)
22  {
23  case GL_BOOL:
24  return "bool";
25  case GL_UNSIGNED_INT:
26  return "uint";
27  case GL_INT:
28  return "int";
29  case GL_FLOAT:
30  return "float";
31  case GL_FLOAT_VEC2:
32  return "vec2";
33  case GL_FLOAT_VEC3:
34  return "vec3";
35  case GL_FLOAT_VEC4:
36  return "vec4";
37  case GL_FLOAT_MAT4:
38  return "mat4";
39 
40  default:
41  return "";
42  }
43 }
44 
45 // utilitaire : affiche la valeur d'un uniform.
46 void print_uniform_value( const GLuint program, const int index, const char *name, const GLenum type, const GLint size )
47 {
48  if(program == 0)
49  return;
50  if(index < 0)
51  return;
52 
53  int value= 0;
54  float values[16]= { };
55 
56 /* les tableaux occuppent plusieurs uniforms places les uns apres les autres, donc :
57  for(int i= 0; i < size; i++)
58  glGetActiveUniform(program, location + i, ...)
59  permet de recuperer toutes les cellules du tableau...
60  */
61 
62  // limite l'affichage d'un tableau a quelques valeurs
63  int n= std::min(10, size);
64  for(int i= 0; i < n; i++)
65  {
66  if(size > 1)
67  printf("[%02d] ", i);
68  else
69  printf(" ");
70 
71  switch(type)
72  {
73  case GL_BOOL:
74  glGetUniformiv(program, index +i, &value);
75  printf("value= %s\n", value ? "true" : "false");
76  break;
77  case GL_INT:
78  glGetUniformiv(program, index +i, &value);
79  printf("value= %d\n", value);
80  break;
81  case GL_FLOAT:
82  glGetUniformfv(program, index +i, values);
83  printf("value= %f\n", values[0]);
84  break;
85  case GL_FLOAT_VEC2:
86  glGetUniformfv(program, index +i, values);
87  printf("values= %f %f\n", values[0], values[1]);
88  break;
89  case GL_FLOAT_VEC3:
90  glGetUniformfv(program, index +i, values);
91  printf("values= %f %f %f\n", values[0], values[1], values[2]);
92  break;
93  case GL_FLOAT_VEC4:
94  glGetUniformfv(program, index +i, values);
95  printf("values= %f %f %f %f\n", values[0], values[1], values[2], values[3]);
96  break;
97  case GL_FLOAT_MAT4:
98  glGetUniformfv(program, index +i, values);
99  printf("values=\n");
100  for(int r= 0; r < 4; r++)
101  {
102  printf(" ");
103  for(int c= 0; c < 4; c++)
104  printf("%f ", values[c*4 + r]);
105  printf("\n");
106  }
107  break;
108 
109  default:
110  printf(" uniform '%s', type %x, type unknown\n", name, type);
111  }
112  }
113 
114  // indiquer que le tableau a ete tronque
115  if(n < size)
116  printf("... \n");
117 }
118 
119 // utilitaire : affiche les uniforms utilises par un program
120 int print_uniforms( const GLuint program )
121 {
122  if(program == 0)
123  {
124  printf("[error] program 0, no uniforms...\n");
125  return -1;
126  }
127 
128  // recuperer le nombre total d'uniforms
129  GLint n= 0;
130  glGetProgramiv(program, GL_ACTIVE_UNIFORMS, &n);
131  if(n == 0)
132  {
133  printf("program %u: no uniforms...\n", program);
134  return 0;
135  }
136 
137  // recuperer la longueur max occuppee par un nom d'uniform
138  GLint length_max= 0;
139  glGetProgramiv(program, GL_ACTIVE_UNIFORM_MAX_LENGTH, &length_max);
140 
141  // allouer une chaine de caractere
142  char *name= new char [length_max];
143 
144  printf("program %u:\n", program);
145  // recuperer les infos de chaque uniform
146  for(int index= 0; index < n; index++)
147  {
148  GLint glsl_size;
149  GLenum glsl_type;
150  glGetActiveUniform(program, index, length_max, NULL, &glsl_size, &glsl_type, name);
151  // et son identifiant
152  GLint location= glGetUniformLocation(program, name);
153 
154  printf(" uniform %i '%s': location %d, type %s (0x%x), array_size %d\n", index, name, location,
155  glsl_string(glsl_type), glsl_type, glsl_size);
156 
157  print_uniform_value(program, index, name, glsl_type, glsl_size);
158  }
159 
160  delete [] name;
161  return 0;
162 }
163 
164 
165 // utilitaire : affiche tous les attributs utilises par un program, et eventuellement a quel buffer ils sont associes
166 int print_attribs( const GLuint program, const GLuint vao= 0 )
167 {
168  if(program == 0)
169  {
170  printf("[error] program 0, no attributes...\n");
171  return -1;
172  }
173 
174  // recuperer le nombre total d'attributs
175  GLint n= 0;
176  glGetProgramiv(program, GL_ACTIVE_ATTRIBUTES, &n);
177  if(n == 0)
178  {
179  printf("program %u: no attributes...\n", program);
180  return 0;
181  }
182 
183  // recuperer la longueur max occuppee par un nom d'attribut
184  GLint length_max= 0;
185  glGetProgramiv(program, GL_ACTIVE_ATTRIBUTE_MAX_LENGTH, &length_max);
186 
187  // allouer une chaine de caractere
188  char *name= new char [length_max];
189 
190  printf("program %u:\n", program);
191  // recuperer les infos de chaque attribut
192  for(int index= 0; index < n; index++)
193  {
194  GLint glsl_size;
195  GLenum glsl_type;
196  glGetActiveAttrib(program, index, length_max, NULL, &glsl_size, &glsl_type, name);
197  // et son identifiant
198  GLint location= glGetAttribLocation(program, name);
199 
200  printf(" attribute %d '%s': location %d, type %s (0x%x), array_size %d\n", index, name, location,
201  glsl_string(glsl_type), glsl_type, glsl_size);
202 
203  if(vao > 0)
204  {
205  GLint buffer= 0;
206  glGetVertexAttribiv(index, GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING, &buffer);
207  if(buffer > 0)
208  printf(" buffer %d\n", buffer);
209  else
210  printf(" no buffer\n");
211  }
212  }
213 
214  delete [] name;
215  return 0;
216 }
217 
218 
219 int init( )
220 {
221  // charge 12 triangles, soit un cube...
222  Mesh cube= read_mesh("data/flat_bbox.obj");
223  printf(" %d positions\n", cube.vertex_count());
224 
225  // compile le shader program, le program est selectionne
226  program= read_program("tutos/tuto3GL.glsl");
227 
228  // affiche les uniforms et leurs valeurs par defaut
229  print_uniforms(program);
230  // affiche les attributs
231  //~ print_attribs(program);
232 
233  // transfere les 36 positions dans le tableau declare par le vertex shader
234  // etape 1 : recuperer l'identifiant de l'uniform
235  GLint location= glGetUniformLocation(program, "positions"); // uniform vec3 positions[36];
236  // etape 2 : modifier sa valeur
237  glUniform3fv(location, cube.vertex_count(), cube.vertex_buffer());
238 
239  // mesh n'est plus necessaire
240  cube.release();
241 
242  // creer un vertex array object
243  glGenVertexArrays(1, &vao);
244 
245  // afficher les uniforms apres l'affectation...
246  print_uniforms(program);
247  // afficher les attributs... et leurs buffers
248  print_attribs(program, vao);
249 
250  // etat openGL par defaut
251  glClearColor(0.2, 0.2, 0.2, 1); // definir la couleur par defaut
252  glClearDepth(1.f); // profondeur par defaut
253 
254  glDepthFunc(GL_LESS); // ztest, conserver l'intersection la plus proche de la camera
255  glEnable(GL_DEPTH_TEST); // activer le ztest
256 
257  return 0;
258 }
259 
260 int quit( )
261 {
262  release_program(program);
263  glDeleteVertexArrays(1, &vao);
264  return 0;
265 }
266 
267 
268 // affichage
269 int draw( )
270 {
271  // effacer la fenetre : copier la couleur par defaut dans tous les pixels de la fenetre
272  glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // "effacer"
273 
274  // configurer le pipeline, selectionner le vertex array a utiliser
275  glBindVertexArray(vao);
276 
277  // configurer le pipeline, selectionner le shader program a utiliser
278  glUseProgram(program);
279 
280  // modifier les valeurs des parametres uniforms du shader program
281  GLint location;
282  location= glGetUniformLocation(program, "color"); // declare dans le fragment shader
283  glUniform4f(location, 1, 0.5, 0, 1); // vec4 color;
284 
285 /* modifiez la valeur de time, declare dans le vertex shader pour modifier la position du cube dans le repere du monde,
286  en fonction du temps. vous pouvez utiliser la fonction mod ou modf pour creer un mouvement cyclique
287 
288  utilisez la fonction SDL_GetTicks( ), pour connaitre l'heure exprimee en milli secondes
289 
290  float time= SDL_GetTicks();
291  location= glGetUniformLocation(program, "time");
292  glUniform1f(location, time);
293  */
294 
295 /* utilisez print_uniforms(program) pour verifier les valeurs des parametres uniforms
296  remarque: eventuellement pas tres lisible...
297  modifiez print_uniform( ) pour n'afficher un message que si l'uniform est egal a 0
298  */
299 
300  // dessiner 12 triangles, indices gl_VertexID de 0 a 36
301  glDrawArrays(GL_TRIANGLES, 0, 36);
302 
303  return 1; // on continue, renvoyer 0 pour sortir de l'application
304 }
305 
306 
307 int main( int argc, char **argv )
308 {
309  // etape 1 : creer la fenetre
310  Window window= create_window(1024, 640);
311  if(window == NULL)
312  return 1; // erreur lors de la creation de la fenetre ou de l'init de sdl2
313 
314  // etape 2 : creer un contexte opengl pour pouvoir dessiner
315  Context context= create_context(window);
316  if(context == NULL)
317  return 1; // erreur lors de la creation du contexte opengl
318 
319  // etape 3 : creation des objets
320  if(init() < 0)
321  {
322  printf("[error] init failed.\n");
323  return 1;
324  }
325 
326  // etape 4 : affichage de l'application, tant que la fenetre n'est pas fermee. ou que draw() ne renvoie pas 0
327  run(window, draw);
328 
329  // etape 5 : nettoyage
330  quit();
331  release_context(context);
332  release_window(window);
333  return 0;
334 }
representation d'un objet / maillage.
Definition: mesh.h:112
const float * vertex_buffer() const
renvoie l'adresse de la position du premier sommet. permet de construire les vertex buffers openGL....
Definition: mesh.h:296
int vertex_count() const
renvoie le nombre de sommets.
Definition: mesh.h:291
void release()
detruit les objets openGL.
Definition: mesh.cpp:62
Context create_context(Window window)
cree et configure un contexte opengl
Definition: window.cpp:356
void release_window(Window window)
destruction de la fenetre.
Definition: window.cpp:325
bool value(Widgets &w, const char *label, int &value, const int value_min, const int value_max, const int value_step)
valeur editable par increment.
Definition: widgets.cpp:191
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
Window create_window(const int w, const int h, const int major, const int minor, const int samples)
creation d'une fenetre pour l'application.
Definition: window.cpp:259
void release_context(Context context)
detruit le contexte openGL.
Definition: window.cpp:422
Point min(const Point &a, const Point &b)
renvoie la plus petite composante de chaque point. x, y, z= min(a.x, b.x), min(a.y,...
Definition: vec.cpp:30
Mesh read_mesh(const char *filename)
charge un fichier wavefront .obj et renvoie un mesh compose de triangles non indexes....
Definition: wavefront.cpp:14
GLuint read_program(const char *filename, const char *definitions)
Definition: program.cpp:204
int release_program(const GLuint program)
detruit les shaders et le program.
Definition: program.cpp:211
int init(std::vector< const char * > &options)
Definition: shader_kit.cpp:92
int run(Window window, int(*draw)())
boucle de gestion des evenements de l'application.
Definition: window.cpp:147