diff --git a/src/graphics/irr_driver.cpp b/src/graphics/irr_driver.cpp index 888a2eba4..e540e9cf1 100644 --- a/src/graphics/irr_driver.cpp +++ b/src/graphics/irr_driver.cpp @@ -279,121 +279,6 @@ scene::ISceneNode *IrrDriver::addMesh(scene::IMesh *mesh) return m_scene_manager->addMeshSceneNode(mesh); } // addMesh -// ---------------------------------------------------------------------------- -/** Begins a rendering to a texture. - * \param dimension The size of the texture. - * \param name Name of the texture. - */ -#ifdef IRR_SVN -void IrrDriver::beginRenderToTexture(const core::dimension2du &dimension, - const std::string &name) -#else -void IrrDriver::beginRenderToTexture(const core::dimension2di &dimension, - const std::string &name) -#endif -{ - m_render_target_texture = m_video_driver->addRenderTargetTexture(dimension, - name.c_str()); - m_device->getVideoDriver()->setRenderTarget(m_render_target_texture); -} // beginRenderToTexture - -// ---------------------------------------------------------------------------- -/** Does the actual rendering to a texture, and switches the rendering system - * back to render on the screen. - * \return A pointer to the texture on which the scene was rendered. - */ -video::ITexture *IrrDriver::endRenderToTexture() -{ - m_scene_manager->drawAll(); - m_device->getVideoDriver()->setRenderTarget(0, false, false); - return m_render_target_texture; -} // endRenderToTexture - -// ---------------------------------------------------------------------------- -/** Renders a given vector of meshes onto a texture. Parameters: - * \param mesh Vector of meshes to render. - * \param mesh_location For each mesh the location where it should be - * positioned. - * \param target The texture to render the meshes to. - * \param angle Heading for all meshes. - */ -void IrrDriver::renderToTexture(ptr_vector& mesh, - std::vector& mesh_location, - ITexture* target, float angle) -{ - scene::ISceneNode* main_node = NULL; - - const int mesh_amount = mesh.size(); - for(int n=0; nsetParent(main_node); - } - - node->setPosition( mesh_location[n].toIrrVector() ); - node->updateAbsolutePosition(); - } - - main_node->setScale( core::vector3df(50.0f, 50.0f, 50.0f) ); - main_node->setRotation( core::vector3df(0, angle, 0) ); - - //vector3d< f32 > modelsize = mesh->getBoundingBox().getExtent(); - //std::cout << "box size " << modelsize.X*50.0 << ", " << modelsize.Y*50.0 << ", " << modelsize.Z*50.0 << std::endl; - - getSceneManager()->setAmbientLight(video::SColor(255, 120, 120, 120)); - - const core::vector3df &sun_pos = core::vector3df( 0, 200, 100.0f ); - scene::ILightSceneNode* light = getSceneManager()->addLightSceneNode(NULL, sun_pos, video::SColorf(1.0f,1.0f,1.0f), 10000.0f /* radius */); - //light->setLightType(ELT_DIRECTIONAL); // ELT_DIRECTIONAL , ELT_POINT - //light->getLightData().AmbientColor = irr::video::SColorf(0.5f, 0.5f, 0.5f, 1.0f); - //light->getLightData().Attenuation = core::vector3df(10, 10, 10); - light->getLightData().DiffuseColor = irr::video::SColorf(1.0f, 1.0f, 1.0f, 1.0f); - light->getLightData().SpecularColor = irr::video::SColorf(1.0f, 1.0f, 1.0f, 1.0f); - - main_node->setMaterialFlag(EMF_GOURAUD_SHADING , true); - main_node->setMaterialFlag(EMF_LIGHTING, true); - // node->setMaterialFlag(EMF_LIGHTING, true); - - const int materials = main_node->getMaterialCount(); - for(int n=0; ngetMaterial(n).setFlag(EMF_LIGHTING, true); - - main_node->getMaterial(n).Shininess = 200.0f; // set size of specular highlights - main_node->getMaterial(n).SpecularColor.set(255,150,150,150); - main_node->getMaterial(n).DiffuseColor.set(255,150,150,150); - - //node->getMaterial(n).setFlag(EMF_NORMALIZE_NORMALS , true); - main_node->getMaterial(n).setFlag(EMF_GOURAUD_SHADING , true); - main_node->getMaterial(n).GouraudShading = true; - } - - ICameraSceneNode* camera = m_scene_manager->addCameraSceneNode(); - - camera->setPosition( core::vector3df(0.0, 30.0f, 70.0f) ); - camera->setUpVector( core::vector3df(0.0, 1.0, 0.0) ); - camera->setTarget( core::vector3df(0, 10, 0.0f) ); - camera->updateAbsolutePosition(); - - m_device->getVideoDriver()->setRenderTarget(target); - //m_device->getVideoDriver()->beginScene(true, true, video::SColor(0,0,0,0)); - m_scene_manager->drawAll(); - //m_device->getVideoDriver()->endScene(); - - removeNode(main_node); - removeCamera(camera); - removeNode(light); - - m_device->getVideoDriver()->setRenderTarget(0, false, false); -} - // ---------------------------------------------------------------------------- /** Creates a quad mesh buffer and adds it to the scene graph. */ @@ -723,3 +608,133 @@ bool IrrDriver::OnEvent(const irr::SEvent &event) } // OnEvent // ---------------------------------------------------------------------------- + +#if 0 +#pragma mark - +#pragma mark RTT +#endif + +// ---------------------------------------------------------------------------- +/** Begins a rendering to a texture. + * \param dimension The size of the texture. + * \param name Name of the texture. + */ +#ifdef IRR_SVN +IrrDriver::RTTProvider::RTTProvider(const core::dimension2du &dimension, + const std::string &name) +#else +IrrDriver::RTTProvider::RTTProvider(const core::dimension2di &dimension, + const std::string &name) +#endif +{ + m_video_driver = irr_driver->getVideoDriver(); + + m_render_target_texture = m_video_driver->addRenderTargetTexture(dimension, + name.c_str()); + m_video_driver->setRenderTarget(m_render_target_texture); + + m_rtt_main_node = NULL; + m_camera = NULL; + m_light = NULL; +} +// ---------------------------------------------------------------------------- +IrrDriver::RTTProvider::~RTTProvider() +{ + tearDownRTTScene(); +} +// ---------------------------------------------------------------------------- +/** Sets up a given vector of meshes for render-to-texture. Parameters: + * \param mesh Vector of meshes to render. + * \param mesh_location For each mesh the location where it should be + * positioned. + */ +void IrrDriver::RTTProvider::setupRTTScene(ptr_vector& mesh, + std::vector& mesh_location) +{ + m_rtt_main_node = NULL; + + const int mesh_amount = mesh.size(); + for (int n=0; naddMesh(mesh.get(n)); + + if (m_rtt_main_node == NULL) + { + m_rtt_main_node = node; + } + else + { + node->setParent(m_rtt_main_node); + } + + node->setPosition( mesh_location[n].toIrrVector() ); + node->updateAbsolutePosition(); + } + + m_rtt_main_node->setScale( core::vector3df(50.0f, 50.0f, 50.0f) ); + + //vector3d< f32 > modelsize = mesh->getBoundingBox().getExtent(); + //std::cout << "box size " << modelsize.X*50.0 << ", " << modelsize.Y*50.0 << ", " << modelsize.Z*50.0 << std::endl; + + irr_driver->getSceneManager()->setAmbientLight(video::SColor(255, 120, 120, 120)); + + const core::vector3df &sun_pos = core::vector3df( 0, 200, 100.0f ); + m_light = irr_driver->getSceneManager()->addLightSceneNode(NULL, sun_pos, video::SColorf(1.0f,1.0f,1.0f), 10000.0f /* radius */); + //light->setLightType(ELT_DIRECTIONAL); // ELT_DIRECTIONAL , ELT_POINT + //light->getLightData().AmbientColor = irr::video::SColorf(0.5f, 0.5f, 0.5f, 1.0f); + //light->getLightData().Attenuation = core::vector3df(10, 10, 10); + m_light->getLightData().DiffuseColor = irr::video::SColorf(1.0f, 1.0f, 1.0f, 1.0f); + m_light->getLightData().SpecularColor = irr::video::SColorf(1.0f, 1.0f, 1.0f, 1.0f); + + m_rtt_main_node->setMaterialFlag(EMF_GOURAUD_SHADING , true); + m_rtt_main_node->setMaterialFlag(EMF_LIGHTING, true); + // node->setMaterialFlag(EMF_LIGHTING, true); + + const int materials = m_rtt_main_node->getMaterialCount(); + for (int n=0; ngetMaterial(n).setFlag(EMF_LIGHTING, true); + + m_rtt_main_node->getMaterial(n).Shininess = 200.0f; // set size of specular highlights + m_rtt_main_node->getMaterial(n).SpecularColor.set(255,150,150,150); + m_rtt_main_node->getMaterial(n).DiffuseColor.set(255,150,150,150); + + //node->getMaterial(n).setFlag(EMF_NORMALIZE_NORMALS , true); + m_rtt_main_node->getMaterial(n).setFlag(EMF_GOURAUD_SHADING , true); + m_rtt_main_node->getMaterial(n).GouraudShading = true; + } + + m_camera = irr_driver->getSceneManager()->addCameraSceneNode(); + + m_camera->setPosition( core::vector3df(0.0, 30.0f, 70.0f) ); + m_camera->setUpVector( core::vector3df(0.0, 1.0, 0.0) ); + m_camera->setTarget( core::vector3df(0, 10, 0.0f) ); + m_camera->updateAbsolutePosition(); +} + +void IrrDriver::RTTProvider::tearDownRTTScene() +{ + if (m_rtt_main_node != NULL) irr_driver->removeNode(m_rtt_main_node); + if (m_camera != NULL) irr_driver->removeCamera(m_camera); + if (m_light != NULL) irr_driver->removeNode(m_light); + + m_rtt_main_node = NULL; + m_camera = NULL; + m_light = NULL; +} + +/** + * Performs the actual render-to-texture + * \param target The texture to render the meshes to. + * \param angle (Optional) heading for all meshes. + */ +ITexture* IrrDriver::RTTProvider::renderToTexture(float angle) +{ + m_video_driver->setRenderTarget(m_render_target_texture); + irr_driver->getSceneManager()->drawAll(); + + if (angle != -1) m_rtt_main_node->setRotation( core::vector3df(0, angle, 0) ); + + m_video_driver->setRenderTarget(0, false, false); + return m_render_target_texture; +} diff --git a/src/graphics/irr_driver.hpp b/src/graphics/irr_driver.hpp index 836982a62..d4d2c572a 100644 --- a/src/graphics/irr_driver.hpp +++ b/src/graphics/irr_driver.hpp @@ -48,9 +48,7 @@ private: /** Irrlicht race font. */ irr::gui::IGUIFont *m_race_font; - /** A pointer to texture on which a scene is rendered. Only used - * in between beginRenderToTexture() and endRenderToTexture calls. */ - video::ITexture *m_render_target_texture; + void setAllMaterialFlags(scene::IAnimatedMesh *mesh) const; std::vector m_modes; @@ -115,22 +113,58 @@ public: */ unsigned int getRealTime() {return m_device->getTimer()->getRealTime(); } - void renderToTexture(ptr_vector& mesh, - std::vector& mesh_location, - video::ITexture* target, float angle); -#ifdef IRR_SVN - void beginRenderToTexture(const core::dimension2du &dimension, - const std::string &name); -#else - void beginRenderToTexture(const core::dimension2di &dimension, - const std::string &name); -#endif - video::ITexture *endRenderToTexture(); + void draw2dTriangle(const core::vector2df &a, const core::vector2df &b, const core::vector2df &c, const video::ITexture *texture = NULL, const video::SColor *ca=NULL, const video::SColor *cb=NULL, const video::SColor *cc=NULL); + + // --------------------- RTT -------------------- + /** + * 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 to prepare rendering of 3D objects + * but you can also manually set the scene/camera. If you use the factory 'setupRTTScene', cleanup can be + * done through 'tearDownRTTScene' (destructor will also do this). If you set it up manually, you need + * to clean it up manually. + */ + class RTTProvider + { + /** A pointer to texture on which a scene is rendered. Only used + * in between beginRenderToTexture() and endRenderToTexture calls. */ + video::ITexture *m_render_target_texture; + + /** Main node of the RTT scene */ + scene::ISceneNode *m_rtt_main_node; + + scene::ICameraSceneNode *m_camera; + + scene::ILightSceneNode *m_light; + + /** Irrlicht video driver. */ + video::IVideoDriver *m_video_driver; + + public: + #ifdef IRR_SVN + RTTProvider(const core::dimension2du &dimension, + const std::string &name); + #else + RTTProvider(const core::dimension2di &dimension, + const std::string &name); + #endif + + ~RTTProvider(); + + void setupRTTScene(ptr_vector& mesh, + std::vector& mesh_location); + + /** Optional 'angle' parameter will rotate the object added *through setupRTTScene* */ + video::ITexture* renderToTexture(float angle=-1); + + void tearDownRTTScene(); + + }; + }; // IrrDriver diff --git a/src/guiengine/widgets/model_view_widget.cpp b/src/guiengine/widgets/model_view_widget.cpp index af8ecc52b..a12ea122c 100644 --- a/src/guiengine/widgets/model_view_widget.cpp +++ b/src/guiengine/widgets/model_view_widget.cpp @@ -23,11 +23,15 @@ using namespace GUIEngine; ModelViewWidget::ModelViewWidget() { m_type = WTYPE_MODEL_VIEW; + m_rtt_provider = NULL; } // ----------------------------------------------------------------------------- ModelViewWidget::~ModelViewWidget() { GUIEngine::needsUpdate.remove(this); + + delete m_rtt_provider; + m_rtt_provider = NULL; } // ----------------------------------------------------------------------------- void ModelViewWidget::add() @@ -51,13 +55,6 @@ void ModelViewWidget::add() //m_element->setTabOrder(id); m_element->setTabGroup(false); m_element->setTabStop(false); - - std::string name = "model view "; name += m_properties[PROP_ID].c_str(); -#ifdef IRR_SVN - m_texture = GUIEngine::getDriver()->addRenderTargetTexture( core::dimension2d< u32 >(512, 512), name.c_str() ); -#else - m_texture = GUIEngine::getDriver()->addRenderTargetTexture( core::dimension2d< s32 >(512, 512), name.c_str() ); -#endif } // add // ----------------------------------------------------------------------------- @@ -65,6 +62,9 @@ void ModelViewWidget::clearModels() { m_models.clearWithoutDeleting(); m_model_location.clear(); + + delete m_rtt_provider; + m_rtt_provider = NULL; } // ----------------------------------------------------------------------------- void ModelViewWidget::addModel(irr::scene::IMesh* mesh, const Vec3& location) @@ -81,14 +81,29 @@ void ModelViewWidget::addModel(irr::scene::IMesh* mesh, const Vec3& location) //mat.setFlag(EMF_NORMALIZE_NORMALS, true); ((IGUIMeshViewer*)m_element)->setMaterial(mat); */ + + delete m_rtt_provider; + m_rtt_provider = NULL; } // ----------------------------------------------------------------------------- void ModelViewWidget::update(float delta) { angle += delta*25; - if(angle > 360) angle -= 360; + if (angle > 360) angle -= 360; - irr_driver->renderToTexture(m_models, m_model_location, m_texture, angle); + if (m_rtt_provider == NULL) + { + std::string name = "model view "; + name += m_properties[PROP_ID].c_str(); +#ifdef IRR_SVN + m_rtt_provider = new IrrDriver::RTTProvider(core::dimension2d< u32 >(512, 512), name ); +#else + m_rtt_provider = new IrrDriver::RTTProvider(core::dimension2d< s32 >(512, 512), name ); +#endif + m_rtt_provider->setupRTTScene(m_models, m_model_location); + } + + m_texture = m_rtt_provider->renderToTexture(angle); ((IGUIImage*)m_element)->setImage(m_texture); } diff --git a/src/guiengine/widgets/model_view_widget.hpp b/src/guiengine/widgets/model_view_widget.hpp index acc54f510..bb0a06883 100644 --- a/src/guiengine/widgets/model_view_widget.hpp +++ b/src/guiengine/widgets/model_view_widget.hpp @@ -22,12 +22,14 @@ #include +#include "graphics/irr_driver.hpp" #include "guiengine/widget.hpp" #include "utils/ptr_vector.hpp" using namespace irr; using namespace gui; + namespace GUIEngine { /** A model view widget. See guiengine/engine.hpp for a detailed overview */ @@ -38,6 +40,9 @@ namespace GUIEngine std::vector m_model_location; video::ITexture* m_texture; + + IrrDriver::RTTProvider* m_rtt_provider; + float angle; public: ModelViewWidget(); diff --git a/src/states_screens/kart_selection.cpp b/src/states_screens/kart_selection.cpp index 34e23136d..118a10744 100644 --- a/src/states_screens/kart_selection.cpp +++ b/src/states_screens/kart_selection.cpp @@ -387,9 +387,9 @@ namespace KartSelectionScreen const int modelMaxWidth = w; const int bestSize = std::min(modelMaxWidth, modelMaxHeight); const int modelY = y + player_name_h + player_id_h; - model_x = x + w/2 - (int)(bestSize*1.2f/2); + model_x = x + w/2 - (int)(bestSize/2); model_y = modelY + modelMaxHeight/2 - bestSize/2; - model_w = (int)(bestSize*1.2f); // FIXME : for some reason, it looks better this way, though full square should be ok + model_w = (int)(bestSize); model_h = bestSize; kart_name_x = x; diff --git a/src/states_screens/race_gui.cpp b/src/states_screens/race_gui.cpp index c5e98b0d9..92c35b0a2 100644 --- a/src/states_screens/race_gui.cpp +++ b/src/states_screens/race_gui.cpp @@ -82,11 +82,11 @@ void RaceGUI::createMarkerTexture() int radius = (m_marker_rendered_size>>1)-1; #ifdef IRR_SVN - irr_driver->beginRenderToTexture(core::dimension2du(m_marker_rendered_size * npower2, + IrrDriver::RTTProvider rttProvider(core::dimension2du(m_marker_rendered_size * npower2, m_marker_rendered_size), "RaceGUI::markers"); #else - irr_driver->beginRenderToTexture(core::dimension2di(m_marker_rendered_size * npower2, + IrrDriver::RTTProvider rttProvider(core::dimension2di(m_marker_rendered_size * npower2, m_marker_rendered_size), "RaceGUI::markers"); #endif @@ -125,7 +125,7 @@ void RaceGUI::createMarkerTexture() #endif } - m_marker = irr_driver->endRenderToTexture(); + m_marker = rttProvider.renderToTexture(); irr_driver->removeCamera(camera); } // createMarkerTexture diff --git a/src/tracks/quad_graph.cpp b/src/tracks/quad_graph.cpp index 3a9fa3694..72819d203 100644 --- a/src/tracks/quad_graph.cpp +++ b/src/tracks/quad_graph.cpp @@ -421,7 +421,7 @@ video::ITexture *QuadGraph::makeMiniMap(const core::dimension2di &dimension, const video::SColor &fill_color) #endif { - irr_driver->beginRenderToTexture(dimension, name); + IrrDriver::RTTProvider rttProvider(dimension, name); createMesh(); video::S3DVertex *v = (video::S3DVertex*)m_mesh_buffer->getVertices(); for(unsigned int i=0; igetVertexCount(); i++) @@ -446,7 +446,9 @@ video::ITexture *QuadGraph::makeMiniMap(const core::dimension2di &dimension, camera->setPosition(core::vector3df(center.getX(), bb_max.getZ(), center.getY())); camera->setUpVector(core::vector3df(0,0,1)); camera->setTarget(core::vector3df(center.getX(),0,center.getY())); - video::ITexture *texture=irr_driver->endRenderToTexture(); + + video::ITexture *texture = rttProvider.renderToTexture(); + cleanupDebugMesh(); irr_driver->removeCamera(camera); m_min_coord = bb_min;