gKit2 light

- Main Page
- Related Pages
- Modules
- Classes
- Files

- File List
- File Members

shader_kit.cpp
Go to the documentation of this file.
1
3
4 #include <cstdio>
5 #include <cstring>
6
7 #include "glcore.h"
8 #include "window.h"
9
10 #include "program.h"
11 #include "uniforms.h"
12
13 #include "texture.h"
14 #include "mesh.h"
15 #include "wavefront.h"
16 #include "buffer.h"
17
18 #include "vec.h"
19 #include "mat.h"
20 #include "orbiter.h"
21
22 #include "text.h"
23 #include "widgets.h"
24
25
26 // utilitaire
27 struct Filename
28 {
29 char path[1024];
30
31 Filename( ) { path[0]= 0; }
32 Filename( const char *_filename ) { strcpy(path, _filename); }
33 operator const char *( ) { return path; }
34 };
35
36 // program
37 Filename program_filename;
38 GLuint program;
39
40 // affichage des erreurs
41 std::string program_log;
42 int program_area;
43 bool program_failed;
44
45 Filename mesh_filename;
46 Mesh mesh;
47 Point mesh_pmin;
48 Point mesh_pmax;
49 int vertex_count;
50 GLuint vao;
51 bool wireframe= false;
52
53 std::vector<Filename> texture_filenames;
54 std::vector<GLuint> textures;
55
56 Orbiter camera;
57 Widgets widgets;
58
59 // application
60 void reload_program( )
61 {
62 if(program == 0)
63 program= read_program(program_filename);
64 else
65 reload_program(program, program_filename);
66
67 // recupere les erreurs, si necessaire
68 program_area= program_format_errors(program, program_log);
69
70 if(program_log.size() > 0)
71 printf("[boom]\n%s\n", program_log.c_str());
72
73 program_failed= (program_log.size() > 0);
74 }
75
76
77 // cherche un fichier avec l'extension ext dans les options
78 const char *option_find( std::vector<const char *>& options, const char *ext )
79 {
80 for(unsigned int i= 0; i < (unsigned int) options.size() ; i++)
81 {
82 if(std::string(options[i]).rfind(ext) != std::string::npos)
83 {
84 const char *option= options[i];
85 options[i]= options.back();
86 options.pop_back();
87 return option;
88 }
89 }
90
91 return NULL;
92 }
93
96 int init( std::vector<const char *>& options )
97 {
98 widgets= create_widgets();
99 camera= Orbiter();
100
101 program= 0;
102 const char *option;
103 option= option_find(options, ".glsl");
104 if(option != NULL)
105 {
106 program_filename= Filename(option);
107 reload_program();
108 }
109
110 glGenVertexArrays(1, &vao);
111 vertex_count= 3;
112
113 option= option_find(options, ".obj");
114 if(option != NULL)
115 {
116 mesh= read_mesh(option);
117 if(mesh.vertex_buffer_size() > 0)
118 {
119 mesh_filename= Filename(option);
120
121 vao= mesh.create_buffers();
122 vertex_count= mesh.vertex_count();
123
124 mesh.bounds(mesh_pmin, mesh_pmax);
125 camera.lookat(mesh_pmin, mesh_pmax);
126 }
127 }
128
129 // charge les textures, si necessaire
130 for(unsigned int i= 0; i < (unsigned int) options.size(); i++)
131 {
132 GLuint texture= read_texture(0, options[i]);
133 if(texture > 0)
134 {
135 texture_filenames.push_back(Filename(options[i]));
136 textures.push_back(texture);
137 }
138 }
139
140 // nettoyage
141 glUseProgram(0);
142 glBindTexture(GL_TEXTURE_2D, 0);
143 glBindVertexArray(0);
144 glBindBuffer(GL_ARRAY_BUFFER, 0);
145 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
146
147 // etat openGL par defaut
148 glClearColor(0.2f, 0.2f, 0.2f, 1.f);
149 glClearDepth(1.f);
150
151 glCullFace(GL_BACK);
152 glFrontFace(GL_CCW);
153 //~ glEnable(GL_CULL_FACE); // n'affiche que les faces correctement orientees...
154 glDisable(GL_CULL_FACE); // les faces mal orientees sont affichees avec des hachures oranges...
155
156 glDepthFunc(GL_LESS);
157 glEnable(GL_DEPTH_TEST);
158
159 return 0;
160 }
161
162 int quit( )
163 {
164 // detruit les objets openGL
165 release_widgets(widgets);
166 release_program(program);
167 release_vertex_format(vao);
168 for(unsigned int i= 0; i < (unsigned int) textures.size(); i++)
169 glDeleteTextures(1, &textures[i]);
170 return 0;
171 }
172
173 int draw( void )
174 {
175
176 if(wireframe)
177 {
178 glClearColor(1, 1, 1, 1);
179 glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
180 glLineWidth(2);
181 }
182 else
183 {
184 glClearColor(0.2f, 0.2f, 0.2f, 1);
185 glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
186 }
187
188 // effacer l'image
189 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
190
191 if(key_state('r'))
192 {
193 clear_key_state('r');
194 reload_program();
195 }
196
197 // recupere les mouvements de la souris
198 int mx, my;
199 unsigned int mb= SDL_GetRelativeMouseState(&mx, &my);
200 int mousex, mousey;
201 SDL_GetMouseState(&mousex, &mousey);
202
203 // deplace la camera
204 if(mb & SDL_BUTTON(1))
205 camera.rotation(mx, my); // tourne autour de l'objet
206 else if(mb & SDL_BUTTON(2))
207 camera.translation((float) mx / (float) window_width(), (float) my / (float) window_height()); // deplace le point de rotation
208 else if(mb & SDL_BUTTON(3))
209 camera.move(mx); // approche / eloigne l'objet
210
211 // recupere les transformations
212 Transform model= Identity();
213 Transform view= camera.view();
214 Transform projection= camera.projection(window_width(), window_height(), 45);
215 Transform viewport= Viewport(window_width(), window_height());
216
217 Transform mvp= projection * view * model;
218 Transform mvpInv= Inverse(mvp);
219 Transform mv= model * view;
220
221 // affiche l'objet
222 if(program_failed == false)
223 {
224 if(key_state('w'))
225 {
226 clear_key_state('w');
227 wireframe= !wireframe;
228 }
229
230 // configuration minimale du pipeline
231 glBindVertexArray(vao);
232 glUseProgram(program);
233
234 // affecte une valeur aux uniforms
235 // transformations standards
236 program_uniform(program, "modelMatrix", model);
237 program_uniform(program, "modelInvMatrix", model.inverse());
238 program_uniform(program, "viewMatrix", view);
239 program_uniform(program, "viewInvMatrix", view.inverse());
240 program_uniform(program, "projectionMatrix", projection);
241 program_uniform(program, "projectionInvMatrix", projection.inverse());
242 program_uniform(program, "viewportMatrix", viewport);
243 program_uniform(program, "viewportInvMatrix", viewport.inverse());
244
245 program_uniform(program, "mvpMatrix", mvp);
246 program_uniform(program, "mvpInvMatrix", mvpInv);
247
248 program_uniform(program, "mvMatrix", mv);
249 program_uniform(program, "normalMatrix", mv.normal());
250
251 // interactions
252 program_uniform(program, "viewport", vec2(window_width(), window_height()));
253 program_uniform(program, "time", (float) SDL_GetTicks());
254 program_uniform(program, "motion", vec3(mx, my, mb & SDL_BUTTON(1)));
255 program_uniform(program, "mouse", vec3(mousex, mousey, mb & SDL_BUTTON(1)));
256
257 // textures
258 for(unsigned int i= 0; i < (unsigned int) textures.size(); i++)
259 {
260 char uniform[1024];
261 sprintf(uniform, "texture%d", i);
262 program_use_texture(program, uniform, i, textures[i]);
263 }
264
265 // go
266 glDrawArrays(GL_TRIANGLES, 0, vertex_count);
267 }
268
269 // affiche les infos
270 begin(widgets);
271 if(program_failed)
272 {
273 label(widgets, "[error] program '%s'", program_filename.path);
274 begin_line(widgets);
275 text_area(widgets, 20, program_log.c_str(), program_area);
276 }
277 else
278 {
279 label(widgets, "program '%s' running...", program_filename.path);
280 if(mesh_filename[0] != 0)
281 {
282 begin_line(widgets);
283 label(widgets, "mesh '%s', %d vertices %s %s", mesh_filename.path, mesh.vertex_count(),
284 mesh.texcoord_buffer_size() ? "texcoords" : "", mesh.normal_buffer_size() ? "normals" : "");
285 }
286 for(unsigned int i= 0; i < (unsigned int) texture_filenames.size(); i++)
287 {
288 begin_line(widgets);
289 label(widgets, "texture%u '%s'", i, texture_filenames[i].path);
290 }
291 }
292
293 end(widgets);
294
295 draw(widgets, window_width(), window_height());
296
297
298 if(key_state('s'))
299 {
300 clear_key_state('s');
301 screenshot("shader_kit.png");
302 }
303
304 static bool video= false;
305 if(key_state(SDLK_RETURN))
306 {
307 clear_key_state(SDLK_RETURN);
308 video= !video;
309
310 if(video)
311 printf("start video capture...\n");
312 else
313 printf("stop video capture.\n");
314 }
315 if(video)
316 capture("shader_kit");
317
318 if(key_state('c'))
319 {
320 clear_key_state('c');
321 camera.write_orbiter("orbiter.txt");
322 }
323 if(key_state('v'))
324 {
325 clear_key_state('v');
326 if(camera.read_orbiter("orbiter.txt") < 0)
327 camera= Orbiter(mesh_pmin, mesh_pmax);
328 }
329
330 return 1;
331 }
332
333
334 int main( int argc, char **argv )
335 {
336 if(argc == 1)
337 {
338 printf("usage: %s shader.glsl [mesh.obj] [texture0.png [texture1.png]]\n", argv[0]);
339 return 0;
340 }
341
342 Window window= create_window(1024, 640);
343 if(window == NULL)
344 return 1;
345
346 Context context= create_context(window);
347 if(context == NULL)
348 return 1;
349
350 // creation des objets opengl
351 std::vector<const char *> options(argv + 1, argv + argc);
352 if(init(options) < 0)
353 {
354 printf("[error] init failed.\n");
355 return 1;
356 }
357
358 // affichage de l'application
359 run(window, draw);
360
361 // nettoyage
362 quit();
363 release_context(context);
364 release_window(window);
365 return 0;
366 }
create_context
Context create_context(Window window, const int major, const int minor)
cree et configure un contexte opengl
Definition: window.cpp:251
Orbiter
representation de la camera, type orbiter, placee sur une sphere autour du centre de l'objet...
Definition: orbiter.h:16
window.h
Widgets
Definition: widgets.h:66
end
void end(Widgets &w)
termine la description des elements de l'interface graphique.
Definition: widgets.cpp:363
uniforms.h
Mesh::bounds
void bounds(Point &pmin, Point &pmax)
renvoie min et max les coordonnees des extremites des positions des sommets de l'objet (boite engloba...
Definition: mesh.cpp:146
Transform::inverse
Transform inverse() const
renvoie l'inverse de la matrice.
Definition: mat.cpp:260
vec3
vecteur generique, utilitaire.
Definition: vec.h:104
text.h
Transform::normal
Transform normal() const
renvoie la transformation a appliquer aux normales d'un objet transforme par la matrice m...
Definition: mat.cpp:94
vec2
vecteur generique, utilitaire.
Definition: vec.h:94
mesh.h
Mesh::normal_buffer_size
std::size_t normal_buffer_size() const
renvoie la longueur (en octets) du normal buffer.
Definition: mesh.h:204
clear_key_state
void clear_key_state(const SDL_Keycode key)
desactive une touche du clavier.
Definition: window.cpp:30
Mesh
representation d'un objet / maillage.
Definition: mesh.h:87
Orbiter::move
void move(const float z)
rapproche / eloigne la camera du centre.
Definition: orbiter.cpp:31
release_vertex_format
void release_vertex_format(const GLuint vao)
detruit le vertex array vao et les buffers associes, crees par make_vertex_buffer() et make_index_buf...
Definition: buffer.cpp:31
init
int init(std::vector< const char * > &options)
Definition: shader_kit.cpp:96
create_widgets
Widgets create_widgets()
cree une interface graphique. a detruire avec release_widgets( ).
Definition: widgets.cpp:12
Identity
Transform Identity()
construit la transformation identite.
Definition: mat.cpp:100
Mesh::vertex_buffer_size
std::size_t vertex_buffer_size() const
renvoie la longueur (en octets) du vertex buffer.
Definition: mesh.h:199
texture.h
Mesh::create_buffers
GLuint create_buffers(const bool use_texcoord=true, const bool use_normal=true, const bool use_color=true)
Definition: mesh.cpp:189
Viewport
Transform Viewport(const float width, const float height)
renvoie la matrice representant une transformation viewport.
Definition: mat.cpp:218
program.h
program_uniform
void program_uniform(const GLuint program, const char *uniform, const unsigned int v)
affecte une valeur a un uniform du shader program. uint.
Definition: uniforms.cpp:54
program_use_texture
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 filtrages...
Definition: uniforms.cpp:104
Orbiter::view
Transform view() const
renvoie la transformation vue.
Definition: orbiter.cpp:38
window_width
int window_width()
renvoie la largeur de la fenetre de l'application.
Definition: window.cpp:14
capture
int capture(const char *prefix)
Definition: texture.cpp:125
Inverse
Transform Inverse(const Transform &m)
renvoie l'inverse de la matrice.
Definition: mat.cpp:110
read_texture
GLuint read_texture(const int unit, const char *filename)
cree une texture a partir d'un fichier filename. a detruire avec glDeleteTextures( )...
Definition: texture.cpp:97
Orbiter::read_orbiter
int read_orbiter(const char *filename)
relit la position de l'orbiter depuis un fichier texte.
Definition: orbiter.cpp:77
mat.h
widgets.h
Orbiter::projection
Transform projection(const float width, const float height, const float fov) const
renvoie la projection reglee pour une image d'aspect width / height, et une ouverture de fov degres...
Definition: orbiter.cpp:45
text_area
void text_area(Widgets &w, const int height, const char *text, int &begin_line)
Definition: widgets.cpp:232
release_widgets
void release_widgets(Widgets &w)
detruit l'interface graphique.
Definition: widgets.cpp:23
Orbiter::lookat
void lookat(const Point &center, const float size)
observe le point center a une distance size.
Definition: orbiter.cpp:6
create_window
Window create_window(const int w, const int h)
creation d'une fenetre pour l'application.
Definition: window.cpp:187
read_program
GLuint read_program(const char *filename, const char *definitions)
Definition: program.cpp:150
key_state
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:24
Mesh::texcoord_buffer_size
std::size_t texcoord_buffer_size() const
renvoie la taille (en octets) du texcoord buffer.
Definition: mesh.h:209
Orbiter::translation
void translation(const float x, const float y)
deplace le centre / le point observe.
Definition: orbiter.cpp:25
program_format_errors
int program_format_errors(const GLuint program, std::string &errors)
renvoie les erreurs de compilation.
Definition: program.cpp:257
begin
void begin(Widgets &w)
debut de la description des elements de l'interface graphique.
Definition: widgets.cpp:29
printf
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
buffer.h
wavefront.h
begin_line
void begin_line(Widgets &w)
place les prochains elements sur une nouvelle ligne.
Definition: widgets.cpp:129
Orbiter::rotation
void rotation(const float x, const float y)
change le point de vue / la direction d'observation.
Definition: orbiter.cpp:19
window_height
int window_height()
renvoie la hauteur de la fenetre de l'application.
Definition: window.cpp:18
Transform
representation d'une transformation, une matrice 4x4, organisee par ligne / row major.
Definition: mat.h:20
release_program
int release_program(const GLuint program)
detruit les shaders et le program.
Definition: program.cpp:157
release_context
void release_context(Context context)
detruit le contexte openGL.
Definition: window.cpp:305
Point
representation d'un point 3d.
Definition: vec.h:19
Mesh::vertex_count
int vertex_count() const
renvoie le nombre de sommets.
Definition: mesh.h:192
Filename
Definition: shader_kit.cpp:27
label
void label(Widgets &w, const char *format,...)
cree un texte. meme fonctionnement que printf().
Definition: widgets.cpp:142
Orbiter::write_orbiter
int write_orbiter(const char *filename)
enregistre la position de l'orbiter dans un fichier texte.
Definition: orbiter.cpp:108
screenshot
int screenshot(const char *filename)
enregistre le contenu de la fenetre dans un fichier filename nom de l'image a ecrire. doit etre de type .png / .bmp
Definition: texture.cpp:104
orbiter.h
release_window
void release_window(Window window)
destruction de la fenetre.
Definition: window.cpp:222
run
int run(Window window, int(*draw)(void))
fonction principale. gestion des evenements et appel de la fonction draw de l'application.
vec.h
read_mesh
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