void multidrawindirect_app::render(double currentTime) { int j; static const float one = 1.0f; static const float black[] = { 0.0f, 0.0f, 0.0f, 0.0f }; static double last_time = 0.0; static double total_time = 0.0; if (!paused) total_time += (currentTime - last_time); last_time = currentTime; float t = float(total_time); int i = int(total_time * 3.0f); glViewport(0, 0, info.windowWidth, info.windowHeight); glClearBufferfv(GL_COLOR, 0, black); glClearBufferfv(GL_DEPTH, 0, &one); const vmath::mat4 view_matrix = vmath::lookat(vmath::vec3(100.0f * cosf(t * 0.023f), 100.0f * cosf(t * 0.023f), 300.0f * sinf(t * 0.037f) - 600.0f), vmath::vec3(0.0f, 0.0f, 260.0f), vmath::normalize(vmath::vec3(0.1f - cosf(t * 0.1f) * 0.3f, 1.0f, 0.0f))); const vmath::mat4 proj_matrix = vmath::perspective(50.0f, (float)info.windowWidth / (float)info.windowHeight, 1.0f, 2000.0f); glUseProgram(render_program); glUniform1f(uniforms.time, t); glUniformMatrix4fv(uniforms.view_matrix, 1, GL_FALSE, view_matrix); glUniformMatrix4fv(uniforms.proj_matrix, 1, GL_FALSE, proj_matrix); glUniformMatrix4fv(uniforms.viewproj_matrix, 1, GL_FALSE, proj_matrix * view_matrix); glBindVertexArray(object.get_vao()); if (mode == MODE_MULTIDRAW) { glMultiDrawArraysIndirect(GL_TRIANGLES, NULL, NUM_DRAWS, 0); } else if (mode == MODE_SEPARATE_DRAWS) { for (j = 0; j < NUM_DRAWS; j++) { GLuint first, count; object.get_sub_object_info(j % object.get_sub_object_count(), first, count); glDrawArraysInstancedBaseInstance(GL_TRIANGLES, first, count, 1, j); } } }
void multidrawindirect_app::startup() { int i; load_shaders(); object.load("media/objects/asteroids.sbm"); glGenBuffers(1, &indirect_draw_buffer); glBindBuffer(GL_DRAW_INDIRECT_BUFFER, indirect_draw_buffer); glBufferData(GL_DRAW_INDIRECT_BUFFER, NUM_DRAWS * sizeof(DrawArraysIndirectCommand), NULL, GL_STATIC_DRAW); DrawArraysIndirectCommand * cmd = (DrawArraysIndirectCommand *) glMapBufferRange(GL_DRAW_INDIRECT_BUFFER, 0, NUM_DRAWS * sizeof(DrawArraysIndirectCommand), GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_BUFFER_BIT); for (i = 0; i < NUM_DRAWS; i++) { object.get_sub_object_info(i % object.get_sub_object_count(), cmd[i].first, cmd[i].count); cmd[i].primCount = 1; cmd[i].baseInstance = i; } glUnmapBuffer(GL_DRAW_INDIRECT_BUFFER); glBindVertexArray(object.get_vao()); glGenBuffers(1, &draw_index_buffer); glBindBuffer(GL_ARRAY_BUFFER, draw_index_buffer); glBufferData(GL_ARRAY_BUFFER, NUM_DRAWS * sizeof(GLuint), NULL, GL_STATIC_DRAW); GLuint * draw_index = (GLuint *)glMapBufferRange(GL_ARRAY_BUFFER, 0, NUM_DRAWS * sizeof(GLuint), GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_BUFFER_BIT); for (i = 0; i < NUM_DRAWS; i++) { draw_index[i] = i; } glUnmapBuffer(GL_ARRAY_BUFFER); glVertexAttribIPointer(10, 1, GL_UNSIGNED_INT, 0, NULL); glVertexAttribDivisor(10, 1); glEnableVertexAttribArray(10); glEnable(GL_DEPTH_TEST); glDepthFunc(GL_LEQUAL); glEnable(GL_CULL_FACE); }