Panda3D
Loading...
Searching...
No Matches
shaderTerrainMesh.h
Go to the documentation of this file.
1/**
2 * PANDA 3D SOFTWARE
3 * Copyright (c) Carnegie Mellon University. All rights reserved.
4 *
5 * All use of this software is subject to the terms of the revised BSD
6 * license. You should have received a copy of this license along
7 * with this source code in a file named "LICENSE."
8 *
9 * @file shaderTerrainMesh.h
10 * @author tobspr
11 * @date 2016-02-16
12 */
13
14#ifndef SHADER_TERRAIN_MESH_H
15#define SHADER_TERRAIN_MESH_H
16
17#include "pandabase.h"
18#include "luse.h"
19#include "pnmImage.h"
20#include "geom.h"
21#include "pandaNode.h"
22#include "texture.h"
23#include "texturePeeker.h"
24#include "configVariableBool.h"
25#include "configVariableInt.h"
26#include "pStatCollector.h"
27#include "filename.h"
28#include "pmutex.h"
29#include "mutexHolder.h"
30#include <stdint.h>
31
32extern ConfigVariableBool stm_use_hexagonal_layout;
33extern ConfigVariableInt stm_max_chunk_count;
34extern ConfigVariableInt stm_max_views;
35
36
37NotifyCategoryDecl(shader_terrain, EXPCL_PANDA_GRUTIL, EXPTP_PANDA_GRUTIL);
38
39
40/**
41 * @brief Terrain Renderer class utilizing the GPU
42 * @details This class provides functionality to render heightfields of large
43 * sizes utilizing the GPU. Internally a quadtree is used to generate the LODs.
44 * The final terrain is then rendered using instancing on the GPU. This makes
45 * it possible to use very large heightfields (8192+) with very reasonable
46 * performance. The terrain provides options to control the LOD using a
47 * target triangle width, see ShaderTerrainMesh::set_target_triangle_width().
48 *
49 * Because the Terrain is rendered entirely on the GPU, it needs a special
50 * vertex shader. There is a default vertex shader available, which you can
51 * use in your own shaders. IMPORTANT: If you don't set an appropriate shader
52 * on the terrain, nothing will be visible.
53 */
54class EXPCL_PANDA_GRUTIL ShaderTerrainMesh : public PandaNode {
55
56PUBLISHED:
57
59
60 INLINE void set_heightfield(Texture* heightfield);
61 INLINE Texture* get_heightfield() const;
62 MAKE_PROPERTY(heightfield, get_heightfield, set_heightfield);
63
64 INLINE void set_chunk_size(size_t chunk_size);
65 INLINE size_t get_chunk_size() const;
66 MAKE_PROPERTY(chunk_size, get_chunk_size, set_chunk_size);
67
68 INLINE void set_generate_patches(bool generate_patches);
69 INLINE bool get_generate_patches() const;
70 MAKE_PROPERTY(generate_patches, get_generate_patches, set_generate_patches);
71
72 INLINE void set_update_enabled(bool update_enabled);
73 INLINE bool get_update_enabled() const;
74 MAKE_PROPERTY(update_enabled, get_update_enabled, set_update_enabled);
75
76 INLINE void set_target_triangle_width(PN_stdfloat target_triangle_width);
77 INLINE PN_stdfloat get_target_triangle_width() const;
78 MAKE_PROPERTY(target_triangle_width, get_target_triangle_width, set_target_triangle_width);
79
80 LPoint3 uv_to_world(const LTexCoord& coord) const;
81 INLINE LPoint3 uv_to_world(PN_stdfloat u, PN_stdfloat v) const;
82
83 bool generate();
84
85public:
86
87 // Methods derived from PandaNode
88 virtual bool is_renderable() const;
89 virtual bool safe_to_flatten() const;
90 virtual bool safe_to_combine() const;
91 virtual void add_for_draw(CullTraverser *trav, CullTraverserData &data);
92
93private:
94
95 // Chunk data
96 struct Chunk {
97 // Depth, starting at 0
98 size_t depth;
99
100 // Chunk position in heightfield space
101 size_t x, y;
102
103 // Chunk size in heightfield space
104 size_t size;
105
106 // Children, in the order (0, 0) (1, 0) (0, 1) (1, 1)
107 Chunk* children[4];
108
109 // Chunk heights, used for culling
110 PN_stdfloat avg_height, min_height, max_height;
111
112 // Edge heights, used for lod computation, in the same order as the children
113 LVector4 edges;
114
115 // Last CLOD factor, stored while computing LOD, used for seamless transitions between lods
116 PN_stdfloat last_clod;
117
118 INLINE void clear_children();
119 INLINE Chunk();
120 INLINE ~Chunk();
121 };
122
123
124 // Single entry in the data block
125 struct ChunkDataEntry {
126 // float x, y, size, clod;
127
128 // Panda uses BGRA, the above layout shows how its actually in texture memory,
129 // the layout below makes it work with BGRA.
130 PN_float32 size, y, x, clod;
131 };
132
133 // Data used while traversing all chunks
134 struct TraversalData {
135 // Global MVP used for LOD
136 LMatrix4 mvp_mat;
137
138 // Local model matrix used for culling
139 LMatrix4 model_mat;
140
141 // Camera bounds in world space
142 BoundingVolume* cam_bounds;
143
144 // Amount of emitted chunks so far
145 int emitted_chunks;
146
147 // Screen resolution, used for LOD
148 LVector2i screen_size;
149
150 // Pointer to the texture memory, where each chunk is written to
151 ChunkDataEntry* storage_ptr;
152 };
153
154 bool do_check_heightfield();
155 void do_extract_heightfield();
156 void do_init_data_texture();
157 void do_create_chunks();
158 void do_init_chunk(Chunk* chunk);
159 void do_compute_bounds(Chunk* chunk);
160 void do_create_chunk_geom();
161 void do_traverse(Chunk* chunk, TraversalData* data, bool fully_visible = false);
162 void do_emit_chunk(Chunk* chunk, TraversalData* data);
163 bool do_check_lod_matches(Chunk* chunk, TraversalData* data);
164
165 Mutex _lock;
166 Chunk _base_chunk;
167 size_t _size;
168 size_t _chunk_size;
169 bool _generate_patches;
170 PNMImage _heightfield;
171 PT(Texture) _heightfield_tex;
172 PT(Geom) _chunk_geom;
173 PT(Texture) _data_texture;
174 size_t _current_view_index;
175 int _last_frame_count;
176 PN_stdfloat _target_triangle_width;
177 bool _update_enabled;
178
179 // PStats stuff
180 static PStatCollector _lod_collector;
181 static PStatCollector _basic_collector;
182
183
184// Type handle stuff
185public:
186 static TypeHandle get_class_type() {
187 return _type_handle;
188 }
189 static void init_type() {
190 PandaNode::init_type();
191 register_type(_type_handle, "ShaderTerrainMesh", PandaNode::get_class_type());
192 }
193 virtual TypeHandle get_type() const {
194 return get_class_type();
195 }
196 virtual TypeHandle force_init_type() {init_type(); return get_class_type();}
197
198private:
199 static TypeHandle _type_handle;
200};
201
202#include "shaderTerrainMesh.I"
203
204#endif // SHADER_TERRAIN_MESH_H
This is an abstract class for any volume in any sense which can be said to define the locality of ref...
This is a convenience class to specialize ConfigVariable as a boolean type.
This is a convenience class to specialize ConfigVariable as an integer type.
This collects together the pieces of data that are accumulated for each node while walking the scene ...
This object performs a depth-first traversal of the scene graph, with optional view-frustum culling,...
A container for geometry primitives.
Definition geom.h:54
A standard mutex, or mutual exclusion lock.
Definition pmutex.h:40
The name of this class derives from the fact that we originally implemented it as a layer on top of t...
Definition pnmImage.h:58
A lightweight class that represents a single element that may be timed and/or counted via stats.
A basic node of the scene graph or data graph.
Definition pandaNode.h:65
virtual bool safe_to_combine() const
Returns true if it is generally safe to combine this particular kind of PandaNode with other kinds of...
virtual bool is_renderable() const
Returns true if there is some value to visiting this particular node during the cull traversal for an...
virtual void add_for_draw(CullTraverser *trav, CullTraverserData &data)
Adds the node's contents to the CullResult we are building up during the cull traversal,...
virtual bool safe_to_flatten() const
Returns true if it is generally safe to flatten out this particular kind of PandaNode by duplicating ...
Terrain Renderer class utilizing the GPU.
Represents a texture object, which is typically a single 2-d image but may also represent a 1-d or 3-...
Definition texture.h:72
TypeHandle is the identifier used to differentiate C++ class types.
Definition typeHandle.h:81
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
void register_type(TypeHandle &type_handle, const std::string &name)
This inline function is just a convenient way to call TypeRegistry::register_type(),...
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.