summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRealBadAngel <maciej.kasatkin@o2.pl>2014-07-15 09:07:52 +0200
committersapier <Sapier at GMX dot net>2014-07-17 22:28:14 +0200
commitf0db6c4423db86203db83538704cc34152c59a09 (patch)
treeda1362d260f341898e26f7983a3b1156cce47820
parent625489dff4cf7d97f49035f5e490476ced42e38f (diff)
downloadminetest-f0db6c4423db86203db83538704cc34152c59a09.tar.gz
minetest-f0db6c4423db86203db83538704cc34152c59a09.tar.bz2
minetest-f0db6c4423db86203db83538704cc34152c59a09.zip
Speedup mapblock_mesh
-rw-r--r--src/mapblock_mesh.cpp106
-rw-r--r--src/nodedef.cpp65
-rw-r--r--src/tile.cpp22
-rw-r--r--src/tile.h21
4 files changed, 114 insertions, 100 deletions
diff --git a/src/mapblock_mesh.cpp b/src/mapblock_mesh.cpp
index 080131a6f..b29d07319 100644
--- a/src/mapblock_mesh.cpp
+++ b/src/mapblock_mesh.cpp
@@ -32,14 +32,11 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "settings.h"
#include "util/directiontables.h"
-void applyContrast(video::SColor& color, float Factor)
+static void applyContrast(video::SColor& color, float factor)
{
- float r = color.getRed();
- float g = color.getGreen();
- float b = color.getBlue();
- color.setRed(irr::core::clamp((int)sqrt(r * r * Factor), 0, 255));
- color.setGreen(irr::core::clamp((int)sqrt(g * g * Factor), 0, 255));
- color.setBlue(irr::core::clamp((int)sqrt(b * b * Factor), 0, 255));
+ color.setRed(core::clamp(core::round32(color.getRed()*factor), 0, 255));
+ color.setGreen(core::clamp(core::round32(color.getGreen()*factor), 0, 255));
+ color.setBlue(core::clamp(core::round32(color.getBlue()*factor), 0, 255));
}
/*
@@ -1099,8 +1096,6 @@ MapBlockMesh::MapBlockMesh(MeshMakeData *data, v3s16 camera_offset):
IShaderSource *shdrsrc = m_gamedef->getShaderSource();
bool enable_shaders = g_settings->getBool("enable_shaders");
- bool enable_bumpmapping = g_settings->getBool("enable_bumpmapping");
- bool enable_parallax_occlusion = g_settings->getBool("enable_parallax_occlusion");
for(u32 i = 0; i < collector.prebuffers.size(); i++)
{
@@ -1141,33 +1136,31 @@ MapBlockMesh::MapBlockMesh(MeshMakeData *data, v3s16 camera_offset):
m_animation_frame_offsets[i] = 0;
}
// Replace tile texture with the first animation frame
- std::ostringstream os(std::ios::binary);
- os<<tsrc->getTextureName(p.tile.texture_id);
- os<<"^[verticalframe:"<<(int)p.tile.animation_frame_count<<":0";
- p.tile.texture = tsrc->getTexture(
- os.str(),
- &p.tile.texture_id);
+ FrameSpec animation_frame = p.tile.frames.find(0)->second;
+ p.tile.texture = animation_frame.texture;
}
for(u32 j = 0; j < p.vertices.size(); j++)
{
+ // Note applyContrast second parameter is precalculated sqrt from original
+ // values for speed improvement
video::SColor &vc = p.vertices[j].Color;
if(p.vertices[j].Normal.Y > 0.5) {
- applyContrast (vc, 1.2);
+ applyContrast (vc, 1.095445);
} else if (p.vertices[j].Normal.Y < -0.5) {
- applyContrast (vc, 0.3);
+ applyContrast (vc, 0.547723);
} else if (p.vertices[j].Normal.X > 0.5) {
- applyContrast (vc, 0.5);
+ applyContrast (vc, 0.707107);
} else if (p.vertices[j].Normal.X < -0.5) {
- applyContrast (vc, 0.5);
+ applyContrast (vc, 0.707107);
} else if (p.vertices[j].Normal.Z > 0.5) {
- applyContrast (vc, 0.8);
+ applyContrast (vc, 0.894427);
} else if (p.vertices[j].Normal.Z < -0.5) {
- applyContrast (vc, 0.8);
+ applyContrast (vc, 0.894427);
}
if(!enable_shaders)
{
- // - Classic lighting (shaders handle this by themselves)
+ // - Classic lighting (shaders handle this by themselves)
// Set initial real color and store for later updates
u8 day = vc.getRed();
u8 night = vc.getGreen();
@@ -1191,34 +1184,17 @@ MapBlockMesh::MapBlockMesh(MeshMakeData *data, v3s16 camera_offset):
if (enable_shaders) {
material.MaterialType = shdrsrc->getShaderInfo(p.tile.shader_id).material;
p.tile.applyMaterialOptionsWithShaders(material);
- material.setTexture(2, tsrc->getTexture("disable_img.png"));
- if (enable_bumpmapping || enable_parallax_occlusion) {
- if (tsrc->isKnownSourceImage("override_normal.png")){
- material.setTexture(1, tsrc->getTexture("override_normal.png"));
- material.setTexture(2, tsrc->getTexture("enable_img.png"));
- } else {
- std::string fname_base = tsrc->getTextureName(p.tile.texture_id);
- std::string normal_ext = "_normal.png";
- size_t pos = fname_base.find(".");
- std::string fname_normal = fname_base.substr(0, pos) + normal_ext;
-
- if (tsrc->isKnownSourceImage(fname_normal)) {
- // look for image extension and replace it
- size_t i = 0;
- while ((i = fname_base.find(".", i)) != std::string::npos) {
- fname_base.replace(i, 4, normal_ext);
- i += normal_ext.length();
- }
- material.setTexture(1, tsrc->getTexture(fname_base));
- material.setTexture(2, tsrc->getTexture("enable_img.png"));
- }
- }
+ if (p.tile.normal_texture) {
+ material.setTexture(1, p.tile.normal_texture);
+ material.setTexture(2, tsrc->getTexture("enable_img.png"));
+ } else {
+ material.setTexture(2, tsrc->getTexture("disable_img.png"));
}
} else {
p.tile.applyMaterialOptions(material);
}
- // Create meshbuffer
+ // Create meshbuffer
// This is a "Standard MeshBuffer",
// it's a typedeffed CMeshBuffer<video::S3DVertex>
scene::SMeshBuffer *buf = new scene::SMeshBuffer();
@@ -1278,8 +1254,6 @@ MapBlockMesh::~MapBlockMesh()
bool MapBlockMesh::animate(bool faraway, float time, int crack, u32 daynight_ratio)
{
bool enable_shaders = g_settings->getBool("enable_shaders");
- bool enable_bumpmapping = g_settings->getBool("enable_bumpmapping");
- bool enable_parallax_occlusion = g_settings->getBool("enable_parallax_occlusion");
if(!m_has_animation)
{
@@ -1342,35 +1316,15 @@ bool MapBlockMesh::animate(bool faraway, float time, int crack, u32 daynight_rat
scene::IMeshBuffer *buf = m_mesh->getMeshBuffer(i->first);
ITextureSource *tsrc = m_gamedef->getTextureSource();
- IShaderSource *shdrsrc = m_gamedef->getShaderSource();
-
- // Create new texture name from original
- std::ostringstream os(std::ios::binary);
- os<<tsrc->getTextureName(tile.texture_id);
- os<<"^[verticalframe:"<<(int)tile.animation_frame_count<<":"<<frame;
- // Set the texture
- buf->getMaterial().setTexture(0, tsrc->getTexture(os.str()));
- if (enable_shaders){
- buf->getMaterial().setTexture(2, tsrc->getTexture("disable_img.png"));
- buf->getMaterial().MaterialType = shdrsrc->getShaderInfo(tile.shader_id).material;
- if (enable_bumpmapping || enable_parallax_occlusion){
- if (tsrc->isKnownSourceImage("override_normal.png")){
- buf->getMaterial().setTexture(1, tsrc->getTexture("override_normal.png"));
- buf->getMaterial().setTexture(2, tsrc->getTexture("enable_img.png"));
- } else {
- std::string fname_base,fname_normal;
- fname_base = tsrc->getTextureName(tile.texture_id);
- unsigned pos;
- pos = fname_base.find(".");
- fname_normal = fname_base.substr (0, pos);
- fname_normal += "_normal.png";
- if (tsrc->isKnownSourceImage(fname_normal)){
- os.str("");
- os<<fname_normal<<"^[verticalframe:"<<(int)tile.animation_frame_count<<":"<<frame;
- buf->getMaterial().setTexture(1, tsrc->getTexture(os.str()));
- buf->getMaterial().setTexture(2, tsrc->getTexture("enable_img.png"));
- }
- }
+
+ FrameSpec animation_frame = tile.frames.find(frame)->second;
+ buf->getMaterial().setTexture(0, animation_frame.texture);
+ if (enable_shaders) {
+ if (animation_frame.normal_texture) {
+ buf->getMaterial().setTexture(1, animation_frame.normal_texture);
+ buf->getMaterial().setTexture(2, tsrc->getTexture("enable_img.png"));
+ } else {
+ buf->getMaterial().setTexture(2, tsrc->getTexture("disable_img.png"));
}
}
}
diff --git a/src/nodedef.cpp b/src/nodedef.cpp
index f62c9e82c..e972ab927 100644
--- a/src/nodedef.cpp
+++ b/src/nodedef.cpp
@@ -607,6 +607,9 @@ public:
bool new_style_water = g_settings->getBool("new_style_water");
bool new_style_leaves = g_settings->getBool("new_style_leaves");
bool opaque_water = g_settings->getBool("opaque_water");
+ bool enable_shaders = g_settings->getBool("enable_shaders");
+ bool enable_bumpmapping = g_settings->getBool("enable_bumpmapping");
+ bool enable_parallax_occlusion = g_settings->getBool("enable_parallax_occlusion");
for(u32 i=0; i<m_content_features.size(); i++)
{
@@ -716,6 +719,9 @@ public:
f->tiles[j].texture = tsrc->getTexture(
tiledef[j].name,
&f->tiles[j].texture_id);
+ // Normal texture
+ if (enable_shaders && (enable_bumpmapping || enable_parallax_occlusion))
+ f->tiles[j].normal_texture = tsrc->getNormalTexture(tiledef[j].name);
// Alpha
f->tiles[j].alpha = f->alpha;
// Material type
@@ -727,28 +733,32 @@ public:
if(tiledef[j].animation.type == TAT_VERTICAL_FRAMES)
f->tiles[j].material_flags |= MATERIAL_FLAG_ANIMATION_VERTICAL_FRAMES;
// Animation parameters
- if(f->tiles[j].material_flags &
- MATERIAL_FLAG_ANIMATION_VERTICAL_FRAMES)
- {
+ int frame_count = 1;
+ if(f->tiles[j].material_flags & MATERIAL_FLAG_ANIMATION_VERTICAL_FRAMES) {
// Get texture size to determine frame count by
// aspect ratio
v2u32 size = f->tiles[j].texture->getOriginalSize();
int frame_height = (float)size.X /
(float)tiledef[j].animation.aspect_w *
(float)tiledef[j].animation.aspect_h;
- int frame_count = size.Y / frame_height;
+ frame_count = size.Y / frame_height;
int frame_length_ms = 1000.0 *
tiledef[j].animation.length / frame_count;
f->tiles[j].animation_frame_count = frame_count;
f->tiles[j].animation_frame_length_ms = frame_length_ms;
-
- // If there are no frames for an animation, switch
- // animation off (so that having specified an animation
- // for something but not using it in the texture pack
- // gives no overhead)
- if(frame_count == 1){
- f->tiles[j].material_flags &=
- ~MATERIAL_FLAG_ANIMATION_VERTICAL_FRAMES;
+ }
+ if(frame_count == 1) {
+ f->tiles[j].material_flags &= ~MATERIAL_FLAG_ANIMATION_VERTICAL_FRAMES;
+ } else {
+ std::ostringstream os(std::ios::binary);
+ for (int i = 0; i < frame_count; i++) {
+ FrameSpec frame;
+ os.str("");
+ os<<tiledef[j].name<<"^[verticalframe:"<<frame_count<<":"<<i;
+ frame.texture = tsrc->getTexture(os.str(), &frame.texture_id);
+ if (f->tiles[j].normal_texture)
+ frame.normal_texture = tsrc->getNormalTexture(os.str());
+ f->tiles[j].frames[i]=frame;
}
}
}
@@ -760,6 +770,9 @@ public:
f->special_tiles[j].texture = tsrc->getTexture(
f->tiledef_special[j].name,
&f->special_tiles[j].texture_id);
+ // Normal texture
+ if (enable_shaders && (enable_bumpmapping || enable_parallax_occlusion))
+ f->special_tiles[j].normal_texture = tsrc->getNormalTexture(f->tiledef_special[j].name);
// Alpha
f->special_tiles[j].alpha = f->alpha;
// Material type
@@ -771,28 +784,32 @@ public:
if(f->tiledef_special[j].animation.type == TAT_VERTICAL_FRAMES)
f->special_tiles[j].material_flags |= MATERIAL_FLAG_ANIMATION_VERTICAL_FRAMES;
// Animation parameters
- if(f->special_tiles[j].material_flags &
- MATERIAL_FLAG_ANIMATION_VERTICAL_FRAMES)
- {
+ int frame_count = 1;
+ if(f->special_tiles[j].material_flags & MATERIAL_FLAG_ANIMATION_VERTICAL_FRAMES) {
// Get texture size to determine frame count by
// aspect ratio
v2u32 size = f->special_tiles[j].texture->getOriginalSize();
int frame_height = (float)size.X /
(float)f->tiledef_special[j].animation.aspect_w *
(float)f->tiledef_special[j].animation.aspect_h;
- int frame_count = size.Y / frame_height;
+ frame_count = size.Y / frame_height;
int frame_length_ms = 1000.0 *
f->tiledef_special[j].animation.length / frame_count;
f->special_tiles[j].animation_frame_count = frame_count;
f->special_tiles[j].animation_frame_length_ms = frame_length_ms;
-
- // If there are no frames for an animation, switch
- // animation off (so that having specified an animation
- // for something but not using it in the texture pack
- // gives no overhead)
- if(frame_count == 1){
- f->special_tiles[j].material_flags &=
- ~MATERIAL_FLAG_ANIMATION_VERTICAL_FRAMES;
+ }
+ if(frame_count == 1) {
+ f->special_tiles[j].material_flags &= ~MATERIAL_FLAG_ANIMATION_VERTICAL_FRAMES;
+ } else {
+ std::ostringstream os(std::ios::binary);
+ for (int i = 0; i < frame_count; i++) {
+ FrameSpec frame;
+ os.str("");
+ os<<f->tiledef_special[j].name<<"^[verticalframe:"<<frame_count<<":"<<i;
+ frame.texture = tsrc->getTexture(os.str(), &frame.texture_id);
+ if (f->special_tiles[j].normal_texture)
+ frame.normal_texture = tsrc->getNormalTexture(os.str());
+ f->special_tiles[j].frames[i]=frame;
}
}
}
diff --git a/src/tile.cpp b/src/tile.cpp
index 17ec51614..7cb39eabf 100644
--- a/src/tile.cpp
+++ b/src/tile.cpp
@@ -389,6 +389,7 @@ public:
// Shall be called from the main thread.
bool generateImage(std::string part_of_name, video::IImage *& baseimg);
+ video::ITexture* getNormalTexture(const std::string &name);
private:
// 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)
dst->setPixel(dx,dy,c);
}
}
+
+video::ITexture* TextureSource::getNormalTexture(const std::string &name)
+{
+ u32 id;
+ if (isKnownSourceImage("override_normal.png"))
+ return getTexture("override_normal.png", &id);
+ std::string fname_base = name;
+ std::string normal_ext = "_normal.png";
+ size_t pos = fname_base.find(".");
+ std::string fname_normal = fname_base.substr(0, pos) + normal_ext;
+ if (isKnownSourceImage(fname_normal)) {
+ // look for image extension and replace it
+ size_t i = 0;
+ while ((i = fname_base.find(".", i)) != std::string::npos) {
+ fname_base.replace(i, 4, normal_ext);
+ i += normal_ext.length();
+ }
+ return getTexture(fname_base, &id);
+ }
+ return NULL;
+}
diff --git a/src/tile.h b/src/tile.h
index 29c6b69f2..f3250669e 100644
--- a/src/tile.h
+++ b/src/tile.h
@@ -27,6 +27,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include <IrrlichtDevice.h>
#include "threads.h"
#include <string>
+#include <map>
class IGameDef;
@@ -106,6 +107,7 @@ public:
virtual bool isKnownSourceImage(const std::string &name)=0;
virtual video::ITexture* generateTextureFromMesh(
const TextureFromMeshParams &params)=0;
+ virtual video::ITexture* getNormalTexture(const std::string &name)=0;
};
class IWritableTextureSource : public ITextureSource
@@ -127,6 +129,7 @@ public:
virtual void processQueue()=0;
virtual void insertSourceImage(const std::string &name, video::IImage *img)=0;
virtual void rebuildImagesAndTextures()=0;
+ virtual video::ITexture* getNormalTexture(const std::string &name)=0;
};
IWritableTextureSource* createTextureSource(IrrlichtDevice *device);
@@ -175,11 +178,25 @@ enum MaterialType{
This fully defines the looks of a tile.
The SMaterial of a tile is constructed according to this.
*/
+struct FrameSpec
+{
+ FrameSpec():
+ texture_id(0),
+ texture(NULL),
+ normal_texture(NULL)
+ {
+ }
+ u32 texture_id;
+ video::ITexture *texture;
+ video::ITexture *normal_texture;
+};
+
struct TileSpec
{
TileSpec():
texture_id(0),
texture(NULL),
+ normal_texture(NULL),
alpha(255),
material_type(TILE_MATERIAL_BASIC),
material_flags(
@@ -243,6 +260,8 @@ struct TileSpec
u32 texture_id;
video::ITexture *texture;
+ video::ITexture *normal_texture;
+
// Vertex alpha (when MATERIAL_ALPHA_VERTEX is used)
u8 alpha;
// Material parameters
@@ -252,6 +271,8 @@ struct TileSpec
// Animation parameters
u8 animation_frame_count;
u16 animation_frame_length_ms;
+ std::map<u32, FrameSpec> frames;
+
u8 rotation;
};