mirror of
https://github.com/minetest/minetest.git
synced 2024-11-23 16:13:46 +01:00
Use vertices with tangents only when its needed.
This commit is contained in:
parent
3a74b84007
commit
7ea40e45b1
@ -263,6 +263,9 @@ Client::Client(
|
|||||||
|
|
||||||
m_cache_smooth_lighting = g_settings->getBool("smooth_lighting");
|
m_cache_smooth_lighting = g_settings->getBool("smooth_lighting");
|
||||||
m_cache_enable_shaders = g_settings->getBool("enable_shaders");
|
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()
|
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
|
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");
|
//TimeTaker timer("data fill");
|
||||||
|
@ -677,6 +677,7 @@ private:
|
|||||||
// TODO: Add callback to update these when g_settings changes
|
// TODO: Add callback to update these when g_settings changes
|
||||||
bool m_cache_smooth_lighting;
|
bool m_cache_smooth_lighting;
|
||||||
bool m_cache_enable_shaders;
|
bool m_cache_enable_shaders;
|
||||||
|
bool m_cache_use_tangent_vertices;
|
||||||
|
|
||||||
DISABLE_CLASS_COPY(Client);
|
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 "util/directiontables.h"
|
||||||
#include <IMeshManipulator.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.setRed(core::clamp(core::round32(color.getRed() * factor), 0, 255));
|
||||||
color.setGreen(core::clamp(core::round32(color.getGreen()*factor), 0, 255));
|
color.setGreen(core::clamp(core::round32(color.getGreen() * factor), 0, 255));
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
MeshMakeData
|
MeshMakeData
|
||||||
*/
|
*/
|
||||||
|
|
||||||
MeshMakeData::MeshMakeData(IGameDef *gamedef, bool use_shaders):
|
MeshMakeData::MeshMakeData(IGameDef *gamedef, bool use_shaders,
|
||||||
|
bool use_tangent_vertices):
|
||||||
m_vmanip(),
|
m_vmanip(),
|
||||||
m_blockpos(-1337,-1337,-1337),
|
m_blockpos(-1337,-1337,-1337),
|
||||||
m_crack_pos_relative(-1337, -1337, -1337),
|
m_crack_pos_relative(-1337, -1337, -1337),
|
||||||
m_smooth_lighting(false),
|
m_smooth_lighting(false),
|
||||||
m_show_hud(false),
|
m_show_hud(false),
|
||||||
m_gamedef(gamedef),
|
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)
|
void MeshMakeData::fill(MapBlock *block)
|
||||||
@ -1032,6 +1034,7 @@ MapBlockMesh::MapBlockMesh(MeshMakeData *data, v3s16 camera_offset):
|
|||||||
m_daynight_diffs()
|
m_daynight_diffs()
|
||||||
{
|
{
|
||||||
m_enable_shaders = data->m_use_shaders;
|
m_enable_shaders = data->m_use_shaders;
|
||||||
|
m_use_tangent_vertices = data->m_use_tangent_vertices;
|
||||||
|
|
||||||
if (g_settings->getBool("enable_minimap")) {
|
if (g_settings->getBool("enable_minimap")) {
|
||||||
m_minimap_mapblock = new MinimapMapblock;
|
m_minimap_mapblock = new MinimapMapblock;
|
||||||
@ -1064,15 +1067,14 @@ MapBlockMesh::MapBlockMesh(MeshMakeData *data, v3s16 camera_offset):
|
|||||||
Convert FastFaces to MeshCollector
|
Convert FastFaces to MeshCollector
|
||||||
*/
|
*/
|
||||||
|
|
||||||
MeshCollector collector;
|
MeshCollector collector(m_use_tangent_vertices);
|
||||||
|
|
||||||
{
|
{
|
||||||
// avg 0ms (100ms spikes when loading textures the first time)
|
// avg 0ms (100ms spikes when loading textures the first time)
|
||||||
// (NOTE: probably outdated)
|
// (NOTE: probably outdated)
|
||||||
//TimeTaker timer2("MeshCollector building");
|
//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];
|
FastFace &f = fastfaces_new[i];
|
||||||
|
|
||||||
const u16 indices[] = {0,1,2,2,3,0};
|
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;
|
p.tile.texture = animation_frame.texture;
|
||||||
}
|
}
|
||||||
|
|
||||||
for(u32 j = 0; j < p.vertices.size(); j++)
|
u32 vertex_count = m_use_tangent_vertices ?
|
||||||
{
|
p.tangent_vertices.size() : p.vertices.size();
|
||||||
video::S3DVertex *vertex = &p.vertices[j];
|
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
|
// Note applyFacesShading second parameter is precalculated sqrt
|
||||||
// value for speed improvement
|
// value for speed improvement
|
||||||
// Skip it for lightsources and top faces.
|
// Skip it for lightsources and top faces.
|
||||||
video::SColor &vc = vertex->Color;
|
if (!vc->getBlue()) {
|
||||||
if (!vc.getBlue()) {
|
if (Normal->Y < -0.5) {
|
||||||
if (vertex->Normal.Y < -0.5) {
|
applyFacesShading(*vc, 0.447213);
|
||||||
applyFacesShading (vc, 0.447213);
|
} else if (Normal->X > 0.5) {
|
||||||
} else if (vertex->Normal.X > 0.5) {
|
applyFacesShading(*vc, 0.670820);
|
||||||
applyFacesShading (vc, 0.670820);
|
} else if (Normal->X < -0.5) {
|
||||||
} else if (vertex->Normal.X < -0.5) {
|
applyFacesShading(*vc, 0.670820);
|
||||||
applyFacesShading (vc, 0.670820);
|
} else if (Normal->Z > 0.5) {
|
||||||
} else if (vertex->Normal.Z > 0.5) {
|
applyFacesShading(*vc, 0.836660);
|
||||||
applyFacesShading (vc, 0.836660);
|
} else if (Normal->Z < -0.5) {
|
||||||
} else if (vertex->Normal.Z < -0.5) {
|
applyFacesShading(*vc, 0.836660);
|
||||||
applyFacesShading (vc, 0.836660);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(!m_enable_shaders)
|
if (!m_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
|
// Set initial real color and store for later updates
|
||||||
u8 day = vc.getRed();
|
u8 day = vc->getRed();
|
||||||
u8 night = vc.getGreen();
|
u8 night = vc->getGreen();
|
||||||
finalColorBlend(vc, day, night, 1000);
|
finalColorBlend(*vc, day, night, 1000);
|
||||||
if(day != night)
|
if (day != night) {
|
||||||
m_daynight_diffs[i][j] = std::make_pair(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);
|
p.tile.applyMaterialOptions(material);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create meshbuffer
|
scene::SMesh *mesh = (scene::SMesh *)m_mesh;
|
||||||
scene::SMeshBuffer *buf = new scene::SMeshBuffer();
|
|
||||||
// Set material
|
// Create meshbuffer, add to mesh
|
||||||
buf->Material = material;
|
if (m_use_tangent_vertices) {
|
||||||
// Add to mesh
|
scene::SMeshBufferTangents *buf = new scene::SMeshBufferTangents();
|
||||||
scene::SMesh *mesh = (scene::SMesh *)m_mesh;
|
// Set material
|
||||||
mesh->addMeshBuffer(buf);
|
buf->Material = material;
|
||||||
// Mesh grabbed it
|
// Add to mesh
|
||||||
buf->drop();
|
mesh->addMeshBuffer(buf);
|
||||||
buf->append(&p.vertices[0], p.vertices.size(),
|
// Mesh grabbed it
|
||||||
&p.indices[0], p.indices.size());
|
buf->drop();
|
||||||
}
|
buf->append(&p.tangent_vertices[0], p.tangent_vertices.size(),
|
||||||
m_camera_offset = camera_offset;
|
&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
|
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_use_tangent_vertices) {
|
||||||
|
scene::IMeshManipulator* meshmanip =
|
||||||
if (m_enable_shaders) {
|
m_gamedef->getSceneManager()->getMeshManipulator();
|
||||||
scene::IMeshManipulator* meshmanip = m_gamedef->getSceneManager()->getMeshManipulator();
|
meshmanip->recalculateTangents(m_mesh, true, false, false);
|
||||||
scene::IMesh* tangentMesh = meshmanip->createMeshWithTangents(m_mesh);
|
|
||||||
m_mesh->drop();
|
|
||||||
m_mesh = tangentMesh;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if(m_mesh)
|
if (m_mesh)
|
||||||
{
|
{
|
||||||
#if 0
|
#if 0
|
||||||
// Usually 1-700 faces and 1-7 materials
|
// Usually 1-700 faces and 1-7 materials
|
||||||
@ -1400,17 +1422,30 @@ void MeshCollector::append(const TileSpec &tile,
|
|||||||
p = &prebuffers[prebuffers.size() - 1];
|
p = &prebuffers[prebuffers.size() - 1];
|
||||||
}
|
}
|
||||||
|
|
||||||
u32 vertex_count = p->vertices.size();
|
u32 vertex_count;
|
||||||
for (u32 i = 0; i < numIndices; i++) {
|
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;
|
u32 j = indices[i] + vertex_count;
|
||||||
p->indices.push_back(j);
|
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];
|
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++) {
|
for (u32 i = 0; i < numIndices; i++) {
|
||||||
u32 j = indices[i] + vertex_count;
|
u32 j = indices[i] + vertex_count;
|
||||||
p->indices.push_back(j);
|
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;
|
IGameDef *m_gamedef;
|
||||||
bool m_use_shaders;
|
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
|
Copy central data directly from block, and other data from
|
||||||
@ -130,6 +132,7 @@ private:
|
|||||||
IShaderSource *m_shdrsrc;
|
IShaderSource *m_shdrsrc;
|
||||||
|
|
||||||
bool m_enable_shaders;
|
bool m_enable_shaders;
|
||||||
|
bool m_use_tangent_vertices;
|
||||||
|
|
||||||
// Must animate() be called before rendering?
|
// Must animate() be called before rendering?
|
||||||
bool m_has_animation;
|
bool m_has_animation;
|
||||||
@ -167,11 +170,19 @@ struct PreMeshBuffer
|
|||||||
TileSpec tile;
|
TileSpec tile;
|
||||||
std::vector<u16> indices;
|
std::vector<u16> indices;
|
||||||
std::vector<video::S3DVertex> vertices;
|
std::vector<video::S3DVertex> vertices;
|
||||||
|
std::vector<video::S3DVertexTangents> tangent_vertices;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct MeshCollector
|
struct MeshCollector
|
||||||
{
|
{
|
||||||
std::vector<PreMeshBuffer> prebuffers;
|
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,
|
void append(const TileSpec &material,
|
||||||
const video::S3DVertex *vertices, u32 numVertices,
|
const video::S3DVertex *vertices, u32 numVertices,
|
||||||
const u16 *indices, u32 numIndices);
|
const u16 *indices, u32 numIndices);
|
||||||
|
Loading…
Reference in New Issue
Block a user