Skip to content

Commit f0db6c4

Browse files
RealBadAngelsapier
authored and
sapier
committedJul 17, 2014
Speedup mapblock_mesh
1 parent 625489d commit f0db6c4

File tree

4 files changed

+114
-100
lines changed

4 files changed

+114
-100
lines changed
 

‎src/mapblock_mesh.cpp

+30-76
Original file line numberDiff line numberDiff line change
@@ -32,14 +32,11 @@ with this program; if not, write to the Free Software Foundation, Inc.,
3232
#include "settings.h"
3333
#include "util/directiontables.h"
3434

35-
void applyContrast(video::SColor& color, float Factor)
35+
static void applyContrast(video::SColor& color, float factor)
3636
{
37-
float r = color.getRed();
38-
float g = color.getGreen();
39-
float b = color.getBlue();
40-
color.setRed(irr::core::clamp((int)sqrt(r * r * Factor), 0, 255));
41-
color.setGreen(irr::core::clamp((int)sqrt(g * g * Factor), 0, 255));
42-
color.setBlue(irr::core::clamp((int)sqrt(b * b * Factor), 0, 255));
37+
color.setRed(core::clamp(core::round32(color.getRed()*factor), 0, 255));
38+
color.setGreen(core::clamp(core::round32(color.getGreen()*factor), 0, 255));
39+
color.setBlue(core::clamp(core::round32(color.getBlue()*factor), 0, 255));
4340
}
4441

4542
/*
@@ -1099,8 +1096,6 @@ MapBlockMesh::MapBlockMesh(MeshMakeData *data, v3s16 camera_offset):
10991096
IShaderSource *shdrsrc = m_gamedef->getShaderSource();
11001097

11011098
bool enable_shaders = g_settings->getBool("enable_shaders");
1102-
bool enable_bumpmapping = g_settings->getBool("enable_bumpmapping");
1103-
bool enable_parallax_occlusion = g_settings->getBool("enable_parallax_occlusion");
11041099

11051100
for(u32 i = 0; i < collector.prebuffers.size(); i++)
11061101
{
@@ -1141,33 +1136,31 @@ MapBlockMesh::MapBlockMesh(MeshMakeData *data, v3s16 camera_offset):
11411136
m_animation_frame_offsets[i] = 0;
11421137
}
11431138
// Replace tile texture with the first animation frame
1144-
std::ostringstream os(std::ios::binary);
1145-
os<<tsrc->getTextureName(p.tile.texture_id);
1146-
os<<"^[verticalframe:"<<(int)p.tile.animation_frame_count<<":0";
1147-
p.tile.texture = tsrc->getTexture(
1148-
os.str(),
1149-
&p.tile.texture_id);
1139+
FrameSpec animation_frame = p.tile.frames.find(0)->second;
1140+
p.tile.texture = animation_frame.texture;
11501141
}
11511142

11521143
for(u32 j = 0; j < p.vertices.size(); j++)
11531144
{
1145+
// Note applyContrast second parameter is precalculated sqrt from original
1146+
// values for speed improvement
11541147
video::SColor &vc = p.vertices[j].Color;
11551148
if(p.vertices[j].Normal.Y > 0.5) {
1156-
applyContrast (vc, 1.2);
1149+
applyContrast (vc, 1.095445);
11571150
} else if (p.vertices[j].Normal.Y < -0.5) {
1158-
applyContrast (vc, 0.3);
1151+
applyContrast (vc, 0.547723);
11591152
} else if (p.vertices[j].Normal.X > 0.5) {
1160-
applyContrast (vc, 0.5);
1153+
applyContrast (vc, 0.707107);
11611154
} else if (p.vertices[j].Normal.X < -0.5) {
1162-
applyContrast (vc, 0.5);
1155+
applyContrast (vc, 0.707107);
11631156
} else if (p.vertices[j].Normal.Z > 0.5) {
1164-
applyContrast (vc, 0.8);
1157+
applyContrast (vc, 0.894427);
11651158
} else if (p.vertices[j].Normal.Z < -0.5) {
1166-
applyContrast (vc, 0.8);
1159+
applyContrast (vc, 0.894427);
11671160
}
11681161
if(!enable_shaders)
11691162
{
1170-
// - Classic lighting (shaders handle this by themselves)
1163+
// - Classic lighting (shaders handle this by themselves)
11711164
// Set initial real color and store for later updates
11721165
u8 day = vc.getRed();
11731166
u8 night = vc.getGreen();
@@ -1191,34 +1184,17 @@ MapBlockMesh::MapBlockMesh(MeshMakeData *data, v3s16 camera_offset):
11911184
if (enable_shaders) {
11921185
material.MaterialType = shdrsrc->getShaderInfo(p.tile.shader_id).material;
11931186
p.tile.applyMaterialOptionsWithShaders(material);
1194-
material.setTexture(2, tsrc->getTexture("disable_img.png"));
1195-
if (enable_bumpmapping || enable_parallax_occlusion) {
1196-
if (tsrc->isKnownSourceImage("override_normal.png")){
1197-
material.setTexture(1, tsrc->getTexture("override_normal.png"));
1198-
material.setTexture(2, tsrc->getTexture("enable_img.png"));
1199-
} else {
1200-
std::string fname_base = tsrc->getTextureName(p.tile.texture_id);
1201-
std::string normal_ext = "_normal.png";
1202-
size_t pos = fname_base.find(".");
1203-
std::string fname_normal = fname_base.substr(0, pos) + normal_ext;
1204-
1205-
if (tsrc->isKnownSourceImage(fname_normal)) {
1206-
// look for image extension and replace it
1207-
size_t i = 0;
1208-
while ((i = fname_base.find(".", i)) != std::string::npos) {
1209-
fname_base.replace(i, 4, normal_ext);
1210-
i += normal_ext.length();
1211-
}
1212-
material.setTexture(1, tsrc->getTexture(fname_base));
1213-
material.setTexture(2, tsrc->getTexture("enable_img.png"));
1214-
}
1215-
}
1187+
if (p.tile.normal_texture) {
1188+
material.setTexture(1, p.tile.normal_texture);
1189+
material.setTexture(2, tsrc->getTexture("enable_img.png"));
1190+
} else {
1191+
material.setTexture(2, tsrc->getTexture("disable_img.png"));
12161192
}
12171193
} else {
12181194
p.tile.applyMaterialOptions(material);
12191195
}
1220-
// Create meshbuffer
12211196

1197+
// Create meshbuffer
12221198
// This is a "Standard MeshBuffer",
12231199
// it's a typedeffed CMeshBuffer<video::S3DVertex>
12241200
scene::SMeshBuffer *buf = new scene::SMeshBuffer();
@@ -1278,8 +1254,6 @@ MapBlockMesh::~MapBlockMesh()
12781254
bool MapBlockMesh::animate(bool faraway, float time, int crack, u32 daynight_ratio)
12791255
{
12801256
bool enable_shaders = g_settings->getBool("enable_shaders");
1281-
bool enable_bumpmapping = g_settings->getBool("enable_bumpmapping");
1282-
bool enable_parallax_occlusion = g_settings->getBool("enable_parallax_occlusion");
12831257

12841258
if(!m_has_animation)
12851259
{
@@ -1342,35 +1316,15 @@ bool MapBlockMesh::animate(bool faraway, float time, int crack, u32 daynight_rat
13421316

13431317
scene::IMeshBuffer *buf = m_mesh->getMeshBuffer(i->first);
13441318
ITextureSource *tsrc = m_gamedef->getTextureSource();
1345-
IShaderSource *shdrsrc = m_gamedef->getShaderSource();
1346-
1347-
// Create new texture name from original
1348-
std::ostringstream os(std::ios::binary);
1349-
os<<tsrc->getTextureName(tile.texture_id);
1350-
os<<"^[verticalframe:"<<(int)tile.animation_frame_count<<":"<<frame;
1351-
// Set the texture
1352-
buf->getMaterial().setTexture(0, tsrc->getTexture(os.str()));
1353-
if (enable_shaders){
1354-
buf->getMaterial().setTexture(2, tsrc->getTexture("disable_img.png"));
1355-
buf->getMaterial().MaterialType = shdrsrc->getShaderInfo(tile.shader_id).material;
1356-
if (enable_bumpmapping || enable_parallax_occlusion){
1357-
if (tsrc->isKnownSourceImage("override_normal.png")){
1358-
buf->getMaterial().setTexture(1, tsrc->getTexture("override_normal.png"));
1359-
buf->getMaterial().setTexture(2, tsrc->getTexture("enable_img.png"));
1360-
} else {
1361-
std::string fname_base,fname_normal;
1362-
fname_base = tsrc->getTextureName(tile.texture_id);
1363-
unsigned pos;
1364-
pos = fname_base.find(".");
1365-
fname_normal = fname_base.substr (0, pos);
1366-
fname_normal += "_normal.png";
1367-
if (tsrc->isKnownSourceImage(fname_normal)){
1368-
os.str("");
1369-
os<<fname_normal<<"^[verticalframe:"<<(int)tile.animation_frame_count<<":"<<frame;
1370-
buf->getMaterial().setTexture(1, tsrc->getTexture(os.str()));
1371-
buf->getMaterial().setTexture(2, tsrc->getTexture("enable_img.png"));
1372-
}
1373-
}
1319+
1320+
FrameSpec animation_frame = tile.frames.find(frame)->second;
1321+
buf->getMaterial().setTexture(0, animation_frame.texture);
1322+
if (enable_shaders) {
1323+
if (animation_frame.normal_texture) {
1324+
buf->getMaterial().setTexture(1, animation_frame.normal_texture);
1325+
buf->getMaterial().setTexture(2, tsrc->getTexture("enable_img.png"));
1326+
} else {
1327+
buf->getMaterial().setTexture(2, tsrc->getTexture("disable_img.png"));
13741328
}
13751329
}
13761330
}

‎src/nodedef.cpp

+41-24
Original file line numberDiff line numberDiff line change
@@ -607,6 +607,9 @@ class CNodeDefManager: public IWritableNodeDefManager
607607
bool new_style_water = g_settings->getBool("new_style_water");
608608
bool new_style_leaves = g_settings->getBool("new_style_leaves");
609609
bool opaque_water = g_settings->getBool("opaque_water");
610+
bool enable_shaders = g_settings->getBool("enable_shaders");
611+
bool enable_bumpmapping = g_settings->getBool("enable_bumpmapping");
612+
bool enable_parallax_occlusion = g_settings->getBool("enable_parallax_occlusion");
610613

611614
for(u32 i=0; i<m_content_features.size(); i++)
612615
{
@@ -716,6 +719,9 @@ class CNodeDefManager: public IWritableNodeDefManager
716719
f->tiles[j].texture = tsrc->getTexture(
717720
tiledef[j].name,
718721
&f->tiles[j].texture_id);
722+
// Normal texture
723+
if (enable_shaders && (enable_bumpmapping || enable_parallax_occlusion))
724+
f->tiles[j].normal_texture = tsrc->getNormalTexture(tiledef[j].name);
719725
// Alpha
720726
f->tiles[j].alpha = f->alpha;
721727
// Material type
@@ -727,28 +733,32 @@ class CNodeDefManager: public IWritableNodeDefManager
727733
if(tiledef[j].animation.type == TAT_VERTICAL_FRAMES)
728734
f->tiles[j].material_flags |= MATERIAL_FLAG_ANIMATION_VERTICAL_FRAMES;
729735
// Animation parameters
730-
if(f->tiles[j].material_flags &
731-
MATERIAL_FLAG_ANIMATION_VERTICAL_FRAMES)
732-
{
736+
int frame_count = 1;
737+
if(f->tiles[j].material_flags & MATERIAL_FLAG_ANIMATION_VERTICAL_FRAMES) {
733738
// Get texture size to determine frame count by
734739
// aspect ratio
735740
v2u32 size = f->tiles[j].texture->getOriginalSize();
736741
int frame_height = (float)size.X /
737742
(float)tiledef[j].animation.aspect_w *
738743
(float)tiledef[j].animation.aspect_h;
739-
int frame_count = size.Y / frame_height;
744+
frame_count = size.Y / frame_height;
740745
int frame_length_ms = 1000.0 *
741746
tiledef[j].animation.length / frame_count;
742747
f->tiles[j].animation_frame_count = frame_count;
743748
f->tiles[j].animation_frame_length_ms = frame_length_ms;
744-
745-
// If there are no frames for an animation, switch
746-
// animation off (so that having specified an animation
747-
// for something but not using it in the texture pack
748-
// gives no overhead)
749-
if(frame_count == 1){
750-
f->tiles[j].material_flags &=
751-
~MATERIAL_FLAG_ANIMATION_VERTICAL_FRAMES;
749+
}
750+
if(frame_count == 1) {
751+
f->tiles[j].material_flags &= ~MATERIAL_FLAG_ANIMATION_VERTICAL_FRAMES;
752+
} else {
753+
std::ostringstream os(std::ios::binary);
754+
for (int i = 0; i < frame_count; i++) {
755+
FrameSpec frame;
756+
os.str("");
757+
os<<tiledef[j].name<<"^[verticalframe:"<<frame_count<<":"<<i;
758+
frame.texture = tsrc->getTexture(os.str(), &frame.texture_id);
759+
if (f->tiles[j].normal_texture)
760+
frame.normal_texture = tsrc->getNormalTexture(os.str());
761+
f->tiles[j].frames[i]=frame;
752762
}
753763
}
754764
}
@@ -760,6 +770,9 @@ class CNodeDefManager: public IWritableNodeDefManager
760770
f->special_tiles[j].texture = tsrc->getTexture(
761771
f->tiledef_special[j].name,
762772
&f->special_tiles[j].texture_id);
773+
// Normal texture
774+
if (enable_shaders && (enable_bumpmapping || enable_parallax_occlusion))
775+
f->special_tiles[j].normal_texture = tsrc->getNormalTexture(f->tiledef_special[j].name);
763776
// Alpha
764777
f->special_tiles[j].alpha = f->alpha;
765778
// Material type
@@ -771,28 +784,32 @@ class CNodeDefManager: public IWritableNodeDefManager
771784
if(f->tiledef_special[j].animation.type == TAT_VERTICAL_FRAMES)
772785
f->special_tiles[j].material_flags |= MATERIAL_FLAG_ANIMATION_VERTICAL_FRAMES;
773786
// Animation parameters
774-
if(f->special_tiles[j].material_flags &
775-
MATERIAL_FLAG_ANIMATION_VERTICAL_FRAMES)
776-
{
787+
int frame_count = 1;
788+
if(f->special_tiles[j].material_flags & MATERIAL_FLAG_ANIMATION_VERTICAL_FRAMES) {
777789
// Get texture size to determine frame count by
778790
// aspect ratio
779791
v2u32 size = f->special_tiles[j].texture->getOriginalSize();
780792
int frame_height = (float)size.X /
781793
(float)f->tiledef_special[j].animation.aspect_w *
782794
(float)f->tiledef_special[j].animation.aspect_h;
783-
int frame_count = size.Y / frame_height;
795+
frame_count = size.Y / frame_height;
784796
int frame_length_ms = 1000.0 *
785797
f->tiledef_special[j].animation.length / frame_count;
786798
f->special_tiles[j].animation_frame_count = frame_count;
787799
f->special_tiles[j].animation_frame_length_ms = frame_length_ms;
788-
789-
// If there are no frames for an animation, switch
790-
// animation off (so that having specified an animation
791-
// for something but not using it in the texture pack
792-
// gives no overhead)
793-
if(frame_count == 1){
794-
f->special_tiles[j].material_flags &=
795-
~MATERIAL_FLAG_ANIMATION_VERTICAL_FRAMES;
800+
}
801+
if(frame_count == 1) {
802+
f->special_tiles[j].material_flags &= ~MATERIAL_FLAG_ANIMATION_VERTICAL_FRAMES;
803+
} else {
804+
std::ostringstream os(std::ios::binary);
805+
for (int i = 0; i < frame_count; i++) {
806+
FrameSpec frame;
807+
os.str("");
808+
os<<f->tiledef_special[j].name<<"^[verticalframe:"<<frame_count<<":"<<i;
809+
frame.texture = tsrc->getTexture(os.str(), &frame.texture_id);
810+
if (f->special_tiles[j].normal_texture)
811+
frame.normal_texture = tsrc->getNormalTexture(os.str());
812+
f->special_tiles[j].frames[i]=frame;
796813
}
797814
}
798815
}

‎src/tile.cpp

+22
Original file line numberDiff line numberDiff line change
@@ -389,6 +389,7 @@ class TextureSource : public IWritableTextureSource
389389
// Shall be called from the main thread.
390390
bool generateImage(std::string part_of_name, video::IImage *& baseimg);
391391

392+
video::ITexture* getNormalTexture(const std::string &name);
392393
private:
393394

394395
// The id of the thread that is allowed to use irrlicht directly
@@ -1872,3 +1873,24 @@ void imageTransform(u32 transform, video::IImage *src, video::IImage *dst)
18721873
dst->setPixel(dx,dy,c);
18731874
}
18741875
}
1876+
1877+
video::ITexture* TextureSource::getNormalTexture(const std::string &name)
1878+
{
1879+
u32 id;
1880+
if (isKnownSourceImage("override_normal.png"))
1881+
return getTexture("override_normal.png", &id);
1882+
std::string fname_base = name;
1883+
std::string normal_ext = "_normal.png";
1884+
size_t pos = fname_base.find(".");
1885+
std::string fname_normal = fname_base.substr(0, pos) + normal_ext;
1886+
if (isKnownSourceImage(fname_normal)) {
1887+
// look for image extension and replace it
1888+
size_t i = 0;
1889+
while ((i = fname_base.find(".", i)) != std::string::npos) {
1890+
fname_base.replace(i, 4, normal_ext);
1891+
i += normal_ext.length();
1892+
}
1893+
return getTexture(fname_base, &id);
1894+
}
1895+
return NULL;
1896+
}

‎src/tile.h

+21
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
2727
#include <IrrlichtDevice.h>
2828
#include "threads.h"
2929
#include <string>
30+
#include <map>
3031

3132
class IGameDef;
3233

@@ -106,6 +107,7 @@ class ITextureSource : public ISimpleTextureSource
106107
virtual bool isKnownSourceImage(const std::string &name)=0;
107108
virtual video::ITexture* generateTextureFromMesh(
108109
const TextureFromMeshParams &params)=0;
110+
virtual video::ITexture* getNormalTexture(const std::string &name)=0;
109111
};
110112

111113
class IWritableTextureSource : public ITextureSource
@@ -127,6 +129,7 @@ class IWritableTextureSource : public ITextureSource
127129
virtual void processQueue()=0;
128130
virtual void insertSourceImage(const std::string &name, video::IImage *img)=0;
129131
virtual void rebuildImagesAndTextures()=0;
132+
virtual video::ITexture* getNormalTexture(const std::string &name)=0;
130133
};
131134

132135
IWritableTextureSource* createTextureSource(IrrlichtDevice *device);
@@ -175,11 +178,25 @@ enum MaterialType{
175178
This fully defines the looks of a tile.
176179
The SMaterial of a tile is constructed according to this.
177180
*/
181+
struct FrameSpec
182+
{
183+
FrameSpec():
184+
texture_id(0),
185+
texture(NULL),
186+
normal_texture(NULL)
187+
{
188+
}
189+
u32 texture_id;
190+
video::ITexture *texture;
191+
video::ITexture *normal_texture;
192+
};
193+
178194
struct TileSpec
179195
{
180196
TileSpec():
181197
texture_id(0),
182198
texture(NULL),
199+
normal_texture(NULL),
183200
alpha(255),
184201
material_type(TILE_MATERIAL_BASIC),
185202
material_flags(
@@ -243,6 +260,8 @@ struct TileSpec
243260

244261
u32 texture_id;
245262
video::ITexture *texture;
263+
video::ITexture *normal_texture;
264+
246265
// Vertex alpha (when MATERIAL_ALPHA_VERTEX is used)
247266
u8 alpha;
248267
// Material parameters
@@ -252,6 +271,8 @@ struct TileSpec
252271
// Animation parameters
253272
u8 animation_frame_count;
254273
u16 animation_frame_length_ms;
274+
std::map<u32, FrameSpec> frames;
275+
255276
u8 rotation;
256277
};
257278

0 commit comments

Comments
 (0)
Please sign in to comment.