浏览代码

stubs for geomnodectx

cxgeorge 24 年之前
父节点
当前提交
900d965a20

+ 2 - 2
panda/src/dxgsg/Sources.pp

@@ -17,10 +17,10 @@
     config_dxgsg.h dxGraphicsStateGuardian.I \
     dxGraphicsStateGuardian.cxx dxGraphicsStateGuardian.h \
     dxSavedFrameBuffer.I dxSavedFrameBuffer.h \
-    dxTextureContext.I dxTextureContext.h
+    dxTextureContext.I dxTextureContext.h dxGeomNodeContext.h dxGeomNodeContext.I
     
   #define INCLUDED_SOURCES \
-    config_dxgsg.cxx dxSavedFrameBuffer.cxx dxTextureContext.cxx 
+    config_dxgsg.cxx dxSavedFrameBuffer.cxx dxTextureContext.cxx dxGeomNodeContext.cxx
     
   #define INSTALL_HEADERS \
     config_dxgsg.h dxGraphicsStateGuardian.I dxGraphicsStateGuardian.h \

+ 32 - 0
panda/src/dxgsg/dxGeomNodeContext.I

@@ -0,0 +1,32 @@
+// Filename: dxGeomNodeContext.I
+// Created by:  drose (12Jun01)
+//
+////////////////////////////////////////////////////////////////////
+//
+// PANDA 3D SOFTWARE
+// Copyright (c) 2001, Disney Enterprises, Inc.  All rights reserved
+//
+// All use of this software is subject to the terms of the Panda 3d
+// Software license.  You should have received a copy of this license
+// along with this source code; you will also find a current copy of
+// the license at http://www.panda3d.org/license.txt .
+//
+// To contact the maintainers of this program write to
+// [email protected] .
+//
+////////////////////////////////////////////////////////////////////
+
+
+////////////////////////////////////////////////////////////////////
+//     Function: dxGeomNodeContext::Constructor
+//       Access: Public
+//  Description:
+////////////////////////////////////////////////////////////////////
+INLINE DXGeomNodeContext::
+DXGeomNodeContext(GeomNode *node) :
+  GeomNodeContext(node)
+{
+#ifdef DO_PSTATS
+  _num_verts = 0;
+#endif
+}

+ 21 - 0
panda/src/dxgsg/dxGeomNodeContext.cxx

@@ -0,0 +1,21 @@
+// Filename: dxGeomNodeContext.cxx
+// Created by:  drose (12Jun01)
+//
+////////////////////////////////////////////////////////////////////
+//
+// PANDA 3D SOFTWARE
+// Copyright (c) 2001, Disney Enterprises, Inc.  All rights reserved
+//
+// All use of this software is subject to the terms of the Panda 3d
+// Software license.  You should have received a copy of this license
+// along with this source code; you will also find a current copy of
+// the license at http://www.panda3d.org/license.txt .
+//
+// To contact the maintainers of this program write to
+// [email protected] .
+//
+////////////////////////////////////////////////////////////////////
+
+#include "dxGeomNodeContext.h"
+
+TypeHandle DXGeomNodeContext::_type_handle;

+ 80 - 0
panda/src/dxgsg/dxGeomNodeContext.h

@@ -0,0 +1,80 @@
+// Filename: dxGeomNodeContext.h
+// Created by:  drose (12Jun01)
+//
+////////////////////////////////////////////////////////////////////
+//
+// PANDA 3D SOFTWARE
+// Copyright (c) 2001, Disney Enterprises, Inc.  All rights reserved
+//
+// All use of this software is subject to the terms of the Panda 3d
+// Software license.  You should have received a copy of this license
+// along with this source code; you will also find a current copy of
+// the license at http://www.panda3d.org/license.txt .
+//
+// To contact the maintainers of this program write to
+// [email protected] .
+//
+////////////////////////////////////////////////////////////////////
+
+#ifndef DXGEOMNODECONTEXT_H
+#define DXGEOMNODECONTEXT_H
+
+#include <pandabase.h>
+
+#ifdef WIN32_VC
+// Must include windows.h before dx.h on NT
+#define WIN32_LEAN_AND_MEAN
+#include <windows.h>
+#undef WIN32_LEAN_AND_MEAN
+#endif
+
+#include <geomNodeContext.h>
+#include <geomNode.h>
+#include "pvector.h"
+
+////////////////////////////////////////////////////////////////////
+//       Class : DXGeomNodeContext
+// Description :
+////////////////////////////////////////////////////////////////////
+class EXPCL_PANDADX DXGeomNodeContext : public GeomNodeContext {
+public:
+  INLINE DXGeomNodeContext(GeomNode *node);
+
+#if 0
+  // The DX display list index that draws the contents of this
+  // GeomNode.
+  DXuint _index;
+#endif
+  // A list of the dynamic Geoms within the GeomNode; these aren't
+  // part of the above display list.
+  typedef pvector<PT(dDrawable) > Geoms;
+  Geoms _dynamic_geoms;
+
+#ifdef DO_PSTATS
+  // The number of vertices represented by the display list.  This is
+  // strictly for the benefit of PStats reporting.
+  int _num_verts;
+#endif
+
+public:
+  static TypeHandle get_class_type() {
+    return _type_handle;
+  }
+  static void init_type() {
+    GeomNodeContext::init_type();
+    register_type(_type_handle, "DXGeomNodeContext",
+                  GeomNodeContext::get_class_type());
+  }
+  virtual TypeHandle get_type() const {
+    return get_class_type();
+  }
+  virtual TypeHandle force_init_type() {init_type(); return get_class_type();}
+
+private:
+  static TypeHandle _type_handle;
+};
+
+#include "dxGeomNodeContext.I"
+
+#endif
+

+ 212 - 16
panda/src/dxgsg/dxGraphicsStateGuardian.cxx

@@ -85,7 +85,6 @@
 
 #include <mmsystem.h>
 
-
 // print out simple drawprim stats every few secs
 //#define COUNT_DRAWPRIMS
 
@@ -127,13 +126,26 @@ static D3DMATRIX matIdentity;
 #define Colorf_to_D3DCOLOR(out_color) (D3DRGBA((out_color)[0], (out_color)[1], (out_color)[2], (out_color)[3]))
 
 #ifdef COUNT_DRAWPRIMS
+
 static DWORD cDPcount=0;
 static DWORD cVertcount=0;
 static DWORD cTricount=0;
+static DWORD cGeomcount=0;
+
+static LPDIRECTDRAWSURFACE7 pLastTexture=NULL;
+static DWORD cDP_noTexChangeCount=0;
+static LPDIRECT3DDEVICE7 global_pD3DDevice = NULL;
+
 static void CountDPs(DWORD nVerts,DWORD nTris) {
     cDPcount++;
     cVertcount+=nVerts;
     cTricount+=nTris;
+
+    LPDIRECTDRAWSURFACE7 pCurTexture;
+    global_pD3DDevice->GetTexture(0,&pCurTexture);
+    if(pCurTexture==pLastTexture) {
+        cDP_noTexChangeCount++;
+    } else pLastTexture = pCurTexture;
 }
 #else
 #define CountDPs(nv,nt)
@@ -307,6 +319,10 @@ init_dx(  LPDIRECTDRAW7     context,
     _d3dDevice = pDevice;
     _view_rect = viewrect;
 
+#ifdef COUNT_DRAWPRIMS
+     global_pD3DDevice = pDevice;
+#endif
+
     _last_testcooplevel_result = S_OK;
 
     HRESULT hr;
@@ -885,21 +901,29 @@ render_frame(const AllAttributesWrapper &initial_state) {
             float verts_per_frame = cVertcount/numframes;
             float tris_per_frame = cTricount/numframes;
             float DPs_per_frame = cDPcount/numframes;
+            float DPs_notexchange_per_frame = cDP_noTexChangeCount/numframes;
             float verts_per_DP = cVertcount/(float)cDPcount;
             float verts_per_sec = cVertcount/delta_secs;
             float tris_per_sec = cTricount/delta_secs;
+            float Geoms_per_frame = cGeomcount/numframes;
+            float DrawPrims_per_Geom = cDPcount/(float)cGeomcount;
+            float verts_per_Geom = cVertcount/(float)cGeomcount;
 
-            dxgsg_cat.spam() 
+            dxgsg_cat.spam() << "==================================="
                 << "\n Avg Verts/sec:\t\t" << verts_per_sec
                 << "\n Avg Tris/sec:\t\t" << tris_per_sec
                 << "\n Avg Verts/frame:\t" << verts_per_frame
                 << "\n Avg Tris/frame:\t" << tris_per_frame
                 << "\n Avg DrawPrims/frm:\t" << DPs_per_frame
                 << "\n Avg Verts/DrawPrim:\t" << verts_per_DP 
+                << "\n Avg DrawPrims w/no Texture Change from prev DrawPrim/frm:\t" << DPs_notexchange_per_frame
+                << "\n Avg Geoms/frm:\t" << Geoms_per_frame
+                << "\n Avg DrawPrims/Geom:\t" << DrawPrims_per_Geom
+                << "\n Avg Verts/Geom:\t" << verts_per_Geom
                 << endl;
 
             LastDPInfoFrame=_cur_frame_count;
-            cDPcount = cVertcount=cTricount=0;
+            cDPcount = cVertcount=cTricount=cDP_noTexChangeCount=cGeomcount=0;
             LastTickCount=CurTickCount;
         }
     }
@@ -1167,7 +1191,7 @@ typedef enum {DrawPrim,DrawPrimStrided} DP_Type;
 
 void INLINE TestDrawPrimFailure(DP_Type dptype,HRESULT hr,LPDIRECTDRAW7 pDD,DWORD nVerts,DWORD nTris) {
         if(FAILED(hr)) {
-            // loss of exclusive mode is not a real DrawPrim problem
+            // loss of exclusive mode is not a real DrawPrim problem, ignore it
             HRESULT testcooplvl_hr = pDD->TestCooperativeLevel();
             if((testcooplvl_hr != DDERR_NOEXCLUSIVEMODE)||(testcooplvl_hr != DDERR_EXCLUSIVEMODEALREADYSET)) {
                 dxgsg_cat.fatal() << ((dptype==DrawPrimStrided) ? "DrawPrimStrided" : "DrawPrim") << " failed: result = " << ConvD3DErrorToString(hr) << endl;
@@ -2136,6 +2160,10 @@ draw_tri(GeomTri *geom, GeomContext *gc) {
     }
 #endif
 
+#ifdef COUNT_DRAWPRIMS
+    cGeomcount++;
+#endif
+
     int nPrims = geom->get_num_prims();
     HRESULT hr;
 
@@ -2460,13 +2488,17 @@ draw_multitri(Geom *geom, D3DPRIMITIVETYPE trilisttype) {
     const int *pLengthArr = geom->get_lengths();
     HRESULT hr;
 
-    if (nPrims==0) {
+    if(nPrims==0) {
         #ifdef _DEBUG
           dxgsg_cat.warning() << "draw_multitri() called with ZERO vertices!!" << endl;
         #endif
         return;
     }
 
+#ifdef COUNT_DRAWPRIMS
+    cGeomcount++;
+#endif
+
     PTA_Vertexf coords;
     PTA_Normalf norms;
     PTA_Colorf colors;
@@ -2486,19 +2518,18 @@ draw_multitri(Geom *geom, D3DPRIMITIVETYPE trilisttype) {
 #else
     GeomVrtFmt=FlatVerts;
 
-    // first determine if we're indexed or non-indexed
-
-    if ((vindexes!=NULL)&&(cindexes!=NULL)&&(tindexes!=NULL)&&(nindexes!=NULL)) {
-        GeomVrtFmt=IndexedVerts;
-        //make sure array sizes are consistent, we can only pass 1 size to DrawIPrm
-        //      nassertv(coords.size==norms.size);      nassertv(coords.size==colors.size);     nassertv(coords.size==texcoords.size);  need to assert only if we have this w/same binding
-        // indexed mode requires all used norms,colors,texcoords,coords array be the same
-        // length, or 0 or 1 (dwStride==0), also requires all elements to use the same index array
-    } else if (!((vindexes==NULL)&&(cindexes==NULL)&&(tindexes==NULL)&&(nindexes==NULL)))
-        GeomVrtFmt=MixedFmtVerts;
-
     if(!geom->uses_components()) {
        GeomVrtFmt=MixedFmtVerts; // dont need efficiency here, just use simpler codepath
+    } else {
+        // first determine if we're indexed or non-indexed
+        if((vindexes!=NULL)&&(cindexes!=NULL)&&(tindexes!=NULL)&&(nindexes!=NULL)) {
+            GeomVrtFmt=IndexedVerts;
+            //make sure array sizes are consistent, we can only pass 1 size to DrawIPrm
+            //      nassertv(coords.size==norms.size);      nassertv(coords.size==colors.size);     nassertv(coords.size==texcoords.size);  need to assert only if we have this w/same binding
+            // indexed mode requires all used norms,colors,texcoords,coords array be the same
+            // length, or 0 or 1 (dwStride==0), also requires all elements to use the same index array
+        } else if (!((vindexes==NULL)&&(cindexes==NULL)&&(tindexes==NULL)&&(nindexes==NULL)))
+            GeomVrtFmt=MixedFmtVerts;
     }
 #endif
 
@@ -5939,3 +5970,168 @@ HRESULT SetViewMatrix( D3DMATRIX& mat, D3DVECTOR& vFrom, D3DVECTOR& vAt,
 }
 
 #endif
+
+
+////////////////////////////////////////////////////////////////////
+//     Function: DXGraphicsStateGuardian::prepare_geom_node
+//       Access: Public, Virtual
+//  Description: Prepares the indicated GeomNode for retained-mode
+//               rendering.  If this function returns non-NULL, the
+//               value returned will be passed back to a future call
+//               to draw_geom_node(), which is expected to draw the
+//               contents of the node.
+////////////////////////////////////////////////////////////////////
+GeomNodeContext *DXGraphicsStateGuardian::
+prepare_geom_node(GeomNode *node) {
+#if 1
+  return NULL;
+#else
+  // Make sure we have at least some static Geoms in the GeomNode;
+  // otherwise there's no point in building a display list.
+  int num_geoms = node->get_num_geoms();
+  bool all_dynamic = true;
+  int i;
+
+  for (i = 0; (i < num_geoms) && all_dynamic; i++) {
+    dDrawable *geom = node->get_geom(i);
+    all_dynamic = geom->is_dynamic();
+  }
+  if (all_dynamic) {
+    // Never mind.
+    return (GeomNodeContext *)NULL;
+  }
+
+  // Ok, we've got something; use it.
+  DXGeomNodeContext *ggnc = new DXGeomNodeContext(node);
+
+#if 0
+  ggnc->_index = DXGenLists(1);
+  if (ggnc->_index == 0) {
+    DXgsg_cat.error() << "Ran out of display list indices.\n";
+    delete ggnc;
+    return (GeomNodeContext *)NULL;
+  }
+#endif
+
+  // We need to temporarily force normals and UV's on, so the display
+  // list will have them built in.
+  bool old_normals_enabled = _normals_enabled;
+  bool old_texturing_enabled = _texturing_enabled;
+  bool old_vertex_colors_enabled = _vertex_colors_enabled;
+  _normals_enabled = true;
+  _texturing_enabled = true;
+  _vertex_colors_enabled = true;
+
+#ifdef DO_PSTATS
+  // Count up the number of vertices we're about to render, by
+  // checking the PStats vertex counters now, and at the end.  This is
+  // kind of hacky, but this is debug code.
+  float num_verts_before = 
+    _vertices_tristrip_pcollector.get_level() +
+    _vertices_trifan_pcollector.get_level() +
+    _vertices_tri_pcollector.get_level() +
+    _vertices_other_pcollector.get_level();
+#endif
+
+  // Now define the display list.
+  DXNewList(ggnc->_index, DX_COMPILE);
+  for (i = 0; i < num_geoms; i++) {
+    dDrawable *geom = node->get_geom(i);
+    if (geom->is_dynamic()) {
+      // Wait, this is a dynamic Geom.  We can't safely put it in the
+      // display list, because it may change from one frame to the
+      // next; instead, we'll keep it out.
+      ggnc->_dynamic_geoms.push_back(geom);
+    } else {
+      // A static Geom becomes part of the display list.
+      geom->draw(this);
+    }
+  }
+  DXEndList();
+
+#ifdef DO_PSTATS
+  float num_verts_after = 
+    _vertices_tristrip_pcollector.get_level() +
+    _vertices_trifan_pcollector.get_level() +
+    _vertices_tri_pcollector.get_level() +
+    _vertices_other_pcollector.get_level();
+  float num_verts = num_verts_after - num_verts_before;
+  ggnc->_num_verts = (int)(num_verts + 0.5);
+#endif
+
+  _normals_enabled = old_normals_enabled;
+  _texturing_enabled = old_texturing_enabled;
+  _vertex_colors_enabled = old_vertex_colors_enabled;
+
+  bool inserted = mark_prepared_geom_node(ggnc);
+
+  // If this assertion fails, the same GeomNode was prepared twice,
+  // which shouldn't be possible, since the GeomNode itself should
+  // detect this.
+  nassertr(inserted, NULL);
+
+  return ggnc;
+#endif
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: DXGraphicsStateGuardian::draw_geom_node
+//       Access: Public, Virtual
+//  Description: Draws a GeomNode previously indicated by a call to
+//               prepare_geom_node().
+////////////////////////////////////////////////////////////////////
+void DXGraphicsStateGuardian::
+draw_geom_node(GeomNode *node, GeomNodeContext *gnc) {
+#if 0
+  if (gnc == (GeomNodeContext *)NULL) {
+    // We don't have a saved context; just draw the GeomNode in
+    // immediate mode.
+    int num_geoms = node->get_num_geoms();
+    for (int i = 0; i < num_geoms; i++) {
+      node->get_geom(i)->draw(this);
+    }
+
+  } else {
+    // We do have a saved context; use it.
+    add_to_geom_node_record(gnc);
+    DXGeomNodeContext *ggnc = DCAST(DXGeomNodeContext, gnc);
+    DXCallList(ggnc->_index);
+
+#ifdef DO_PSTATS
+    _vertices_display_list_pcollector.add_level(ggnc->_num_verts);
+#endif
+
+    // Also draw all the dynamic Geoms.
+    int num_geoms = ggnc->_dynamic_geoms.size();
+    for (int i = 0; i < num_geoms; i++) {
+      ggnc->_dynamic_geoms[i]->draw(this);
+    }
+  }
+#endif
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: DXGraphicsStateGuardian::release_geom_node
+//       Access: Public, Virtual
+//  Description: Frees the resources previously allocated via a call
+//               to prepare_geom_node(), including deleting the
+//               GeomNodeContext itself, if necessary.
+////////////////////////////////////////////////////////////////////
+void DXGraphicsStateGuardian::
+release_geom_node(GeomNodeContext *gnc) {
+#if 0
+  if (gnc != (GeomNodeContext *)NULL) {
+    DXGeomNodeContext *ggnc = DCAST(DXGeomNodeContext, gnc);
+    DXDeleteLists(ggnc->_index, 1);
+
+    bool erased = unmark_prepared_geom_node(ggnc);
+
+    // If this assertion fails, a GeomNode was released that hadn't
+    // been prepared (or a GeomNode was released twice).
+    nassertv(erased);
+    
+    ggnc->_node->clear_gsg(this);
+    delete ggnc;
+  }
+#endif
+}

+ 5 - 0
panda/src/dxgsg/dxGraphicsStateGuardian.h

@@ -40,6 +40,7 @@
 #include <pointerToArray.h>
 #include <planeNode.h>
 
+#include "dxGeomNodeContext.h"
 #include "dxTextureContext.h"
 
 extern char * ConvD3DErrorToString(const HRESULT &error);   // defined in wdxGraphicsPipe.cxx
@@ -121,6 +122,10 @@ public:
   virtual void draw_trifan(GeomTrifan *geom, GeomContext *gc);
   virtual void draw_sphere(GeomSphere *geom, GeomContext *gc);
 
+  virtual GeomNodeContext *prepare_geom_node(GeomNode *node);
+  virtual void draw_geom_node(GeomNode *node, GeomNodeContext *gnc);
+  virtual void release_geom_node(GeomNodeContext *gnc);
+
   virtual TextureContext *prepare_texture(Texture *tex);
   virtual void apply_texture(TextureContext *tc);
   virtual void release_texture(TextureContext *tc);

+ 1 - 0
panda/src/dxgsg/dxgsg_composite1.cxx

@@ -1,3 +1,4 @@
 #include "config_dxgsg.cxx"
 #include "dxSavedFrameBuffer.cxx"
 #include "dxTextureContext.cxx"
+#include "dxGeomNodeContext.cxx"