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).
This commit is contained in:
parent
b1ef850877
commit
8f1d5d34a6
|
@ -229,7 +229,6 @@ public:
|
||||||
|
|
||||||
#ifndef SERVER
|
#ifndef SERVER
|
||||||
m_main_thread = get_current_thread_id();
|
m_main_thread = get_current_thread_id();
|
||||||
m_driver = NULL;
|
|
||||||
#endif
|
#endif
|
||||||
clear();
|
clear();
|
||||||
}
|
}
|
||||||
|
@ -246,13 +245,6 @@ public:
|
||||||
delete cc;
|
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
|
#endif
|
||||||
for (std::map<std::string, ItemDefinition*>::iterator iter =
|
for (std::map<std::string, ItemDefinition*>::iterator iter =
|
||||||
m_item_definitions.begin(); iter != m_item_definitions.end();
|
m_item_definitions.begin(); iter != m_item_definitions.end();
|
||||||
|
@ -307,9 +299,6 @@ public:
|
||||||
return m_item_definitions.find(name) != m_item_definitions.end();
|
return m_item_definitions.find(name) != m_item_definitions.end();
|
||||||
}
|
}
|
||||||
#ifndef SERVER
|
#ifndef SERVER
|
||||||
private:
|
|
||||||
static video::IVideoDriver * m_driver;
|
|
||||||
static std::vector<video::ITexture*> m_extruded_textures;
|
|
||||||
public:
|
public:
|
||||||
ClientCached* createClientCachedDirect(const std::string &name,
|
ClientCached* createClientCachedDirect(const std::string &name,
|
||||||
IGameDef *gamedef) const
|
IGameDef *gamedef) const
|
||||||
|
@ -416,31 +405,25 @@ public:
|
||||||
*/
|
*/
|
||||||
if(cc->inventory_texture == NULL)
|
if(cc->inventory_texture == NULL)
|
||||||
{
|
{
|
||||||
core::dimension2d<u32> dim(64,64);
|
TextureFromMeshParams params;
|
||||||
std::string rtt_texture_name = "INVENTORY_"
|
params.mesh = node_mesh;
|
||||||
|
params.dim.set(64, 64);
|
||||||
|
params.rtt_texture_name = "INVENTORY_"
|
||||||
+ def->name + "_RTT";
|
+ def->name + "_RTT";
|
||||||
v3f camera_position(0, 1.0, -1.5);
|
params.delete_texture_on_shutdown = true;
|
||||||
camera_position.rotateXZBy(45);
|
params.camera_position.set(0, 1.0, -1.5);
|
||||||
v3f camera_lookat(0, 0, 0);
|
params.camera_position.rotateXZBy(45);
|
||||||
core::CMatrix4<f32> camera_projection_matrix;
|
params.camera_lookat.set(0, 0, 0);
|
||||||
// Set orthogonal projection
|
// Set orthogonal projection
|
||||||
camera_projection_matrix.buildProjectionMatrixOrthoLH(
|
params.camera_projection_matrix.buildProjectionMatrixOrthoLH(
|
||||||
1.65, 1.65, 0, 100);
|
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);
|
cc->inventory_texture =
|
||||||
v3f light_position(10, 100, -50);
|
tsrc->generateTextureFromMesh(params);
|
||||||
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);
|
|
||||||
|
|
||||||
// render-to-target didn't work
|
// render-to-target didn't work
|
||||||
if(cc->inventory_texture == NULL)
|
if(cc->inventory_texture == NULL)
|
||||||
|
@ -449,13 +432,6 @@ public:
|
||||||
tsrc->getTexture(f.tiledef[0].name);
|
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
|
Use the node mesh as the wield mesh
|
||||||
|
@ -681,9 +657,3 @@ IWritableItemDefManager* createItemDefManager()
|
||||||
{
|
{
|
||||||
return new CItemDefManager();
|
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
|
|
||||||
|
|
77
src/mesh.cpp
77
src/mesh.cpp
|
@ -23,7 +23,6 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <IAnimatedMesh.h>
|
#include <IAnimatedMesh.h>
|
||||||
#include <SAnimatedMesh.h>
|
#include <SAnimatedMesh.h>
|
||||||
#include <ICameraSceneNode.h>
|
|
||||||
|
|
||||||
// In Irrlicht 1.8 the signature of ITexture::lock was changed from
|
// In Irrlicht 1.8 the signature of ITexture::lock was changed from
|
||||||
// (bool, u32) to (E_TEXTURE_LOCK_MODE, u32).
|
// (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;
|
|
||||||
}
|
|
||||||
|
|
16
src/mesh.h
16
src/mesh.h
|
@ -69,20 +69,4 @@ void setMeshColorByNormalXYZ(scene::IMesh *mesh,
|
||||||
const video::SColor &colorY,
|
const video::SColor &colorY,
|
||||||
const video::SColor &colorZ);
|
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
|
#endif
|
||||||
|
|
250
src/tile.cpp
250
src/tile.cpp
|
@ -18,6 +18,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "tile.h"
|
#include "tile.h"
|
||||||
|
#include "irrlichttypes_extrabloated.h"
|
||||||
#include "debug.h"
|
#include "debug.h"
|
||||||
#include "main.h" // for g_settings
|
#include "main.h" // for g_settings
|
||||||
#include "filesys.h"
|
#include "filesys.h"
|
||||||
|
@ -238,7 +239,7 @@ public:
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
// Primarily fetches from cache, secondarily tries to read from filesystem
|
// 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;
|
std::map<std::string, video::IImage*>::iterator n;
|
||||||
n = m_images.find(name);
|
n = m_images.find(name);
|
||||||
|
@ -246,7 +247,7 @@ public:
|
||||||
n->second->grab(); // Grab for caller
|
n->second->grab(); // Grab for caller
|
||||||
return n->second;
|
return n->second;
|
||||||
}
|
}
|
||||||
video::IVideoDriver* driver = device->getVideoDriver();
|
video::IVideoDriver* driver = m_device->getVideoDriver();
|
||||||
std::string path = getTexturePath(name.c_str());
|
std::string path = getTexturePath(name.c_str());
|
||||||
if(path == ""){
|
if(path == ""){
|
||||||
infostream<<"SourceImageCache::getOrLoad(): No path found for \""
|
infostream<<"SourceImageCache::getOrLoad(): No path found for \""
|
||||||
|
@ -378,6 +379,22 @@ public:
|
||||||
// Shall be called from the main thread.
|
// Shall be called from the main thread.
|
||||||
void rebuildImagesAndTextures();
|
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:
|
private:
|
||||||
|
|
||||||
// The id of the thread that is allowed to use irrlicht directly
|
// 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
|
// Textures that have been overwritten with other ones
|
||||||
// but can't be deleted because the ITexture* might still be used
|
// but can't be deleted because the ITexture* might still be used
|
||||||
std::list<video::ITexture*> m_texture_trash;
|
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)
|
IWritableTextureSource* createTextureSource(IrrlichtDevice *device)
|
||||||
|
@ -425,6 +447,13 @@ TextureSource::TextureSource(IrrlichtDevice *device):
|
||||||
// Add a NULL TextureInfo as the first index, named ""
|
// Add a NULL TextureInfo as the first index, named ""
|
||||||
m_textureinfo_cache.push_back(TextureInfo(""));
|
m_textureinfo_cache.push_back(TextureInfo(""));
|
||||||
m_name_to_id[""] = 0;
|
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()
|
TextureSource::~TextureSource()
|
||||||
|
@ -538,20 +567,6 @@ core::dimension2d<u32> imageTransformDimension(u32 transform, core::dimension2d<
|
||||||
// Apply transform to image data
|
// Apply transform to image data
|
||||||
void imageTransform(u32 transform, video::IImage *src, video::IImage *dst);
|
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
|
This method generates all the textures
|
||||||
*/
|
*/
|
||||||
|
@ -685,7 +700,7 @@ u32 TextureSource::getTextureIdDirect(const std::string &name)
|
||||||
//infostream<<"last_part_of_name=\""<<last_part_of_name<<"\""<<std::endl;
|
//infostream<<"last_part_of_name=\""<<last_part_of_name<<"\""<<std::endl;
|
||||||
|
|
||||||
// Generate image according to part of name
|
// 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(): "
|
errorstream<<"getTextureIdDirect(): "
|
||||||
"failed to generate \""<<last_part_of_name<<"\""
|
"failed to generate \""<<last_part_of_name<<"\""
|
||||||
|
@ -800,8 +815,7 @@ void TextureSource::rebuildImagesAndTextures()
|
||||||
// Recreate textures
|
// Recreate textures
|
||||||
for(u32 i=0; i<m_textureinfo_cache.size(); i++){
|
for(u32 i=0; i<m_textureinfo_cache.size(); i++){
|
||||||
TextureInfo *ti = &m_textureinfo_cache[i];
|
TextureInfo *ti = &m_textureinfo_cache[i];
|
||||||
video::IImage *img =
|
video::IImage *img = generateImageFromScratch(ti->name);
|
||||||
generate_image_from_scratch(ti->name, m_device, &m_sourcecache);
|
|
||||||
// Create texture from resulting image
|
// Create texture from resulting image
|
||||||
video::ITexture *t = NULL;
|
video::ITexture *t = NULL;
|
||||||
if(img)
|
if(img)
|
||||||
|
@ -816,13 +830,90 @@ void TextureSource::rebuildImagesAndTextures()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
video::IImage* generate_image_from_scratch(std::string name,
|
video::ITexture* TextureSource::generateTextureFromMesh(
|
||||||
IrrlichtDevice *device, SourceImageCache *sourcecache)
|
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;*/
|
"\""<<name<<"\""<<std::endl;*/
|
||||||
|
|
||||||
video::IVideoDriver* driver = device->getVideoDriver();
|
video::IVideoDriver *driver = m_device->getVideoDriver();
|
||||||
assert(driver);
|
assert(driver);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -835,12 +926,6 @@ video::IImage* generate_image_from_scratch(std::string name,
|
||||||
|
|
||||||
// Find last meta separator in name
|
// Find last meta separator in name
|
||||||
s32 last_separator_position = name.find_last_of(separator);
|
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
|
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
|
// Construct base name
|
||||||
base_image_name = name.substr(0, last_separator_position);
|
base_image_name = name.substr(0, last_separator_position);
|
||||||
/*infostream<<"generate_image_from_scratch(): Calling itself recursively"
|
baseimg = generateImageFromScratch(base_image_name);
|
||||||
" to get base image of \""<<name<<"\" = \""
|
|
||||||
<<base_image_name<<"\""<<std::endl;*/
|
|
||||||
baseimg = generate_image_from_scratch(base_image_name, device,
|
|
||||||
sourcecache);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -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);
|
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
|
// 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<<"\""
|
"failed to generate \""<<last_part_of_name<<"\""
|
||||||
<<std::endl;
|
<<std::endl;
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -878,23 +958,22 @@ video::IImage* generate_image_from_scratch(std::string name,
|
||||||
return baseimg;
|
return baseimg;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool generate_image(std::string part_of_name, video::IImage *& baseimg,
|
bool TextureSource::generateImage(std::string part_of_name, video::IImage *& baseimg)
|
||||||
IrrlichtDevice *device, SourceImageCache *sourcecache)
|
|
||||||
{
|
{
|
||||||
video::IVideoDriver* driver = device->getVideoDriver();
|
video::IVideoDriver* driver = m_device->getVideoDriver();
|
||||||
assert(driver);
|
assert(driver);
|
||||||
|
|
||||||
// Stuff starting with [ are special commands
|
// Stuff starting with [ are special commands
|
||||||
if(part_of_name.size() == 0 || part_of_name[0] != '[')
|
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(image == NULL)
|
||||||
{
|
{
|
||||||
if(part_of_name != ""){
|
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;
|
<<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;
|
<<" 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
|
// A special texture modification
|
||||||
|
|
||||||
/*infostream<<"generate_image(): generating special "
|
/*infostream<<"generateImage(): generating special "
|
||||||
<<"modification \""<<part_of_name<<"\""
|
<<"modification \""<<part_of_name<<"\""
|
||||||
<<std::endl;*/
|
<<std::endl;*/
|
||||||
|
|
||||||
|
@ -967,7 +1046,7 @@ bool generate_image(std::string part_of_name, video::IImage *& baseimg,
|
||||||
{
|
{
|
||||||
if(baseimg == NULL)
|
if(baseimg == NULL)
|
||||||
{
|
{
|
||||||
errorstream<<"generate_image(): baseimg==NULL "
|
errorstream<<"generateImage(): baseimg==NULL "
|
||||||
<<"for part_of_name=\""<<part_of_name
|
<<"for part_of_name=\""<<part_of_name
|
||||||
<<"\", cancelling."<<std::endl;
|
<<"\", cancelling."<<std::endl;
|
||||||
return false;
|
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
|
It is an image with a number of cracking stages
|
||||||
horizontally tiled.
|
horizontally tiled.
|
||||||
*/
|
*/
|
||||||
video::IImage *img_crack = sourcecache->getOrLoad(
|
video::IImage *img_crack = m_sourcecache.getOrLoad(
|
||||||
"crack_anylength.png", device);
|
"crack_anylength.png", m_device);
|
||||||
|
|
||||||
if(img_crack && progression >= 0)
|
if(img_crack && progression >= 0)
|
||||||
{
|
{
|
||||||
|
@ -1080,7 +1159,7 @@ bool generate_image(std::string part_of_name, video::IImage *& baseimg,
|
||||||
infostream<<"Adding \""<<filename
|
infostream<<"Adding \""<<filename
|
||||||
<<"\" to combined ("<<x<<","<<y<<")"
|
<<"\" to combined ("<<x<<","<<y<<")"
|
||||||
<<std::endl;
|
<<std::endl;
|
||||||
video::IImage *img = sourcecache->getOrLoad(filename, device);
|
video::IImage *img = m_sourcecache.getOrLoad(filename, m_device);
|
||||||
if(img)
|
if(img)
|
||||||
{
|
{
|
||||||
core::dimension2d<u32> dim = img->getDimension();
|
core::dimension2d<u32> dim = img->getDimension();
|
||||||
|
@ -1111,7 +1190,7 @@ bool generate_image(std::string part_of_name, video::IImage *& baseimg,
|
||||||
{
|
{
|
||||||
if(baseimg == NULL)
|
if(baseimg == NULL)
|
||||||
{
|
{
|
||||||
errorstream<<"generate_image(): baseimg==NULL "
|
errorstream<<"generateImage(): baseimg==NULL "
|
||||||
<<"for part_of_name=\""<<part_of_name
|
<<"for part_of_name=\""<<part_of_name
|
||||||
<<"\", cancelling."<<std::endl;
|
<<"\", cancelling."<<std::endl;
|
||||||
return false;
|
return false;
|
||||||
|
@ -1130,7 +1209,7 @@ bool generate_image(std::string part_of_name, video::IImage *& baseimg,
|
||||||
{
|
{
|
||||||
if(baseimg == NULL)
|
if(baseimg == NULL)
|
||||||
{
|
{
|
||||||
errorstream<<"generate_image(): baseimg==NULL "
|
errorstream<<"generateImage(): baseimg==NULL "
|
||||||
<<"for part_of_name=\""<<part_of_name
|
<<"for part_of_name=\""<<part_of_name
|
||||||
<<"\", cancelling."<<std::endl;
|
<<"\", cancelling."<<std::endl;
|
||||||
return false;
|
return false;
|
||||||
|
@ -1155,7 +1234,7 @@ bool generate_image(std::string part_of_name, video::IImage *& baseimg,
|
||||||
{
|
{
|
||||||
if(baseimg == NULL)
|
if(baseimg == NULL)
|
||||||
{
|
{
|
||||||
errorstream<<"generate_image(): baseimg==NULL "
|
errorstream<<"generateImage(): baseimg==NULL "
|
||||||
<<"for part_of_name=\""<<part_of_name
|
<<"for part_of_name=\""<<part_of_name
|
||||||
<<"\", cancelling."<<std::endl;
|
<<"\", cancelling."<<std::endl;
|
||||||
return false;
|
return false;
|
||||||
|
@ -1212,7 +1291,7 @@ bool generate_image(std::string part_of_name, video::IImage *& baseimg,
|
||||||
{
|
{
|
||||||
if(baseimg == NULL)
|
if(baseimg == NULL)
|
||||||
{
|
{
|
||||||
errorstream<<"generate_image(): baseimg==NULL "
|
errorstream<<"generateImage(): baseimg==NULL "
|
||||||
<<"for part_of_name=\""<<part_of_name
|
<<"for part_of_name=\""<<part_of_name
|
||||||
<<"\", cancelling."<<std::endl;
|
<<"\", cancelling."<<std::endl;
|
||||||
return false;
|
return false;
|
||||||
|
@ -1240,7 +1319,7 @@ bool generate_image(std::string part_of_name, video::IImage *& baseimg,
|
||||||
{
|
{
|
||||||
if(baseimg != NULL)
|
if(baseimg != NULL)
|
||||||
{
|
{
|
||||||
errorstream<<"generate_image(): baseimg!=NULL "
|
errorstream<<"generateImage(): baseimg!=NULL "
|
||||||
<<"for part_of_name=\""<<part_of_name
|
<<"for part_of_name=\""<<part_of_name
|
||||||
<<"\", cancelling."<<std::endl;
|
<<"\", cancelling."<<std::endl;
|
||||||
return false;
|
return false;
|
||||||
|
@ -1254,12 +1333,12 @@ bool generate_image(std::string part_of_name, video::IImage *& baseimg,
|
||||||
std::string imagename_right = sf.next("{");
|
std::string imagename_right = sf.next("{");
|
||||||
|
|
||||||
// Generate images for the faces of the cube
|
// Generate images for the faces of the cube
|
||||||
video::IImage *img_top = generate_image_from_scratch(
|
video::IImage *img_top =
|
||||||
imagename_top, device, sourcecache);
|
generateImageFromScratch(imagename_top);
|
||||||
video::IImage *img_left = generate_image_from_scratch(
|
video::IImage *img_left =
|
||||||
imagename_left, device, sourcecache);
|
generateImageFromScratch(imagename_left);
|
||||||
video::IImage *img_right = generate_image_from_scratch(
|
video::IImage *img_right =
|
||||||
imagename_right, device, sourcecache);
|
generateImageFromScratch(imagename_right);
|
||||||
assert(img_top && img_left && img_right);
|
assert(img_top && img_left && img_right);
|
||||||
|
|
||||||
// Create textures from images
|
// 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(4)->getMaterial().setTexture(0, texture_left);
|
||||||
cube->getMeshBuffer(5)->getMaterial().setTexture(0, texture_left);
|
cube->getMeshBuffer(5)->getMaterial().setTexture(0, texture_left);
|
||||||
|
|
||||||
core::dimension2d<u32> dim(64,64);
|
TextureFromMeshParams params;
|
||||||
std::string rtt_texture_name = part_of_name + "_RTT";
|
params.mesh = cube;
|
||||||
|
params.dim.set(64, 64);
|
||||||
v3f camera_position(0, 1.0, -1.5);
|
params.rtt_texture_name = part_of_name + "_RTT";
|
||||||
camera_position.rotateXZBy(45);
|
// We will delete the rtt texture ourselves
|
||||||
v3f camera_lookat(0, 0, 0);
|
params.delete_texture_on_shutdown = false;
|
||||||
core::CMatrix4<f32> camera_projection_matrix;
|
params.camera_position.set(0, 1.0, -1.5);
|
||||||
|
params.camera_position.rotateXZBy(45);
|
||||||
|
params.camera_lookat.set(0, 0, 0);
|
||||||
// Set orthogonal projection
|
// Set orthogonal projection
|
||||||
camera_projection_matrix.buildProjectionMatrixOrthoLH(
|
params.camera_projection_matrix.buildProjectionMatrixOrthoLH(
|
||||||
1.65, 1.65, 0, 100);
|
1.65, 1.65, 0, 100);
|
||||||
|
|
||||||
video::SColorf ambient_light(0.2,0.2,0.2);
|
params.ambient_light.set(1.0, 0.2, 0.2, 0.2);
|
||||||
v3f light_position(10, 100, -50);
|
params.light_position.set(10, 100, -50);
|
||||||
video::SColorf light_color(0.5,0.5,0.5);
|
params.light_color.set(1.0, 0.5, 0.5, 0.5);
|
||||||
f32 light_radius = 1000;
|
params.light_radius = 1000;
|
||||||
|
|
||||||
video::ITexture *rtt = generateTextureFromMesh(
|
video::ITexture *rtt = generateTextureFromMesh(params);
|
||||||
cube, device, dim, rtt_texture_name,
|
|
||||||
camera_position,
|
|
||||||
camera_lookat,
|
|
||||||
camera_projection_matrix,
|
|
||||||
ambient_light,
|
|
||||||
light_position,
|
|
||||||
light_color,
|
|
||||||
light_radius);
|
|
||||||
|
|
||||||
// Drop mesh
|
// Drop mesh
|
||||||
cube->drop();
|
cube->drop();
|
||||||
|
@ -1324,19 +1397,18 @@ bool generate_image(std::string part_of_name, video::IImage *& baseimg,
|
||||||
|
|
||||||
if(rtt == NULL)
|
if(rtt == NULL)
|
||||||
{
|
{
|
||||||
baseimg = generate_image_from_scratch(
|
baseimg = generateImageFromScratch(imagename_top);
|
||||||
imagename_top, device, sourcecache);
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create image of render target
|
// 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);
|
assert(image);
|
||||||
|
|
||||||
//cleanup texture
|
// Cleanup texture
|
||||||
driver->removeTexture(rtt);
|
driver->removeTexture(rtt);
|
||||||
|
|
||||||
baseimg = driver->createImage(video::ECF_A8R8G8B8, dim);
|
baseimg = driver->createImage(video::ECF_A8R8G8B8, params.dim);
|
||||||
|
|
||||||
if(image)
|
if(image)
|
||||||
{
|
{
|
||||||
|
@ -1358,7 +1430,7 @@ bool generate_image(std::string part_of_name, video::IImage *& baseimg,
|
||||||
|
|
||||||
if(baseimg == NULL)
|
if(baseimg == NULL)
|
||||||
baseimg = driver->createImage(video::ECF_A8R8G8B8, v2u32(16,16));
|
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)
|
if(img)
|
||||||
{
|
{
|
||||||
core::dimension2d<u32> dim = img->getDimension();
|
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(":"));
|
u32 frame_index = stoi(sf.next(":"));
|
||||||
|
|
||||||
if(baseimg == NULL){
|
if(baseimg == NULL){
|
||||||
errorstream<<"generate_image(): baseimg!=NULL "
|
errorstream<<"generateImage(): baseimg!=NULL "
|
||||||
<<"for part_of_name=\""<<part_of_name
|
<<"for part_of_name=\""<<part_of_name
|
||||||
<<"\", cancelling."<<std::endl;
|
<<"\", cancelling."<<std::endl;
|
||||||
return false;
|
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,
|
video::IImage *img = driver->createImage(video::ECF_A8R8G8B8,
|
||||||
frame_size);
|
frame_size);
|
||||||
if(!img){
|
if(!img){
|
||||||
errorstream<<"generate_image(): Could not create image "
|
errorstream<<"generateImage(): Could not create image "
|
||||||
<<"for part_of_name=\""<<part_of_name
|
<<"for part_of_name=\""<<part_of_name
|
||||||
<<"\", cancelling."<<std::endl;
|
<<"\", cancelling."<<std::endl;
|
||||||
return false;
|
return false;
|
||||||
|
@ -1426,7 +1498,7 @@ bool generate_image(std::string part_of_name, video::IImage *& baseimg,
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
errorstream<<"generate_image(): Invalid "
|
errorstream<<"generateImage(): Invalid "
|
||||||
" modification: \""<<part_of_name<<"\""<<std::endl;
|
" modification: \""<<part_of_name<<"\""<<std::endl;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
23
src/tile.h
23
src/tile.h
|
@ -57,6 +57,25 @@ std::string getImagePath(std::string path);
|
||||||
*/
|
*/
|
||||||
std::string getTexturePath(const std::string &filename);
|
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.
|
TextureSource creates and caches textures.
|
||||||
*/
|
*/
|
||||||
|
@ -78,6 +97,8 @@ public:
|
||||||
virtual IrrlichtDevice* getDevice()
|
virtual IrrlichtDevice* getDevice()
|
||||||
{return NULL;}
|
{return NULL;}
|
||||||
virtual bool isKnownSourceImage(const std::string &name)=0;
|
virtual bool isKnownSourceImage(const std::string &name)=0;
|
||||||
|
virtual video::ITexture* generateTextureFromMesh(
|
||||||
|
const TextureFromMeshParams ¶ms)=0;
|
||||||
};
|
};
|
||||||
|
|
||||||
class IWritableTextureSource : public ITextureSource
|
class IWritableTextureSource : public ITextureSource
|
||||||
|
@ -100,6 +121,8 @@ public:
|
||||||
virtual void processQueue()=0;
|
virtual void processQueue()=0;
|
||||||
virtual void insertSourceImage(const std::string &name, video::IImage *img)=0;
|
virtual void insertSourceImage(const std::string &name, video::IImage *img)=0;
|
||||||
virtual void rebuildImagesAndTextures()=0;
|
virtual void rebuildImagesAndTextures()=0;
|
||||||
|
virtual video::ITexture* generateTextureFromMesh(
|
||||||
|
const TextureFromMeshParams ¶ms)=0;
|
||||||
};
|
};
|
||||||
|
|
||||||
IWritableTextureSource* createTextureSource(IrrlichtDevice *device);
|
IWritableTextureSource* createTextureSource(IrrlichtDevice *device);
|
||||||
|
|
Loading…
Reference in New Issue