]> git.lizzy.rs Git - minetest.git/blob - src/client/clientmap.h
8x block meshes (#13133)
[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         // Wanted drawing range
31         float wanted_range = 0.0f;
32         // Overrides limits by drawing everything
33         bool range_all = false;
34         // Allow rendering out of bounds
35         bool allow_noclip = false;
36         // show a wire frame for debugging
37         bool show_wireframe = false;
38 };
39
40 struct MeshBufList
41 {
42         video::SMaterial m;
43         std::vector<std::pair<v3s16,scene::IMeshBuffer*>> bufs;
44 };
45
46 struct MeshBufListList
47 {
48         /*!
49          * Stores the mesh buffers of the world.
50          * The array index is the material's layer.
51          * The vector part groups vertices by material.
52          */
53         std::vector<MeshBufList> lists[MAX_TILE_LAYERS];
54
55         void clear();
56         void add(scene::IMeshBuffer *buf, v3s16 position, u8 layer);
57 };
58
59 class Client;
60 class ITextureSource;
61 class PartialMeshBuffer;
62
63 /*
64         ClientMap
65
66         This is the only map class that is able to render itself on screen.
67 */
68
69 class ClientMap : public Map, public scene::ISceneNode
70 {
71 public:
72         ClientMap(
73                         Client *client,
74                         RenderingEngine *rendering_engine,
75                         MapDrawControl &control,
76                         s32 id
77         );
78
79         virtual ~ClientMap();
80
81         bool maySaveBlocks() override
82         {
83                 return false;
84         }
85
86         void drop() override
87         {
88                 ISceneNode::drop(); // calls destructor
89         }
90
91         void updateCamera(v3f pos, v3f dir, f32 fov, v3s16 offset);
92
93         /*
94                 Forcefully get a sector from somewhere
95         */
96         MapSector * emergeSector(v2s16 p) override;
97
98         /*
99                 ISceneNode methods
100         */
101
102         virtual void OnRegisterSceneNode() override;
103
104         virtual void render() override
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 override
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         // @brief Calculate statistics about the map and keep the blocks alive
120         void touchMapBlocks();
121         void updateDrawListShadow(v3f shadow_light_pos, v3f shadow_light_dir, float radius, float length);
122         // Returns true if draw list needs updating before drawing the next frame.
123         bool needsUpdateDrawList() { return m_needs_update_drawlist; }
124         void renderMap(video::IVideoDriver* driver, s32 pass);
125
126         void renderMapShadows(video::IVideoDriver *driver,
127                         const video::SMaterial &material, s32 pass, int frame, int total_frames);
128
129         int getBackgroundBrightness(float max_d, u32 daylight_factor,
130                         int oldvalue, bool *sunlight_seen_result);
131
132         void renderPostFx(CameraMode cam_mode);
133
134         // For debug printing
135         void PrintInfo(std::ostream &out) override;
136
137         const MapDrawControl & getControl() const { return m_control; }
138         f32 getWantedRange() const { return m_control.wanted_range; }
139         f32 getCameraFov() const { return m_camera_fov; }
140
141         void onSettingChanged(const std::string &name);
142
143 protected:
144         void reportMetrics(u64 save_time_us, u32 saved_blocks, u32 all_blocks) override;
145 private:
146
147         // update the vertex order in transparent mesh buffers
148         void updateTransparentMeshBuffers();
149
150
151         // Orders blocks by distance to the camera
152         class MapBlockComparer
153         {
154         public:
155                 MapBlockComparer(const v3s16 &camera_block) : m_camera_block(camera_block) {}
156
157                 bool operator() (const v3s16 &left, const v3s16 &right) const
158                 {
159                         auto distance_left = left.getDistanceFromSQ(m_camera_block);
160                         auto distance_right = right.getDistanceFromSQ(m_camera_block);
161                         return distance_left > distance_right || (distance_left == distance_right && left > right);
162                 }
163
164         private:
165                 v3s16 m_camera_block;
166         };
167
168
169         // reference to a mesh buffer used when rendering the map.
170         struct DrawDescriptor {
171                 v3s16 m_pos;
172                 union {
173                         scene::IMeshBuffer *m_buffer;
174                         const PartialMeshBuffer *m_partial_buffer;
175                 };
176                 bool m_reuse_material:1;
177                 bool m_use_partial_buffer:1;
178
179                 DrawDescriptor(v3s16 pos, scene::IMeshBuffer *buffer, bool reuse_material) :
180                         m_pos(pos), m_buffer(buffer), m_reuse_material(reuse_material), m_use_partial_buffer(false)
181                 {}
182
183                 DrawDescriptor(v3s16 pos, const PartialMeshBuffer *buffer) :
184                         m_pos(pos), m_partial_buffer(buffer), m_reuse_material(false), m_use_partial_buffer(true)
185                 {}
186
187                 scene::IMeshBuffer* getBuffer();
188                 void draw(video::IVideoDriver* driver);
189         };
190
191         Client *m_client;
192         RenderingEngine *m_rendering_engine;
193
194         aabb3f m_box = aabb3f(-BS * 1000000, -BS * 1000000, -BS * 1000000,
195                 BS * 1000000, BS * 1000000, BS * 1000000);
196
197         MapDrawControl &m_control;
198
199         v3f m_camera_position = v3f(0,0,0);
200         v3f m_camera_direction = v3f(0,0,1);
201         f32 m_camera_fov = M_PI;
202         v3s16 m_camera_offset;
203         bool m_needs_update_transparent_meshes = true;
204
205         std::map<v3s16, MapBlock*, MapBlockComparer> m_drawlist;
206         std::map<v3s16, MapBlock*> m_drawlist_shadow;
207         bool m_needs_update_drawlist;
208
209         std::set<v2s16> m_last_drawn_sectors;
210
211         bool m_cache_trilinear_filter;
212         bool m_cache_bilinear_filter;
213         bool m_cache_anistropic_filter;
214         u16 m_cache_transparency_sorting_distance;
215
216         bool m_new_occlusion_culler;
217         bool m_enable_raytraced_culling;
218 };