diff --git a/panda/src/display/graphicsEngine.cxx b/panda/src/display/graphicsEngine.cxx index 446a623371..9e2295f824 100644 --- a/panda/src/display/graphicsEngine.cxx +++ b/panda/src/display/graphicsEngine.cxx @@ -194,6 +194,11 @@ make_gsg(GraphicsPipe *pipe, const FrameBufferProperties &properties, gsg->_threading_model = get_threading_model(); gsg->_pipe = pipe; gsg->_engine = this; + + // If there was no global GSG previously, this becomes the one. + if (GraphicsStateGuardian::get_global_gsg() == NULL) { + gsg->make_global_gsg(); + } } return gsg; diff --git a/panda/src/display/graphicsStateGuardian.I b/panda/src/display/graphicsStateGuardian.I index f2b3245704..77d5a880c2 100644 --- a/panda/src/display/graphicsStateGuardian.I +++ b/panda/src/display/graphicsStateGuardian.I @@ -163,6 +163,44 @@ get_threading_model() const { return _threading_model; } +//////////////////////////////////////////////////////////////////// +// Function: GraphicsStateGuardian::prefers_triangle_strips +// Access: Published +// Description: Returns true if this GSG strongly prefers triangle +// strips to individual triangles (such as SGI), or +// false if it prefers to minimize the number of +// primitive batches, even at the expense of triangle +// strips (such as most PC hardware). +//////////////////////////////////////////////////////////////////// +INLINE bool GraphicsStateGuardian:: +prefers_triangle_strips() const { + return _prefers_triangle_strips; +} + +//////////////////////////////////////////////////////////////////// +// Function: GraphicsStateGuardian::get_max_vertices_per_array +// Access: Published +// Description: Returns the maximum number of vertices that should be +// put into any one GeomVertexData object for use with +// this GSG. +//////////////////////////////////////////////////////////////////// +INLINE int GraphicsStateGuardian:: +get_max_vertices_per_array() const { + return _max_vertices_per_array; +} + +//////////////////////////////////////////////////////////////////// +// Function: GraphicsStateGuardian::get_max_vertices_per_primitive +// Access: Published +// Description: Returns the maximum number of vertex indices that +// should be put into any one GeomPrimitive object for +// use with this GSG. +//////////////////////////////////////////////////////////////////// +INLINE int GraphicsStateGuardian:: +get_max_vertices_per_primitive() const { + return _max_vertices_per_primitive; +} + //////////////////////////////////////////////////////////////////// // Function: GraphicsStateGuardian::get_max_texture_stages // Access: Published @@ -445,6 +483,35 @@ get_coordinate_system() const { return _coordinate_system; } +//////////////////////////////////////////////////////////////////// +// Function: GraphicsStateGuardian::make_global_gsg +// Access: Published +// Description: Marks this particular GraphicsStateGuardian as the +// "global" GSG, which is used for optimization hints by +// operations like NodePath::flatten_strong(). +//////////////////////////////////////////////////////////////////// +INLINE void GraphicsStateGuardian:: +make_global_gsg() { + _global_gsg = this; +} + +//////////////////////////////////////////////////////////////////// +// Function: GraphicsStateGuardian::get_global_gsg +// Access: Published, Static +// Description: Returns the "global" GSG, which is to say, the +// GraphicsStateGuardian object that has most recently +// had make_global_gsg() called for it. It may return +// NULL if there is no such GSG. +// +// This object should be used for optimization hints +// where appropriate, for instance by operations like +// NodePath::flatten_strong(). +//////////////////////////////////////////////////////////////////// +INLINE GraphicsStateGuardian *GraphicsStateGuardian:: +get_global_gsg() { + return _global_gsg; +} + //////////////////////////////////////////////////////////////////// // Function: GraphicsStateGuardian::set_scene diff --git a/panda/src/display/graphicsStateGuardian.cxx b/panda/src/display/graphicsStateGuardian.cxx index 25f76ab0f5..91855c3cbc 100644 --- a/panda/src/display/graphicsStateGuardian.cxx +++ b/panda/src/display/graphicsStateGuardian.cxx @@ -45,6 +45,7 @@ #include "geomLinestrips.h" #include +#include PStatCollector GraphicsStateGuardian::_total_texusage_pcollector("Texture usage"); PStatCollector GraphicsStateGuardian::_active_texusage_pcollector("Texture usage:Active"); @@ -84,6 +85,8 @@ PStatCollector GraphicsStateGuardian::_draw_primitive_pcollector("Draw:Primitive PStatCollector GraphicsStateGuardian::_clear_pcollector("Draw:Clear"); PStatCollector GraphicsStateGuardian::_flush_pcollector("Draw:Flush"); +GraphicsStateGuardian *GraphicsStateGuardian::_global_gsg = NULL; + TypeHandle GraphicsStateGuardian::_type_handle; //////////////////////////////////////////////////////////////////// @@ -111,6 +114,10 @@ GraphicsStateGuardian(const FrameBufferProperties &properties, _active = true; _prepared_objects = new PreparedGraphicsObjects; + _prefers_triangle_strips = false; + _max_vertices_per_array = INT_MAX; + _max_vertices_per_primitive = INT_MAX; + // Initially, we set this to 1 (the default--no multitexturing // supported). A derived GSG may set this differently if it // supports multitexturing. @@ -163,6 +170,9 @@ GraphicsStateGuardian(const FrameBufferProperties &properties, //////////////////////////////////////////////////////////////////// GraphicsStateGuardian:: ~GraphicsStateGuardian() { + if (_global_gsg == this) { + _global_gsg = NULL; + } } //////////////////////////////////////////////////////////////////// diff --git a/panda/src/display/graphicsStateGuardian.h b/panda/src/display/graphicsStateGuardian.h index 3182295fc6..3a43c5b77e 100644 --- a/panda/src/display/graphicsStateGuardian.h +++ b/panda/src/display/graphicsStateGuardian.h @@ -89,6 +89,10 @@ PUBLISHED: INLINE GraphicsEngine *get_engine() const; INLINE const GraphicsThreadingModel &get_threading_model() const; + INLINE bool prefers_triangle_strips() const; + INLINE int get_max_vertices_per_array() const; + INLINE int get_max_vertices_per_primitive() const; + INLINE int get_max_texture_stages() const; INLINE int get_max_texture_dimension() const; INLINE int get_max_3d_texture_dimension() const; @@ -120,6 +124,9 @@ PUBLISHED: INLINE CoordinateSystem get_coordinate_system() const; virtual CoordinateSystem get_internal_coordinate_system() const; + INLINE void make_global_gsg(); + INLINE static GraphicsStateGuardian *get_global_gsg(); + public: INLINE bool set_scene(SceneSetup *scene_setup); INLINE SceneSetup *get_scene() const; @@ -368,6 +375,11 @@ protected: bool _active; PT(PreparedGraphicsObjects) _prepared_objects; + + bool _prefers_triangle_strips; + int _max_vertices_per_array; + int _max_vertices_per_primitive; + int _max_texture_stages; int _max_texture_dimension; int _max_3d_texture_dimension; @@ -461,6 +473,8 @@ private: GraphicsEngine *_engine; GraphicsThreadingModel _threading_model; + static GraphicsStateGuardian *_global_gsg; + public: void traverse_prepared_textures(bool (*pertex_callbackfn)(TextureContext *,void *),void *callback_arg); diff --git a/panda/src/dxgsg8/dxGraphicsStateGuardian8.cxx b/panda/src/dxgsg8/dxGraphicsStateGuardian8.cxx index 2ce940d03e..472e098faa 100644 --- a/panda/src/dxgsg8/dxGraphicsStateGuardian8.cxx +++ b/panda/src/dxgsg8/dxGraphicsStateGuardian8.cxx @@ -1517,6 +1517,9 @@ reset() { << "\n"; } + _max_vertices_per_array = d3d_caps.MaxVertexIndex; + _max_vertices_per_primitive = d3d_caps.MaxPrimitiveCount; + _max_texture_stages = d3d_caps.MaxSimultaneousTextures; _max_texture_dimension = min(d3d_caps.MaxTextureWidth, d3d_caps.MaxTextureHeight); diff --git a/panda/src/glstuff/glGraphicsStateGuardian_src.cxx b/panda/src/glstuff/glGraphicsStateGuardian_src.cxx index cc35448495..e2cd6c067c 100644 --- a/panda/src/glstuff/glGraphicsStateGuardian_src.cxx +++ b/panda/src/glstuff/glGraphicsStateGuardian_src.cxx @@ -686,14 +686,17 @@ reset() { _max_cube_map_dimension = 0; } + GLint max_elements_vertices, max_elements_indices; + GLP(GetIntegerv)(GL_MAX_ELEMENTS_VERTICES, &max_elements_vertices); + GLP(GetIntegerv)(GL_MAX_ELEMENTS_INDICES, &max_elements_indices); + _max_vertices_per_array = max_elements_vertices; + _max_vertices_per_primitive = max_elements_indices; + if (GLCAT.is_debug()) { GLCAT.debug() << "max texture dimension = " << _max_texture_dimension << ", max 3d texture = " << _max_3d_texture_dimension << ", max cube map = " << _max_cube_map_dimension << "\n"; - GLint max_elements_vertices, max_elements_indices; - GLP(GetIntegerv)(GL_MAX_ELEMENTS_VERTICES, &max_elements_vertices); - GLP(GetIntegerv)(GL_MAX_ELEMENTS_INDICES, &max_elements_indices); GLCAT.debug() << "max_elements_vertices = " << max_elements_vertices << ", max_elements_indices = " << max_elements_indices << "\n";