diff options
author | Kahrl <kahrl@gmx.net> | 2013-07-03 02:22:39 +0200 |
---|---|---|
committer | Kahrl <kahrl@gmx.net> | 2013-07-03 03:24:28 +0200 |
commit | 8f1d5d34a6191346d7f8cb5e012053bcd19795c4 (patch) | |
tree | 05626dceb2ba4ce97ed79cb3f5d43c2dd5a12513 /src | |
parent | b1ef850877278d2af0b35f792e34b39258cf875f (diff) | |
download | minetest-8f1d5d34a6191346d7f8cb5e012053bcd19795c4.tar.gz minetest-8f1d5d34a6191346d7f8cb5e012053bcd19795c4.tar.bz2 minetest-8f1d5d34a6191346d7f8cb5e012053bcd19795c4.zip |
Move generateTextureFromMesh to TextureSource to fix a texture leak
TextureSource has a list of textures to delete (m_texture_trash) so this
provides a proper, non-hacky way to delete RTT textures. Also, the prior,
hacky way of deleting them seems to be broken (see pull request #803).
To avoid header file clutter by repeating the same long list of
arguments over and over again, store the arguments of
generateTextureFromMesh in a struct called TextureFromMeshParams.
Also fix issue #782 (Only use bilinear (and others) on item textures
when settings allow it).
Diffstat (limited to 'src')
-rw-r--r-- | src/itemdef.cpp | 60 | ||||
-rw-r--r-- | src/mesh.cpp | 77 | ||||
-rw-r--r-- | src/mesh.h | 16 | ||||
-rw-r--r-- | src/tile.cpp | 256 | ||||
-rw-r--r-- | src/tile.h | 23 |
5 files changed, 202 insertions, 230 deletions
diff --git a/src/itemdef.cpp b/src/itemdef.cpp index b582aef78..238ff58c0 100644 --- a/src/itemdef.cpp +++ b/src/itemdef.cpp @@ -229,7 +229,6 @@ public: #ifndef SERVER m_main_thread = get_current_thread_id(); - m_driver = NULL; #endif clear(); } @@ -246,13 +245,6 @@ public: delete cc; } - if (m_driver != NULL) { - for (unsigned int i = 0; i < m_extruded_textures.size(); i++) { - m_driver->removeTexture(m_extruded_textures[i]); - } - m_extruded_textures.clear(); - } - m_driver = NULL; #endif for (std::map<std::string, ItemDefinition*>::iterator iter = m_item_definitions.begin(); iter != m_item_definitions.end(); @@ -307,9 +299,6 @@ public: return m_item_definitions.find(name) != m_item_definitions.end(); } #ifndef SERVER -private: - static video::IVideoDriver * m_driver; - static std::vector<video::ITexture*> m_extruded_textures; public: ClientCached* createClientCachedDirect(const std::string &name, IGameDef *gamedef) const @@ -416,31 +405,25 @@ public: */ if(cc->inventory_texture == NULL) { - core::dimension2d<u32> dim(64,64); - std::string rtt_texture_name = "INVENTORY_" + TextureFromMeshParams params; + params.mesh = node_mesh; + params.dim.set(64, 64); + params.rtt_texture_name = "INVENTORY_" + def->name + "_RTT"; - v3f camera_position(0, 1.0, -1.5); - camera_position.rotateXZBy(45); - v3f camera_lookat(0, 0, 0); - core::CMatrix4<f32> camera_projection_matrix; + params.delete_texture_on_shutdown = true; + params.camera_position.set(0, 1.0, -1.5); + params.camera_position.rotateXZBy(45); + params.camera_lookat.set(0, 0, 0); // Set orthogonal projection - camera_projection_matrix.buildProjectionMatrixOrthoLH( + params.camera_projection_matrix.buildProjectionMatrixOrthoLH( 1.65, 1.65, 0, 100); + params.ambient_light.set(1.0, 0.2, 0.2, 0.2); + params.light_position.set(10, 100, -50); + params.light_color.set(1.0, 0.5, 0.5, 0.5); + params.light_radius = 1000; - video::SColorf ambient_light(0.2,0.2,0.2); - v3f light_position(10, 100, -50); - video::SColorf light_color(0.5,0.5,0.5); - f32 light_radius = 1000; - - cc->inventory_texture = generateTextureFromMesh( - node_mesh, device, dim, rtt_texture_name, - camera_position, - camera_lookat, - camera_projection_matrix, - ambient_light, - light_position, - light_color, - light_radius); + cc->inventory_texture = + tsrc->generateTextureFromMesh(params); // render-to-target didn't work if(cc->inventory_texture == NULL) @@ -449,13 +432,6 @@ public: tsrc->getTexture(f.tiledef[0].name); } } - else - { - if (m_driver == 0) - m_driver = driver; - - m_extruded_textures.push_back(cc->inventory_texture); - } /* Use the node mesh as the wield mesh @@ -681,9 +657,3 @@ IWritableItemDefManager* createItemDefManager() { return new CItemDefManager(); } - -#ifndef SERVER -//TODO very very very dirty hack! -video::IVideoDriver * CItemDefManager::m_driver = 0; -std::vector<video::ITexture*> CItemDefManager::m_extruded_textures; -#endif diff --git a/src/mesh.cpp b/src/mesh.cpp index fd35a3a06..a98cb8bf4 100644 --- a/src/mesh.cpp +++ b/src/mesh.cpp @@ -23,7 +23,6 @@ with this program; if not, write to the Free Software Foundation, Inc., #include <iostream> #include <IAnimatedMesh.h> #include <SAnimatedMesh.h> -#include <ICameraSceneNode.h> // In Irrlicht 1.8 the signature of ITexture::lock was changed from // (bool, u32) to (E_TEXTURE_LOCK_MODE, u32). @@ -407,79 +406,3 @@ void setMeshColorByNormalXYZ(scene::IMesh *mesh, } } } - -video::ITexture *generateTextureFromMesh(scene::IMesh *mesh, - IrrlichtDevice *device, - core::dimension2d<u32> dim, - std::string texture_name, - v3f camera_position, - v3f camera_lookat, - core::CMatrix4<f32> camera_projection_matrix, - video::SColorf ambient_light, - v3f light_position, - video::SColorf light_color, - f32 light_radius) -{ - video::IVideoDriver *driver = device->getVideoDriver(); - if(driver->queryFeature(video::EVDF_RENDER_TO_TARGET) == false) - { - static bool warned = false; - if(!warned) - { - errorstream<<"generateTextureFromMesh(): EVDF_RENDER_TO_TARGET" - " not supported."<<std::endl; - warned = true; - } - return NULL; - } - - // Create render target texture - video::ITexture *rtt = driver->addRenderTargetTexture( - dim, texture_name.c_str(), video::ECF_A8R8G8B8); - if(rtt == NULL) - { - errorstream<<"generateTextureFromMesh(): addRenderTargetTexture" - " returned NULL."<<std::endl; - return NULL; - } - - // Set render target - driver->setRenderTarget(rtt, false, true, video::SColor(0,0,0,0)); - - // Get a scene manager - scene::ISceneManager *smgr_main = device->getSceneManager(); - assert(smgr_main); - scene::ISceneManager *smgr = smgr_main->createNewSceneManager(); - assert(smgr); - - scene::IMeshSceneNode* meshnode = smgr->addMeshSceneNode(mesh, NULL, -1, v3f(0,0,0), v3f(0,0,0), v3f(1,1,1), true); - meshnode->setMaterialFlag(video::EMF_LIGHTING, true); - meshnode->setMaterialFlag(video::EMF_ANTI_ALIASING, true); - meshnode->setMaterialFlag(video::EMF_BILINEAR_FILTER, true); - - scene::ICameraSceneNode* camera = smgr->addCameraSceneNode(0, - camera_position, camera_lookat); - // second parameter of setProjectionMatrix (isOrthogonal) is ignored - camera->setProjectionMatrix(camera_projection_matrix, false); - - smgr->setAmbientLight(ambient_light); - smgr->addLightSceneNode(0, light_position, light_color, light_radius); - - // Render scene - driver->beginScene(true, true, video::SColor(0,0,0,0)); - smgr->drawAll(); - driver->endScene(); - - // NOTE: The scene nodes should not be dropped, otherwise - // smgr->drop() segfaults - /*cube->drop(); - camera->drop(); - light->drop();*/ - // Drop scene manager - smgr->drop(); - - // Unset render target - driver->setRenderTarget(0, false, true, 0); - - return rtt; -} diff --git a/src/mesh.h b/src/mesh.h index cf46e7f8f..a89bea385 100644 --- a/src/mesh.h +++ b/src/mesh.h @@ -69,20 +69,4 @@ void setMeshColorByNormalXYZ(scene::IMesh *mesh, const video::SColor &colorY, const video::SColor &colorZ); -/* - Render a mesh to a texture. - Returns NULL if render-to-texture failed. -*/ -video::ITexture *generateTextureFromMesh(scene::IMesh *mesh, - IrrlichtDevice *device, - core::dimension2d<u32> dim, - std::string texture_name, - v3f camera_position, - v3f camera_lookat, - core::CMatrix4<f32> camera_projection_matrix, - video::SColorf ambient_light, - v3f light_position, - video::SColorf light_color, - f32 light_radius); - #endif diff --git a/src/tile.cpp b/src/tile.cpp index da286fda9..1361d57e5 100644 --- a/src/tile.cpp +++ b/src/tile.cpp @@ -18,6 +18,7 @@ with this program; if not, write to the Free Software Foundation, Inc., */ #include "tile.h" +#include "irrlichttypes_extrabloated.h" #include "debug.h" #include "main.h" // for g_settings #include "filesys.h" @@ -238,7 +239,7 @@ public: return NULL; } // Primarily fetches from cache, secondarily tries to read from filesystem - video::IImage* getOrLoad(const std::string &name, IrrlichtDevice *device) + video::IImage* getOrLoad(const std::string &name, IrrlichtDevice *m_device) { std::map<std::string, video::IImage*>::iterator n; n = m_images.find(name); @@ -246,7 +247,7 @@ public: n->second->grab(); // Grab for caller return n->second; } - video::IVideoDriver* driver = device->getVideoDriver(); + video::IVideoDriver* driver = m_device->getVideoDriver(); std::string path = getTexturePath(name.c_str()); if(path == ""){ infostream<<"SourceImageCache::getOrLoad(): No path found for \"" @@ -378,6 +379,22 @@ public: // Shall be called from the main thread. void rebuildImagesAndTextures(); + // Render a mesh to a texture. + // Returns NULL if render-to-texture failed. + // Shall be called from the main thread. + video::ITexture* generateTextureFromMesh( + const TextureFromMeshParams ¶ms); + + // Generates an image from a full string like + // "stone.png^mineral_coal.png^[crack0". + // Shall be called from the main thread. + video::IImage* generateImageFromScratch(std::string name); + + // Generate image based on a string like "stone.png" or "[crack0". + // if baseimg is NULL, it is created. Otherwise stuff is made on it. + // Shall be called from the main thread. + bool generateImage(std::string part_of_name, video::IImage *& baseimg); + private: // The id of the thread that is allowed to use irrlicht directly @@ -406,6 +423,11 @@ private: // Textures that have been overwritten with other ones // but can't be deleted because the ITexture* might still be used std::list<video::ITexture*> m_texture_trash; + + // Cached settings needed for making textures from meshes + bool m_setting_trilinear_filter; + bool m_setting_bilinear_filter; + bool m_setting_anisotropic_filter; }; IWritableTextureSource* createTextureSource(IrrlichtDevice *device) @@ -425,6 +447,13 @@ TextureSource::TextureSource(IrrlichtDevice *device): // Add a NULL TextureInfo as the first index, named "" m_textureinfo_cache.push_back(TextureInfo("")); m_name_to_id[""] = 0; + + // Cache some settings + // Note: Since this is only done once, the game must be restarted + // for these settings to take effect + m_setting_trilinear_filter = g_settings->getBool("trilinear_filter"); + m_setting_bilinear_filter = g_settings->getBool("bilinear_filter"); + m_setting_anisotropic_filter = g_settings->getBool("anisotropic_filter"); } TextureSource::~TextureSource() @@ -539,20 +568,6 @@ core::dimension2d<u32> imageTransformDimension(u32 transform, core::dimension2d< void imageTransform(u32 transform, video::IImage *src, video::IImage *dst); /* - Generate image based on a string like "stone.png" or "[crack0". - if baseimg is NULL, it is created. Otherwise stuff is made on it. -*/ -bool generate_image(std::string part_of_name, video::IImage *& baseimg, - IrrlichtDevice *device, SourceImageCache *sourcecache); - -/* - Generates an image from a full string like - "stone.png^mineral_coal.png^[crack0". -*/ -video::IImage* generate_image_from_scratch(std::string name, - IrrlichtDevice *device, SourceImageCache *sourcecache); - -/* This method generates all the textures */ u32 TextureSource::getTextureIdDirect(const std::string &name) @@ -685,7 +700,7 @@ u32 TextureSource::getTextureIdDirect(const std::string &name) //infostream<<"last_part_of_name=\""<<last_part_of_name<<"\""<<std::endl; // Generate image according to part of name - if(!generate_image(last_part_of_name, baseimg, m_device, &m_sourcecache)) + if(!generateImage(last_part_of_name, baseimg)) { errorstream<<"getTextureIdDirect(): " "failed to generate \""<<last_part_of_name<<"\"" @@ -790,7 +805,7 @@ void TextureSource::insertSourceImage(const std::string &name, video::IImage *im m_sourcecache.insert(name, img, true, m_device->getVideoDriver()); m_source_image_existence.set(name, true); } - + void TextureSource::rebuildImagesAndTextures() { JMutexAutoLock lock(m_textureinfo_cache_mutex); @@ -800,8 +815,7 @@ void TextureSource::rebuildImagesAndTextures() // Recreate textures for(u32 i=0; i<m_textureinfo_cache.size(); i++){ TextureInfo *ti = &m_textureinfo_cache[i]; - video::IImage *img = - generate_image_from_scratch(ti->name, m_device, &m_sourcecache); + video::IImage *img = generateImageFromScratch(ti->name); // Create texture from resulting image video::ITexture *t = NULL; if(img) @@ -816,13 +830,90 @@ void TextureSource::rebuildImagesAndTextures() } } -video::IImage* generate_image_from_scratch(std::string name, - IrrlichtDevice *device, SourceImageCache *sourcecache) +video::ITexture* TextureSource::generateTextureFromMesh( + const TextureFromMeshParams ¶ms) { - /*infostream<<"generate_image_from_scratch(): " + video::IVideoDriver *driver = m_device->getVideoDriver(); + assert(driver); + + if(driver->queryFeature(video::EVDF_RENDER_TO_TARGET) == false) + { + static bool warned = false; + if(!warned) + { + errorstream<<"TextureSource::generateTextureFromMesh(): " + <<"EVDF_RENDER_TO_TARGET not supported."<<std::endl; + warned = true; + } + return NULL; + } + + // Create render target texture + video::ITexture *rtt = driver->addRenderTargetTexture( + params.dim, params.rtt_texture_name.c_str(), + video::ECF_A8R8G8B8); + if(rtt == NULL) + { + errorstream<<"TextureSource::generateTextureFromMesh(): " + <<"addRenderTargetTexture returned NULL."<<std::endl; + return NULL; + } + + // Set render target + driver->setRenderTarget(rtt, false, true, video::SColor(0,0,0,0)); + + // Get a scene manager + scene::ISceneManager *smgr_main = m_device->getSceneManager(); + assert(smgr_main); + scene::ISceneManager *smgr = smgr_main->createNewSceneManager(); + assert(smgr); + + scene::IMeshSceneNode* meshnode = smgr->addMeshSceneNode(params.mesh, NULL, -1, v3f(0,0,0), v3f(0,0,0), v3f(1,1,1), true); + meshnode->setMaterialFlag(video::EMF_LIGHTING, true); + meshnode->setMaterialFlag(video::EMF_ANTI_ALIASING, true); + meshnode->setMaterialFlag(video::EMF_TRILINEAR_FILTER, m_setting_trilinear_filter); + meshnode->setMaterialFlag(video::EMF_BILINEAR_FILTER, m_setting_bilinear_filter); + meshnode->setMaterialFlag(video::EMF_ANISOTROPIC_FILTER, m_setting_anisotropic_filter); + + scene::ICameraSceneNode* camera = smgr->addCameraSceneNode(0, + params.camera_position, params.camera_lookat); + // second parameter of setProjectionMatrix (isOrthogonal) is ignored + camera->setProjectionMatrix(params.camera_projection_matrix, false); + + smgr->setAmbientLight(params.ambient_light); + smgr->addLightSceneNode(0, + params.light_position, + params.light_color, + params.light_radius); + + // Render scene + driver->beginScene(true, true, video::SColor(0,0,0,0)); + smgr->drawAll(); + driver->endScene(); + + // NOTE: The scene nodes should not be dropped, otherwise + // smgr->drop() segfaults + /*cube->drop(); + camera->drop(); + light->drop();*/ + // Drop scene manager + smgr->drop(); + + // Unset render target + driver->setRenderTarget(0, false, true, 0); + + if(params.delete_texture_on_shutdown) + m_texture_trash.push_back(rtt); + + return rtt; +} + +video::IImage* TextureSource::generateImageFromScratch(std::string name) +{ + /*infostream<<"generateImageFromScratch(): " "\""<<name<<"\""<<std::endl;*/ - - video::IVideoDriver* driver = device->getVideoDriver(); + + video::IVideoDriver *driver = m_device->getVideoDriver(); assert(driver); /* @@ -835,12 +926,6 @@ video::IImage* generate_image_from_scratch(std::string name, // Find last meta separator in name s32 last_separator_position = name.find_last_of(separator); - //if(last_separator_position == std::npos) - // last_separator_position = -1; - - /*infostream<<"generate_image_from_scratch(): " - <<"last_separator_position="<<last_separator_position - <<std::endl;*/ /* If separator was found, construct the base name and make the @@ -851,11 +936,7 @@ video::IImage* generate_image_from_scratch(std::string name, { // Construct base name base_image_name = name.substr(0, last_separator_position); - /*infostream<<"generate_image_from_scratch(): Calling itself recursively" - " to get base image of \""<<name<<"\" = \"" - <<base_image_name<<"\""<<std::endl;*/ - baseimg = generate_image_from_scratch(base_image_name, device, - sourcecache); + baseimg = generateImageFromScratch(base_image_name); } /* @@ -864,12 +945,11 @@ video::IImage* generate_image_from_scratch(std::string name, */ std::string last_part_of_name = name.substr(last_separator_position+1); - //infostream<<"last_part_of_name=\""<<last_part_of_name<<"\""<<std::endl; // Generate image according to part of name - if(!generate_image(last_part_of_name, baseimg, device, sourcecache)) + if(!generateImage(last_part_of_name, baseimg)) { - errorstream<<"generate_image_from_scratch(): " + errorstream<<"generateImageFromScratch(): " "failed to generate \""<<last_part_of_name<<"\"" <<std::endl; return NULL; @@ -878,23 +958,22 @@ video::IImage* generate_image_from_scratch(std::string name, return baseimg; } -bool generate_image(std::string part_of_name, video::IImage *& baseimg, - IrrlichtDevice *device, SourceImageCache *sourcecache) +bool TextureSource::generateImage(std::string part_of_name, video::IImage *& baseimg) { - video::IVideoDriver* driver = device->getVideoDriver(); + video::IVideoDriver* driver = m_device->getVideoDriver(); assert(driver); // Stuff starting with [ are special commands if(part_of_name.size() == 0 || part_of_name[0] != '[') { - video::IImage *image = sourcecache->getOrLoad(part_of_name, device); + video::IImage *image = m_sourcecache.getOrLoad(part_of_name, m_device); if(image == NULL) { if(part_of_name != ""){ - errorstream<<"generate_image(): Could not load image \"" + errorstream<<"generateImage(): Could not load image \"" <<part_of_name<<"\""<<" while building texture"<<std::endl; - errorstream<<"generate_image(): Creating a dummy" + errorstream<<"generateImage(): Creating a dummy" <<" image for \""<<part_of_name<<"\""<<std::endl; } @@ -955,7 +1034,7 @@ bool generate_image(std::string part_of_name, video::IImage *& baseimg, { // A special texture modification - /*infostream<<"generate_image(): generating special " + /*infostream<<"generateImage(): generating special " <<"modification \""<<part_of_name<<"\"" <<std::endl;*/ @@ -967,7 +1046,7 @@ bool generate_image(std::string part_of_name, video::IImage *& baseimg, { if(baseimg == NULL) { - errorstream<<"generate_image(): baseimg==NULL " + errorstream<<"generateImage(): baseimg==NULL " <<"for part_of_name=\""<<part_of_name <<"\", cancelling."<<std::endl; return false; @@ -996,8 +1075,8 @@ bool generate_image(std::string part_of_name, video::IImage *& baseimg, It is an image with a number of cracking stages horizontally tiled. */ - video::IImage *img_crack = sourcecache->getOrLoad( - "crack_anylength.png", device); + video::IImage *img_crack = m_sourcecache.getOrLoad( + "crack_anylength.png", m_device); if(img_crack && progression >= 0) { @@ -1080,7 +1159,7 @@ bool generate_image(std::string part_of_name, video::IImage *& baseimg, infostream<<"Adding \""<<filename <<"\" to combined ("<<x<<","<<y<<")" <<std::endl; - video::IImage *img = sourcecache->getOrLoad(filename, device); + video::IImage *img = m_sourcecache.getOrLoad(filename, m_device); if(img) { core::dimension2d<u32> dim = img->getDimension(); @@ -1111,7 +1190,7 @@ bool generate_image(std::string part_of_name, video::IImage *& baseimg, { if(baseimg == NULL) { - errorstream<<"generate_image(): baseimg==NULL " + errorstream<<"generateImage(): baseimg==NULL " <<"for part_of_name=\""<<part_of_name <<"\", cancelling."<<std::endl; return false; @@ -1130,7 +1209,7 @@ bool generate_image(std::string part_of_name, video::IImage *& baseimg, { if(baseimg == NULL) { - errorstream<<"generate_image(): baseimg==NULL " + errorstream<<"generateImage(): baseimg==NULL " <<"for part_of_name=\""<<part_of_name <<"\", cancelling."<<std::endl; return false; @@ -1155,7 +1234,7 @@ bool generate_image(std::string part_of_name, video::IImage *& baseimg, { if(baseimg == NULL) { - errorstream<<"generate_image(): baseimg==NULL " + errorstream<<"generateImage(): baseimg==NULL " <<"for part_of_name=\""<<part_of_name <<"\", cancelling."<<std::endl; return false; @@ -1212,7 +1291,7 @@ bool generate_image(std::string part_of_name, video::IImage *& baseimg, { if(baseimg == NULL) { - errorstream<<"generate_image(): baseimg==NULL " + errorstream<<"generateImage(): baseimg==NULL " <<"for part_of_name=\""<<part_of_name <<"\", cancelling."<<std::endl; return false; @@ -1240,7 +1319,7 @@ bool generate_image(std::string part_of_name, video::IImage *& baseimg, { if(baseimg != NULL) { - errorstream<<"generate_image(): baseimg!=NULL " + errorstream<<"generateImage(): baseimg!=NULL " <<"for part_of_name=\""<<part_of_name <<"\", cancelling."<<std::endl; return false; @@ -1254,12 +1333,12 @@ bool generate_image(std::string part_of_name, video::IImage *& baseimg, std::string imagename_right = sf.next("{"); // Generate images for the faces of the cube - video::IImage *img_top = generate_image_from_scratch( - imagename_top, device, sourcecache); - video::IImage *img_left = generate_image_from_scratch( - imagename_left, device, sourcecache); - video::IImage *img_right = generate_image_from_scratch( - imagename_right, device, sourcecache); + video::IImage *img_top = + generateImageFromScratch(imagename_top); + video::IImage *img_left = + generateImageFromScratch(imagename_left); + video::IImage *img_right = + generateImageFromScratch(imagename_right); assert(img_top && img_left && img_right); // Create textures from images @@ -1288,31 +1367,25 @@ bool generate_image(std::string part_of_name, video::IImage *& baseimg, cube->getMeshBuffer(4)->getMaterial().setTexture(0, texture_left); cube->getMeshBuffer(5)->getMaterial().setTexture(0, texture_left); - core::dimension2d<u32> dim(64,64); - std::string rtt_texture_name = part_of_name + "_RTT"; - - v3f camera_position(0, 1.0, -1.5); - camera_position.rotateXZBy(45); - v3f camera_lookat(0, 0, 0); - core::CMatrix4<f32> camera_projection_matrix; + TextureFromMeshParams params; + params.mesh = cube; + params.dim.set(64, 64); + params.rtt_texture_name = part_of_name + "_RTT"; + // We will delete the rtt texture ourselves + params.delete_texture_on_shutdown = false; + params.camera_position.set(0, 1.0, -1.5); + params.camera_position.rotateXZBy(45); + params.camera_lookat.set(0, 0, 0); // Set orthogonal projection - camera_projection_matrix.buildProjectionMatrixOrthoLH( + params.camera_projection_matrix.buildProjectionMatrixOrthoLH( 1.65, 1.65, 0, 100); - video::SColorf ambient_light(0.2,0.2,0.2); - v3f light_position(10, 100, -50); - video::SColorf light_color(0.5,0.5,0.5); - f32 light_radius = 1000; - - video::ITexture *rtt = generateTextureFromMesh( - cube, device, dim, rtt_texture_name, - camera_position, - camera_lookat, - camera_projection_matrix, - ambient_light, - light_position, - light_color, - light_radius); + params.ambient_light.set(1.0, 0.2, 0.2, 0.2); + params.light_position.set(10, 100, -50); + params.light_color.set(1.0, 0.5, 0.5, 0.5); + params.light_radius = 1000; + + video::ITexture *rtt = generateTextureFromMesh(params); // Drop mesh cube->drop(); @@ -1324,19 +1397,18 @@ bool generate_image(std::string part_of_name, video::IImage *& baseimg, if(rtt == NULL) { - baseimg = generate_image_from_scratch( - imagename_top, device, sourcecache); + baseimg = generateImageFromScratch(imagename_top); return true; } // Create image of render target - video::IImage *image = driver->createImage(rtt, v2s32(0,0), dim); + video::IImage *image = driver->createImage(rtt, v2s32(0,0), params.dim); assert(image); - //cleanup texture + // Cleanup texture driver->removeTexture(rtt); - baseimg = driver->createImage(video::ECF_A8R8G8B8, dim); + baseimg = driver->createImage(video::ECF_A8R8G8B8, params.dim); if(image) { @@ -1358,7 +1430,7 @@ bool generate_image(std::string part_of_name, video::IImage *& baseimg, if(baseimg == NULL) baseimg = driver->createImage(video::ECF_A8R8G8B8, v2u32(16,16)); - video::IImage *img = sourcecache->getOrLoad(filename, device); + video::IImage *img = m_sourcecache.getOrLoad(filename, m_device); if(img) { core::dimension2d<u32> dim = img->getDimension(); @@ -1392,7 +1464,7 @@ bool generate_image(std::string part_of_name, video::IImage *& baseimg, u32 frame_index = stoi(sf.next(":")); if(baseimg == NULL){ - errorstream<<"generate_image(): baseimg!=NULL " + errorstream<<"generateImage(): baseimg!=NULL " <<"for part_of_name=\""<<part_of_name <<"\", cancelling."<<std::endl; return false; @@ -1404,7 +1476,7 @@ bool generate_image(std::string part_of_name, video::IImage *& baseimg, video::IImage *img = driver->createImage(video::ECF_A8R8G8B8, frame_size); if(!img){ - errorstream<<"generate_image(): Could not create image " + errorstream<<"generateImage(): Could not create image " <<"for part_of_name=\""<<part_of_name <<"\", cancelling."<<std::endl; return false; @@ -1426,7 +1498,7 @@ bool generate_image(std::string part_of_name, video::IImage *& baseimg, } else { - errorstream<<"generate_image(): Invalid " + errorstream<<"generateImage(): Invalid " " modification: \""<<part_of_name<<"\""<<std::endl; } } diff --git a/src/tile.h b/src/tile.h index 144cb6475..8008d2127 100644 --- a/src/tile.h +++ b/src/tile.h @@ -58,6 +58,25 @@ std::string getImagePath(std::string path); std::string getTexturePath(const std::string &filename); /* + ITextureSource::generateTextureFromMesh parameters +*/ +namespace irr {namespace scene {class IMesh;}} +struct TextureFromMeshParams +{ + scene::IMesh *mesh; + core::dimension2d<u32> dim; + std::string rtt_texture_name; + bool delete_texture_on_shutdown; + v3f camera_position; + v3f camera_lookat; + core::CMatrix4<f32> camera_projection_matrix; + video::SColorf ambient_light; + v3f light_position; + video::SColorf light_color; + f32 light_radius; +}; + +/* TextureSource creates and caches textures. */ @@ -78,6 +97,8 @@ public: virtual IrrlichtDevice* getDevice() {return NULL;} virtual bool isKnownSourceImage(const std::string &name)=0; + virtual video::ITexture* generateTextureFromMesh( + const TextureFromMeshParams ¶ms)=0; }; class IWritableTextureSource : public ITextureSource @@ -100,6 +121,8 @@ public: virtual void processQueue()=0; virtual void insertSourceImage(const std::string &name, video::IImage *img)=0; virtual void rebuildImagesAndTextures()=0; + virtual video::ITexture* generateTextureFromMesh( + const TextureFromMeshParams ¶ms)=0; }; IWritableTextureSource* createTextureSource(IrrlichtDevice *device); |