Browse Source

fiddly bits

David Rose 17 years ago
parent
commit
230d7825d3

+ 13 - 0
panda/src/display/graphicsStateGuardian.I

@@ -612,6 +612,19 @@ get_alpha_scale_texture_stage() {
   return _alpha_scale_texture_stage;
 }
 
+////////////////////////////////////////////////////////////////////
+//     Function: GraphicsStateGuardian::get_runtime_color_scale
+//       Access: Published
+//  Description: Returns true if this particular GSG can implement (or
+//               would prefer to implement) set color and/or color
+//               scale directly, without requiring any munging of
+//               vertices or tricks with lighting.
+////////////////////////////////////////////////////////////////////
+INLINE bool GraphicsStateGuardian::
+get_runtime_color_scale() const {
+  return _runtime_color_scale;
+}
+
 ////////////////////////////////////////////////////////////////////
 //     Function: GraphicsStateGuardian::get_coordinate_system
 //       Access: Published

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

@@ -201,6 +201,10 @@ GraphicsStateGuardian(CoordinateSystem internal_coordinate_system,
   // scaling.
   _alpha_scale_via_texture = alpha_scale_via_texture;
 
+  // Few GSG's can do this, since it requires touching each vertex as
+  // it is rendered.
+  _runtime_color_scale = false;
+
   _stencil_render_states = 0;
 
   // The default is no shader support.

+ 3 - 1
panda/src/display/graphicsStateGuardian.h

@@ -103,7 +103,7 @@ PUBLISHED:
   virtual INLINE int get_max_vertices_per_primitive() const;
 
   INLINE int get_max_texture_stages() const;
-  INLINE int get_max_texture_dimension() const;
+  virtual INLINE int get_max_texture_dimension() const;
   INLINE int get_max_3d_texture_dimension() const;
   INLINE int get_max_cube_map_dimension() const;
 
@@ -142,6 +142,7 @@ PUBLISHED:
   INLINE bool get_color_scale_via_lighting() const;
   INLINE bool get_alpha_scale_via_texture() const;
   INLINE bool get_alpha_scale_via_texture(const TextureAttrib *tex_attrib) const;
+  INLINE bool get_runtime_color_scale() const;
 
   INLINE static TextureStage *get_alpha_scale_texture_stage();
 
@@ -397,6 +398,7 @@ protected:
   int  _supported_geom_rendering;
   bool _color_scale_via_lighting;
   bool _alpha_scale_via_texture;
+  bool _runtime_color_scale;
 
   int  _stereo_buffer_mask;
 

+ 41 - 38
panda/src/display/standardMunger.cxx

@@ -48,46 +48,49 @@ StandardMunger(GraphicsStateGuardianBase *gsg, const RenderState *state,
   _munge_color = false;
   _munge_color_scale = false;
 
-  CPT(ColorAttrib) color_attrib = state->get_color();
-  CPT(ColorScaleAttrib) color_scale_attrib = state->get_color_scale();
-
-  if (color_attrib != (ColorAttrib *)NULL && 
-      color_attrib->get_color_type() == ColorAttrib::T_flat) {
-
-    if (!get_gsg()->get_color_scale_via_lighting()) {
-      // We only need to munge the color directly if the GSG says it
-      // can't cheat the color via lighting (presumably, in this case,
-      // by applying a material).
-      _color = color_attrib->get_color();
-      if (color_scale_attrib != (ColorScaleAttrib *)NULL &&
-          color_scale_attrib->has_scale()) {
-        const LVecBase4f &cs = color_scale_attrib->get_scale();
-        _color.set(_color[0] * cs[0],
-                   _color[1] * cs[1],
-                   _color[2] * cs[2],
-                   _color[3] * cs[3]);
+  if (!get_gsg()->get_runtime_color_scale()) {
+    // We might need to munge the colors.
+    CPT(ColorAttrib) color_attrib = state->get_color();
+    CPT(ColorScaleAttrib) color_scale_attrib = state->get_color_scale();
+
+    if (color_attrib != (ColorAttrib *)NULL && 
+        color_attrib->get_color_type() == ColorAttrib::T_flat) {
+      
+      if (!get_gsg()->get_color_scale_via_lighting()) {
+        // We only need to munge the color directly if the GSG says it
+        // can't cheat the color via lighting (presumably, in this case,
+        // by applying a material).
+        _color = color_attrib->get_color();
+        if (color_scale_attrib != (ColorScaleAttrib *)NULL &&
+            color_scale_attrib->has_scale()) {
+          const LVecBase4f &cs = color_scale_attrib->get_scale();
+          _color.set(_color[0] * cs[0],
+                     _color[1] * cs[1],
+                     _color[2] * cs[2],
+                     _color[3] * cs[3]);
+        }
+        _munge_color = true;
       }
-      _munge_color = true;
-    }
-
-  } else if (color_scale_attrib != (ColorScaleAttrib *)NULL &&
-             color_scale_attrib->has_scale()) {
-    _color_scale = color_scale_attrib->get_scale();
-
-    CPT(TextureAttrib) tex_attrib = state->get_texture();
-
-    // If the GSG says it can't cheat this RGB or alpha scale, we have
-    // to apply the color scale directly.
-    if ((color_scale_attrib->has_rgb_scale() && !get_gsg()->get_color_scale_via_lighting()) ||
-        (color_scale_attrib->has_alpha_scale() && !get_gsg()->get_alpha_scale_via_texture(tex_attrib))) {
-      _munge_color_scale = true;
+      
+    } else if (color_scale_attrib != (ColorScaleAttrib *)NULL &&
+               color_scale_attrib->has_scale()) {
+      _color_scale = color_scale_attrib->get_scale();
+      
+      CPT(TextureAttrib) tex_attrib = state->get_texture();
+      
+      // If the GSG says it can't cheat this RGB or alpha scale, we have
+      // to apply the color scale directly.
+      if ((color_scale_attrib->has_rgb_scale() && !get_gsg()->get_color_scale_via_lighting()) ||
+          (color_scale_attrib->has_alpha_scale() && !get_gsg()->get_alpha_scale_via_texture(tex_attrib))) {
+        _munge_color_scale = true;
+      }
+      
+      // Known bug: if there is a material on an object that would
+      // obscure the effect of color_scale, we scale the lighting
+      // anyway, thus applying the effect even if it should be obscured.
+      // It doesn't seem worth the effort to detect this contrived
+      // situation and handle it correctly.
     }
-
-    // Known bug: if there is a material on an object that would
-    // obscure the effect of color_scale, we scale the lighting
-    // anyway, thus applying the effect even if it should be obscured.
-    // It doesn't seem worth the effort to detect this contrived
-    // situation and handle it correctly.
   }
 }
 

+ 3 - 1
panda/src/gobj/config_gobj.cxx

@@ -73,7 +73,9 @@ ConfigVariableInt max_texture_dimension
           "texture sizes for limited graphics cards.  When this is greater "
           "than zero, each texture image loaded from a file (but only those "
           "loaded from a file) will be automatically scaled down, if "
-          "necessary, so that neither dimension is larger than this value."));
+          "necessary, so that neither dimension is larger than this value.  "
+          "If this is less than zero, the size limit is taken from the "
+          "primary GSG.  If this is exactly zero, there is no limit."));
 
 ConfigVariableDouble texture_scale
 ("texture-scale", 1.0,

+ 14 - 3
panda/src/gobj/texture.cxx

@@ -2960,9 +2960,20 @@ consider_rescale(PNMImage &pnmimage, const string &name) {
     break;
   }
 
-  if (max_texture_dimension > 0 && !exclude) {
-    new_x_size = min(new_x_size, (int)max_texture_dimension);
-    new_y_size = min(new_y_size, (int)max_texture_dimension);
+  if (!exclude) {
+    int max_dimension = max_texture_dimension;
+    
+    if (max_dimension < 0) {
+      GraphicsStateGuardianBase *gsg = GraphicsStateGuardianBase::get_default_gsg();
+      if (gsg != (GraphicsStateGuardianBase *)NULL) {
+        max_dimension = gsg->get_max_texture_dimension();
+      }
+    }
+
+    if (max_dimension > 0) {
+      new_x_size = min(new_x_size, (int)max_dimension);
+      new_y_size = min(new_y_size, (int)max_dimension);
+    }
   }
 
   if (pnmimage.get_x_size() != new_x_size ||

+ 2 - 0
panda/src/gsgbase/graphicsStateGuardianBase.h

@@ -116,6 +116,8 @@ PUBLISHED:
   virtual int get_max_vertices_per_array() const=0;
   virtual int get_max_vertices_per_primitive() const=0;
 
+  virtual int get_max_texture_dimension() const=0;
+
   virtual bool get_supports_multisample() const=0;
   virtual int get_supported_geom_rendering() const=0;
   virtual bool get_supports_occlusion_query() const=0;

+ 2 - 0
panda/src/text/dynamicTextGlyph.cxx

@@ -28,6 +28,7 @@
 #include "geomVertexWriter.h"
 #include "textureAttrib.h"
 #include "transparencyAttrib.h"
+#include "colorAttrib.h"
 #include "renderState.h"
 #include "config_gobj.h"
 
@@ -163,6 +164,7 @@ make_geom(int bitmap_top, int bitmap_left, float advance, float poly_margin,
   
   _state = RenderState::make(TextureAttrib::make(_page),
                              TransparencyAttrib::make(TransparencyAttrib::M_alpha));
+  _state = _state->add_attrib(ColorAttrib::make_flat(Colorf(1.0f, 1.0f, 1.0f, 1.0f)), -1);
   
   _advance = advance / font_pixels_per_unit;
 }

+ 3 - 5
panda/src/tinydisplay/Sources.pp

@@ -1,9 +1,9 @@
-#define BUILD_DIRECTORY $[HAVE_TINYSDGL]
-//#define BUILDING_DLL BUILDING_PANDATINYSDGL
+#define BUILD_DIRECTORY $[HAVE_SDL]
+//#define BUILDING_DLL BUILDING_TINYDISPLAY
 
 #define OTHER_LIBS interrogatedb:c dconfig:c dtoolconfig:m \
                    dtoolutil:c dtoolbase:c dtool:m
-#define USE_PACKAGES tinysdgl
+#define USE_PACKAGES sdl
 
 #begin lib_target
   #define TARGET tinydisplay
@@ -18,8 +18,6 @@
     tinyGraphicsWindow.h tinyGraphicsWindow.I tinyGraphicsWindow.cxx \
     tinyGraphicsStateGuardian.h tinyGraphicsStateGuardian.I \
     tinyGraphicsStateGuardian.cxx \
-    tinyImmediateModeSender.h tinyImmediateModeSender.I \
-    tinyImmediateModeSender.cxx \
     tinyTextureContext.I tinyTextureContext.cxx tinyTextureContext.h \
     api.c arrays.c clear.c clip.c error.c get.c \
     glu.c image_util.c init.c light.c list.c \

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

@@ -23,7 +23,6 @@
 
 #include "graphicsStateGuardian.h"
 #include "tinyGraphicsPipe.h"
-#include "tinyImmediateModeSender.h"
 #include "tinygl.h"
 
 extern "C" {

+ 0 - 101
panda/src/tinydisplay/tinyImmediateModeSender.I

@@ -1,101 +0,0 @@
-// Filename: glImmediateModeSender_src.I
-// Created by:  drose (15Aug05)
-//
-////////////////////////////////////////////////////////////////////
-//
-// PANDA 3D SOFTWARE
-// Copyright (c) 2001 - 2004, 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://etc.cmu.edu/panda3d/docs/license/ .
-//
-// To contact the maintainers of this program write to
-// [email protected] .
-//
-////////////////////////////////////////////////////////////////////
-
-
-////////////////////////////////////////////////////////////////////
-//     Function: TinyImmediateModeSender::Constructor
-//       Access: Public
-//  Description:
-////////////////////////////////////////////////////////////////////
-INLINE TinyImmediateModeSender::
-TinyImmediateModeSender() {
-}
-
-////////////////////////////////////////////////////////////////////
-//     Function: TinyImmediateModeSender::ComponentSender::Constructor
-//       Access: Public
-//  Description: The ComponentSender becomes the owner of the
-//               GeomVertexReader pointer, and will delete it when it
-//               is done.
-////////////////////////////////////////////////////////////////////
-INLINE TinyImmediateModeSender::ComponentSender::
-ComponentSender(GeomVertexReader *reader) :
-  _reader(reader)
-{
-}
-
-////////////////////////////////////////////////////////////////////
-//     Function: TinyImmediateModeSender::ComponentSender::set_vertex
-//       Access: Public
-//  Description: Specifies the vertex index of the next vertex to
-//               send.  If this is not called, the next consecutive
-//               vertex will be sent.
-////////////////////////////////////////////////////////////////////
-INLINE void TinyImmediateModeSender::ComponentSender::
-set_vertex(int vertex_index) {
-  _reader->set_row(vertex_index);
-}
-
-
-////////////////////////////////////////////////////////////////////
-//     Function: TinyImmediateModeSender::ComponentSender1f::Constructor
-//       Access: Public
-//  Description: 
-////////////////////////////////////////////////////////////////////
-INLINE TinyImmediateModeSender::ComponentSender1f::
-ComponentSender1f(GeomVertexReader *reader, Func1f *func) :
-  ComponentSender(reader),
-  _func(func)
-{
-}
-
-////////////////////////////////////////////////////////////////////
-//     Function: TinyImmediateModeSender::ComponentSender2f::Constructor
-//       Access: Public
-//  Description: 
-////////////////////////////////////////////////////////////////////
-INLINE TinyImmediateModeSender::ComponentSender2f::
-ComponentSender2f(GeomVertexReader *reader, Func2f *func) :
-  ComponentSender(reader),
-  _func(func)
-{
-}
-
-////////////////////////////////////////////////////////////////////
-//     Function: TinyImmediateModeSender::ComponentSender3f::Constructor
-//       Access: Public
-//  Description: 
-////////////////////////////////////////////////////////////////////
-INLINE TinyImmediateModeSender::ComponentSender3f::
-ComponentSender3f(GeomVertexReader *reader, Func3f *func) :
-  ComponentSender(reader),
-  _func(func)
-{
-}
-
-////////////////////////////////////////////////////////////////////
-//     Function: TinyImmediateModeSender::ComponentSender4f::Constructor
-//       Access: Public
-//  Description: 
-////////////////////////////////////////////////////////////////////
-INLINE TinyImmediateModeSender::ComponentSender4f::
-ComponentSender4f(GeomVertexReader *reader, Func4f *func) :
-  ComponentSender(reader),
-  _func(func)
-{
-}

+ 0 - 232
panda/src/tinydisplay/tinyImmediateModeSender.cxx

@@ -1,232 +0,0 @@
-// Filename: glImmediateModeSender_src.cxx
-// Created by:  drose (15Aug05)
-//
-////////////////////////////////////////////////////////////////////
-//
-// PANDA 3D SOFTWARE
-// Copyright (c) 2001 - 2004, 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://etc.cmu.edu/panda3d/docs/license/ .
-//
-// To contact the maintainers of this program write to
-// [email protected] .
-//
-////////////////////////////////////////////////////////////////////
-
-#include "tinyImmediateModeSender.h"
-#include "config_tinydisplay.h"
-
-////////////////////////////////////////////////////////////////////
-//     Function: TinyImmediateModeSender::Destructor
-//       Access: Public
-//  Description: 
-////////////////////////////////////////////////////////////////////
-TinyImmediateModeSender::
-~TinyImmediateModeSender() {
-  clear();
-}
-
-////////////////////////////////////////////////////////////////////
-//     Function: TinyImmediateModeSender::clear
-//       Access: Public
-//  Description: Removes (and deletes) all of the senders from the
-//               object.
-////////////////////////////////////////////////////////////////////
-void TinyImmediateModeSender::
-clear() {
-  ComponentSenders::iterator si;
-  for (si = _senders.begin(); si != _senders.end(); ++si) {
-    delete (*si);
-  }
-  _senders.clear();
-}
-
-////////////////////////////////////////////////////////////////////
-//     Function: TinyImmediateModeSender::set_vertex
-//       Access: Public
-//  Description: Specifies the vertex index of the next vertex to
-//               send.  If this is not called, the next consecutive
-//               vertex will be sent.
-////////////////////////////////////////////////////////////////////
-void TinyImmediateModeSender::
-set_vertex(int vertex_index) {
-  ComponentSenders::iterator si;
-  for (si = _senders.begin(); si != _senders.end(); ++si) {
-    (*si)->set_vertex(vertex_index);
-  }
-}
-
-////////////////////////////////////////////////////////////////////
-//     Function: TinyImmediateModeSender::issue_vertex
-//       Access: Public
-//  Description: Sends the next vertex to the OpenGL API.
-////////////////////////////////////////////////////////////////////
-void TinyImmediateModeSender::
-issue_vertex() {
-  ComponentSenders::iterator si;
-  for (si = _senders.begin(); si != _senders.end(); ++si) {
-    (*si)->issue_vertex();
-  }
-}
-
-////////////////////////////////////////////////////////////////////
-//     Function: TinyImmediateModeSender::add_column
-//       Access: Public
-//  Description: Creates a new ComponentSender for the named data
-//               column, if it exists in the vertex data, and adds it
-//               to the list of senders for this object.
-//
-//               The four function pointers are the four variants on
-//               the function pointer for the possible number of
-//               components of the data column.  The appropriate
-//               pointer will be used, depending on the number of
-//               components the data column actually uses.
-//
-//               The return value is true if the column is added,
-//               false if it is not for some reason (for instance, the
-//               named column doesn't exist in the vertex data).
-////////////////////////////////////////////////////////////////////
-bool TinyImmediateModeSender::
-add_column(const GeomVertexDataPipelineReader *data_reader, const InternalName *name,
-           Func1f *func1f, Func2f *func2f, Func3f *func3f, Func4f *func4f) {
-  if (data_reader->has_column(name)) {
-    GeomVertexReader *reader = new GeomVertexReader(data_reader, name);
-    ComponentSender *sender = NULL;
-    const GeomVertexColumn *column = reader->get_column();
-    switch (column->get_num_components()) {
-    case 1:
-      if (func1f != (Func1f *)NULL) {
-        sender = new ComponentSender1f(reader, func1f);
-      }
-      break;
-
-    case 2:
-      if (func2f != (Func2f *)NULL) {
-        sender = new ComponentSender2f(reader, func2f);
-      }
-      break;
-
-    case 3:
-      if (func3f != (Func3f *)NULL) {
-        sender = new ComponentSender3f(reader, func3f);
-      }
-      break;
-
-    case 4:
-      if (func4f != (Func4f *)NULL) {
-        sender = new ComponentSender4f(reader, func4f);
-      }
-      break;
-    }
-
-    if (sender != (ComponentSender *)NULL) {
-      // Ok, we've got a valid sender; add it to the list.
-      _senders.push_back(sender);
-      return true;
-
-    } else {
-      // We didn't get a valid sender; clean up and return.
-      delete reader;
-    }
-  }
-
-  return false;
-}
-
-////////////////////////////////////////////////////////////////////
-//     Function: TinyImmediateModeSender::add_sender
-//       Access: Public
-//  Description: Adds a new ComponentSender to the list of senders for
-//               this object.  The GLImmediateModeSender object
-//               becomes the owner of the ComponentSender pointer and
-//               will delete it when it is done.
-////////////////////////////////////////////////////////////////////
-void TinyImmediateModeSender::
-add_sender(ComponentSender *sender) {
-  _senders.push_back(sender);
-}
-
-////////////////////////////////////////////////////////////////////
-//     Function: TinyImmediateModeSender::ComponentSender::Destructor
-//       Access: Public, Virtual
-//  Description: 
-////////////////////////////////////////////////////////////////////
-TinyImmediateModeSender::ComponentSender::
-~ComponentSender() {
-  delete _reader;
-}
-
-////////////////////////////////////////////////////////////////////
-//     Function: TinyImmediateModeSender::ComponentSender1f::issue_vertex
-//       Access: Public, Virtual
-//  Description: 
-////////////////////////////////////////////////////////////////////
-void TinyImmediateModeSender::ComponentSender1f::
-issue_vertex() {
-  float d = _reader->get_data1f();
-#ifndef NDEBUG
-  if (tinydisplay_cat.is_spam()) {
-    tinydisplay_cat.spam()
-      << *_reader->get_column()->get_name() << ": " << d << "\n";
-  }
-#endif  // NDEBUG
-
-  (*_func)(d);
-}
-
-////////////////////////////////////////////////////////////////////
-//     Function: TinyImmediateModeSender::ComponentSender2f::issue_vertex
-//       Access: Public, Virtual
-//  Description: 
-////////////////////////////////////////////////////////////////////
-void TinyImmediateModeSender::ComponentSender2f::
-issue_vertex() {
-  const LVecBase2f &d = _reader->get_data2f();
-#ifndef NDEBUG
-  if (tinydisplay_cat.is_spam()) {
-    tinydisplay_cat.spam()
-      << *_reader->get_column()->get_name() << ": " << d << "\n";
-  }
-#endif  // NDEBUG
-
-  (*_func)(d[0], d[1]);
-}
-
-////////////////////////////////////////////////////////////////////
-//     Function: TinyImmediateModeSender::ComponentSender3f::issue_vertex
-//       Access: Public, Virtual
-//  Description: 
-////////////////////////////////////////////////////////////////////
-void TinyImmediateModeSender::ComponentSender3f::
-issue_vertex() {
-  const LVecBase3f &d = _reader->get_data3f();
-#ifndef NDEBUG
-  if (tinydisplay_cat.is_spam()) {
-    tinydisplay_cat.spam()
-      << *_reader->get_column()->get_name() << ": " << d << "\n";
-  }
-#endif  // NDEBUG
-
-  (*_func)(d[0], d[1], d[2]);
-}
-
-////////////////////////////////////////////////////////////////////
-//     Function: TinyImmediateModeSender::ComponentSender4f::issue_vertex
-//       Access: Public, Virtual
-//  Description: 
-////////////////////////////////////////////////////////////////////
-void TinyImmediateModeSender::ComponentSender4f::
-issue_vertex() {
-  const LVecBase4f &d = _reader->get_data4f();
-#ifndef NDEBUG
-  if (tinydisplay_cat.is_spam()) {
-    tinydisplay_cat.spam()
-      << *_reader->get_column()->get_name() << ": " << d << "\n";
-  }
-#endif  // NDEBUG
-
-  (*_func)(d[0], d[1], d[2], d[3]);
-}

+ 0 - 112
panda/src/tinydisplay/tinyImmediateModeSender.h

@@ -1,112 +0,0 @@
-// Filename: tinyImmediateModeSender.h
-// Created by:  drose (29Apr08)
-//
-////////////////////////////////////////////////////////////////////
-//
-// PANDA 3D SOFTWARE
-// Copyright (c) 2001 - 2004, 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://etc.cmu.edu/panda3d/docs/license/ .
-//
-// To contact the maintainers of this program write to
-// [email protected] .
-//
-////////////////////////////////////////////////////////////////////
-
-#ifndef TINYIMMEDIATEMODESENDER_H
-#define TINYIMMEDIATEMODESENDER_H
-
-#include "pandabase.h"
-#include "geomVertexReader.h"
-#include "tinygl.h"
-
-////////////////////////////////////////////////////////////////////
-//       Class : TinyImmediateModeSender
-// Description : This class collects together a handful of objects
-//               that will issue immediate-mode commands like
-//               glVertex, glTexCoord, etc., for the purposes of
-//               sending an object's vertices using the immediate mode
-//               functions.
-//
-//               Since unlike OpenGL, TinyGL prefers the
-//               immediate-mode interface, this is used all of the
-//               time.
-////////////////////////////////////////////////////////////////////
-class TinyImmediateModeSender {
-public:
-  INLINE TinyImmediateModeSender();
-  ~TinyImmediateModeSender();
-
-  void clear();
-  
-  void set_vertex(int vertex_index);
-  void issue_vertex();
-
-  class ComponentSender;
-  typedef void Func1f(GLfloat a);
-  typedef void Func2f(GLfloat a, GLfloat b);
-  typedef void Func3f(GLfloat a, GLfloat b, GLfloat c);
-  typedef void Func4f(GLfloat a, GLfloat b, GLfloat c, GLfloat d);
-
-  bool add_column(const GeomVertexDataPipelineReader *data_reader, 
-                  const InternalName *name, Func1f *func1f, 
-                  Func2f *func2f, Func3f *func3f, Func4f *func4f);
-
-  void add_sender(ComponentSender *sender);
-
-public:
-
-  class ComponentSender {
-  public:
-    INLINE ComponentSender(GeomVertexReader *reader);
-    virtual ~ComponentSender();
-    INLINE void set_vertex(int vertex_index);
-    virtual void issue_vertex()=0;
-  protected:
-    GeomVertexReader *_reader;
-  };
-
-  class ComponentSender1f : public ComponentSender {
-  public:
-    INLINE ComponentSender1f(GeomVertexReader *reader, Func1f *func);
-    virtual void issue_vertex();
-  private:
-    Func1f *_func;
-  };
-
-  class ComponentSender2f : public ComponentSender {
-  public:
-    INLINE ComponentSender2f(GeomVertexReader *reader, Func2f *func);
-    virtual void issue_vertex();
-  private:
-    Func2f *_func;
-  };
-
-  class ComponentSender3f : public ComponentSender {
-  public:
-    INLINE ComponentSender3f(GeomVertexReader *reader, Func3f *func);
-    virtual void issue_vertex();
-  private:
-    Func3f *_func;
-  };
-
-  class ComponentSender4f : public ComponentSender {
-  public:
-    INLINE ComponentSender4f(GeomVertexReader *reader, Func4f *func);
-    virtual void issue_vertex();
-  private:
-    Func4f *_func;
-  };
-
-private:
-  typedef pvector<ComponentSender *> ComponentSenders;
-  ComponentSenders _senders;
-};
-
-#include "tinyImmediateModeSender.I"
-
-#endif  // SUPPORT_IMMEDIATE_MODE
-