189{
190 if(wireframe)
191 {
192 glClearColor(1, 1, 1, 1);
193 glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
194 glLineWidth(2);
195 }
196 else
197 {
198 glClearColor(0.2f, 0.2f, 0.2f, 1);
199 glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
200 }
201
202
203 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
204
205
206 static float last_time= 0;
207
209 {
210 if(timestamp(program_filename) != last_load)
211
212 reload_program();
213
214
215
217 }
218
220 {
222 reload_program();
223 }
224
225
226 int mx, my;
227 unsigned int mb= SDL_GetRelativeMouseState(&mx, &my);
228 int mousex, mousey;
229 SDL_GetMouseState(&mousex, &mousey);
230
231
232 if(mb & SDL_BUTTON(1))
233 camera.rotation(mx, my);
234 else if(mb & SDL_BUTTON(3))
236 else if(mb & SDL_BUTTON(2))
237 camera.move(mx);
238
240 if(wheel.y != 0)
241 {
243 camera.move(8.f * wheel.y);
244 }
245
246
247 static float time= 0;
248 static int frame= 0;
249 static int zbuffer= 0;
250 static int video= 0;
251 static int freeze= 0;
252 static int reset_camera= 0;
253 static int copy_camera= 0;
254 static int paste_camera= 0;
255
256
261
262 Transform mvp= projection * view * model;
265
266
268 {
270 freeze= (freeze+1) % 2;
271 }
272 if(freeze == 0)
274
275
276 if(program_failed == false)
277 {
279 {
281 wireframe= !wireframe;
282 }
283
284
285 glBindVertexArray(vao);
286 glUseProgram(program);
287
288
289
290 program_uniform(program, "modelMatrix", model);
291 program_uniform(program, "modelInvMatrix", model.inverse());
292 program_uniform(program, "viewMatrix", view);
293 program_uniform(program, "viewInvMatrix", view.inverse());
294 program_uniform(program, "projectionMatrix", projection);
295 program_uniform(program,
"projectionInvMatrix", projection.
inverse());
296 program_uniform(program, "viewportMatrix", viewport);
297 program_uniform(program,
"viewportInvMatrix", viewport.
inverse());
298
299 program_uniform(program, "mvpMatrix", mvp);
300 program_uniform(program, "mvpInvMatrix", mvpInv);
301
302 program_uniform(program, "mvMatrix", mv);
303 program_uniform(program,
"mvInvMatrix", mv.
inverse());
304 program_uniform(program,
"normalMatrix", mv.
normal());
305
306 program_uniform(program, "pmin", mesh_pmin);
307 program_uniform(program, "pmax", mesh_pmax);
308
309
311 program_uniform(program, "time", time);
312 program_uniform(program,
"motion",
vec3(mx, my, mb & SDL_BUTTON(1)));
313 program_uniform(program,
"mouse",
vec3(mousex,
window_height() - mousey -1, mb & SDL_BUTTON(1)));
314
315
316 for(unsigned i= 0; i < textures.size(); i++)
317 {
318 char uniform[1024];
319 sprintf(uniform, "texture%u", i);
321 }
322
323
324 glDrawArrays(GL_TRIANGLES, 0, vertex_count);
325 }
326
327
328
330 if(program_failed)
331 {
332 label(widgets, "[error] program '%s'", program_filename);
334 text_area(widgets, 20, program_log.c_str(), program_area);
335 }
336 else
337 {
338 button(widgets,
"[s] screenshot ", frame);
339 button(widgets,
"[z] depth screenshot", zbuffer);
340 button(widgets,
"capture frames", video);
342 button(widgets,
"[t] freeze time", freeze);
343 button(widgets,
"[f] reset camera", reset_camera);
344 button(widgets,
"[c] copy/save camera", copy_camera);
345 button(widgets,
"[v] paste/read camera", paste_camera);
346
349 label(widgets, "program '%s' running...", program_filename);
350 if(mesh_filename && mesh_filename[0])
351 {
353 label(widgets, "mesh '%s', %d vertices %s %s", mesh_filename, mesh.vertex_count(),
354 mesh.texcoord_buffer_size() ? "texcoords" : "", mesh.normal_buffer_size() ? "normals" : "");
355 }
356 for(unsigned i= 0; i < texture_filenames.size(); i++)
357 {
359 label(widgets, "texture%u '%s'", i, texture_filenames[i]);
360 }
361
362 }
363
364 end(widgets);
365
366
368 {
369 zbuffer= 0;
371
372 frame= 1;
373 copy_camera= 1;
374
375 printf(
"zbuffer screenshot...\n");
376
377
379 std::vector<float> tmp(image.width() * image.height());
380
381 glReadBuffer(GL_BACK);
382 glReadPixels(0, 0, image.width(), image.height(), GL_DEPTH_COMPONENT, GL_FLOAT, tmp.data());
383
384
385 for(unsigned i= 0; i < image.size(); i++)
386 image(i)=
Color(tmp[i]);
387
388 write_image_pfm(image, "zbuffer_viewport.pfm");
389
390
392 for(unsigned py= 0; py < image.height(); py++)
393 for(unsigned px= 0; px < image.width(); px++)
394 {
395 unsigned i= py * image.width() + px;
398
399 image(i)=
Color(p.z);
400 }
401
402 write_image_pfm(image, "zbuffer_camera.pfm");
403
404
405 for(unsigned i= 0; i < image.size(); i++)
406 image(i)=
Color(std::abs(image(i).r));
407
408 write_image_pfm(image, "zbuffer_color.pfm");
409 }
410
411
413
415 {
416 frame= 0;
418
419 static int calls= 1;
420 printf(
"screenshot %d...\n", calls);
422 }
423
424 if(video)
426
428 {
429 copy_camera= 0;
431 camera.write_orbiter("orbiter.txt");
432 {
433 vec3 p= camera.translation();
434 vec2 r= camera.rotation();
435 printf(
"Translation( %f, %f, %f ) * RotationX( %f ) * RotationY( %f )\n", p.x, p.y, p.z, r.x, r.y );
436 }
437 }
439 {
440 paste_camera= 0;
442 if(camera.read_orbiter("orbiter.txt") < 0)
443 {
445 camera.lookat(mesh_pmin, mesh_pmax);
446 }
447 }
448
450 {
451 reset_camera= 0;
453
455 camera.lookat(mesh_pmin, mesh_pmax);
456 }
457
458 return 1;
459}
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.