40 glGenVertexArrays(1, &m_vao);
41 glBindVertexArray(m_vao);
44 glGenBuffers(1, &m_buffer);
45 glBindBuffer(GL_ARRAY_BUFFER, m_buffer);
48 glBufferData(GL_ARRAY_BUFFER, size,
nullptr, GL_STATIC_DRAW);
51 size_t offset_positions= 0;
53 glBufferSubData(GL_ARRAY_BUFFER, offset_positions, size, mesh.
vertex_buffer());
55 glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, (
const GLvoid *) offset_positions);
56 glEnableVertexAttribArray(0);
59 size_t offset_normals= offset_positions + size;
61 glBufferSubData(GL_ARRAY_BUFFER, offset_normals, size, mesh.
normal_buffer());
63 glVertexAttribPointer(2, 3, GL_FLOAT, GL_FALSE, 0, (
const GLvoid *) offset_normals);
64 glEnableVertexAttribArray(2);
71 for(
int i= 0; i < 1024*1024; i++)
73 float x= rand() % 256 - 128;
74 float y= rand() % 256 - 128;
75 float z= rand() % 256 - 128;
77 m_positions.push_back(
vec3(x *4, y *4, z *4));
81 m_instance_count= int(m_positions.size());
83 printf(
"buffer %dKB\n",
int(
sizeof(
vec3) * m_positions.size() / 1024));
87 glGenBuffers(1, &m_instance_buffer);
88 glBindBuffer(GL_ARRAY_BUFFER, m_instance_buffer);
89 glBufferData(GL_ARRAY_BUFFER,
sizeof(
vec3) * m_positions.size(), m_positions.data(), GL_DYNAMIC_DRAW);
93 glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 0, 0);
94 glVertexAttribDivisor(1, 1);
95 glEnableVertexAttribArray(1);
98 glGenBuffers(1, &m_instance_storage);
99 glBindBuffer(GL_ARRAY_BUFFER, m_instance_storage);
100 glBufferStorage(GL_ARRAY_BUFFER,
sizeof(
vec3) * m_positions.size(),
nullptr, GL_DYNAMIC_STORAGE_BIT | GL_MAP_WRITE_BIT | GL_MAP_PERSISTENT_BIT);
102 m_storage= glMapBufferRange(GL_ARRAY_BUFFER, 0,
sizeof(
vec3) * m_positions.size(),
103 GL_MAP_INVALIDATE_RANGE_BIT | GL_MAP_WRITE_BIT | GL_MAP_FLUSH_EXPLICIT_BIT | GL_MAP_PERSISTENT_BIT);
104 if(m_storage ==
nullptr)
108 glGenVertexArrays(1, &m_vao_storage);
109 glBindVertexArray(m_vao_storage);
111 glBindBuffer(GL_ARRAY_BUFFER, m_buffer);
112 glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, (
const GLvoid *) offset_positions);
113 glEnableVertexAttribArray(0);
114 glVertexAttribPointer(2, 3, GL_FLOAT, GL_FALSE, 0, (
const GLvoid *) offset_normals);
115 glEnableVertexAttribArray(2);
117 glBindBuffer(GL_ARRAY_BUFFER, m_instance_storage);
118 glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 0, 0);
119 glVertexAttribDivisor(1, 1);
120 glEnableVertexAttribArray(1);
122 glBindVertexArray(0);
126 glBindVertexArray(0);
127 glBindBuffer(GL_ARRAY_BUFFER, 0);
134 glClearColor(0.2f, 0.2f, 0.2f, 1.f);
137 glDepthFunc(GL_LESS);
138 glEnable(GL_DEPTH_TEST);
147 glDeleteVertexArrays(1, &m_vao);
148 glDeleteBuffers(1, &m_buffer);
149 glDeleteBuffers(1, &m_instance_buffer);
153 int update(
const float time,
const float delta )
162 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
166 unsigned int mb= SDL_GetRelativeMouseState(&mx, &my);
167 if(mb & SDL_BUTTON(1))
169 else if(mb & SDL_BUTTON(3))
171 else if(mb & SDL_BUTTON(2))
178 mode= (mode + 1) % 5;
179 printf(
"mode %d\n", mode);
189 glBindBuffer(GL_ARRAY_BUFFER, m_instance_buffer);
190 glBufferData(GL_ARRAY_BUFFER,
sizeof(
vec3) * m_positions.size(), m_positions.data(), GL_DYNAMIC_DRAW);
192 glBindVertexArray(m_vao);
198 glBindBuffer(GL_ARRAY_BUFFER, m_instance_buffer);
199 glBufferSubData(GL_ARRAY_BUFFER, 0,
sizeof(
vec3) * m_positions.size(), m_positions.data());
201 glBindVertexArray(m_vao);
207 glInvalidateBufferData(m_instance_buffer);
208 glBindBuffer(GL_ARRAY_BUFFER, m_instance_buffer);
209 glBufferSubData(GL_ARRAY_BUFFER, 0,
sizeof(
vec3) * m_positions.size(), m_positions.data());
211 glBindVertexArray(m_vao);
218 std::chrono::high_resolution_clock::time_point copy_start= std::chrono::high_resolution_clock::now();
219 memcpy(m_storage, m_positions.data(),
sizeof(
vec3) * m_positions.size());
221 std::chrono::high_resolution_clock::time_point copy_stop= std::chrono::high_resolution_clock::now();
222 auto copy_time= std::chrono::duration_cast<std::chrono::microseconds>(copy_stop - copy_start).count();
223 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 glBindBuffer(GL_ARRAY_BUFFER, m_instance_storage);
226 glFlushMappedBufferRange(GL_ARRAY_BUFFER, 0,
sizeof(
vec3) * m_positions.size());
228 glMemoryBarrier(GL_CLIENT_MAPPED_BUFFER_BARRIER_BIT);
230 glBindVertexArray(m_vao_storage);
235 glBindVertexArray(m_vao);
239 glUseProgram(m_program);
250 glDrawArraysInstanced(GL_TRIANGLES, 0, m_vertex_count,
std::min(m_instance_count, 4096));
256 std::vector<vec3> m_positions;
260 GLuint m_instance_buffer;
262 GLuint m_vao_storage;
263 GLuint m_instance_storage;
272 int m_instance_count;
276 int main(
int argc,
char **argv )
int run()
execution de l'application.
int render()
a deriver pour afficher les objets. renvoie 1 pour continuer, 0 pour fermer l'application.
int update(const float time, const float delta)
a deriver et redefinir pour animer les objets en fonction du temps.
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.
representation d'un objet / maillage.
const float * vertex_buffer() const
renvoie l'adresse de la position du premier sommet. permet de construire les vertex buffers 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...
std::size_t vertex_buffer_size() const
renvoie la longueur (en octets) du vertex buffer.
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.
const float * normal_buffer() const
renvoie l'adresse de la normale du premier sommet. par convention, la normale est un vec3,...
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.
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.
Transform view() const
renvoie la transformation vue.
int window_height()
renvoie la hauteur de la fenetre de l'application.
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().
int key_state(const SDL_Keycode key)
renvoie l'etat d'une touche du clavier. cf la doc SDL2 pour les codes.
int window_width()
renvoie la largeur de la fenetre de l'application.
Point min(const Point &a, const Point &b)
renvoie la plus petite composante de chaque point. x, y, z= min(a.x, b.x), min(a.y,...
Transform RotationY(const float a)
renvoie la matrice representation une rotation de a degree autour de l'axe Y.
Mesh read_mesh(const char *filename)
charge un fichier wavefront .obj et renvoie un mesh compose de triangles non indexes....
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 program_print_errors(const GLuint program)
affiche les erreurs de compilation.
int release_program(const GLuint program)
detruit les shaders et le program.
representation d'un point 3d.
representation d'un vecteur 3d.
vecteur generique, utilitaire.