bool GeoVectorBufferRefProperty::unmapBuffer(DrawEnv *pEnv)
{
    bool returnValue = true;

    if((getUseVBO() == true) && (getGLId() != 0))
    {
        Window *pWin = pEnv->getWindow();

        OSGGETGLFUNCBYID( OSGglBindBufferARB, 
                          osgGlBindBufferARB,
                         _funcBindBuffer, 
                          pWin);

        OSGGETGLFUNCBYID( OSGglUnmapBufferARB, 
                          osgGlUnmapBufferARB,
                         _funcUnmapBuffer, 
                          pWin);

        osgGlBindBufferARB(GL_ARRAY_BUFFER_ARB,
                           getGLId());

        returnValue = osgGlUnmapBufferARB(GL_ARRAY_BUFFER_ARB);

        osgGlBindBufferARB(GL_ARRAY_BUFFER_ARB, 0);
    }
    
    return returnValue;
}
void GeoIntegralBufferRefProperty::changeFrom(DrawEnv    *pEnv, 
                                              StateChunk *old, 
                                              UInt32      slot)
{
    // change from me to me?
    // this assumes I haven't changed in the meantime.
    if(old == this)
        return;

    Window *win = pEnv->getWindow();

    GeoIntegralProperty *o = dynamic_cast<GeoIntegralProperty*>(old);
    
    if(!win->hasExtension(_extVertexBufferObject))
        return;

    OSGGETGLFUNCBYID( OSGglBindBufferARB, 
                      osgGlBindBufferARB,
                     _funcBindBuffer, 
                      win);

    if(getGLId() != 0 && getUseVBO()) // Do we have a VBO?
    {
        osgGlBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 
                           getGLId());
    }
    else if(o != NULL && o->getGLId() != 0 && o->getUseVBO())
    {
        osgGlBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 0);            
    }
}
void *GeoVectorBufferRefProperty::mapBuffer(GLenum eAccess, DrawEnv *pEnv)
{
    void *returnValue = NULL;

    if((getUseVBO() == true) && (getGLId() != 0))
    {
        Window *pWin = pEnv->getWindow();

        OSGGETGLFUNCBYID( OSGglBindBufferARB, 
                          osgGlBindBufferARB,
                         _funcBindBuffer, 
                          pWin);

        OSGGETGLFUNCBYID( OSGglMapBufferARB, 
                          osgGlMapBufferARB,
                         _funcMapBuffer, 
                          pWin);
       
        osgGlBindBufferARB(GL_ARRAY_BUFFER_ARB,
                           getGLId());

        returnValue = osgGlMapBufferARB(GL_ARRAY_BUFFER_ARB, eAccess);

        osgGlBindBufferARB(GL_ARRAY_BUFFER_ARB, 0);
    }

    return returnValue;
}
bool GeoVectorProperty::unmapBuffer(DrawEnv *pEnv)
{
    bool returnValue = true;

    if((getUseVBO() == true) && (getGLId() != 0))
    {
        Window *pWin = pEnv->getWindow();

        osgSinkUnusedWarning(pWin);

        OSGGETGLFUNCBYID_GL3_ES( glBindBuffer, 
                                 osgGlBindBuffer,
                                _funcBindBuffer, 
                                 pWin);

        OSGGETGLFUNCBYID_GL3   ( glUnmapBuffer, 
                                 osgGlUnmapBuffer,
                                _funcUnmapBuffer, 
                                 pWin);

        osgGlBindBuffer(GL_ARRAY_BUFFER_ARB,
                        pWin->getGLObjectId(getGLId()));

        returnValue = (osgGlUnmapBuffer(GL_ARRAY_BUFFER_ARB) != 0);

        osgGlBindBuffer(GL_ARRAY_BUFFER_ARB, 0);
    }
    
    return returnValue;
}
void *GeoVectorProperty::mapBuffer(GLenum eAccess, DrawEnv *pEnv)
{
    void *returnValue = NULL;

    if((getUseVBO() == true) && (getGLId() != 0))
    {
        Window *pWin = pEnv->getWindow();

        osgSinkUnusedWarning(pWin);

        OSGGETGLFUNCBYID_GL3_ES( glBindBuffer, 
                                 osgGlBindBuffer,
                                _funcBindBuffer, 
                                 pWin);

        OSGGETGLFUNCBYID_GL3   ( glMapBuffer, 
                                 osgGlMapBuffer,
                                _funcMapBuffer, 
                                 pWin);

        pWin->validateGLObject(getGLId(), pEnv);                
        
        osgGlBindBuffer(GL_ARRAY_BUFFER_ARB,
                        pWin->getGLObjectId(getGLId()));

        returnValue = osgGlMapBuffer(GL_ARRAY_BUFFER_ARB, eAccess);

        osgGlBindBuffer(GL_ARRAY_BUFFER_ARB, 0);
    }

    return returnValue;
}
void GeoIntegralBufferRefProperty::activate(DrawEnv *pEnv, UInt32 slot)
{
    Window *win = pEnv->getWindow();
    
    if(!win->hasExtension(_extVertexBufferObject))
        return;

    if(getGLId() != 0 && getUseVBO()) // Do we have a VBO?
    {
        OSGGETGLFUNCBYID( OSGglBindBufferARB, 
                          osgGlBindBufferARB,
                         _funcBindBuffer, 
                          win);

        osgGlBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 
                           getGLId());
    }
}
void GeoVectorBufferRefProperty::activate(DrawEnv *pEnv, UInt32 slot)
{
#ifndef OSG_EMBEDDED
    Window *win = pEnv->getWindow();

    bool isGeneric = (slot >= 16);  // !!!HACK. needs to be replaced for 2.0
    slot &= 15;

    bool hasVBO = win->hasExtension(_extVertexBufferObject);

    if(hasVBO && isGeneric == true)
    {
        OSGGETGLFUNCBYID( OSGglVertexAttribPointerARB, 
                          osgGlVertexAttribPointerARB,
                         _funcglVertexAttribPointerARB,
                          win);

        if(getGLId() != 0 && getUseVBO()) // Do we have a VBO?
        {
            OSGGETGLFUNCBYID( OSGglBindBufferARB, 
                              osgGlBindBufferARB,
                             _funcBindBuffer, 
                              win);
            
            osgGlBindBufferARB(GL_ARRAY_BUFFER_ARB,
                               getGLId());
            
            osgGlVertexAttribPointerARB(slot, 
                                        getDimension(),
                                        getFormat   (),
                                        getNormalize(),
                                        getStride   (), 
                                        0);
            
            osgGlBindBufferARB(GL_ARRAY_BUFFER_ARB, 0);
        }
        else
        {
            osgGlVertexAttribPointerARB(slot, 
                                        getDimension(),
                                        getFormat   (), 
                                        getNormalize(),
                                        getStride   (), 
                                        getData     ());
        }
        
        OSGGETGLFUNCBYID( OSGglEnableVertexAttribArrayARB,
                          osgGlEnableVertexAttribArrayARB,
                         _funcglEnableVertexAttribArrayARB,
                          win);
        
        osgGlEnableVertexAttribArrayARB(slot);
    }
    else 
    {        
        const void *pData = NULL;

        OSGGETGLFUNCBYID( OSGglBindBufferARB, 
                          osgGlBindBufferARB,
                         _funcBindBuffer, 
                          win);

        hasVBO &= getUseVBO() && (getGLId() != 0);

        if(hasVBO == true) // Do we have a VBO?
        {
            osgGlBindBufferARB(GL_ARRAY_BUFFER_ARB,
                               getGLId());
        }
        else
        {
            pData = getData();
        }
        
        switch(slot)
        {
            case 0:     
                glVertexPointer(getDimension(), 
                                getFormat   (),
                                getStride   (),
                                pData         );

                glEnableClientState(GL_VERTEX_ARRAY);
                break;

            case 2:     
                glNormalPointer(getFormat(),
                                getStride(),
                                pData      );

                glEnableClientState(GL_NORMAL_ARRAY);
                break;

            case 3:   
                glColorPointer(getDimension(), 
                               getFormat   (),
                               getStride   (), 
                               pData         );

                glEnableClientState(GL_COLOR_ARRAY);
                break;

            case 4:   
                if (win->hasExtension(_extSecondaryColor))
                {
                    OSGGETGLFUNCBYID( OSGglSecondaryColorPointerEXT,
                                      osgGlSecondaryColorPointerEXT,
                                     _funcglSecondaryColorPointer,
                                      win);

                    osgGlSecondaryColorPointerEXT(getDimension(),
                                                  getFormat   (),
                                                  getStride   (), 
                                                  pData         );

                    glEnableClientState(GL_SECONDARY_COLOR_ARRAY_EXT);
                }
                else
                {
                    FWARNING(("GeoVectorProperty::activate: Window "
                              "has no Secondary Color extension\n"));
                }
                break;

            case 8:  
            case 9:
            case 10: 
            case 11:
            case 12: 
            case 13:
            case 14: 
            case 15:
            {
                OSGGETGLFUNCBYID( OSGglClientActiveTextureARB,
                                  osgGlClientActiveTextureARB,
                                 _funcglClientActiveTextureARB,
                                  win);

                osgGlClientActiveTextureARB(GL_TEXTURE0_ARB + slot - 8);

                glTexCoordPointer(getDimension(), 
                                  getFormat   (),
                                  getStride   (),
                                  pData         );

                glEnableClientState(GL_TEXTURE_COORD_ARRAY);
            }
            break;

            default:    FWARNING(("GeoVectorProperty::activate: Non-Generic"
                                  " attribute nr. %d unknown!\n", slot));
                break;

        }
        if(hasVBO == true) // Do we have a VBO?
        {
            osgGlBindBufferARB(GL_ARRAY_BUFFER_ARB, 0);
        }
    }
#endif
}
void GeoVectorProperty::activate(DrawEnv *pEnv, UInt32 slot)
{
    Window *pWin = pEnv->getWindow();

    bool isGeneric = (slot >= 16);  // !!!HACK. needs to be replaced for 2.0
    slot &= 15;

    bool hasVBO = pWin->hasExtOrVersion(_extVertexBufferObject, 0x0105, 0x0200);

    osgSinkUnusedWarning(pWin);

    if(hasVBO && isGeneric == true)
    {
        OSGGETGLFUNCBYID_GL3_ES( glVertexAttribPointer, 
                                 osgGlVertexAttribPointer,
                                _funcVertexAttribPointerARB,
                                 pWin);

        if(getGLId() != 0 && getUseVBO()) // Do we have a VBO?
        {
            pWin->validateGLObject(getGLId(), pEnv);
            
            OSGGETGLFUNCBYID_GL3_ES(  glBindBuffer, 
                                      osgGlBindBuffer,
                                     _funcBindBuffer, 
                                      pWin);
            
            osgGlBindBuffer(GL_ARRAY_BUFFER_ARB,
                            pWin->getGLObjectId(getGLId()));
            
            osgGlVertexAttribPointer(slot, 
                                     getDimension(),
                                     getFormat   (),
                                     getNormalize(),
                                     getStride   (), 
                                     0);
            
            osgGlBindBuffer(GL_ARRAY_BUFFER_ARB, 0);
        }
        else
        {
            osgGlVertexAttribPointer(slot, 
                                     getDimension(),
                                     getFormat   (), 
                                     getNormalize(),
                                     getStride   (), 
                                     getData     ());
        }
        
        OSGGETGLFUNCBYID_GL3_ES( glEnableVertexAttribArray,
                                 osgGlEnableVertexAttribArray,
                                _funcEnableVertexAttribArrayARB,
                                 pWin);
        
        osgGlEnableVertexAttribArray(slot);
  
        OSGGETGLFUNCBYID_GL3_ES( glVertexAttribDivisor,
                                 osgGlVertexAttribDivisor,
                                _funcVertexAttribDivisorARB,
                                 pWin);
 
        osgGlVertexAttribDivisor(slot, _sfDivisor.getValue());
    }
    else 
    {        
#if !defined(OSG_OGL_COREONLY) || defined(OSG_CHECK_COREONLY)
        const void *pData = NULL;

        OSGGETGLFUNCBYID_GL3_ES( glBindBuffer, 
                                 osgGlBindBuffer,
                                _funcBindBuffer, 
                                 pWin);

        hasVBO &= getUseVBO() && (getGLId() != 0);

        if(hasVBO == true) // Do we have a VBO?
        {
            pWin->validateGLObject(getGLId(), pEnv);                

            osgGlBindBuffer(GL_ARRAY_BUFFER_ARB,
                            pWin->getGLObjectId(getGLId()));
        }
        else
        {
            pData = getData();
        }
        
        switch(slot)
        {
            case 0:     
                glVertexPointer(getDimension(), 
                                getFormat   (),
                                getStride   (),
                                pData         );

                glEnableClientState(GL_VERTEX_ARRAY);
                break;

            case 2:     
                glNormalPointer(getFormat(),
                                getStride(),
                                pData      );

                glEnableClientState(GL_NORMAL_ARRAY);
                break;

            case 3:   
                glColorPointer(getDimension(), 
                               getFormat   (),
                               getStride   (), 
                               pData         );

                glEnableClientState(GL_COLOR_ARRAY);
                break;

            case 4:   
                if(pWin->hasExtOrVersion(_extSecondaryColor, 0x0104))
                {
                    OSGGETGLFUNCBYID_GL3( glSecondaryColorPointer,
                                          osgGlSecondaryColorPointer,
                                         _funcSecondaryColorPointer,
                                          pWin);

                    osgGlSecondaryColorPointer(getDimension(),
                                               getFormat   (),
                                               getStride   (), 
                                               pData         );

                    glEnableClientState(GL_SECONDARY_COLOR_ARRAY_EXT);
                }
                else
                {
                    FWARNING(("GeoVectorProperty::activate: Window "
                              "has no Secondary Color extension\n"));
                }
                break;

            case 8:  
            case 9:
            case 10: 
            case 11:
            case 12: 
            case 13:
            case 14: 
            case 15:
            {
                if(pWin->hasExtOrVersion(_extMultitexture, 0x0103, 0x0200))
                {
                    OSGGETGLFUNCBYID_GL3_ES( glClientActiveTexture,
                                             osgGlClientActiveTexture,
                                            _funcClientActiveTextureARB,
                                             pWin);

                    osgGlClientActiveTexture(GL_TEXTURE0_ARB + slot - 8);

                    glTexCoordPointer(getDimension(),
                                      getFormat   (),
                                      getStride   (),
                                      pData         );

                    glEnableClientState(GL_TEXTURE_COORD_ARRAY);
                }
                else if(slot == 8)
                {
                    glTexCoordPointer(getDimension(),
                                      getFormat   (),
                                      getStride   (),
                                      pData         );

                    glEnableClientState(GL_TEXTURE_COORD_ARRAY);
                }
                else
                {
                    SWARNING << "GeoVectorProperty::activate: Window "
                             << "has no Multi Texture extension" << std::endl;
                }
            }
            break;

            default:    FWARNING(("GeoVectorProperty::activate: Non-Generic"
                                  " attribute nr. %d unknown!\n", slot));
                break;

        }
        if(hasVBO == true) // Do we have a VBO?
        {
            osgGlBindBuffer(GL_ARRAY_BUFFER_ARB, 0);
        }
#endif
    }
}