void IrrDriver::renderGLSL(float dt) { BoundingBoxes.clear(); World *world = World::getWorld(); // Never NULL. Track *track = world->getTrack(); for (unsigned i = 0; i < PowerupManager::POWERUP_MAX; i++) { scene::IMesh *mesh = powerup_manager->m_all_meshes[i]; if (!mesh) continue; for (unsigned j = 0; j < mesh->getMeshBufferCount(); j++) { scene::IMeshBuffer *mb = mesh->getMeshBuffer(j); if (!mb) continue; for (unsigned k = 0; k < 4; k++) { video::ITexture *tex = mb->getMaterial().getTexture(k); if (!tex) continue; compressTexture(tex, true); } } } // Overrides video::SOverrideMaterial &overridemat = m_video_driver->getOverrideMaterial(); overridemat.EnablePasses = scene::ESNRP_SOLID | scene::ESNRP_TRANSPARENT; overridemat.EnableFlags = 0; if (m_wireframe) { overridemat.Material.Wireframe = 1; overridemat.EnableFlags |= video::EMF_WIREFRAME; } if (m_mipviz) { overridemat.Material.MaterialType = m_shaders->getShader(ES_MIPVIZ); overridemat.EnableFlags |= video::EMF_MATERIAL_TYPE; overridemat.EnablePasses = scene::ESNRP_SOLID; } // Get a list of all glowing things. The driver's list contains the static ones, // here we add items, as they may disappear each frame. std::vector<GlowData> glows = m_glowing; ItemManager * const items = ItemManager::get(); const u32 itemcount = items->getNumberOfItems(); u32 i; for (i = 0; i < itemcount; i++) { Item * const item = items->getItem(i); if (!item) continue; const Item::ItemType type = item->getType(); if (type != Item::ITEM_NITRO_BIG && type != Item::ITEM_NITRO_SMALL && type != Item::ITEM_BONUS_BOX && type != Item::ITEM_BANANA && type != Item::ITEM_BUBBLEGUM) continue; LODNode * const lod = (LODNode *) item->getSceneNode(); if (!lod->isVisible()) continue; const int level = lod->getLevel(); if (level < 0) continue; scene::ISceneNode * const node = lod->getAllNodes()[level]; node->updateAbsolutePosition(); GlowData dat; dat.node = node; dat.r = 1.0f; dat.g = 1.0f; dat.b = 1.0f; const video::SColorf &c = ItemManager::getGlowColor(type); dat.r = c.getRed(); dat.g = c.getGreen(); dat.b = c.getBlue(); glows.push_back(dat); } // Start the RTT for post-processing. // We do this before beginScene() because we want to capture the glClear() // because of tracks that do not have skyboxes (generally add-on tracks) m_post_processing->begin(); RaceGUIBase *rg = world->getRaceGUI(); if (rg) rg->update(dt); if (!CVS->isDefferedEnabled()) { SColor clearColor(0, 150, 150, 150); if (World::getWorld() != NULL) clearColor = World::getWorld()->getClearColor(); glClear(GL_COLOR_BUFFER_BIT); glDepthMask(GL_TRUE); glBindFramebuffer(GL_FRAMEBUFFER, 0); glClearColor(clearColor.getRed() / 255.f, clearColor.getGreen() / 255.f, clearColor.getBlue() / 255.f, clearColor.getAlpha() / 255.f); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); } for(unsigned int cam = 0; cam < Camera::getNumCameras(); cam++) { Camera * const camera = Camera::getCamera(cam); scene::ICameraSceneNode * const camnode = camera->getCameraSceneNode(); std::ostringstream oss; oss << "drawAll() for kart " << cam; PROFILER_PUSH_CPU_MARKER(oss.str().c_str(), (cam+1)*60, 0x00, 0x00); camera->activate(!CVS->isDefferedEnabled()); rg->preRenderCallback(camera); // adjusts start referee m_scene_manager->setActiveCamera(camnode); const core::recti &viewport = camera->getViewport(); if (World::getWorld() && World::getWorld()->getTrack()->hasShadows() && !SphericalHarmonicsTextures.empty()) irr_driver->getSceneManager()->setAmbientLight(SColor(0, 0, 0, 0)); // TODO: put this outside of the rendering loop if (!m_skybox_ready) { prepareSkybox(); m_skybox_ready = true; } if (!CVS->isDefferedEnabled()) glEnable(GL_FRAMEBUFFER_SRGB); PROFILER_PUSH_CPU_MARKER("Update Light Info", 0xFF, 0x0, 0x0); unsigned plc = UpdateLightsInfo(camnode, dt); PROFILER_POP_CPU_MARKER(); PROFILER_PUSH_CPU_MARKER("UBO upload", 0x0, 0xFF, 0x0); computeMatrixesAndCameras(camnode, viewport.LowerRightCorner.X - viewport.UpperLeftCorner.X, viewport.LowerRightCorner.Y - viewport.UpperLeftCorner.Y); uploadLightingData(); PROFILER_POP_CPU_MARKER(); renderScene(camnode, plc, glows, dt, track->hasShadows(), false); // Render bounding boxes if (irr_driver->getBoundingBoxesViz()) { glUseProgram(UtilShader::ColoredLine::getInstance()->Program); glBindVertexArray(UtilShader::ColoredLine::getInstance()->vao); glBindBuffer(GL_ARRAY_BUFFER, UtilShader::ColoredLine::getInstance()->vbo); UtilShader::ColoredLine::getInstance()->setUniforms(SColor(255, 255, 0, 0)); const float *tmp = BoundingBoxes.data(); for (unsigned int i = 0; i < BoundingBoxes.size(); i += 1024 * 6) { unsigned count = MIN2((int)BoundingBoxes.size() - i, 1024 * 6); glBufferSubData(GL_ARRAY_BUFFER, 0, count * sizeof(float), &tmp[i]); glDrawArrays(GL_LINES, 0, count / 3); } } // Debug physic // Note that drawAll must be called before rendering // the bullet debug view, since otherwise the camera // is not set up properly. This is only used for // the bullet debug view. if (UserConfigParams::m_artist_debug_mode) World::getWorld()->getPhysics()->draw(); if (world != NULL && world->getPhysics() != NULL) { IrrDebugDrawer* debug_drawer = world->getPhysics()->getDebugDrawer(); if (debug_drawer != NULL && debug_drawer->debugEnabled()) { const std::map<video::SColor, std::vector<float> >& lines = debug_drawer->getLines(); std::map<video::SColor, std::vector<float> >::const_iterator it; glUseProgram(UtilShader::ColoredLine::getInstance()->Program); glBindVertexArray(UtilShader::ColoredLine::getInstance()->vao); glBindBuffer(GL_ARRAY_BUFFER, UtilShader::ColoredLine::getInstance()->vbo); for (it = lines.begin(); it != lines.end(); it++) { UtilShader::ColoredLine::getInstance()->setUniforms(it->first); const std::vector<float> &vertex = it->second; const float *tmp = vertex.data(); for (unsigned int i = 0; i < vertex.size(); i += 1024 * 6) { unsigned count = MIN2((int)vertex.size() - i, 1024 * 6); glBufferSubData(GL_ARRAY_BUFFER, 0, count * sizeof(float), &tmp[i]); glDrawArrays(GL_LINES, 0, count / 3); } } glUseProgram(0); glBindVertexArray(0); } } // Render the post-processed scene if (CVS->isDefferedEnabled()) { bool isRace = StateManager::get()->getGameState() == GUIEngine::GAME; FrameBuffer *fbo = m_post_processing->render(camnode, isRace); if (irr_driver->getNormals()) irr_driver->getFBO(FBO_NORMAL_AND_DEPTHS).BlitToDefault(viewport.UpperLeftCorner.X, viewport.UpperLeftCorner.Y, viewport.LowerRightCorner.X, viewport.LowerRightCorner.Y); else if (irr_driver->getSSAOViz()) { glBindFramebuffer(GL_FRAMEBUFFER, 0); glViewport(viewport.UpperLeftCorner.X, viewport.UpperLeftCorner.Y, viewport.LowerRightCorner.X, viewport.LowerRightCorner.Y); m_post_processing->renderPassThrough(m_rtts->getFBO(FBO_HALF1_R).getRTT()[0], viewport.LowerRightCorner.X - viewport.UpperLeftCorner.X, viewport.LowerRightCorner.Y - viewport.UpperLeftCorner.Y); } else if (irr_driver->getRSM()) { glBindFramebuffer(GL_FRAMEBUFFER, 0); glViewport(viewport.UpperLeftCorner.X, viewport.UpperLeftCorner.Y, viewport.LowerRightCorner.X, viewport.LowerRightCorner.Y); m_post_processing->renderPassThrough(m_rtts->getRSM().getRTT()[0], viewport.LowerRightCorner.X - viewport.UpperLeftCorner.X, viewport.LowerRightCorner.Y - viewport.UpperLeftCorner.Y); } else if (irr_driver->getShadowViz()) { renderShadowsDebug(); } else { glEnable(GL_FRAMEBUFFER_SRGB); glBindFramebuffer(GL_FRAMEBUFFER, 0); if (CVS->isDefferedEnabled()) camera->activate(); m_post_processing->renderPassThrough(fbo->getRTT()[0], viewport.LowerRightCorner.X - viewport.UpperLeftCorner.X, viewport.LowerRightCorner.Y - viewport.UpperLeftCorner.Y); glDisable(GL_FRAMEBUFFER_SRGB); } } // Save projection-view matrix for the next frame camera->setPreviousPVMatrix(m_ProjViewMatrix); PROFILER_POP_CPU_MARKER(); } // for i<world->getNumKarts() // Use full screen size float tmp[2]; tmp[0] = float(m_actual_screen_size.Width); tmp[1] = float(m_actual_screen_size.Height); glBindBuffer(GL_UNIFORM_BUFFER, SharedObject::ViewProjectionMatrixesUBO); glBufferSubData(GL_UNIFORM_BUFFER, (16 * 9) * sizeof(float), 2 * sizeof(float), tmp); glBindVertexArray(0); glBindBuffer(GL_ARRAY_BUFFER, 0); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); glUseProgram(0); // Set the viewport back to the full screen for race gui m_video_driver->setViewPort(core::recti(0, 0, irr_driver->getActualScreenSize().Width, irr_driver->getActualScreenSize().Height)); for(unsigned int i=0; i<Camera::getNumCameras(); i++) { Camera *camera = Camera::getCamera(i); std::ostringstream oss; oss << "renderPlayerView() for kart " << i; PROFILER_PUSH_CPU_MARKER(oss.str().c_str(), 0x00, 0x00, (i+1)*60); rg->renderPlayerView(camera, dt); PROFILER_POP_CPU_MARKER(); } // for i<getNumKarts { ScopedGPUTimer Timer(getGPUTimer(Q_GUI)); PROFILER_PUSH_CPU_MARKER("GUIEngine", 0x75, 0x75, 0x75); // Either render the gui, or the global elements of the race gui. GUIEngine::render(dt); PROFILER_POP_CPU_MARKER(); } // Render the profiler if(UserConfigParams::m_profiler_enabled) { PROFILER_DRAW(); } #ifdef DEBUG drawDebugMeshes(); #endif PROFILER_PUSH_CPU_MARKER("EndSccene", 0x45, 0x75, 0x45); m_video_driver->endScene(); PROFILER_POP_CPU_MARKER(); getPostProcessing()->update(dt); }
void IrrDriver::renderScene(scene::ICameraSceneNode * const camnode, unsigned pointlightcount, std::vector<GlowData>& glows, float dt, bool hasShadow, bool forceRTT) { glBindBufferBase(GL_UNIFORM_BUFFER, 0, SharedObject::ViewProjectionMatrixesUBO); m_scene_manager->setActiveCamera(camnode); PROFILER_PUSH_CPU_MARKER("- Draw Call Generation", 0xFF, 0xFF, 0xFF); PrepareDrawCalls(camnode); PROFILER_POP_CPU_MARKER(); // Shadows { // To avoid wrong culling, use the largest view possible m_scene_manager->setActiveCamera(m_suncam); if (!m_mipviz && !m_wireframe && UserConfigParams::m_dynamic_lights && UserConfigParams::m_shadows && !irr_driver->needUBOWorkaround() && hasShadow) { PROFILER_PUSH_CPU_MARKER("- Shadow", 0x30, 0x6F, 0x90); renderShadows(); PROFILER_POP_CPU_MARKER(); if (UserConfigParams::m_gi) { PROFILER_PUSH_CPU_MARKER("- RSM", 0xFF, 0x0, 0xFF); renderRSM(); PROFILER_POP_CPU_MARKER(); } } m_scene_manager->setActiveCamera(camnode); } PROFILER_PUSH_CPU_MARKER("- Solid Pass 1", 0xFF, 0x00, 0x00); glDepthMask(GL_TRUE); glDepthFunc(GL_LEQUAL); glEnable(GL_DEPTH_TEST); glDisable(GL_BLEND); glEnable(GL_CULL_FACE); if (UserConfigParams::m_dynamic_lights || forceRTT) { m_rtts->getFBO(FBO_NORMAL_AND_DEPTHS).Bind(); glClearColor(0., 0., 0., 0.); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); renderSolidFirstPass(); } PROFILER_POP_CPU_MARKER(); // Lights { PROFILER_PUSH_CPU_MARKER("- Light", 0x00, 0xFF, 0x00); if (UserConfigParams::m_dynamic_lights) renderLights(pointlightcount, hasShadow); PROFILER_POP_CPU_MARKER(); } // Handle SSAO { PROFILER_PUSH_CPU_MARKER("- SSAO", 0xFF, 0xFF, 0x00); ScopedGPUTimer Timer(getGPUTimer(Q_SSAO)); if (UserConfigParams::m_ssao) renderSSAO(); PROFILER_POP_CPU_MARKER(); } PROFILER_PUSH_CPU_MARKER("- Solid Pass 2", 0x00, 0x00, 0xFF); if (UserConfigParams::m_dynamic_lights || forceRTT) { m_rtts->getFBO(FBO_COLORS).Bind(); SColor clearColor(0, 150, 150, 150); if (World::getWorld() != NULL) clearColor = World::getWorld()->getClearColor(); glClearColor(clearColor.getRed() / 255.f, clearColor.getGreen() / 255.f, clearColor.getBlue() / 255.f, clearColor.getAlpha() / 255.f); glClear(GL_COLOR_BUFFER_BIT); glDepthMask(GL_FALSE); } renderSolidSecondPass(); PROFILER_POP_CPU_MARKER(); if (getNormals()) { m_rtts->getFBO(FBO_NORMAL_AND_DEPTHS).Bind(); renderNormalsVisualisation(); m_rtts->getFBO(FBO_COLORS).Bind(); } if (UserConfigParams::m_dynamic_lights && World::getWorld() != NULL && World::getWorld()->isFogEnabled()) { PROFILER_PUSH_CPU_MARKER("- Fog", 0xFF, 0x00, 0x00); m_post_processing->renderFog(); PROFILER_POP_CPU_MARKER(); } PROFILER_PUSH_CPU_MARKER("- Skybox", 0xFF, 0x00, 0xFF); renderSkybox(camnode); PROFILER_POP_CPU_MARKER(); if (getRH()) { m_rtts->getFBO(FBO_COLORS).Bind(); m_post_processing->renderRHDebug(m_rtts->getRH().getRTT()[0], m_rtts->getRH().getRTT()[1], m_rtts->getRH().getRTT()[2], rh_matrix, rh_extend); } if (getGI()) { m_rtts->getFBO(FBO_COLORS).Bind(); m_post_processing->renderGI(rh_matrix, rh_extend, m_rtts->getRH().getRTT()[0], m_rtts->getRH().getRTT()[1], m_rtts->getRH().getRTT()[2]); } PROFILER_PUSH_CPU_MARKER("- Glow", 0xFF, 0xFF, 0x00); // Render anything glowing. if (!m_mipviz && !m_wireframe && UserConfigParams::m_glow) { irr_driver->setPhase(GLOW_PASS); renderGlow(glows); } // end glow PROFILER_POP_CPU_MARKER(); PROFILER_PUSH_CPU_MARKER("- Lensflare/godray", 0x00, 0xFF, 0xFF); computeSunVisibility(); PROFILER_POP_CPU_MARKER(); // Render transparent { PROFILER_PUSH_CPU_MARKER("- Transparent Pass", 0xFF, 0x00, 0x00); ScopedGPUTimer Timer(getGPUTimer(Q_TRANSPARENT)); renderTransparent(); PROFILER_POP_CPU_MARKER(); } m_sync = glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0); // Render particles { PROFILER_PUSH_CPU_MARKER("- Particles", 0xFF, 0xFF, 0x00); ScopedGPUTimer Timer(getGPUTimer(Q_PARTICLES)); renderParticles(); PROFILER_POP_CPU_MARKER(); } if (!UserConfigParams::m_dynamic_lights && !forceRTT) { glDisable(GL_FRAMEBUFFER_SRGB); glDisable(GL_DEPTH_TEST); glDepthMask(GL_FALSE); return; } // Ensure that no object will be drawn after that by using invalid pass irr_driver->setPhase(PASS_COUNT); }
void IrrDriver::renderScene(scene::ICameraSceneNode * const camnode, unsigned pointlightcount, std::vector<GlowData>& glows, float dt, bool hasShadow, bool forceRTT) { glBindBufferBase(GL_UNIFORM_BUFFER, 0, SharedObject::ViewProjectionMatrixesUBO); glBindBufferBase(GL_UNIFORM_BUFFER, 1, SharedObject::LightingDataUBO); m_scene_manager->setActiveCamera(camnode); PROFILER_PUSH_CPU_MARKER("- Draw Call Generation", 0xFF, 0xFF, 0xFF); PrepareDrawCalls(camnode); PROFILER_POP_CPU_MARKER(); // Shadows { // To avoid wrong culling, use the largest view possible m_scene_manager->setActiveCamera(m_suncam); if (CVS->isDefferedEnabled() && CVS->isShadowEnabled() && hasShadow) { PROFILER_PUSH_CPU_MARKER("- Shadow", 0x30, 0x6F, 0x90); renderShadows(); PROFILER_POP_CPU_MARKER(); if (CVS->isGlobalIlluminationEnabled()) { PROFILER_PUSH_CPU_MARKER("- RSM", 0xFF, 0x0, 0xFF); renderRSM(); PROFILER_POP_CPU_MARKER(); } } m_scene_manager->setActiveCamera(camnode); } PROFILER_PUSH_CPU_MARKER("- Solid Pass 1", 0xFF, 0x00, 0x00); glDepthMask(GL_TRUE); glDepthFunc(GL_LEQUAL); glEnable(GL_DEPTH_TEST); glDisable(GL_BLEND); glEnable(GL_CULL_FACE); if (CVS->isDefferedEnabled() || forceRTT) { m_rtts->getFBO(FBO_NORMAL_AND_DEPTHS).Bind(); glClearColor(0., 0., 0., 0.); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); renderSolidFirstPass(); } else { // We need a cleared depth buffer for some effect (eg particles depth blending) if (GraphicsRestrictions::isDisabled(GraphicsRestrictions::GR_FRAMEBUFFER_SRGB_WORKING)) glDisable(GL_FRAMEBUFFER_SRGB); m_rtts->getFBO(FBO_NORMAL_AND_DEPTHS).Bind(); // Bind() modifies the viewport. In order not to affect anything else, // the viewport is just reset here and not removed in Bind(). const core::recti &vp = Camera::getActiveCamera()->getViewport(); glViewport(vp.UpperLeftCorner.X, irr_driver->getActualScreenSize().Height - vp.LowerRightCorner.Y, vp.LowerRightCorner.X - vp.UpperLeftCorner.X, vp.LowerRightCorner.Y - vp.UpperLeftCorner.Y); glClear(GL_DEPTH_BUFFER_BIT); if (GraphicsRestrictions::isDisabled(GraphicsRestrictions::GR_FRAMEBUFFER_SRGB_WORKING)) glEnable(GL_FRAMEBUFFER_SRGB); glBindFramebuffer(GL_FRAMEBUFFER, 0); } PROFILER_POP_CPU_MARKER(); // Lights { PROFILER_PUSH_CPU_MARKER("- Light", 0x00, 0xFF, 0x00); if (CVS->isDefferedEnabled()) renderLights(pointlightcount, hasShadow); PROFILER_POP_CPU_MARKER(); } // Handle SSAO { PROFILER_PUSH_CPU_MARKER("- SSAO", 0xFF, 0xFF, 0x00); ScopedGPUTimer Timer(getGPUTimer(Q_SSAO)); if (UserConfigParams::m_ssao) renderSSAO(); PROFILER_POP_CPU_MARKER(); } PROFILER_PUSH_CPU_MARKER("- Solid Pass 2", 0x00, 0x00, 0xFF); if (CVS->isDefferedEnabled() || forceRTT) { m_rtts->getFBO(FBO_COLORS).Bind(); SColor clearColor(0, 150, 150, 150); if (World::getWorld() != NULL) clearColor = World::getWorld()->getClearColor(); glClearColor(clearColor.getRed() / 255.f, clearColor.getGreen() / 255.f, clearColor.getBlue() / 255.f, clearColor.getAlpha() / 255.f); glClear(GL_COLOR_BUFFER_BIT); glDepthMask(GL_FALSE); } renderSolidSecondPass(); PROFILER_POP_CPU_MARKER(); if (getNormals()) { m_rtts->getFBO(FBO_NORMAL_AND_DEPTHS).Bind(); renderNormalsVisualisation(); m_rtts->getFBO(FBO_COLORS).Bind(); } // Render ambient scattering if (CVS->isDefferedEnabled() && World::getWorld() != NULL && World::getWorld()->isFogEnabled()) { PROFILER_PUSH_CPU_MARKER("- Ambient scatter", 0xFF, 0x00, 0x00); ScopedGPUTimer Timer(getGPUTimer(Q_FOG)); renderAmbientScatter(); PROFILER_POP_CPU_MARKER(); } { PROFILER_PUSH_CPU_MARKER("- Skybox", 0xFF, 0x00, 0xFF); ScopedGPUTimer Timer(getGPUTimer(Q_SKYBOX)); renderSkybox(camnode); PROFILER_POP_CPU_MARKER(); } // Render discrete lights scattering if (CVS->isDefferedEnabled() && World::getWorld() != NULL && World::getWorld()->isFogEnabled()) { PROFILER_PUSH_CPU_MARKER("- PointLight Scatter", 0xFF, 0x00, 0x00); ScopedGPUTimer Timer(getGPUTimer(Q_FOG)); renderLightsScatter(pointlightcount); PROFILER_POP_CPU_MARKER(); } if (getRH()) { glDisable(GL_BLEND); m_rtts->getFBO(FBO_COLORS).Bind(); m_post_processing->renderRHDebug(m_rtts->getRH().getRTT()[0], m_rtts->getRH().getRTT()[1], m_rtts->getRH().getRTT()[2], rh_matrix, rh_extend); } if (getGI()) { glDisable(GL_BLEND); m_rtts->getFBO(FBO_COLORS).Bind(); m_post_processing->renderGI(rh_matrix, rh_extend, m_rtts->getRH().getRTT()[0], m_rtts->getRH().getRTT()[1], m_rtts->getRH().getRTT()[2]); } PROFILER_PUSH_CPU_MARKER("- Glow", 0xFF, 0xFF, 0x00); // Render anything glowing. if (!m_mipviz && !m_wireframe && UserConfigParams::m_glow) { ScopedGPUTimer Timer(getGPUTimer(Q_GLOW)); irr_driver->setPhase(GLOW_PASS); renderGlow(glows); } // end glow PROFILER_POP_CPU_MARKER(); PROFILER_PUSH_CPU_MARKER("- Lensflare/godray", 0x00, 0xFF, 0xFF); computeSunVisibility(); PROFILER_POP_CPU_MARKER(); // Render transparent { PROFILER_PUSH_CPU_MARKER("- Transparent Pass", 0xFF, 0x00, 0x00); ScopedGPUTimer Timer(getGPUTimer(Q_TRANSPARENT)); renderTransparent(); PROFILER_POP_CPU_MARKER(); } m_sync = glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0); // Render particles { PROFILER_PUSH_CPU_MARKER("- Particles", 0xFF, 0xFF, 0x00); ScopedGPUTimer Timer(getGPUTimer(Q_PARTICLES)); renderParticles(); PROFILER_POP_CPU_MARKER(); } if (!CVS->isDefferedEnabled() && !forceRTT) { glDisable(GL_FRAMEBUFFER_SRGB); glDisable(GL_DEPTH_TEST); glDepthMask(GL_FALSE); return; } // Ensure that no object will be drawn after that by using invalid pass irr_driver->setPhase(PASS_COUNT); }
void IrrDriver::renderScene(scene::ICameraSceneNode * const camnode, unsigned pointlightcount, std::vector<GlowData>& glows, float dt, bool hasShadow, bool forceRTT) { glBindBufferBase(GL_UNIFORM_BUFFER, 0, SharedObject::ViewProjectionMatrixesUBO); // Shadows { PROFILER_PUSH_CPU_MARKER("- Shadow", 0x30, 0x6F, 0x90); ScopedGPUTimer Timer(getGPUTimer(Q_SHADOWS)); // To avoid wrong culling, use the largest view possible m_scene_manager->setActiveCamera(m_suncam); if (!m_mipviz && !m_wireframe && UserConfigParams::m_dynamic_lights && UserConfigParams::m_shadows && !irr_driver->needUBOWorkaround() && hasShadow) renderShadows(); m_scene_manager->setActiveCamera(camnode); PROFILER_POP_CPU_MARKER(); } PROFILER_PUSH_CPU_MARKER("- Solid Pass 1", 0xFF, 0x00, 0x00); renderSolidFirstPass(); PROFILER_POP_CPU_MARKER(); // Lights { PROFILER_PUSH_CPU_MARKER("- Light", 0x00, 0xFF, 0x00); renderLights(pointlightcount); PROFILER_POP_CPU_MARKER(); } // Handle SSAO { PROFILER_PUSH_CPU_MARKER("- SSAO", 0xFF, 0xFF, 0x00); ScopedGPUTimer Timer(getGPUTimer(Q_SSAO)); if (UserConfigParams::m_ssao) renderSSAO(); PROFILER_POP_CPU_MARKER(); } PROFILER_PUSH_CPU_MARKER("- Solid Pass 2", 0x00, 0x00, 0xFF); if (!UserConfigParams::m_dynamic_lights && ! forceRTT) { glEnable(GL_FRAMEBUFFER_SRGB); glBindFramebuffer(GL_FRAMEBUFFER, 0); } else m_rtts->getFBO(FBO_COLORS).Bind(); renderSolidSecondPass(); PROFILER_POP_CPU_MARKER(); if (UserConfigParams::m_dynamic_lights && World::getWorld() != NULL && World::getWorld()->isFogEnabled()) { PROFILER_PUSH_CPU_MARKER("- Fog", 0xFF, 0x00, 0x00); m_post_processing->renderFog(); PROFILER_POP_CPU_MARKER(); } PROFILER_PUSH_CPU_MARKER("- Skybox", 0xFF, 0x00, 0xFF); renderSkybox(camnode); PROFILER_POP_CPU_MARKER(); if (getRH()) { glEnable(GL_PROGRAM_POINT_SIZE); m_rtts->getFBO(FBO_COLORS).Bind(); glUseProgram(FullScreenShader::RHDebug::Program); glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_3D, m_rtts->getRH().getRTT()[0]); glActiveTexture(GL_TEXTURE1); glBindTexture(GL_TEXTURE_3D, m_rtts->getRH().getRTT()[1]); glActiveTexture(GL_TEXTURE2); glBindTexture(GL_TEXTURE_3D, m_rtts->getRH().getRTT()[2]); FullScreenShader::RHDebug::setUniforms(rh_matrix, rh_extend, 0, 1, 2); glDrawArrays(GL_POINTS, 0, 32 * 16 * 32); glDisable(GL_PROGRAM_POINT_SIZE); } if (getGI()) { m_rtts->getFBO(FBO_COLORS).Bind(); m_post_processing->renderGI(rh_matrix, rh_extend, m_rtts->getRH().getRTT()[0], m_rtts->getRH().getRTT()[1], m_rtts->getRH().getRTT()[2]); } PROFILER_PUSH_CPU_MARKER("- Glow", 0xFF, 0xFF, 0x00); // Render anything glowing. if (!m_mipviz && !m_wireframe && UserConfigParams::m_glow) { irr_driver->setPhase(GLOW_PASS); renderGlow(glows); } // end glow PROFILER_POP_CPU_MARKER(); PROFILER_PUSH_CPU_MARKER("- Lensflare/godray", 0x00, 0xFF, 0xFF); computeSunVisibility(); PROFILER_POP_CPU_MARKER(); // Render transparent { PROFILER_PUSH_CPU_MARKER("- Transparent Pass", 0xFF, 0x00, 0x00); ScopedGPUTimer Timer(getGPUTimer(Q_TRANSPARENT)); renderTransparent(); PROFILER_POP_CPU_MARKER(); } // Render particles { PROFILER_PUSH_CPU_MARKER("- Particles", 0xFF, 0xFF, 0x00); ScopedGPUTimer Timer(getGPUTimer(Q_PARTICLES)); renderParticles(); PROFILER_POP_CPU_MARKER(); } if (!UserConfigParams::m_dynamic_lights && !forceRTT) { glDisable(GL_FRAMEBUFFER_SRGB); glDisable(GL_DEPTH_TEST); glDepthMask(GL_FALSE); return; } // Ensure that no object will be drawn after that by using invalid pass irr_driver->setPhase(PASS_COUNT); }