190{
191 if(wireframe)
192 {
193 glClearColor(1, 1, 1, 1);
194 glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
195 glLineWidth(2);
196 }
197 else
198 {
199 glClearColor(0.2f, 0.2f, 0.2f, 1);
200 glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
201 }
202
203
204 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
205
206
207 static float last_time= 0;
208
210 {
211 if(timestamp(program_filename) != last_load)
212
213 reload_program();
214
215
216
218 }
219
221 {
223 reload_program();
224 }
225
226
227 int mx, my;
228 unsigned int mb= SDL_GetRelativeMouseState(&mx, &my);
229 int mousex, mousey;
230 SDL_GetMouseState(&mousex, &mousey);
231
232
233 if(mb & SDL_BUTTON(1))
234 camera.rotation(mx, my);
235 else if(mb & SDL_BUTTON(3))
237 else if(mb & SDL_BUTTON(2))
238 camera.move(mx);
239
241 if(wheel.y != 0)
242 {
244 camera.move(8.f * wheel.y);
245 }
246
247
248 static float time= 0;
249 static int frame= 0;
250 static int zbuffer= 0;
251 static int video= 0;
252 static int freeze= 0;
253 static int reset_camera= 0;
254 static int copy_camera= 0;
255 static int paste_camera= 0;
256
257
262
263 Transform mvp= projection * view * model;
266
267
269 {
271 freeze= (freeze+1) % 2;
272 }
273 if(freeze == 0)
275
276
277 if(program_failed == false)
278 {
280 {
282 wireframe= !wireframe;
283 }
284
285
286 glBindVertexArray(vao);
287 glUseProgram(program);
288
289
290
291 program_uniform(program, "modelMatrix", model);
292 program_uniform(program, "modelInvMatrix", model.inverse());
293 program_uniform(program, "viewMatrix", view);
294 program_uniform(program, "viewInvMatrix", view.inverse());
295 program_uniform(program, "projectionMatrix", projection);
296 program_uniform(program,
"projectionInvMatrix", projection.
inverse());
297 program_uniform(program, "viewportMatrix", viewport);
298 program_uniform(program,
"viewportInvMatrix", viewport.
inverse());
299
300 program_uniform(program, "mvpMatrix", mvp);
301 program_uniform(program, "mvpInvMatrix", mvpInv);
302
303 program_uniform(program, "mvMatrix", mv);
304 program_uniform(program,
"mvInvMatrix", mv.
inverse());
305 program_uniform(program,
"normalMatrix", mv.
normal());
306
307 program_uniform(program, "pmin", mesh_pmin);
308 program_uniform(program, "pmax", mesh_pmax);
309
310
312 program_uniform(program, "time", time);
313 program_uniform(program,
"motion",
vec3(mx, my, mb & SDL_BUTTON(1)));
314 program_uniform(program,
"mouse",
vec3(mousex,
window_height() - mousey -1, mb & SDL_BUTTON(1)));
315
316
317 for(unsigned i= 0; i < textures.size(); i++)
318 {
319 char uniform[1024];
320 sprintf(uniform, "texture%u", i);
322 }
323
324
325 glDrawArrays(GL_TRIANGLES, 0, vertex_count);
326 }
327
328
329
331 if(program_failed)
332 {
333 label(widgets, "[error] program '%s'", program_filename);
335 text_area(widgets, 20, program_log.c_str(), program_area);
336 }
337 else
338 {
339 button(widgets,
"[s] screenshot ", frame);
340 button(widgets,
"[z] depth screenshot", zbuffer);
341 button(widgets,
"capture frames", video);
343 button(widgets,
"[t] freeze time", freeze);
344 button(widgets,
"[f] reset camera", reset_camera);
345 button(widgets,
"[c] copy/save camera", copy_camera);
346 button(widgets,
"[v] paste/read camera", paste_camera);
347
350 label(widgets, "program '%s' running...", program_filename);
351 if(mesh_filename && mesh_filename[0])
352 {
354 label(widgets, "mesh '%s', %d vertices %s %s", mesh_filename, mesh.vertex_count(),
355 mesh.texcoord_buffer_size() ? "texcoords" : "", mesh.normal_buffer_size() ? "normals" : "");
356 }
357 for(unsigned i= 0; i < texture_filenames.size(); i++)
358 {
360 label(widgets, "texture%u '%s'", i, texture_filenames[i]);
361 }
362
363 }
364
365 end(widgets);
366
367
369 {
370 zbuffer= 0;
372
373 frame= 1;
374 copy_camera= 1;
375
376 printf(
"zbuffer screenshot...\n");
377
378
380 std::vector<float> tmp(image.width() * image.height());
381
382 glReadBuffer(GL_BACK);
383 glReadPixels(0, 0, image.width(), image.height(), GL_DEPTH_COMPONENT, GL_FLOAT, tmp.data());
384
385
386 for(unsigned i= 0; i < image.size(); i++)
387 image(i)=
Color(tmp[i]);
388
389 write_image_pfm(image, "zbuffer_viewport.pfm");
390
391
393 for(unsigned py= 0; py < image.height(); py++)
394 for(unsigned px= 0; px < image.width(); px++)
395 {
396 unsigned i= py * image.width() + px;
397 Point fragment=
Point(
float(px) +
float(0.5),
float(py) +
float(0.5), tmp[i]);
398 Point p= inv( fragment );
399
400 image(i)=
Color(p.z);
401 }
402
403 write_image_pfm(image, "zbuffer_camera.pfm");
404
405
406 for(unsigned i= 0; i < image.size(); i++)
407 image(i)=
Color(std::abs(image(i).r));
408
409 write_image_pfm(image, "zbuffer_color.pfm");
410 }
411
412
414
416 {
417 frame= 0;
419
420 static int calls= 1;
421 printf(
"screenshot %d...\n", calls);
423 }
424
425 if(video)
427
429 {
430 copy_camera= 0;
432 camera.write_orbiter("orbiter.txt");
433 {
434 vec3 p= camera.translation();
435 vec2 r= camera.rotation();
436 printf(
"Translation( %f, %f, %f ) * RotationX( %f ) * RotationY( %f )\n", p.x, p.y, p.z, r.x, r.y );
437 }
438 }
440 {
441 paste_camera= 0;
443 if(camera.read_orbiter("orbiter.txt") < 0)
444 {
446 camera.lookat(mesh_pmin, mesh_pmax);
447 }
448 }
449
451 {
452 reset_camera= 0;
454
456 camera.lookat(mesh_pmin, mesh_pmax);
457 }
458
459 return 1;
460}
representation d'une image.
void begin(Widgets &w)
debut de la description des elements de l'interface graphique.
bool button(Widgets &w, const char *text, int &status)
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 clear_wheel_event()
desactive l'evenement.
int key_state(const SDL_Keycode key)
renvoie l'etat d'une touche du clavier. cf la doc SDL2 pour les codes.
void text_area(Widgets &w, const int height, const char *text, int &begin_line)
void begin_line(Widgets &w)
place les prochains elements sur une nouvelle ligne.
SDL_MouseWheelEvent wheel_event()
renvoie le dernier evenement. etat de la molette de la souris / glisser sur le pad.
int window_width()
renvoie la largeur de la fenetre de l'application.
float global_time()
renvoie le temps ecoule depuis le lancement de l'application, en millisecondes.
Transform Inverse(const Transform &m)
renvoie l'inverse de la matrice.
Transform Viewport(const float width, const float height)
renvoie la matrice representant une transformation viewport.
Transform Identity()
construit la transformation identite.
int capture(const char *prefix)
int screenshot(const char *filename)
enregistre le contenu de la fenetre dans un fichier. doit etre de type .png / .bmp
void program_use_texture(const GLuint program, const char *uniform, const int unit, const GLuint texture, const GLuint sampler)
configure le pipeline et le shader program pour utiliser une texture, et des parametres de filtrage,...
representation d'une couleur (rgba) transparente ou opaque.
vecteur generique, utilitaire.
vecteur generique, utilitaire.