34 const char *program_filename;
38 std::string program_log;
42 const char *mesh_filename;
48 bool wireframe=
false;
50 std::vector<const char *> texture_filenames;
51 std::vector<GLuint> textures;
58 void reload_program( )
63 reload_program(program, program_filename);
66 last_load= timestamp(program_filename);
71 if(program_log.size() > 0)
72 printf(
"[boom]\n%s\n", program_log.c_str());
74 program_failed= (program_log.size() > 0);
79 const char *option_find( std::vector<const char *>& options,
const char *ext )
81 for(
unsigned int i= 0; i < (
unsigned int) options.size() ; i++)
83 if(options[i] !=
nullptr && std::string(options[i]).rfind(ext) != std::string::npos)
85 const char *option= options[i];
96 int init( std::vector<const char *>& options )
103 option= option_find(options,
".glsl");
104 if(option !=
nullptr)
106 program_filename= option;
114 option= option_find(options,
".obj");
115 if(option !=
nullptr)
120 mesh_filename= option;
122 vao= mesh.
create_buffers(mesh.has_texcoord(), mesh.has_normal(), mesh.has_color(), mesh.has_material_index());
125 mesh.
bounds(mesh_pmin, mesh_pmax);
126 camera.
lookat(mesh_pmin, mesh_pmax);
134 glGenVertexArrays(1, &vao);
139 for(
int i= 0; i < int(options.size()); i++)
141 if(options[i] ==
nullptr)
147 texture_filenames.push_back(options[i]);
148 textures.push_back(texture);
154 glBindTexture(GL_TEXTURE_2D, 0);
155 glBindVertexArray(0);
156 glBindBuffer(GL_ARRAY_BUFFER, 0);
157 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
160 glClearColor(0.2f, 0.2f, 0.2f, 1.f);
166 glDisable(GL_CULL_FACE);
168 glDepthFunc(GL_LESS);
169 glEnable(GL_DEPTH_TEST);
181 glDeleteTextures(textures.size(), textures.data());
189 glClearColor(1, 1, 1, 1);
190 glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
195 glClearColor(0.2f, 0.2f, 0.2f, 1);
196 glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
200 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
203 static float last_time= 0;
207 if(timestamp(program_filename) != last_load)
224 unsigned int mb= SDL_GetRelativeMouseState(&mx, &my);
226 SDL_GetMouseState(&mousex, &mousey);
229 if(mb & SDL_BUTTON(1))
231 else if(mb & SDL_BUTTON(3))
233 else if(mb & SDL_BUTTON(2))
240 camera.
move(8.f * wheel.y);
244 static float time= 0;
246 static int zbuffer= 0;
248 static int freeze= 0;
249 static int reset_camera= 0;
250 static int copy_camera= 0;
251 static int paste_camera= 0;
259 Transform mvp= projection * view * model;
267 freeze= (freeze+1) % 2;
273 if(program_failed ==
false)
278 wireframe= !wireframe;
282 glBindVertexArray(vao);
283 glUseProgram(program);
310 for(
unsigned i= 0; i < textures.size(); i++)
313 sprintf(uniform,
"texture%u", i);
318 glDrawArrays(GL_TRIANGLES, 0, vertex_count);
326 label(widgets,
"[error] program '%s'", program_filename);
328 text_area(widgets, 20, program_log.c_str(), program_area);
332 button(widgets,
"[s] screenshot ", frame);
333 button(widgets,
"[z] depth screenshot", zbuffer);
334 button(widgets,
"capture frames", video);
336 button(widgets,
"[t] freeze time", freeze);
337 button(widgets,
"[f] reset camera", reset_camera);
338 button(widgets,
"[c] copy/save camera", copy_camera);
339 button(widgets,
"[v] paste/read camera", paste_camera);
343 label(widgets,
"program '%s' running...", program_filename);
344 if(mesh_filename && mesh_filename[0])
347 label(widgets,
"mesh '%s', %d vertices %s %s", mesh_filename, mesh.
vertex_count(),
350 for(
unsigned i= 0; i < texture_filenames.size(); i++)
353 label(widgets,
"texture%u '%s'", i, texture_filenames[i]);
369 printf(
"zbuffer screenshot...\n");
373 std::vector<float> tmp(image.width() * image.height());
375 glReadBuffer(GL_BACK);
376 glReadPixels(0, 0, image.width(), image.height(), GL_DEPTH_COMPONENT, GL_FLOAT, tmp.data());
379 for(
unsigned i= 0; i < image.size(); i++)
380 image(i)=
Color(tmp[i]);
386 for(
int py= 0; py < image.height(); py++)
387 for(
int px= 0; px < image.width(); px++)
389 int i= py * image.width() + px;
390 Point fragment=
Point(
float(px) +
float(0.5),
float(py) +
float(0.5), tmp[i]);
391 Point p= inv( fragment );
393 image(i)=
Color(p.z);
399 for(
unsigned i= 0; i < image.size(); i++)
400 image(i)=
Color(std::abs(image(i).r));
414 printf(
"screenshot %d...\n", calls);
434 camera.
lookat(mesh_pmin, mesh_pmax);
444 camera.
lookat(mesh_pmin, mesh_pmax);
451 int main(
int argc,
char **argv )
455 printf(
"usage: %s shader.glsl [mesh.obj] [texture0.png [texture1.png]]\n", argv[0]);
460 if(window ==
nullptr)
464 if(context ==
nullptr)
468 std::vector<const char *> options(argv + 1, argv + argc);
469 if(
init(options) < 0)
471 printf(
"[error] init failed.\n");
representation d'une image.
representation d'un objet / maillage.
std::size_t texcoord_buffer_size() const
renvoie la taille (en octets) du texcoord buffer.
GLuint create_buffers(const bool use_texcoord, const bool use_normal, const bool use_color, const bool use_material_index)
construit les buffers et le vertex array object necessaires pour dessiner l'objet avec openGL....
void bounds(Point &pmin, Point &pmax) const
renvoie min et max les coordonnees des extremites des positions des sommets de l'objet (boite engloba...
int vertex_count() const
renvoie le nombre de sommets.
void release()
detruit les objets openGL.
std::size_t normal_buffer_size() const
renvoie la longueur (en octets) du normal buffer.
representation de la camera, type orbiter, placee sur une sphere autour du centre de l'objet.
void lookat(const Point ¢er, const float size)
observe le point center a une distance size.
int read_orbiter(const char *filename)
relit la position de l'orbiter depuis un fichier texte.
void move(const float z)
rapproche / eloigne la camera du centre.
Transform projection(const int width, const int height, const float fov)
fixe la projection reglee pour une image d'aspect width / height, et une demi ouverture de fov degres...
void translation(const float x, const float y)
deplace le centre / le point observe.
void rotation(const float x, const float y)
change le point de vue / la direction d'observation.
int write_orbiter(const char *filename)
enregistre la position de l'orbiter dans un fichier texte.
Transform view() const
renvoie la transformation vue.
void begin(Widgets &w)
debut de la description des elements de l'interface graphique.
Widgets create_widgets()
cree une interface graphique. a detruire avec release_widgets( ).
void release_widgets(Widgets &w)
detruit l'interface graphique.
Context create_context(Window window)
cree et configure un contexte opengl
bool button(Widgets &w, const char *text, int &status)
void label(Widgets &w, const char *format,...)
cree un texte. meme fonctionnement que printf().
int window_height()
renvoie la hauteur de la fenetre de l'application.
void release_window(Window window)
destruction de la fenetre.
void clear_key_state(const SDL_Keycode key)
desactive une touche du clavier.
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().
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.
void release_context(Context context)
detruit le contexte openGL.
void clear_wheel_event()
desactive l'evenement.
void end(Widgets &w)
termine la description des elements de l'interface graphique.
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.
Vector normalize(const Vector &v)
renvoie un vecteur unitaire / longueur == 1.
Mesh read_mesh(const char *filename)
charge un fichier wavefront .obj et renvoie un mesh compose de triangles non indexes....
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
GLuint read_program(const char *filename, const char *definitions)
void program_uniform(const GLuint program, const char *uniform, const std::vector< unsigned > &v)
affecte un tableau de valeurs a un uniform du shader program.
int release_program(const GLuint program)
detruit les shaders et le program.
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,...
GLuint read_texture(const int unit, const char *filename, const GLenum texel_type)
int program_format_errors(const GLuint program, std::string &errors)
renvoie les erreurs de compilation.
int write_image_pfm(const Image &image, const char *filename)
enregistre une image dans un fichier .pfm.
int init(std::vector< const char * > &options)
representation d'une couleur (rgba) transparente ou opaque.
representation d'un point 3d.
representation d'un vecteur 3d.
vecteur generique, utilitaire.
vecteur generique, utilitaire.
int run(Window window, int(*draw)())
boucle de gestion des evenements de l'application.