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)
|
||||
if(g_settings->getBool("enable_texture_atlas"))
|
||||
tsrc->buildMainAtlas(this);
|
||||
m_tsrc->buildMainAtlas(this);
|
||||
else
|
||||
infostream<<"Not building texture atlas."<<std::endl;
|
||||
|
||||
// Update textures
|
||||
m_nodedef->updateTextures(tsrc);
|
||||
// Update node textures
|
||||
m_nodedef->updateTextures(m_tsrc);
|
||||
|
||||
// NOTE: This should be done only after getting possible dynamic
|
||||
// game definitions from the server, or at least shut down and
|
||||
// restarted when doing so
|
||||
// Start threads after setting up content definitions
|
||||
m_mesh_update_thread.Start();
|
||||
|
||||
/*
|
||||
@ -1568,17 +1566,28 @@ void Client::ProcessData(u8 *data, u32 datasize, u16 sender_peer_id)
|
||||
rfile->drop();
|
||||
continue;
|
||||
}
|
||||
m_tsrc->insertImage(name, img);
|
||||
m_tsrc->insertSourceImage(name, img);
|
||||
img->drop();
|
||||
rfile->drop();
|
||||
}
|
||||
|
||||
// Rebuild inherited images and recreate textures
|
||||
m_tsrc->rebuildImagesAndTextures();
|
||||
|
||||
// Update texture atlas
|
||||
if(g_settings->getBool("enable_texture_atlas"))
|
||||
m_tsrc->buildMainAtlas(this);
|
||||
|
||||
// Update node textures
|
||||
m_nodedef->updateTextures(m_tsrc);
|
||||
|
||||
// Resume threads
|
||||
m_mesh_update_thread.setRun(true);
|
||||
m_mesh_update_thread.Start();
|
||||
|
||||
ClientEvent event;
|
||||
event.type = CE_TEXTURES_UPDATED;
|
||||
m_client_event_queue.push_back(event);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
13
src/client.h
13
src/client.h
@ -122,6 +122,7 @@ enum ClientEventType
|
||||
CE_PLAYER_DAMAGE,
|
||||
CE_PLAYER_FORCE_MOVE,
|
||||
CE_DEATHSCREEN,
|
||||
CE_TEXTURES_UPDATED
|
||||
};
|
||||
|
||||
struct ClientEvent
|
||||
@ -143,6 +144,8 @@ struct ClientEvent
|
||||
f32 camera_point_target_y;
|
||||
f32 camera_point_target_z;
|
||||
} deathscreen;
|
||||
struct{
|
||||
} textures_updated;
|
||||
};
|
||||
};
|
||||
|
||||
@ -302,15 +305,11 @@ public:
|
||||
ClientEvent getClientEvent();
|
||||
|
||||
inline bool accessDenied()
|
||||
{
|
||||
return m_access_denied;
|
||||
}
|
||||
{ return m_access_denied; }
|
||||
|
||||
inline std::wstring accessDeniedReason()
|
||||
{
|
||||
return m_access_denied_reason;
|
||||
}
|
||||
|
||||
{ return m_access_denied_reason; }
|
||||
|
||||
float getRTT(void);
|
||||
|
||||
// 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 "tooldef.h"
|
||||
#include "content_mapnode.h" // Default nodes
|
||||
#include "tile.h" // For TextureSource
|
||||
|
||||
/*
|
||||
Setting this to 1 enables a special camera mode that forces
|
||||
@ -519,7 +520,7 @@ void getPointedNode(Client *client, v3f player_position,
|
||||
} // for coords
|
||||
}
|
||||
|
||||
void update_skybox(video::IVideoDriver* driver,
|
||||
void update_skybox(video::IVideoDriver* driver, ITextureSource *tsrc,
|
||||
scene::ISceneManager* smgr, scene::ISceneNode* &skybox,
|
||||
float brightness)
|
||||
{
|
||||
@ -535,32 +536,32 @@ void update_skybox(video::IVideoDriver* driver,
|
||||
if(brightness >= 0.5)
|
||||
{
|
||||
skybox = smgr->addSkyBoxSceneNode(
|
||||
driver->getTexture(getTexturePath("skybox2.png").c_str()),
|
||||
driver->getTexture(getTexturePath("skybox3.png").c_str()),
|
||||
driver->getTexture(getTexturePath("skybox1.png").c_str()),
|
||||
driver->getTexture(getTexturePath("skybox1.png").c_str()),
|
||||
driver->getTexture(getTexturePath("skybox1.png").c_str()),
|
||||
driver->getTexture(getTexturePath("skybox1.png").c_str()));
|
||||
tsrc->getTextureRaw("skybox2.png"),
|
||||
tsrc->getTextureRaw("skybox3.png"),
|
||||
tsrc->getTextureRaw("skybox1.png"),
|
||||
tsrc->getTextureRaw("skybox1.png"),
|
||||
tsrc->getTextureRaw("skybox1.png"),
|
||||
tsrc->getTextureRaw("skybox1.png"));
|
||||
}
|
||||
else if(brightness >= 0.2)
|
||||
{
|
||||
skybox = smgr->addSkyBoxSceneNode(
|
||||
driver->getTexture(getTexturePath("skybox2_dawn.png").c_str()),
|
||||
driver->getTexture(getTexturePath("skybox3_dawn.png").c_str()),
|
||||
driver->getTexture(getTexturePath("skybox1_dawn.png").c_str()),
|
||||
driver->getTexture(getTexturePath("skybox1_dawn.png").c_str()),
|
||||
driver->getTexture(getTexturePath("skybox1_dawn.png").c_str()),
|
||||
driver->getTexture(getTexturePath("skybox1_dawn.png").c_str()));
|
||||
tsrc->getTextureRaw("skybox2_dawn.png"),
|
||||
tsrc->getTextureRaw("skybox3_dawn.png"),
|
||||
tsrc->getTextureRaw("skybox1_dawn.png"),
|
||||
tsrc->getTextureRaw("skybox1_dawn.png"),
|
||||
tsrc->getTextureRaw("skybox1_dawn.png"),
|
||||
tsrc->getTextureRaw("skybox1_dawn.png"));
|
||||
}
|
||||
else
|
||||
{
|
||||
skybox = smgr->addSkyBoxSceneNode(
|
||||
driver->getTexture(getTexturePath("skybox2_night.png").c_str()),
|
||||
driver->getTexture(getTexturePath("skybox3_night.png").c_str()),
|
||||
driver->getTexture(getTexturePath("skybox1_night.png").c_str()),
|
||||
driver->getTexture(getTexturePath("skybox1_night.png").c_str()),
|
||||
driver->getTexture(getTexturePath("skybox1_night.png").c_str()),
|
||||
driver->getTexture(getTexturePath("skybox1_night.png").c_str()));
|
||||
tsrc->getTextureRaw("skybox2_night.png"),
|
||||
tsrc->getTextureRaw("skybox3_night.png"),
|
||||
tsrc->getTextureRaw("skybox1_night.png"),
|
||||
tsrc->getTextureRaw("skybox1_night.png"),
|
||||
tsrc->getTextureRaw("skybox1_night.png"),
|
||||
tsrc->getTextureRaw("skybox1_night.png"));
|
||||
}
|
||||
}
|
||||
|
||||
@ -771,7 +772,7 @@ void the_game(
|
||||
*/
|
||||
float old_brightness = 1.0;
|
||||
scene::ISceneNode* skybox = NULL;
|
||||
update_skybox(driver, smgr, skybox, 1.0);
|
||||
update_skybox(driver, tsrc, smgr, skybox, 1.0);
|
||||
|
||||
/*
|
||||
Create the camera node
|
||||
@ -886,6 +887,8 @@ void the_game(
|
||||
// A test
|
||||
//throw con::PeerNotFoundException("lol");
|
||||
|
||||
float brightness = 1.0;
|
||||
|
||||
core::list<float> frametime_log;
|
||||
|
||||
float nodig_delay_counter = 0.0;
|
||||
@ -1537,6 +1540,10 @@ void the_game(
|
||||
player->setPosition(player->getPosition() + v3f(0,-BS,0));
|
||||
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 general brightness
|
||||
*/
|
||||
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(
|
||||
255,
|
||||
bgcolor_bright.getRed() * l / 255,
|
||||
bgcolor_bright.getGreen() * l / 255,
|
||||
bgcolor_bright.getBlue() * l / 255);
|
||||
/*skycolor.getRed() * l / 255,
|
||||
skycolor.getGreen() * l / 255,
|
||||
skycolor.getBlue() * l / 255);*/
|
||||
|
||||
float brightness = (float)l/255.0;
|
||||
bgcolor_bright.getRed() * brightness,
|
||||
bgcolor_bright.getGreen() * brightness,
|
||||
bgcolor_bright.getBlue() * brightness);
|
||||
/*skycolor.getRed() * brightness,
|
||||
skycolor.getGreen() * brightness,
|
||||
skycolor.getBlue() * brightness);*/
|
||||
|
||||
/*
|
||||
Update skybox
|
||||
*/
|
||||
if(fabs(brightness - old_brightness) > 0.01)
|
||||
update_skybox(driver, smgr, skybox, brightness);
|
||||
update_skybox(driver, tsrc, smgr, skybox, brightness);
|
||||
|
||||
/*
|
||||
Update clouds
|
||||
|
@ -174,8 +174,13 @@ public:
|
||||
ContentFeatures *f = &m_content_features[i];
|
||||
for(u16 j=0; j<6; j++)
|
||||
tsrc->updateAP(f->tiles[j].texture);
|
||||
if(f->special_atlas)
|
||||
if(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
|
||||
}
|
||||
|
@ -122,6 +122,9 @@ struct ContentFeatures
|
||||
// Special irrlicht material, used sometimes
|
||||
video::SMaterial *special_material;
|
||||
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;
|
||||
#endif
|
||||
|
||||
|
344
src/tile.cpp
344
src/tile.cpp
@ -145,6 +145,95 @@ std::string getTexturePath(const std::string &filename)
|
||||
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
|
||||
*/
|
||||
@ -209,9 +298,7 @@ public:
|
||||
*/
|
||||
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);
|
||||
|
||||
/*
|
||||
@ -236,29 +323,25 @@ public:
|
||||
return ap.atlas;
|
||||
}
|
||||
|
||||
/*
|
||||
Update new texture pointer and texture coordinates to an
|
||||
AtlasPointer based on it's texture id
|
||||
*/
|
||||
// Update new texture pointer and texture coordinates to an
|
||||
// AtlasPointer based on it's texture id
|
||||
void updateAP(AtlasPointer &ap);
|
||||
|
||||
/*
|
||||
Processes queued texture requests from other threads.
|
||||
|
||||
Shall be called from the main thread.
|
||||
*/
|
||||
// Processes queued texture requests from other threads.
|
||||
// Shall be called from the main thread.
|
||||
void processQueue();
|
||||
|
||||
/*
|
||||
Build the main texture atlas which contains most of the
|
||||
textures.
|
||||
*/
|
||||
void buildMainAtlas(class IGameDef *gamedef);
|
||||
// Insert an image into the cache without touching the filesystem.
|
||||
// Shall be called from the main thread.
|
||||
void insertSourceImage(const std::string &name, video::IImage *img);
|
||||
|
||||
/*
|
||||
Insert an image into the cache without touching the filesystem.
|
||||
*/
|
||||
void insertImage(const std::string &name, video::IImage *img);
|
||||
// Rebuild images and textures from the current set of source images
|
||||
// Shall be called from the main thread.
|
||||
void rebuildImagesAndTextures();
|
||||
|
||||
// Build the main texture atlas which contains most of the
|
||||
// textures.
|
||||
void buildMainAtlas(class IGameDef *gamedef);
|
||||
|
||||
private:
|
||||
|
||||
@ -267,6 +350,10 @@ private:
|
||||
// The irrlicht 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.
|
||||
// The first position contains a NULL texture.
|
||||
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.
|
||||
*/
|
||||
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
|
||||
@ -385,7 +472,7 @@ bool generate_image(std::string part_of_name, video::IImage *& baseimg,
|
||||
This is used by buildMainAtlas().
|
||||
*/
|
||||
video::IImage* generate_image_from_scratch(std::string name,
|
||||
IrrlichtDevice *device);
|
||||
IrrlichtDevice *device, SourceImageCache *sourcecache);
|
||||
|
||||
/*
|
||||
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;
|
||||
|
||||
// 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(): "
|
||||
"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)
|
||||
{
|
||||
assert(gamedef->tsrc() == this);
|
||||
@ -711,20 +883,9 @@ void TextureSource::buildMainAtlas(class IGameDef *gamedef)
|
||||
{
|
||||
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
|
||||
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)
|
||||
{
|
||||
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){
|
||||
id = n->getValue();
|
||||
reuse_old_id = true;
|
||||
infostream<<"TextureSource::buildMainAtlas(): "
|
||||
<<"Replacing old AtlasPointer"<<std::endl;
|
||||
}
|
||||
infostream<<"TextureSource::buildMainAtlas(): "
|
||||
<<"Replacing old AtlasPointer"<<std::endl;
|
||||
|
||||
// Create AtlasPointer
|
||||
AtlasPointer ap(id);
|
||||
@ -867,48 +1028,8 @@ void TextureSource::buildMainAtlas(class IGameDef *gamedef)
|
||||
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,
|
||||
IrrlichtDevice *device)
|
||||
IrrlichtDevice *device, SourceImageCache *sourcecache)
|
||||
{
|
||||
/*infostream<<"generate_image_from_scratch(): "
|
||||
"\""<<name<<"\""<<std::endl;*/
|
||||
@ -951,7 +1072,8 @@ video::IImage* generate_image_from_scratch(std::string name,
|
||||
/*infostream<<"generate_image_from_scratch(): Calling itself recursively"
|
||||
" to get base image of \""<<name<<"\" = \""
|
||||
<<base_image_name<<"\""<<std::endl;*/
|
||||
baseimg = generate_image_from_scratch(base_image_name, device);
|
||||
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;
|
||||
|
||||
// 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(): "
|
||||
"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,
|
||||
IrrlichtDevice *device)
|
||||
IrrlichtDevice *device, SourceImageCache *sourcecache)
|
||||
{
|
||||
video::IVideoDriver* driver = device->getVideoDriver();
|
||||
assert(driver);
|
||||
@ -983,18 +1105,12 @@ bool generate_image(std::string part_of_name, video::IImage *& baseimg,
|
||||
// Stuff starting with [ are special commands
|
||||
if(part_of_name[0] != '[')
|
||||
{
|
||||
// A normal texture; load it from a file
|
||||
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());
|
||||
video::IImage *image = sourcecache->getOrLoad(part_of_name, device);
|
||||
|
||||
if(image == NULL)
|
||||
{
|
||||
infostream<<"generate_image(): Could not load image \""
|
||||
<<part_of_name<<"\" from path \""<<path<<"\""
|
||||
<<" while building texture"<<std::endl;
|
||||
<<part_of_name<<"\""<<" while building texture"<<std::endl;
|
||||
|
||||
//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
|
||||
horizontally tiled.
|
||||
*/
|
||||
video::IImage *img_crack = driver->createImageFromFile(
|
||||
getTexturePath("crack.png").c_str());
|
||||
video::IImage *img_crack = sourcecache->getOrLoad("crack.png", device);
|
||||
|
||||
if(img_crack)
|
||||
{
|
||||
@ -1186,8 +1301,7 @@ bool generate_image(std::string part_of_name, video::IImage *& baseimg,
|
||||
infostream<<"Adding \""<<filename
|
||||
<<"\" to combined ("<<x<<","<<y<<")"
|
||||
<<std::endl;
|
||||
video::IImage *img = driver->createImageFromFile(
|
||||
getTexturePath(filename.c_str()).c_str());
|
||||
video::IImage *img = sourcecache->getOrLoad(filename, device);
|
||||
if(img)
|
||||
{
|
||||
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());
|
||||
|
||||
infostream<<"generate_image(): Loading path \""<<path
|
||||
infostream<<"generate_image(): Loading file \""<<filename
|
||||
<<"\""<<std::endl;
|
||||
|
||||
video::IImage *image = driver->createImageFromFile(path.c_str());
|
||||
video::IImage *image = sourcecache->getOrLoad(filename, device);
|
||||
|
||||
if(image == NULL)
|
||||
{
|
||||
@ -1297,17 +1411,15 @@ bool generate_image(std::string part_of_name, video::IImage *& baseimg,
|
||||
u32 b1 = stoi(sf.next(":"));
|
||||
std::string filename = sf.next("");
|
||||
|
||||
std::string path = getTexturePath(filename.c_str());
|
||||
|
||||
infostream<<"generate_image(): Loading path \""<<path
|
||||
infostream<<"generate_image(): Loading file \""<<filename
|
||||
<<"\""<<std::endl;
|
||||
|
||||
video::IImage *image = driver->createImageFromFile(path.c_str());
|
||||
video::IImage *image = sourcecache->getOrLoad(filename, device);
|
||||
|
||||
if(image == NULL)
|
||||
{
|
||||
infostream<<"generate_image(): Loading path \""
|
||||
<<path<<"\" failed"<<std::endl;
|
||||
infostream<<"generate_image(): Loading file \""
|
||||
<<filename<<"\" failed"<<std::endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -1356,17 +1468,15 @@ bool generate_image(std::string part_of_name, video::IImage *& baseimg,
|
||||
u32 b2 = stoi(sf.next(":"));
|
||||
std::string filename = sf.next("");
|
||||
|
||||
std::string path = getTexturePath(filename.c_str());
|
||||
|
||||
infostream<<"generate_image(): Loading path \""<<path
|
||||
infostream<<"generate_image(): Loading filename \""<<filename
|
||||
<<"\""<<std::endl;
|
||||
|
||||
video::IImage *image = driver->createImageFromFile(path.c_str());
|
||||
video::IImage *image = sourcecache->getOrLoad(filename, device);
|
||||
|
||||
if(image == NULL)
|
||||
{
|
||||
infostream<<"generate_image(): Loading path \""
|
||||
<<path<<"\" failed"<<std::endl;
|
||||
infostream<<"generate_image(): Loading file \""
|
||||
<<filename<<"\" failed"<<std::endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -1419,14 +1529,14 @@ bool generate_image(std::string part_of_name, video::IImage *& baseimg,
|
||||
std::string imagename_right = sf.next("{");
|
||||
|
||||
#if 1
|
||||
//TODO
|
||||
// TODO: Create cube with different textures on different sides
|
||||
|
||||
if(driver->queryFeature(video::EVDF_RENDER_TO_TARGET) == false)
|
||||
{
|
||||
infostream<<"generate_image(): EVDF_RENDER_TO_TARGET"
|
||||
" not supported. Creating fallback image"<<std::endl;
|
||||
baseimg = generate_image_from_scratch(
|
||||
imagename_top, device);
|
||||
imagename_top, device, sourcecache);
|
||||
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
|
||||
video::IImage *img_top = generate_image_from_scratch(
|
||||
imagename_top, device);
|
||||
imagename_top, device, sourcecache);
|
||||
video::IImage *img_left = generate_image_from_scratch(
|
||||
imagename_left, device);
|
||||
imagename_left, device, sourcecache);
|
||||
video::IImage *img_right = generate_image_from_scratch(
|
||||
imagename_right, device);
|
||||
imagename_right, device, sourcecache);
|
||||
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(
|
||||
(imagename_top + "__temp__").c_str(), img_top);
|
||||
assert(texture_top);
|
||||
@ -1515,7 +1626,8 @@ bool generate_image(std::string part_of_name, video::IImage *& baseimg,
|
||||
// Unset render target
|
||||
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);
|
||||
|
||||
// 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; }
|
||||
};
|
||||
|
||||
/*
|
||||
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.
|
||||
*/
|
||||
@ -157,9 +129,9 @@ public:
|
||||
virtual void updateAP(AtlasPointer &ap){};
|
||||
|
||||
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;
|
||||
// img is eaten, do not drop it
|
||||
virtual void insertImage(const std::string &name, video::IImage *img)=0;
|
||||
};
|
||||
|
||||
IWritableTextureSource* createTextureSource(IrrlichtDevice *device);
|
||||
|
Loading…
Reference in New Issue
Block a user