Added #define WATER_ALPHA in content_mapnode.cpp
[oweals/minetest.git] / src / mapblock_mesh.h
1 /*
2 Minetest-c55
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 "voxel.h"
26
27 /*
28         Mesh making stuff
29 */
30
31 /*
32         This is used because CMeshBuffer::append() is very slow
33 */
34 struct PreMeshBuffer
35 {
36         video::SMaterial material;
37         core::array<u16> indices;
38         core::array<video::S3DVertex> vertices;
39 };
40
41 class MeshCollector
42 {
43 public:
44         void append(
45                         video::SMaterial material,
46                         const video::S3DVertex* const vertices,
47                         u32 numVertices,
48                         const u16* const indices,
49                         u32 numIndices
50                 )
51         {
52                 PreMeshBuffer *p = NULL;
53                 for(u32 i=0; i<m_prebuffers.size(); i++)
54                 {
55                         PreMeshBuffer &pp = m_prebuffers[i];
56                         if(pp.material != material)
57                                 continue;
58
59                         p = &pp;
60                         break;
61                 }
62
63                 if(p == NULL)
64                 {
65                         PreMeshBuffer pp;
66                         pp.material = material;
67                         m_prebuffers.push_back(pp);
68                         p = &m_prebuffers[m_prebuffers.size()-1];
69                 }
70
71                 u32 vertex_count = p->vertices.size();
72                 for(u32 i=0; i<numIndices; i++)
73                 {
74                         u32 j = indices[i] + vertex_count;
75                         if(j > 65535)
76                         {
77                                 dstream<<"FIXME: Meshbuffer ran out of indices"<<std::endl;
78                                 // NOTE: Fix is to just add an another MeshBuffer
79                         }
80                         p->indices.push_back(j);
81                 }
82                 for(u32 i=0; i<numVertices; i++)
83                 {
84                         p->vertices.push_back(vertices[i]);
85                 }
86         }
87
88         void fillMesh(scene::SMesh *mesh)
89         {
90                 /*dstream<<"Filling mesh with "<<m_prebuffers.size()
91                                 <<" meshbuffers"<<std::endl;*/
92                 for(u32 i=0; i<m_prebuffers.size(); i++)
93                 {
94                         PreMeshBuffer &p = m_prebuffers[i];
95
96                         /*dstream<<"p.vertices.size()="<<p.vertices.size()
97                                         <<", p.indices.size()="<<p.indices.size()
98                                         <<std::endl;*/
99                         
100                         // Create meshbuffer
101                         
102                         // This is a "Standard MeshBuffer",
103                         // it's a typedeffed CMeshBuffer<video::S3DVertex>
104                         scene::SMeshBuffer *buf = new scene::SMeshBuffer();
105                         // Set material
106                         buf->Material = p.material;
107                         //((scene::SMeshBuffer*)buf)->Material = p.material;
108                         // Use VBO
109                         //buf->setHardwareMappingHint(scene::EHM_STATIC);
110                         // Add to mesh
111                         mesh->addMeshBuffer(buf);
112                         // Mesh grabbed it
113                         buf->drop();
114
115                         buf->append(p.vertices.pointer(), p.vertices.size(),
116                                         p.indices.pointer(), p.indices.size());
117                 }
118         }
119
120 private:
121         core::array<PreMeshBuffer> m_prebuffers;
122 };
123
124 // Helper functions
125 video::SColor MapBlock_LightColor(u8 alpha, u8 light);
126
127 class MapBlock;
128
129 struct MeshMakeData
130 {
131         u32 m_daynight_ratio;
132         NodeModMap m_temp_mods;
133         VoxelManipulator m_vmanip;
134         v3s16 m_blockpos;
135         
136         /*
137                 Copy central data directly from block, and other data from
138                 parent of block.
139         */
140         void fill(u32 daynight_ratio, MapBlock *block);
141 };
142
143 // This is the highest-level function in here
144 scene::SMesh* makeMapBlockMesh(MeshMakeData *data);
145
146 #endif
147