forked from Mirrorlandia_minetest/minetest
Properly update textures in node definitions
This commit is contained in:
parent
45fc45a49e
commit
01ae0daea5
@ -222,16 +222,14 @@ Client::Client(
|
|||||||
|
|
||||||
// Build main texture atlas, now that the GameDef exists (that is, us)
|
// Build main texture atlas, now that the GameDef exists (that is, us)
|
||||||
if(g_settings->getBool("enable_texture_atlas"))
|
if(g_settings->getBool("enable_texture_atlas"))
|
||||||
tsrc->buildMainAtlas(this);
|
m_tsrc->buildMainAtlas(this);
|
||||||
else
|
else
|
||||||
infostream<<"Not building texture atlas."<<std::endl;
|
infostream<<"Not building texture atlas."<<std::endl;
|
||||||
|
|
||||||
// Update textures
|
// Update node textures
|
||||||
m_nodedef->updateTextures(tsrc);
|
m_nodedef->updateTextures(m_tsrc);
|
||||||
|
|
||||||
// NOTE: This should be done only after getting possible dynamic
|
// Start threads after setting up content definitions
|
||||||
// game definitions from the server, or at least shut down and
|
|
||||||
// restarted when doing so
|
|
||||||
m_mesh_update_thread.Start();
|
m_mesh_update_thread.Start();
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -1568,17 +1566,28 @@ void Client::ProcessData(u8 *data, u32 datasize, u16 sender_peer_id)
|
|||||||
rfile->drop();
|
rfile->drop();
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
m_tsrc->insertImage(name, img);
|
m_tsrc->insertSourceImage(name, img);
|
||||||
|
img->drop();
|
||||||
rfile->drop();
|
rfile->drop();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Rebuild inherited images and recreate textures
|
||||||
|
m_tsrc->rebuildImagesAndTextures();
|
||||||
|
|
||||||
// Update texture atlas
|
// Update texture atlas
|
||||||
if(g_settings->getBool("enable_texture_atlas"))
|
if(g_settings->getBool("enable_texture_atlas"))
|
||||||
m_tsrc->buildMainAtlas(this);
|
m_tsrc->buildMainAtlas(this);
|
||||||
|
|
||||||
|
// Update node textures
|
||||||
|
m_nodedef->updateTextures(m_tsrc);
|
||||||
|
|
||||||
// Resume threads
|
// Resume threads
|
||||||
m_mesh_update_thread.setRun(true);
|
m_mesh_update_thread.setRun(true);
|
||||||
m_mesh_update_thread.Start();
|
m_mesh_update_thread.Start();
|
||||||
|
|
||||||
|
ClientEvent event;
|
||||||
|
event.type = CE_TEXTURES_UPDATED;
|
||||||
|
m_client_event_queue.push_back(event);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
13
src/client.h
13
src/client.h
@ -122,6 +122,7 @@ enum ClientEventType
|
|||||||
CE_PLAYER_DAMAGE,
|
CE_PLAYER_DAMAGE,
|
||||||
CE_PLAYER_FORCE_MOVE,
|
CE_PLAYER_FORCE_MOVE,
|
||||||
CE_DEATHSCREEN,
|
CE_DEATHSCREEN,
|
||||||
|
CE_TEXTURES_UPDATED
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ClientEvent
|
struct ClientEvent
|
||||||
@ -143,6 +144,8 @@ struct ClientEvent
|
|||||||
f32 camera_point_target_y;
|
f32 camera_point_target_y;
|
||||||
f32 camera_point_target_z;
|
f32 camera_point_target_z;
|
||||||
} deathscreen;
|
} deathscreen;
|
||||||
|
struct{
|
||||||
|
} textures_updated;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -302,15 +305,11 @@ public:
|
|||||||
ClientEvent getClientEvent();
|
ClientEvent getClientEvent();
|
||||||
|
|
||||||
inline bool accessDenied()
|
inline bool accessDenied()
|
||||||
{
|
{ return m_access_denied; }
|
||||||
return m_access_denied;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline std::wstring accessDeniedReason()
|
inline std::wstring accessDeniedReason()
|
||||||
{
|
{ return m_access_denied_reason; }
|
||||||
return m_access_denied_reason;
|
|
||||||
}
|
|
||||||
|
|
||||||
float getRTT(void);
|
float getRTT(void);
|
||||||
|
|
||||||
// IGameDef interface
|
// IGameDef interface
|
||||||
|
71
src/game.cpp
71
src/game.cpp
@ -50,6 +50,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
|||||||
#include "content_mapnode.h" // For content_mapnode_init
|
#include "content_mapnode.h" // For content_mapnode_init
|
||||||
#include "tooldef.h"
|
#include "tooldef.h"
|
||||||
#include "content_mapnode.h" // Default nodes
|
#include "content_mapnode.h" // Default nodes
|
||||||
|
#include "tile.h" // For TextureSource
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Setting this to 1 enables a special camera mode that forces
|
Setting this to 1 enables a special camera mode that forces
|
||||||
@ -519,7 +520,7 @@ void getPointedNode(Client *client, v3f player_position,
|
|||||||
} // for coords
|
} // for coords
|
||||||
}
|
}
|
||||||
|
|
||||||
void update_skybox(video::IVideoDriver* driver,
|
void update_skybox(video::IVideoDriver* driver, ITextureSource *tsrc,
|
||||||
scene::ISceneManager* smgr, scene::ISceneNode* &skybox,
|
scene::ISceneManager* smgr, scene::ISceneNode* &skybox,
|
||||||
float brightness)
|
float brightness)
|
||||||
{
|
{
|
||||||
@ -535,32 +536,32 @@ void update_skybox(video::IVideoDriver* driver,
|
|||||||
if(brightness >= 0.5)
|
if(brightness >= 0.5)
|
||||||
{
|
{
|
||||||
skybox = smgr->addSkyBoxSceneNode(
|
skybox = smgr->addSkyBoxSceneNode(
|
||||||
driver->getTexture(getTexturePath("skybox2.png").c_str()),
|
tsrc->getTextureRaw("skybox2.png"),
|
||||||
driver->getTexture(getTexturePath("skybox3.png").c_str()),
|
tsrc->getTextureRaw("skybox3.png"),
|
||||||
driver->getTexture(getTexturePath("skybox1.png").c_str()),
|
tsrc->getTextureRaw("skybox1.png"),
|
||||||
driver->getTexture(getTexturePath("skybox1.png").c_str()),
|
tsrc->getTextureRaw("skybox1.png"),
|
||||||
driver->getTexture(getTexturePath("skybox1.png").c_str()),
|
tsrc->getTextureRaw("skybox1.png"),
|
||||||
driver->getTexture(getTexturePath("skybox1.png").c_str()));
|
tsrc->getTextureRaw("skybox1.png"));
|
||||||
}
|
}
|
||||||
else if(brightness >= 0.2)
|
else if(brightness >= 0.2)
|
||||||
{
|
{
|
||||||
skybox = smgr->addSkyBoxSceneNode(
|
skybox = smgr->addSkyBoxSceneNode(
|
||||||
driver->getTexture(getTexturePath("skybox2_dawn.png").c_str()),
|
tsrc->getTextureRaw("skybox2_dawn.png"),
|
||||||
driver->getTexture(getTexturePath("skybox3_dawn.png").c_str()),
|
tsrc->getTextureRaw("skybox3_dawn.png"),
|
||||||
driver->getTexture(getTexturePath("skybox1_dawn.png").c_str()),
|
tsrc->getTextureRaw("skybox1_dawn.png"),
|
||||||
driver->getTexture(getTexturePath("skybox1_dawn.png").c_str()),
|
tsrc->getTextureRaw("skybox1_dawn.png"),
|
||||||
driver->getTexture(getTexturePath("skybox1_dawn.png").c_str()),
|
tsrc->getTextureRaw("skybox1_dawn.png"),
|
||||||
driver->getTexture(getTexturePath("skybox1_dawn.png").c_str()));
|
tsrc->getTextureRaw("skybox1_dawn.png"));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
skybox = smgr->addSkyBoxSceneNode(
|
skybox = smgr->addSkyBoxSceneNode(
|
||||||
driver->getTexture(getTexturePath("skybox2_night.png").c_str()),
|
tsrc->getTextureRaw("skybox2_night.png"),
|
||||||
driver->getTexture(getTexturePath("skybox3_night.png").c_str()),
|
tsrc->getTextureRaw("skybox3_night.png"),
|
||||||
driver->getTexture(getTexturePath("skybox1_night.png").c_str()),
|
tsrc->getTextureRaw("skybox1_night.png"),
|
||||||
driver->getTexture(getTexturePath("skybox1_night.png").c_str()),
|
tsrc->getTextureRaw("skybox1_night.png"),
|
||||||
driver->getTexture(getTexturePath("skybox1_night.png").c_str()),
|
tsrc->getTextureRaw("skybox1_night.png"),
|
||||||
driver->getTexture(getTexturePath("skybox1_night.png").c_str()));
|
tsrc->getTextureRaw("skybox1_night.png"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -771,7 +772,7 @@ void the_game(
|
|||||||
*/
|
*/
|
||||||
float old_brightness = 1.0;
|
float old_brightness = 1.0;
|
||||||
scene::ISceneNode* skybox = NULL;
|
scene::ISceneNode* skybox = NULL;
|
||||||
update_skybox(driver, smgr, skybox, 1.0);
|
update_skybox(driver, tsrc, smgr, skybox, 1.0);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Create the camera node
|
Create the camera node
|
||||||
@ -886,6 +887,8 @@ void the_game(
|
|||||||
// A test
|
// A test
|
||||||
//throw con::PeerNotFoundException("lol");
|
//throw con::PeerNotFoundException("lol");
|
||||||
|
|
||||||
|
float brightness = 1.0;
|
||||||
|
|
||||||
core::list<float> frametime_log;
|
core::list<float> frametime_log;
|
||||||
|
|
||||||
float nodig_delay_counter = 0.0;
|
float nodig_delay_counter = 0.0;
|
||||||
@ -1537,6 +1540,10 @@ void the_game(
|
|||||||
player->setPosition(player->getPosition() + v3f(0,-BS,0));
|
player->setPosition(player->getPosition() + v3f(0,-BS,0));
|
||||||
camera.update(player, busytime, screensize);*/
|
camera.update(player, busytime, screensize);*/
|
||||||
}
|
}
|
||||||
|
else if(event.type == CE_TEXTURES_UPDATED)
|
||||||
|
{
|
||||||
|
update_skybox(driver, tsrc, smgr, skybox, brightness);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1902,25 +1909,27 @@ void the_game(
|
|||||||
/*
|
/*
|
||||||
Calculate stuff for drawing
|
Calculate stuff for drawing
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
Calculate general brightness
|
||||||
|
*/
|
||||||
u32 daynight_ratio = client.getDayNightRatio();
|
u32 daynight_ratio = client.getDayNightRatio();
|
||||||
u8 l = decode_light((daynight_ratio * LIGHT_SUN) / 1000);
|
u8 light8 = decode_light((daynight_ratio * LIGHT_SUN) / 1000);
|
||||||
|
brightness = (float)light8/255.0;
|
||||||
video::SColor bgcolor = video::SColor(
|
video::SColor bgcolor = video::SColor(
|
||||||
255,
|
255,
|
||||||
bgcolor_bright.getRed() * l / 255,
|
bgcolor_bright.getRed() * brightness,
|
||||||
bgcolor_bright.getGreen() * l / 255,
|
bgcolor_bright.getGreen() * brightness,
|
||||||
bgcolor_bright.getBlue() * l / 255);
|
bgcolor_bright.getBlue() * brightness);
|
||||||
/*skycolor.getRed() * l / 255,
|
/*skycolor.getRed() * brightness,
|
||||||
skycolor.getGreen() * l / 255,
|
skycolor.getGreen() * brightness,
|
||||||
skycolor.getBlue() * l / 255);*/
|
skycolor.getBlue() * brightness);*/
|
||||||
|
|
||||||
float brightness = (float)l/255.0;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Update skybox
|
Update skybox
|
||||||
*/
|
*/
|
||||||
if(fabs(brightness - old_brightness) > 0.01)
|
if(fabs(brightness - old_brightness) > 0.01)
|
||||||
update_skybox(driver, smgr, skybox, brightness);
|
update_skybox(driver, tsrc, smgr, skybox, brightness);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Update clouds
|
Update clouds
|
||||||
|
@ -174,8 +174,13 @@ public:
|
|||||||
ContentFeatures *f = &m_content_features[i];
|
ContentFeatures *f = &m_content_features[i];
|
||||||
for(u16 j=0; j<6; j++)
|
for(u16 j=0; j<6; j++)
|
||||||
tsrc->updateAP(f->tiles[j].texture);
|
tsrc->updateAP(f->tiles[j].texture);
|
||||||
if(f->special_atlas)
|
if(f->special_atlas){
|
||||||
tsrc->updateAP(*(f->special_atlas));
|
tsrc->updateAP(*(f->special_atlas));
|
||||||
|
if(f->special_material)
|
||||||
|
f->special_material->setTexture(0, f->special_atlas->atlas);
|
||||||
|
if(f->special_material2)
|
||||||
|
f->special_material2->setTexture(0, f->special_atlas->atlas);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
@ -122,6 +122,9 @@ struct ContentFeatures
|
|||||||
// Special irrlicht material, used sometimes
|
// Special irrlicht material, used sometimes
|
||||||
video::SMaterial *special_material;
|
video::SMaterial *special_material;
|
||||||
video::SMaterial *special_material2;
|
video::SMaterial *special_material2;
|
||||||
|
// Currently used for fetching liquid texture coordinates
|
||||||
|
// - This is also updated to the above two (if they are non-NULL)
|
||||||
|
// when textures are updated
|
||||||
AtlasPointer *special_atlas;
|
AtlasPointer *special_atlas;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
344
src/tile.cpp
344
src/tile.cpp
@ -145,6 +145,95 @@ std::string getTexturePath(const std::string &filename)
|
|||||||
return fullpath;
|
return fullpath;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
An internal variant of AtlasPointer with more data.
|
||||||
|
(well, more like a wrapper)
|
||||||
|
*/
|
||||||
|
|
||||||
|
struct SourceAtlasPointer
|
||||||
|
{
|
||||||
|
std::string name;
|
||||||
|
AtlasPointer a;
|
||||||
|
video::IImage *atlas_img; // The source image of the atlas
|
||||||
|
// Integer variants of position and size
|
||||||
|
v2s32 intpos;
|
||||||
|
v2u32 intsize;
|
||||||
|
|
||||||
|
SourceAtlasPointer(
|
||||||
|
const std::string &name_,
|
||||||
|
AtlasPointer a_=AtlasPointer(0, NULL),
|
||||||
|
video::IImage *atlas_img_=NULL,
|
||||||
|
v2s32 intpos_=v2s32(0,0),
|
||||||
|
v2u32 intsize_=v2u32(0,0)
|
||||||
|
):
|
||||||
|
name(name_),
|
||||||
|
a(a_),
|
||||||
|
atlas_img(atlas_img_),
|
||||||
|
intpos(intpos_),
|
||||||
|
intsize(intsize_)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
SourceImageCache: A cache used for storing source images.
|
||||||
|
*/
|
||||||
|
|
||||||
|
class SourceImageCache
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
void insert(const std::string &name, video::IImage *img)
|
||||||
|
{
|
||||||
|
assert(img);
|
||||||
|
core::map<std::string, video::IImage*>::Node *n;
|
||||||
|
n = m_images.find(name);
|
||||||
|
if(n){
|
||||||
|
video::IImage *oldimg = n->getValue();
|
||||||
|
if(oldimg)
|
||||||
|
oldimg->drop();
|
||||||
|
}
|
||||||
|
img->grab();
|
||||||
|
m_images[name] = img;
|
||||||
|
}
|
||||||
|
video::IImage* get(const std::string &name)
|
||||||
|
{
|
||||||
|
core::map<std::string, video::IImage*>::Node *n;
|
||||||
|
n = m_images.find(name);
|
||||||
|
if(n)
|
||||||
|
return n->getValue();
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
// Primarily fetches from cache, secondarily tries to read from filesystem
|
||||||
|
video::IImage* getOrLoad(const std::string &name, IrrlichtDevice *device)
|
||||||
|
{
|
||||||
|
core::map<std::string, video::IImage*>::Node *n;
|
||||||
|
n = m_images.find(name);
|
||||||
|
if(n){
|
||||||
|
n->getValue()->grab(); // Grab for caller
|
||||||
|
return n->getValue();
|
||||||
|
}
|
||||||
|
video::IVideoDriver* driver = device->getVideoDriver();
|
||||||
|
std::string path = getTexturePath(name.c_str());
|
||||||
|
if(path == ""){
|
||||||
|
infostream<<"SourceImageCache::getOrLoad(): No path found for \""
|
||||||
|
<<name<<"\""<<std::endl;
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
infostream<<"SourceImageCache::getOrLoad(): Loading path \""<<path
|
||||||
|
<<"\""<<std::endl;
|
||||||
|
video::IImage *img = driver->createImageFromFile(path.c_str());
|
||||||
|
// Even if could not be loaded, put as NULL
|
||||||
|
//m_images[name] = img;
|
||||||
|
if(img){
|
||||||
|
m_images[name] = img;
|
||||||
|
img->grab(); // Grab for caller
|
||||||
|
}
|
||||||
|
return img;
|
||||||
|
}
|
||||||
|
private:
|
||||||
|
core::map<std::string, video::IImage*> m_images;
|
||||||
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
TextureSource
|
TextureSource
|
||||||
*/
|
*/
|
||||||
@ -209,9 +298,7 @@ public:
|
|||||||
*/
|
*/
|
||||||
u32 getTextureIdDirect(const std::string &name);
|
u32 getTextureIdDirect(const std::string &name);
|
||||||
|
|
||||||
/*
|
// Finds out the name of a cached texture.
|
||||||
Finds out the name of a cached texture.
|
|
||||||
*/
|
|
||||||
std::string getTextureName(u32 id);
|
std::string getTextureName(u32 id);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -236,29 +323,25 @@ public:
|
|||||||
return ap.atlas;
|
return ap.atlas;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// Update new texture pointer and texture coordinates to an
|
||||||
Update new texture pointer and texture coordinates to an
|
// AtlasPointer based on it's texture id
|
||||||
AtlasPointer based on it's texture id
|
|
||||||
*/
|
|
||||||
void updateAP(AtlasPointer &ap);
|
void updateAP(AtlasPointer &ap);
|
||||||
|
|
||||||
/*
|
// Processes queued texture requests from other threads.
|
||||||
Processes queued texture requests from other threads.
|
// Shall be called from the main thread.
|
||||||
|
|
||||||
Shall be called from the main thread.
|
|
||||||
*/
|
|
||||||
void processQueue();
|
void processQueue();
|
||||||
|
|
||||||
/*
|
// Insert an image into the cache without touching the filesystem.
|
||||||
Build the main texture atlas which contains most of the
|
// Shall be called from the main thread.
|
||||||
textures.
|
void insertSourceImage(const std::string &name, video::IImage *img);
|
||||||
*/
|
|
||||||
void buildMainAtlas(class IGameDef *gamedef);
|
|
||||||
|
|
||||||
/*
|
// Rebuild images and textures from the current set of source images
|
||||||
Insert an image into the cache without touching the filesystem.
|
// Shall be called from the main thread.
|
||||||
*/
|
void rebuildImagesAndTextures();
|
||||||
void insertImage(const std::string &name, video::IImage *img);
|
|
||||||
|
// Build the main texture atlas which contains most of the
|
||||||
|
// textures.
|
||||||
|
void buildMainAtlas(class IGameDef *gamedef);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
@ -267,6 +350,10 @@ private:
|
|||||||
// The irrlicht device
|
// The irrlicht device
|
||||||
IrrlichtDevice *m_device;
|
IrrlichtDevice *m_device;
|
||||||
|
|
||||||
|
// Cache of source images
|
||||||
|
// This should be only accessed from the main thread
|
||||||
|
SourceImageCache m_sourcecache;
|
||||||
|
|
||||||
// A texture id is index in this array.
|
// A texture id is index in this array.
|
||||||
// The first position contains a NULL texture.
|
// The first position contains a NULL texture.
|
||||||
core::array<SourceAtlasPointer> m_atlaspointer_cache;
|
core::array<SourceAtlasPointer> m_atlaspointer_cache;
|
||||||
@ -376,7 +463,7 @@ void make_progressbar(float value, video::IImage *image);
|
|||||||
if baseimg is NULL, it is created. Otherwise stuff is made on it.
|
if baseimg is NULL, it is created. Otherwise stuff is made on it.
|
||||||
*/
|
*/
|
||||||
bool generate_image(std::string part_of_name, video::IImage *& baseimg,
|
bool generate_image(std::string part_of_name, video::IImage *& baseimg,
|
||||||
IrrlichtDevice *device);
|
IrrlichtDevice *device, SourceImageCache *sourcecache);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Generates an image from a full string like
|
Generates an image from a full string like
|
||||||
@ -385,7 +472,7 @@ bool generate_image(std::string part_of_name, video::IImage *& baseimg,
|
|||||||
This is used by buildMainAtlas().
|
This is used by buildMainAtlas().
|
||||||
*/
|
*/
|
||||||
video::IImage* generate_image_from_scratch(std::string name,
|
video::IImage* generate_image_from_scratch(std::string name,
|
||||||
IrrlichtDevice *device);
|
IrrlichtDevice *device, SourceImageCache *sourcecache);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
This method generates all the textures
|
This method generates all the textures
|
||||||
@ -525,7 +612,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) == false)
|
if(!generate_image(last_part_of_name, baseimg, m_device, &m_sourcecache))
|
||||||
{
|
{
|
||||||
infostream<<"getTextureIdDirect(): "
|
infostream<<"getTextureIdDirect(): "
|
||||||
"failed to generate \""<<last_part_of_name<<"\""
|
"failed to generate \""<<last_part_of_name<<"\""
|
||||||
@ -627,6 +714,91 @@ void TextureSource::processQueue()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void TextureSource::insertSourceImage(const std::string &name, video::IImage *img)
|
||||||
|
{
|
||||||
|
infostream<<"TextureSource::insertSourceImage(): name="<<name<<std::endl;
|
||||||
|
|
||||||
|
assert(get_current_thread_id() == m_main_thread);
|
||||||
|
|
||||||
|
m_sourcecache.insert(name, img);
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
JMutexAutoLock lock(m_atlaspointer_cache_mutex);
|
||||||
|
|
||||||
|
video::IVideoDriver* driver = m_device->getVideoDriver();
|
||||||
|
assert(driver);
|
||||||
|
|
||||||
|
// Create texture
|
||||||
|
video::ITexture *t = driver->addTexture(name.c_str(), img);
|
||||||
|
|
||||||
|
bool reuse_old_id = false;
|
||||||
|
u32 id = m_atlaspointer_cache.size();
|
||||||
|
// Check old id without fetching a texture
|
||||||
|
core::map<std::string, u32>::Node *n;
|
||||||
|
n = m_name_to_id.find(name);
|
||||||
|
// If it exists, we will replace the old definition
|
||||||
|
if(n){
|
||||||
|
id = n->getValue();
|
||||||
|
reuse_old_id = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create AtlasPointer
|
||||||
|
AtlasPointer ap(id);
|
||||||
|
ap.atlas = t;
|
||||||
|
ap.pos = v2f(0,0);
|
||||||
|
ap.size = v2f(1,1);
|
||||||
|
ap.tiled = 0;
|
||||||
|
core::dimension2d<u32> dim = img->getDimension();
|
||||||
|
|
||||||
|
// Create SourceAtlasPointer and add to containers
|
||||||
|
SourceAtlasPointer nap(name, ap, img, v2s32(0,0), dim);
|
||||||
|
if(reuse_old_id)
|
||||||
|
m_atlaspointer_cache[id] = nap;
|
||||||
|
else
|
||||||
|
m_atlaspointer_cache.push_back(nap);
|
||||||
|
m_name_to_id[name] = id;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void TextureSource::rebuildImagesAndTextures()
|
||||||
|
{
|
||||||
|
JMutexAutoLock lock(m_atlaspointer_cache_mutex);
|
||||||
|
|
||||||
|
/*// Oh well... just clear everything, they'll load sometime.
|
||||||
|
m_atlaspointer_cache.clear();
|
||||||
|
m_name_to_id.clear();*/
|
||||||
|
|
||||||
|
video::IVideoDriver* driver = m_device->getVideoDriver();
|
||||||
|
|
||||||
|
// Remove source images from textures to disable inheriting textures
|
||||||
|
// from existing textures
|
||||||
|
/*for(u32 i=0; i<m_atlaspointer_cache.size(); i++){
|
||||||
|
SourceAtlasPointer *sap = &m_atlaspointer_cache[i];
|
||||||
|
sap->atlas_img->drop();
|
||||||
|
sap->atlas_img = NULL;
|
||||||
|
}*/
|
||||||
|
|
||||||
|
// Recreate textures
|
||||||
|
for(u32 i=0; i<m_atlaspointer_cache.size(); i++){
|
||||||
|
SourceAtlasPointer *sap = &m_atlaspointer_cache[i];
|
||||||
|
video::IImage *img =
|
||||||
|
generate_image_from_scratch(sap->name, m_device, &m_sourcecache);
|
||||||
|
// Create texture from resulting image
|
||||||
|
video::ITexture *t = NULL;
|
||||||
|
if(img)
|
||||||
|
t = driver->addTexture(sap->name.c_str(), img);
|
||||||
|
|
||||||
|
// Replace texture
|
||||||
|
sap->a.atlas = t;
|
||||||
|
sap->a.pos = v2f(0,0);
|
||||||
|
sap->a.size = v2f(1,1);
|
||||||
|
sap->a.tiled = 0;
|
||||||
|
sap->atlas_img = img;
|
||||||
|
sap->intpos = v2s32(0,0);
|
||||||
|
sap->intsize = img->getDimension();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void TextureSource::buildMainAtlas(class IGameDef *gamedef)
|
void TextureSource::buildMainAtlas(class IGameDef *gamedef)
|
||||||
{
|
{
|
||||||
assert(gamedef->tsrc() == this);
|
assert(gamedef->tsrc() == this);
|
||||||
@ -711,20 +883,9 @@ void TextureSource::buildMainAtlas(class IGameDef *gamedef)
|
|||||||
{
|
{
|
||||||
std::string name = i.getNode()->getKey();
|
std::string name = i.getNode()->getKey();
|
||||||
|
|
||||||
/*video::IImage *img = driver->createImageFromFile(
|
|
||||||
getTexturePath(name.c_str()).c_str());
|
|
||||||
if(img == NULL)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
core::dimension2d<u32> dim = img->getDimension();
|
|
||||||
// Make a copy with the right color format
|
|
||||||
video::IImage *img2 =
|
|
||||||
driver->createImage(video::ECF_A8R8G8B8, dim);
|
|
||||||
img->copyTo(img2);
|
|
||||||
img->drop();*/
|
|
||||||
|
|
||||||
// Generate image by name
|
// Generate image by name
|
||||||
video::IImage *img2 = generate_image_from_scratch(name, m_device);
|
video::IImage *img2 = generate_image_from_scratch(name, m_device,
|
||||||
|
&m_sourcecache);
|
||||||
if(img2 == NULL)
|
if(img2 == NULL)
|
||||||
{
|
{
|
||||||
infostream<<"TextureSource::buildMainAtlas(): Couldn't generate texture atlas: Couldn't generate image \""<<name<<"\""<<std::endl;
|
infostream<<"TextureSource::buildMainAtlas(): Couldn't generate texture atlas: Couldn't generate image \""<<name<<"\""<<std::endl;
|
||||||
@ -810,9 +971,9 @@ void TextureSource::buildMainAtlas(class IGameDef *gamedef)
|
|||||||
if(n){
|
if(n){
|
||||||
id = n->getValue();
|
id = n->getValue();
|
||||||
reuse_old_id = true;
|
reuse_old_id = true;
|
||||||
|
infostream<<"TextureSource::buildMainAtlas(): "
|
||||||
|
<<"Replacing old AtlasPointer"<<std::endl;
|
||||||
}
|
}
|
||||||
infostream<<"TextureSource::buildMainAtlas(): "
|
|
||||||
<<"Replacing old AtlasPointer"<<std::endl;
|
|
||||||
|
|
||||||
// Create AtlasPointer
|
// Create AtlasPointer
|
||||||
AtlasPointer ap(id);
|
AtlasPointer ap(id);
|
||||||
@ -867,48 +1028,8 @@ void TextureSource::buildMainAtlas(class IGameDef *gamedef)
|
|||||||
driver->writeImageToFile(atlas_img, atlaspath.c_str());*/
|
driver->writeImageToFile(atlas_img, atlaspath.c_str());*/
|
||||||
}
|
}
|
||||||
|
|
||||||
void TextureSource::insertImage(const std::string &name, video::IImage *img)
|
|
||||||
{
|
|
||||||
infostream<<"TextureSource::insertImage(): name="<<name<<std::endl;
|
|
||||||
|
|
||||||
JMutexAutoLock lock(m_atlaspointer_cache_mutex);
|
|
||||||
|
|
||||||
video::IVideoDriver* driver = m_device->getVideoDriver();
|
|
||||||
assert(driver);
|
|
||||||
|
|
||||||
// Create texture
|
|
||||||
video::ITexture *t = driver->addTexture(name.c_str(), img);
|
|
||||||
|
|
||||||
bool reuse_old_id = false;
|
|
||||||
u32 id = m_atlaspointer_cache.size();
|
|
||||||
// Check old id without fetching a texture
|
|
||||||
core::map<std::string, u32>::Node *n;
|
|
||||||
n = m_name_to_id.find(name);
|
|
||||||
// If it exists, we will replace the old definition
|
|
||||||
if(n){
|
|
||||||
id = n->getValue();
|
|
||||||
reuse_old_id = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Create AtlasPointer
|
|
||||||
AtlasPointer ap(id);
|
|
||||||
ap.atlas = t;
|
|
||||||
ap.pos = v2f(0,0);
|
|
||||||
ap.size = v2f(1,1);
|
|
||||||
ap.tiled = 0;
|
|
||||||
core::dimension2d<u32> dim = img->getDimension();
|
|
||||||
|
|
||||||
// Create SourceAtlasPointer and add to containers
|
|
||||||
SourceAtlasPointer nap(name, ap, img, v2s32(0,0), dim);
|
|
||||||
if(reuse_old_id)
|
|
||||||
m_atlaspointer_cache[id] = nap;
|
|
||||||
else
|
|
||||||
m_atlaspointer_cache.push_back(nap);
|
|
||||||
m_name_to_id[name] = id;
|
|
||||||
}
|
|
||||||
|
|
||||||
video::IImage* generate_image_from_scratch(std::string name,
|
video::IImage* generate_image_from_scratch(std::string name,
|
||||||
IrrlichtDevice *device)
|
IrrlichtDevice *device, SourceImageCache *sourcecache)
|
||||||
{
|
{
|
||||||
/*infostream<<"generate_image_from_scratch(): "
|
/*infostream<<"generate_image_from_scratch(): "
|
||||||
"\""<<name<<"\""<<std::endl;*/
|
"\""<<name<<"\""<<std::endl;*/
|
||||||
@ -951,7 +1072,8 @@ video::IImage* generate_image_from_scratch(std::string name,
|
|||||||
/*infostream<<"generate_image_from_scratch(): Calling itself recursively"
|
/*infostream<<"generate_image_from_scratch(): Calling itself recursively"
|
||||||
" to get base image of \""<<name<<"\" = \""
|
" to get base image of \""<<name<<"\" = \""
|
||||||
<<base_image_name<<"\""<<std::endl;*/
|
<<base_image_name<<"\""<<std::endl;*/
|
||||||
baseimg = generate_image_from_scratch(base_image_name, device);
|
baseimg = generate_image_from_scratch(base_image_name, device,
|
||||||
|
sourcecache);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -963,7 +1085,7 @@ video::IImage* generate_image_from_scratch(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, device) == false)
|
if(!generate_image(last_part_of_name, baseimg, device, sourcecache))
|
||||||
{
|
{
|
||||||
infostream<<"generate_image_from_scratch(): "
|
infostream<<"generate_image_from_scratch(): "
|
||||||
"failed to generate \""<<last_part_of_name<<"\""
|
"failed to generate \""<<last_part_of_name<<"\""
|
||||||
@ -975,7 +1097,7 @@ video::IImage* generate_image_from_scratch(std::string name,
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool generate_image(std::string part_of_name, video::IImage *& baseimg,
|
bool generate_image(std::string part_of_name, video::IImage *& baseimg,
|
||||||
IrrlichtDevice *device)
|
IrrlichtDevice *device, SourceImageCache *sourcecache)
|
||||||
{
|
{
|
||||||
video::IVideoDriver* driver = device->getVideoDriver();
|
video::IVideoDriver* driver = device->getVideoDriver();
|
||||||
assert(driver);
|
assert(driver);
|
||||||
@ -983,18 +1105,12 @@ bool generate_image(std::string part_of_name, video::IImage *& baseimg,
|
|||||||
// Stuff starting with [ are special commands
|
// Stuff starting with [ are special commands
|
||||||
if(part_of_name[0] != '[')
|
if(part_of_name[0] != '[')
|
||||||
{
|
{
|
||||||
// A normal texture; load it from a file
|
video::IImage *image = sourcecache->getOrLoad(part_of_name, device);
|
||||||
std::string path = getTexturePath(part_of_name.c_str());
|
|
||||||
/*infostream<<"generate_image(): Loading path \""<<path
|
|
||||||
<<"\""<<std::endl;*/
|
|
||||||
|
|
||||||
video::IImage *image = driver->createImageFromFile(path.c_str());
|
|
||||||
|
|
||||||
if(image == NULL)
|
if(image == NULL)
|
||||||
{
|
{
|
||||||
infostream<<"generate_image(): Could not load image \""
|
infostream<<"generate_image(): Could not load image \""
|
||||||
<<part_of_name<<"\" from path \""<<path<<"\""
|
<<part_of_name<<"\""<<" while building texture"<<std::endl;
|
||||||
<<" while building texture"<<std::endl;
|
|
||||||
|
|
||||||
//return false;
|
//return false;
|
||||||
|
|
||||||
@ -1099,8 +1215,7 @@ 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 = driver->createImageFromFile(
|
video::IImage *img_crack = sourcecache->getOrLoad("crack.png", device);
|
||||||
getTexturePath("crack.png").c_str());
|
|
||||||
|
|
||||||
if(img_crack)
|
if(img_crack)
|
||||||
{
|
{
|
||||||
@ -1186,8 +1301,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 = driver->createImageFromFile(
|
video::IImage *img = sourcecache->getOrLoad(filename, device);
|
||||||
getTexturePath(filename.c_str()).c_str());
|
|
||||||
if(img)
|
if(img)
|
||||||
{
|
{
|
||||||
core::dimension2d<u32> dim = img->getDimension();
|
core::dimension2d<u32> dim = img->getDimension();
|
||||||
@ -1248,10 +1362,10 @@ bool generate_image(std::string part_of_name, video::IImage *& baseimg,
|
|||||||
|
|
||||||
std::string path = getTexturePath(filename.c_str());
|
std::string path = getTexturePath(filename.c_str());
|
||||||
|
|
||||||
infostream<<"generate_image(): Loading path \""<<path
|
infostream<<"generate_image(): Loading file \""<<filename
|
||||||
<<"\""<<std::endl;
|
<<"\""<<std::endl;
|
||||||
|
|
||||||
video::IImage *image = driver->createImageFromFile(path.c_str());
|
video::IImage *image = sourcecache->getOrLoad(filename, device);
|
||||||
|
|
||||||
if(image == NULL)
|
if(image == NULL)
|
||||||
{
|
{
|
||||||
@ -1297,17 +1411,15 @@ bool generate_image(std::string part_of_name, video::IImage *& baseimg,
|
|||||||
u32 b1 = stoi(sf.next(":"));
|
u32 b1 = stoi(sf.next(":"));
|
||||||
std::string filename = sf.next("");
|
std::string filename = sf.next("");
|
||||||
|
|
||||||
std::string path = getTexturePath(filename.c_str());
|
infostream<<"generate_image(): Loading file \""<<filename
|
||||||
|
|
||||||
infostream<<"generate_image(): Loading path \""<<path
|
|
||||||
<<"\""<<std::endl;
|
<<"\""<<std::endl;
|
||||||
|
|
||||||
video::IImage *image = driver->createImageFromFile(path.c_str());
|
video::IImage *image = sourcecache->getOrLoad(filename, device);
|
||||||
|
|
||||||
if(image == NULL)
|
if(image == NULL)
|
||||||
{
|
{
|
||||||
infostream<<"generate_image(): Loading path \""
|
infostream<<"generate_image(): Loading file \""
|
||||||
<<path<<"\" failed"<<std::endl;
|
<<filename<<"\" failed"<<std::endl;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -1356,17 +1468,15 @@ bool generate_image(std::string part_of_name, video::IImage *& baseimg,
|
|||||||
u32 b2 = stoi(sf.next(":"));
|
u32 b2 = stoi(sf.next(":"));
|
||||||
std::string filename = sf.next("");
|
std::string filename = sf.next("");
|
||||||
|
|
||||||
std::string path = getTexturePath(filename.c_str());
|
infostream<<"generate_image(): Loading filename \""<<filename
|
||||||
|
|
||||||
infostream<<"generate_image(): Loading path \""<<path
|
|
||||||
<<"\""<<std::endl;
|
<<"\""<<std::endl;
|
||||||
|
|
||||||
video::IImage *image = driver->createImageFromFile(path.c_str());
|
video::IImage *image = sourcecache->getOrLoad(filename, device);
|
||||||
|
|
||||||
if(image == NULL)
|
if(image == NULL)
|
||||||
{
|
{
|
||||||
infostream<<"generate_image(): Loading path \""
|
infostream<<"generate_image(): Loading file \""
|
||||||
<<path<<"\" failed"<<std::endl;
|
<<filename<<"\" failed"<<std::endl;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -1419,14 +1529,14 @@ bool generate_image(std::string part_of_name, video::IImage *& baseimg,
|
|||||||
std::string imagename_right = sf.next("{");
|
std::string imagename_right = sf.next("{");
|
||||||
|
|
||||||
#if 1
|
#if 1
|
||||||
//TODO
|
// TODO: Create cube with different textures on different sides
|
||||||
|
|
||||||
if(driver->queryFeature(video::EVDF_RENDER_TO_TARGET) == false)
|
if(driver->queryFeature(video::EVDF_RENDER_TO_TARGET) == false)
|
||||||
{
|
{
|
||||||
infostream<<"generate_image(): EVDF_RENDER_TO_TARGET"
|
infostream<<"generate_image(): EVDF_RENDER_TO_TARGET"
|
||||||
" not supported. Creating fallback image"<<std::endl;
|
" not supported. Creating fallback image"<<std::endl;
|
||||||
baseimg = generate_image_from_scratch(
|
baseimg = generate_image_from_scratch(
|
||||||
imagename_top, device);
|
imagename_top, device, sourcecache);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1437,14 +1547,15 @@ bool generate_image(std::string part_of_name, video::IImage *& baseimg,
|
|||||||
|
|
||||||
// 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 = generate_image_from_scratch(
|
||||||
imagename_top, device);
|
imagename_top, device, sourcecache);
|
||||||
video::IImage *img_left = generate_image_from_scratch(
|
video::IImage *img_left = generate_image_from_scratch(
|
||||||
imagename_left, device);
|
imagename_left, device, sourcecache);
|
||||||
video::IImage *img_right = generate_image_from_scratch(
|
video::IImage *img_right = generate_image_from_scratch(
|
||||||
imagename_right, device);
|
imagename_right, device, sourcecache);
|
||||||
assert(img_top && img_left && img_right);
|
assert(img_top && img_left && img_right);
|
||||||
|
|
||||||
// TODO: Create textures from images
|
// Create textures from images
|
||||||
|
// TODO: Use them all
|
||||||
video::ITexture *texture_top = driver->addTexture(
|
video::ITexture *texture_top = driver->addTexture(
|
||||||
(imagename_top + "__temp__").c_str(), img_top);
|
(imagename_top + "__temp__").c_str(), img_top);
|
||||||
assert(texture_top);
|
assert(texture_top);
|
||||||
@ -1515,7 +1626,8 @@ bool generate_image(std::string part_of_name, video::IImage *& baseimg,
|
|||||||
// Unset render target
|
// Unset render target
|
||||||
driver->setRenderTarget(0, true, true, 0);
|
driver->setRenderTarget(0, true, true, 0);
|
||||||
|
|
||||||
//TODO: Free textures of images
|
// Free textures of images
|
||||||
|
// TODO: When all are used, free them all
|
||||||
driver->removeTexture(texture_top);
|
driver->removeTexture(texture_top);
|
||||||
|
|
||||||
// Create image of render target
|
// Create image of render target
|
||||||
|
32
src/tile.h
32
src/tile.h
@ -93,34 +93,6 @@ struct AtlasPointer
|
|||||||
float y1(){ return pos.Y + size.Y; }
|
float y1(){ return pos.Y + size.Y; }
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
|
||||||
An internal variant of the former with more data.
|
|
||||||
*/
|
|
||||||
struct SourceAtlasPointer
|
|
||||||
{
|
|
||||||
std::string name;
|
|
||||||
AtlasPointer a;
|
|
||||||
video::IImage *atlas_img; // The source image of the atlas
|
|
||||||
// Integer variants of position and size
|
|
||||||
v2s32 intpos;
|
|
||||||
v2u32 intsize;
|
|
||||||
|
|
||||||
SourceAtlasPointer(
|
|
||||||
const std::string &name_,
|
|
||||||
AtlasPointer a_=AtlasPointer(0, NULL),
|
|
||||||
video::IImage *atlas_img_=NULL,
|
|
||||||
v2s32 intpos_=v2s32(0,0),
|
|
||||||
v2u32 intsize_=v2u32(0,0)
|
|
||||||
):
|
|
||||||
name(name_),
|
|
||||||
a(a_),
|
|
||||||
atlas_img(atlas_img_),
|
|
||||||
intpos(intpos_),
|
|
||||||
intsize(intsize_)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
TextureSource creates and caches textures.
|
TextureSource creates and caches textures.
|
||||||
*/
|
*/
|
||||||
@ -157,9 +129,9 @@ public:
|
|||||||
virtual void updateAP(AtlasPointer &ap){};
|
virtual void updateAP(AtlasPointer &ap){};
|
||||||
|
|
||||||
virtual void processQueue()=0;
|
virtual void processQueue()=0;
|
||||||
|
virtual void insertSourceImage(const std::string &name, video::IImage *img)=0;
|
||||||
|
virtual void rebuildImagesAndTextures()=0;
|
||||||
virtual void buildMainAtlas(class IGameDef *gamedef)=0;
|
virtual void buildMainAtlas(class IGameDef *gamedef)=0;
|
||||||
// img is eaten, do not drop it
|
|
||||||
virtual void insertImage(const std::string &name, video::IImage *img)=0;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
IWritableTextureSource* createTextureSource(IrrlichtDevice *device);
|
IWritableTextureSource* createTextureSource(IrrlichtDevice *device);
|
||||||
|
Loading…
Reference in New Issue
Block a user