]> git.lizzy.rs Git - minetest.git/blob - src/client/clientmap.h
Add depth sorting for node faces (#11696)
[minetest.git] / src / client / clientmap.h
1 /*
2 Minetest
3 Copyright (C) 2010-2013 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 Lesser General Public License as published by
7 the Free Software Foundation; either version 2.1 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 Lesser General Public License for more details.
14
15 You should have received a copy of the GNU Lesser 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 #pragma once
21
22 #include "irrlichttypes_extrabloated.h"
23 #include "map.h"
24 #include "camera.h"
25 #include <set>
26 #include <map>
27
28 struct MapDrawControl
29 {
30         // Overrides limits by drawing everything
31         bool range_all = false;
32         // Wanted drawing range
33         float wanted_range = 0.0f;
34         // show a wire frame for debugging
35         bool show_wireframe = false;
36 };
37
38 struct MeshBufList
39 {
40         video::SMaterial m;
41         std::vector<std::pair<v3s16,scene::IMeshBuffer*>> bufs;
42 };
43
44 struct MeshBufListList
45 {
46         /*!
47          * Stores the mesh buffers of the world.
48          * The array index is the material's layer.
49          * The vector part groups vertices by material.
50          */
51         std::vector<MeshBufList> lists[MAX_TILE_LAYERS];
52
53         void clear();
54         void add(scene::IMeshBuffer *buf, v3s16 position, u8 layer);
55 };
56
57 class Client;
58 class ITextureSource;
59 class PartialMeshBuffer;
60
61 /*
62         ClientMap
63
64         This is the only map class that is able to render itself on screen.
65 */
66
67 class ClientMap : public Map, public scene::ISceneNode
68 {
69 public:
70         ClientMap(
71                         Client *client,
72                         RenderingEngine *rendering_engine,
73                         MapDrawControl &control,
74                         s32 id
75         );
76
77         virtual ~ClientMap() = default;
78
79         s32 mapType() const
80         {
81                 return MAPTYPE_CLIENT;
82         }
83
84         void drop()
85         {
86                 ISceneNode::drop();
87         }
88
89         void updateCamera(v3f pos, v3f dir, f32 fov, v3s16 offset);
90
91         /*
92                 Forcefully get a sector from somewhere
93         */
94         MapSector * emergeSector(v2s16 p);
95
96         //void deSerializeSector(v2s16 p2d, std::istream &is);
97
98         /*
99                 ISceneNode methods
100         */
101
102         virtual void OnRegisterSceneNode();
103
104         virtual void render()
105         {
106                 video::IVideoDriver* driver = SceneManager->getVideoDriver();
107                 driver->setTransform(video::ETS_WORLD, AbsoluteTransformation);
108                 renderMap(driver, SceneManager->getSceneNodeRenderPass());
109         }
110
111         virtual const aabb3f &getBoundingBox() const
112         {
113                 return m_box;
114         }
115
116         void getBlocksInViewRange(v3s16 cam_pos_nodes,
117                 v3s16 *p_blocks_min, v3s16 *p_blocks_max, float range=-1.0f);
118         void updateDrawList();
119         void updateDrawListShadow(const v3f &shadow_light_pos, const v3f &shadow_light_dir, float shadow_range);
120         // Returns true if draw list needs updating before drawing the next frame.
121         bool needsUpdateDrawList() { return m_needs_update_drawlist; }
122         void renderMap(video::IVideoDriver* driver, s32 pass);
123
124         void renderMapShadows(video::IVideoDriver *driver,
125                         const video::SMaterial &material, s32 pass, int frame, int total_frames);
126
127         int getBackgroundBrightness(float max_d, u32 daylight_factor,
128                         int oldvalue, bool *sunlight_seen_result);
129
130         void renderPostFx(CameraMode cam_mode);
131
132         // For debug printing
133         virtual void PrintInfo(std::ostream &out);
134
135         const MapDrawControl & getControl() const { return m_control; }
136         f32 getWantedRange() const { return m_control.wanted_range; }
137         f32 getCameraFov() const { return m_camera_fov; }
138
139 private:
140
141         // update the vertex order in transparent mesh buffers
142         void updateTransparentMeshBuffers();
143
144         // Orders blocks by distance to the camera
145         class MapBlockComparer
146         {
147         public:
148                 MapBlockComparer(const v3s16 &camera_block) : m_camera_block(camera_block) {}
149
150                 bool operator() (const v3s16 &left, const v3s16 &right) const
151                 {
152                         auto distance_left = left.getDistanceFromSQ(m_camera_block);
153                         auto distance_right = right.getDistanceFromSQ(m_camera_block);
154                         return distance_left > distance_right || (distance_left == distance_right && left > right);
155                 }
156
157         private:
158                 v3s16 m_camera_block;
159         };
160
161
162         // reference to a mesh buffer used when rendering the map.
163         struct DrawDescriptor {
164                 v3s16 m_pos;
165                 union {
166                         scene::IMeshBuffer *m_buffer;
167                         const PartialMeshBuffer *m_partial_buffer;
168                 };
169                 bool m_reuse_material:1;
170                 bool m_use_partial_buffer:1;
171
172                 DrawDescriptor(v3s16 pos, scene::IMeshBuffer *buffer, bool reuse_material) :
173                         m_pos(pos), m_buffer(buffer), m_reuse_material(reuse_material), m_use_partial_buffer(false)
174                 {}
175
176                 DrawDescriptor(v3s16 pos, const PartialMeshBuffer *buffer) :
177                         m_pos(pos), m_partial_buffer(buffer), m_reuse_material(false), m_use_partial_buffer(true)
178                 {}
179         };
180
181         Client *m_client;
182         RenderingEngine *m_rendering_engine;
183
184         aabb3f m_box = aabb3f(-BS * 1000000, -BS * 1000000, -BS * 1000000,
185                 BS * 1000000, BS * 1000000, BS * 1000000);
186
187         MapDrawControl &m_control;
188
189         v3f m_camera_position = v3f(0,0,0);
190         v3f m_camera_direction = v3f(0,0,1);
191         f32 m_camera_fov = M_PI;
192         v3s16 m_camera_offset;
193         bool m_needs_update_transparent_meshes = true;
194
195         std::map<v3s16, MapBlock*, MapBlockComparer> m_drawlist;
196         std::map<v3s16, MapBlock*> m_drawlist_shadow;
197         bool m_needs_update_drawlist;
198
199         std::set<v2s16> m_last_drawn_sectors;
200
201         bool m_cache_trilinear_filter;
202         bool m_cache_bilinear_filter;
203         bool m_cache_anistropic_filter;
204         bool m_added_to_shadow_renderer{false};
205         u16 m_cache_transparency_sorting_distance;
206 };