void GeoImmediatePumpGroup::masterClassicGeoPump(
          DrawEnv                     *pEnv,
    const GeoIntegralProperty         *lengths,
    const GeoIntegralProperty         *types,
    const Geometry::MFPropertiesType  *prop,
    const Geometry::MFPropIndicesType *propIdx)
{
    Window *win = pEnv->getWindow();

    // Setup: get all the data

    // check for empty geometry
    if(types == NULL || types->getSize() == 0)
        return;

    if(!pumpInternalSetup(types,   true))
        return;
    if(!pumpInternalSetup(lengths, false))
        return;

    PumpClassicInfo pumpInfo;
    pumpInfo.lengths = lengths;
    pumpInfo.types   = types;
    pumpInfo.prop    = prop;
    pumpInfo.propIdx = propIdx;

    // setup standard properties
    pumpGLSetup(pumpInfo, Geometry::PositionsIndex, PositionsPumpSlot);
    pumpGLSetup(pumpInfo, Geometry::ColorsIndex,    ColorsPumpSlot);
    pumpGLSetup(pumpInfo, Geometry::NormalsIndex,   NormalsPumpSlot);
    pumpGLSetup(pumpInfo, Geometry::TexCoordsIndex, TexCoordsPumpSlot);

    // setup extension properties
    if(win->hasExtension(_extSecondaryColor) == true)
    {
        pumpGLExtSetup(pumpInfo, Geometry::SecondaryColorsIndex,
                       SecColorsPumpSlot, win);
    }

    // setup extension multi properties
    if(win->hasExtension(_extMultitexture) == true)
    {
        pumpGLExtMultiSetup(pumpInfo, Geometry::TexCoords1Index,
                            TexCoords1PumpSlot, win);
        pumpGLExtMultiSetup(pumpInfo, Geometry::TexCoords2Index,
                            TexCoords2PumpSlot, win);
        pumpGLExtMultiSetup(pumpInfo, Geometry::TexCoords3Index,
                            TexCoords3PumpSlot, win);
        pumpGLExtMultiSetup(pumpInfo, Geometry::TexCoords4Index,
                            TexCoords4PumpSlot, win);
        pumpGLExtMultiSetup(pumpInfo, Geometry::TexCoords5Index,
                            TexCoords5PumpSlot, win);
        pumpGLExtMultiSetup(pumpInfo, Geometry::TexCoords6Index,
                            TexCoords6PumpSlot, win);
        pumpGLExtMultiSetup(pumpInfo, Geometry::TexCoords7Index,
                            TexCoords7PumpSlot, win);
    }

    // we need positions
    if(pumpInfo.attribPtr[Geometry::PositionsIndex] == NULL)
    {
        if(pumpInfo.attribPtr[Geometry::PositionsIndex]              == NULL ||
           pumpInfo.attribPtr[Geometry::PositionsIndex]->getUseVBO() == false)
        {
            SWARNING << "GeoImmediatePumpGroup::masterClassicGeoPump: "
                     << "No positions." << endLog;
            return;
        }
    }

    // global attribs?
    globalAttrib(pumpInfo, Geometry::NormalsIndex,   NormalsPumpSlot);
    globalAttrib(pumpInfo, Geometry::ColorsIndex,    ColorsPumpSlot);
    globalAttrib(pumpInfo, Geometry::TexCoordsIndex, TexCoordsPumpSlot);

    if(win->hasExtension(_extSecondaryColor) == true)
    {
        globalExtAttrib(pumpInfo,          Geometry::SecondaryColorsIndex,
                        SecColorsPumpSlot, win                            );
    }

    if(win->hasExtension(_extMultitexture) == true)
    {
        globalExtMultiAttrib(pumpInfo,           Geometry::TexCoords1Index,
                             TexCoords1PumpSlot, GL_TEXTURE1_ARB, win);
        globalExtMultiAttrib(pumpInfo,           Geometry::TexCoords1Index,
                             TexCoords2PumpSlot, GL_TEXTURE2_ARB, win);
        globalExtMultiAttrib(pumpInfo,           Geometry::TexCoords1Index,
                             TexCoords3PumpSlot, GL_TEXTURE3_ARB, win);
        globalExtMultiAttrib(pumpInfo,           Geometry::TexCoords1Index,
                             TexCoords4PumpSlot, GL_TEXTURE4_ARB, win);
        globalExtMultiAttrib(pumpInfo,           Geometry::TexCoords1Index,
                             TexCoords5PumpSlot, GL_TEXTURE5_ARB, win);
        globalExtMultiAttrib(pumpInfo,           Geometry::TexCoords1Index,
                             TexCoords6PumpSlot, GL_TEXTURE6_ARB, win);
        globalExtMultiAttrib(pumpInfo,           Geometry::TexCoords1Index,
                             TexCoords7PumpSlot, GL_TEXTURE7_ARB, win);
    }

    // Length handling. Special case: no length given

    UInt32 curlen;
    UInt32 nprims;

    // no lengths? use all available data for the first type
    if(lengths == NULL)
    {
        if(types->getSize() != 1)
        {
            SWARNING << "GeoImmediatePumpGroup::masterClassicGeoPump: "
                     << "No lengths, but more than one type?!"
                     << endLog;
            return;
        }

        nprims = 1;
        if(pumpInfo.attribIndex[Geometry::PositionsIndex] != NULL)
        {
            curlen = pumpInfo.attribIndex[Geometry::PositionsIndex]->getSize();
        }
        else
        {
            curlen = pumpInfo.attribPtr[Geometry::PositionsIndex]->getSize();
        }
    }
    else
    {
        nprims = types->getSize();
        lengths->getValue(curlen, 0);
    }

    UInt32 vertindex = 0;

    for(UInt32 primindex = 0; primindex < nprims; ++primindex)
    {
        glBegin(types->getValue<UInt16>(primindex));

        if(primindex < lengths->getSize())
            curlen = lengths->getValue<UInt32>(primindex);

        for(; curlen > 0; --curlen, ++vertindex)
        {
            pumpAttrib(pumpInfo, Geometry::NormalsIndex,   vertindex);
            pumpAttrib(pumpInfo, Geometry::ColorsIndex,    vertindex);
            pumpAttrib(pumpInfo, Geometry::TexCoordsIndex, vertindex);

            if(win->hasExtension(_extSecondaryColor) == true)
            {
                pumpAttrib(pumpInfo, Geometry::SecondaryColorsIndex, vertindex);
            }

            if(win->hasExtension(_extMultitexture))
            {
                pumpMultiAttrib(pumpInfo, Geometry::TexCoords1Index,
                                GL_TEXTURE1_ARB, vertindex);
                pumpMultiAttrib(pumpInfo, Geometry::TexCoords2Index,
                                GL_TEXTURE2_ARB, vertindex);
                pumpMultiAttrib(pumpInfo, Geometry::TexCoords3Index,
                                GL_TEXTURE3_ARB, vertindex);
                pumpMultiAttrib(pumpInfo, Geometry::TexCoords4Index,
                                GL_TEXTURE4_ARB, vertindex);
                pumpMultiAttrib(pumpInfo, Geometry::TexCoords5Index,
                                GL_TEXTURE5_ARB, vertindex);
                pumpMultiAttrib(pumpInfo, Geometry::TexCoords6Index,
                                GL_TEXTURE6_ARB, vertindex);
                pumpMultiAttrib(pumpInfo, Geometry::TexCoords7Index,
                                GL_TEXTURE7_ARB, vertindex);
            }

            pumpAttrib(pumpInfo, Geometry::PositionsIndex, vertindex);
        }

        glEnd();
    }
}
void GeoSplitVertexArrayPumpGroup::masterClassicGeoJustDrawPump(
          DrawEnv                     *pEnv,
    const GeoIntegralProperty         *lengths,
    const GeoIntegralProperty         *types,
    const Geometry::MFPropertiesType  *prop,
    const Geometry::MFPropIndicesType *propIdx,
          UInt32                       uiNumInstances)
{
#ifdef DEBUG_WHICH_PUMP
    static bool bPrinted = false;

    if(bPrinted == false)
    {
        fprintf(stderr, 
                "GeoSplitVertexArrayPumpGroup::masterClassicGeoJustDrawPump\n");
        bPrinted = true;
    }
#endif

    Window *win = pEnv->getWindow();

    // check for empty geometry
    if(types == NULL || types->size() == 0)
        return;

    if(!pumpInternalSetup(types,   true))
        return;
    if(!pumpInternalSetup(lengths, false))
        return;

    PumpData       pumpData;

    pumpData.lengths = lengths;
    pumpData.types   = types;
    pumpData.prop    = prop;
    pumpData.propIdx = propIdx;

    UInt16 nattrib = prop->size32();

    for(UInt16 i = 0; i < nattrib; ++i)
    {
        if(pumpGLSetup(pumpData, i) == false)
            continue;
    }

    // Length handling. Special case: no length given

    UInt32 curlen;
    UInt32 nprims;

    // no lengths? use all available data for the first type
    if(lengths == NULL)
    {
        if(types->size() != 1)
        {
            SWARNING << "GeoVertexArrayPumpGroup::masterAttribGeoPump: "
                     << "No lengths, but more than one type?!"
                     << endLog;
            return;
        }

        nprims = 1;

        if(propIdx->size() != 0 && (*propIdx)[0] != NULL)
        {
            curlen = (*propIdx)[0]->size32();
        }
        else
        {
            curlen = (*prop)[0]->size32();
        }
    }
    else
    {
        nprims = types->size32();
        lengths->getValue(curlen, 0);
    }

    // global attribs?
    globalAttrib(pumpData, Geometry::NormalsIndex,   NormalsPumpSlot);
    globalAttrib(pumpData, Geometry::ColorsIndex,    ColorsPumpSlot);
    globalAttrib(pumpData, Geometry::TexCoordsIndex, TexCoordsPumpSlot);

    if(win->hasExtOrVersion(_extSecondaryColor, 0x0104) == true)
    {
        globalExtAttrib(pumpData,          Geometry::SecondaryColorsIndex,
                        SecColorsPumpSlot, win                            );
    }

    if(win->hasExtOrVersion(_extMultitexture, 0x0103, 0x0200) == true)
    {
        globalExtMultiAttrib(pumpData,           Geometry::TexCoords1Index,
                             TexCoords1PumpSlot, GL_TEXTURE1_ARB, win);
        globalExtMultiAttrib(pumpData,           Geometry::TexCoords1Index,
                             TexCoords2PumpSlot, GL_TEXTURE2_ARB, win);
        globalExtMultiAttrib(pumpData,           Geometry::TexCoords1Index,
                             TexCoords3PumpSlot, GL_TEXTURE3_ARB, win);
        globalExtMultiAttrib(pumpData,           Geometry::TexCoords1Index,
                             TexCoords4PumpSlot, GL_TEXTURE4_ARB, win);
        globalExtMultiAttrib(pumpData,           Geometry::TexCoords1Index,
                             TexCoords5PumpSlot, GL_TEXTURE5_ARB, win);
        globalExtMultiAttrib(pumpData,           Geometry::TexCoords1Index,
                             TexCoords6PumpSlot, GL_TEXTURE6_ARB, win);
        globalExtMultiAttrib(pumpData,           Geometry::TexCoords1Index,
                             TexCoords7PumpSlot, GL_TEXTURE7_ARB, win);
    }

    UInt32 vertindex = 0;

    if(propIdx->size() != 0 && (*propIdx)[0] != NULL)
    {
        // Single Indexed

        GeoIntegralProperty *index       = (*propIdx)[0];
        const UInt8         *indexData   = index->getData();
        GLenum               indexFormat = index->getFormat();
        UInt32               indexStride =
            index->getStride() ? index->getStride() : index->getFormatSize() *
            index->getDimension();

#if 0
        index->activate(pEnv, 0);

        if(index->isInVBO(pEnv))
        {
#endif
            indexData = NULL;
#if 0
        }
#endif

        if(uiNumInstances > 1)
        {        
            OSGGETGLFUNCBYID_GL3_ES(glDrawElementsInstanced,
                                    osgGlDrawElementsInstanced,
                                    Geometry::getFuncIdDrawElementsInstanced(),
                                    win);

            for(UInt32 primindex = 0; primindex < nprims; ++primindex)
            {
                if(primindex < lengths->size())
                    curlen = lengths->getValue<UInt32>(primindex);

                if(curlen > 0)
                {
                    osgGlDrawElementsInstanced(
                        types->getValue<UInt16>(primindex),
                        curlen,
                        indexFormat,
                        indexData + vertindex * indexStride,
                        uiNumInstances                     );

                    vertindex += curlen;
                }
            }
        }
        else
        {
            for(UInt32 primindex = 0; primindex < nprims; ++primindex)
            {
                if(primindex < lengths->size())
                    curlen = lengths->getValue<UInt32>(primindex);

                if(curlen > 0)
                {
                    glDrawElements(types->getValue<UInt16>(primindex),
                                   curlen,
                                   indexFormat,
                                   indexData + vertindex * indexStride);

                    vertindex += curlen;
                }
            }
        }

#if 0
        index->deactivate(pEnv, 0);
#endif
    }
    else
    {
        if(uiNumInstances > 1)
        {
            OSGGETGLFUNCBYID_GL3_ES(glDrawArraysInstanced,
                                    osgGlDrawArraysInstanced,
                                    Geometry::getFuncIdDrawArraysInstanced(),
                                    win);
            // Non-indexed
            for(UInt32 primindex = 0; primindex < nprims; ++primindex)
            {
                if(primindex < lengths->size())
                    curlen = lengths->getValue<UInt32>(primindex);

                if(curlen > 0)
                {
                    osgGlDrawArraysInstanced(
                        types->getValue<UInt16>(primindex), 
                        vertindex,
                        curlen,
                        uiNumInstances);

                    vertindex += curlen;
                }
            }
        }
        else
        {
            // Non-indexed
            for(UInt32 primindex = 0; primindex < nprims; ++primindex)
            {
                if(primindex < lengths->size())
                    curlen = lengths->getValue<UInt32>(primindex);

                if(curlen > 0)
                {
                    glDrawArrays(types->getValue<UInt16>(primindex), vertindex,
                                 curlen);
                    vertindex += curlen;
                }
            }
        }
    }
}