Browse Source

add retained mode (display list) support

David Rose 24 years ago
parent
commit
123223a153

+ 2 - 1
panda/src/glgsg/Sources.pp

@@ -14,7 +14,8 @@
     config_glgsg.cxx config_glgsg.h glGraphicsStateGuardian.I \
     glGraphicsStateGuardian.cxx glGraphicsStateGuardian.h \
     glSavedFrameBuffer.I glSavedFrameBuffer.cxx glSavedFrameBuffer.h \
-    glTextureContext.I glTextureContext.cxx glTextureContext.h
+    glTextureContext.I glGeomNodeContext.I glGeomNodeContext.cxx \
+    glGeomNodeContext.h glTextureContext.cxx glTextureContext.h
 
   #define INSTALL_HEADERS \
     config_glgsg.h glGraphicsStateGuardian.I glGraphicsStateGuardian.h

+ 2 - 0
panda/src/glgsg/config_glgsg.cxx

@@ -20,6 +20,7 @@
 #include "glGraphicsStateGuardian.h"
 #include "glSavedFrameBuffer.h"
 #include "glTextureContext.h"
+#include "glGeomNodeContext.h"
 
 #include <dconfig.h>
 
@@ -103,6 +104,7 @@ init_libglgsg() {
   GLGraphicsStateGuardian::init_type();
   GLSavedFrameBuffer::init_type();
   GLTextureContext::init_type();
+  GLGeomNodeContext::init_type();
 
   GraphicsStateGuardian::get_factory().register_factory
     (GLGraphicsStateGuardian::get_class_type(),

+ 30 - 0
panda/src/glgsg/glGeomNodeContext.I

@@ -0,0 +1,30 @@
+// Filename: glGeomNodeContext.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: GLGeomNodeContext::Constructor
+//       Access: Public
+//  Description:
+////////////////////////////////////////////////////////////////////
+INLINE GLGeomNodeContext::
+GLGeomNodeContext(GeomNode *node) :
+  GeomNodeContext(node)
+{
+  _index = 0;
+}

+ 21 - 0
panda/src/glgsg/glGeomNodeContext.cxx

@@ -0,0 +1,21 @@
+// Filename: glGeomNodeContext.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 "glGeomNodeContext.h"
+
+TypeHandle GLGeomNodeContext::_type_handle;

+ 74 - 0
panda/src/glgsg/glGeomNodeContext.h

@@ -0,0 +1,74 @@
+// Filename: glGeomNodeContext.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 GLGEOMNODECONTEXT_H
+#define GLGEOMNODECONTEXT_H
+
+#include <pandabase.h>
+
+#ifdef WIN32_VC
+// Must include windows.h before gl.h on NT
+#define WIN32_LEAN_AND_MEAN
+#include <windows.h>
+#undef WIN32_LEAN_AND_MEAN
+#endif
+
+#include <GL/gl.h>
+#include <geomNodeContext.h>
+#include <geomNode.h>
+#include "pvector.h"
+
+////////////////////////////////////////////////////////////////////
+//       Class : GLGeomNodeContext
+// Description :
+////////////////////////////////////////////////////////////////////
+class EXPCL_PANDAGL GLGeomNodeContext : public GeomNodeContext {
+public:
+  INLINE GLGeomNodeContext(GeomNode *node);
+
+  // The GL display list index that draws the contents of this
+  // GeomNode.
+  GLuint _index;
+
+  // 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;
+
+public:
+  static TypeHandle get_class_type() {
+    return _type_handle;
+  }
+  static void init_type() {
+    GeomNodeContext::init_type();
+    register_type(_type_handle, "GLGeomNodeContext",
+                  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 "glGeomNodeContext.I"
+
+#endif
+

+ 125 - 0
panda/src/glgsg/glGraphicsStateGuardian.cxx

@@ -19,6 +19,7 @@
 #include "glGraphicsStateGuardian.h"
 #include "glSavedFrameBuffer.h"
 #include "glTextureContext.h"
+#include "glGeomNodeContext.h"
 #include "config_glgsg.h"
 
 #include <config_util.h>
@@ -1771,6 +1772,130 @@ release_texture(TextureContext *tc) {
   report_errors();
 }
 
+////////////////////////////////////////////////////////////////////
+//     Function: GLGraphicsStateGuardian::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 *GLGraphicsStateGuardian::
+prepare_geom_node(GeomNode *node) {
+  // 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;
+  for (int 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.
+  GLGeomNodeContext *ggnc = new GLGeomNodeContext(node);
+  ggnc->_index = glGenLists(1);
+  if (ggnc->_index == 0) {
+    glgsg_cat.error()
+      << "Ran out of display list indices.\n";
+    delete ggnc;
+    return (GeomNodeContext *)NULL;
+  }
+
+  // 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;
+  _normals_enabled = true;
+  _texturing_enabled = true;
+
+  // Now define the display list.
+  glNewList(ggnc->_index, GL_COMPILE);
+  for (int 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);
+    }
+  }
+  glEndList();
+
+  _normals_enabled = old_normals_enabled;
+  _texturing_enabled = old_texturing_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;
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: GLGraphicsStateGuardian::draw_geom_node
+//       Access: Public, Virtual
+//  Description: Draws a GeomNode previously indicated by a call to
+//               prepare_geom_node().
+////////////////////////////////////////////////////////////////////
+void GLGraphicsStateGuardian::
+draw_geom_node(GeomNode *node, GeomNodeContext *gnc) {
+  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);
+    GLGeomNodeContext *ggnc = DCAST(GLGeomNodeContext, gnc);
+    glCallList(ggnc->_index);
+
+    // 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);
+    }
+  }
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: GLGraphicsStateGuardian::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 GLGraphicsStateGuardian::
+release_geom_node(GeomNodeContext *gnc) {
+  if (gnc != (GeomNodeContext *)NULL) {
+    GLGeomNodeContext *ggnc = DCAST(GLGeomNodeContext, gnc);
+    glDeleteLists(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;
+  }
+}
+
 static int logs[] = { 1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048,
                       4096, 0 };
 

+ 4 - 0
panda/src/glgsg/glGraphicsStateGuardian.h

@@ -102,6 +102,10 @@ public:
   virtual void apply_texture(TextureContext *tc);
   virtual void release_texture(TextureContext *tc);
 
+  virtual GeomNodeContext *prepare_geom_node(GeomNode *node);
+  virtual void draw_geom_node(GeomNode *node, GeomNodeContext *gnc);
+  virtual void release_geom_node(GeomNodeContext *gnc);
+
   virtual void copy_texture(TextureContext *tc, const DisplayRegion *dr);
   virtual void copy_texture(TextureContext *tc, const DisplayRegion *dr,
                             const RenderBuffer &rb);