Skip to content
Snippets Groups Projects
Commit 7ea40e45 authored by RealBadAngel's avatar RealBadAngel Committed by paramat
Browse files

Use vertices with tangents only when its needed.

parent 3a74b840
No related branches found
No related tags found
No related merge requests found
......@@ -263,6 +263,9 @@ Client::Client(
m_cache_smooth_lighting = g_settings->getBool("smooth_lighting");
m_cache_enable_shaders = g_settings->getBool("enable_shaders");
m_cache_use_tangent_vertices = m_cache_enable_shaders && (
g_settings->getBool("enable_bumpmapping") ||
g_settings->getBool("enable_parallax_occlusion"));
}
void Client::Stop()
......@@ -1582,7 +1585,8 @@ void Client::addUpdateMeshTask(v3s16 p, bool ack_to_server, bool urgent)
Create a task to update the mesh of the block
*/
MeshMakeData *data = new MeshMakeData(this, m_cache_enable_shaders);
MeshMakeData *data = new MeshMakeData(this, m_cache_enable_shaders,
m_cache_use_tangent_vertices);
{
//TimeTaker timer("data fill");
......
......@@ -677,6 +677,7 @@ class Client : public con::PeerHandler, public InventoryManager, public IGameDef
// TODO: Add callback to update these when g_settings changes
bool m_cache_smooth_lighting;
bool m_cache_enable_shaders;
bool m_cache_use_tangent_vertices;
DISABLE_CLASS_COPY(Client);
};
......
......@@ -33,24 +33,26 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "util/directiontables.h"
#include <IMeshManipulator.h>
static void applyFacesShading(video::SColor& color, float factor)
static void applyFacesShading(video::SColor &color, const float factor)
{
color.setRed(core::clamp(core::round32(color.getRed()*factor), 0, 255));
color.setGreen(core::clamp(core::round32(color.getGreen()*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));
}
/*
MeshMakeData
*/
MeshMakeData::MeshMakeData(IGameDef *gamedef, bool use_shaders):
MeshMakeData::MeshMakeData(IGameDef *gamedef, bool use_shaders,
bool use_tangent_vertices):
m_vmanip(),
m_blockpos(-1337,-1337,-1337),
m_crack_pos_relative(-1337, -1337, -1337),
m_smooth_lighting(false),
m_show_hud(false),
m_gamedef(gamedef),
m_use_shaders(use_shaders)
m_use_shaders(use_shaders),
m_use_tangent_vertices(use_tangent_vertices)
{}
void MeshMakeData::fill(MapBlock *block)
......@@ -1032,6 +1034,7 @@ MapBlockMesh::MapBlockMesh(MeshMakeData *data, v3s16 camera_offset):
m_daynight_diffs()
{
m_enable_shaders = data->m_use_shaders;
m_use_tangent_vertices = data->m_use_tangent_vertices;
if (g_settings->getBool("enable_minimap")) {
m_minimap_mapblock = new MinimapMapblock;
......@@ -1064,15 +1067,14 @@ MapBlockMesh::MapBlockMesh(MeshMakeData *data, v3s16 camera_offset):
Convert FastFaces to MeshCollector
*/
MeshCollector collector;
MeshCollector collector(m_use_tangent_vertices);
{
// avg 0ms (100ms spikes when loading textures the first time)
// (NOTE: probably outdated)
//TimeTaker timer2("MeshCollector building");
for(u32 i=0; i<fastfaces_new.size(); i++)
{
for (u32 i = 0; i < fastfaces_new.size(); i++) {
FastFace &f = fastfaces_new[i];
const u16 indices[] = {0,1,2,2,3,0};
......@@ -1150,35 +1152,43 @@ MapBlockMesh::MapBlockMesh(MeshMakeData *data, v3s16 camera_offset):
p.tile.texture = animation_frame.texture;
}
for(u32 j = 0; j < p.vertices.size(); j++)
{
video::S3DVertex *vertex = &p.vertices[j];
u32 vertex_count = m_use_tangent_vertices ?
p.tangent_vertices.size() : p.vertices.size();
for (u32 j = 0; j < vertex_count; j++) {
v3f *Normal;
video::SColor *vc;
if (m_use_tangent_vertices) {
vc = &p.tangent_vertices[j].Color;
Normal = &p.tangent_vertices[j].Normal;
} else {
vc = &p.vertices[j].Color;
Normal = &p.vertices[j].Normal;
}
// Note applyFacesShading second parameter is precalculated sqrt
// value for speed improvement
// Skip it for lightsources and top faces.
video::SColor &vc = vertex->Color;
if (!vc.getBlue()) {
if (vertex->Normal.Y < -0.5) {
applyFacesShading (vc, 0.447213);
} else if (vertex->Normal.X > 0.5) {
applyFacesShading (vc, 0.670820);
} else if (vertex->Normal.X < -0.5) {
applyFacesShading (vc, 0.670820);
} else if (vertex->Normal.Z > 0.5) {
applyFacesShading (vc, 0.836660);
} else if (vertex->Normal.Z < -0.5) {
applyFacesShading (vc, 0.836660);
if (!vc->getBlue()) {
if (Normal->Y < -0.5) {
applyFacesShading(*vc, 0.447213);
} else if (Normal->X > 0.5) {
applyFacesShading(*vc, 0.670820);
} else if (Normal->X < -0.5) {
applyFacesShading(*vc, 0.670820);
} else if (Normal->Z > 0.5) {
applyFacesShading(*vc, 0.836660);
} else if (Normal->Z < -0.5) {
applyFacesShading(*vc, 0.836660);
}
}
if(!m_enable_shaders)
{
if (!m_enable_shaders) {
// - Classic lighting (shaders handle this by themselves)
// Set initial real color and store for later updates
u8 day = vc.getRed();
u8 night = vc.getGreen();
finalColorBlend(vc, day, night, 1000);
if(day != night)
u8 day = vc->getRed();
u8 night = vc->getGreen();
finalColorBlend(*vc, day, night, 1000);
if (day != night) {
m_daynight_diffs[i][j] = std::make_pair(day, night);
}
}
}
......@@ -1201,34 +1211,46 @@ MapBlockMesh::MapBlockMesh(MeshMakeData *data, v3s16 camera_offset):
p.tile.applyMaterialOptions(material);
}
// Create meshbuffer
scene::SMeshBuffer *buf = new scene::SMeshBuffer();
// Set material
buf->Material = material;
// Add to mesh
scene::SMesh *mesh = (scene::SMesh *)m_mesh;
mesh->addMeshBuffer(buf);
// Mesh grabbed it
buf->drop();
buf->append(&p.vertices[0], p.vertices.size(),
&p.indices[0], p.indices.size());
}
m_camera_offset = camera_offset;
scene::SMesh *mesh = (scene::SMesh *)m_mesh;
// Create meshbuffer, add to mesh
if (m_use_tangent_vertices) {
scene::SMeshBufferTangents *buf = new scene::SMeshBufferTangents();
// Set material
buf->Material = material;
// Add to mesh
mesh->addMeshBuffer(buf);
// Mesh grabbed it
buf->drop();
buf->append(&p.tangent_vertices[0], p.tangent_vertices.size(),
&p.indices[0], p.indices.size());
} else {
scene::SMeshBuffer *buf = new scene::SMeshBuffer();
// Set material
buf->Material = material;
// Add to mesh
mesh->addMeshBuffer(buf);
// Mesh grabbed it
buf->drop();
buf->append(&p.vertices[0], p.vertices.size(),
&p.indices[0], p.indices.size());
}
}
/*
Do some stuff to the mesh
*/
m_camera_offset = camera_offset;
translateMesh(m_mesh,
intToFloat(data->m_blockpos * MAP_BLOCKSIZE - camera_offset, BS));
translateMesh(m_mesh, intToFloat(data->m_blockpos * MAP_BLOCKSIZE - camera_offset, BS));
if (m_enable_shaders) {
scene::IMeshManipulator* meshmanip = m_gamedef->getSceneManager()->getMeshManipulator();
scene::IMesh* tangentMesh = meshmanip->createMeshWithTangents(m_mesh);
m_mesh->drop();
m_mesh = tangentMesh;
if (m_use_tangent_vertices) {
scene::IMeshManipulator* meshmanip =
m_gamedef->getSceneManager()->getMeshManipulator();
meshmanip->recalculateTangents(m_mesh, true, false, false);
}
if(m_mesh)
if (m_mesh)
{
#if 0
// Usually 1-700 faces and 1-7 materials
......@@ -1400,17 +1422,30 @@ void MeshCollector::append(const TileSpec &tile,
p = &prebuffers[prebuffers.size() - 1];
}
u32 vertex_count = p->vertices.size();
for (u32 i = 0; i < numIndices; i++) {
u32 vertex_count;
if (m_use_tangent_vertices) {
vertex_count = p->tangent_vertices.size();
p->tangent_vertices.reserve(vertex_count + numVertices);
for (u32 i = 0; i < numVertices; i++) {
video::S3DVertexTangents vert(vertices[i].Pos, vertices[i].Normal,
vertices[i].Color, vertices[i].TCoords);
p->tangent_vertices.push_back(vert);
}
} else {
vertex_count = p->vertices.size();
p->vertices.reserve(vertex_count + numVertices);
for (u32 i = 0; i < numVertices; i++) {
video::S3DVertex vert(vertices[i].Pos, vertices[i].Normal,
vertices[i].Color, vertices[i].TCoords);
p->vertices.push_back(vert);
}
}
p->indices.reserve(p->indices.size() + numIndices);
for (u32 i = 0; i < numIndices; i++) {
u32 j = indices[i] + vertex_count;
p->indices.push_back(j);
}
for (u32 i = 0; i < numVertices; i++) {
video::S3DVertex vert(vertices[i].Pos, vertices[i].Normal,
vertices[i].Color, vertices[i].TCoords);
p->vertices.push_back(vert);
}
}
/*
......@@ -1446,15 +1481,28 @@ void MeshCollector::append(const TileSpec &tile,
p = &prebuffers[prebuffers.size() - 1];
}
u32 vertex_count = p->vertices.size();
u32 vertex_count;
if (m_use_tangent_vertices) {
vertex_count = p->tangent_vertices.size();
p->tangent_vertices.reserve(vertex_count + numVertices);
for (u32 i = 0; i < numVertices; i++) {
video::S3DVertexTangents vert(vertices[i].Pos + pos,
vertices[i].Normal, c, vertices[i].TCoords);
p->tangent_vertices.push_back(vert);
}
} else {
vertex_count = p->vertices.size();
p->vertices.reserve(vertex_count + numVertices);
for (u32 i = 0; i < numVertices; i++) {
video::S3DVertex vert(vertices[i].Pos + pos,
vertices[i].Normal, c, vertices[i].TCoords);
p->vertices.push_back(vert);
}
}
p->indices.reserve(p->indices.size() + numIndices);
for (u32 i = 0; i < numIndices; i++) {
u32 j = indices[i] + vertex_count;
p->indices.push_back(j);
}
for (u32 i = 0; i < numVertices; i++) {
video::S3DVertex vert(vertices[i].Pos + pos, vertices[i].Normal,
c, vertices[i].TCoords);
p->vertices.push_back(vert);
}
}
......@@ -46,8 +46,10 @@ struct MeshMakeData
IGameDef *m_gamedef;
bool m_use_shaders;
bool m_use_tangent_vertices;
MeshMakeData(IGameDef *gamedef, bool use_shaders);
MeshMakeData(IGameDef *gamedef, bool use_shaders,
bool use_tangent_vertices = false);
/*
Copy central data directly from block, and other data from
......@@ -130,6 +132,7 @@ class MapBlockMesh
IShaderSource *m_shdrsrc;
bool m_enable_shaders;
bool m_use_tangent_vertices;
// Must animate() be called before rendering?
bool m_has_animation;
......@@ -167,11 +170,19 @@ struct PreMeshBuffer
TileSpec tile;
std::vector<u16> indices;
std::vector<video::S3DVertex> vertices;
std::vector<video::S3DVertexTangents> tangent_vertices;
};
struct MeshCollector
{
std::vector<PreMeshBuffer> prebuffers;
bool m_use_tangent_vertices;
MeshCollector(bool use_tangent_vertices):
m_use_tangent_vertices(use_tangent_vertices)
{
}
void append(const TileSpec &material,
const video::S3DVertex *vertices, u32 numVertices,
const u16 *indices, u32 numIndices);
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment