Skip to content

Commit db32e6c

Browse files
Warr1024Zeno-
authored andcommittedMar 31, 2015
Move texture_min_size even further down the pipe. Now, textures are JIT-upscaled using an image transformation, right at the time they're added to a mesh or particle; images used in 2D elements are left unscaled. This should fix any remaining issues with HUD elements.
1 parent 862d4ea commit db32e6c

11 files changed

+78
-78
lines changed
 

Diff for: ‎src/client/tile.cpp

+47-49
Original file line numberDiff line numberDiff line change
@@ -182,47 +182,6 @@ struct TextureInfo
182182
}
183183
};
184184

185-
/* Upscale textures to user's requested minimum size. This is a trick to make
186-
* filters look as good on low-res textures as on high-res ones, by making
187-
* low-res textures BECOME high-res ones. This is helpful for worlds that
188-
* mix high- and low-res textures, or for mods with least-common-denominator
189-
* textures that don't have the resources to offer high-res alternatives.
190-
*/
191-
video::IImage *textureMinSizeUpscale(video::IVideoDriver *driver, video::IImage *orig) {
192-
if(orig == NULL)
193-
return orig;
194-
s32 scaleto = g_settings->getS32("texture_min_size");
195-
if (scaleto > 1) {
196-
const core::dimension2d<u32> dim = orig->getDimension();
197-
198-
// Don't upscale 1px images. They don't benefit from it anyway
199-
// (wouldn't have been blurred) and MIGHT be sun/moon tonemaps.
200-
if ((dim.Width <= 1) || (dim.Height <= 1))
201-
return orig;
202-
203-
/* Calculate scaling needed to make the shortest texture dimension
204-
* equal to the target minimum. If e.g. this is a vertical frames
205-
* animation, the short dimension will be the real size.
206-
*/
207-
u32 xscale = scaleto / dim.Width;
208-
u32 yscale = scaleto / dim.Height;
209-
u32 scale = (xscale > yscale) ? xscale : yscale;
210-
211-
// Never downscale; only scale up by 2x or more.
212-
if (scale > 1) {
213-
u32 w = scale * dim.Width;
214-
u32 h = scale * dim.Height;
215-
const core::dimension2d<u32> newdim = core::dimension2d<u32>(w, h);
216-
video::IImage *newimg = driver->createImage(
217-
orig->getColorFormat(), newdim);
218-
orig->copyToScaling(newimg);
219-
return newimg;
220-
}
221-
}
222-
223-
return orig;
224-
}
225-
226185
/*
227186
SourceImageCache: A cache used for storing source images.
228187
*/
@@ -425,6 +384,14 @@ class TextureSource : public IWritableTextureSource
425384

426385
video::ITexture* getTexture(const std::string &name, u32 *id);
427386

387+
/*
388+
Get a texture specifically intended for mesh
389+
application, i.e. not HUD, compositing, or other 2D
390+
use. This texture may be a different size and may
391+
have had additional filters applied.
392+
*/
393+
video::ITexture* getTextureForMesh(const std::string &name, u32 *id);
394+
428395
// Returns a pointer to the irrlicht device
429396
virtual IrrlichtDevice* getDevice()
430397
{
@@ -693,8 +660,7 @@ u32 TextureSource::generateTexture(const std::string &name)
693660
video::IVideoDriver *driver = m_device->getVideoDriver();
694661
sanity_check(driver);
695662

696-
video::IImage *origimg = generateImage(name);
697-
video::IImage *img = textureMinSizeUpscale(driver, origimg);
663+
video::IImage *img = generateImage(name);
698664

699665
video::ITexture *tex = NULL;
700666

@@ -705,8 +671,6 @@ u32 TextureSource::generateTexture(const std::string &name)
705671
// Create texture from resulting image
706672
tex = driver->addTexture(name.c_str(), img);
707673
img->drop();
708-
if((origimg != NULL) && (img != origimg))
709-
origimg->drop();
710674
}
711675

712676
/*
@@ -757,6 +721,11 @@ video::ITexture* TextureSource::getTexture(const std::string &name, u32 *id)
757721
return getTexture(actual_id);
758722
}
759723

724+
video::ITexture* TextureSource::getTextureForMesh(const std::string &name, u32 *id)
725+
{
726+
return getTexture(name + "^[autoupscaleformesh", id);
727+
}
728+
760729
void TextureSource::processQueue()
761730
{
762731
/*
@@ -797,8 +766,7 @@ void TextureSource::rebuildImagesAndTextures()
797766
// Recreate textures
798767
for (u32 i=0; i<m_textureinfo_cache.size(); i++){
799768
TextureInfo *ti = &m_textureinfo_cache[i];
800-
video::IImage *origimg = generateImage(ti->name);
801-
video::IImage *img = textureMinSizeUpscale(driver, origimg);
769+
video::IImage *img = generateImage(ti->name);
802770
#ifdef __ANDROID__
803771
img = Align2Npot2(img, driver);
804772
sanity_check(img->getDimension().Height == npot2(img->getDimension().Height));
@@ -809,8 +777,6 @@ void TextureSource::rebuildImagesAndTextures()
809777
if (img) {
810778
t = driver->addTexture(ti->name.c_str(), img);
811779
img->drop();
812-
if(origimg && (origimg != img))
813-
origimg->drop();
814780
}
815781
video::ITexture *t_old = ti->texture;
816782
// Replace texture
@@ -1735,6 +1701,38 @@ bool TextureSource::generateImagePart(std::string part_of_name,
17351701
blit_with_interpolate_overlay(img, baseimg, v2s32(0,0), v2s32(0,0), dim, ratio);
17361702
img->drop();
17371703
}
1704+
else if (part_of_name.substr(0,19) == "[autoupscaleformesh") {
1705+
/* Upscale textures to user's requested minimum size. This is a trick to make
1706+
* filters look as good on low-res textures as on high-res ones, by making
1707+
* low-res textures BECOME high-res ones. This is helpful for worlds that
1708+
* mix high- and low-res textures, or for mods with least-common-denominator
1709+
* textures that don't have the resources to offer high-res alternatives.
1710+
*/
1711+
s32 scaleto = g_settings->getS32("texture_min_size");
1712+
if (scaleto > 1) {
1713+
const core::dimension2d<u32> dim = baseimg->getDimension();
1714+
1715+
/* Calculate scaling needed to make the shortest texture dimension
1716+
* equal to the target minimum. If e.g. this is a vertical frames
1717+
* animation, the short dimension will be the real size.
1718+
*/
1719+
u32 xscale = scaleto / dim.Width;
1720+
u32 yscale = scaleto / dim.Height;
1721+
u32 scale = (xscale > yscale) ? xscale : yscale;
1722+
1723+
// Never downscale; only scale up by 2x or more.
1724+
if (scale > 1) {
1725+
u32 w = scale * dim.Width;
1726+
u32 h = scale * dim.Height;
1727+
const core::dimension2d<u32> newdim = core::dimension2d<u32>(w, h);
1728+
video::IImage *newimg = driver->createImage(
1729+
baseimg->getColorFormat(), newdim);
1730+
baseimg->copyToScaling(newimg);
1731+
baseimg->drop();
1732+
baseimg = newimg;
1733+
}
1734+
}
1735+
}
17381736
else
17391737
{
17401738
errorstream << "generateImagePart(): Invalid "

Diff for: ‎src/client/tile.h

+2
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,8 @@ class ITextureSource : public ISimpleTextureSource
102102
virtual video::ITexture* getTexture(u32 id)=0;
103103
virtual video::ITexture* getTexture(
104104
const std::string &name, u32 *id = NULL)=0;
105+
virtual video::ITexture* getTextureForMesh(
106+
const std::string &name, u32 *id = NULL) = 0;
105107
virtual IrrlichtDevice* getDevice()=0;
106108
virtual bool isKnownSourceImage(const std::string &name)=0;
107109
virtual video::ITexture* generateTextureFromMesh(

Diff for: ‎src/content_cao.cpp

+7-7
Original file line numberDiff line numberDiff line change
@@ -211,7 +211,7 @@ void TestCAO::addToScene(scene::ISceneManager *smgr, ITextureSource *tsrc,
211211
// Set material
212212
buf->getMaterial().setFlag(video::EMF_LIGHTING, false);
213213
buf->getMaterial().setFlag(video::EMF_BACK_FACE_CULLING, false);
214-
buf->getMaterial().setTexture(0, tsrc->getTexture("rat.png"));
214+
buf->getMaterial().setTexture(0, tsrc->getTextureForMesh("rat.png"));
215215
buf->getMaterial().setFlag(video::EMF_BILINEAR_FILTER, false);
216216
buf->getMaterial().setFlag(video::EMF_FOG_ENABLE, true);
217217
buf->getMaterial().MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL;
@@ -822,7 +822,7 @@ void GenericCAO::addToScene(scene::ISceneManager *smgr, ITextureSource *tsrc,
822822
NULL, v2f(1, 1), v3f(0,0,0), -1);
823823
m_spritenode->grab();
824824
m_spritenode->setMaterialTexture(0,
825-
tsrc->getTexture("unknown_node.png"));
825+
tsrc->getTextureForMesh("unknown_node.png"));
826826
m_spritenode->setMaterialFlag(video::EMF_LIGHTING, false);
827827
m_spritenode->setMaterialFlag(video::EMF_BILINEAR_FILTER, false);
828828
m_spritenode->setMaterialType(video::EMT_TRANSPARENT_ALPHA_CHANNEL_REF);
@@ -1299,7 +1299,7 @@ void GenericCAO::updateTextures(const std::string &mod)
12991299
texturestring = m_prop.textures[0];
13001300
texturestring += mod;
13011301
m_spritenode->setMaterialTexture(0,
1302-
tsrc->getTexture(texturestring));
1302+
tsrc->getTextureForMesh(texturestring));
13031303

13041304
// This allows setting per-material colors. However, until a real lighting
13051305
// system is added, the code below will have no effect. Once MineTest
@@ -1327,7 +1327,7 @@ void GenericCAO::updateTextures(const std::string &mod)
13271327
if(texturestring == "")
13281328
continue; // Empty texture string means don't modify that material
13291329
texturestring += mod;
1330-
video::ITexture* texture = tsrc->getTexture(texturestring);
1330+
video::ITexture* texture = tsrc->getTextureForMesh(texturestring);
13311331
if(!texture)
13321332
{
13331333
errorstream<<"GenericCAO::updateTextures(): Could not load texture "<<texturestring<<std::endl;
@@ -1376,7 +1376,7 @@ void GenericCAO::updateTextures(const std::string &mod)
13761376
material.setFlag(video::EMF_LIGHTING, false);
13771377
material.setFlag(video::EMF_BILINEAR_FILTER, false);
13781378
material.setTexture(0,
1379-
tsrc->getTexture(texturestring));
1379+
tsrc->getTextureForMesh(texturestring));
13801380
material.getTextureMatrix(0).makeIdentity();
13811381

13821382
// This allows setting per-material colors. However, until a real lighting
@@ -1404,7 +1404,7 @@ void GenericCAO::updateTextures(const std::string &mod)
14041404
tname += mod;
14051405
scene::IMeshBuffer *buf = mesh->getMeshBuffer(0);
14061406
buf->getMaterial().setTexture(0,
1407-
tsrc->getTexture(tname));
1407+
tsrc->getTextureForMesh(tname));
14081408

14091409
// This allows setting per-material colors. However, until a real lighting
14101410
// system is added, the code below will have no effect. Once MineTest
@@ -1429,7 +1429,7 @@ void GenericCAO::updateTextures(const std::string &mod)
14291429
tname += mod;
14301430
scene::IMeshBuffer *buf = mesh->getMeshBuffer(1);
14311431
buf->getMaterial().setTexture(0,
1432-
tsrc->getTexture(tname));
1432+
tsrc->getTextureForMesh(tname));
14331433

14341434
// This allows setting per-material colors. However, until a real lighting
14351435
// system is added, the code below will have no effect. Once MineTest

Diff for: ‎src/content_cso.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ class SmokePuffCSO: public ClientSimpleObject
5050
m_spritenode = smgr->addBillboardSceneNode(
5151
NULL, v2f(1,1), pos, -1);
5252
m_spritenode->setMaterialTexture(0,
53-
env->getGameDef()->tsrc()->getTexture("smoke_puff.png"));
53+
env->getGameDef()->tsrc()->getTextureForMesh("smoke_puff.png"));
5454
m_spritenode->setMaterialFlag(video::EMF_LIGHTING, false);
5555
m_spritenode->setMaterialFlag(video::EMF_BILINEAR_FILTER, false);
5656
//m_spritenode->setMaterialType(video::EMT_TRANSPARENT_ALPHA_CHANNEL_REF);

Diff for: ‎src/content_mapblock.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -1686,7 +1686,7 @@ void mapblock_mesh_generate_special(MeshMakeData *data,
16861686
std::vector<aabb3f> boxes = n.getSelectionBoxes(nodedef);
16871687
TileSpec h_tile;
16881688
h_tile.material_flags |= MATERIAL_FLAG_HIGHLIGHTED;
1689-
h_tile.texture = tsrc->getTexture("halo.png",&h_tile.texture_id);
1689+
h_tile.texture = tsrc->getTextureForMesh("halo.png",&h_tile.texture_id);
16901690
v3f pos = intToFloat(p, BS);
16911691
f32 d = 0.05 * BS;
16921692
for (std::vector<aabb3f>::iterator i = boxes.begin();

Diff for: ‎src/game.cpp

+6-6
Original file line numberDiff line numberDiff line change
@@ -3202,12 +3202,12 @@ void Game::processClientEvents(CameraOrientation *cam, float *damage_flash)
32023202
event.set_sky.params->size() == 6) {
32033203
sky->setFallbackBgColor(*event.set_sky.bgcolor);
32043204
skybox = smgr->addSkyBoxSceneNode(
3205-
texture_src->getTexture((*event.set_sky.params)[0]),
3206-
texture_src->getTexture((*event.set_sky.params)[1]),
3207-
texture_src->getTexture((*event.set_sky.params)[2]),
3208-
texture_src->getTexture((*event.set_sky.params)[3]),
3209-
texture_src->getTexture((*event.set_sky.params)[4]),
3210-
texture_src->getTexture((*event.set_sky.params)[5]));
3205+
texture_src->getTextureForMesh((*event.set_sky.params)[0]),
3206+
texture_src->getTextureForMesh((*event.set_sky.params)[1]),
3207+
texture_src->getTextureForMesh((*event.set_sky.params)[2]),
3208+
texture_src->getTextureForMesh((*event.set_sky.params)[3]),
3209+
texture_src->getTextureForMesh((*event.set_sky.params)[4]),
3210+
texture_src->getTextureForMesh((*event.set_sky.params)[5]));
32113211
}
32123212
// Handle everything else as plain color
32133213
else {

Diff for: ‎src/mapblock_mesh.cpp

+6-6
Original file line numberDiff line numberDiff line change
@@ -1130,7 +1130,7 @@ MapBlockMesh::MapBlockMesh(MeshMakeData *data, v3s16 camera_offset):
11301130
os<<":"<<(u32)p.tile.animation_frame_count<<":";
11311131
m_crack_materials.insert(std::make_pair(i, os.str()));
11321132
// Replace tile texture with the cracked one
1133-
p.tile.texture = tsrc->getTexture(
1133+
p.tile.texture = tsrc->getTextureForMesh(
11341134
os.str()+"0",
11351135
&p.tile.texture_id);
11361136
}
@@ -1204,9 +1204,9 @@ MapBlockMesh::MapBlockMesh(MeshMakeData *data, v3s16 camera_offset):
12041204
p.tile.applyMaterialOptionsWithShaders(material);
12051205
if (p.tile.normal_texture) {
12061206
material.setTexture(1, p.tile.normal_texture);
1207-
material.setTexture(2, tsrc->getTexture("enable_img.png"));
1207+
material.setTexture(2, tsrc->getTextureForMesh("enable_img.png"));
12081208
} else {
1209-
material.setTexture(2, tsrc->getTexture("disable_img.png"));
1209+
material.setTexture(2, tsrc->getTextureForMesh("disable_img.png"));
12101210
}
12111211
} else {
12121212
p.tile.applyMaterialOptions(material);
@@ -1298,7 +1298,7 @@ bool MapBlockMesh::animate(bool faraway, float time, int crack, u32 daynight_rat
12981298
os<<basename<<crack;
12991299
u32 new_texture_id = 0;
13001300
video::ITexture *new_texture =
1301-
tsrc->getTexture(os.str(), &new_texture_id);
1301+
tsrc->getTextureForMesh(os.str(), &new_texture_id);
13021302
buf->getMaterial().setTexture(0, new_texture);
13031303

13041304
// If the current material is also animated,
@@ -1341,9 +1341,9 @@ bool MapBlockMesh::animate(bool faraway, float time, int crack, u32 daynight_rat
13411341
if (m_enable_shaders) {
13421342
if (animation_frame.normal_texture) {
13431343
buf->getMaterial().setTexture(1, animation_frame.normal_texture);
1344-
buf->getMaterial().setTexture(2, tsrc->getTexture("enable_img.png"));
1344+
buf->getMaterial().setTexture(2, tsrc->getTextureForMesh("enable_img.png"));
13451345
} else {
1346-
buf->getMaterial().setTexture(2, tsrc->getTexture("disable_img.png"));
1346+
buf->getMaterial().setTexture(2, tsrc->getTextureForMesh("disable_img.png"));
13471347
}
13481348
}
13491349
}

Diff for: ‎src/nodedef.cpp

+2-2
Original file line numberDiff line numberDiff line change
@@ -930,7 +930,7 @@ void CNodeDefManager::fillTileAttribs(ITextureSource *tsrc, TileSpec *tile,
930930
bool backface_culling, u8 alpha, u8 material_type)
931931
{
932932
tile->shader_id = shader_id;
933-
tile->texture = tsrc->getTexture(tiledef->name, &tile->texture_id);
933+
tile->texture = tsrc->getTextureForMesh(tiledef->name, &tile->texture_id);
934934
tile->alpha = alpha;
935935
tile->material_type = material_type;
936936

@@ -973,7 +973,7 @@ void CNodeDefManager::fillTileAttribs(ITextureSource *tsrc, TileSpec *tile,
973973
os << tiledef->name << "^[verticalframe:"
974974
<< frame_count << ":" << i;
975975

976-
frame.texture = tsrc->getTexture(os.str(), &frame.texture_id);
976+
frame.texture = tsrc->getTextureForMesh(os.str(), &frame.texture_id);
977977
if (tile->normal_texture)
978978
frame.normal_texture = tsrc->getNormalTexture(os.str());
979979
tile->frames[i] = frame;

Diff for: ‎src/particles.cpp

+2-2
Original file line numberDiff line numberDiff line change
@@ -434,7 +434,7 @@ void ParticleManager::handleParticleEvent(ClientEvent *event, IGameDef *gamedef,
434434
}
435435
}
436436
video::ITexture *texture =
437-
gamedef->tsrc()->getTexture(*(event->add_particlespawner.texture));
437+
gamedef->tsrc()->getTextureForMesh(*(event->add_particlespawner.texture));
438438

439439
ParticleSpawner* toadd = new ParticleSpawner(gamedef, smgr, player,
440440
event->add_particlespawner.amount,
@@ -477,7 +477,7 @@ void ParticleManager::handleParticleEvent(ClientEvent *event, IGameDef *gamedef,
477477

478478
if (event->type == CE_SPAWN_PARTICLE) {
479479
video::ITexture *texture =
480-
gamedef->tsrc()->getTexture(*(event->spawn_particle.texture));
480+
gamedef->tsrc()->getTextureForMesh(*(event->spawn_particle.texture));
481481

482482
Particle* toadd = new Particle(gamedef, smgr, player, m_env,
483483
*event->spawn_particle.pos,

Diff for: ‎src/sky.cpp

+3-3
Original file line numberDiff line numberDiff line change
@@ -47,14 +47,14 @@ Sky::Sky(scene::ISceneNode* parent, scene::ISceneManager* mgr, s32 id,
4747
m_materials[1].MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL;
4848

4949
m_materials[2] = mat;
50-
m_materials[2].setTexture(0, tsrc->getTexture("sunrisebg.png"));
50+
m_materials[2].setTexture(0, tsrc->getTextureForMesh("sunrisebg.png"));
5151
m_materials[2].MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL;
5252
//m_materials[2].MaterialType = video::EMT_TRANSPARENT_ADD_COLOR;
5353

5454
m_sun_texture = tsrc->isKnownSourceImage("sun.png") ?
55-
tsrc->getTexture("sun.png") : NULL;
55+
tsrc->getTextureForMesh("sun.png") : NULL;
5656
m_moon_texture = tsrc->isKnownSourceImage("moon.png") ?
57-
tsrc->getTexture("moon.png") : NULL;
57+
tsrc->getTextureForMesh("moon.png") : NULL;
5858
m_sun_tonemap = tsrc->isKnownSourceImage("sun_tonemap.png") ?
5959
tsrc->getTexture("sun_tonemap.png") : NULL;
6060
m_moon_tonemap = tsrc->isKnownSourceImage("moon_tonemap.png") ?

Diff for: ‎src/wieldmesh.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -276,7 +276,7 @@ void WieldMeshSceneNode::setExtruded(const std::string &imagename,
276276

277277
// Customize material
278278
video::SMaterial &material = m_meshnode->getMaterial(0);
279-
material.setTexture(0, texture);
279+
material.setTexture(0, tsrc->getTextureForMesh(imagename));
280280
material.MaterialType = m_material_type;
281281
material.setFlag(video::EMF_BACK_FACE_CULLING, true);
282282
// Enable bi/trilinear filtering only for high resolution textures

0 commit comments

Comments
 (0)
Please sign in to comment.