]> git.lizzy.rs Git - minetest-m13.git/blob - src/mapblock_mesh.h
921daf2d2342bc29c6d31f0f66c3e63cc1e3694d
[minetest-m13.git] / src / mapblock_mesh.h
1 /*
2 Minetest-m13
3 Copyright (C) 2010-2011 celeron55, Perttu Ahola <celeron55@gmail.com>
4
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2 of the License, or
8 (at your option) any later version.
9
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13 GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License along
16 with this program; if not, write to the Free Software Foundation, Inc.,
17 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18 */
19
20 #ifndef MAPBLOCK_MESH_HEADER
21 #define MAPBLOCK_MESH_HEADER
22
23 #include "common_irrlicht.h"
24 #include "mapblock_nodemod.h"
25 #include "tile.h"
26 #include "voxel.h"
27
28 class IGameDef;
29
30 /*
31         Mesh making stuff
32 */
33
34 /*
35         This is used because CMeshBuffer::append() is very slow
36 */
37 struct PreMeshBuffer
38 {
39         video::SMaterial material;
40         core::array<u16> indices;
41         core::array<video::S3DVertex> vertices;
42 };
43
44 class MeshCollector
45 {
46 public:
47         void append(
48                         video::SMaterial material,
49                         const video::S3DVertex* const vertices,
50                         u32 numVertices,
51                         const u16* const indices,
52                         u32 numIndices
53                 )
54         {
55                 PreMeshBuffer *p = NULL;
56                 for(u32 i=0; i<m_prebuffers.size(); i++)
57                 {
58                         PreMeshBuffer &pp = m_prebuffers[i];
59                         if(pp.material != material)
60                                 continue;
61
62                         p = &pp;
63                         break;
64                 }
65
66                 if(p == NULL)
67                 {
68                         PreMeshBuffer pp;
69                         pp.material = material;
70                         m_prebuffers.push_back(pp);
71                         p = &m_prebuffers[m_prebuffers.size()-1];
72                 }
73
74                 u32 vertex_count = p->vertices.size();
75                 for(u32 i=0; i<numIndices; i++)
76                 {
77                         u32 j = indices[i] + vertex_count;
78                         if(j > 65535)
79                         {
80                                 dstream<<"FIXME: Meshbuffer ran out of indices"<<std::endl;
81                                 // NOTE: Fix is to just add an another MeshBuffer
82                         }
83                         p->indices.push_back(j);
84                 }
85                 for(u32 i=0; i<numVertices; i++)
86                 {
87                         p->vertices.push_back(vertices[i]);
88                 }
89         }
90
91         void fillMesh(scene::SMesh *mesh)
92         {
93                 /*dstream<<"Filling mesh with "<<m_prebuffers.size()
94                                 <<" meshbuffers"<<std::endl;*/
95                 for(u32 i=0; i<m_prebuffers.size(); i++)
96                 {
97                         PreMeshBuffer &p = m_prebuffers[i];
98
99                         /*dstream<<"p.vertices.size()="<<p.vertices.size()
100                                         <<", p.indices.size()="<<p.indices.size()
101                                         <<std::endl;*/
102                         
103                         // Create meshbuffer
104                         
105                         // This is a "Standard MeshBuffer",
106                         // it's a typedeffed CMeshBuffer<video::S3DVertex>
107                         scene::SMeshBuffer *buf = new scene::SMeshBuffer();
108                         // Set material
109                         buf->Material = p.material;
110                         //((scene::SMeshBuffer*)buf)->Material = p.material;
111                         // Use VBO
112                         //buf->setHardwareMappingHint(scene::EHM_STATIC);
113                         // Add to mesh
114                         mesh->addMeshBuffer(buf);
115                         // Mesh grabbed it
116                         buf->drop();
117
118                         buf->append(p.vertices.pointer(), p.vertices.size(),
119                                         p.indices.pointer(), p.indices.size());
120                 }
121         }
122
123 private:
124         core::array<PreMeshBuffer> m_prebuffers;
125 };
126
127 // Helper functions
128 video::SColor MapBlock_LightColor(u8 alpha, u8 light);
129 TileSpec getNodeTile(MapNode mn, v3s16 p, v3s16 face_dir,
130                 NodeModMap *temp_mods, ITextureSource *tsrc, INodeDefManager *ndef);
131
132 class MapBlock;
133
134 struct MeshMakeData
135 {
136         u32 m_daynight_ratio;
137         NodeModMap m_temp_mods;
138         VoxelManipulator m_vmanip;
139         v3s16 m_blockpos;
140         
141         /*
142                 Copy central data directly from block, and other data from
143                 parent of block.
144         */
145         void fill(u32 daynight_ratio, MapBlock *block);
146
147         /*
148                 Set up with only a single node at (1,1,1)
149         */
150         void fillSingleNode(u32 daynight_ratio, MapNode *node);
151 };
152
153 // This is the highest-level function in here
154 scene::SMesh* makeMapBlockMesh(MeshMakeData *data, IGameDef *gamedef);
155
156 #endif
157