Browse Source

immediate-mode refinements

David Rose 20 years ago
parent
commit
d13afc82cf

+ 8 - 0
dtool/Config.pp

@@ -306,6 +306,14 @@
 // only in a development build.
 #defer SIMULATE_NETWORK_DELAY $[<= $[OPTIMIZE], 3]
 
+// This option compiles in support for immediate-mode OpenGL
+// rendering.  Since this is normally useful only for researching
+// buggy drivers, and since there is a tiny bit of per-primitive
+// overhead to have this option available even if it is unused, it is
+// by default enabled only in a development build.  This has no effect
+// on DirectX rendering.
+#define SUPPORT_IMMEDIATE_MODE $[<= $[OPTIMIZE], 3]
+
 // Do you want to compile in support for pipelining?  This enables
 // setting and accessing multiple different copies of frame-specific
 // data stored in nodes, etc.  At the moment, Panda cannot actually

+ 3 - 0
dtool/LocalSetup.pp

@@ -226,6 +226,9 @@ $[cdefine DO_MEMORY_USAGE]
 /* Define if we want to enable min-lag and max-lag.  */
 $[cdefine SIMULATE_NETWORK_DELAY]
 
+/* Define if we want to allow immediate mode OpenGL rendering.  */
+$[cdefine SUPPORT_IMMEDIATE_MODE]
+
 /* Define if we want to compile in support for pipelining.  */
 $[cdefine DO_PIPELINING]
 

+ 77 - 59
panda/src/glstuff/glGraphicsStateGuardian_src.cxx

@@ -1041,6 +1041,7 @@ begin_frame() {
 
 #ifdef DO_PSTATS
   _vertices_display_list_pcollector.clear_level();
+  _vertices_immediate_pcollector.clear_level();
   _primitive_batches_display_list_pcollector.clear_level();
 #endif
 
@@ -1297,10 +1298,11 @@ begin_draw_primitives(const Geom *geom, const GeomMunger *munger,
 #endif
   }
 
-  if (!vertex_arrays) {
+#ifdef SUPPORT_IMMEDIATE_MODE
+  _use_sender = !vertex_arrays;
+  if (_use_sender) {
     // We must use immediate mode to render primitives.
     _sender.clear();
-    _use_sender = true;
 
     _sender.add_column(_vertex_data, InternalName::get_normal(),
                        NULL, NULL, GLP(Normal3f), NULL);
@@ -1371,10 +1373,10 @@ begin_draw_primitives(const Geom *geom, const GeomMunger *munger,
     _sender.add_column(_vertex_data, InternalName::get_vertex(),
                        NULL, GLP(Vertex2f), GLP(Vertex3f), GLP(Vertex4f));
 
-  } else {
+  } else
+#endif  // SUPPORT_IMMEDIATE_MODE
+  {
     // We may use vertex arrays or buffers to render primitives.
-    _use_sender = false;
-
     const GeomVertexArrayData *array_data;
     int num_values;
     Geom::NumericType numeric_type;
@@ -1517,29 +1519,32 @@ draw_triangles(const GeomTriangles *primitive) {
   }
 #endif  // NDEBUG
 
-  _vertices_tri_pcollector.add_level(primitive->get_num_vertices());
-  _primitive_batches_tri_pcollector.add_level(1);
-
+#ifdef SUPPORT_IMMEDIATE_MODE
   if (_use_sender) {
     draw_immediate_simple_primitives(primitive, GL_TRIANGLES);
 
-  } else {
+  } else 
+#endif  // SUPPORT_IMMEDIATE_MODE
+  {
+    _vertices_tri_pcollector.add_level(primitive->get_num_vertices());
+    _primitive_batches_tri_pcollector.add_level(1);
+
     if (primitive->is_indexed()) {
       const unsigned char *client_pointer = setup_primitive(primitive);
       
       _glDrawRangeElements(GL_TRIANGLES, 
-                           primitive->get_min_vertex(),
-                           primitive->get_max_vertex(),
-                           primitive->get_num_vertices(),
-                           get_numeric_type(primitive->get_index_type()), 
-                           client_pointer);
+			   primitive->get_min_vertex(),
+			   primitive->get_max_vertex(),
+			   primitive->get_num_vertices(),
+			   get_numeric_type(primitive->get_index_type()), 
+			   client_pointer);
     } else {
       GLP(DrawArrays)(GL_TRIANGLES,
-                      primitive->get_first_vertex(),
-                      primitive->get_num_vertices());
+		      primitive->get_first_vertex(),
+		      primitive->get_num_vertices());
     }
   }
-    
+  
   report_my_gl_errors();
 }
 
@@ -1556,27 +1561,30 @@ draw_tristrips(const GeomTristrips *primitive) {
   }
 #endif  // NDEBUG
 
+#ifdef SUPPORT_IMMEDIATE_MODE
   if (_use_sender) {
     draw_immediate_composite_primitives(primitive, GL_TRIANGLE_STRIP);
 
-  } else {
+  } else 
+#endif  // SUPPORT_IMMEDIATE_MODE
+  {
     if (connect_triangle_strips && _render_mode != RenderModeAttrib::M_wireframe) {
       // One long triangle strip, connected by the degenerate vertices
       // that have already been set up within the primitive.
       _vertices_tristrip_pcollector.add_level(primitive->get_num_vertices());
       _primitive_batches_tristrip_pcollector.add_level(1);
       if (primitive->is_indexed()) {
-        const unsigned char *client_pointer = setup_primitive(primitive);
-        _glDrawRangeElements(GL_TRIANGLE_STRIP, 
-                             primitive->get_min_vertex(),
-                             primitive->get_max_vertex(),
-                             primitive->get_num_vertices(),
-                             get_numeric_type(primitive->get_index_type()), 
-                             client_pointer);
+	const unsigned char *client_pointer = setup_primitive(primitive);
+	_glDrawRangeElements(GL_TRIANGLE_STRIP, 
+			     primitive->get_min_vertex(),
+			     primitive->get_max_vertex(),
+			     primitive->get_num_vertices(),
+			     get_numeric_type(primitive->get_index_type()), 
+			     client_pointer);
       } else {
-        GLP(DrawArrays)(GL_TRIANGLE_STRIP,
-                        primitive->get_first_vertex(),
-                        primitive->get_num_vertices());
+	GLP(DrawArrays)(GL_TRIANGLE_STRIP,
+			primitive->get_first_vertex(),
+			primitive->get_num_vertices());
       }
       
     } else {
@@ -1586,32 +1594,32 @@ draw_tristrips(const GeomTristrips *primitive) {
       
       _primitive_batches_tristrip_pcollector.add_level(ends.size());
       if (primitive->is_indexed()) {
-        const unsigned char *client_pointer = setup_primitive(primitive);
-        int index_stride = primitive->get_index_stride();
-        GeomVertexReader mins(primitive->get_mins(), 0);
-        GeomVertexReader maxs(primitive->get_maxs(), 0);
-        nassertv(primitive->get_mins()->get_num_rows() == (int)ends.size() && 
-                 primitive->get_maxs()->get_num_rows() == (int)ends.size());
-        
-        unsigned int start = 0;
-        for (size_t i = 0; i < ends.size(); i++) {
-          _vertices_tristrip_pcollector.add_level(ends[i] - start);
-          _glDrawRangeElements(GL_TRIANGLE_STRIP, 
-                               mins.get_data1i(), maxs.get_data1i(), 
-                               ends[i] - start,
-                               get_numeric_type(primitive->get_index_type()), 
-                               client_pointer + start * index_stride);
-          start = ends[i] + 2;
-        }
+	const unsigned char *client_pointer = setup_primitive(primitive);
+	int index_stride = primitive->get_index_stride();
+	GeomVertexReader mins(primitive->get_mins(), 0);
+	GeomVertexReader maxs(primitive->get_maxs(), 0);
+	nassertv(primitive->get_mins()->get_num_rows() == (int)ends.size() && 
+		 primitive->get_maxs()->get_num_rows() == (int)ends.size());
+	
+	unsigned int start = 0;
+	for (size_t i = 0; i < ends.size(); i++) {
+	  _vertices_tristrip_pcollector.add_level(ends[i] - start);
+	  _glDrawRangeElements(GL_TRIANGLE_STRIP, 
+			       mins.get_data1i(), maxs.get_data1i(), 
+			       ends[i] - start,
+			       get_numeric_type(primitive->get_index_type()), 
+			       client_pointer + start * index_stride);
+	  start = ends[i] + 2;
+	}
       } else {
-        unsigned int start = 0;
-        int first_vertex = primitive->get_first_vertex();
-        for (size_t i = 0; i < ends.size(); i++) {
-          _vertices_tristrip_pcollector.add_level(ends[i] - start);
-          GLP(DrawArrays)(GL_TRIANGLE_STRIP, first_vertex + start, 
-                          ends[i] - start);
-          start = ends[i] + 2;
-        }
+	unsigned int start = 0;
+	int first_vertex = primitive->get_first_vertex();
+	for (size_t i = 0; i < ends.size(); i++) {
+	  _vertices_tristrip_pcollector.add_level(ends[i] - start);
+	  GLP(DrawArrays)(GL_TRIANGLE_STRIP, first_vertex + start, 
+			  ends[i] - start);
+	  start = ends[i] + 2;
+	}
       }
     }
   }
@@ -1632,10 +1640,12 @@ draw_trifans(const GeomTrifans *primitive) {
   }
 #endif  // NDEBUG
 
+#ifdef SUPPORT_IMMEDIATE_MODE
   if (_use_sender) {
     draw_immediate_composite_primitives(primitive, GL_TRIANGLE_FAN);
-
-  } else {
+  } else 
+#endif  // SUPPORT_IMMEDIATE_MODE
+  {
     // Send the individual triangle fans.  There's no connecting fans
     // with degenerate vertices, so no worries about that.
     CPTA_int ends = primitive->get_ends();
@@ -1686,10 +1696,12 @@ draw_lines(const GeomLines *primitive) {
   }
 #endif  // NDEBUG
 
+#ifdef SUPPORT_IMMEDIATE_MODE
   if (_use_sender) {
     draw_immediate_simple_primitives(primitive, GL_LINES);
-
-  } else {
+  } else 
+#endif  // SUPPORT_IMMEDIATE_MODE
+  {
     _vertices_other_pcollector.add_level(primitive->get_num_vertices());
     _primitive_batches_other_pcollector.add_level(1);
     
@@ -1739,10 +1751,12 @@ draw_points(const GeomPoints *primitive) {
   }
 #endif  // NDEBUG
 
+#ifdef SUPPORT_IMMEDIATE_MODE
   if (_use_sender) {
     draw_immediate_simple_primitives(primitive, GL_POINTS);
-
-  } else {
+  } else 
+#endif  // SUPPORT_IMMEDIATE_MODE
+  {
     _vertices_other_pcollector.add_level(primitive->get_num_vertices());
     _primitive_batches_other_pcollector.add_level(1);
     
@@ -3082,6 +3096,7 @@ wants_texcoords() const {
   return true;
 }
 
+#ifdef SUPPORT_IMMEDIATE_MODE
 ////////////////////////////////////////////////////////////////////
 //     Function: GLGraphicsStateGuardian::draw_immediate_simple_primitives
 //       Access: Protected
@@ -3108,7 +3123,9 @@ draw_immediate_simple_primitives(const GeomPrimitive *primitive, GLenum mode) {
 
   GLP(End)();
 }
+#endif  // SUPPORT_IMMEDIATE_MODE
 
+#ifdef SUPPORT_IMMEDIATE_MODE
 ////////////////////////////////////////////////////////////////////
 //     Function: GLGraphicsStateGuardian::draw_immediate_composite_primitives
 //       Access: Protected
@@ -3156,6 +3173,7 @@ draw_immediate_composite_primitives(const GeomPrimitive *primitive, GLenum mode)
     }
   }
 }
+#endif  // SUPPORT_IMMEDIATE_MODE
 
 ////////////////////////////////////////////////////////////////////
 //     Function: GLGraphicsStateGuardian::report_errors_loop

+ 6 - 0
panda/src/glstuff/glGraphicsStateGuardian_src.h

@@ -157,8 +157,11 @@ public:
   void dump_state(void);
 
   const float *get_light_color(Light *light) const;
+
+#ifdef SUPPORT_IMMEDIATE_MODE
   void draw_immediate_simple_primitives(const GeomPrimitive *primitive, GLenum mode);
   void draw_immediate_composite_primitives(const GeomPrimitive *primitive, GLenum mode);
+#endif  // SUPPORT_IMMEDIATE_MODE
 
   INLINE static bool report_errors(int line, const char *source_file);
   INLINE void report_my_errors(int line, const char *source_file);
@@ -306,8 +309,11 @@ protected:
   bool _vertex_blending_enabled;
 
   CPT(DisplayRegion) _actual_display_region;
+
+#ifdef SUPPORT_IMMEDIATE_MODE
   CLP(ImmediateModeSender) _sender;
   bool _use_sender;
+#endif  // SUPPORT_IMMEDIATE_MODE
 
 #ifdef HAVE_CGGL
   PT(CgShader) _cg_shader; // The current CgShader object

+ 3 - 0
panda/src/glstuff/glImmediateModeSender_src.cxx

@@ -16,6 +16,7 @@
 //
 ////////////////////////////////////////////////////////////////////
 
+#ifdef SUPPORT_IMMEDIATE_MODE
 
 ////////////////////////////////////////////////////////////////////
 //     Function: CLP(ImmediateModeSender)::Destructor
@@ -616,3 +617,5 @@ issue_vertex() {
 
   (*_func)(4, (const unsigned int *)d);
 }
+
+#endif  // SUPPORT_IMMEDIATE_MODE

+ 4 - 0
panda/src/glstuff/glImmediateModeSender_src.h

@@ -19,6 +19,8 @@
 #include "pandabase.h"
 #include "geomVertexReader.h"
 
+#ifdef SUPPORT_IMMEDIATE_MODE
+
 ////////////////////////////////////////////////////////////////////
 //       Class : GLImmediateModeSender
 // Description : This class collects together a handful of objects
@@ -225,3 +227,5 @@ private:
 
 #include "glImmediateModeSender_src.I"
 
+#endif  // SUPPORT_IMMEDIATE_MODE
+

+ 6 - 4
panda/src/gobj/config_gobj.cxx

@@ -92,15 +92,17 @@ ConfigVariableBool vertex_arrays
  PRC_DESC("Set this true to allow the use of vertex arrays for rendering "
           "OpenGL vertex data.  This, or vertex buffers, is the normal "
           "way of issuing vertices ever since OpenGL 1.1, and you "
-          "almost always want to have set to true.  However, some very "
+          "almost always want to have this set to true.  However, some very "
           "buggy graphics drivers may have problems handling vertex arrays "
           "correctly, so if you are experiencing problems you might try "
           "setting this to false.  If this is false, Panda will fall back "
           "to using immediate-mode commands like glVertex3f(), etc., to "
           "issue the vertices, which is potentially much slower than "
-          "vertex arrays.  Setting this false causes vertex_buffers to be "
-          "ignored (since vertex buffers are a special case of vertex "
-          "arrays in OpenGL).  This has no effect on DirectX rendering."));
+          "vertex arrays.  Setting this false also disables vertex buffers, "
+	  "effectively ignoring the setting of the vertex-buffers variable "
+	  "(since vertex buffers are a special case of vertex arrays in "
+	  "OpenGL).  This variable is normally not enabled in a production "
+	  "build.  This has no effect on DirectX rendering."));
 
 ConfigVariableBool display_lists
 ("display-lists", false,

+ 1 - 0
panda/src/pstatclient/pStatProperties.cxx

@@ -189,6 +189,7 @@ static LevelCollectorProperties level_properties[] = {
   { 1, "Vertices:Triangle strips",         { 0.2, 0.5, 0.8 } },
   { 1, "Vertices:Indexed triangle strips", { 0.5, 0.2, 0.8 } },
   { 1, "Vertices:Display lists",           { 0.8, 0.5, 1.0 } },
+  { 1, "Vertices:Immediate mode",          { 1.0, 0.5, 0.0 } },
   { 1, "Nodes",                            { 0.4, 0.2, 0.8 },  "", 500.0 },
   { 1, "Nodes:GeomNodes",                  { 0.8, 0.2, 0.0 } },
   { 1, "Geoms",                            { 0.4, 0.8, 0.3 },  "", 500.0 },