JNIEXPORT void JNICALL Java_org_lwjgl_opengl_ARBIndirectParameters_nglMultiDrawArraysIndirectCountARB(JNIEnv *env, jclass clazz, jint mode, jlong indirect, jlong drawcount, jint maxdrawcount, jint stride, jlong function_pointer) { const GLvoid *indirect_address = (const GLvoid *)(intptr_t)indirect; glMultiDrawArraysIndirectCountARBPROC glMultiDrawArraysIndirectCountARB = (glMultiDrawArraysIndirectCountARBPROC)((intptr_t)function_pointer); glMultiDrawArraysIndirectCountARB(mode, indirect_address, drawcount, maxdrawcount, stride); }
void cullindirect_app::render(double currentTime) { static const GLfloat farplane[] = { 1.0f }; static float lastTime = 0.0f; static int frames = 0; float nowTime = float(currentTime); int i; // Set viewport and clear glViewport(0, 0, info.windowWidth, info.windowHeight); glClearBufferfv(GL_COLOR, 0, sb7::color::Black); glClearBufferfv(GL_DEPTH, 0, farplane); // Bind and clear atomic counter glBindBufferBase(GL_ATOMIC_COUNTER_BUFFER, 0, buffers.parameters); glClearBufferSubData(GL_ATOMIC_COUNTER_BUFFER, GL_R32UI, 0, sizeof(GLuint), GL_RED_INTEGER, GL_UNSIGNED_INT, nullptr); // Bind shader storage buffers glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, buffers.drawCandidates); glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 1, buffers.drawCommands); // Bind model matrix UBO and fill with data glBindBufferBase(GL_UNIFORM_BUFFER, 0, buffers.modelMatrices); vmath::mat4* pModelMatrix = (vmath::mat4*)glMapBufferRange(GL_UNIFORM_BUFFER, 0, 1024 * sizeof(vmath::mat4), GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_BUFFER_BIT); for (i = 0; i < 1024; i++) { float f = float(i) / 127.0f + nowTime * 0.025f; float g = float(i) / 127.0f; const vmath::mat4 model_matrix = vmath::translate(70.0f * vmath::vec3(sinf(f * 3.0f), cosf(f * 5.0f), cosf(f * 9.0f))) * vmath::rotate(nowTime * 140.0f, vmath::normalize(vmath::vec3(sinf(g * 35.0f), cosf(g * 75.0f), cosf(g * 39.0f)))); pModelMatrix[i] = model_matrix; } glUnmapBuffer(GL_UNIFORM_BUFFER); // Bind view + projection matrix UBO and fill glBindBufferBase(GL_UNIFORM_BUFFER, 1, buffers.transforms); TransformBuffer* pTransforms = (TransformBuffer*)glMapBufferRange(GL_UNIFORM_BUFFER, 0, sizeof(TransformBuffer), GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_BUFFER_BIT); float t = nowTime * 0.1f; const vmath::mat4 view_matrix = vmath::lookat(vmath::vec3(150.0f * cosf(t), 0.0f, 150.0f * sinf(t)), vmath::vec3(0.0f, 0.0f, 0.0f), vmath::vec3(0.0f, 1.0f, 0.0f)); const vmath::mat4 proj_matrix = vmath::perspective(50.0f, (float)info.windowWidth / (float)info.windowHeight, 1.0f, 2000.0f); pTransforms->view_matrix = view_matrix; pTransforms->proj_matrix = proj_matrix; pTransforms->view_proj_matrix = proj_matrix * view_matrix; glUnmapBuffer(GL_UNIFORM_BUFFER); // Bind the culling compute shader and dispatch it glUseProgram(programs.cull); glDispatchCompute(CANDIDATE_COUNT / 16, 1, 1); // Barrier glMemoryBarrier(GL_COMMAND_BARRIER_BIT); // Get ready to render glEnable(GL_DEPTH_TEST); glEnable(GL_CULL_FACE); glBindVertexArray(object.get_vao()); glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, texture); // Bind indirect command buffer and parameter buffer glBindBuffer(GL_DRAW_INDIRECT_BUFFER, buffers.drawCommands); glBindBuffer(GL_PARAMETER_BUFFER_ARB, buffers.parameters); glUseProgram(programs.draw); // Draw glMultiDrawArraysIndirectCountARB(GL_TRIANGLES, 0, 0, CANDIDATE_COUNT, 0); // Update overlay if (nowTime > (lastTime + 0.25f)) { fps = float(frames) / (nowTime - lastTime); frames = 0; lastTime = nowTime; } glDisable(GL_CULL_FACE); updateOverlay(); frames++; }