Browse Source

dx9 shader support from zhao

David Rose 14 years ago
parent
commit
cd79af53fe

+ 4 - 0
panda/src/display/graphicsStateGuardian.h

@@ -360,7 +360,11 @@ protected:
   // This bitmask contains a 1 bit everywhere that _state_rs has a
   // known value.  If a bit is 0, the corresponding state must be
   // re-sent.
+  // 
+  // Derived GSGs should initialize _inv_state_mask in reset() as a mask of
+  // 1's where they don't care, and 0's where they do care, about the state.
   RenderState::SlotMask _state_mask;
+  RenderState::SlotMask _inv_state_mask;
 
   // The current transform, as of the last call to
   // set_state_and_transform().

+ 30 - 0
panda/src/dxgsg9/dxGeomMunger9.cxx

@@ -174,6 +174,21 @@ munge_format_impl(const GeomVertexFormat *orig,
     }
   }
 
+  // Now go through the remaining arrays and make sure they are
+  // tightly packed.  If not, repack them.
+  for (int i = 0; i < new_format->get_num_arrays(); ++i) {
+    CPT(GeomVertexArrayFormat) orig_a = new_format->get_array(i);
+    if (orig_a->count_unused_space() != 0) {
+      PT(GeomVertexArrayFormat) new_a = new GeomVertexArrayFormat;
+      for (int j = 0; j < orig_a->get_num_columns(); ++j) {
+        const GeomVertexColumn *column = orig_a->get_column(j);
+        new_a->add_column(column->get_name(), column->get_num_components(),
+                          column->get_numeric_type(), column->get_contents());
+      }
+      new_format->set_array(i, new_a);
+    }
+  }
+
   // Make sure the FVF-style array we just built up is first in the
   // list.
   new_format->insert_array(0, new_array_format);
@@ -268,6 +283,21 @@ premunge_format_impl(const GeomVertexFormat *orig) {
     }
   }
 
+  // Now go through the remaining arrays and make sure they are
+  // tightly packed.  If not, repack them.
+  for (int i = 0; i < new_format->get_num_arrays(); ++i) {
+    CPT(GeomVertexArrayFormat) orig_a = new_format->get_array(i);
+    if (orig_a->count_unused_space() != 0) {
+      PT(GeomVertexArrayFormat) new_a = new GeomVertexArrayFormat;
+      for (int j = 0; j < orig_a->get_num_columns(); ++j) {
+        const GeomVertexColumn *column = orig_a->get_column(j);
+        new_a->add_column(column->get_name(), column->get_num_components(),
+                          column->get_numeric_type(), column->get_contents());
+      }
+      new_format->set_array(i, new_a);
+    }
+  }
+
   // Make sure the FVF-style array we just built up is first in the
   // list.
   new_format->insert_array(0, new_array_format);

File diff suppressed because it is too large
+ 327 - 552
panda/src/dxgsg9/dxGraphicsStateGuardian9.cxx


+ 10 - 11
panda/src/dxgsg9/dxGraphicsStateGuardian9.h

@@ -33,12 +33,6 @@
 
 #include "lru.h"
 
-typedef LPDIRECT3DDEVICE9 DIRECT_3D_DEVICE;
-typedef D3DVERTEXELEMENT9 DIRECT_3D_VERTEX_ELEMENT;
-typedef LPDIRECT3DVERTEXDECLARATION9 DIRECT_3D_VERTEX_DECLARATION;
-typedef LPDIRECT3DVERTEXSHADER9 DIRECT_3D_VERTEX_SHADER;
-typedef LPDIRECT3DPIXELSHADER9 DIRECT_3D_PIXEL_SHADER;
-
 #include "vertexElementArray.h"
 #include "dxShaderContext9.h"
 
@@ -83,10 +77,15 @@ public:
   void release_shader(ShaderContext *sc);
 
   virtual VertexBufferContext *prepare_vertex_buffer(GeomVertexArrayData *data);
-  bool apply_vertex_buffer(VertexBufferContext *vbc, CLP(ShaderContext) *shader_context,
-                           const GeomVertexArrayDataHandle *reader, bool force, string name);
+  bool apply_vertex_buffer(VertexBufferContext *vbc,
+                           const GeomVertexArrayDataHandle *reader,
+                           bool force);
   virtual void release_vertex_buffer(VertexBufferContext *vbc);
 
+  bool setup_array_data(CLP(VertexBufferContext)*& vbc,
+                        const GeomVertexArrayDataHandle* data,
+                        bool force);
+
   virtual IndexBufferContext *prepare_index_buffer(GeomPrimitive *data);
   bool apply_index_buffer(IndexBufferContext *ibc,
                           const GeomPrimitivePipelineReader *reader, bool force);
@@ -206,8 +205,8 @@ protected:
 
   void do_auto_rescale_normal();
 
-//  void disable_standard_vertex_arrays();
-//  void update_standard_vertex_arrays();
+  void disable_standard_vertex_arrays();
+  bool update_standard_vertex_arrays(bool force);
   void disable_standard_texture_bindings();
   void update_standard_texture_bindings();
 
@@ -301,7 +300,6 @@ protected:
   PT(Shader)  _texture_binding_shader;
   CLP(ShaderContext)  *_texture_binding_shader_context;
 
-  const DXVertexBufferContext9 *_active_vbuffer;
   const DXIndexBufferContext9 *_active_ibuffer;
 
   bool _overlay_windows_supported;
@@ -320,6 +318,7 @@ protected:
   UINT _available_texture_memory;
 
   DWORD _last_fvf;
+  int _num_bound_streams;
 
   // Cache the data necessary to bind each particular light each
   // frame, so if we bind a given light multiple times, we only have

+ 243 - 201
panda/src/dxgsg9/dxShaderContext9.cxx

@@ -14,6 +14,7 @@
 
 #include "dxGraphicsStateGuardian9.h"
 #include "dxShaderContext9.h"
+#include "dxVertexBufferContext9.h"
 
 #include <io.h>
 #include <stdio.h>
@@ -37,8 +38,11 @@ TypeHandle CLP(ShaderContext)::_type_handle;
 CLP(ShaderContext)::
 CLP(ShaderContext)(Shader *s, GSG *gsg) : ShaderContext(s) {
 
-  _vertex_size = 0;
-  _vertex_element_array = 0;
+  _vertex_element_array = NULL;
+  _vertex_declaration = NULL;
+
+  _num_bound_streams = 0;
+
   _name = s->get_filename ( );
 
 #ifdef HAVE_CG
@@ -131,9 +135,14 @@ CLP(ShaderContext)::
 ~CLP(ShaderContext)() {
   release_resources();
 
-  if (_vertex_element_array) {
+  if ( _vertex_declaration != NULL ) {
+    _vertex_declaration->Release();
+    _vertex_declaration = NULL;
+  }
+
+  if ( _vertex_element_array != NULL ) {
     delete _vertex_element_array;
-    _vertex_element_array = 0;
+    _vertex_element_array = NULL;
   }
 }
 
@@ -203,6 +212,10 @@ release_resources() {
     _cg_parameter_map.clear();
   }
 #endif
+
+  // I think we need to call SetStreamSource for _num_bound_streams -- basically the logic from
+  // disable_shader_vertex_arrays -- but to do that we need to introduce logic like the GL code
+  // has to manage _last_gsg, so we can get at the device.  Sigh.
 }
 
 ////////////////////////////////////////////////////////////////////
@@ -473,13 +486,14 @@ issue_parameters(GSG *gsg, int altered)
 //  Description: Disable all the vertex arrays used by this shader.
 ////////////////////////////////////////////////////////////////////
 void CLP(ShaderContext)::
-disable_shader_vertex_arrays(GSG *gsg)
-{
-#ifdef HAVE_CG
-  if (_cg_context) {
-    // DO NOTHING, CURRENTLY USING ONLY ONE STREAM SOURCE
+disable_shader_vertex_arrays(GSG *gsg) {
+  LPDIRECT3DDEVICE9 device = gsg->_screen->_d3d_device;
+
+  for ( int array_index = 0; array_index < _num_bound_streams; ++array_index )
+  {
+    device->SetStreamSource( array_index, NULL, 0, 0 );
   }
-#endif
+  _num_bound_streams = 0;
 }
 
 ////////////////////////////////////////////////////////////////////
@@ -493,221 +507,249 @@ disable_shader_vertex_arrays(GSG *gsg)
 //               it may unnecessarily disable arrays then immediately
 //               reenable them.  We may optimize this someday.
 ////////////////////////////////////////////////////////////////////
-
-// DEBUG
-#if DEBUG_SHADER
-VertexElementArray *global_vertex_element_array = 0;
-#endif
-
-void CLP(ShaderContext)::
-update_shader_vertex_arrays(CLP(ShaderContext) *prev, GSG *gsg)
-{
+bool CLP(ShaderContext)::
+update_shader_vertex_arrays(CLP(ShaderContext) *prev, GSG *gsg, bool force) {
   if (prev) prev->disable_shader_vertex_arrays(gsg);
 #ifdef HAVE_CG
-  if (_cg_context) {
+  if (!_cg_context) {
+    return true;
+  }
 
-  #ifdef SUPPORT_IMMEDIATE_MODE
+#ifdef SUPPORT_IMMEDIATE_MODE
 /*
     if (gsg->_use_sender) {
       dxgsg9_cat.error() << "immediate mode shaders not implemented yet\n";
     } else
 */
-  #endif // SUPPORT_IMMEDIATE_MODE
-    {
-      if (_vertex_element_array == 0) {
-        bool error;
-        const GeomVertexArrayDataHandle *array_reader;
+#endif // SUPPORT_IMMEDIATE_MODE
+  {
+    int nvarying = _shader->_var_spec.size();
+    LPDIRECT3DDEVICE9 device = gsg->_screen->_d3d_device;
+    HRESULT hr;
+
+    // Discard and recreate the VertexElementArray.  This thrashes pretty bad....
+    if ( _vertex_element_array != NULL ) {
+      delete _vertex_element_array;
+    }
+    _vertex_element_array = new VertexElementArray(nvarying + 2);
+    VertexElementArray* vertex_element_array = _vertex_element_array;
+
+    // Experimentally determined that DX doesn't like us crossing the streams!
+    // It seems to be okay with out-of-order offsets in both source and destination,
+    // but it wants all stream X entries grouped together, then all stream Y entries, etc.
+    // To accomplish this out outer loop processes arrays ("streams"), and we repeatedly
+    // iterate the parameters to pull out only those for a single stream.
+
+    int number_of_arrays = gsg->_data_reader->get_num_arrays();
+    for ( int array_index = 0; array_index < number_of_arrays; ++array_index ) {
+      const GeomVertexArrayDataHandle* array_reader =
+        gsg->_data_reader->get_array_reader( array_index );
+      if ( array_reader == NULL ) {
+        dxgsg9_cat.error() << "Unable to get reader for array " << array_index << "\n";
+        continue;
+      }
+
+      for ( int var_index = 0; var_index < nvarying; ++var_index ) {
+        CGparameter p = _cg_parameter_map[_shader->_var_spec[var_index]._id._seqno];
+        if ( p == NULL ) {
+          dxgsg9_cat.info() <<
+            "No parameter in map for parameter " << var_index <<
+            " (probably optimized away)\n";
+          continue;
+        }
+
+        InternalName *name = _shader->_var_spec[var_index]._name;
+
+        // This is copied from the GL version of this function, and I've yet to 100% convince
+        // myself that it works properly....
+        int texslot = _shader->_var_spec[var_index]._append_uv;
+        if (texslot >= 0 && texslot < gsg->_state_texture->get_num_on_stages()) {
+          TextureStage *stage = gsg->_state_texture->get_on_stage(texslot);
+          InternalName *texname = stage->get_texcoord_name();
+          if (name == InternalName::get_texcoord()) {
+            name = texname;
+          } else if (texname != InternalName::get_texcoord()) {
+            name = name->append(texname->get_basename());
+          }
+        }
+
+        const GeomVertexArrayDataHandle* param_array_reader;
         Geom::NumericType numeric_type;
-        int start, stride, num_values;
-        int nvarying = _shader->_var_spec.size();
-
-        int stream_index;
-        VertexElementArray *vertex_element_array;
-
-        error = false;
-        // SHADER ISSUE: STREAM INDEX ALWAYS 0 FOR VERTEX BUFFER?
-        stream_index = 0;
-        vertex_element_array = new VertexElementArray (nvarying + 2);
-
-        #if DEBUG_SHADER
-        // DEBUG
-        global_vertex_element_array = vertex_element_array;
-        #endif
-
-        for (int i=0; i<nvarying; i++) {
-          CGparameter p = _cg_parameter_map[_shader->_var_spec[i]._id._seqno];
-          if (p == NULL) {
-            continue;
-          }        
-          InternalName *name = _shader->_var_spec[i]._name;
-          int texslot = _shader->_var_spec[i]._append_uv;
-          if (texslot >= 0 && texslot < gsg->_state_texture->get_num_on_stages()) {
-            TextureStage *stage = gsg->_state_texture->get_on_stage(texslot);
-            InternalName *texname = stage->get_texcoord_name();
-            if (name == InternalName::get_texcoord()) {
-              name = texname;
-            } else if (texname != InternalName::get_texcoord()) {
-              name = name->append(texname->get_basename());
+        int num_values;
+        int start;
+        int stride;
+        if ( gsg->_data_reader->get_array_info( name,
+                                                param_array_reader, num_values, numeric_type,
+                                                start, stride ) == false ) {
+          // This is apparently not an error (actually I think it is, just not a fatal one).
+          //
+          // The GL implementation fails silently in this case, but the net result is that we
+          // end up not supplying input for a shader parameter, which can cause Bad Things to
+          // happen so I'd like to at least get a hint as to what's gone wrong.
+          dxgsg9_cat.info() << "Geometry contains no data for shader parameter " << *name << "\n";
+          continue;
+        }
+        
+        // If not associated with the array we're working on, move on.
+        if ( param_array_reader != array_reader ) {
+          continue;
+        }
+
+        const char* semantic = cgGetParameterSemantic( p );
+        if ( semantic == NULL ) {
+          dxgsg9_cat.error() << "Unable to retrieve semantic for parameter " << var_index << "\n";
+          continue;
+        }
+
+        if ( strncmp( semantic, "POSITION", strlen( "POSITION" ) ) == 0 ) {
+          if (numeric_type == Geom::NT_float32) {
+            switch (num_values) {
+              case 3:
+                vertex_element_array->add_position_xyz_vertex_element(array_index, start);
+                break;
+              case 4:
+                vertex_element_array->add_position_xyzw_vertex_element(array_index, start);
+                break;
+              default:
+                dxgsg9_cat.error() << "VE ERROR: invalid number of vertex coordinate elements " << num_values << "\n";
+                break;
             }
+          } else {
+            dxgsg9_cat.error() << "VE ERROR: invalid vertex type " << numeric_type << "\n";
           }
-          if (gsg->_data_reader->get_array_info(name, array_reader, num_values, numeric_type, start, stride)) {
-
-            if (false) {
-
-            } else if (name -> get_top ( ) == InternalName::get_vertex ( )) {
-
-              if (numeric_type == Geom::NT_float32) {
-                switch (num_values) {
-                  case 3:
-                    vertex_element_array -> add_position_xyz_vertex_element (stream_index);
-                    break;
-                  case 4:
-                    vertex_element_array -> add_position_xyzw_vertex_element (stream_index);
-                    break;
-                  default:
-                    dxgsg9_cat.error ( ) << "VE ERROR: invalid number of vertex coordinate elements " << num_values << "\n";
-                    break;
-                }
-              } else {
-                dxgsg9_cat.error ( ) << "VE ERROR: invalid vertex type " << numeric_type << "\n";
-              }
-
-            } else if (name -> get_top ( ) == InternalName::get_texcoord ( )) {
-
-              if (numeric_type == Geom::NT_float32) {
-                switch (num_values)
-                {
-                  case 1:
-                    vertex_element_array -> add_u_vertex_element (stream_index);
-                    break;
-                  case 2:
-                    vertex_element_array -> add_uv_vertex_element (stream_index);
-                    break;
-                  case 3:
-                    vertex_element_array -> add_uvw_vertex_element (stream_index);
-                    break;
-                  default:
-                    dxgsg9_cat.error ( ) << "VE ERROR: invalid number of vertex texture coordinate elements " << num_values <<  "\n";
-                    break;
-                }
-              } else {
-                dxgsg9_cat.error ( ) << "VE ERROR: invalid texture coordinate type " << numeric_type << "\n";
-              }
-
-            } else if (name -> get_top ( ) == InternalName::get_normal ( )) {
-
-              if (numeric_type == Geom::NT_float32) {
-                switch (num_values)
-                {
-                  case 3:
-                    vertex_element_array -> add_normal_vertex_element (stream_index);
-                    break;
-                  default:
-                    dxgsg9_cat.error ( ) << "VE ERROR: invalid number of normal coordinate elements " << num_values << "\n";
-                    break;
-                }
-              } else {
-                dxgsg9_cat.error ( ) << "VE ERROR: invalid normal type " << numeric_type << "\n";
-              }
-
-            } else if (name -> get_top ( ) == InternalName::get_binormal ( )) {
-
-              if (numeric_type == Geom::NT_float32) {
-                switch (num_values)
-                {
-                  case 3:
-                    vertex_element_array -> add_binormal_vertex_element (stream_index);
-                    break;
-                  default:
-                    dxgsg9_cat.error ( ) << "VE ERROR: invalid number of binormal coordinate elements " << num_values << "\n";
-                    break;
-                }
-              } else {
-                dxgsg9_cat.error ( ) << "VE ERROR: invalid binormal type " << numeric_type << "\n";
-              }
-
-            } else if (name -> get_top ( ) == InternalName::get_tangent ( )) {
-
-              if (numeric_type == Geom::NT_float32) {
-                switch (num_values)
-                {
-                  case 3:
-                    vertex_element_array -> add_tangent_vertex_element (stream_index);
-                    break;
-                  default:
-                    dxgsg9_cat.error ( ) << "VE ERROR: invalid number of tangent coordinate elements " << num_values << "\n";
-                    break;
-                }
-              } else {
-                dxgsg9_cat.error ( ) << "VE ERROR: invalid tangent type " << numeric_type << "\n";
-              }
-
-            } else if (name -> get_top ( ) == InternalName::get_color ( )) {
-
-              if (numeric_type == Geom::NT_packed_dcba ||
-                  numeric_type == Geom::NT_packed_dabc ||
-                  numeric_type == Geom::NT_uint8) {
-                switch (num_values)
-                {
-                  case 4:
-                    vertex_element_array -> add_diffuse_color_vertex_element (stream_index);
-                    break;
-                  default:
-                    dxgsg9_cat.error ( ) << "VE ERROR: invalid color coordinates " << num_values << "\n";
-                    break;
-                }
-              } else {
-                dxgsg9_cat.error ( ) << "VE ERROR: invalid color type " << numeric_type << "\n";
-              }
-
-            } else {
-              dxgsg9_cat.error ( ) << "VE ERROR: unsupported vertex element " << name -> get_name ( ) << "\n";
+        } else if ( strncmp( semantic, "TEXCOORD", strlen( "TEXCOORD" ) ) == 0 ) {
+          int slot = atoi( semantic + strlen( "TEXCOORD" ) );
+          if (numeric_type == Geom::NT_float32) {
+            switch (num_values) {
+              case 1:
+                vertex_element_array->add_u_vertex_element(array_index, start, slot);
+                break;
+              case 2:
+                vertex_element_array->add_uv_vertex_element(array_index, start, slot);
+                break;
+              case 3:
+                vertex_element_array->add_uvw_vertex_element(array_index, start, slot);
+                break;
+              default:
+                dxgsg9_cat.error() << "VE ERROR: invalid number of vertex texture coordinate elements " << num_values <<  "\n";
+                break;
+            }
+          } else {
+            dxgsg9_cat.error() << "VE ERROR: invalid texture coordinate type " << numeric_type << "\n";
+          }
+        } else if ( strncmp( semantic, "COLOR", strlen( "COLOR" ) ) == 0 ) {
+          if (numeric_type == Geom::NT_packed_dcba ||
+              numeric_type == Geom::NT_packed_dabc ||
+              numeric_type == Geom::NT_uint8) {
+            switch (num_values) {
+              case 4:
+                vertex_element_array->add_diffuse_color_vertex_element(array_index, start);
+                break;
+              default:
+                dxgsg9_cat.error() << "VE ERROR: invalid color coordinates " << num_values << "\n";
+                break;
+            }
+          } else {
+            dxgsg9_cat.error() << "VE ERROR: invalid color type " << numeric_type << "\n";
+          }
+        } else if ( strncmp( semantic, "NORMAL", strlen( "NORMAL" ) ) == 0 ) {
+          if (numeric_type == Geom::NT_float32) {
+            switch (num_values) {
+              case 3:
+                vertex_element_array->add_normal_vertex_element(array_index, start);
+                break;
+              default:
+                dxgsg9_cat.error() << "VE ERROR: invalid number of normal coordinate elements " << num_values << "\n";
+                break;
+            }
+          } else {
+            dxgsg9_cat.error() << "VE ERROR: invalid normal type " << numeric_type << "\n";
+          }
+        } else if ( strncmp( semantic, "BINORMAL", strlen( "BINORMAL" ) ) == 0 ) {
+          if (numeric_type == Geom::NT_float32) {
+            switch (num_values) {
+              case 3:
+                vertex_element_array->add_binormal_vertex_element(array_index, start);
+                break;
+              default:
+                dxgsg9_cat.error() << "VE ERROR: invalid number of binormal coordinate elements " << num_values << "\n";
+                break;
+            }
+          } else {
+            dxgsg9_cat.error() << "VE ERROR: invalid binormal type " << numeric_type << "\n";
+          }
+        } else if ( strncmp( semantic, "TANGENT", strlen( "TANGENT" ) ) == 0 ) {
+          if (numeric_type == Geom::NT_float32) {
+            switch (num_values) {
+              case 3:
+                vertex_element_array->add_tangent_vertex_element(array_index, start);
+                break;
+              default:
+                dxgsg9_cat.error() << "VE ERROR: invalid number of tangent coordinate elements " << num_values << "\n";
+                break;
             }
-
           } else {
-            dxgsg9_cat.error ( )
-              << "get_array_info ( ) failed for shader "
-              << _name
-              << "\n"
-              << "  vertex element name = "
-              << name -> get_name ( )
-              << "\n";
-            error = true;
+            dxgsg9_cat.error() << "VE ERROR: invalid tangent type " << numeric_type << "\n";
           }
+        } else {
+          dxgsg9_cat.error() << "Unsupported semantic " << semantic << " for parameter " << var_index << "\n";
         }
+      }
+
+      // Get the vertex buffer for this array.
+      CLP(VertexBufferContext)* dvbc;
+      if (!gsg->setup_array_data(dvbc, array_reader, force)) {
+        dxgsg9_cat.error() << "Unable to setup vertex buffer for array " << array_index << "\n";
+        continue;
+      }
+
+      // Bind this array as the data source for the corresponding stream.
+      const GeomVertexArrayFormat* array_format = array_reader->get_array_format();
+      hr = device->SetStreamSource( array_index, dvbc->_vbuffer, 0, array_format->get_stride() );
+      if (FAILED(hr)) {
+        dxgsg9_cat.error() << "SetStreamSource failed" << D3DERRORSTRING(hr);
+      }
+    }
 
-        if (error) {
-          delete vertex_element_array;
+    _num_bound_streams = number_of_arrays;
+
+    if (( _vertex_element_array != NULL ) &&
+        ( _vertex_element_array->add_end_vertex_element() != false )) {
+      if ( dxgsg9_cat.is_debug() ) {
+        // Note that the currently generated vertex declaration works but never validates.
+        // My theory is that this is due to the shader programs always using float4 whereas
+        // the vertex declaration correctly sets the number of inputs (float2, float3, etc.).
+        if (cgD3D9ValidateVertexDeclaration(_cg_vprogram,
+                                            _vertex_element_array->_vertex_element_array) == CG_TRUE) {
+          dxgsg9_cat.debug() << "cgD3D9ValidateVertexDeclaration succeeded\n";
+        } else {
+          dxgsg9_cat.debug() << "cgD3D9ValidateVertexDeclaration failed\n";
         }
-        else {
-          int state;
-
-          state = vertex_element_array -> add_end_vertex_element ( );
-          if (state) {
-            if (_cg_context) {
-              if (cgD3D9ValidateVertexDeclaration (_cg_vprogram,
-                    vertex_element_array -> vertex_element_array) == CG_TRUE) {
-                dxgsg9_cat.debug() << "|||||cgD3D9ValidateVertexDeclaration succeeded\n";
-              }
-              else {
-              }
-            }
-            else {
+      }
 
-            }
+      // Discard the old VertexDeclaration.  This thrashes pretty bad....
+      if ( _vertex_declaration != NULL ) {
+        _vertex_declaration->Release();
+        _vertex_declaration = NULL;
+      }
 
-            _vertex_size = vertex_element_array -> offset;
-            _vertex_element_array = vertex_element_array;
-          }
-          else {
-            dxgsg9_cat.error ( ) << "VertexElementArray creation failed\n";
-            delete vertex_element_array;
-          }
+      hr = device->CreateVertexDeclaration( _vertex_element_array->_vertex_element_array,
+                                            &_vertex_declaration );
+      if (FAILED (hr)) {
+        dxgsg9_cat.error() << "CreateVertexDeclaration failed" << D3DERRORSTRING(hr);
+      } else {
+        hr = device->SetVertexDeclaration( _vertex_declaration );
+        if (FAILED(hr)) {
+          dxgsg9_cat.error() << "SetVertexDeclaration failed" << D3DERRORSTRING(hr);
         }
       }
+    } else {
+      dxgsg9_cat.error() << "VertexElementArray creation failed\n";
     }
   }
 #endif // HAVE_CG
+
+  return true;
 }
 
 ////////////////////////////////////////////////////////////////////

+ 6 - 3
panda/src/dxgsg9/dxShaderContext9.h

@@ -76,14 +76,17 @@ public:
   void issue_parameters(GSG *gsg, int altered);
   void issue_transform(GSG *gsg);
   void disable_shader_vertex_arrays(GSG *gsg);
-  void update_shader_vertex_arrays(CLP(ShaderContext) *prev, GSG *gsg);
+  bool update_shader_vertex_arrays(CLP(ShaderContext) *prev, GSG *gsg,
+                                   bool force);
   void disable_shader_texture_bindings(GSG *gsg);
   void update_shader_texture_bindings(CLP(ShaderContext) *prev, GSG *gsg);
 
-  class VertexElementArray *_vertex_element_array;
+  class VertexElementArray* _vertex_element_array;
+  LPDIRECT3DVERTEXDECLARATION9 _vertex_declaration;
+
+  int _num_bound_streams;
 
   // FOR DEBUGGING
-  int _vertex_size;
   string _name;
   
 private:

+ 10 - 275
panda/src/dxgsg9/dxVertexBufferContext9.cxx

@@ -29,8 +29,10 @@ TypeHandle DXVertexBufferContext9::_type_handle;
 //       Access: Public
 //  Description:
 ////////////////////////////////////////////////////////////////////
-DXVertexBufferContext9::
-DXVertexBufferContext9(PreparedGraphicsObjects *pgo, GeomVertexArrayData *data, DXScreenData &scrn) :
+CLP(VertexBufferContext)::
+CLP(VertexBufferContext)(CLP(GraphicsStateGuardian) *dxgsg,
+                         PreparedGraphicsObjects *pgo,
+                         GeomVertexArrayData *data) :
   VertexBufferContext(pgo, data),
   _vbuffer(NULL)
 {
@@ -43,112 +45,11 @@ DXVertexBufferContext9(PreparedGraphicsObjects *pgo, GeomVertexArrayData *data,
   int n = 0;
   int num_columns = array_format->get_num_columns();
 
-  _vertex_element_type_array = 0;
-
-  VERTEX_ELEMENT_TYPE *vertex_element_type_array;
-
-//  if (scrn._dxgsg9 -> _current_shader_context)
-  {
-    int total_elements;
-    unsigned char vertex_element_type_counter_array [VS_TOTAL_TYPES];
-    VERTEX_ELEMENT_TYPE *vertex_element_type;
-
-    total_elements = num_columns + 2;
-    vertex_element_type_array = new VERTEX_ELEMENT_TYPE [total_elements];
-    memset (vertex_element_type_array, 0, total_elements * sizeof (VERTEX_ELEMENT_TYPE));
-    memset (vertex_element_type_counter_array, 0, sizeof (vertex_element_type_counter_array));
-
-    // create a simple vertex type mapping from the vertex elements
-    vertex_element_type = vertex_element_type_array;
-    for (index = 0; index < num_columns; index++)
-    {
-      int num_values;
-      const InternalName *name;
-
-      name = array_format -> get_column (index) -> get_name ( );
-      num_values = array_format -> get_column(index) -> get_num_values ( );
-
-      if (false) {
-
-      } else if (name -> get_top ( ) == InternalName::get_vertex ( )) {
-
-        switch (num_values)
-        {
-          case 3:
-            vertex_element_type -> vs_input_type = VS_POSITION_XYZ;
-            break;
-          case 4:
-            vertex_element_type -> vs_input_type = VS_POSITION_XYZW;
-            break;
-          default:
-            dxgsg9_cat.warning ( ) << "VERTEX ERROR: invalid number of position coordinate elements " << num_values << "\n";
-            break;
-        }
-
-      } else if (name -> get_top ( ) == InternalName::get_texcoord ( )) {
-
-        switch (num_values)
-        {
-          case 1:
-            vertex_element_type -> vs_input_type = VS_TEXTURE_U;
-            break;
-          case 2:
-            vertex_element_type -> vs_input_type = VS_TEXTURE_UV;
-            break;
-          case 3:
-            vertex_element_type -> vs_input_type = VS_TEXTURE_UVW;
-            break;
-          default:
-            dxgsg9_cat.warning ( ) << "VERTEX ERROR: invalid number of vertex texture coordinate elements " << num_values << "\n";
-            break;
-        }
-
-      } else if (name -> get_top ( ) == InternalName::get_normal ( )) {
-
-        vertex_element_type -> vs_input_type = VS_NORMAL;
-
-      } else if (name -> get_top ( ) == InternalName::get_binormal ( )) {
-
-        vertex_element_type -> vs_input_type = VS_BINORMAL;
-
-      } else if (name -> get_top ( ) == InternalName::get_tangent ( )) {
-
-        vertex_element_type -> vs_input_type = VS_TANGENT;
-
-      } else if (name -> get_top ( ) == InternalName::get_color ( )) {
-
-        vertex_element_type -> vs_input_type = VS_DIFFUSE;
-
-      } else {
-
-        dxgsg9_cat.error ( )
-          << "VERTEX ERROR: unsupported vertex element " << name -> get_name ( )
-          << "\n";
-
-        vertex_element_type -> vs_input_type = VS_ERROR;
-      }
-
-      vertex_element_type -> index = vertex_element_type_counter_array [vertex_element_type -> vs_input_type];
-      vertex_element_type_counter_array [vertex_element_type -> vs_input_type]++;
-
-      // SHADER ISSUE: STREAM INDEX ALWAYS 0 FOR VERTEX BUFFER ???
-      vertex_element_type -> stream = 0;
-      vertex_element_type -> offset = array_format -> get_column(index) -> get_start ( );
-
-      vertex_element_type++;
-    }
-  }
-
-  _vertex_element_type_array = vertex_element_type_array;
-
   _fvf = 0;
-  _managed = -1;
-
-  _direct_3d_vertex_declaration = 0;
-  _shader_context = 0;
 
   if (n < num_columns &&
       array_format->get_column(n)->get_name() == InternalName::get_vertex()) {
+    Geom::Contents contents = array_format->get_column(n)->get_contents();
     ++n;
 
     int num_blend_values = 0;
@@ -263,26 +164,6 @@ DXVertexBufferContext9(PreparedGraphicsObjects *pgo, GeomVertexArrayData *data,
   }
 }
 
-////////////////////////////////////////////////////////////////////
-//     Function: DXVertexBufferContext9::Destructor
-//       Access: Public
-//  Description:
-////////////////////////////////////////////////////////////////////
-DXVertexBufferContext9::
-~DXVertexBufferContext9() {
-
-  if (_vertex_element_type_array) {
-    delete _vertex_element_type_array;
-    _vertex_element_type_array = 0;
-  }
-  if (_direct_3d_vertex_declaration) {
-    _direct_3d_vertex_declaration -> Release ( );
-    _direct_3d_vertex_declaration = 0;
-  }
-
-  free_vbuffer ( );
-}
-
 ////////////////////////////////////////////////////////////////////
 //     Function: DXVertexBufferContext9::evict_lru
 //       Access: Public, Virtual
@@ -298,162 +179,16 @@ DXVertexBufferContext9::
 //               case the eviction will be requested again much
 //               later).
 ////////////////////////////////////////////////////////////////////
-void DXVertexBufferContext9::
+void CLP(VertexBufferContext)::
 evict_lru() {
   dequeue_lru();
-  free_vbuffer();
-  update_data_size_bytes(0);
-  mark_unloaded();
-}
-
-////////////////////////////////////////////////////////////////////
-//     Function: DXVertexBufferContext9::free_vbuffer
-//       Access: Public
-//  Description: Frees vertex buffer memory.
-////////////////////////////////////////////////////////////////////
-void DXVertexBufferContext9::
-free_vbuffer(void) {
-
-  if (_vbuffer != NULL) {
-    if (DEBUG_VERTEX_BUFFER && dxgsg9_cat.is_debug()) {
-      dxgsg9_cat.debug()
-        << "deleting vertex buffer " << _vbuffer << "\n";
-    }
-
-    if (DEBUG_VERTEX_BUFFER) {
-      RELEASE(_vbuffer, dxgsg9, "vertex buffer", RELEASE_ONCE);
-    }
-    else {
-      _vbuffer -> Release ( );
-    }
-
-    _vbuffer = NULL;
-  }
-}
-
-////////////////////////////////////////////////////////////////////
-//     Function: DXVertexBufferContext9::allocate_vbuffer
-//       Access: Public
-//  Description: Allocates vertex buffer memory.
-////////////////////////////////////////////////////////////////////
-void DXVertexBufferContext9::
-allocate_vbuffer(DXScreenData &scrn,
-                 const GeomVertexArrayDataHandle *reader) {
 
-  int data_size;
-  HRESULT hr;
-  DWORD usage;
-  D3DPOOL pool;
-
-  data_size = reader->get_data_size_bytes();
-
-  _managed = scrn._managed_vertex_buffers;
-  if (_managed) {
-    pool = D3DPOOL_MANAGED;
-    usage = D3DUSAGE_WRITEONLY;
-  }
-  else {
-    pool = D3DPOOL_DEFAULT;
-    usage = D3DUSAGE_WRITEONLY | D3DUSAGE_DYNAMIC;
-  }
-
-  int attempts;
-
-  attempts = 0;
-  do
-  {
-    hr = scrn._d3d_device->CreateVertexBuffer
-        (data_size, usage, _fvf, pool, &_vbuffer, NULL);
-    attempts++;
-  }
-  while (scrn._dxgsg9 -> check_dx_allocation (hr, data_size, attempts));
-
-  if (FAILED(hr)) {
-    dxgsg9_cat.warning()
-      << "CreateVertexBuffer failed" << D3DERRORSTRING(hr);
-      
-    printf ("data_size %d \n", data_size);
-    
+  if ( _vbuffer != NULL ) {
+    _vbuffer->Release();
     _vbuffer = NULL;
-  } else {
-    if (DEBUG_VERTEX_BUFFER && dxgsg9_cat.is_debug()) {
-      dxgsg9_cat.debug()
-        << "created vertex buffer " << _vbuffer << ": "
-        << reader->get_num_rows() << " vertices "
-        << *reader->get_array_format() << "\n";
-    }
   }
-}
 
-////////////////////////////////////////////////////////////////////
-//     Function: DXVertexBufferContext9::create_vbuffer
-//       Access: Public
-//  Description: Creates a new vertex buffer (but does not upload data
-//               to it).
-////////////////////////////////////////////////////////////////////
-void DXVertexBufferContext9::
-create_vbuffer(DXScreenData &scrn,
-               const GeomVertexArrayDataHandle *reader,
-               string name) {
-  nassertv(reader->get_object() == get_data());
-  Thread *current_thread = reader->get_current_thread();
-
-  free_vbuffer ( );
-
-  PStatTimer timer(GraphicsStateGuardian::_create_vertex_buffer_pcollector,
-                   current_thread);
-
-  int data_size;
-
-  data_size = reader->get_data_size_bytes();
-
-  this -> allocate_vbuffer(scrn, reader);
+  update_data_size_bytes(0);
+  mark_unloaded();
 }
 
-////////////////////////////////////////////////////////////////////
-//     Function: DXVertexBufferContext9::upload_data
-//       Access: Public
-//  Description: Copies the latest data from the client store to
-//               DirectX.
-////////////////////////////////////////////////////////////////////
-bool DXVertexBufferContext9::
-upload_data(const GeomVertexArrayDataHandle *reader, bool force) {
-  nassertr(reader->get_object() == get_data(), false);
-  nassertr(_vbuffer != NULL, false);
-  Thread *current_thread = reader->get_current_thread();
-
-  const unsigned char *data_pointer = reader->get_read_pointer(force);
-  if (data_pointer == NULL) {
-    return false;
-  }
-  int data_size = reader->get_data_size_bytes();
-
-  if (dxgsg9_cat.is_spam()) {
-    dxgsg9_cat.spam()
-      << "copying " << data_size
-      << " bytes into vertex buffer " << _vbuffer << "\n";
-  }
-  PStatTimer timer(GraphicsStateGuardian::_load_vertex_buffer_pcollector,
-                   current_thread);
-
-  HRESULT hr;
-  BYTE *local_pointer;
-
-  if (_managed) {
-    hr = _vbuffer->Lock(0, data_size, (void **) &local_pointer, 0);
-  }
-  else {
-    hr = _vbuffer->Lock(0, data_size, (void **) &local_pointer, D3DLOCK_DISCARD);
-  }
-  if (FAILED(hr)) {
-    dxgsg9_cat.error()
-      << "VertexBuffer::Lock failed" << D3DERRORSTRING(hr);
-    return false;
-  }
-
-  GraphicsStateGuardian::_data_transferred_pcollector.add_level(data_size);
-  memcpy(local_pointer, data_pointer, data_size);
-
-  _vbuffer->Unlock();
-  return true;
-}

+ 9 - 15
panda/src/dxgsg9/dxVertexBufferContext9.h

@@ -18,33 +18,27 @@
 #include "pandabase.h"
 #include "dxgsg9base.h"
 #include "vertexBufferContext.h"
+#include "deletedChain.h"
+
+class CLP(GraphicsStateGuardian);
 
 ////////////////////////////////////////////////////////////////////
 //       Class : DXVertexBufferContext9
 // Description : Caches a GeomVertexArrayData in the DirectX device as
 //               a vertex buffer.
 ////////////////////////////////////////////////////////////////////
-class EXPCL_PANDADX DXVertexBufferContext9 : public VertexBufferContext {
+class EXPCL_PANDADX CLP(VertexBufferContext) : public VertexBufferContext {
 public:
-  DXVertexBufferContext9(PreparedGraphicsObjects *pgo, GeomVertexArrayData *data, DXScreenData &scrn);
-  virtual ~DXVertexBufferContext9();
+  CLP(VertexBufferContext)(CLP(GraphicsStateGuardian) *dxgsg,
+                           PreparedGraphicsObjects *pgo,
+                           GeomVertexArrayData *data);
+  ALLOC_DELETED_CHAIN(CLP(VertexBufferContext));
 
   virtual void evict_lru();
 
-  void free_vbuffer();
-  void allocate_vbuffer(DXScreenData &scrn, const GeomVertexArrayDataHandle *reader);
-  void create_vbuffer(DXScreenData &scrn, const GeomVertexArrayDataHandle *reader, string name);
-  bool upload_data(const GeomVertexArrayDataHandle *reader, bool force);
-
-  IDirect3DVertexBuffer9 *_vbuffer;
+  LPDIRECT3DVERTEXBUFFER9 _vbuffer;
   int _fvf;
 
-  int _managed;
-
-  VERTEX_ELEMENT_TYPE *_vertex_element_type_array;
-  DIRECT_3D_VERTEX_DECLARATION _direct_3d_vertex_declaration;
-  CLP(ShaderContext) *_shader_context;
-
 public:
   static TypeHandle get_class_type() {
     return _type_handle;

+ 139 - 220
panda/src/dxgsg9/vertexElementArray.cxx

@@ -16,294 +16,213 @@
 #include "vertexElementArray.h"
 
 
-VertexElementArray::VertexElementArray (int maximum_vertex_elements) {
-  this -> offset = 0;
-  this -> total_elements = 0;
-  this -> maximum_vertex_elements = maximum_vertex_elements;
-  this -> total_texture_coordinate_elements = 0;
-  this -> vertex_element_array = new DIRECT_3D_VERTEX_ELEMENT [maximum_vertex_elements];
-  memset (this -> vertex_element_array, 0, sizeof (DIRECT_3D_VERTEX_ELEMENT) * maximum_vertex_elements);
-  this -> vertex_element_type_array = new VERTEX_ELEMENT_TYPE [maximum_vertex_elements];
-  memset (this -> vertex_element_type_array, 0, sizeof (VERTEX_ELEMENT_TYPE) * maximum_vertex_elements);
-
-  memset (this -> vertex_element_type_counter_array, 0, VS_TOTAL_TYPES * sizeof (int));
-}
-
-VertexElementArray::~VertexElementArray ( ) {
-  delete this -> vertex_element_array;
-  delete this -> vertex_element_type_array;
-}
-
-int VertexElementArray::set_vertex_element_offset (int vertex_element_index, int offset) {
-  int state;
-  DIRECT_3D_VERTEX_ELEMENT *vertex_element;
-
-  if (vertex_element_index >= 0 && vertex_element_index < this -> total_elements) {
-    vertex_element = &this -> vertex_element_array [vertex_element_index];
-    vertex_element -> Offset = offset;
-    state = true;
-  }
+VertexElementArray::VertexElementArray(int maximum_vertex_elements) {
+  _total_elements = 0;
+  _maximum_vertex_elements = maximum_vertex_elements;
 
-  return state;
+  _vertex_element_array = new D3DVERTEXELEMENT9[maximum_vertex_elements];
+  memset(_vertex_element_array, 0, sizeof(D3DVERTEXELEMENT9) * maximum_vertex_elements);
 }
 
-void VertexElementArray::set_vs_input_type (int vs_input_type, VERTEX_ELEMENT_TYPE *vertex_element_type) {
-  vertex_element_type -> vs_input_type = vs_input_type;
-  vertex_element_type -> index = vertex_element_type_counter_array [vertex_element_type -> vs_input_type];
-  vertex_element_type_counter_array [vertex_element_type -> vs_input_type]++;
+VertexElementArray::~VertexElementArray() {
+  delete _vertex_element_array;
 }
 
-void VertexElementArray::add_position_xyz_vertex_element (int stream_index) {
-  DIRECT_3D_VERTEX_ELEMENT *vertex_element;
-  VERTEX_ELEMENT_TYPE *vertex_element_type;
-
-  if (this -> total_elements < this -> maximum_vertex_elements) {
-    vertex_element = &this -> vertex_element_array [this -> total_elements];
-    vertex_element_type = &this -> vertex_element_type_array [this -> total_elements];
+void VertexElementArray::add_position_xyz_vertex_element(int stream_index, int offset) {
+  if (_total_elements >= _maximum_vertex_elements) {
+    return;
+  }
 
-    set_vs_input_type (VS_POSITION_XYZ, vertex_element_type);
+  LPD3DVERTEXELEMENT9 vertex_element = &_vertex_element_array[_total_elements];
 
-    vertex_element -> Stream = stream_index;
-    vertex_element -> Offset = this -> offset;
-    vertex_element -> Type = D3DDECLTYPE_FLOAT3;
-    vertex_element -> Method = D3DDECLMETHOD_DEFAULT;
+  vertex_element->Stream = stream_index;
+  vertex_element->Offset = offset;
+  vertex_element->Type = D3DDECLTYPE_FLOAT3;
+  vertex_element->Method = D3DDECLMETHOD_DEFAULT;
 
-    vertex_element -> Usage = D3DDECLUSAGE_POSITION;
-    vertex_element -> UsageIndex = 0;
+  vertex_element->Usage = D3DDECLUSAGE_POSITION;
+  vertex_element->UsageIndex = 0;
 
-    this -> offset += 12;
-    this -> total_elements++;
-  }
+  _total_elements++;
 }
 
-void VertexElementArray::add_position_xyzw_vertex_element (int stream_index) {
-  DIRECT_3D_VERTEX_ELEMENT *vertex_element;
-  VERTEX_ELEMENT_TYPE *vertex_element_type;
-
-  if (this -> total_elements < this -> maximum_vertex_elements) {
-    vertex_element = &this -> vertex_element_array [this -> total_elements];
-    vertex_element_type = &this -> vertex_element_type_array [this -> total_elements];
+void VertexElementArray::add_position_xyzw_vertex_element(int stream_index, int offset) {
+  if (_total_elements >= _maximum_vertex_elements) {
+    return;
+  }
 
-    set_vs_input_type (VS_POSITION_XYZW, vertex_element_type);
+  LPD3DVERTEXELEMENT9 vertex_element = &_vertex_element_array[_total_elements];
 
-    vertex_element -> Stream = stream_index;
-    vertex_element -> Offset = this -> offset;
-    vertex_element -> Type = D3DDECLTYPE_FLOAT4;
-    vertex_element -> Method = D3DDECLMETHOD_DEFAULT;
+  vertex_element->Stream = stream_index;
+  vertex_element->Offset = offset;
+  vertex_element->Type = D3DDECLTYPE_FLOAT4;
+  vertex_element->Method = D3DDECLMETHOD_DEFAULT;
 
-    vertex_element -> Usage = D3DDECLUSAGE_POSITION;
-    vertex_element -> UsageIndex = 0;
+  vertex_element->Usage = D3DDECLUSAGE_POSITION;
+  vertex_element->UsageIndex = 0;
 
-    this -> offset += 16;
-    this -> total_elements++;
-  }
+  _total_elements++;
 }
 
-void VertexElementArray::add_normal_vertex_element (int stream_index) {
-  DIRECT_3D_VERTEX_ELEMENT *vertex_element;
-  VERTEX_ELEMENT_TYPE *vertex_element_type;
-
-  if (this -> total_elements < this -> maximum_vertex_elements) {
-    vertex_element = &this -> vertex_element_array [this -> total_elements];
-    vertex_element_type = &this -> vertex_element_type_array [this -> total_elements];
+void VertexElementArray::add_normal_vertex_element(int stream_index, int offset) {
+  if (_total_elements >= _maximum_vertex_elements) {
+    return;
+  }
 
-    set_vs_input_type (VS_NORMAL, vertex_element_type);
+  LPD3DVERTEXELEMENT9 vertex_element = &_vertex_element_array[_total_elements];
 
-    vertex_element -> Stream = stream_index;
-    vertex_element -> Offset = this -> offset;
-    vertex_element -> Type = D3DDECLTYPE_FLOAT3;
-    vertex_element -> Method = D3DDECLMETHOD_DEFAULT;
+  vertex_element->Stream = stream_index;
+  vertex_element->Offset = offset;
+  vertex_element->Type = D3DDECLTYPE_FLOAT3;
+  vertex_element->Method = D3DDECLMETHOD_DEFAULT;
 
-    vertex_element -> Usage = D3DDECLUSAGE_NORMAL;
-    vertex_element -> UsageIndex = 0;
+  vertex_element->Usage = D3DDECLUSAGE_NORMAL;
+  vertex_element->UsageIndex = 0;
 
-    this -> offset += 12;
-    this -> total_elements++;
-  }
+  _total_elements++;
 }
 
-void VertexElementArray::add_binormal_vertex_element (int stream_index) {
-  DIRECT_3D_VERTEX_ELEMENT *vertex_element;
-  VERTEX_ELEMENT_TYPE *vertex_element_type;
-
-  if (this -> total_elements < this -> maximum_vertex_elements) {
-    vertex_element = &this -> vertex_element_array [this -> total_elements];
-    vertex_element_type = &this -> vertex_element_type_array [this -> total_elements];
+void VertexElementArray::add_binormal_vertex_element(int stream_index, int offset) {
+  if (_total_elements >= _maximum_vertex_elements) {
+    return;
+  }
 
-    set_vs_input_type (VS_BINORMAL, vertex_element_type);
+  LPD3DVERTEXELEMENT9 vertex_element = &_vertex_element_array[_total_elements];
 
-    vertex_element -> Stream = stream_index;
-    vertex_element -> Offset = this -> offset;
-    vertex_element -> Type = D3DDECLTYPE_FLOAT3;
-    vertex_element -> Method = D3DDECLMETHOD_DEFAULT;
+  vertex_element->Stream = stream_index;
+  vertex_element->Offset = offset;
+  vertex_element->Type = D3DDECLTYPE_FLOAT3;
+  vertex_element->Method = D3DDECLMETHOD_DEFAULT;
 
-    vertex_element -> Usage = D3DDECLUSAGE_BINORMAL;
-    vertex_element -> UsageIndex = 0;
+  vertex_element->Usage = D3DDECLUSAGE_BINORMAL;
+  vertex_element->UsageIndex = 0;
 
-    this -> offset += 12;
-    this -> total_elements++;
-  }
+  _total_elements++;
 }
 
-void VertexElementArray::add_tangent_vertex_element (int stream_index) {
-  DIRECT_3D_VERTEX_ELEMENT *vertex_element;
-  VERTEX_ELEMENT_TYPE *vertex_element_type;
-
-  if (this -> total_elements < this -> maximum_vertex_elements) {
-    vertex_element = &this -> vertex_element_array [this -> total_elements];
-    vertex_element_type = &this -> vertex_element_type_array [this -> total_elements];
+void VertexElementArray::add_tangent_vertex_element(int stream_index, int offset) {
+  if (_total_elements >= _maximum_vertex_elements) {
+    return;
+  }
 
-    set_vs_input_type (VS_TANGENT, vertex_element_type);
+  LPD3DVERTEXELEMENT9 vertex_element = &_vertex_element_array[_total_elements];
 
-    vertex_element -> Stream = stream_index;
-    vertex_element -> Offset = this -> offset;
-    vertex_element -> Type = D3DDECLTYPE_FLOAT3;
-    vertex_element -> Method = D3DDECLMETHOD_DEFAULT;
+  vertex_element->Stream = stream_index;
+  vertex_element->Offset = offset;
+  vertex_element->Type = D3DDECLTYPE_FLOAT3;
+  vertex_element->Method = D3DDECLMETHOD_DEFAULT;
 
-    vertex_element -> Usage = D3DDECLUSAGE_TANGENT;
-    vertex_element -> UsageIndex = 0;
+  vertex_element->Usage = D3DDECLUSAGE_TANGENT;
+  vertex_element->UsageIndex = 0;
 
-    this -> offset += 12;
-    this -> total_elements++;
-  }
+  _total_elements++;
 }
 
-void VertexElementArray::add_diffuse_color_vertex_element (int stream_index) {
-  DIRECT_3D_VERTEX_ELEMENT *vertex_element;
-  VERTEX_ELEMENT_TYPE *vertex_element_type;
-
-  if (this -> total_elements < this -> maximum_vertex_elements) {
-    vertex_element = &this -> vertex_element_array [this -> total_elements];
-    vertex_element_type = &this -> vertex_element_type_array [this -> total_elements];
+void VertexElementArray::add_diffuse_color_vertex_element(int stream_index, int offset) {
+  if (_total_elements >= _maximum_vertex_elements) {
+    return;
+  }
 
-    set_vs_input_type (VS_DIFFUSE, vertex_element_type);
+  LPD3DVERTEXELEMENT9 vertex_element = &_vertex_element_array[_total_elements];
 
-    vertex_element -> Stream = stream_index;
-    vertex_element -> Offset = this -> offset;
-    vertex_element -> Type = D3DDECLTYPE_D3DCOLOR;
-    vertex_element -> Method = D3DDECLMETHOD_DEFAULT;
+  vertex_element->Stream = stream_index;
+  vertex_element->Offset = offset;
+  vertex_element->Type = D3DDECLTYPE_D3DCOLOR;
+  vertex_element->Method = D3DDECLMETHOD_DEFAULT;
 
-    vertex_element -> Usage = D3DDECLUSAGE_COLOR;
-    vertex_element -> UsageIndex = 0;
+  vertex_element->Usage = D3DDECLUSAGE_COLOR;
+  vertex_element->UsageIndex = 0;
 
-    this -> offset += 4;
-    this -> total_elements++;
-  }
+  _total_elements++;
 }
 
-void VertexElementArray::add_specular_color_vertex_element (int stream_index) {
-  DIRECT_3D_VERTEX_ELEMENT *vertex_element;
-  VERTEX_ELEMENT_TYPE *vertex_element_type;
-
-  if (this -> total_elements < this -> maximum_vertex_elements) {
-    vertex_element = &this -> vertex_element_array [this -> total_elements];
-    vertex_element_type = &this -> vertex_element_type_array [this -> total_elements];
+void VertexElementArray::add_specular_color_vertex_element(int stream_index, int offset) {
+  if (_total_elements >= _maximum_vertex_elements) {
+    return;
+  }
 
-    set_vs_input_type (VS_SPECULAR, vertex_element_type);
+  LPD3DVERTEXELEMENT9 vertex_element = &_vertex_element_array[_total_elements];
 
-    vertex_element -> Stream = stream_index;
-    vertex_element -> Offset = this -> offset;
-    vertex_element -> Type = D3DDECLTYPE_D3DCOLOR;
-    vertex_element -> Method = D3DDECLMETHOD_DEFAULT;
+  vertex_element->Stream = stream_index;
+  vertex_element->Offset = offset;
+  vertex_element->Type = D3DDECLTYPE_D3DCOLOR;
+  vertex_element->Method = D3DDECLMETHOD_DEFAULT;
 
-    vertex_element -> Usage = D3DDECLUSAGE_COLOR;
-    vertex_element -> UsageIndex = 1;
+  vertex_element->Usage = D3DDECLUSAGE_COLOR;
+  vertex_element->UsageIndex = 1;
 
-    this -> offset += 4;
-    this -> total_elements++;
-  }
+  _total_elements++;
 }
 
-void VertexElementArray::add_u_vertex_element (int stream_index) {
-  DIRECT_3D_VERTEX_ELEMENT *vertex_element;
-  VERTEX_ELEMENT_TYPE *vertex_element_type;
-
-  if (this -> total_elements < this -> maximum_vertex_elements) {
-    vertex_element = &this -> vertex_element_array [this -> total_elements];
-    vertex_element_type = &this -> vertex_element_type_array [this -> total_elements];
+void VertexElementArray::add_u_vertex_element(int stream_index, int offset, int texture_stage) {
+  if (_total_elements >= _maximum_vertex_elements) {
+    return;
+  }
 
-    set_vs_input_type (VS_TEXTURE_U, vertex_element_type);
+  LPD3DVERTEXELEMENT9 vertex_element = &_vertex_element_array[_total_elements];
 
-    vertex_element -> Stream = stream_index;
-    vertex_element -> Offset = this -> offset;
-    vertex_element -> Type = D3DDECLTYPE_FLOAT1;
-    vertex_element -> Method = D3DDECLMETHOD_DEFAULT;
+  vertex_element->Stream = stream_index;
+  vertex_element->Offset = offset;
+  vertex_element->Type = D3DDECLTYPE_FLOAT1;
+  vertex_element->Method = D3DDECLMETHOD_DEFAULT;
 
-    vertex_element -> Usage = D3DDECLUSAGE_TEXCOORD;
-    vertex_element -> UsageIndex = this -> total_texture_coordinate_elements;
-    this -> total_texture_coordinate_elements++;
+  vertex_element->Usage = D3DDECLUSAGE_TEXCOORD;
+  vertex_element->UsageIndex = texture_stage;
 
-    this -> offset += 4;
-    this -> total_elements++;
-  }
+  _total_elements++;
 }
 
-void VertexElementArray::add_uv_vertex_element (int stream_index) {
-  DIRECT_3D_VERTEX_ELEMENT *vertex_element;
-  VERTEX_ELEMENT_TYPE *vertex_element_type;
-
-  if (this -> total_elements < this -> maximum_vertex_elements) {
-    vertex_element = &this -> vertex_element_array [this -> total_elements];
-    vertex_element_type = &this -> vertex_element_type_array [this -> total_elements];
+void VertexElementArray::add_uv_vertex_element(int stream_index, int offset, int texture_stage) {
+  if (_total_elements >= _maximum_vertex_elements) {
+    return;
+  }
 
-    set_vs_input_type (VS_TEXTURE_UV, vertex_element_type);
+  LPD3DVERTEXELEMENT9 vertex_element = &_vertex_element_array[_total_elements];
 
-    vertex_element -> Stream = stream_index;
-    vertex_element -> Offset = this -> offset;
-    vertex_element -> Type = D3DDECLTYPE_FLOAT2;
-    vertex_element -> Method = D3DDECLMETHOD_DEFAULT;
+  vertex_element->Stream = stream_index;
+  vertex_element->Offset = offset;
+  vertex_element->Type = D3DDECLTYPE_FLOAT2;
+  vertex_element->Method = D3DDECLMETHOD_DEFAULT;
 
-    vertex_element -> Usage = D3DDECLUSAGE_TEXCOORD;
-    vertex_element -> UsageIndex = this -> total_texture_coordinate_elements;
-    this -> total_texture_coordinate_elements++;
+  vertex_element->Usage = D3DDECLUSAGE_TEXCOORD;
+  vertex_element->UsageIndex = texture_stage;
 
-    this -> offset += 8;
-    this -> total_elements++;
-  }
+  _total_elements++;
 }
 
-void VertexElementArray::add_uvw_vertex_element (int stream_index) {
-  DIRECT_3D_VERTEX_ELEMENT *vertex_element;
-  VERTEX_ELEMENT_TYPE *vertex_element_type;
-
-  if (this -> total_elements < this -> maximum_vertex_elements) {
-    vertex_element = &this -> vertex_element_array [this -> total_elements];
-    vertex_element_type = &this -> vertex_element_type_array [this -> total_elements];
+void VertexElementArray::add_uvw_vertex_element(int stream_index, int offset, int texture_stage) {
+  if (_total_elements >= _maximum_vertex_elements) {
+    return;
+  }
 
-    set_vs_input_type (VS_TEXTURE_UVW, vertex_element_type);
+  LPD3DVERTEXELEMENT9 vertex_element = &_vertex_element_array[_total_elements];
 
-    vertex_element -> Stream = stream_index;
-    vertex_element -> Offset = this -> offset;
-    vertex_element -> Type = D3DDECLTYPE_FLOAT3;
-    vertex_element -> Method = D3DDECLMETHOD_DEFAULT;
+  vertex_element->Stream = stream_index;
+  vertex_element->Offset = offset;
+  vertex_element->Type = D3DDECLTYPE_FLOAT3;
+  vertex_element->Method = D3DDECLMETHOD_DEFAULT;
 
-    vertex_element -> Usage = D3DDECLUSAGE_TEXCOORD;
-    vertex_element -> UsageIndex = this -> total_texture_coordinate_elements;
-    this -> total_texture_coordinate_elements++;
+  vertex_element->Usage = D3DDECLUSAGE_TEXCOORD;
+  vertex_element->UsageIndex = texture_stage;
 
-    this -> offset += 12;
-    this -> total_elements++;
-  }
+  _total_elements++;
 }
 
-int VertexElementArray::add_end_vertex_element (void) {
-  int add;
-  DIRECT_3D_VERTEX_ELEMENT *vertex_element;
-  VERTEX_ELEMENT_TYPE *vertex_element_type;
-
-  add = FALSE;
-  if (this -> total_elements < this -> maximum_vertex_elements) {
-    vertex_element = &this -> vertex_element_array [this -> total_elements];
-    vertex_element_type = &this -> vertex_element_type_array [this -> total_elements];
+bool VertexElementArray::add_end_vertex_element(void) {
+  if (_total_elements >= _maximum_vertex_elements) {
+    return false;
+  }
 
-    vertex_element_type -> vs_input_type = VS_END;
+  LPD3DVERTEXELEMENT9 vertex_element = &_vertex_element_array[_total_elements];
 
-    vertex_element -> Stream = 0xFF;
-    vertex_element -> Type = D3DDECLTYPE_UNUSED;
+  vertex_element->Stream = 0xFF;
+  vertex_element->Offset = 0;
+  vertex_element->Type = D3DDECLTYPE_UNUSED;
+  vertex_element->Method = 0;
 
-    add = TRUE;
-  }
+  vertex_element->Usage = 0;
+  vertex_element->UsageIndex = 0;
 
-  return add;
+  return true;
 }
 

+ 18 - 50
panda/src/dxgsg9/vertexElementArray.h

@@ -15,36 +15,6 @@
 #ifndef VERTEX_ELEMENT_ARRAY_H
 #define VERTEX_ELEMENT_ARRAY_H
 
-
-enum
-{
-  VS_END = 0,
-
-  VS_POSITION_XYZ,
-  VS_POSITION_XYZW,
-  VS_NORMAL,
-  VS_DIFFUSE,
-  VS_SPECULAR,
-  VS_TEXTURE_U,
-  VS_TEXTURE_UV,
-  VS_TEXTURE_UVW,
-  VS_TANGENT,
-  VS_BINORMAL,
-
-  VS_ERROR,
-
-  VS_TOTAL_TYPES
-};
-
-typedef struct
-{
-  int vs_input_type; // this is VS_XXXXX from the enum above
-  int index;
-  int stream;
-  int offset;
-}
-VERTEX_ELEMENT_TYPE;
-
 ////////////////////////////////////////////////////////////////////
 //       Class : VertexElementArray
 // Description : This class gives the ability for a user-friendly way
@@ -67,28 +37,26 @@ public:
   VertexElementArray (int maximum_vertex_elements);
   ~VertexElementArray ( );
 
-  int set_vertex_element_offset (int vertex_element_index, int offset);
-  void set_vs_input_type (int vs_input_type, VERTEX_ELEMENT_TYPE *vertex_element_type);
+  void add_position_xyz_vertex_element (int stream_index, int offset);
+  void add_position_xyzw_vertex_element (int stream_index, int offset);
+
+  void add_normal_vertex_element (int stream_index, int offset);
+  void add_binormal_vertex_element (int stream_index, int offset);
+  void add_tangent_vertex_element (int stream_index, int offset);
+
+  void add_diffuse_color_vertex_element (int stream_index, int offset);
+  void add_specular_color_vertex_element (int stream_index, int offset);
+
+  void add_u_vertex_element (int stream_index, int offset, int texture_stage);
+  void add_uv_vertex_element (int stream_index, int offset, int texture_stage);
+  void add_uvw_vertex_element (int stream_index, int offset, int texture_stage);
+
+  bool add_end_vertex_element (void);
 
-  void add_position_xyz_vertex_element (int stream_index);
-  void add_position_xyzw_vertex_element (int stream_index);
-  void add_normal_vertex_element (int stream_index);
-  void add_binormal_vertex_element (int stream_index);
-  void add_tangent_vertex_element (int stream_index);
-  void add_diffuse_color_vertex_element (int stream_index);
-  void add_specular_color_vertex_element (int stream_index);
-  void add_u_vertex_element (int stream_index);
-  void add_uv_vertex_element (int stream_index);
-  void add_uvw_vertex_element (int stream_index);
-  int add_end_vertex_element (void);
+  int _total_elements;
+  int _maximum_vertex_elements;
 
-  int offset;
-  int total_elements;
-  int maximum_vertex_elements;
-  int total_texture_coordinate_elements;
-  int vertex_element_type_counter_array [VS_TOTAL_TYPES];
-  DIRECT_3D_VERTEX_ELEMENT *vertex_element_array;
-  VERTEX_ELEMENT_TYPE *vertex_element_type_array;
+  LPD3DVERTEXELEMENT9 _vertex_element_array;
 };
 
 #endif

+ 1 - 1
panda/src/glstuff/glGraphicsStateGuardian_src.cxx

@@ -341,7 +341,7 @@ reset() {
 
   // Build _inv_state_mask as a mask of 1's where we don't care, and
   // 0's where we do care, about the state.
-  _inv_state_mask = RenderState::SlotMask::all_on();
+  //_inv_state_mask = RenderState::SlotMask::all_on();
   _inv_state_mask.clear_bit(ShaderAttrib::get_class_slot());
   _inv_state_mask.clear_bit(AlphaTestAttrib::get_class_slot());
   _inv_state_mask.clear_bit(AntialiasAttrib::get_class_slot());

+ 1 - 1
panda/src/glstuff/glGraphicsStateGuardian_src.h

@@ -652,7 +652,7 @@ public:
   DeletedDisplayLists _deleted_display_lists;
   DeletedDisplayLists _deleted_queries;
 
-  RenderState::SlotMask _inv_state_mask;
+  //RenderState::SlotMask _inv_state_mask;
 
   bool _track_errors;
   bool _allow_flush;

+ 1 - 1
panda/src/gobj/geomVertexArrayFormat.cxx

@@ -476,7 +476,7 @@ output(ostream &out) const {
   for (ci = _columns.begin(); ci != _columns.end(); ++ci) {
     const GeomVertexColumn *column = (*ci);
     if (column->get_start() > last_pos) {
-      out << " ..." << (column->get_start() - last_pos) << "...";
+      out << " (..." << (column->get_start() - last_pos) << "...)";
     }
     out << " " << *column;
     last_pos = column->get_start() + column->get_total_bytes();

+ 5 - 2
panda/src/pgraphnodes/shaderGenerator.cxx

@@ -622,7 +622,10 @@ synthesize_shader(const RenderState *rs) {
   analyze_renderstate(rs);
   reset_register_allocator();
 
-  pgraph_cat.info() << "Generating shader for render state " << rs << "\n";
+  if (pgraph_cat.is_debug()) {
+    pgraph_cat.debug()
+      << "Generating shader for render state " << *rs << "\n";
+  }
 
   // These variables will hold the results of register allocation.
 
@@ -998,7 +1001,7 @@ synthesize_shader(const RenderState *rs) {
   if (_lighting) {
     text << "\t // Begin view-space light calculations\n";
     text << "\t float ldist,lattenv,langle;\n";
-    text << "\t float4 lcolor,lspec,lvec,lpoint,latten,ldir,leye,lhalf;";
+    text << "\t float4 lcolor,lspec,lvec,lpoint,latten,ldir,leye,lhalf;\n";
     if (_shadows && _auto_shadow_on) {
       text << "\t float lshad;\n";
     }

+ 0 - 1
panda/src/tinydisplay/tinyGraphicsStateGuardian.cxx

@@ -95,7 +95,6 @@ reset() {
 
   // Build _inv_state_mask as a mask of 1's where we don't care, and
   // 0's where we do care, about the state.
-  _inv_state_mask = RenderState::SlotMask::all_on();
   _inv_state_mask.clear_bit(ColorAttrib::get_class_slot());
   _inv_state_mask.clear_bit(ColorScaleAttrib::get_class_slot());
   _inv_state_mask.clear_bit(CullFaceAttrib::get_class_slot());

+ 0 - 1
panda/src/tinydisplay/tinyGraphicsStateGuardian.h

@@ -170,7 +170,6 @@ private:
   bool _texture_replace;
   bool _filled_flat;
   bool _auto_rescale_normal;
-  RenderState::SlotMask _inv_state_mask;
 
   CPT(TransformState) _scissor_mat;
 

Some files were not shown because too many files changed in this diff