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