minetest/src/mapblock_mesh.h

148 lines
3.3 KiB
C++

/*
Minetest-c55
Copyright (C) 2010-2011 celeron55, Perttu Ahola <celeron55@gmail.com>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#ifndef MAPBLOCK_MESH_HEADER
#define MAPBLOCK_MESH_HEADER
#include "common_irrlicht.h"
#include "mapblock_nodemod.h"
#include "voxel.h"
/*
Mesh making stuff
*/
/*
This is used because CMeshBuffer::append() is very slow
*/
struct PreMeshBuffer
{
video::SMaterial material;
core::array<u16> indices;
core::array<video::S3DVertex> vertices;
};
class MeshCollector
{
public:
void append(
video::SMaterial material,
const video::S3DVertex* const vertices,
u32 numVertices,
const u16* const indices,
u32 numIndices
)
{
PreMeshBuffer *p = NULL;
for(u32 i=0; i<m_prebuffers.size(); i++)
{
PreMeshBuffer &pp = m_prebuffers[i];
if(pp.material != material)
continue;
p = &pp;
break;
}
if(p == NULL)
{
PreMeshBuffer pp;
pp.material = material;
m_prebuffers.push_back(pp);
p = &m_prebuffers[m_prebuffers.size()-1];
}
u32 vertex_count = p->vertices.size();
for(u32 i=0; i<numIndices; i++)
{
u32 j = indices[i] + vertex_count;
if(j > 65535)
{
dstream<<"FIXME: Meshbuffer ran out of indices"<<std::endl;
// NOTE: Fix is to just add an another MeshBuffer
}
p->indices.push_back(j);
}
for(u32 i=0; i<numVertices; i++)
{
p->vertices.push_back(vertices[i]);
}
}
void fillMesh(scene::SMesh *mesh)
{
/*dstream<<"Filling mesh with "<<m_prebuffers.size()
<<" meshbuffers"<<std::endl;*/
for(u32 i=0; i<m_prebuffers.size(); i++)
{
PreMeshBuffer &p = m_prebuffers[i];
/*dstream<<"p.vertices.size()="<<p.vertices.size()
<<", p.indices.size()="<<p.indices.size()
<<std::endl;*/
// Create meshbuffer
// This is a "Standard MeshBuffer",
// it's a typedeffed CMeshBuffer<video::S3DVertex>
scene::SMeshBuffer *buf = new scene::SMeshBuffer();
// Set material
buf->Material = p.material;
//((scene::SMeshBuffer*)buf)->Material = p.material;
// Use VBO
//buf->setHardwareMappingHint(scene::EHM_STATIC);
// Add to mesh
mesh->addMeshBuffer(buf);
// Mesh grabbed it
buf->drop();
buf->append(p.vertices.pointer(), p.vertices.size(),
p.indices.pointer(), p.indices.size());
}
}
private:
core::array<PreMeshBuffer> m_prebuffers;
};
// Helper functions
video::SColor MapBlock_LightColor(u8 alpha, u8 light);
class MapBlock;
struct MeshMakeData
{
u32 m_daynight_ratio;
NodeModMap m_temp_mods;
VoxelManipulator m_vmanip;
v3s16 m_blockpos;
/*
Copy central data directly from block, and other data from
parent of block.
*/
void fill(u32 daynight_ratio, MapBlock *block);
};
// This is the highest-level function in here
scene::SMesh* makeMapBlockMesh(MeshMakeData *data);
#endif