Panda3D
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 
32 extern ConfigVariableBool stm_use_hexagonal_layout;
33 extern ConfigVariableInt stm_max_chunk_count;
34 extern ConfigVariableInt stm_max_views;
35 
36 
37 NotifyCategoryDecl(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  */
54 class EXPCL_PANDA_GRUTIL ShaderTerrainMesh : public PandaNode {
55 
56 PUBLISHED:
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 
85 public:
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 
93 private:
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
185 public:
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 
198 private:
199  static TypeHandle _type_handle;
200 };
201 
202 #include "shaderTerrainMesh.I"
203 
204 #endif // SHADER_TERRAIN_MESH_H
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
A basic node of the scene graph or data graph.
Definition: pandaNode.h:64
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
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
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
This is a convenience class to specialize ConfigVariable as a boolean type.
Represents a texture object, which is typically a single 2-d image but may also represent a 1-d or 3-...
Definition: texture.h:71
void register_type(TypeHandle &type_handle, const std::string &name)
This inline function is just a convenient way to call TypeRegistry::register_type(),...
Definition: register_type.I:22
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
This collects together the pieces of data that are accumulated for each node while walking the scene ...
A standard mutex, or mutual exclusion lock.
Definition: pmutex.h:38
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
virtual bool safe_to_combine() const
Returns true if it is generally safe to combine this particular kind of PandaNode with other kinds of...
Definition: pandaNode.cxx:234
This is an abstract class for any volume in any sense which can be said to define the locality of ref...
A lightweight class that represents a single element that may be timed and/or counted via stats.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
A container for geometry primitives.
Definition: geom.h:54
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,...
Definition: pandaNode.cxx:478
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
This is a convenience class to specialize ConfigVariable as an integer type.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
TypeHandle is the identifier used to differentiate C++ class types.
Definition: typeHandle.h:81
virtual bool is_renderable() const
Returns true if there is some value to visiting this particular node during the cull traversal for an...
Definition: pandaNode.cxx:468
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
This object performs a depth-first traversal of the scene graph, with optional view-frustum culling,...
Definition: cullTraverser.h:45
Terrain Renderer class utilizing the GPU.
virtual bool safe_to_flatten() const
Returns true if it is generally safe to flatten out this particular kind of PandaNode by duplicating ...
Definition: pandaNode.cxx:201