gKit2 light
Loading...
Searching...
No Matches
DrawInstanceBuffer Class Reference
Inheritance diagram for DrawInstanceBuffer:

Public Member Functions

int init ()
 a deriver pour creer les objets openGL. renvoie -1 pour indiquer une erreur, 0 sinon.
int quit ()
 a deriver pour detruire les objets openGL. renvoie -1 pour indiquer une erreur, 0 sinon.
int update (const float time, const float delta)
 a deriver et redefinir pour animer les objets en fonction du temps.
int render ()
 a deriver pour afficher les objets. renvoie 1 pour continuer, 0 pour fermer l'application.
int init ()
 a deriver pour creer les objets openGL. renvoie -1 pour indiquer une erreur, 0 sinon.
int quit ()
 a deriver pour detruire les objets openGL. renvoie -1 pour indiquer une erreur, 0 sinon.
int update (const float time, const float delta)
 a deriver et redefinir pour animer les objets en fonction du temps.
int render ()
 a deriver pour afficher les objets. renvoie 1 pour continuer, 0 pour fermer l'application.
Public Member Functions inherited from App
 App (const int width, const int height, const int major=3, const int minor=3)
 constructeur, dimensions de la fenetre et version d'openGL.
int run ()
 execution de l'application.
Public Member Functions inherited from AppTime
 AppTime (const int width, const int height, const int major=3, const int minor=3)
 constructeur, dimensions de la fenetre et version d'openGL.

Protected Attributes

Transform m_model
Orbiter m_camera
GLuint m_vao
GLuint m_buffer
GLuint m_instance_buffer
GLuint m_program
int m_vertex_count
int m_instance_count
std::vector< vec3m_positions
GLuint m_vao_storage
GLuint m_instance_storage
void * m_storage
Protected Attributes inherited from App
Window m_window
Context m_context
bool sync
Protected Attributes inherited from AppTime
std::chrono::high_resolution_clock::time_point m_cpu_start
std::chrono::high_resolution_clock::time_point m_cpu_stop
GLuint m_time_query [MAX_FRAMES]
GLint64 m_frame_time
int m_frame
Text m_console

Additional Inherited Members

Protected Member Functions inherited from App
void vsync_off ()
Protected Member Functions inherited from AppTime
virtual int prerender ()
virtual int postrender ()

Detailed Description

Definition at line 20 of file tuto6GL_buffer.cpp.

Constructor & Destructor Documentation

◆ DrawInstanceBuffer() [1/2]

DrawInstanceBuffer::DrawInstanceBuffer ( )
inline

Definition at line 24 of file tuto6GL_buffer.cpp.

24: App(1024, 640) {}
App(const int width, const int height, const int major=3, const int minor=3)
constructeur, dimensions de la fenetre et version d'openGL.
Definition app.cpp:11

◆ DrawInstanceBuffer() [2/2]

DrawInstanceBuffer::DrawInstanceBuffer ( )
inline

Definition at line 25 of file tuto_stream.cpp.

25: AppTime(1024, 640, 4,4) {}
AppTime(const int width, const int height, const int major=3, const int minor=3)
constructeur, dimensions de la fenetre et version d'openGL.
Definition app_time.cpp:8

Member Function Documentation

◆ init() [1/2]

int DrawInstanceBuffer::init ( )
inlinevirtual

a deriver pour creer les objets openGL. renvoie -1 pour indiquer une erreur, 0 sinon.

Implements App.

Definition at line 26 of file tuto6GL_buffer.cpp.

27 {
28 // charge un mesh
29 Mesh mesh= read_mesh("data/cube.obj");
30 if(mesh.vertex_count() == 0)
31 return -1;
32
33 Point pmin, pmax;
34 mesh.bounds(pmin, pmax);
35 m_camera.lookat(pmin - Vector(40, 40, 40), pmax + Vector(40, 40, 40));
36
37 m_vertex_count= mesh.vertex_count();
38
39 // cree les buffers et le vao
40 glGenVertexArrays(1, &m_vao);
41 glBindVertexArray(m_vao);
42
43 // buffer : positions + normals
44 glGenBuffers(1, &m_buffer);
45 glBindBuffer(GL_ARRAY_BUFFER, m_buffer);
46
47 size_t size= mesh.vertex_buffer_size() + mesh.normal_buffer_size();
48 glBufferData(GL_ARRAY_BUFFER, size, nullptr, GL_STATIC_DRAW);
49
50 // transfere les positions des sommets
51 size_t offset= 0;
52 size= mesh.vertex_buffer_size();
53 glBufferSubData(GL_ARRAY_BUFFER, offset, size, mesh.vertex_buffer());
54 // configure l'attribut 0, vec3 position
55 glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, /* stride */ 0, (const GLvoid *) offset);
56 glEnableVertexAttribArray(0);
57
58 // transfere les normales des sommets
59 offset= offset + size;
60 size= mesh.normal_buffer_size();
61 glBufferSubData(GL_ARRAY_BUFFER, offset, size, mesh.normal_buffer());
62 // configure l'attribut 2, vec3 normal
63 glVertexAttribPointer(2, 3, GL_FLOAT, GL_FALSE, /* stride */ 0, (const GLvoid *) offset);
64 glEnableVertexAttribArray(2);
65
66
67 // instance buffer, position aleatoire des cubes...
68 srand(time(NULL));
69
70 std::vector<vec3> positions;
71 for(int i= 0; i < 50; i++)
72 {
73 float x= rand() % 11 - 5;
74 float y= rand() % 11 - 5;
75 float z= rand() % 11 - 5;
76
77 positions.push_back(vec3(x *4, y *4, z *4));
78 }
79
80 m_instance_count= (int) positions.size();
81
82 // cree et initialise le buffer d'instance
83 glGenBuffers(1, &m_instance_buffer);
84 glBindBuffer(GL_ARRAY_BUFFER, m_instance_buffer);
85 glBufferData(GL_ARRAY_BUFFER, sizeof(vec3) * positions.size(), &positions.front().x, GL_STATIC_DRAW);
86
87 // configure le vao pour l'attribut d'instance
88 // configure l'attribut 1, vec3 instance_position
89 glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, /* stride */ 0, /* offset */ 0);
90 glVertexAttribDivisor(1, 1); // !! c'est la seule difference entre un attribut de sommet et un attribut d'instance !!
91 glEnableVertexAttribArray(1);
92
93 //
94 mesh.release();
95 glBindVertexArray(0);
96 glBindBuffer(GL_ARRAY_BUFFER, 0);
97
98 // shaders
99 m_program= read_program("gkit2_tutos/instance_buffer.glsl");
100 program_print_errors(m_program);
101
102
103 // etat openGL par defaut
104 glClearColor(0.2f, 0.2f, 0.2f, 1.f); // couleur par defaut de la fenetre
105
106 glClearDepth(1.f); // profondeur par defaut
107 glDepthFunc(GL_LESS); // ztest, conserver l'intersection la plus proche de la camera
108 glEnable(GL_DEPTH_TEST); // activer le ztest
109
110 return 0; // ras, pas d'erreur
111 }
const float * vertex_buffer() const
renvoie l'adresse de la position du premier sommet. permet de construire les vertex buffers openGL....
Definition mesh.h:305
void bounds(Point &pmin, Point &pmax) const
renvoie min et max les coordonnees des extremites des positions des sommets de l'objet (boite engloba...
Definition mesh.cpp:489
std::size_t vertex_buffer_size() const
renvoie la longueur (en octets) du vertex buffer.
Definition mesh.h:307
int vertex_count() const
renvoie le nombre de sommets.
Definition mesh.h:300
void release()
detruit les objets openGL.
Definition mesh.cpp:50
const float * normal_buffer() const
renvoie l'adresse de la normale du premier sommet. par convention, la normale est un vec3,...
Definition mesh.h:310
std::size_t normal_buffer_size() const
renvoie la longueur (en octets) du normal buffer.
Definition mesh.h:312
Mesh read_mesh(const char *filename)
charge un fichier wavefront .obj et renvoie un mesh compose de triangles non indexes....
Definition wavefront.cpp:14
GLuint read_program(const char *filename, const char *definitions)
Definition program.cpp:217
int program_print_errors(const GLuint program, const char *filename)
affiche les erreurs de compilation.
Definition program.cpp:461

◆ quit() [1/2]

int DrawInstanceBuffer::quit ( )
inlinevirtual

a deriver pour detruire les objets openGL. renvoie -1 pour indiquer une erreur, 0 sinon.

Implements App.

Definition at line 114 of file tuto6GL_buffer.cpp.

115 {
116 release_program(m_program);
117 glDeleteVertexArrays(1, &m_vao);
118 glDeleteBuffers(1, &m_buffer);
119 glDeleteBuffers(1, &m_instance_buffer);
120 return 0;
121 }
int release_program(const GLuint program)
detruit les shaders et le program.
Definition program.cpp:240

◆ update() [1/2]

int DrawInstanceBuffer::update ( const float time,
const float delta )
inlinevirtual

a deriver et redefinir pour animer les objets en fonction du temps.

Reimplemented from App.

Definition at line 123 of file tuto6GL_buffer.cpp.

124 {
125 m_model= RotationY(time / 20);
126 return 0;
127 }
Transform RotationY(const float a)
renvoie la matrice representation une rotation de a degree autour de l'axe Y.
Definition mat.cpp:242

◆ render() [1/2]

int DrawInstanceBuffer::render ( )
inlinevirtual

a deriver pour afficher les objets. renvoie 1 pour continuer, 0 pour fermer l'application.

Implements App.

Definition at line 130 of file tuto6GL_buffer.cpp.

131 {
132 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
133
134 // deplace la camera
135 int mx, my;
136 unsigned int mb= SDL_GetRelativeMouseState(&mx, &my);
137 if(mb & SDL_BUTTON(1)) // le bouton gauche est enfonce
138 m_camera.rotation(mx, my);
139 else if(mb & SDL_BUTTON(3)) // le bouton droit est enfonce
140 m_camera.move(mx);
141 else if(mb & SDL_BUTTON(2)) // le bouton du milieu est enfonce
142 m_camera.translation((float) mx / (float) window_width(), (float) my / (float) window_height());
143
144 glBindVertexArray(m_vao);
145 glUseProgram(m_program);
146
147 Transform m= m_model;
148 Transform v= m_camera.view();
149 Transform p= m_camera.projection(window_width(), window_height(), 45);
150 Transform mvp= p * v * m;
151 Transform mv= v * m;
152
153 program_uniform(m_program, "mvpMatrix", mvp);
154 program_uniform(m_program, "normalMatrix", mv.normal());
155
156 glDrawArraysInstanced(GL_TRIANGLES, 0, m_vertex_count, m_instance_count);
157
158 return 1;
159 }
int window_height()
renvoie la hauteur de la fenetre de l'application.
Definition window.cpp:27
int window_width()
renvoie la largeur de la fenetre de l'application.
Definition window.cpp:23
Transform normal() const
renvoie la transformation a appliquer aux normales d'un objet transforme par la matrice m.
Definition mat.cpp:181

◆ init() [2/2]

int DrawInstanceBuffer::init ( )
inlinevirtual

a deriver pour creer les objets openGL. renvoie -1 pour indiquer une erreur, 0 sinon.

Implements App.

Definition at line 27 of file tuto_stream.cpp.

28 {
29 // charge un mesh
30 Mesh mesh= read_mesh("data/cube.obj");
31 if(mesh.vertex_count() == 0)
32 return -1;
33
34 Point pmin, pmax;
35 mesh.bounds(pmin, pmax);
36 m_camera.lookat(pmin - Vector(40, 40, 40), pmax + Vector(40, 40, 40));
37
38 m_vertex_count= mesh.vertex_count();
39
40 // cree les buffers et le vao
41 glGenVertexArrays(1, &m_vao);
42 glBindVertexArray(m_vao);
43
44 // buffer : positions + normals
45 glGenBuffers(1, &m_buffer);
46 glBindBuffer(GL_ARRAY_BUFFER, m_buffer);
47
48 size_t size= mesh.vertex_buffer_size() + mesh.normal_buffer_size();
49 glBufferData(GL_ARRAY_BUFFER, size, nullptr, GL_STATIC_DRAW);
50
51 // transfere les positions des sommets
52 size_t offset_positions= 0;
53 size= mesh.vertex_buffer_size();
54 glBufferSubData(GL_ARRAY_BUFFER, offset_positions, size, mesh.vertex_buffer());
55 // configure l'attribut 0, vec3 position
56 glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, /* stride */ 0, (const GLvoid *) offset_positions);
57 glEnableVertexAttribArray(0);
58
59 // transfere les normales des sommets
60 size_t offset_normals= offset_positions + size;
61 size= mesh.normal_buffer_size();
62 glBufferSubData(GL_ARRAY_BUFFER, offset_normals, size, mesh.normal_buffer());
63 // configure l'attribut 2, vec3 normal
64 glVertexAttribPointer(2, 3, GL_FLOAT, GL_FALSE, /* stride */ 0, (const GLvoid *) offset_normals);
65 glEnableVertexAttribArray(2);
66
67 // remarque : oui, c'est mal et la suite montre comment le faire correctement !!
68
69 // instance buffer, position aleatoire des cubes...
70 srand(time(nullptr));
71
72 for(int i= 0; i < 1024*1024; i++)
73 {
74 float x= rand() % 256 - 128;
75 float y= rand() % 256 - 128;
76 float z= rand() % 256 - 128;
77
78 m_positions.push_back(vec3(x *4, y *4, z *4));
79 }
80
81
82 m_instance_count= int(m_positions.size());
83
84 printf("buffer %dKB\n", int(sizeof(vec3) * m_positions.size() / 1024));
85
86 // cree et initialise le buffer d'instance
87 // version openGL 3, buffer dynamique + glBufferSubData()
88 glGenBuffers(1, &m_instance_buffer);
89 glBindBuffer(GL_ARRAY_BUFFER, m_instance_buffer);
90 glBufferData(GL_ARRAY_BUFFER, sizeof(vec3) * m_positions.size(), m_positions.data(), GL_DYNAMIC_DRAW);
91
92 // configure le vao pour l'attribut d'instance
93 // configure l'attribut 1, vec3 instance_position
94 glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, /* stride */ 0, /* offset */ 0);
95 glVertexAttribDivisor(1, 1); // !! c'est la seule difference entre un attribut de sommet et un attribut d'instance !!
96 glEnableVertexAttribArray(1);
97
98 // openGL 4.4, buffer dynamique explicite + map persistant
99 glGenBuffers(1, &m_instance_storage);
100 glBindBuffer(GL_ARRAY_BUFFER, m_instance_storage);
101 glBufferStorage(GL_ARRAY_BUFFER, sizeof(vec3) * m_positions.size(), nullptr, GL_DYNAMIC_STORAGE_BIT | GL_MAP_WRITE_BIT | GL_MAP_PERSISTENT_BIT);
102
103 m_storage= glMapBufferRange(GL_ARRAY_BUFFER, 0, sizeof(vec3) * m_positions.size(),
104 GL_MAP_INVALIDATE_RANGE_BIT | GL_MAP_WRITE_BIT | GL_MAP_FLUSH_EXPLICIT_BIT | GL_MAP_PERSISTENT_BIT);
105 if(m_storage == nullptr)
106 return -1;
107
108 // cree et initialise un autre vao
109 glGenVertexArrays(1, &m_vao_storage);
110 glBindVertexArray(m_vao_storage);
111
112 glBindBuffer(GL_ARRAY_BUFFER, m_buffer);
113 glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, /* stride */ 0, (const GLvoid *) offset_positions);
114 glEnableVertexAttribArray(0);
115 glVertexAttribPointer(2, 3, GL_FLOAT, GL_FALSE, /* stride */ 0, (const GLvoid *) offset_normals);
116 glEnableVertexAttribArray(2);
117
118 glBindBuffer(GL_ARRAY_BUFFER, m_instance_storage);
119 glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, /* stride */ 0, /* offset */ 0);
120 glVertexAttribDivisor(1, 1); // !! c'est la seule difference entre un attribut de sommet et un attribut d'instance !!
121 glEnableVertexAttribArray(1);
122
123 glBindVertexArray(0);
124
125 //
126 mesh.release();
127 glBindVertexArray(0);
128 glBindBuffer(GL_ARRAY_BUFFER, 0);
129
130 // shaders
131 m_program= read_program("gkit2_tutos/instance_buffer.glsl");
132 program_print_errors(m_program);
133
134 // etat openGL par defaut
135 glClearColor(0.2f, 0.2f, 0.2f, 1.f); // couleur par defaut de la fenetre
136
137 glClearDepth(1.f); // profondeur par defaut
138 glDepthFunc(GL_LESS); // ztest, conserver l'intersection la plus proche de la camera
139 glEnable(GL_DEPTH_TEST); // activer le ztest
140
141 return 0; // ras, pas d'erreur
142 }
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

◆ quit() [2/2]

int DrawInstanceBuffer::quit ( )
inlinevirtual

a deriver pour detruire les objets openGL. renvoie -1 pour indiquer une erreur, 0 sinon.

Implements App.

Definition at line 145 of file tuto_stream.cpp.

146 {
147 release_program(m_program);
148 glDeleteVertexArrays(1, &m_vao);
149 glDeleteBuffers(1, &m_buffer);
150 glDeleteBuffers(1, &m_instance_buffer);
151 return 0;
152 }

◆ update() [2/2]

int DrawInstanceBuffer::update ( const float time,
const float delta )
inlinevirtual

a deriver et redefinir pour animer les objets en fonction du temps.

Reimplemented from App.

Definition at line 154 of file tuto_stream.cpp.

155 {
156 m_model= RotationY(time / 20);
157 return 0;
158 }

◆ render() [2/2]

int DrawInstanceBuffer::render ( )
inlinevirtual

a deriver pour afficher les objets. renvoie 1 pour continuer, 0 pour fermer l'application.

Implements App.

Definition at line 161 of file tuto_stream.cpp.

162 {
163 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
164
165 // deplace la camera
166 int mx, my;
167 unsigned int mb= SDL_GetRelativeMouseState(&mx, &my);
168 if(mb & SDL_BUTTON(1)) // le bouton gauche est enfonce
169 m_camera.rotation(mx, my);
170 else if(mb & SDL_BUTTON(3)) // le bouton droit est enfonce
171 m_camera.move(mx);
172 else if(mb & SDL_BUTTON(2)) // le bouton du milieu est enfonce
173 m_camera.translation((float) mx / (float) window_width(), (float) my / (float) window_height());
174
175 static int mode= 0;
176 if(key_state(SDLK_SPACE))
177 {
178 clear_key_state(SDLK_SPACE);
179 mode= (mode + 1) % 5;
180 printf("mode %d\n", mode);
181
182 // alterne entre les 4 solutions de transfert...
183 }
184
185 // modifie le contenu du buffer d'instances
186 if(mode == 0)
187 {
188 // strategie 1 :
189 // recreer le buffer + transferer les donnees
190 glBindBuffer(GL_ARRAY_BUFFER, m_instance_buffer);
191 glBufferData(GL_ARRAY_BUFFER, sizeof(vec3) * m_positions.size(), m_positions.data(), GL_DYNAMIC_DRAW);
192
193 glBindVertexArray(m_vao);
194 }
195 else if(mode == 1)
196 {
197 // strategie 2 :
198 // transferer les donnees
199 glBindBuffer(GL_ARRAY_BUFFER, m_instance_buffer);
200 glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(vec3) * m_positions.size(), m_positions.data());
201
202 glBindVertexArray(m_vao);
203 }
204 else if(mode == 2)
205 {
206 // strategie 3 :
207 // invalider les donnees + transfert
208 glInvalidateBufferData(m_instance_buffer);
209 glBindBuffer(GL_ARRAY_BUFFER, m_instance_buffer);
210 glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(vec3) * m_positions.size(), m_positions.data());
211
212 glBindVertexArray(m_vao);
213 }
214 else if(mode == 3)
215 {
216 // strategie 4 :
217 // persistant map + flush + barrier
218
219 std::chrono::high_resolution_clock::time_point copy_start= std::chrono::high_resolution_clock::now();
220 memcpy(m_storage, m_positions.data(), sizeof(vec3) * m_positions.size());
221
222 std::chrono::high_resolution_clock::time_point copy_stop= std::chrono::high_resolution_clock::now();
223 auto copy_time= std::chrono::duration_cast<std::chrono::microseconds>(copy_stop - copy_start).count();
224 printf("memcpy %dK %02dus = %.2fK/s\n", int(sizeof(vec3) * m_positions.size()) / 1024, int(copy_time), float(sizeof(vec3) * m_positions.size() / 1024) / (float(copy_time) / 1000000));
225
226 glBindBuffer(GL_ARRAY_BUFFER, m_instance_storage);
227 glFlushMappedBufferRange(GL_ARRAY_BUFFER, 0, sizeof(vec3) * m_positions.size());
228
229 glMemoryBarrier(GL_CLIENT_MAPPED_BUFFER_BARRIER_BIT);
230
231 glBindVertexArray(m_vao_storage);
232 }
233 else
234 {
235 // pas de modifications
236 glBindVertexArray(m_vao);
237 }
238
239 // draw
240 glUseProgram(m_program);
241
242 Transform m= m_model;
243 Transform v= m_camera.view();
244 Transform p= m_camera.projection(window_width(), window_height(), 45);
245 Transform mvp= p * v * m;
246 Transform mv= v * m;
247
248 program_uniform(m_program, "mvpMatrix", mvp);
249 program_uniform(m_program, "normalMatrix", mv.normal());
250
251 glDrawArraysInstanced(GL_TRIANGLES, 0, m_vertex_count, std::min(m_instance_count, 4096));
252
253 return 1;
254 }
void clear_key_state(const SDL_Keycode key)
desactive une touche du clavier.
Definition window.cpp:59
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:53

Member Data Documentation

◆ m_model

Transform DrawInstanceBuffer::m_model
protected

Definition at line 162 of file tuto6GL_buffer.cpp.

◆ m_camera

Orbiter DrawInstanceBuffer::m_camera
protected

Definition at line 163 of file tuto6GL_buffer.cpp.

◆ m_vao

GLuint DrawInstanceBuffer::m_vao
protected

Definition at line 164 of file tuto6GL_buffer.cpp.

◆ m_buffer

GLuint DrawInstanceBuffer::m_buffer
protected

Definition at line 165 of file tuto6GL_buffer.cpp.

◆ m_instance_buffer

GLuint DrawInstanceBuffer::m_instance_buffer
protected

Definition at line 166 of file tuto6GL_buffer.cpp.

◆ m_program

GLuint DrawInstanceBuffer::m_program
protected

Definition at line 167 of file tuto6GL_buffer.cpp.

◆ m_vertex_count

int DrawInstanceBuffer::m_vertex_count
protected

Definition at line 168 of file tuto6GL_buffer.cpp.

◆ m_instance_count

int DrawInstanceBuffer::m_instance_count
protected

Definition at line 169 of file tuto6GL_buffer.cpp.

◆ m_positions

std::vector<vec3> DrawInstanceBuffer::m_positions
protected

Definition at line 257 of file tuto_stream.cpp.

◆ m_vao_storage

GLuint DrawInstanceBuffer::m_vao_storage
protected

Definition at line 263 of file tuto_stream.cpp.

◆ m_instance_storage

GLuint DrawInstanceBuffer::m_instance_storage
protected

Definition at line 264 of file tuto_stream.cpp.

◆ m_storage

void* DrawInstanceBuffer::m_storage
protected

Definition at line 265 of file tuto_stream.cpp.


The documentation for this class was generated from the following files: