Skip to content

Commit 8f1d5d3

Browse files
committedJul 3, 2013
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).
1 parent b1ef850 commit 8f1d5d3

File tree

5 files changed

+202
-230
lines changed

5 files changed

+202
-230
lines changed
 

‎src/itemdef.cpp

+15-45
Original file line numberDiff line numberDiff line change
@@ -229,7 +229,6 @@ class CItemDefManager: public IWritableItemDefManager
229229

230230
#ifndef SERVER
231231
m_main_thread = get_current_thread_id();
232-
m_driver = NULL;
233232
#endif
234233
clear();
235234
}
@@ -246,13 +245,6 @@ class CItemDefManager: public IWritableItemDefManager
246245
delete cc;
247246
}
248247

249-
if (m_driver != NULL) {
250-
for (unsigned int i = 0; i < m_extruded_textures.size(); i++) {
251-
m_driver->removeTexture(m_extruded_textures[i]);
252-
}
253-
m_extruded_textures.clear();
254-
}
255-
m_driver = NULL;
256248
#endif
257249
for (std::map<std::string, ItemDefinition*>::iterator iter =
258250
m_item_definitions.begin(); iter != m_item_definitions.end();
@@ -307,9 +299,6 @@ class CItemDefManager: public IWritableItemDefManager
307299
return m_item_definitions.find(name) != m_item_definitions.end();
308300
}
309301
#ifndef SERVER
310-
private:
311-
static video::IVideoDriver * m_driver;
312-
static std::vector<video::ITexture*> m_extruded_textures;
313302
public:
314303
ClientCached* createClientCachedDirect(const std::string &name,
315304
IGameDef *gamedef) const
@@ -416,31 +405,25 @@ class CItemDefManager: public IWritableItemDefManager
416405
*/
417406
if(cc->inventory_texture == NULL)
418407
{
419-
core::dimension2d<u32> dim(64,64);
420-
std::string rtt_texture_name = "INVENTORY_"
408+
TextureFromMeshParams params;
409+
params.mesh = node_mesh;
410+
params.dim.set(64, 64);
411+
params.rtt_texture_name = "INVENTORY_"
421412
+ def->name + "_RTT";
422-
v3f camera_position(0, 1.0, -1.5);
423-
camera_position.rotateXZBy(45);
424-
v3f camera_lookat(0, 0, 0);
425-
core::CMatrix4<f32> camera_projection_matrix;
413+
params.delete_texture_on_shutdown = true;
414+
params.camera_position.set(0, 1.0, -1.5);
415+
params.camera_position.rotateXZBy(45);
416+
params.camera_lookat.set(0, 0, 0);
426417
// Set orthogonal projection
427-
camera_projection_matrix.buildProjectionMatrixOrthoLH(
418+
params.camera_projection_matrix.buildProjectionMatrixOrthoLH(
428419
1.65, 1.65, 0, 100);
420+
params.ambient_light.set(1.0, 0.2, 0.2, 0.2);
421+
params.light_position.set(10, 100, -50);
422+
params.light_color.set(1.0, 0.5, 0.5, 0.5);
423+
params.light_radius = 1000;
429424

430-
video::SColorf ambient_light(0.2,0.2,0.2);
431-
v3f light_position(10, 100, -50);
432-
video::SColorf light_color(0.5,0.5,0.5);
433-
f32 light_radius = 1000;
434-
435-
cc->inventory_texture = generateTextureFromMesh(
436-
node_mesh, device, dim, rtt_texture_name,
437-
camera_position,
438-
camera_lookat,
439-
camera_projection_matrix,
440-
ambient_light,
441-
light_position,
442-
light_color,
443-
light_radius);
425+
cc->inventory_texture =
426+
tsrc->generateTextureFromMesh(params);
444427

445428
// render-to-target didn't work
446429
if(cc->inventory_texture == NULL)
@@ -449,13 +432,6 @@ class CItemDefManager: public IWritableItemDefManager
449432
tsrc->getTexture(f.tiledef[0].name);
450433
}
451434
}
452-
else
453-
{
454-
if (m_driver == 0)
455-
m_driver = driver;
456-
457-
m_extruded_textures.push_back(cc->inventory_texture);
458-
}
459435

460436
/*
461437
Use the node mesh as the wield mesh
@@ -681,9 +657,3 @@ IWritableItemDefManager* createItemDefManager()
681657
{
682658
return new CItemDefManager();
683659
}
684-
685-
#ifndef SERVER
686-
//TODO very very very dirty hack!
687-
video::IVideoDriver * CItemDefManager::m_driver = 0;
688-
std::vector<video::ITexture*> CItemDefManager::m_extruded_textures;
689-
#endif

‎src/mesh.cpp

-77
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,6 @@ with this program; if not, write to the Free Software Foundation, Inc.,
2323
#include <iostream>
2424
#include <IAnimatedMesh.h>
2525
#include <SAnimatedMesh.h>
26-
#include <ICameraSceneNode.h>
2726

2827
// In Irrlicht 1.8 the signature of ITexture::lock was changed from
2928
// (bool, u32) to (E_TEXTURE_LOCK_MODE, u32).
@@ -407,79 +406,3 @@ void setMeshColorByNormalXYZ(scene::IMesh *mesh,
407406
}
408407
}
409408
}
410-
411-
video::ITexture *generateTextureFromMesh(scene::IMesh *mesh,
412-
IrrlichtDevice *device,
413-
core::dimension2d<u32> dim,
414-
std::string texture_name,
415-
v3f camera_position,
416-
v3f camera_lookat,
417-
core::CMatrix4<f32> camera_projection_matrix,
418-
video::SColorf ambient_light,
419-
v3f light_position,
420-
video::SColorf light_color,
421-
f32 light_radius)
422-
{
423-
video::IVideoDriver *driver = device->getVideoDriver();
424-
if(driver->queryFeature(video::EVDF_RENDER_TO_TARGET) == false)
425-
{
426-
static bool warned = false;
427-
if(!warned)
428-
{
429-
errorstream<<"generateTextureFromMesh(): EVDF_RENDER_TO_TARGET"
430-
" not supported."<<std::endl;
431-
warned = true;
432-
}
433-
return NULL;
434-
}
435-
436-
// Create render target texture
437-
video::ITexture *rtt = driver->addRenderTargetTexture(
438-
dim, texture_name.c_str(), video::ECF_A8R8G8B8);
439-
if(rtt == NULL)
440-
{
441-
errorstream<<"generateTextureFromMesh(): addRenderTargetTexture"
442-
" returned NULL."<<std::endl;
443-
return NULL;
444-
}
445-
446-
// Set render target
447-
driver->setRenderTarget(rtt, false, true, video::SColor(0,0,0,0));
448-
449-
// Get a scene manager
450-
scene::ISceneManager *smgr_main = device->getSceneManager();
451-
assert(smgr_main);
452-
scene::ISceneManager *smgr = smgr_main->createNewSceneManager();
453-
assert(smgr);
454-
455-
scene::IMeshSceneNode* meshnode = smgr->addMeshSceneNode(mesh, NULL, -1, v3f(0,0,0), v3f(0,0,0), v3f(1,1,1), true);
456-
meshnode->setMaterialFlag(video::EMF_LIGHTING, true);
457-
meshnode->setMaterialFlag(video::EMF_ANTI_ALIASING, true);
458-
meshnode->setMaterialFlag(video::EMF_BILINEAR_FILTER, true);
459-
460-
scene::ICameraSceneNode* camera = smgr->addCameraSceneNode(0,
461-
camera_position, camera_lookat);
462-
// second parameter of setProjectionMatrix (isOrthogonal) is ignored
463-
camera->setProjectionMatrix(camera_projection_matrix, false);
464-
465-
smgr->setAmbientLight(ambient_light);
466-
smgr->addLightSceneNode(0, light_position, light_color, light_radius);
467-
468-
// Render scene
469-
driver->beginScene(true, true, video::SColor(0,0,0,0));
470-
smgr->drawAll();
471-
driver->endScene();
472-
473-
// NOTE: The scene nodes should not be dropped, otherwise
474-
// smgr->drop() segfaults
475-
/*cube->drop();
476-
camera->drop();
477-
light->drop();*/
478-
// Drop scene manager
479-
smgr->drop();
480-
481-
// Unset render target
482-
driver->setRenderTarget(0, false, true, 0);
483-
484-
return rtt;
485-
}

‎src/mesh.h

-16
Original file line numberDiff line numberDiff line change
@@ -69,20 +69,4 @@ void setMeshColorByNormalXYZ(scene::IMesh *mesh,
6969
const video::SColor &colorY,
7070
const video::SColor &colorZ);
7171

72-
/*
73-
Render a mesh to a texture.
74-
Returns NULL if render-to-texture failed.
75-
*/
76-
video::ITexture *generateTextureFromMesh(scene::IMesh *mesh,
77-
IrrlichtDevice *device,
78-
core::dimension2d<u32> dim,
79-
std::string texture_name,
80-
v3f camera_position,
81-
v3f camera_lookat,
82-
core::CMatrix4<f32> camera_projection_matrix,
83-
video::SColorf ambient_light,
84-
v3f light_position,
85-
video::SColorf light_color,
86-
f32 light_radius);
87-
8872
#endif

‎src/tile.cpp

+164-92
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
1818
*/
1919

2020
#include "tile.h"
21+
#include "irrlichttypes_extrabloated.h"
2122
#include "debug.h"
2223
#include "main.h" // for g_settings
2324
#include "filesys.h"
@@ -238,15 +239,15 @@ class SourceImageCache
238239
return NULL;
239240
}
240241
// Primarily fetches from cache, secondarily tries to read from filesystem
241-
video::IImage* getOrLoad(const std::string &name, IrrlichtDevice *device)
242+
video::IImage* getOrLoad(const std::string &name, IrrlichtDevice *m_device)
242243
{
243244
std::map<std::string, video::IImage*>::iterator n;
244245
n = m_images.find(name);
245246
if(n != m_images.end()){
246247
n->second->grab(); // Grab for caller
247248
return n->second;
248249
}
249-
video::IVideoDriver* driver = device->getVideoDriver();
250+
video::IVideoDriver* driver = m_device->getVideoDriver();
250251
std::string path = getTexturePath(name.c_str());
251252
if(path == ""){
252253
infostream<<"SourceImageCache::getOrLoad(): No path found for \""
@@ -378,6 +379,22 @@ class TextureSource : public IWritableTextureSource
378379
// Shall be called from the main thread.
379380
void rebuildImagesAndTextures();
380381

382+
// Render a mesh to a texture.
383+
// Returns NULL if render-to-texture failed.
384+
// Shall be called from the main thread.
385+
video::ITexture* generateTextureFromMesh(
386+
const TextureFromMeshParams &params);
387+
388+
// Generates an image from a full string like
389+
// "stone.png^mineral_coal.png^[crack0".
390+
// Shall be called from the main thread.
391+
video::IImage* generateImageFromScratch(std::string name);
392+
393+
// Generate image based on a string like "stone.png" or "[crack0".
394+
// if baseimg is NULL, it is created. Otherwise stuff is made on it.
395+
// Shall be called from the main thread.
396+
bool generateImage(std::string part_of_name, video::IImage *& baseimg);
397+
381398
private:
382399

383400
// The id of the thread that is allowed to use irrlicht directly
@@ -406,6 +423,11 @@ class TextureSource : public IWritableTextureSource
406423
// Textures that have been overwritten with other ones
407424
// but can't be deleted because the ITexture* might still be used
408425
std::list<video::ITexture*> m_texture_trash;
426+
427+
// Cached settings needed for making textures from meshes
428+
bool m_setting_trilinear_filter;
429+
bool m_setting_bilinear_filter;
430+
bool m_setting_anisotropic_filter;
409431
};
410432

411433
IWritableTextureSource* createTextureSource(IrrlichtDevice *device)
@@ -425,6 +447,13 @@ TextureSource::TextureSource(IrrlichtDevice *device):
425447
// Add a NULL TextureInfo as the first index, named ""
426448
m_textureinfo_cache.push_back(TextureInfo(""));
427449
m_name_to_id[""] = 0;
450+
451+
// Cache some settings
452+
// Note: Since this is only done once, the game must be restarted
453+
// for these settings to take effect
454+
m_setting_trilinear_filter = g_settings->getBool("trilinear_filter");
455+
m_setting_bilinear_filter = g_settings->getBool("bilinear_filter");
456+
m_setting_anisotropic_filter = g_settings->getBool("anisotropic_filter");
428457
}
429458

430459
TextureSource::~TextureSource()
@@ -538,20 +567,6 @@ core::dimension2d<u32> imageTransformDimension(u32 transform, core::dimension2d<
538567
// Apply transform to image data
539568
void imageTransform(u32 transform, video::IImage *src, video::IImage *dst);
540569

541-
/*
542-
Generate image based on a string like "stone.png" or "[crack0".
543-
if baseimg is NULL, it is created. Otherwise stuff is made on it.
544-
*/
545-
bool generate_image(std::string part_of_name, video::IImage *& baseimg,
546-
IrrlichtDevice *device, SourceImageCache *sourcecache);
547-
548-
/*
549-
Generates an image from a full string like
550-
"stone.png^mineral_coal.png^[crack0".
551-
*/
552-
video::IImage* generate_image_from_scratch(std::string name,
553-
IrrlichtDevice *device, SourceImageCache *sourcecache);
554-
555570
/*
556571
This method generates all the textures
557572
*/
@@ -685,7 +700,7 @@ u32 TextureSource::getTextureIdDirect(const std::string &name)
685700
//infostream<<"last_part_of_name=\""<<last_part_of_name<<"\""<<std::endl;
686701

687702
// Generate image according to part of name
688-
if(!generate_image(last_part_of_name, baseimg, m_device, &m_sourcecache))
703+
if(!generateImage(last_part_of_name, baseimg))
689704
{
690705
errorstream<<"getTextureIdDirect(): "
691706
"failed to generate \""<<last_part_of_name<<"\""
@@ -790,7 +805,7 @@ void TextureSource::insertSourceImage(const std::string &name, video::IImage *im
790805
m_sourcecache.insert(name, img, true, m_device->getVideoDriver());
791806
m_source_image_existence.set(name, true);
792807
}
793-
808+
794809
void TextureSource::rebuildImagesAndTextures()
795810
{
796811
JMutexAutoLock lock(m_textureinfo_cache_mutex);
@@ -800,8 +815,7 @@ void TextureSource::rebuildImagesAndTextures()
800815
// Recreate textures
801816
for(u32 i=0; i<m_textureinfo_cache.size(); i++){
802817
TextureInfo *ti = &m_textureinfo_cache[i];
803-
video::IImage *img =
804-
generate_image_from_scratch(ti->name, m_device, &m_sourcecache);
818+
video::IImage *img = generateImageFromScratch(ti->name);
805819
// Create texture from resulting image
806820
video::ITexture *t = NULL;
807821
if(img)
@@ -816,13 +830,90 @@ void TextureSource::rebuildImagesAndTextures()
816830
}
817831
}
818832

819-
video::IImage* generate_image_from_scratch(std::string name,
820-
IrrlichtDevice *device, SourceImageCache *sourcecache)
833+
video::ITexture* TextureSource::generateTextureFromMesh(
834+
const TextureFromMeshParams &params)
821835
{
822-
/*infostream<<"generate_image_from_scratch(): "
836+
video::IVideoDriver *driver = m_device->getVideoDriver();
837+
assert(driver);
838+
839+
if(driver->queryFeature(video::EVDF_RENDER_TO_TARGET) == false)
840+
{
841+
static bool warned = false;
842+
if(!warned)
843+
{
844+
errorstream<<"TextureSource::generateTextureFromMesh(): "
845+
<<"EVDF_RENDER_TO_TARGET not supported."<<std::endl;
846+
warned = true;
847+
}
848+
return NULL;
849+
}
850+
851+
// Create render target texture
852+
video::ITexture *rtt = driver->addRenderTargetTexture(
853+
params.dim, params.rtt_texture_name.c_str(),
854+
video::ECF_A8R8G8B8);
855+
if(rtt == NULL)
856+
{
857+
errorstream<<"TextureSource::generateTextureFromMesh(): "
858+
<<"addRenderTargetTexture returned NULL."<<std::endl;
859+
return NULL;
860+
}
861+
862+
// Set render target
863+
driver->setRenderTarget(rtt, false, true, video::SColor(0,0,0,0));
864+
865+
// Get a scene manager
866+
scene::ISceneManager *smgr_main = m_device->getSceneManager();
867+
assert(smgr_main);
868+
scene::ISceneManager *smgr = smgr_main->createNewSceneManager();
869+
assert(smgr);
870+
871+
scene::IMeshSceneNode* meshnode = smgr->addMeshSceneNode(params.mesh, NULL, -1, v3f(0,0,0), v3f(0,0,0), v3f(1,1,1), true);
872+
meshnode->setMaterialFlag(video::EMF_LIGHTING, true);
873+
meshnode->setMaterialFlag(video::EMF_ANTI_ALIASING, true);
874+
meshnode->setMaterialFlag(video::EMF_TRILINEAR_FILTER, m_setting_trilinear_filter);
875+
meshnode->setMaterialFlag(video::EMF_BILINEAR_FILTER, m_setting_bilinear_filter);
876+
meshnode->setMaterialFlag(video::EMF_ANISOTROPIC_FILTER, m_setting_anisotropic_filter);
877+
878+
scene::ICameraSceneNode* camera = smgr->addCameraSceneNode(0,
879+
params.camera_position, params.camera_lookat);
880+
// second parameter of setProjectionMatrix (isOrthogonal) is ignored
881+
camera->setProjectionMatrix(params.camera_projection_matrix, false);
882+
883+
smgr->setAmbientLight(params.ambient_light);
884+
smgr->addLightSceneNode(0,
885+
params.light_position,
886+
params.light_color,
887+
params.light_radius);
888+
889+
// Render scene
890+
driver->beginScene(true, true, video::SColor(0,0,0,0));
891+
smgr->drawAll();
892+
driver->endScene();
893+
894+
// NOTE: The scene nodes should not be dropped, otherwise
895+
// smgr->drop() segfaults
896+
/*cube->drop();
897+
camera->drop();
898+
light->drop();*/
899+
// Drop scene manager
900+
smgr->drop();
901+
902+
// Unset render target
903+
driver->setRenderTarget(0, false, true, 0);
904+
905+
if(params.delete_texture_on_shutdown)
906+
m_texture_trash.push_back(rtt);
907+
908+
return rtt;
909+
}
910+
911+
video::IImage* TextureSource::generateImageFromScratch(std::string name)
912+
{
913+
/*infostream<<"generateImageFromScratch(): "
823914
"\""<<name<<"\""<<std::endl;*/
824-
825-
video::IVideoDriver* driver = device->getVideoDriver();
915+
916+
video::IVideoDriver *driver = m_device->getVideoDriver();
826917
assert(driver);
827918

828919
/*
@@ -835,12 +926,6 @@ video::IImage* generate_image_from_scratch(std::string name,
835926

836927
// Find last meta separator in name
837928
s32 last_separator_position = name.find_last_of(separator);
838-
//if(last_separator_position == std::npos)
839-
// last_separator_position = -1;
840-
841-
/*infostream<<"generate_image_from_scratch(): "
842-
<<"last_separator_position="<<last_separator_position
843-
<<std::endl;*/
844929

845930
/*
846931
If separator was found, construct the base name and make the
@@ -851,11 +936,7 @@ video::IImage* generate_image_from_scratch(std::string name,
851936
{
852937
// Construct base name
853938
base_image_name = name.substr(0, last_separator_position);
854-
/*infostream<<"generate_image_from_scratch(): Calling itself recursively"
855-
" to get base image of \""<<name<<"\" = \""
856-
<<base_image_name<<"\""<<std::endl;*/
857-
baseimg = generate_image_from_scratch(base_image_name, device,
858-
sourcecache);
939+
baseimg = generateImageFromScratch(base_image_name);
859940
}
860941

861942
/*
@@ -864,12 +945,11 @@ video::IImage* generate_image_from_scratch(std::string name,
864945
*/
865946

866947
std::string last_part_of_name = name.substr(last_separator_position+1);
867-
//infostream<<"last_part_of_name=\""<<last_part_of_name<<"\""<<std::endl;
868948

869949
// Generate image according to part of name
870-
if(!generate_image(last_part_of_name, baseimg, device, sourcecache))
950+
if(!generateImage(last_part_of_name, baseimg))
871951
{
872-
errorstream<<"generate_image_from_scratch(): "
952+
errorstream<<"generateImageFromScratch(): "
873953
"failed to generate \""<<last_part_of_name<<"\""
874954
<<std::endl;
875955
return NULL;
@@ -878,23 +958,22 @@ video::IImage* generate_image_from_scratch(std::string name,
878958
return baseimg;
879959
}
880960

881-
bool generate_image(std::string part_of_name, video::IImage *& baseimg,
882-
IrrlichtDevice *device, SourceImageCache *sourcecache)
961+
bool TextureSource::generateImage(std::string part_of_name, video::IImage *& baseimg)
883962
{
884-
video::IVideoDriver* driver = device->getVideoDriver();
963+
video::IVideoDriver* driver = m_device->getVideoDriver();
885964
assert(driver);
886965

887966
// Stuff starting with [ are special commands
888967
if(part_of_name.size() == 0 || part_of_name[0] != '[')
889968
{
890-
video::IImage *image = sourcecache->getOrLoad(part_of_name, device);
969+
video::IImage *image = m_sourcecache.getOrLoad(part_of_name, m_device);
891970

892971
if(image == NULL)
893972
{
894973
if(part_of_name != ""){
895-
errorstream<<"generate_image(): Could not load image \""
974+
errorstream<<"generateImage(): Could not load image \""
896975
<<part_of_name<<"\""<<" while building texture"<<std::endl;
897-
errorstream<<"generate_image(): Creating a dummy"
976+
errorstream<<"generateImage(): Creating a dummy"
898977
<<" image for \""<<part_of_name<<"\""<<std::endl;
899978
}
900979

@@ -955,7 +1034,7 @@ bool generate_image(std::string part_of_name, video::IImage *& baseimg,
9551034
{
9561035
// A special texture modification
9571036

958-
/*infostream<<"generate_image(): generating special "
1037+
/*infostream<<"generateImage(): generating special "
9591038
<<"modification \""<<part_of_name<<"\""
9601039
<<std::endl;*/
9611040

@@ -967,7 +1046,7 @@ bool generate_image(std::string part_of_name, video::IImage *& baseimg,
9671046
{
9681047
if(baseimg == NULL)
9691048
{
970-
errorstream<<"generate_image(): baseimg==NULL "
1049+
errorstream<<"generateImage(): baseimg==NULL "
9711050
<<"for part_of_name=\""<<part_of_name
9721051
<<"\", cancelling."<<std::endl;
9731052
return false;
@@ -996,8 +1075,8 @@ bool generate_image(std::string part_of_name, video::IImage *& baseimg,
9961075
It is an image with a number of cracking stages
9971076
horizontally tiled.
9981077
*/
999-
video::IImage *img_crack = sourcecache->getOrLoad(
1000-
"crack_anylength.png", device);
1078+
video::IImage *img_crack = m_sourcecache.getOrLoad(
1079+
"crack_anylength.png", m_device);
10011080

10021081
if(img_crack && progression >= 0)
10031082
{
@@ -1080,7 +1159,7 @@ bool generate_image(std::string part_of_name, video::IImage *& baseimg,
10801159
infostream<<"Adding \""<<filename
10811160
<<"\" to combined ("<<x<<","<<y<<")"
10821161
<<std::endl;
1083-
video::IImage *img = sourcecache->getOrLoad(filename, device);
1162+
video::IImage *img = m_sourcecache.getOrLoad(filename, m_device);
10841163
if(img)
10851164
{
10861165
core::dimension2d<u32> dim = img->getDimension();
@@ -1111,7 +1190,7 @@ bool generate_image(std::string part_of_name, video::IImage *& baseimg,
11111190
{
11121191
if(baseimg == NULL)
11131192
{
1114-
errorstream<<"generate_image(): baseimg==NULL "
1193+
errorstream<<"generateImage(): baseimg==NULL "
11151194
<<"for part_of_name=\""<<part_of_name
11161195
<<"\", cancelling."<<std::endl;
11171196
return false;
@@ -1130,7 +1209,7 @@ bool generate_image(std::string part_of_name, video::IImage *& baseimg,
11301209
{
11311210
if(baseimg == NULL)
11321211
{
1133-
errorstream<<"generate_image(): baseimg==NULL "
1212+
errorstream<<"generateImage(): baseimg==NULL "
11341213
<<"for part_of_name=\""<<part_of_name
11351214
<<"\", cancelling."<<std::endl;
11361215
return false;
@@ -1155,7 +1234,7 @@ bool generate_image(std::string part_of_name, video::IImage *& baseimg,
11551234
{
11561235
if(baseimg == NULL)
11571236
{
1158-
errorstream<<"generate_image(): baseimg==NULL "
1237+
errorstream<<"generateImage(): baseimg==NULL "
11591238
<<"for part_of_name=\""<<part_of_name
11601239
<<"\", cancelling."<<std::endl;
11611240
return false;
@@ -1212,7 +1291,7 @@ bool generate_image(std::string part_of_name, video::IImage *& baseimg,
12121291
{
12131292
if(baseimg == NULL)
12141293
{
1215-
errorstream<<"generate_image(): baseimg==NULL "
1294+
errorstream<<"generateImage(): baseimg==NULL "
12161295
<<"for part_of_name=\""<<part_of_name
12171296
<<"\", cancelling."<<std::endl;
12181297
return false;
@@ -1240,7 +1319,7 @@ bool generate_image(std::string part_of_name, video::IImage *& baseimg,
12401319
{
12411320
if(baseimg != NULL)
12421321
{
1243-
errorstream<<"generate_image(): baseimg!=NULL "
1322+
errorstream<<"generateImage(): baseimg!=NULL "
12441323
<<"for part_of_name=\""<<part_of_name
12451324
<<"\", cancelling."<<std::endl;
12461325
return false;
@@ -1254,12 +1333,12 @@ bool generate_image(std::string part_of_name, video::IImage *& baseimg,
12541333
std::string imagename_right = sf.next("{");
12551334

12561335
// Generate images for the faces of the cube
1257-
video::IImage *img_top = generate_image_from_scratch(
1258-
imagename_top, device, sourcecache);
1259-
video::IImage *img_left = generate_image_from_scratch(
1260-
imagename_left, device, sourcecache);
1261-
video::IImage *img_right = generate_image_from_scratch(
1262-
imagename_right, device, sourcecache);
1336+
video::IImage *img_top =
1337+
generateImageFromScratch(imagename_top);
1338+
video::IImage *img_left =
1339+
generateImageFromScratch(imagename_left);
1340+
video::IImage *img_right =
1341+
generateImageFromScratch(imagename_right);
12631342
assert(img_top && img_left && img_right);
12641343

12651344
// Create textures from images
@@ -1288,31 +1367,25 @@ bool generate_image(std::string part_of_name, video::IImage *& baseimg,
12881367
cube->getMeshBuffer(4)->getMaterial().setTexture(0, texture_left);
12891368
cube->getMeshBuffer(5)->getMaterial().setTexture(0, texture_left);
12901369

1291-
core::dimension2d<u32> dim(64,64);
1292-
std::string rtt_texture_name = part_of_name + "_RTT";
1293-
1294-
v3f camera_position(0, 1.0, -1.5);
1295-
camera_position.rotateXZBy(45);
1296-
v3f camera_lookat(0, 0, 0);
1297-
core::CMatrix4<f32> camera_projection_matrix;
1370+
TextureFromMeshParams params;
1371+
params.mesh = cube;
1372+
params.dim.set(64, 64);
1373+
params.rtt_texture_name = part_of_name + "_RTT";
1374+
// We will delete the rtt texture ourselves
1375+
params.delete_texture_on_shutdown = false;
1376+
params.camera_position.set(0, 1.0, -1.5);
1377+
params.camera_position.rotateXZBy(45);
1378+
params.camera_lookat.set(0, 0, 0);
12981379
// Set orthogonal projection
1299-
camera_projection_matrix.buildProjectionMatrixOrthoLH(
1380+
params.camera_projection_matrix.buildProjectionMatrixOrthoLH(
13001381
1.65, 1.65, 0, 100);
13011382

1302-
video::SColorf ambient_light(0.2,0.2,0.2);
1303-
v3f light_position(10, 100, -50);
1304-
video::SColorf light_color(0.5,0.5,0.5);
1305-
f32 light_radius = 1000;
1306-
1307-
video::ITexture *rtt = generateTextureFromMesh(
1308-
cube, device, dim, rtt_texture_name,
1309-
camera_position,
1310-
camera_lookat,
1311-
camera_projection_matrix,
1312-
ambient_light,
1313-
light_position,
1314-
light_color,
1315-
light_radius);
1383+
params.ambient_light.set(1.0, 0.2, 0.2, 0.2);
1384+
params.light_position.set(10, 100, -50);
1385+
params.light_color.set(1.0, 0.5, 0.5, 0.5);
1386+
params.light_radius = 1000;
1387+
1388+
video::ITexture *rtt = generateTextureFromMesh(params);
13161389

13171390
// Drop mesh
13181391
cube->drop();
@@ -1324,19 +1397,18 @@ bool generate_image(std::string part_of_name, video::IImage *& baseimg,
13241397

13251398
if(rtt == NULL)
13261399
{
1327-
baseimg = generate_image_from_scratch(
1328-
imagename_top, device, sourcecache);
1400+
baseimg = generateImageFromScratch(imagename_top);
13291401
return true;
13301402
}
13311403

13321404
// Create image of render target
1333-
video::IImage *image = driver->createImage(rtt, v2s32(0,0), dim);
1405+
video::IImage *image = driver->createImage(rtt, v2s32(0,0), params.dim);
13341406
assert(image);
13351407

1336-
//cleanup texture
1408+
// Cleanup texture
13371409
driver->removeTexture(rtt);
13381410

1339-
baseimg = driver->createImage(video::ECF_A8R8G8B8, dim);
1411+
baseimg = driver->createImage(video::ECF_A8R8G8B8, params.dim);
13401412

13411413
if(image)
13421414
{
@@ -1358,7 +1430,7 @@ bool generate_image(std::string part_of_name, video::IImage *& baseimg,
13581430

13591431
if(baseimg == NULL)
13601432
baseimg = driver->createImage(video::ECF_A8R8G8B8, v2u32(16,16));
1361-
video::IImage *img = sourcecache->getOrLoad(filename, device);
1433+
video::IImage *img = m_sourcecache.getOrLoad(filename, m_device);
13621434
if(img)
13631435
{
13641436
core::dimension2d<u32> dim = img->getDimension();
@@ -1392,7 +1464,7 @@ bool generate_image(std::string part_of_name, video::IImage *& baseimg,
13921464
u32 frame_index = stoi(sf.next(":"));
13931465

13941466
if(baseimg == NULL){
1395-
errorstream<<"generate_image(): baseimg!=NULL "
1467+
errorstream<<"generateImage(): baseimg!=NULL "
13961468
<<"for part_of_name=\""<<part_of_name
13971469
<<"\", cancelling."<<std::endl;
13981470
return false;
@@ -1404,7 +1476,7 @@ bool generate_image(std::string part_of_name, video::IImage *& baseimg,
14041476
video::IImage *img = driver->createImage(video::ECF_A8R8G8B8,
14051477
frame_size);
14061478
if(!img){
1407-
errorstream<<"generate_image(): Could not create image "
1479+
errorstream<<"generateImage(): Could not create image "
14081480
<<"for part_of_name=\""<<part_of_name
14091481
<<"\", cancelling."<<std::endl;
14101482
return false;
@@ -1426,7 +1498,7 @@ bool generate_image(std::string part_of_name, video::IImage *& baseimg,
14261498
}
14271499
else
14281500
{
1429-
errorstream<<"generate_image(): Invalid "
1501+
errorstream<<"generateImage(): Invalid "
14301502
" modification: \""<<part_of_name<<"\""<<std::endl;
14311503
}
14321504
}

‎src/tile.h

+23
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,25 @@ std::string getImagePath(std::string path);
5757
*/
5858
std::string getTexturePath(const std::string &filename);
5959

60+
/*
61+
ITextureSource::generateTextureFromMesh parameters
62+
*/
63+
namespace irr {namespace scene {class IMesh;}}
64+
struct TextureFromMeshParams
65+
{
66+
scene::IMesh *mesh;
67+
core::dimension2d<u32> dim;
68+
std::string rtt_texture_name;
69+
bool delete_texture_on_shutdown;
70+
v3f camera_position;
71+
v3f camera_lookat;
72+
core::CMatrix4<f32> camera_projection_matrix;
73+
video::SColorf ambient_light;
74+
v3f light_position;
75+
video::SColorf light_color;
76+
f32 light_radius;
77+
};
78+
6079
/*
6180
TextureSource creates and caches textures.
6281
*/
@@ -78,6 +97,8 @@ class ITextureSource
7897
virtual IrrlichtDevice* getDevice()
7998
{return NULL;}
8099
virtual bool isKnownSourceImage(const std::string &name)=0;
100+
virtual video::ITexture* generateTextureFromMesh(
101+
const TextureFromMeshParams &params)=0;
81102
};
82103

83104
class IWritableTextureSource : public ITextureSource
@@ -100,6 +121,8 @@ class IWritableTextureSource : public ITextureSource
100121
virtual void processQueue()=0;
101122
virtual void insertSourceImage(const std::string &name, video::IImage *img)=0;
102123
virtual void rebuildImagesAndTextures()=0;
124+
virtual video::ITexture* generateTextureFromMesh(
125+
const TextureFromMeshParams &params)=0;
103126
};
104127

105128
IWritableTextureSource* createTextureSource(IrrlichtDevice *device);

0 commit comments

Comments
 (0)
Please sign in to comment.