31 if(mesh.vertex_count() == 0)
35 mesh.bounds(pmin, pmax);
36 m_camera.lookat(pmin -
Vector(40, 40, 40), pmax +
Vector(40, 40, 40));
38 m_vertex_count= mesh.vertex_count();
41 glGenVertexArrays(1, &m_vao);
42 glBindVertexArray(m_vao);
45 glGenBuffers(1, &m_buffer);
46 glBindBuffer(GL_ARRAY_BUFFER, m_buffer);
48 size_t size= mesh.vertex_buffer_size() + mesh.normal_buffer_size();
49 glBufferData(GL_ARRAY_BUFFER, size,
nullptr, GL_STATIC_DRAW);
52 size_t offset_positions= 0;
53 size= mesh.vertex_buffer_size();
54 glBufferSubData(GL_ARRAY_BUFFER, offset_positions, size, mesh.vertex_buffer());
56 glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, (
const GLvoid *) offset_positions);
57 glEnableVertexAttribArray(0);
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());
64 glVertexAttribPointer(2, 3, GL_FLOAT, GL_FALSE, 0, (
const GLvoid *) offset_normals);
65 glEnableVertexAttribArray(2);
72 for(
int i= 0; i < 1024*1024; i++)
74 float x= rand() % 256 - 128;
75 float y= rand() % 256 - 128;
76 float z= rand() % 256 - 128;
78 m_positions.push_back(
vec3(x *4, y *4, z *4));
82 m_instance_count= int(m_positions.size());
84 printf(
"buffer %dKB\n",
int(
sizeof(
vec3) * m_positions.size() / 1024));
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);
94 glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 0, 0);
95 glVertexAttribDivisor(1, 1);
96 glEnableVertexAttribArray(1);
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);
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)
109 glGenVertexArrays(1, &m_vao_storage);
110 glBindVertexArray(m_vao_storage);
112 glBindBuffer(GL_ARRAY_BUFFER, m_buffer);
113 glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, (
const GLvoid *) offset_positions);
114 glEnableVertexAttribArray(0);
115 glVertexAttribPointer(2, 3, GL_FLOAT, GL_FALSE, 0, (
const GLvoid *) offset_normals);
116 glEnableVertexAttribArray(2);
118 glBindBuffer(GL_ARRAY_BUFFER, m_instance_storage);
119 glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 0, 0);
120 glVertexAttribDivisor(1, 1);
121 glEnableVertexAttribArray(1);
123 glBindVertexArray(0);
127 glBindVertexArray(0);
128 glBindBuffer(GL_ARRAY_BUFFER, 0);
131 m_program=
read_program(
"gkit2_tutos/instance_buffer.glsl");
135 glClearColor(0.2f, 0.2f, 0.2f, 1.f);
138 glDepthFunc(GL_LESS);
139 glEnable(GL_DEPTH_TEST);
163 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
167 unsigned int mb= SDL_GetRelativeMouseState(&mx, &my);
168 if(mb & SDL_BUTTON(1))
169 m_camera.rotation(mx, my);
170 else if(mb & SDL_BUTTON(3))
172 else if(mb & SDL_BUTTON(2))
179 mode= (mode + 1) % 5;
180 printf(
"mode %d\n", mode);
190 glBindBuffer(GL_ARRAY_BUFFER, m_instance_buffer);
191 glBufferData(GL_ARRAY_BUFFER,
sizeof(
vec3) * m_positions.size(), m_positions.data(), GL_DYNAMIC_DRAW);
193 glBindVertexArray(m_vao);
199 glBindBuffer(GL_ARRAY_BUFFER, m_instance_buffer);
200 glBufferSubData(GL_ARRAY_BUFFER, 0,
sizeof(
vec3) * m_positions.size(), m_positions.data());
202 glBindVertexArray(m_vao);
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());
212 glBindVertexArray(m_vao);
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());
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));
226 glBindBuffer(GL_ARRAY_BUFFER, m_instance_storage);
227 glFlushMappedBufferRange(GL_ARRAY_BUFFER, 0,
sizeof(
vec3) * m_positions.size());
229 glMemoryBarrier(GL_CLIENT_MAPPED_BUFFER_BARRIER_BIT);
231 glBindVertexArray(m_vao_storage);
236 glBindVertexArray(m_vao);
240 glUseProgram(m_program);
248 program_uniform(m_program,
"mvpMatrix", mvp);
249 program_uniform(m_program,
"normalMatrix", mv.
normal());
251 glDrawArraysInstanced(GL_TRIANGLES, 0, m_vertex_count, std::min(m_instance_count, 4096));