diff options
Diffstat (limited to 'src/mapblock_mesh.h')
-rw-r--r-- | src/mapblock_mesh.h | 143 |
1 files changed, 143 insertions, 0 deletions
diff --git a/src/mapblock_mesh.h b/src/mapblock_mesh.h new file mode 100644 index 000000000..591172bc9 --- /dev/null +++ b/src/mapblock_mesh.h @@ -0,0 +1,143 @@ +/* +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; +}; + +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); +}; + +scene::SMesh* makeMapBlockMesh(MeshMakeData *data); + +#endif + |