gKit2 light
Loading...
Searching...
No Matches
shader_kit.cpp File Reference

shader_kit light, bac a sable fragment shader, cf shader_toy More...

#include <cstdio>
#include <cstring>
#include <chrono>
#include "glcore.h"
#include "window.h"
#include "files.h"
#include "program.h"
#include "uniforms.h"
#include "texture.h"
#include "mesh.h"
#include "wavefront.h"
#include "wavefront_fast.h"
#include "vec.h"
#include "mat.h"
#include "orbiter.h"
#include "color.h"
#include "image.h"
#include "image_hdr.h"
#include "text.h"
#include "widgets.h"

Go to the source code of this file.

Functions

void reload_program ()
const char * option_find (std::vector< const char * > &options, const char *ext)
int init (std::vector< const char * > &options)
int quit ()
int draw (void)
int main (int argc, char **argv)

Variables

const char * program_filename
GLuint program
std::string program_log
int program_area
bool program_failed
const char * mesh_filename
Mesh mesh
Point mesh_pmin
Point mesh_pmax
int vertex_count
GLuint vao
bool wireframe = false
std::vector< const char * > texture_filenames
std::vector< GLuint > textures
Orbiter camera
Widgets widgets
size_t last_load = 0

Detailed Description

shader_kit light, bac a sable fragment shader, cf shader_toy

Definition in file shader_kit.cpp.

Function Documentation

◆ reload_program()

void reload_program ( )

Definition at line 59 of file shader_kit.cpp.

60{
61 if(program == 0)
62 program= read_program(program_filename);
63 else
64 reload_program(program, program_filename);
65
66 // conserve la date du fichier
67 last_load= timestamp(program_filename);
68
69 // recupere les erreurs, si necessaire
70 program_area= program_format_errors(program, program_log);
71
72 if(program_log.size() > 0)
73 printf("[boom]\n%s\n", program_log.c_str());
74
75 program_failed= (program_log.size() > 0);
76}
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
GLuint read_program(const char *filename, const char *definitions)
Definition program.cpp:218
int program_format_errors(const GLuint program, std::string &errors)
renvoie les erreurs de compilation.
Definition program.cpp:380

◆ option_find()

const char * option_find ( std::vector< const char * > & options,
const char * ext )

Definition at line 80 of file shader_kit.cpp.

81{
82 for(unsigned int i= 0; i < (unsigned int) options.size() ; i++)
83 {
84 if(options[i] != nullptr && std::string(options[i]).rfind(ext) != std::string::npos)
85 {
86 const char *option= options[i];
87 options[i]= nullptr;
88 return option;
89 }
90 }
91
92 return nullptr;
93}

◆ init()

int init ( std::vector< const char * > & options)

compile les shaders et construit le programme + les buffers + le vertex array. renvoie -1 en cas d'erreur.

Definition at line 97 of file shader_kit.cpp.

98{
99 widgets= create_widgets();
100 camera= Orbiter();
101
102 program= 0;
103 const char *option;
104 option= option_find(options, ".glsl");
105 if(option != nullptr)
106 {
107 program_filename= option;
108 reload_program();
109 }
110
111 vao= 0;
112 mesh_pmin= Point(normalize(Vector(-1, -1, 0)) * 2.5f);
113 mesh_pmax= Point(normalize(Vector( 1, 1, 0)) * 2.5f);
114
115 option= option_find(options, ".obj");
116 if(option != nullptr)
117 {
118 //~ mesh= read_mesh(option);
119 mesh= read_mesh_fast(option);
120 //~ mesh= read_indexed_mesh_fast(option);
121 //~ mesh= read_indexed_mesh(option);
122 if(mesh.vertex_count() > 0)
123 {
124 mesh_filename= option;
125
126 vao= mesh.create_buffers(mesh.has_texcoord(), mesh.has_normal(), mesh.has_color(), mesh.has_material_index());
127 vertex_count= mesh.vertex_count();
128
129 mesh.bounds(mesh_pmin, mesh_pmax);
130 camera.lookat(mesh_pmin, mesh_pmax);
131 }
132
133 // ou generer une erreur ?
134 }
135
136 if(vao == 0)
137 {
138 glGenVertexArrays(1, &vao);
139 vertex_count= 3;
140 }
141
142 // charge les textures, si necessaire
143 for(unsigned i= 0; i < options.size(); i++)
144 {
145 if(options[i] == nullptr)
146 continue;
147
148 GLuint texture= read_texture(0, options[i]);
149 if(texture > 0)
150 {
151 texture_filenames.push_back(options[i]);
152 textures.push_back(texture);
153 }
154 }
155
156 // nettoyage
157 glUseProgram(0);
158 glBindTexture(GL_TEXTURE_2D, 0);
159 glBindVertexArray(0);
160 glBindBuffer(GL_ARRAY_BUFFER, 0);
161 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
162
163 // etat openGL par defaut
164 glClearColor(0.2f, 0.2f, 0.2f, 1.f);
165 glClearDepth(1.f);
166
167 glCullFace(GL_BACK);
168 glFrontFace(GL_CCW);
169 //~ glEnable(GL_CULL_FACE); // n'affiche que les faces correctement orientees...
170 glDisable(GL_CULL_FACE); // les faces mal orientees sont affichees avec des hachures oranges...
171
172 glDepthFunc(GL_LESS);
173 glEnable(GL_DEPTH_TEST);
174
175 return 0;
176}
representation de la camera, type orbiter, placee sur une sphere autour du centre de l'objet.
Definition orbiter.h:17
Widgets create_widgets()
cree une interface graphique. a detruire avec release_widgets( ).
Definition widgets.cpp:12
Vector normalize(const Vector &v)
renvoie un vecteur unitaire / longueur == 1.
Definition vec.cpp:167
Mesh read_mesh_fast(const char *filename)
charge un fichier wavefront .obj et renvoie un mesh compose de triangles non indexes....
GLuint read_texture(const int unit, const char *filename, const GLenum texel_type)
Definition texture.cpp:133
representation d'un point 3d.
Definition vec.h:21
representation d'un vecteur 3d.
Definition vec.h:67

◆ quit()

int quit ( )

Definition at line 178 of file shader_kit.cpp.

179{
180 // detruit les objets openGL
181 release_widgets(widgets);
182 release_program(program);
183 mesh.release();
184
185 glDeleteTextures(textures.size(), textures.data());
186 return 0;
187}
void release_widgets(Widgets &w)
detruit l'interface graphique.
Definition widgets.cpp:23
int release_program(const GLuint program)
detruit les shaders et le program.
Definition program.cpp:225

◆ draw()

int draw ( void )

Definition at line 189 of file shader_kit.cpp.

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 // effacer l'image
204 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
205
206 // verification de la date du fichier source des shaders...
207 static float last_time= 0;
208 // toutes les secondes, ca suffit, pas tres malin de le faire 60 fois par seconde...
209 if(global_time() > last_time + 400)
210 {
211 if(timestamp(program_filename) != last_load)
212 // date modifiee, recharger les sources et recompiler...
213 reload_program();
214
215 // attends le chargement et la compilation des shaders... au cas ou ce soit plus long qu'une seconde...
216 // (oui ca arrive...)
217 last_time= global_time();
218 }
219
220 if(key_state('r'))
221 {
222 clear_key_state('r');
223 reload_program();
224 }
225
226 // recupere les mouvements de la souris
227 int mx, my;
228 unsigned int mb= SDL_GetRelativeMouseState(&mx, &my);
229 int mousex, mousey;
230 SDL_GetMouseState(&mousex, &mousey);
231
232 // deplace la camera
233 if(mb & SDL_BUTTON(1))
234 camera.rotation(mx, my); // tourne autour de l'objet
235 else if(mb & SDL_BUTTON(3))
236 camera.translation((float) mx / (float) window_width(), (float) my / (float) window_height()); // deplace le point de rotation
237 else if(mb & SDL_BUTTON(2))
238 camera.move(mx); // approche / eloigne l'objet
239
240 SDL_MouseWheelEvent wheel= wheel_event();
241 if(wheel.y != 0)
242 {
244 camera.move(8.f * wheel.y); // approche / eloigne l'objet
245 }
246
247 // etat
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 // recupere les transformations
258 Transform model= Identity();
259 Transform view= camera.view();
260 Transform projection= camera.projection(window_width(), window_height(), 45);
262
263 Transform mvp= projection * view * model;
264 Transform mvpInv= Inverse(mvp);
265 Transform mv= model * view;
266
267 // temps
268 if(key_state('t'))
269 {
270 clear_key_state('t');
271 freeze= (freeze+1) % 2;
272 }
273 if(freeze == 0)
274 time= global_time();
275
276 // affiche l'objet
277 if(program_failed == false)
278 {
279 if(key_state('w'))
280 {
281 clear_key_state('w');
282 wireframe= !wireframe;
283 }
284
285 // configuration minimale du pipeline
286 glBindVertexArray(vao);
287 glUseProgram(program);
288
289 // affecte une valeur aux uniforms
290 // transformations standards
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 // interactions
311 program_uniform(program, "viewport", vec2(window_width(), window_height()));
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 // textures
317 for(unsigned i= 0; i < textures.size(); i++)
318 {
319 char uniform[1024];
320 sprintf(uniform, "texture%u", i);
321 program_use_texture(program, uniform, i, textures[i]);
322 }
323
324 // go
325 glDrawArrays(GL_TRIANGLES, 0, vertex_count);
326 }
327
328
329 // affiche les infos...
330 begin(widgets);
331 if(program_failed)
332 {
333 label(widgets, "[error] program '%s'", program_filename);
334 begin_line(widgets);
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);
342 begin_line(widgets);
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
348 begin_line(widgets);
349 begin_line(widgets);
350 label(widgets, "program '%s' running...", program_filename);
351 if(mesh_filename && mesh_filename[0])
352 {
353 begin_line(widgets);
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 {
359 begin_line(widgets);
360 label(widgets, "texture%u '%s'", i, texture_filenames[i]);
361 }
362
363 }
364
365 end(widgets);
366
367
368 if(zbuffer || key_state('z'))
369 {
370 zbuffer= 0;
371 clear_key_state('z');
372
373 frame= 1; // force un screenshot en meme temps
374 copy_camera= 1; // idem pour l'orbiter
375
376 printf("zbuffer screenshot...\n");
377
378 // recupere le zbuffer
379 Image image(window_width(), window_height());
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 // conversion en image
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 // transformation dans le repere camera
392 Transform inv= Inverse( viewport * projection );
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 // exporte une image avec un z positif...
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 //
413 draw(widgets, window_width(), window_height());
414
415 if(frame || key_state('s'))
416 {
417 frame= 0;
418 clear_key_state('s');
419
420 static int calls= 1;
421 printf("screenshot %d...\n", calls);
422 screenshot("shader_kit", calls++);
423 }
424
425 if(video)
426 capture("shader_kit");
427
428 if(copy_camera || key_state('c'))
429 {
430 copy_camera= 0;
431 clear_key_state('c');
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 }
439 if(paste_camera || key_state('v'))
440 {
441 paste_camera= 0;
442 clear_key_state('v');
443 if(camera.read_orbiter("orbiter.txt") < 0)
444 {
445 camera= Orbiter();
446 camera.lookat(mesh_pmin, mesh_pmax);
447 }
448 }
449
450 if(reset_camera || key_state('f'))
451 {
452 reset_camera= 0;
453 clear_key_state('f');
454
455 camera= Orbiter();
456 camera.lookat(mesh_pmin, mesh_pmax);
457 }
458
459 return 1;
460}
representation d'une image.
Definition image.h:21
void begin(Widgets &w)
debut de la description des elements de l'interface graphique.
Definition widgets.cpp:29
bool button(Widgets &w, const char *text, int &status)
Definition widgets.cpp:155
int window_height()
renvoie la hauteur de la fenetre de l'application.
Definition window.cpp:27
void clear_key_state(const SDL_Keycode key)
desactive une touche du clavier.
Definition window.cpp:46
void clear_wheel_event()
desactive l'evenement.
Definition window.cpp:114
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:40
void text_area(Widgets &w, const int height, const char *text, int &begin_line)
Definition widgets.cpp:273
void begin_line(Widgets &w)
place les prochains elements sur une nouvelle ligne.
Definition widgets.cpp:129
SDL_MouseWheelEvent wheel_event()
renvoie le dernier evenement. etat de la molette de la souris / glisser sur le pad.
Definition window.cpp:110
int window_width()
renvoie la largeur de la fenetre de l'application.
Definition window.cpp:23
float global_time()
renvoie le temps ecoule depuis le lancement de l'application, en millisecondes.
Definition window.cpp:126
Transform Inverse(const Transform &m)
renvoie l'inverse de la matrice.
Definition mat.cpp:197
Transform Viewport(const float width, const float height)
renvoie la matrice representant une transformation viewport.
Definition mat.cpp:357
Transform Identity()
construit la transformation identite.
Definition mat.cpp:187
int capture(const char *prefix)
Definition texture.cpp:205
int screenshot(const char *filename)
enregistre le contenu de la fenetre dans un fichier. doit etre de type .png / .bmp
Definition texture.cpp:178
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,...
Definition uniforms.cpp:198
representation d'une couleur (rgba) transparente ou opaque.
Definition color.h:14
representation d'une transformation, une matrice 4x4, organisee par ligne / row major.
Definition mat.h:21
Transform normal() const
renvoie la transformation a appliquer aux normales d'un objet transforme par la matrice m.
Definition mat.cpp:181
Transform inverse() const
renvoie l'inverse de la matrice.
Definition mat.cpp:399
vecteur generique, utilitaire.
Definition vec.h:152
vecteur generique, utilitaire.
Definition vec.h:169

◆ main()

int main ( int argc,
char ** argv )

Definition at line 463 of file shader_kit.cpp.

464{
465 if(argc == 1)
466 {
467 printf("usage: %s shader.glsl [mesh.obj] [texture0.png [texture1.png]]\n", argv[0]);
468 return 0;
469 }
470
471 Window window= create_window(1024, 640);
472 if(window == nullptr)
473 return 1;
474
475 Context context= create_context(window);
476 if(context == nullptr)
477 return 1;
478
479 // creation des objets opengl
480 std::vector<const char *> options(argv + 1, argv + argc);
481 if(init(options) < 0)
482 {
483 printf("[error] init failed.\n");
484 return 1;
485 }
486
487 // affichage de l'application
488 run(window, draw);
489
490 // nettoyage
491 quit();
492 release_context(context);
493 release_window(window);
494 return 0;
495}
Context create_context(Window window)
cree et configure un contexte opengl
Definition window.cpp:344
void release_window(Window window)
destruction de la fenetre.
Definition window.cpp:314
int run(Window window, int(*draw)())
boucle de gestion des evenements de l'application.
Definition window.cpp:145
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:249
void release_context(Context context)
detruit le contexte openGL.
Definition window.cpp:404
int init(std::vector< const char * > &options)

Variable Documentation

◆ program_filename

const char* program_filename

Definition at line 35 of file shader_kit.cpp.

◆ program

GLuint program

Definition at line 36 of file shader_kit.cpp.

◆ program_log

std::string program_log

Definition at line 39 of file shader_kit.cpp.

◆ program_area

int program_area

Definition at line 40 of file shader_kit.cpp.

◆ program_failed

bool program_failed

Definition at line 41 of file shader_kit.cpp.

◆ mesh_filename

const char* mesh_filename

Definition at line 43 of file shader_kit.cpp.

◆ mesh

Mesh mesh

Definition at line 44 of file shader_kit.cpp.

◆ mesh_pmin

Point mesh_pmin

Definition at line 45 of file shader_kit.cpp.

◆ mesh_pmax

Point mesh_pmax

Definition at line 46 of file shader_kit.cpp.

◆ vertex_count

int vertex_count

Definition at line 47 of file shader_kit.cpp.

◆ vao

GLuint vao

Definition at line 48 of file shader_kit.cpp.

◆ wireframe

bool wireframe = false

Definition at line 49 of file shader_kit.cpp.

◆ texture_filenames

std::vector<const char *> texture_filenames

Definition at line 51 of file shader_kit.cpp.

◆ textures

std::vector<GLuint> textures

Definition at line 52 of file shader_kit.cpp.

◆ camera

Orbiter camera

Definition at line 54 of file shader_kit.cpp.

◆ widgets

Widgets widgets

Definition at line 55 of file shader_kit.cpp.

◆ last_load

size_t last_load = 0

Definition at line 58 of file shader_kit.cpp.