void DynamicMarchingTetrahedra::update(GLContext * gl) { GLContext::Program * prog = gl->getProgram(m_sceneShader.c_str()); prog->use(); Vec3i numBlocks(64); Vec3i threadBlockSize(4); Vec3i gridSize = (numBlocks + threadBlockSize - 1) / threadBlockSize; gl->setUniform(prog->getUniformLoc("cubeInfo"), m_cubeInfo); gl->setUniform(prog->getUniformLoc("isPrefixSumPass"), true); gl->setUniform(prog->getUniformLoc("numCubes"), numBlocks); gl->setUniform(prog->getUniformLoc("sync1"), m_disp1); gl->setUniform(prog->getUniformLoc("sync2"), m_disp2); gl->setUniform(prog->getUniformLoc("sync3"), m_disp3); gl->setUniform(prog->getUniformLoc("sync4"), m_disp4); gl->setUniform(prog->getUniformLoc("maxTetrahedras"), 6); glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 2, m_buffers[DMT_Buffer_Types::INDEX_BUFFER]); glDispatchCompute(gridSize.x, gridSize.y, gridSize.z); glMemoryBarrier(GL_SHADER_STORAGE_BARRIER_BIT); GPUPrefixScan::scan(gl, m_buffers[DMT_Buffer_Types::INDEX_BUFFER], m_buffers[DMT_Buffer_Types::BLOCK_BUFFER], 100*100*100); prog->use(); gl->setUniform(prog->getUniformLoc("isPrefixSumPass"), false); glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 1, m_buffers[DMT_Buffer_Types::MESH_BUFFER]); glDispatchCompute(gridSize.x, gridSize.y, gridSize.z); glMemoryBarrier(GL_SHADER_STORAGE_BARRIER_BIT); m_numTriangles = GPUPrefixScan::getSum(gl, m_buffers[DMT_Buffer_Types::BLOCK_BUFFER]); }
void App::renderFrame(GLContext* gl) { // Setup transformations. Mat4f worldToCamera = m_cameraCtrl.getWorldToCamera(); Mat4f projection = gl->xformFitToView(Vec2f(-1.0f, -1.0f), Vec2f(2.0f, 2.0f)) * m_cameraCtrl.getCameraToClip(); // Initialize GL state. glClearColor(0.2f, 0.4f, 0.8f, 1.0f); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glEnable(GL_DEPTH_TEST); if (m_cullMode == CullMode_None) glDisable(GL_CULL_FACE); else { glEnable(GL_CULL_FACE); glCullFace(GL_BACK); glFrontFace((m_cullMode == CullMode_CW) ? GL_CCW : GL_CW); } // No mesh => skip. if (!m_mesh) { gl->drawModalMessage("No mesh loaded!"); return; } // if we are computing radiosity, refresh mesh colors every 0.5 seconds if ( m_radiosity->isRunning() && m_updateClock.getElapsed() > 0.5f ) { m_radiosity->updateMeshColors(); m_radiosity->checkFinish(); // restart cycle m_updateClock.start(); } // setup up tone mapping GLContext::Program* prog = gl->getProgram("MeshBase::draw_generic"); prog->use(); gl->setUniform(prog->getUniformLoc("reinhardLWhite"), m_toneMapWhite); gl->setUniform(prog->getUniformLoc("tonemapBoost"), m_toneMapBoost); // Render. if (!gl->getConfig().isStereo) renderScene(gl, worldToCamera, projection); else { glDrawBuffer(GL_BACK_LEFT); renderScene(gl, m_cameraCtrl.getCameraToLeftEye() * worldToCamera, projection); glDrawBuffer(GL_BACK_RIGHT); glClear(GL_DEPTH_BUFFER_BIT); renderScene(gl, m_cameraCtrl.getCameraToRightEye() * worldToCamera, projection); glDrawBuffer(GL_BACK); } m_areaLight->setSize( Vec2f( m_lightSize ) ); m_areaLight->draw( worldToCamera, projection ); // Display status line. m_commonCtrl.message(sprintf("Triangles = %d, vertices = %d, materials = %d", m_mesh->numTriangles(), m_mesh->numVertices(), m_mesh->numSubmeshes()), "meshStats"); }