add retained mode (display list) support

This commit is contained in:
David Rose 2001-06-12 23:53:52 +00:00
parent dbe2e6caea
commit 123223a153
7 changed files with 258 additions and 1 deletions

View File

@ -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

View File

@ -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(),

View File

@ -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
// panda3d@yahoogroups.com .
//
////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////
// Function: GLGeomNodeContext::Constructor
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
INLINE GLGeomNodeContext::
GLGeomNodeContext(GeomNode *node) :
GeomNodeContext(node)
{
_index = 0;
}

View File

@ -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
// panda3d@yahoogroups.com .
//
////////////////////////////////////////////////////////////////////
#include "glGeomNodeContext.h"
TypeHandle GLGeomNodeContext::_type_handle;

View File

@ -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
// panda3d@yahoogroups.com .
//
////////////////////////////////////////////////////////////////////
#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

View File

@ -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 };

View File

@ -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);