gKit2 light

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

- File List
- File Members

tuto_time.cpp
Go to the documentation of this file.
1
3
4 #include <chrono>
5
6 #include "mat.h"
7 #include "program.h"
8 #include "uniforms.h"
9 #include "wavefront.h"
10 #include "texture.h"
11
12 #include "orbiter.h"
13 #include "draw.h"
14
15 #include "app.h" // classe Application a deriver
16 #include "text.h"
17
18
19 class TP : public App
20 {
21 public:
22 TP( ) : App(1024, 640) {}
23
24 int init( )
25 {
26 // charge un objet et une texture a afficher
27 // mode 0 & 1
28 m_objet= read_mesh("data/bigguy.obj");
29 Point pmin, pmax;
30 m_objet.bounds(pmin, pmax);
31 m_camera.lookat(pmin - Vector(20, 20, 0), pmax + Vector(20, 20, 0));
32
33 m_texture= read_texture(0, "data/debug2x2red.png");
34
35 // mode 2
36 // configure le vertex array / format de sommet
37 glGenVertexArrays(1, &m_vao);
38 glBindVertexArray(m_vao);
39
40 // buffer : positions + normals
41 glGenBuffers(1, &m_vertex_buffer);
42 glBindBuffer(GL_ARRAY_BUFFER, m_vertex_buffer);
43 glBufferData(GL_ARRAY_BUFFER, m_objet.vertex_buffer_size() + m_objet.normal_buffer_size(), 0, GL_STATIC_DRAW);
44
45 // transfere les positions des sommets
46 glBufferSubData(GL_ARRAY_BUFFER, /* offset */ 0, /* size */ m_objet.vertex_buffer_size(), /* data */ m_objet.vertex_buffer());
47 // configure l'attribut 0, vec3 position
48 glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, /* stride */ 0, /* offset */ 0);
49 glEnableVertexAttribArray(0);
50
51 // transfere les normales des sommets
52 glBufferSubData(GL_ARRAY_BUFFER, /* offset */ m_objet.vertex_buffer_size(), /* size */ m_objet.normal_buffer_size(), /* data */ m_objet.normal_buffer());
53 // configure l'attribut 2, vec3 normal
54 glVertexAttribPointer(2, 3, GL_FLOAT, GL_FALSE, /* stride */ 0, /* offset */ (const GLvoid *) m_objet.vertex_buffer_size());
55 glEnableVertexAttribArray(2);
56
57 m_vertex_count= m_objet.vertex_count();
58
59 m_program= read_program("tutos/M2/instance.glsl");
60 program_print_errors(m_program);
61
62 // nettoyage
63 glBindVertexArray(0);
64 glBindBuffer(GL_ARRAY_BUFFER, 0);
65
66 // mesure du temps gpu de glDraw
67 glGenQueries(1, &m_time_query);
68
69 // affichage du temps dans la fenetre
70 m_console= create_text();
71
72 // etat openGL par defaut
73 glClearColor(0.2f, 0.2f, 0.2f, 1.f); // couleur par defaut de la fenetre
74
75 glClearDepth(1.f); // profondeur par defaut
76 glDepthFunc(GL_LESS); // ztest, conserver l'intersection la plus proche de la camera
77 glEnable(GL_DEPTH_TEST); // activer le ztest
78
79 return 0; // ras, pas d'erreur
80 }
81
82 int quit( )
83 {
84 glDeleteQueries(1, &m_time_query);
85
86 release_text(m_console);
87 m_objet.release();
88 glDeleteTextures(1, &m_texture);
89
90 return 0;
91 }
92
93 int update( const float time, const float delta )
94 {
95 m_model= RotationY(time / 20);
96 return 0;
97 }
98
99 int render( )
100 {
101 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
102
103 // deplace la camera
104 int mx, my;
105 unsigned int mb= SDL_GetRelativeMouseState(&mx, &my);
106 if(mb & SDL_BUTTON(1)) // le bouton gauche est enfonce
107 m_camera.rotation(mx, my);
108 else if(mb & SDL_BUTTON(3)) // le bouton droit est enfonce
109 m_camera.move(mx);
110 else if(mb & SDL_BUTTON(2)) // le bouton du milieu est enfonce
111 m_camera.translation((float) mx / (float) window_width(), (float) my / (float) window_height());
112
113 // mesure le temps d'execution du draw pour le gpu
114 glBeginQuery(GL_TIME_ELAPSED, m_time_query);
115
116 // mesure le temps d'execution du draw pour le cpu
117 // utilise std::chrono pour mesurer le temps cpu
118 std::chrono::high_resolution_clock::time_point cpu_start= std::chrono::high_resolution_clock::now();
119
120 static int mode= 0;
121 if(key_state(' '))
122 {
123 clear_key_state(' ');
124 mode= (mode + 1) % 3;
125 }
126
127 if(mode == 0)
128 {
129 // dessine 1 objet
130 draw(m_objet, m_model, m_camera, m_texture);
131 }
132 else if(mode == 1)
133 {
134 // dessine 25 fois l'objet sur une grille
135 for(int y= -2; y <= 2; y++)
136 for(int x= -2; x <= 2; x++)
137 {
138 Transform t= Translation(x *20, y *20, 0);
139 draw(m_objet, t * m_model, m_camera, m_texture);
140 }
141 }
142 else if(mode == 2)
143 {
144 // dessine 25 copies de l'objet sur une grille avec un seul glDrawArrayInstanced( ), c'est le vertex shader qui calcule la translation
145 // cf gl_InstanceID qui contient l'indice de la copie
146 glBindVertexArray(m_vao);
147 glUseProgram(m_program);
148
149 Transform m= m_model;
150 Transform v= m_camera.view();
151 Transform p= m_camera.projection(window_width(), window_height(), 45);
152 Transform mvp= p * v * m;
153 Transform mv= v * m;
154
155 program_uniform(m_program, "mvpMatrix", mvp);
156 program_uniform(m_program, "normalMatrix", mv.normal());
157
158 glDrawArraysInstanced(GL_TRIANGLES, 0, m_vertex_count, 25);
159 }
160
161 std::chrono::high_resolution_clock::time_point cpu_stop= std::chrono::high_resolution_clock::now();
162 // conversion desmesures en duree...
163 long long int cpu_time= std::chrono::duration_cast<std::chrono::nanoseconds>(cpu_stop - cpu_start).count();
164
165 glEndQuery(GL_TIME_ELAPSED);
166
167 /* recuperer le resultat de la requete time_elapsed, il faut attendre que le gpu ait fini de dessiner...
168 utilise encore std::chrono pour mesurer le temps d'attente.
169 */
170 std::chrono::high_resolution_clock::time_point wait_start= std::chrono::high_resolution_clock::now();
171
172 // attendre le resultat de la requete
173 GLint64 gpu_time= 0;
174 glGetQueryObjecti64v(m_time_query, GL_QUERY_RESULT, &gpu_time);
175
176 std::chrono::high_resolution_clock::time_point wait_stop= std::chrono::high_resolution_clock::now();
177 long long int wait_time= std::chrono::duration_cast<std::chrono::nanoseconds>(wait_stop - wait_start).count();
178
179 // affiche le temps mesure, et formate les valeurs... c'est un peu plus lisible.
180 clear(m_console);
181 if(mode == 0) printf(m_console, 0, 0, "mode 0 : 1 draw");
182 if(mode == 1) printf(m_console, 0, 0, "mode 1 : 25 draws");
183 if(mode == 2) printf(m_console, 0, 0, "mode 2 : 1 draw / 25 instances");
184 printf(m_console, 0, 1, "cpu %02dms %03dus", (int) (cpu_time / 1000000), (int) ((cpu_time / 1000) % 1000));
185 printf(m_console, 0, 2, "gpu %02dms %03dus", (int) (gpu_time / 1000000), (int) ((gpu_time / 1000) % 1000));
186 printf(m_console, 0, 3, "wait %02dms %03dus", (int) (wait_time / 1000000), (int) ((wait_time / 1000) % 1000));
187
188 // affiche le texte dans la fenetre de l'application, utilise console.h
189 draw(m_console, window_width(), window_height());
190
191 // affiche le temps dans le terminal
192 printf("cpu %02dms %03dus ", (int) (cpu_time / 1000000), (int) ((cpu_time / 1000) % 1000));
193 printf("gpu %02dms %03dus\n", (int) (gpu_time / 1000000), (int) ((gpu_time / 1000) % 1000));
194
195 return 1;
196 }
197
198 protected:
199 GLuint m_time_query;
200 Text m_console;
201
202 Transform m_model;
203 Mesh m_objet;
204 Orbiter m_camera;
205
206 GLuint m_texture;
207 GLuint m_program;
208 GLuint m_vao;
209 GLuint m_vertex_buffer;
210 unsigned int m_vertex_count;
211 };
212
213
214 int main( int argc, char **argv )
215 {
216 TP tp;
217 tp.run();
218
219 return 0;
220 }
Mesh::normal_buffer
const float * normal_buffer() const
renvoie l'adresse de la normale du premier sommet. par convention, la normale est un vec3...
Definition: mesh.h:200
Orbiter
representation de la camera, type orbiter, placee sur une sphere autour du centre de l'objet...
Definition: orbiter.h:16
create_text
Text create_text()
cree une console. a detruire avec release_text( ).
Definition: text.cpp:14
TP::init
int init()
a deriver pour creer les objets openGL.
Definition: tuto_time.cpp:24
draw.h
Mesh::vertex_buffer
const float * vertex_buffer() const
renvoie l'adresse de la position du premier sommet. permet de construire les vertex buffers openGL...
Definition: mesh.h:195
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:153
release_text
void release_text(Text &text)
detruit une console.
Definition: text.cpp:64
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:97
Mesh::normal_buffer_size
std::size_t normal_buffer_size() const
renvoie la longueur (en octets) du normal buffer.
Definition: mesh.h:202
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:88
Orbiter::move
void move(const float z)
rapproche / eloigne la camera du centre.
Definition: orbiter.cpp:33
TP::update
int update(const float time, const float delta)
a deriver et redefinir pour animer les objets en fonction du temps.
Definition: tuto_time.cpp:93
Mesh::vertex_buffer_size
std::size_t vertex_buffer_size() const
renvoie la longueur (en octets) du vertex buffer.
Definition: mesh.h:197
texture.h
App::run
int run()
execution de l'application.
Definition: app.cpp:21
read_texture
GLuint read_texture(const int unit, const char *filename, const GLenum texel_type)
Definition: texture.cpp:98
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:68
draw
void draw(Mesh &m, const Transform &model, const Transform &view, const Transform &projection, const GLuint texture)
applique une texture a la surface de l'objet. ne fonctionne que si les coordonnees de textures sont f...
Definition: draw.cpp:6
TP::quit
int quit()
a deriver pour detruire les objets openGL.
Definition: tuto_time.cpp:82
Orbiter::view
Transform view() const
renvoie la transformation vue.
Definition: orbiter.cpp:40
window_width
int window_width()
renvoie la largeur de la fenetre de l'application.
Definition: window.cpp:14
Vector
representation d'un vecteur 3d.
Definition: vec.h:42
Mesh::release
void release()
detruit les objets openGL.
Definition: mesh.cpp:19
mat.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:47
program_print_errors
int program_print_errors(const GLuint program)
affiche les erreurs de compilation.
Definition: program.cpp:330
Orbiter::lookat
void lookat(const Point &center, const float size)
observe le point center a une distance size.
Definition: orbiter.cpp:7
read_program
GLuint read_program(const char *filename, const char *definitions)
Definition: program.cpp:150
Text
Definition: text.h:61
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
Translation
Transform Translation(const Vector &v)
renvoie la matrice representant une translation par un vecteur.
Definition: mat.cpp:132
Orbiter::translation
void translation(const float x, const float y)
deplace le centre / le point observe.
Definition: orbiter.cpp:27
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
wavefront.h
TP
Definition: tuto7.cpp:12
Orbiter::rotation
void rotation(const float x, const float y)
change le point de vue / la direction d'observation.
Definition: orbiter.cpp:21
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
Point
representation d'un point 3d.
Definition: vec.h:19
clear
void clear(Text &text)
efface le contenu de la console.
Definition: text.cpp:72
Mesh::vertex_count
int vertex_count() const
renvoie le nombre de sommets.
Definition: mesh.h:190
app.h
TP::render
int render()
a deriver pour afficher les objets.
Definition: tuto_time.cpp:99
orbiter.h
RotationY
Transform RotationY(const float a)
renvoie la matrice representation une rotation de a degree autour de l'axe Y.
Definition: mat.cpp:158
App
classe application.
Definition: app.h:20
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