Panda3D
sceneGraphAnalyzer.cxx
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 sceneGraphAnalyzer.cxx
10  * @author drose
11  * @date 2000-07-02
12  */
13 
14 #include "sceneGraphAnalyzer.h"
15 #include "config_pgraph.h"
16 
17 #include "indent.h"
18 #include "lodNode.h"
19 #include "geomNode.h"
20 #include "geomVertexData.h"
21 #include "geom.h"
22 #include "geomPrimitive.h"
23 #include "geomPoints.h"
24 #include "geomLines.h"
25 #include "geomLinestrips.h"
26 #include "geomTriangles.h"
27 #include "geomTristrips.h"
28 #include "geomTrifans.h"
29 #include "geomPatches.h"
30 #include "transformState.h"
31 #include "textureAttrib.h"
32 #include "pta_ushort.h"
33 #include "geomVertexReader.h"
34 
35 /**
36  *
37  */
38 SceneGraphAnalyzer::
39 SceneGraphAnalyzer() {
40  _lod_mode = LM_all;
41  clear();
42 }
43 
44 /**
45  *
46  */
47 SceneGraphAnalyzer::
48 ~SceneGraphAnalyzer() {
49 }
50 
51 /**
52  * Resets all of the data in the analyzer in preparation for a new run.
53  */
55 clear() {
56  _nodes.clear();
57  _vdatas.clear();
58  _vformats.clear();
59  _vadatas.clear();
60  _unique_vdatas.clear();
61  _unique_vadatas.clear();
62  _textures.clear();
63 
64  _num_nodes = 0;
65  _num_instances = 0;
66  _num_transforms = 0;
67  _num_nodes_with_attribs = 0;
68  _num_lod_nodes = 0;
69  _num_geom_nodes = 0;
70  _num_geoms = 0;
71  _num_geom_vertex_datas = 0;
72  _num_geom_vertex_formats = 0;
73  _vertex_data_size = 0;
74  _prim_data_size = 0;
75 
76  _num_vertices = 0;
77  _num_vertices_64 = 0;
78  _num_normals = 0;
79  _num_colors = 0;
80  _num_texcoords = 0;
81  _num_tris = 0;
82  _num_lines = 0;
83  _num_points = 0;
84  _num_patches = 0;
85 
86  _num_individual_tris = 0;
87  _num_tristrips = 0;
88  _num_triangles_in_strips = 0;
89  _num_trifans = 0;
90  _num_triangles_in_fans = 0;
91  _num_vertices_in_patches = 0;
92 
93  _texture_bytes = 0;
94 
95  _num_long_normals = 0;
96  _num_short_normals = 0;
97  _total_normal_length = 0.0f;
98 }
99 
100 /**
101  * Adds a new node to the set of data for analysis. Normally, this would only
102  * be called once, and passed the top of the scene graph, but it's possible to
103  * repeatedly pass in subgraphs to get an analysis of all the graphs together.
104  */
107  collect_statistics(node, false);
108 }
109 
110 /**
111  * Describes all the data collected.
112  */
114 write(std::ostream &out, int indent_level) const {
115  indent(out, indent_level)
116  << _num_nodes << " total nodes (including "
117  << _num_instances << " instances); " << _num_lod_nodes << " LODNodes.\n";
118 
119  indent(out, indent_level)
120  << _num_transforms << " transforms";
121 
122  if (_num_nodes != 0) {
123  out << "; " << 100 * _num_nodes_with_attribs / _num_nodes
124  << "% of nodes have some render attribute.";
125  }
126  out << "\n";
127 
128  indent(out, indent_level)
129  << _num_geoms << " Geoms, with " << _num_geom_vertex_datas
130  << " GeomVertexDatas and " << _num_geom_vertex_formats
131  << " GeomVertexFormats, appear on " << _num_geom_nodes
132  << " GeomNodes.\n";
133 
134  indent(out, indent_level);
135  if (_num_vertices_64 != 0) {
136  out << _num_vertices_64 << " 64-bit vertices, ";
137  if (_num_vertices != _num_vertices_64) {
138  out << _num_vertices - _num_vertices_64 << " 32-bit vertices, ";
139  }
140  } else {
141  out << _num_vertices << " vertices, ";
142  }
143 
144  out << _num_normals << " normals, "
145  << _num_colors << " colors, "
146  << _num_texcoords << " texture coordinates.\n";
147 
148  if (_num_long_normals != 0 || _num_short_normals != 0) {
149  indent(out, indent_level)
150  << _num_long_normals << " normals are too long, "
151  << _num_short_normals << " are too short. Average normal length is "
152  << _total_normal_length / (PN_stdfloat)_num_normals << "\n";
153  }
154 
155  indent(out, indent_level)
156  << "GeomVertexData arrays occupy " << (_vertex_data_size + 1023) / 1024
157  << "K memory.\n";
158 
159  indent(out, indent_level)
160  << "GeomPrimitive arrays occupy " << (_prim_data_size + 1023) / 1024
161  << "K memory.\n";
162 
163  int unreferenced_vertices = 0;
164  VDatas::const_iterator vdi;
165  for (vdi = _vdatas.begin(); vdi != _vdatas.end(); ++vdi) {
166  CPT(GeomVertexData) vdata = (*vdi).first;
167  const VDataTracker &tracker = (*vdi).second;
168  int num_unreferenced = vdata->get_num_rows() - tracker._referenced_vertices.get_num_on_bits();
169  nassertv(num_unreferenced >= 0);
170  unreferenced_vertices += num_unreferenced;
171  }
172  if (unreferenced_vertices != 0) {
173  indent(out, indent_level)
174  << unreferenced_vertices << " vertices are unreferenced by any GeomPrimitives.\n";
175  }
176  if (_unique_vdatas.size() != _vdatas.size()) {
177  indent(out, indent_level)
178  << _vdatas.size() - _unique_vdatas.size()
179  << " GeomVertexDatas are redundantly duplicated\n";
180  }
181  if (_unique_vadatas.size() != _vadatas.size()) {
182  int wasted_bytes = 0;
183 
184  UniqueVADatas::const_iterator uvai;
185  for (uvai = _unique_vadatas.begin();
186  uvai != _unique_vadatas.end();
187  ++uvai) {
188  const GeomVertexArrayData *gvad = (*uvai).first;
189  int dup_count = (*uvai).second;
190  if (dup_count > 1) {
191  wasted_bytes += (dup_count - 1) * gvad->get_data_size_bytes();
192  }
193  }
194  indent(out, indent_level)
195  << _vadatas.size() - _unique_vadatas.size()
196  << " GeomVertexArrayDatas are redundant, wasting "
197  << (wasted_bytes + 1023) / 1024 << "K.\n";
198  }
199  if (_unique_prim_vadatas.size() != _prim_vadatas.size()) {
200  int wasted_bytes = 0;
201 
202  UniqueVADatas::const_iterator uvai;
203  for (uvai = _unique_prim_vadatas.begin();
204  uvai != _unique_prim_vadatas.end();
205  ++uvai) {
206  const GeomVertexArrayData *gvad = (*uvai).first;
207  int dup_count = (*uvai).second;
208  if (dup_count > 1) {
209  wasted_bytes += (dup_count - 1) * gvad->get_data_size_bytes();
210  }
211  }
212  indent(out, indent_level)
213  << _prim_vadatas.size() - _unique_prim_vadatas.size()
214  << " GeomPrimitive arrays are redundant, wasting "
215  << (wasted_bytes + 1023) / 1024 << "K.\n";
216  }
217 
218  indent(out, indent_level)
219  << _num_tris << " triangles:\n";
220  indent(out, indent_level + 2)
221  << _num_triangles_in_strips
222  << " of these are on " << _num_tristrips << " tristrips";
223  if (_num_tristrips != 0) {
224  out << " ("
225  << (double)_num_triangles_in_strips / (double)_num_tristrips
226  << " average tris per strip)";
227  }
228  out << ".\n";
229 
230  if (_num_trifans != 0) {
231  indent(out, indent_level + 2)
232  << _num_triangles_in_fans
233  << " of these are on " << _num_trifans << " trifans";
234  if (_num_trifans != 0) {
235  out << " ("
236  << (double)_num_triangles_in_fans / (double)_num_trifans
237  << " average tris per fan)";
238  }
239  out << ".\n";
240  }
241 
242  indent(out, indent_level + 2)
243  << _num_individual_tris
244  << " of these are independent triangles.\n";
245 
246  if (_num_patches != 0) {
247  indent(out, indent_level)
248  << _num_patches << " patches ("
249  << (double)_num_vertices_in_patches / (double)_num_patches
250  << " average verts per patch).\n";
251  }
252 
253  if (_num_lines != 0 || _num_points != 0) {
254  indent(out, indent_level)
255  << _num_lines << " lines, " << _num_points << " points.\n";
256  }
257 
258  indent(out, indent_level)
259  << _textures.size() << " textures, estimated minimum "
260  << (_texture_bytes + 1023) / 1024 << "K texture memory required.\n";
261 }
262 
263 /**
264  * Recursively visits each node, counting up the statistics.
265  */
266 void SceneGraphAnalyzer::
267 collect_statistics(PandaNode *node, bool under_instance) {
268  _num_nodes++;
269 
270  if (!under_instance) {
271  Nodes::iterator ni = _nodes.find(node);
272  if (ni == _nodes.end()) {
273  // This is the first time this node has been encountered.
274  _nodes.insert(Nodes::value_type(node, 1));
275  } else {
276  // This node has been encountered before; that makes it an instance.
277  (*ni).second++;
278  _num_instances++;
279  under_instance = true;
280  }
281  }
282 
283  if (!node->get_state()->is_empty()) {
284  _num_nodes_with_attribs++;
285  const RenderAttrib *attrib =
286  node->get_attrib(TextureAttrib::get_class_slot());
287  if (attrib != nullptr) {
288  const TextureAttrib *ta = DCAST(TextureAttrib, attrib);
289  for (int i = 0; i < ta->get_num_on_stages(); i++) {
290  collect_statistics(ta->get_on_texture(ta->get_on_stage(i)));
291  }
292  }
293  }
294  if (!node->get_transform()->is_identity()) {
295  _num_transforms++;
296  }
297 
298  if (node->is_geom_node()) {
299  collect_statistics(DCAST(GeomNode, node));
300  }
301 
302  if (node->is_lod_node()) {
303  LODNode *lod_node = DCAST(LODNode, node);
304  ++_num_lod_nodes;
305 
306  switch (_lod_mode) {
307  case LM_lowest:
308  case LM_highest:
309  {
310  int sw = (_lod_mode == LM_lowest) ? lod_node->get_lowest_switch() : lod_node->get_highest_switch();
311  if (sw >= 0 && sw < node->get_num_children()) {
312  PandaNode *child = node->get_child(sw);
313  collect_statistics(child, under_instance);
314  }
315  return;
316  }
317 
318  case LM_none:
319  return;
320 
321  case LM_all:
322  // fall through to the loop below.
323  break;
324  }
325  }
326 
327  int num_children = node->get_num_children();
328  for (int i = 0; i < num_children; i++) {
329  PandaNode *child = node->get_child(i);
330  collect_statistics(child, under_instance);
331  }
332 }
333 
334 /**
335  * Recursively visits each node, counting up the statistics.
336  */
337 void SceneGraphAnalyzer::
338 collect_statistics(GeomNode *geom_node) {
339  nassertv(geom_node != nullptr);
340 
341  ++_num_geom_nodes;
342 
343  int num_geoms = geom_node->get_num_geoms();
344  _num_geoms += num_geoms;
345 
346  for (int i = 0; i < num_geoms; i++) {
347  const Geom *geom = geom_node->get_geom(i);
348  collect_statistics(geom);
349 
350  const RenderState *geom_state = geom_node->get_geom_state(i);
351 
352  const RenderAttrib *attrib =
353  geom_state->get_attrib(TextureAttrib::get_class_slot());
354  if (attrib != nullptr) {
355  const TextureAttrib *ta = DCAST(TextureAttrib, attrib);
356  for (int i = 0; i < ta->get_num_on_stages(); i++) {
357  collect_statistics(ta->get_on_texture(ta->get_on_stage(i)));
358  }
359  }
360  }
361 }
362 
363 /**
364  * Recursively visits each node, counting up the statistics.
365  */
366 void SceneGraphAnalyzer::
367 collect_statistics(const Geom *geom) {
368  CPT(GeomVertexData) vdata = geom->get_vertex_data();
369  std::pair<VDatas::iterator, bool> result = _vdatas.insert(VDatas::value_type(vdata, VDataTracker()));
370  if (result.second) {
371  // This is the first time we've encountered this vertex data.
372  ++_num_geom_vertex_datas;
373 
374  CPT(GeomVertexFormat) vformat = vdata->get_format();
375  bool format_inserted = _vformats.insert(vformat).second;
376  if (format_inserted) {
377  // This is the first time we've encountered this vertex format.
378  ++_num_geom_vertex_formats;
379  }
380 
381  int &dup_count = (*(_unique_vdatas.insert(UniqueVDatas::value_type(vdata, 0)).first)).second;
382  ++dup_count;
383 
384  int num_rows = vdata->get_num_rows();
385  const GeomVertexFormat *format = vdata->get_format();
386  if (format->has_column(InternalName::get_vertex())) {
387  _num_vertices += num_rows;
388  const GeomVertexColumn *vcolumn = format->get_column(InternalName::get_vertex());
389  if (vcolumn->get_numeric_type() == GeomEnums::NT_float64) {
390  _num_vertices_64 += num_rows;
391  }
392  }
393  if (format->has_column(InternalName::get_normal())) {
394  _num_normals += num_rows;
395  GeomVertexReader rnormal(vdata, InternalName::get_normal());
396  while (!rnormal.is_at_end()) {
397  LVector3f normal = rnormal.get_data3f();
398  float length = normal.length();
399  if (IS_NEARLY_EQUAL(length, 1.0f)) {
400  // Correct length normal.
401  } else if (length > 1.0f) {
402  ++_num_long_normals;
403  } else { // length < 1.0f
404  ++_num_short_normals;
405  }
406  _total_normal_length += length;
407  }
408  }
409  if (format->has_column(InternalName::get_color())) {
410  _num_colors += num_rows;
411  }
412  int num_texcoords = format->get_num_texcoords();
413  _num_texcoords += num_rows * num_texcoords;
414 
415  int num_arrays = vdata->get_num_arrays();
416  for (int i = 0; i < num_arrays; ++i) {
417  collect_statistics(vdata->get_array(i));
418  }
419  }
420  VDataTracker &tracker = (*(result.first)).second;
421 
422  // Now consider the primitives in the Geom.
423  int num_primitives = geom->get_num_primitives();
424  for (int i = 0; i < num_primitives; ++i) {
425  CPT(GeomPrimitive) prim = geom->get_primitive(i);
426 
427  int num_vertices = prim->get_num_vertices();
428  int strip_cut_index = prim->get_strip_cut_index();
429  for (int vi = 0; vi < num_vertices; ++vi) {
430  int index = prim->get_vertex(vi);
431  if (index != strip_cut_index) {
432  tracker._referenced_vertices.set_bit(index);
433  }
434  }
435 
436  if (prim->is_indexed()) {
437  collect_prim_statistics(prim->get_vertices());
438  if (prim->is_composite()) {
439  collect_statistics(prim->get_mins());
440  collect_statistics(prim->get_maxs());
441  }
442  }
443 
444  if (prim->is_of_type(GeomPoints::get_class_type())) {
445  _num_points += prim->get_num_primitives();
446 
447  } else if (prim->is_of_type(GeomLines::get_class_type())) {
448  _num_lines += prim->get_num_primitives();
449 
450  } else if (prim->is_of_type(GeomLinestrips::get_class_type())) {
451  _num_lines += prim->get_num_faces();
452 
453  } else if (prim->is_of_type(GeomTriangles::get_class_type())) {
454  _num_tris += prim->get_num_primitives();
455  _num_individual_tris += prim->get_num_primitives();
456 
457  } else if (prim->is_of_type(GeomTristrips::get_class_type())) {
458  _num_tris += prim->get_num_faces();
459  _num_tristrips += prim->get_num_primitives();
460  _num_triangles_in_strips += prim->get_num_faces();
461 
462  } else if (prim->is_of_type(GeomTrifans::get_class_type())) {
463  _num_tris += prim->get_num_faces();
464  _num_trifans += prim->get_num_primitives();
465  _num_triangles_in_fans += prim->get_num_faces();
466 
467  } else if (prim->is_of_type(GeomPatches::get_class_type())) {
468  _num_patches += prim->get_num_primitives();
469  _num_vertices_in_patches += prim->get_num_vertices();
470 
471  } else {
472  pgraph_cat.warning()
473  << "Unknown GeomPrimitive type in SceneGraphAnalyzer: "
474  << prim->get_type() << "\n";
475  }
476  }
477 }
478 
479 /**
480  * Recursively visits each node, counting up the statistics.
481  */
482 void SceneGraphAnalyzer::
483 collect_statistics(Texture *texture) {
484  nassertv(texture != nullptr);
485 
486  Textures::iterator ti = _textures.find(texture);
487  if (ti == _textures.end()) {
488  // This is the first time this texture has been encountered.
489  _textures.insert(Textures::value_type(texture, 1));
490 
491  // Attempt to guess how many bytes of texture memory this one requires.
492  size_t bytes =
493  texture->get_x_size() * texture->get_y_size() *
494  texture->get_num_components() * texture->get_component_width();
495 
496  if (texture->uses_mipmaps()) {
497  bytes *= 4/3;
498  }
499 
500  _texture_bytes += bytes;
501 
502  } else {
503  // This texture has been encountered before; don't count it again.
504  (*ti).second++;
505  }
506 }
507 
508 /**
509  * Recursively visits each node, counting up the statistics.
510  */
511 void SceneGraphAnalyzer::
512 collect_statistics(const GeomVertexArrayData *vadata) {
513  nassertv(vadata != nullptr);
514  bool inserted = _vadatas.insert(vadata).second;
515  if (inserted) {
516  // This is the first time we've encountered this vertex array.
517  _vertex_data_size += vadata->get_data_size_bytes();
518  int &dup_count = (*(_unique_vadatas.insert(UniqueVADatas::value_type(vadata, 0)).first)).second;
519  ++dup_count;
520  }
521 }
522 
523 /**
524  * Recursively visits each node, counting up the statistics. This one records
525  * the vertex index array associated with a GeomPrimitive, as opposed to the
526  * vertex data array, component of a GeomVertexData.
527  */
528 void SceneGraphAnalyzer::
529 collect_prim_statistics(const GeomVertexArrayData *vadata) {
530  nassertv(vadata != nullptr);
531  bool inserted = _prim_vadatas.insert(vadata).second;
532  if (inserted) {
533  // This is the first time we've encountered this vertex array.
534  _prim_data_size += vadata->get_data_size_bytes();
535  int &dup_count = (*(_unique_prim_vadatas.insert(UniqueVADatas::value_type(vadata, 0)).first)).second;
536  ++dup_count;
537  }
538 }
PandaNode::is_lod_node
virtual bool is_lod_node() const
A simple downcast check.
Definition: pandaNode.cxx:2074
Geom
A container for geometry primitives.
Definition: geom.h:54
geomVertexData.h
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
indent
std::ostream & indent(std::ostream &out, int indent_level)
A handy function for doing text formatting.
Definition: indent.cxx:20
geomTrifans.h
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PandaNode::is_geom_node
virtual bool is_geom_node() const
A simple downcast check.
Definition: pandaNode.cxx:2062
GeomVertexArrayData
This is the data for one array of a GeomVertexData structure.
Definition: geomVertexArrayData.h:58
LODNode::get_lowest_switch
get_lowest_switch
Returns the index number of the child with the lowest level of detail; that is, the one that is desig...
Definition: lodNode.h:80
GeomVertexData
This defines the actual numeric vertex data stored in a Geom, in the structure defined by a particula...
Definition: geomVertexData.h:68
GeomVertexFormat::get_num_texcoords
get_num_texcoords
Returns the number of columns within the format that represent texture coordinates.
Definition: geomVertexFormat.h:114
geomVertexReader.h
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
LODNode
A Level-of-Detail node.
Definition: lodNode.h:28
sceneGraphAnalyzer.h
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
GeomVertexFormat::get_column
get_column
Returns the ith column of the specification, across all arrays.
Definition: geomVertexFormat.h:97
TextureAttrib::get_on_texture
get_on_texture
Returns the texture associated with the indicated stage, or NULL if no texture is associated.
Definition: textureAttrib.h:69
RenderAttrib
This is the base class for a number of render attributes (other than transform) that may be set on sc...
Definition: renderAttrib.h:51
SceneGraphAnalyzer::write
void write(std::ostream &out, int indent_level=0) const
Describes all the data collected.
Definition: sceneGraphAnalyzer.cxx:114
GeomVertexReader
This object provides a high-level interface for quickly reading a sequence of numeric values from a v...
Definition: geomVertexReader.h:47
geomLines.h
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
Texture
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
Texture::get_x_size
get_x_size
Returns the width of the texture image in texels.
Definition: texture.h:334
GeomNode::get_num_geoms
get_num_geoms
Returns the number of geoms in the node.
Definition: geomNode.h:71
RenderState
This represents a unique collection of RenderAttrib objects that correspond to a particular renderabl...
Definition: renderState.h:47
GeomNode
A node that holds Geom objects, renderable pieces of geometry.
Definition: geomNode.h:34
transformState.h
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
SceneGraphAnalyzer::add_node
void add_node(PandaNode *node)
Adds a new node to the set of data for analysis.
Definition: sceneGraphAnalyzer.cxx:106
pta_ushort.h
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
lodNode.h
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PandaNode::get_child
get_child
Returns the nth child node of this node.
Definition: pandaNode.h:124
geomPrimitive.h
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
geomTriangles.h
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
SceneGraphAnalyzer::clear
void clear()
Resets all of the data in the analyzer in preparation for a new run.
Definition: sceneGraphAnalyzer.cxx:55
geom.h
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
Texture::uses_mipmaps
bool uses_mipmaps() const
Returns true if the minfilter settings on this texture indicate the use of mipmapping,...
Definition: texture.I:1127
GeomVertexColumn::get_numeric_type
NumericType get_numeric_type() const
Returns the token representing the numeric type of the data storage.
Definition: geomVertexColumn.I:116
Texture::get_component_width
get_component_width
Returns the number of bytes stored for each color component of a texel.
Definition: texture.h:356
GeomVertexFormat
This class defines the physical layout of the vertex data stored within a Geom.
Definition: geomVertexFormat.h:55
TextureAttrib::get_num_on_stages
get_num_on_stages
Returns the number of stages that are turned on by the attribute.
Definition: textureAttrib.h:55
geomPatches.h
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
LODNode::get_highest_switch
get_highest_switch
Returns the index number of the child with the highest level of detail; that is, the one that is desi...
Definition: lodNode.h:81
textureAttrib.h
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
GeomVertexFormat::has_column
has_column
Returns true if the format has the named column, false otherwise.
Definition: geomVertexFormat.h:129
GeomVertexArrayData::get_data_size_bytes
get_data_size_bytes
Returns the number of bytes stored in the array.
Definition: geomVertexArrayData.h:92
geomLinestrips.h
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
TextureAttrib::get_on_stage
get_on_stage
Returns the nth stage turned on by the attribute, sorted in render order.
Definition: textureAttrib.h:55
geomTristrips.h
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
geomPoints.h
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
GeomVertexColumn
This defines how a single column is interleaved within a vertex array stored within a Geom.
Definition: geomVertexColumn.h:37
GeomNode::get_geom_state
get_geom_state
Returns the RenderState associated with the nth geom of the node.
Definition: geomNode.h:75
geomNode.h
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
indent.h
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
Texture::get_y_size
get_y_size
Returns the height of the texture image in texels.
Definition: texture.h:338
PandaNode::get_num_children
get_num_children
Returns the number of child nodes this node has.
Definition: pandaNode.h:124
PandaNode
A basic node of the scene graph or data graph.
Definition: pandaNode.h:64
TextureAttrib
Indicates the set of TextureStages and their associated Textures that should be applied to (or remove...
Definition: textureAttrib.h:31
config_pgraph.h
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
GeomPrimitive
This is an abstract base class for a family of classes that represent the fundamental geometry primit...
Definition: geomPrimitive.h:56
Texture::get_num_components
get_num_components
Returns the number of color components for each texel of the texture image.
Definition: texture.h:355