OSGGeoVertexArrayPumpGroup.cpp

Go to the documentation of this file.
00001 /*---------------------------------------------------------------------------*\
00002  *                                OpenSG                                     *
00003  *                                                                           *
00004  *                                                                           *
00005  *             Copyright (C) 2000-2002 by the OpenSG Forum                   *
00006  *                                                                           *
00007  *                            www.opensg.org                                 *
00008  *                                                                           *
00009  *   contact: dirk@opensg.org, gerrit.voss@vossg.org, jbehr@zgdv.de          *
00010  *                                                                           *
00011 \*---------------------------------------------------------------------------*/
00012 /*---------------------------------------------------------------------------*\
00013  *                                License                                    *
00014  *                                                                           *
00015  *                                                                           *
00016  *                                                                           *
00017  * This library is free software; you can redistribute it and/or modify it   *
00018  * under the terms of the GNU Library General Public License as published    *
00019  * by the Free Software Foundation, version 2.                               *
00020  *                                                                           *
00021  * This library is distributed in the hope that it will be useful, but       *
00022  * WITHOUT ANY WARRANTY; without even the implied warranty of                *
00023  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU         *
00024  * Library General Public License for more details.                          *
00025  *                                                                           *
00026  * You should have received a copy of the GNU Library General Public         *
00027  * License along with this library; if not, write to the Free Software       *
00028  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.                 *
00029  *                                                                           *
00030  *                                                                           *
00031 \*---------------------------------------------------------------------------*/
00032 /*---------------------------------------------------------------------------*\
00033  *                                Changes                                    *
00034  *                                                                           *
00035  *                                                                           *
00036  *                                                                           *
00037  *                                                                           *
00038  *                                                                           *
00039  *                                                                           *
00040 \*---------------------------------------------------------------------------*/
00041 
00042 //---------------------------------------------------------------------------
00043 //  Includes
00044 //---------------------------------------------------------------------------
00045 
00046 #include <cstdlib>
00047 #include <cstdio>
00048 
00049 #include "OSGConfig.h"
00050 
00051 #include <OSGGL.h>
00052 #include <OSGGLEXT.h>
00053 
00054 #include "OSGLog.h"
00055 
00056 #include "OSGGeometry.h"
00057 #include "OSGDrawEnv.h"
00058 
00059 #include "OSGMaterial.h"
00060 
00061 #include "OSGGeoVertexArrayPumpGroup.h"
00062 
00063 OSG_USING_NAMESPACE
00064 
00065 
00066 /***************************************************************************\
00067  *                            Description                                  *
00068 \***************************************************************************/
00069 
00070 /* \class OSG::GeoVertexArrayPumpGroup
00071    \ingroup GrpSystemNodeCoresDrawablesGeometry
00072     
00073 */
00074 
00075 /***************************************************************************\
00076  *                           Class variables                               *
00077 \***************************************************************************/
00078 
00081 InitFuncWrapper
00082 GeoVertexArrayPumpGroup::_glextInitFuncWrapper(GeoVertexArrayPumpGroup::glextInitFunction);
00083 
00086 UInt32 GeoVertexArrayPumpGroup::_extSecondaryColor;
00087 UInt32 GeoVertexArrayPumpGroup::_extMultitexture;
00088 UInt32 GeoVertexArrayPumpGroup::_arbVertexProgram;
00089 UInt32 GeoVertexArrayPumpGroup::_extCompiledVertexArray;
00090 UInt32 GeoVertexArrayPumpGroup::_extDrawRangeElements;
00091 
00094 UInt32 GeoVertexArrayPumpGroup::_funcglSecondaryColorPointer;
00095 UInt32 GeoVertexArrayPumpGroup::_funcglClientActiveTextureARB;
00096 UInt32 GeoVertexArrayPumpGroup::_funcglLockArraysEXT;
00097 UInt32 GeoVertexArrayPumpGroup::_funcglUnlockArraysEXT;
00098 UInt32 GeoVertexArrayPumpGroup::_funcglDrawRangeElementsEXT;
00099 UInt32 GeoVertexArrayPumpGroup::_funcglVertexAttribPointerARB;
00100 UInt32 GeoVertexArrayPumpGroup::_funcglEnableVertexAttribArrayARB;
00101 UInt32 GeoVertexArrayPumpGroup::_funcglDisableVertexAttribArrayARB;
00102 
00103 /***************************************************************************\
00104  *                           Instance methods                              *
00105 \***************************************************************************/
00106 
00107 /*------------- constructors & destructors --------------------------------*/
00108 
00109 GeoVertexArrayPumpGroup::GeoVertexArrayPumpGroup(void)
00110 {
00111 }
00112 
00113 GeoVertexArrayPumpGroup::~GeoVertexArrayPumpGroup(void)
00114 {
00115 }
00116 
00117 /*-------------------------------------------------------------------------*\
00118  -  private                                                                -
00119 \*-------------------------------------------------------------------------*/
00120 
00121 // Pumping function definitions
00122 
00123 typedef void (OSG_APIENTRY *pumpFunc)(const UInt8 * data);
00124 typedef void (OSG_APIENTRY *multiPumpFunc)(GLenum which,  const UInt8 * data);
00125 typedef void (OSG_APIENTRY *attribPumpFunc)(GLuint index, const UInt8 * data);
00126 
00127 
00128 // Some helper arrays for function selection
00129 // indexed by data type and dimension
00130 
00131 static const int formatBase = GL_BYTE;
00132 static const int numFormats = GL_DOUBLE - GL_BYTE + 1;
00133 
00134 static char *formatNames[] =
00135 {   "GL_BYTE", "GL_UNSIGNED_BYTE", "GL_SHORT", "GL_UNSIGNED_SHORT",
00136     "GL_INT", "GL_UNSIGNED_INT", "GL_FLOAT", "GL_2_BYTES",
00137     "GL_3_BYTES", "GL_4_BYTES", "GL_DOUBLE"
00138 };
00139 
00140 // little helper class for function init
00141 
00142 #if !defined(OSG_DO_DOC) || defined(OSG_DOC_DEV)
00143 
00144 class glextFuncInit
00145 {
00146     public:
00147 
00148         glextFuncInit(char *name, UInt32 format, UInt32 dim, 
00149                 bool normalizing = false) :
00150             _name(name), _format(format), _dim(dim),
00151             _normalizing(normalizing) {};
00152 
00153         void init(UInt32 (&extids)[numFormats][4], UInt32 extension)
00154         {
00155             extids[_format - formatBase][_dim - 1] =
00156                               Window::registerFunction(_name, extension);
00157         }
00158 
00159     private:
00160 
00161         char   *_name;
00162         UInt32  _format;
00163         UInt32  _dim;
00164         bool    _normalizing;
00165 };
00166 
00167 static glextFuncInit secondaryColorInitFuncs[8] = {
00168     glextFuncInit(OSG_DLSYM_UNDERSCORE"glSecondaryColor3bvEXT",
00169                   GL_BYTE,
00170                   3),
00171     glextFuncInit(OSG_DLSYM_UNDERSCORE"glSecondaryColor3ubvEXT",
00172                   GL_UNSIGNED_BYTE,
00173                   3),
00174     glextFuncInit(OSG_DLSYM_UNDERSCORE"glSecondaryColor3svEXT",
00175                   GL_SHORT,
00176                   3),
00177     glextFuncInit(OSG_DLSYM_UNDERSCORE"glSecondaryColor3usvEXT",
00178                   GL_UNSIGNED_SHORT,
00179                   3),
00180     glextFuncInit(OSG_DLSYM_UNDERSCORE"glSecondaryColor3ivEXT",
00181                   GL_INT,
00182                   3),
00183     glextFuncInit(OSG_DLSYM_UNDERSCORE"glSecondaryColor3uivEXT",
00184                   GL_UNSIGNED_INT,
00185                   3),
00186     glextFuncInit(OSG_DLSYM_UNDERSCORE"glSecondaryColor3fvEXT",
00187                   GL_FLOAT,
00188                   3),
00189     glextFuncInit(OSG_DLSYM_UNDERSCORE"glSecondaryColor3dvEXT",
00190                   GL_DOUBLE,
00191                   3)
00192 };
00193 
00194 static glextFuncInit multiTexCoordsInitFuncs[16] = {
00195     glextFuncInit(OSG_DLSYM_UNDERSCORE"glMultiTexCoord1svARB",
00196                   GL_SHORT,
00197                   1),
00198     glextFuncInit(OSG_DLSYM_UNDERSCORE"glMultiTexCoord2svARB",
00199                   GL_SHORT,
00200                   2),
00201     glextFuncInit(OSG_DLSYM_UNDERSCORE"glMultiTexCoord3svARB",
00202                   GL_SHORT,
00203                   3),
00204     glextFuncInit(OSG_DLSYM_UNDERSCORE"glMultiTexCoord4svARB",
00205                   GL_SHORT,
00206                   4),
00207     glextFuncInit(OSG_DLSYM_UNDERSCORE"glMultiTexCoord1ivARB",
00208                   GL_INT,
00209                   1),
00210     glextFuncInit(OSG_DLSYM_UNDERSCORE"glMultiTexCoord2ivARB",
00211                   GL_INT,
00212                   2),
00213     glextFuncInit(OSG_DLSYM_UNDERSCORE"glMultiTexCoord3ivARB",
00214                   GL_INT,
00215                   3),
00216     glextFuncInit(OSG_DLSYM_UNDERSCORE"glMultiTexCoord4ivARB",
00217                   GL_INT,
00218                   4),
00219     glextFuncInit(OSG_DLSYM_UNDERSCORE"glMultiTexCoord1fvARB",
00220                   GL_FLOAT,
00221                   1),
00222     glextFuncInit(OSG_DLSYM_UNDERSCORE"glMultiTexCoord2fvARB",
00223                   GL_FLOAT,
00224                   2),
00225     glextFuncInit(OSG_DLSYM_UNDERSCORE"glMultiTexCoord3fvARB",
00226                   GL_FLOAT,
00227                   3),
00228     glextFuncInit(OSG_DLSYM_UNDERSCORE"glMultiTexCoord4fvARB",
00229                   GL_FLOAT,
00230                   4),
00231     glextFuncInit(OSG_DLSYM_UNDERSCORE"glMultiTexCoord1dvARB",
00232                   GL_DOUBLE,
00233                   1),
00234     glextFuncInit(OSG_DLSYM_UNDERSCORE"glMultiTexCoord2dvARB",
00235                   GL_DOUBLE,
00236                   2),
00237     glextFuncInit(OSG_DLSYM_UNDERSCORE"glMultiTexCoord3dvARB",
00238                   GL_DOUBLE,
00239                   3),
00240     glextFuncInit(OSG_DLSYM_UNDERSCORE"glMultiTexCoord4dvARB",
00241                   GL_DOUBLE,
00242                   4)
00243 };
00244 
00245 static glextFuncInit attribInitFuncs[23] = {
00246     glextFuncInit(OSG_DLSYM_UNDERSCORE"glVertexAttrib1svARB",
00247                   GL_SHORT,
00248                   1),
00249     glextFuncInit(OSG_DLSYM_UNDERSCORE"glVertexAttrib1fvARB",
00250                   GL_FLOAT,
00251                   1),
00252     glextFuncInit(OSG_DLSYM_UNDERSCORE"glVertexAttrib1dvARB",
00253                   GL_DOUBLE,
00254                   1),
00255     glextFuncInit(OSG_DLSYM_UNDERSCORE"glVertexAttrib2svARB",
00256                   GL_SHORT,
00257                   2),
00258     glextFuncInit(OSG_DLSYM_UNDERSCORE"glVertexAttrib2fvARB",
00259                   GL_FLOAT,
00260                   2),
00261     glextFuncInit(OSG_DLSYM_UNDERSCORE"glVertexAttrib2dvARB",
00262                   GL_DOUBLE,
00263                   2),
00264     glextFuncInit(OSG_DLSYM_UNDERSCORE"glVertexAttrib3svARB",
00265                   GL_SHORT,
00266                   3),
00267     glextFuncInit(OSG_DLSYM_UNDERSCORE"glVertexAttrib3fvARB",
00268                   GL_FLOAT,
00269                   3),
00270     glextFuncInit(OSG_DLSYM_UNDERSCORE"glVertexAttrib3dvARB",
00271                   GL_DOUBLE,
00272                   3),
00273     glextFuncInit(OSG_DLSYM_UNDERSCORE"glVertexAttrib4bvARB",
00274                   GL_BYTE,
00275                   4),
00276     glextFuncInit(OSG_DLSYM_UNDERSCORE"glVertexAttrib4svARB",
00277                   GL_SHORT,
00278                   4),
00279     glextFuncInit(OSG_DLSYM_UNDERSCORE"glVertexAttrib4ivARB",
00280                   GL_INT,
00281                   4),
00282     glextFuncInit(OSG_DLSYM_UNDERSCORE"glVertexAttrib4ubvARB",
00283                   GL_UNSIGNED_BYTE,
00284                   4),
00285     glextFuncInit(OSG_DLSYM_UNDERSCORE"glVertexAttrib4usvARB",
00286                   GL_UNSIGNED_SHORT,
00287                   4),
00288     glextFuncInit(OSG_DLSYM_UNDERSCORE"glVertexAttrib4uivARB",
00289                   GL_UNSIGNED_INT,
00290                   4),
00291     glextFuncInit(OSG_DLSYM_UNDERSCORE"glVertexAttrib4bvARB",
00292                   GL_BYTE,
00293                   4),
00294     glextFuncInit(OSG_DLSYM_UNDERSCORE"glVertexAttrib4svARB",
00295                   GL_SHORT,
00296                   4),
00297     glextFuncInit(OSG_DLSYM_UNDERSCORE"glVertexAttrib4ivARB",
00298                   GL_INT,
00299                   4),
00300     glextFuncInit(OSG_DLSYM_UNDERSCORE"glVertexAttrib4ubvARB",
00301                   GL_UNSIGNED_BYTE,
00302                   4),
00303     glextFuncInit(OSG_DLSYM_UNDERSCORE"glVertexAttrib4usvARB",
00304                   GL_UNSIGNED_SHORT,
00305                   4),
00306     glextFuncInit(OSG_DLSYM_UNDERSCORE"glVertexAttrib4uivARB",
00307                   GL_UNSIGNED_INT,
00308                   4),
00309     glextFuncInit(OSG_DLSYM_UNDERSCORE"glVertexAttrib4fvARB",
00310                   GL_FLOAT,
00311                   4),
00312     glextFuncInit(OSG_DLSYM_UNDERSCORE"glVertexAttrib4dvARB",
00313                   GL_DOUBLE,
00314                   4),
00315 };
00316 
00317 
00318 static glextFuncInit normAttribInitFuncs[6] = {
00319     glextFuncInit(OSG_DLSYM_UNDERSCORE"glVertexAttrib4NbvARB",
00320                   GL_BYTE,
00321                   4, true),
00322     glextFuncInit(OSG_DLSYM_UNDERSCORE"glVertexAttrib4NsvARB",
00323                   GL_SHORT,
00324                   4, true),
00325     glextFuncInit(OSG_DLSYM_UNDERSCORE"glVertexAttrib4NivARB",
00326                   GL_INT,
00327                   4, true),
00328     glextFuncInit(OSG_DLSYM_UNDERSCORE"glVertexAttrib4NubvARB",
00329                   GL_UNSIGNED_BYTE,
00330                   4, true),
00331     glextFuncInit(OSG_DLSYM_UNDERSCORE"glVertexAttrib4NusvARB",
00332                   GL_UNSIGNED_SHORT,
00333                   4, true),
00334     glextFuncInit(OSG_DLSYM_UNDERSCORE"glVertexAttrib4NuivARB",
00335                   GL_UNSIGNED_INT,
00336                   4, true),
00337 };
00338 
00339 // The real pumping functions
00340 
00341 static pumpFunc PositionFuncs[numFormats][4] = {
00342     { NULL, NULL, NULL, NULL },                           // GL_BYTE
00343     { NULL, NULL, NULL, NULL },                           // GL_UNSIGNED_BYTE
00344     { NULL, (pumpFunc)glVertex2sv,
00345       (pumpFunc)glVertex3sv, (pumpFunc)glVertex4sv },     // GL_SHORT
00346     { NULL, NULL, NULL, NULL },                           // GL_UNSIGNED_SHORT
00347     { NULL, (pumpFunc)glVertex2iv,
00348       (pumpFunc)glVertex3iv, (pumpFunc)glVertex4iv },     // GL_INT
00349     { NULL, NULL, NULL, NULL },                           // GL_UNSIGNED_INT
00350     { NULL, (pumpFunc)glVertex2fv,
00351       (pumpFunc)glVertex3fv, (pumpFunc)glVertex4fv },     // GL_FLOAT
00352     { NULL, NULL, NULL, NULL },                           // GL_2_BYTES
00353     { NULL, NULL, NULL, NULL },                           // GL_3_BYTES
00354     { NULL, NULL, NULL, NULL },                           // GL_4_BYTES
00355     { NULL, (pumpFunc)glVertex2dv,
00356       (pumpFunc)glVertex3dv, (pumpFunc)glVertex4dv },     // GL_DOUBLE
00357 };
00358 
00359 static pumpFunc NormalFuncs[numFormats][4] = {
00360     { NULL, NULL, (pumpFunc)glNormal3sv, NULL },          // GL_BYTE
00361     { NULL, NULL, NULL, NULL },                           // GL_UNSIGNED_BYTE
00362     { NULL, NULL, (pumpFunc)glNormal3sv, NULL },          // GL_SHORT
00363     { NULL, NULL, NULL, NULL },                           // GL_UNSIGNED_SHORT
00364     { NULL, NULL, (pumpFunc)glNormal3iv, NULL },          // GL_INT
00365     { NULL, NULL, NULL, NULL },                           // GL_UNSIGNED_INT
00366     { NULL, NULL, (pumpFunc)glNormal3fv, NULL },          // GL_FLOAT
00367     { NULL, NULL, NULL, NULL },                           // GL_2_BYTES
00368     { NULL, NULL, NULL, NULL },                           // GL_3_BYTES
00369     { NULL, NULL, NULL, NULL },                           // GL_4_BYTES
00370     { NULL, NULL, (pumpFunc)glNormal3dv, NULL },          // GL_DOUBLE
00371 };
00372 
00373 static pumpFunc ColorFuncs[numFormats][4] = {
00374     { NULL, NULL,
00375       (pumpFunc)glColor3bv, (pumpFunc)glColor4bv },       // GL_BYTE
00376     { NULL, NULL,
00377       (pumpFunc)glColor3ubv, (pumpFunc)glColor4ubv },     // GL_UNSIGNED_BYTE
00378     { NULL, NULL,
00379       (pumpFunc)glColor3sv, (pumpFunc)glColor4sv },       // GL_SHORT
00380     { NULL, NULL,
00381       (pumpFunc)glColor3usv, (pumpFunc)glColor4usv },     // GL_UNSIGNED_SHORT
00382     { NULL, NULL,
00383       (pumpFunc)glColor3iv, (pumpFunc)glColor4iv },       // GL_INT
00384     { NULL, NULL,
00385       (pumpFunc)glColor3uiv, (pumpFunc)glColor4uiv },     // GL_UNSIGNED_INT
00386     { NULL, NULL,
00387       (pumpFunc)glColor3fv, (pumpFunc)glColor4fv },       // GL_FLOAT
00388     { NULL, NULL, NULL, NULL },                           // GL_2_BYTES
00389     { NULL, NULL, NULL, NULL },                           // GL_3_BYTES
00390     { NULL, NULL, NULL, NULL },                           // GL_4_BYTES
00391     { NULL, NULL,
00392       (pumpFunc)glColor3dv, (pumpFunc)glColor4dv },       // GL_DOUBLE
00393 };
00394 
00395 static UInt32 SecColorIDs[numFormats][4];
00396 
00397 static pumpFunc TexCoordsFuncs[numFormats][4] = {
00398     { NULL, NULL, NULL, NULL },                           // GL_BYTE
00399     { NULL, NULL, NULL, NULL },                           // GL_UNSIGNED_BYTE
00400     { (pumpFunc)glTexCoord1sv, (pumpFunc)glTexCoord2sv,
00401       (pumpFunc)glTexCoord3sv, (pumpFunc)glTexCoord4sv }, // GL_SHORT
00402     { NULL, NULL, NULL, NULL },                           // GL_UNSIGNED_SHORT
00403     { (pumpFunc)glTexCoord1iv, (pumpFunc)glTexCoord2iv,
00404       (pumpFunc)glTexCoord3iv, (pumpFunc)glTexCoord4iv }, // GL_INT
00405     { NULL, NULL, NULL, NULL },                           // GL_UNSIGNED_INT
00406     { (pumpFunc)glTexCoord1fv, (pumpFunc)glTexCoord2fv,
00407       (pumpFunc)glTexCoord3fv, (pumpFunc)glTexCoord4fv }, // GL_FLOAT
00408     { NULL, NULL, NULL, NULL },                           // GL_2_BYTES
00409     { NULL, NULL, NULL, NULL },                           // GL_3_BYTES
00410     { NULL, NULL, NULL, NULL },                           // GL_4_BYTES
00411     { (pumpFunc)glTexCoord1dv, (pumpFunc)glTexCoord2dv,
00412       (pumpFunc)glTexCoord3dv, (pumpFunc)glTexCoord4dv }, // GL_DOUBLE
00413 };
00414 
00415 static UInt32 TexCoords1IDs[numFormats][4];
00416 
00417 #define TexCoords2IDs TexCoords1IDs
00418 #define TexCoords3IDs TexCoords1IDs
00419 #define TexCoords4IDs TexCoords1IDs
00420 #define TexCoords5IDs TexCoords1IDs
00421 #define TexCoords6IDs TexCoords1IDs
00422 #define TexCoords7IDs TexCoords1IDs
00423 
00424 static UInt32 AttribIDs[numFormats][4];
00425 static UInt32 NormAttribIDs[numFormats][4];
00426 
00427 #endif      // remove from all but dev docs
00428 
00429 
00430 #define pumpSetup( name, typename, getmethod )                              \
00431     typename name##Ptr;                                                     \
00432     GLubyte *name##Data   = NULL;                                           \
00433     UInt32   name##Stride = 0;                                              \
00434                                                                             \
00435     name##Ptr = geo->getmethod();                                           \
00436     if ( name##Ptr != NullFC )                                              \
00437     {                                                                       \
00438         name##Data = name##Ptr->getData();                                  \
00439         if ( ! ( name##Stride = name##Ptr->getStride() ) )                  \
00440             name##Stride = name##Ptr->getFormatSize() *                     \
00441             name##Ptr->getDimension();                                      \
00442     }
00443 
00444 
00445 // The master pump. Can render everything, but takes ages to do so.
00446 // A real fallback, when everything else fails.
00447 // Its second function is the example of how things are supposed to work.
00448 // If an optimized pump creates a different result, it's wrong.
00449 // The formal specification is defined in the design document though.
00450 
00451 // some little helper macros to make the code more readable
00452 
00453 // define and initialize the variables needed to access the data
00454 
00455 #define pumpInternalSetup( name, typename, getmethod, mandatory )           \
00456     GeoIntegralPropertyPtr name##Ptr;                                       \
00457     UInt32 name##Ind = 0;                                                   \
00458                                                                             \
00459     name##Ptr = geo->getmethod();                                           \
00460     if(mandatory && name##Ptr == NullFC)                                    \
00461     {                                                                       \
00462         SWARNING << "masterPump: Geometry " << geo << " has no "            \
00463                  << #name << "s!" << std::endl;                             \
00464         return;                                                             \
00465     }
00466 
00467 #define pumpGLSetup( name, propindex )                                      \
00468     attribData[propindex] = NULL;                                           \
00469     attribStride[propindex];                                                \
00470     attribInd[propindex] = 0;                                               \
00471     attribPtr[propindex] = NullFC;                                          \
00472     attribIndex[propindex] = NullFC;                                        \
00473     pumpFunc name##Func = NULL;                                             \
00474                                                                             \
00475     attribPtr[propindex] = geo->getProperty(propindex);                     \
00476     if(attribPtr[propindex] != NullFC)                                      \
00477     {                                                                       \
00478         attribIndex[propindex] = geo->getIndex(propindex);                  \
00479         attribData[propindex] = attribPtr[propindex]->getData();            \
00480         if(!(attribStride[propindex] = attribPtr[propindex]->getStride()))  \
00481             attribStride[propindex] =                                       \
00482                             attribPtr[propindex]->getFormatSize() *         \
00483                             attribPtr[propindex]->getDimension();           \
00484         if(!(name##Func = name##Funcs[attribPtr[propindex]->getFormat() -   \
00485                                             formatBase]                     \
00486                                  [attribPtr[propindex]->getDimension() - 1] \
00487           ) )                                                               \
00488         {                                                                   \
00489             SWARNING << "masterPump: Geometry " << geo << " has illegal "   \
00490                      << #name << "s: "                                      \
00491                      << attribPtr[propindex]->getDimension()                \
00492                      << "D " << formatNames[                                \
00493                             attribPtr[propindex]->getFormat() - formatBase ]\
00494                      << "!" << std::endl;                                   \
00495             return;                                                         \
00496         }                                                                   \
00497     }                                                                       \
00498     else                                                                    \
00499     {                                                                       \
00500         attribData[propindex] = NULL;                                       \
00501         name##Func = NULL;                                                  \
00502         attribStride[propindex] = 0;                                        \
00503     }
00504 
00505 #define pumpGLExtSetup( name, propindex )                                   \
00506     attribData[propindex];                                                  \
00507     attribStride[propindex];                                                \
00508     attribInd[propindex] = 0;                                               \
00509     attribPtr[propindex];                                                   \
00510     attribIndex[propindex];                                                 \
00511     pumpFunc name##Func;                                                    \
00512                                                                             \
00513     attribPtr[propindex] = geo->getProperty(propindex);                     \
00514     if(attribPtr[propindex] != NullFC)                                      \
00515     {                                                                       \
00516         attribIndex[propindex] = geo->getIndex(propindex);                  \
00517         attribData[propindex] = attribPtr[propindex]->getData();            \
00518         if(!(attribStride[propindex] = attribPtr[propindex]->getStride()))  \
00519             attribStride[propindex] = attribPtr                             \
00520                 [propindex]->getFormatSize() *                              \
00521                 attribPtr[propindex]->getDimension();                       \
00522         if(name##IDs[attribPtr[propindex]->getFormat() - formatBase]        \
00523                     [attribPtr[propindex]->getDimension() - 1] ==           \
00524                     Window::invalidFunctionID)                              \
00525         {                                                                   \
00526             SWARNING << "masterPump: Geometry " << geo << " has illegal "   \
00527                      << #name << "s: "                                      \
00528                      << attribPtr[propindex]->getDimension()                \
00529                      << "D " << formatNames[                                \
00530                             attribPtr[propindex]->getFormat() - formatBase ]\
00531                      << "!" << std::endl;                                   \
00532             return;                                                         \
00533         }                                                                   \
00534         if(!(name##Func = (pumpFunc)win->getFunction(name##IDs              \
00535                             [attribPtr[propindex]->getFormat() - formatBase]\
00536                             [attribPtr[propindex]->getDimension() - 1])     \
00537           ) )                                                               \
00538         {                                                                   \
00539             SWARNING << "masterPump: Geometry " << geo << " uses "          \
00540                      << #name << "s: "                                      \
00541                      << attribPtr[propindex]->getDimension()                \
00542                      << "D "                                                \
00543                      << formatNames[ attribPtr[propindex]->getFormat() -    \
00544                                             formatBase ]                    \
00545                      << " which are not supported by Window " << win        \
00546                      <<  "!" << std::endl;                                  \
00547             return;                                                         \
00548         }                                                                   \
00549     }                                                                       \
00550     else                                                                    \
00551     {                                                                       \
00552         attribData[propindex] = NULL;                                       \
00553         name##Func = NULL;                                                  \
00554         attribStride[propindex] = 0;                                        \
00555     }
00556 
00557 
00558 #define pumpMultiGLExtSetup( name, propindex )                              \
00559     attribInd[propindex] = 0;                                               \
00560     multiPumpFunc name##Func;                                               \
00561                                                                             \
00562     attribPtr[propindex] = geo->getProperty(propindex);                     \
00563     if(attribPtr[propindex] != NullFC)                                      \
00564     {                                                                       \
00565         attribIndex[propindex] = geo->getIndex(propindex);                  \
00566         attribData[propindex] = attribPtr[propindex]->getData();            \
00567         if(!(attribStride[propindex] = attribPtr[propindex]->getStride()))  \
00568             attribStride[propindex] =                                       \
00569                 attribPtr[propindex]->getFormatSize() *                     \
00570                 attribPtr[propindex]->getDimension();                       \
00571         if(name##IDs[attribPtr[propindex]->getFormat() - formatBase]        \
00572                     [attribPtr[propindex]->getDimension() - 1] ==           \
00573                     Window::invalidFunctionID)                              \
00574         {                                                                   \
00575             SWARNING << "masterPump: Geometry " << geo << " has illegal "   \
00576                      << #name << "s: "                                      \
00577                      << attribPtr[propindex]->getDimension()                \
00578                      << "D "                                                \
00579                      << formatNames[ attribPtr[propindex]->getFormat() -    \
00580                                             formatBase ]                    \
00581                      << "!" << std::endl;                                   \
00582             return;                                                         \
00583         }                                                                   \
00584         if(!(name##Func = (multiPumpFunc)win->getFunction(name##IDs         \
00585                             [attribPtr[propindex]->getFormat() - formatBase]\
00586                             [attribPtr[propindex]->getDimension() - 1])     \
00587           ) )                                                               \
00588         {                                                                   \
00589             SWARNING << "masterPump: Geometry " << geo << " uses "          \
00590                      << #name << "s: "                                      \
00591                      << attribPtr[propindex]->getDimension()                \
00592                      << "D "                                                \
00593                      << formatNames[ attribPtr[propindex]->getFormat() -    \
00594                                             formatBase ]                    \
00595                      << " which are not supported by Window " << win        \
00596                      <<  "!" << std::endl;                                  \
00597             return;                                                         \
00598         }                                                                   \
00599     }                                                                       \
00600     else                                                                    \
00601     {                                                                       \
00602         attribData[propindex] = NULL;                                       \
00603         name##Func = NULL;                                                  \
00604         attribStride[propindex] = 0;                                        \
00605     }
00606 
00607 void GeoVertexArrayPumpGroup::masterClassicGeoPump(DrawEnv  *pEnv,
00608                                                    Geometry *geo)
00609 {
00610     Window *win = pEnv->getWindow();
00611     
00612     // Setup: get all the data
00613 
00614     pumpInternalSetup( Type, GeoPTypesPtr, getTypes, true );
00615     pumpInternalSetup( Length, GeoPLengthsPtr, getLengths, false );
00616     
00617     // check if the node is empty
00618     if(TypePtr == NullFC || TypePtr->getSize() == 0)
00619         return;
00620     
00621     const UInt8 *attribData[Geometry::MaxAttribs];
00622     UInt32 attribStride[Geometry::MaxAttribs];
00623     UInt32 attribInd[Geometry::MaxAttribs];
00624     GeoVectorPropertyPtr attribPtr[Geometry::MaxAttribs];
00625     GeoIntegralPropertyPtr attribIndex[Geometry::MaxAttribs];
00626 
00627     for(Int16 i = 0; i < Geometry::MaxAttribs; ++i)
00628     {
00629         attribData[i] = NULL;
00630         attribPtr[i] = NullFC;
00631         attribIndex[i] = NullFC;        
00632     }
00633 
00634     pumpGLSetup        ( Position,   Geometry::PositionsIndex      );
00635     pumpGLSetup        ( Color,      Geometry::ColorsIndex         );
00636     pumpGLSetup        ( Normal,     Geometry::NormalsIndex        );
00637     pumpGLSetup        ( TexCoords,  Geometry::TexCoordsIndex      );
00638     pumpGLExtSetup     ( SecColor,   Geometry::SecondaryColorsIndex);
00639     pumpMultiGLExtSetup( TexCoords1, Geometry::TexCoords1Index     );
00640     pumpMultiGLExtSetup( TexCoords2, Geometry::TexCoords2Index     );
00641     pumpMultiGLExtSetup( TexCoords3, Geometry::TexCoords3Index     );
00642     pumpMultiGLExtSetup( TexCoords4, Geometry::TexCoords4Index     );
00643     pumpMultiGLExtSetup( TexCoords5, Geometry::TexCoords5Index     );
00644     pumpMultiGLExtSetup( TexCoords6, Geometry::TexCoords6Index     );
00645     pumpMultiGLExtSetup( TexCoords7, Geometry::TexCoords7Index     );
00646     
00647     // check if the node is empty
00648     if(TypePtr == NullFC || TypePtr->getSize() == 0)
00649         return;
00650 
00651     // if it's not empty we need positions
00652     if(!attribData[Geometry::PositionsIndex])
00653     {
00654         SWARNING << "masterPump: Geometry " << geo << " has no positions!?!"
00655                  << endLog;
00656         return;
00657     }
00658 
00659     // overall attributes?
00660     if(attribData[Geometry::NormalsIndex] != NULL && 
00661        attribPtr[Geometry::NormalsIndex]->getSize() == 1) 
00662     {
00663         NormalFunc(attribData[Geometry::NormalsIndex]);
00664         attribData[Geometry::NormalsIndex] = NULL;
00665     }
00666     if(attribData[Geometry::ColorsIndex] != NULL&& 
00667        attribPtr[Geometry::ColorsIndex]->getSize() == 1)   
00668     {
00669         ColorFunc(attribData[Geometry::ColorsIndex]);
00670         attribData[Geometry::ColorsIndex] = NULL;
00671     }
00672     if(win->hasExtension(_extSecondaryColor) && 
00673        attribData[Geometry::SecondaryColorsIndex] != NULL&& 
00674        attribPtr[Geometry::SecondaryColorsIndex]->getSize() == 1)    
00675     {
00676         SecColorFunc(attribData[Geometry::SecondaryColorsIndex]);
00677         attribData[Geometry::SecondaryColorsIndex] = NULL;
00678     }
00679     if(attribData[Geometry::TexCoordsIndex] != NULL&& 
00680        attribPtr[Geometry::TexCoordsIndex]->getSize() == 1)   
00681     {
00682         TexCoordsFunc(attribData[Geometry::TexCoordsIndex]);
00683         attribData[Geometry::TexCoordsIndex] = NULL;
00684     }
00685     if(win->hasExtension(_extMultitexture))
00686     {
00687         if(attribData[Geometry::TexCoords1Index] != NULL&& 
00688            attribPtr[Geometry::TexCoords1Index]->getSize() == 1)   
00689         {
00690             TexCoords1Func(GL_TEXTURE1_ARB, 
00691                            attribData[Geometry::TexCoords1Index]);
00692             attribData[Geometry::TexCoords1Index] = NULL;
00693         }
00694         if(attribData[Geometry::TexCoords2Index] != NULL&& 
00695            attribPtr[Geometry::TexCoords2Index]->getSize() == 1)   
00696         {
00697             TexCoords2Func(GL_TEXTURE2_ARB, 
00698                            attribData[Geometry::TexCoords2Index]);
00699             attribData[Geometry::TexCoords2Index] = NULL;
00700         }
00701         if(attribData[Geometry::TexCoords3Index] != NULL&& 
00702            attribPtr[Geometry::TexCoords3Index]->getSize() == 1)   
00703         {
00704             TexCoords3Func(GL_TEXTURE3_ARB, 
00705                            attribData[Geometry::TexCoords3Index]);
00706             attribData[Geometry::TexCoords3Index] = NULL;
00707         }
00708         if(attribData[Geometry::TexCoords4Index] != NULL&& 
00709            attribPtr[Geometry::TexCoords4Index]->getSize() == 1)   
00710         {
00711             TexCoords2Func(GL_TEXTURE4_ARB, 
00712                            attribData[Geometry::TexCoords4Index]);
00713             attribData[Geometry::TexCoords4Index] = NULL;
00714         }
00715         if(attribData[Geometry::TexCoords5Index] != NULL&& 
00716            attribPtr[Geometry::TexCoords5Index]->getSize() == 1)   
00717         {
00718             TexCoords2Func(GL_TEXTURE5_ARB, 
00719                            attribData[Geometry::TexCoords5Index]);
00720             attribData[Geometry::TexCoords5Index] = NULL;
00721         }
00722         if(attribData[Geometry::TexCoords6Index] != NULL&& 
00723            attribPtr[Geometry::TexCoords6Index]->getSize() == 1)   
00724         {
00725             TexCoords2Func(GL_TEXTURE6_ARB, 
00726                            attribData[Geometry::TexCoords6Index]);
00727             attribData[Geometry::TexCoords6Index] = NULL;
00728         }
00729         if(attribData[Geometry::TexCoords7Index] != NULL&& 
00730            attribPtr[Geometry::TexCoords7Index]->getSize() == 1)   
00731         {
00732             TexCoords2Func(GL_TEXTURE7_ARB, 
00733                            attribData[Geometry::TexCoords7Index]);
00734             attribData[Geometry::TexCoords7Index] = NULL;
00735         }
00736     }
00737     
00738     // Set up attribute arrays
00739     // !!! This should be using the global state to reduce state changes
00740     // and to allow sharing data between objects
00741 
00742     UInt16 nattrib = geo->getProperties().size();
00743 
00744     for(Int16 i = nattrib - 1; i >= 0; --i)
00745     {
00746         if(attribData[i])
00747         {
00748             attribPtr[i]->activate(pEnv, i);
00749         }
00750     }
00751     
00752     // Length handling. Special case: no length given
00753 
00754     UInt32 curlen;
00755     UInt32 nprims;
00756 
00757     // no lengths? use all available data for the first type
00758     if(LengthPtr == NullFC)
00759     {
00760         if(TypePtr->getSize() != 1)
00761         {
00762             SWARNING << "masterPump: Geometry " << geo 
00763                      << " has no length but more than one type!?!"
00764                      << endLog;
00765             return;
00766         }
00767         
00768         nprims = 1;
00769         if (attribIndex[Geometry::PositionsIndex] != NullFC)
00770         {
00771             curlen = attribIndex[Geometry::PositionsIndex]->getSize();
00772         }
00773         else
00774         {
00775             curlen = attribPtr[Geometry::PositionsIndex]->getSize();
00776         }
00777     }
00778     else
00779     {
00780         nprims = TypePtr->getSize();
00781         LengthPtr->getValue(curlen, 0);
00782     }
00783     
00784     UInt32 vertindex = 0;
00785 
00786     if(attribIndex[0] != NullFC)
00787     {        
00788         // Indexed, i.e. Single Indexed
00789 
00790         GeoIntegralPropertyPtr index = attribIndex[0];
00791         GLenum        indexFormat = index->getFormat();
00792         UInt32        indexSize   = index->getSize();
00793         UInt32        indexStride = index->getStride() ? 
00794                                 index->getStride() : index->getFormatSize() *
00795                                                      index->getDimension();
00796         const UInt8  *indexData   = index->getData();
00797         
00798         index->activate(pEnv, 0);
00799         
00800         if(index->isInVBO(pEnv))
00801             indexData = NULL;
00802         else if (win->hasExtension(_extCompiledVertexArray))
00803         {
00804             void (OSG_APIENTRY*_glLockArraysEXT) 
00805                 (GLint first, GLsizei count)=
00806             (void (OSG_APIENTRY*) (GLint first, GLsizei count))
00807                 win->getFunction(_funcglLockArraysEXT);
00808 
00809             _glLockArraysEXT(0, indexSize);
00810         }
00811 
00812         void (OSG_APIENTRY *osgGLDrawRangeElementsEXT)
00813                 (GLenum mode, GLuint start,
00814                  GLuint end, GLsizei count, 
00815                  GLenum type, const GLvoid*indices) =
00816         (void (OSG_APIENTRY *)(GLenum mode, GLuint start,
00817                GLuint end, GLsizei count, GLenum type, const GLvoid*indices))
00818                 win->getFunction(_funcglDrawRangeElementsEXT);
00819 
00820         if(win->hasExtension(_extDrawRangeElements))
00821         {
00822             for(UInt32 primindex = 0; primindex < nprims; ++primindex)
00823             {
00824                 if(primindex < LengthPtr->getSize())
00825                     curlen = LengthPtr->getValue<UInt32>(primindex);
00826 
00827                 osgGLDrawRangeElementsEXT(TypePtr->getValue<UInt16>(primindex),
00828                                           0, 
00829                                           indexSize, 
00830                                           curlen,
00831                                           indexFormat, 
00832                                           indexData + vertindex * indexStride);
00833                 
00834                 vertindex += curlen;
00835             }
00836         }
00837         else
00838         {
00839             for(UInt32 primindex = 0; primindex < nprims; ++primindex)
00840             {
00841                 if(primindex < LengthPtr->getSize())
00842                     curlen = LengthPtr->getValue<UInt32>(primindex);
00843 
00844                 glDrawElements(TypePtr->getValue<UInt16>(primindex),
00845                                curlen,
00846                                indexFormat, 
00847                                indexData + vertindex * indexStride);
00848                 
00849                 vertindex += curlen;
00850             }
00851         }        
00852 
00853         if(!index->isInVBO(pEnv) && win->hasExtension(_extCompiledVertexArray))
00854         {
00855             void (OSG_APIENTRY*_glUnlockArraysEXT)(void)=
00856             (void (OSG_APIENTRY*) (void))
00857                 win->getFunction(_funcglUnlockArraysEXT);
00858 
00859             _glUnlockArraysEXT();
00860         }
00861         else
00862         {
00863             index->deactivate(pEnv);
00864         }
00865 
00866     }
00867     else
00868     {
00869         // Non-indexed
00870         for(UInt32 primindex = 0; primindex < nprims; ++primindex)
00871         {
00872             if(primindex < LengthPtr->getSize())
00873                 curlen = LengthPtr->getValue<UInt32>(primindex);
00874 
00875             glDrawArrays(TypePtr->getValue<UInt16>(primindex), vertindex,
00876                          curlen);
00877             vertindex += curlen;
00878 
00879         }
00880     }
00881 
00882 
00883     // disable arrays
00884     for(Int16 i = nattrib - 1; i >= 0; --i)
00885     {
00886         if(attribData[i])
00887         {
00888             attribPtr[i]->deactivate(pEnv, i);
00889         }
00890     }
00891 }
00892 
00893 void GeoVertexArrayPumpGroup::masterAttribGeoPump(DrawEnv  *pEnv,
00894                                                   Geometry *geo )
00895 {
00896     Window *win = pEnv->getWindow();
00897     
00898     // Setup: get all the data
00899 
00900     pumpInternalSetup( Type, GeoPTypesPtr, getTypes, true );
00901     pumpInternalSetup( Length, GeoPLengthsPtr, getLengths, false );
00902        
00903     // check if the node is empty
00904     if(TypePtr == NullFC || TypePtr->getSize() == 0)
00905         return;
00906 
00907     // Most of these are only needed for global attribs ...
00908     
00909     const UInt8 *attribData[Geometry::MaxAttribs];
00910     UInt32 attribStride[Geometry::MaxAttribs];
00911     UInt32 attribInd[Geometry::MaxAttribs];
00912     GeoVectorPropertyPtr attribPtr[Geometry::MaxAttribs];
00913     GeoIntegralPropertyPtr attribIndex[Geometry::MaxAttribs];
00914     attribPumpFunc attribFunc[Geometry::MaxAttribs];
00915 
00916     UInt16 nattrib = geo->getProperties().size();
00917     
00918     for(UInt16 i = 0; i < nattrib; ++i)
00919     {
00920         attribInd[i] = 0;
00921         attribPtr[i] = geo->getProperty(i);
00922         if(attribPtr[i] != NullFC)
00923         {
00924             attribIndex[i] = geo->getIndex(i);
00925             attribData[i] = attribPtr[i]->getData();
00926             if(!(attribStride[i] = attribPtr[i]->getStride()))
00927                 attribStride[i] = attribPtr[i]->getFormatSize() *
00928                                   attribPtr[i]->getDimension();
00929                                   
00930             UInt32 funcid;
00931             
00932             if(attribPtr[i]->getNormalize())
00933             {
00934                 if(NormAttribIDs[attribPtr[i]->getFormat() - formatBase]
00935                                 [attribPtr[i]->getDimension() - 1] ==
00936                             Window::invalidFunctionID)
00937                 {
00938                     SWARNING << "masterPump: Geometry " << geo 
00939                              << " has illegal attribute " << i 
00940                              << ": " << attribPtr[i]->getDimension()
00941                              << "D " << formatNames[ attribPtr[i]->getFormat() -
00942                                                     formatBase ]
00943                              << " (normalizing)!" << std::endl;
00944                     return;
00945                 } 
00946                 funcid = NormAttribIDs[attribPtr[i]->getFormat() - formatBase]
00947                                       [attribPtr[i]->getDimension() - 1];    
00948             }
00949             else
00950             {
00951                 if(AttribIDs[attribPtr[i]->getFormat() - formatBase]
00952                             [attribPtr[i]->getDimension() - 1] ==
00953                             Window::invalidFunctionID)
00954                 {
00955                     SWARNING << "masterPump: Geometry " << geo 
00956                              << " has illegal attribute " << i 
00957                              << ": " << attribPtr[i]->getDimension()
00958                              << "D " << formatNames[ attribPtr[i]->getFormat() -
00959                                                     formatBase ]
00960                              << "!" << std::endl;
00961                     return;
00962                 } 
00963                 funcid = AttribIDs[attribPtr[i]->getFormat() - formatBase]
00964                                   [attribPtr[i]->getDimension() - 1];    
00965             }
00966             
00967             if(!(attribFunc[i] = (attribPumpFunc)win->getFunction(funcid) ) )
00968             {
00969                 SWARNING << "masterPump: Geometry " << geo << " uses "
00970                          << "attribute " << i << " "
00971                          << attribPtr[i]->getDimension()
00972                          << "D " << formatNames[ attribPtr[i]->getFormat() -
00973                                                 formatBase ]
00974                          << " which are not supported by Window " << win
00975                          <<  "!" << std::endl;
00976                 return;
00977             }
00978         }
00979         else
00980         {
00981             attribData[i] = NULL;
00982             attribFunc[i] = NULL;
00983             attribStride[i] = 0;
00984         }
00985     }
00986 
00987     // if it's not empty we need positions
00988     if(!attribData[0])
00989     {
00990         SWARNING << "masterPump: Geometry " << geo << " h