From cd9c2653b696dd5aa2065276045e4f4984b7ebfe Mon Sep 17 00:00:00 2001 From: Marianne Gagnon Date: Tue, 17 Jun 2014 19:26:12 -0400 Subject: [PATCH] Initial work on porting minimap to new RTT --- src/graphics/glwrap.hpp | 2 +- src/graphics/irr_driver.cpp | 5 +- src/graphics/irr_driver.hpp | 5 +- src/graphics/post_processing.cpp | 10 ++-- src/graphics/post_processing.hpp | 2 +- src/graphics/render.cpp | 2 +- src/graphics/rtts.cpp | 22 +++++++++ src/graphics/rtts.hpp | 3 ++ src/guiengine/widgets/model_view_widget.cpp | 19 +------- src/states_screens/race_gui.cpp | 22 ++++++--- src/states_screens/race_gui_overworld.cpp | 20 +++++--- src/tracks/quad_graph.cpp | 52 +++++++++++++++++---- src/tracks/quad_graph.hpp | 10 ++-- src/tracks/track.cpp | 43 +++++++++++------ src/tracks/track.hpp | 6 ++- 15 files changed, 153 insertions(+), 70 deletions(-) diff --git a/src/graphics/glwrap.hpp b/src/graphics/glwrap.hpp index bb5a5cbf9..9a735b3ec 100644 --- a/src/graphics/glwrap.hpp +++ b/src/graphics/glwrap.hpp @@ -199,7 +199,7 @@ public: FrameBuffer(const std::vector &RTTs, GLuint DS, size_t w, size_t h, bool layered = false); ~FrameBuffer(); void Bind(); - std::vector &getRTT() { return RenderTargets; } + const std::vector &getRTT() const { return RenderTargets; } GLuint &getDepthTexture() { assert(DepthTexture); return DepthTexture; } size_t getWidth() const { return width; } size_t getHeight() const { return height; } diff --git a/src/graphics/irr_driver.cpp b/src/graphics/irr_driver.cpp index 2f4291056..b38f3cb8d 100644 --- a/src/graphics/irr_driver.cpp +++ b/src/graphics/irr_driver.cpp @@ -2052,7 +2052,10 @@ bool IrrDriver::supportsSplatting() #endif // ---------------------------------------------------------------------------- -/** Begins a rendering to a texture. +/** + * THIS IS THE OLD OPENGL 1 RTT PROVIDER, USE THE SHADER-BASED + * RTT FOR NEW DEVELOPMENT + * Begins a rendering to a texture. * \param dimension The size of the texture. * \param name Name of the texture. * \param persistent_texture Whether the created RTT texture should persist in diff --git a/src/graphics/irr_driver.hpp b/src/graphics/irr_driver.hpp index bfffa6c3c..4b969956b 100644 --- a/src/graphics/irr_driver.hpp +++ b/src/graphics/irr_driver.hpp @@ -714,8 +714,11 @@ public: unsigned UpdateLightsInfo(scene::ICameraSceneNode * const camnode, float dt); void computeCameraMatrix(scene::ICameraSceneNode * const camnode, size_t width, size_t height); - // --------------------- RTT -------------------- + // --------------------- OLD RTT -------------------- /** + * THIS IS THE OLD OPENGL 1 RTT PROVIDER, USE THE SHADER-BASED + * RTT FOR NEW DEVELOPMENT + * * Class that provides RTT (currently, only when no other 3D rendering * in the main scene is required) * Provides an optional 'setupRTTScene' method to make it quick and easy diff --git a/src/graphics/post_processing.cpp b/src/graphics/post_processing.cpp index fd4fc0eed..d0003c733 100644 --- a/src/graphics/post_processing.cpp +++ b/src/graphics/post_processing.cpp @@ -698,7 +698,7 @@ void PostProcessing::applyMLAA() // ---------------------------------------------------------------------------- /** Render the post-processed scene */ -FrameBuffer *PostProcessing::render(scene::ICameraSceneNode * const camnode) +FrameBuffer *PostProcessing::render(scene::ICameraSceneNode * const camnode, bool isRace) { IVideoDriver * const drv = irr_driver->getVideoDriver(); @@ -716,7 +716,7 @@ FrameBuffer *PostProcessing::render(scene::ICameraSceneNode * const camnode) glDisable(GL_DEPTH_TEST); glDisable(GL_BLEND); - if (UserConfigParams::m_dof) + if (isRace && UserConfigParams::m_dof) { PROFILER_PUSH_CPU_MARKER("- DoF", 0xFF, 0x00, 0x00); ScopedGPUTimer Timer(irr_driver->getGPUTimer(Q_DOF)); @@ -732,7 +732,7 @@ FrameBuffer *PostProcessing::render(scene::ICameraSceneNode * const camnode) if (World::getWorld() != NULL) hasgodrays = World::getWorld()->getTrack()->hasGodRays(); - if (UserConfigParams::m_light_shaft && m_sunpixels > 30 && hasgodrays) + if (isRace && UserConfigParams::m_light_shaft && m_sunpixels > 30 && hasgodrays) { glEnable(GL_DEPTH_TEST); // Grab the sky @@ -798,7 +798,7 @@ FrameBuffer *PostProcessing::render(scene::ICameraSceneNode * const camnode) { PROFILER_PUSH_CPU_MARKER("- Bloom", 0xFF, 0x00, 0x00); ScopedGPUTimer Timer(irr_driver->getGPUTimer(Q_BLOOM)); - if (UserConfigParams::m_bloom) + if (isRace && UserConfigParams::m_bloom) { glClear(GL_STENCIL_BUFFER_BIT); glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_FALSE); @@ -850,7 +850,7 @@ FrameBuffer *PostProcessing::render(scene::ICameraSceneNode * const camnode) { PROFILER_PUSH_CPU_MARKER("- Motion blur", 0xFF, 0x00, 0x00); ScopedGPUTimer Timer(irr_driver->getGPUTimer(Q_MOTIONBLUR)); - if (UserConfigParams::m_motionblur && m_any_boost && World::getWorld() != NULL) // motion blur + if (isRace && UserConfigParams::m_motionblur && m_any_boost && World::getWorld() != NULL) // motion blur { renderMotionBlur(0, *in_fbo, *out_fbo); std::swap(in_fbo, out_fbo); diff --git a/src/graphics/post_processing.hpp b/src/graphics/post_processing.hpp index edf314700..c046eb00a 100644 --- a/src/graphics/post_processing.hpp +++ b/src/graphics/post_processing.hpp @@ -96,7 +96,7 @@ public: void renderGlow(unsigned tex); /** Render the post-processed scene */ - FrameBuffer *render(scene::ICameraSceneNode * const camnode); + FrameBuffer *render(scene::ICameraSceneNode * const camnode, bool isRace); /** Use motion blur for a short time */ void giveBoost(unsigned int cam_index); diff --git a/src/graphics/render.cpp b/src/graphics/render.cpp index b7647a38c..ad865aa26 100644 --- a/src/graphics/render.cpp +++ b/src/graphics/render.cpp @@ -185,7 +185,7 @@ void IrrDriver::renderGLSL(float dt) // Render the post-processed scene if (UserConfigParams::m_dynamic_lights) { - FrameBuffer *fbo = m_post_processing->render(camnode); + FrameBuffer *fbo = m_post_processing->render(camnode, true); if (irr_driver->getNormals()) irr_driver->getFBO(FBO_NORMAL_AND_DEPTHS).BlitToDefault(viewport.UpperLeftCorner.X, viewport.UpperLeftCorner.Y, viewport.LowerRightCorner.X, viewport.LowerRightCorner.Y); diff --git a/src/graphics/rtts.cpp b/src/graphics/rtts.cpp index 345841d6e..860725564 100644 --- a/src/graphics/rtts.cpp +++ b/src/graphics/rtts.cpp @@ -20,7 +20,9 @@ #include "config/user_config.hpp" #include "graphics/glwrap.hpp" #include "graphics/irr_driver.hpp" +#include "graphics/post_processing.hpp" #include "utils/log.hpp" +#include static GLuint generateRTT3D(GLenum target, size_t w, size_t h, size_t d, GLint internalFormat, GLint format, GLint type) { @@ -290,3 +292,23 @@ RTT::~RTT() delete m_RSM; } } + +FrameBuffer* RTT::render(scene::ICameraSceneNode* camera, float dt) +{ + irr_driver->setRTT(this); + + irr_driver->getSceneManager()->setActiveCamera(camera); + + std::vector glows; + irr_driver->computeCameraMatrix(camera, 512, 512); + unsigned plc = irr_driver->UpdateLightsInfo(camera, dt); + irr_driver->renderScene(camera, plc, glows, dt, false, true); + FrameBuffer* frame_buffer = irr_driver->getPostProcessing()->render(camera, false); + glViewport(0, 0, UserConfigParams::m_width, UserConfigParams::m_height); + + irr_driver->setRTT(NULL); + glBindFramebuffer(GL_FRAMEBUFFER, 0); + + irr_driver->getSceneManager()->setActiveCamera(NULL); + return frame_buffer; +} \ No newline at end of file diff --git a/src/graphics/rtts.hpp b/src/graphics/rtts.hpp index 2c080eeec..802001eca 100644 --- a/src/graphics/rtts.hpp +++ b/src/graphics/rtts.hpp @@ -45,6 +45,9 @@ public: unsigned getDepthStencilTexture() const { return DepthStencilTexture; } unsigned getRenderTarget(enum TypeRTT target) const { return RenderTargetTextures[target]; } FrameBuffer& getFBO(enum TypeFBO fbo) { return FrameBuffers[fbo]; } + + FrameBuffer* render(scene::ICameraSceneNode* camera, float dt); + private: unsigned RenderTargetTextures[RTT_COUNT]; PtrVector FrameBuffers; diff --git a/src/guiengine/widgets/model_view_widget.cpp b/src/guiengine/widgets/model_view_widget.cpp index a89ad3b5c..745500998 100644 --- a/src/guiengine/widgets/model_view_widget.cpp +++ b/src/guiengine/widgets/model_view_widget.cpp @@ -173,21 +173,9 @@ void ModelViewWidget::update(float delta) m_rtt_main_node->setRotation(core::vector3df(0.0f, angle, 0.0f)); m_rtt_main_node->setVisible(true); - irr_driver->setRTT(m_rtt_provider); - irr_driver->getSceneManager()->setActiveCamera(m_camera); + m_frame_buffer = m_rtt_provider->render(m_camera, GUIEngine::getLatestDt()); - std::vector glows; - irr_driver->computeCameraMatrix(m_camera, 512, 512); - unsigned plc = irr_driver->UpdateLightsInfo(m_camera, GUIEngine::getLatestDt()); - irr_driver->renderScene(m_camera, plc, glows, GUIEngine::getLatestDt(), false, true); - m_frame_buffer = irr_driver->getPostProcessing()->render(m_camera); - glViewport(0, 0, UserConfigParams::m_width, UserConfigParams::m_height); - - irr_driver->setRTT(NULL); - glBindFramebuffer(GL_FRAMEBUFFER, 0); - - irr_driver->getSceneManager()->setActiveCamera(NULL); m_rtt_main_node->setVisible(false); } @@ -284,10 +272,7 @@ void ModelViewWidget::setupRTTScene(PtrVector& mesh, m_camera->setAspectRatio(1.0f); m_camera->setPosition(core::vector3df(0.0, 20.0f, 70.0f)); - if (irr_driver->isGLSL()) - m_camera->setUpVector(core::vector3df(0.0, 1.0, 0.0)); - else - m_camera->setUpVector(core::vector3df(0.0, 1.0, 0.0)); + m_camera->setUpVector(core::vector3df(0.0, 1.0, 0.0)); m_camera->setTarget(core::vector3df(0, 10, 0.0f)); m_camera->setFOV(DEGREE_TO_RAD*50.0f); m_camera->updateAbsolutePosition(); diff --git a/src/states_screens/race_gui.cpp b/src/states_screens/race_gui.cpp index ae03ffe7e..700f955fa 100644 --- a/src/states_screens/race_gui.cpp +++ b/src/states_screens/race_gui.cpp @@ -342,19 +342,27 @@ void RaceGUI::drawGlobalMiniMap() // arenas currently don't have a map. if(world->getTrack()->isArena() || world->getTrack()->isSoccer()) return; - const video::ITexture *mini_map = world->getTrack()->getMiniMap(); + const video::ITexture *old_rtt_mini_map = world->getTrack()->getOldRttMiniMap(); + const FrameBuffer* new_rtt_mini_map = world->getTrack()->getNewRttMiniMap(); int upper_y = UserConfigParams::m_height - m_map_bottom - m_map_height; int lower_y = UserConfigParams::m_height - m_map_bottom; - if (mini_map != NULL) + core::rect dest(m_map_left, upper_y, + m_map_left + m_map_width, lower_y); + + if (old_rtt_mini_map != NULL) { - core::rect dest(m_map_left, upper_y, - m_map_left + m_map_width, lower_y); core::rect source(core::position2di(0, 0), - mini_map->getOriginalSize()); - draw2DImage(mini_map, dest, source, - NULL, NULL, true); + old_rtt_mini_map->getOriginalSize()); + draw2DImage(old_rtt_mini_map, dest, source, + NULL, NULL, true); + } + else if (new_rtt_mini_map != NULL) + { + core::rect source(0, 0, new_rtt_mini_map->getWidth(), new_rtt_mini_map->getHeight()); + draw2DImageFromRTT(new_rtt_mini_map->getRTT()[0], 512, 512, + dest, source, NULL, true); } for(unsigned int i=0; igetNumKarts(); i++) diff --git a/src/states_screens/race_gui_overworld.cpp b/src/states_screens/race_gui_overworld.cpp index 48b85fe91..208bd2360 100644 --- a/src/states_screens/race_gui_overworld.cpp +++ b/src/states_screens/race_gui_overworld.cpp @@ -321,17 +321,25 @@ void RaceGUIOverworld::drawGlobalMiniMap() } - const video::ITexture *mini_map = world->getTrack()->getMiniMap(); + const video::ITexture *old_rtt_mini_map = world->getTrack()->getOldRttMiniMap(); + const FrameBuffer* new_rtt_mini_map = world->getTrack()->getNewRttMiniMap(); int upper_y = m_map_bottom - m_map_height; int lower_y = m_map_bottom; - if (mini_map != NULL) + core::rect dest(m_map_left, upper_y, + m_map_left + m_map_width, lower_y); + + if (old_rtt_mini_map != NULL) { - core::rect dest(m_map_left, upper_y, - m_map_left + m_map_width, lower_y); - core::rect source(core::position2di(0, 0), mini_map->getOriginalSize()); - draw2DImage(mini_map, dest, source, 0, 0, true); + core::rect source(core::position2di(0, 0), old_rtt_mini_map->getOriginalSize()); + draw2DImage(old_rtt_mini_map, dest, source, 0, 0, true); + } + else if (new_rtt_mini_map != NULL) + { + core::rect source(0, 0, new_rtt_mini_map->getWidth(), new_rtt_mini_map->getHeight()); + draw2DImageFromRTT(new_rtt_mini_map->getRTT()[0], 512, 512, + dest, source, NULL, true); } Vec3 kart_xyz; diff --git a/src/tracks/quad_graph.cpp b/src/tracks/quad_graph.cpp index 528519058..70ffe9e9d 100644 --- a/src/tracks/quad_graph.cpp +++ b/src/tracks/quad_graph.cpp @@ -970,20 +970,35 @@ int QuadGraph::findOutOfRoadSector(const Vec3& xyz, //----------------------------------------------------------------------------- /** Takes a snapshot of the driveline quads so they can be used as minimap. */ -video::ITexture *QuadGraph::makeMiniMap(const core::dimension2du &origdimension, - const std::string &name, - const video::SColor &fill_color) +void QuadGraph::makeMiniMap(const core::dimension2du &origdimension, + const std::string &name, + const video::SColor &fill_color, + video::ITexture** oldRttMinimap, + FrameBuffer** newRttMinimap) { + *oldRttMinimap = NULL; + *newRttMinimap = NULL; + const core::dimension2du dimension = origdimension * 2; - IrrDriver::RTTProvider rttProvider(dimension, name, true); + RTT* newRttProvider = NULL; + IrrDriver::RTTProvider* oldRttProvider = NULL; + if (irr_driver->isGLSL()) + { + newRttProvider = new RTT(512, 512); + } + else + { + oldRttProvider = new IrrDriver::RTTProvider(dimension, name, true); + } + video::SColor red(128, 255, 0, 0); createMesh(/*show_invisible part of the track*/ false, /*enable_transparency*/ false, /*track_color*/ &fill_color, /*lap line color*/ &red ); - m_node = irr_driver->getSceneManager()->addMeshSceneNode(m_mesh); // add Debug Mesh + m_node = irr_driver->addMesh(m_mesh); #ifdef DEBUG m_node->setName("minimap-mesh"); #endif @@ -1035,28 +1050,47 @@ video::ITexture *QuadGraph::makeMiniMap(const core::dimension2du &origdimension, range, -1, bb_max.getY()-bb_min.getY()+1); camera->setProjectionMatrix(projection, true); + + irr_driver->suppressSkyBox(); + irr_driver->clearLights(); + // Adjust Y position by +1 for max, -1 for min - this helps in case that // the maximum Y coordinate is negative (otherwise the minimap is mirrored) // and avoids problems for tracks which have a flat (max Y = min Y) minimap. camera->setPosition(core::vector3df(center.getX(), bb_max.getY()+1, center.getZ())); camera->setUpVector(core::vector3df(0, 0, 1)); camera->setTarget(core::vector3df(center.getX(),bb_min.getY()-1,center.getZ())); + camera->setAspectRatio(1.0f); + camera->updateAbsolutePosition(); - video::ITexture *texture = rttProvider.renderToTexture(); + video::ITexture* texture = NULL; + FrameBuffer* frame_buffer = NULL; + if (irr_driver->isGLSL()) + { + frame_buffer = newRttProvider->render(camera, GUIEngine::getLatestDt()); + + // TODO: leak + //delete newRttProvider; + } + else + { + texture = oldRttProvider->renderToTexture(); + delete oldRttProvider; + } cleanupDebugMesh(); irr_driver->removeCameraSceneNode(camera); m_min_coord = bb_min; - if (texture == NULL) + if (texture == NULL && frame_buffer == NULL) { Log::error("Quad Graph", "[makeMiniMap] WARNING: RTT does not appear to work," "mini-map will not be available."); - return NULL; } - return texture; + *oldRttMinimap = texture; + *newRttMinimap = frame_buffer; } // makeMiniMap //----------------------------------------------------------------------------- diff --git a/src/tracks/quad_graph.hpp b/src/tracks/quad_graph.hpp index e4e58b260..23b71a6af 100644 --- a/src/tracks/quad_graph.hpp +++ b/src/tracks/quad_graph.hpp @@ -37,6 +37,7 @@ namespace irr using namespace irr; class CheckLine; +class FrameBuffer; /** * \brief This class stores a graph of quads. It uses a 'simplified singleton' @@ -118,10 +119,11 @@ public: float forwards_distance=1.5f, float sidewards_distance=1.5f, float upwards_distance=0.0f) const; - video::ITexture *makeMiniMap(const core::dimension2du &where, - const std::string &name, - const video::SColor &fill_color - =video::SColor(127, 255, 255, 255) ); + void makeMiniMap(const core::dimension2du &where, + const std::string &name, + const video::SColor &fill_color, + video::ITexture** oldRttMinimap, + FrameBuffer** newRttMinimap); void mapPoint2MiniMap(const Vec3 &xyz, Vec3 *out) const; void updateDistancesForAllSuccessors(unsigned int indx, float delta, diff --git a/src/tracks/track.cpp b/src/tracks/track.cpp index 02ecf8588..e44c6181a 100644 --- a/src/tracks/track.cpp +++ b/src/tracks/track.cpp @@ -115,7 +115,8 @@ Track::Track(const std::string &filename) m_is_soccer = false; m_is_cutscene = false; m_camera_far = 1000.0f; - m_mini_map = NULL; + m_old_rtt_mini_map = NULL; + m_new_rtt_mini_map = NULL; m_bloom = true; m_bloom_threshold = 0.75f; m_color_inlevel = core::vector3df(0.0,1.0, 255.0); @@ -273,13 +274,13 @@ void Track::cleanup() // Clear reminder of the link between textures and file names. irr_driver->clearTexturesFileName(); - for(unsigned int i=0; iremoveNode(m_all_nodes[i]); } @@ -310,37 +311,42 @@ void Track::cleanup() // than once are in m_all_cached_mesh more than once (which is easier // than storing the mesh only once, but then having to test for each // mesh if it is already contained in the list or not). - for(unsigned int i=0; idropAllTextures(m_all_cached_meshes[i]); // If a mesh is not in Irrlicht's texture cache, its refcount is // 1 (since its scene node was removed, so the only other reference // is in m_all_cached_meshes). In this case we only drop it once // and don't try to remove it from the cache. - if(m_all_cached_meshes[i]->getReferenceCount()==1) + if (m_all_cached_meshes[i]->getReferenceCount() == 1) { m_all_cached_meshes[i]->drop(); continue; } m_all_cached_meshes[i]->drop(); - if(m_all_cached_meshes[i]->getReferenceCount()==1) + if (m_all_cached_meshes[i]->getReferenceCount() == 1) irr_driver->removeMeshFromCache(m_all_cached_meshes[i]); } m_all_cached_meshes.clear(); // Now free meshes that are not associated to any scene node. - for (unsigned int i=0; idropAllTextures(m_detached_cached_meshes[i]); irr_driver->removeMeshFromCache(m_detached_cached_meshes[i]); } m_detached_cached_meshes.clear(); - if(m_mini_map) + if (m_old_rtt_mini_map) { - assert(m_mini_map->getReferenceCount()==1); - irr_driver->removeTexture(m_mini_map); - m_mini_map = NULL; + assert(m_old_rtt_mini_map->getReferenceCount() == 1); + irr_driver->removeTexture(m_old_rtt_mini_map); + m_old_rtt_mini_map = NULL; + } + if (m_new_rtt_mini_map) + { + delete m_new_rtt_mini_map; + m_new_rtt_mini_map = NULL; } for(unsigned int i=0; igetRaceGUI()->getMiniMapSize(); core::dimension2du size = m_mini_map_size .getOptimalSize(!nonpower,!nonsquare); - m_mini_map = QuadGraph::get()->makeMiniMap(size, "minimap::"+m_ident); - if (m_mini_map) + + QuadGraph::get()->makeMiniMap(size, "minimap::" + m_ident, video::SColor(127, 255, 255, 255), + &m_old_rtt_mini_map, &m_new_rtt_mini_map); + if (m_old_rtt_mini_map) { - m_minimap_x_scale = float(m_mini_map_size.Width) / float(m_mini_map->getSize().Width); - m_minimap_y_scale = float(m_mini_map_size.Height) / float(m_mini_map->getSize().Height); + m_minimap_x_scale = float(m_mini_map_size.Width) / float(m_old_rtt_mini_map->getSize().Width); + m_minimap_y_scale = float(m_mini_map_size.Height) / float(m_old_rtt_mini_map->getSize().Height); + } + else if (m_new_rtt_mini_map) + { + m_minimap_x_scale = float(m_mini_map_size.Width) / float(m_new_rtt_mini_map->getWidth()); + m_minimap_y_scale = float(m_mini_map_size.Height) / float(m_new_rtt_mini_map->getHeight()); } else { diff --git a/src/tracks/track.hpp b/src/tracks/track.hpp index 3c2b8acaa..1d7073569 100644 --- a/src/tracks/track.hpp +++ b/src/tracks/track.hpp @@ -371,7 +371,8 @@ private: video::SColor m_fog_color; /** The texture for the mini map, which is displayed in the race gui. */ - video::ITexture *m_mini_map; + video::ITexture *m_old_rtt_mini_map; + FrameBuffer *m_new_rtt_mini_map; core::dimension2du m_mini_map_size; float m_minimap_x_scale; float m_minimap_y_scale; @@ -448,7 +449,8 @@ public: std::vector< std::vector > buildHeightMap(); // ------------------------------------------------------------------------ /** Returns the texture with the mini map for this track. */ - const video::ITexture* getMiniMap () const { return m_mini_map; } + const video::ITexture* getOldRttMiniMap() const { return m_old_rtt_mini_map; } + const FrameBuffer* getNewRttMiniMap() const { return m_new_rtt_mini_map; } // ------------------------------------------------------------------------ const core::dimension2du& getMiniMapSize() const { return m_mini_map_size; } // ------------------------------------------------------------------------