UInt32 RenderBuffer::handleGL(DrawEnv                 *pEnv, 
                              UInt32                   osgid, 
                              Window::GLObjectStatusE  mode,
                              UInt32                        )
{
    Window *pWindow = pEnv->getWindow();
    
    if(mode == Window::initialize || mode == Window::reinitialize ||
       mode == Window::needrefresh )
    {
        GLuint uiBufferId = 0;

        if(mode == Window::initialize)
        {
            OSGGETGLFUNCBYID_GL3_ES( glGenRenderbuffers,
                                     osgGlGenRenderbuffers,
                                    _uiFuncGenRenderbuffers,
                                     pWindow);

            osgGlGenRenderbuffers(1, &uiBufferId);

            pWindow->setGLObjectId(osgid, uiBufferId);
        }
        else
        {
            uiBufferId = pWindow->getGLObjectId(osgid);
        }

        OSGGETGLFUNCBYID_GL3_ES( glBindRenderbuffer,
                                 osgGlBindRenderbuffer,
                                _uiFuncBindRenderbuffer, 
                                 pWindow);

        OSGGETGLFUNCBYID_GL3_ES( glRenderbufferStorage,
                                 osgGlRenderbufferStorage,
                                _uiFuncRenderbufferStorage,
                                 pWindow);

        osgGlBindRenderbuffer(GL_RENDERBUFFER_EXT, uiBufferId);

        GLenum internalFormat = getInternalFormat();

        if(internalFormat == GL_NONE && getImage() != NULL)
        {
            internalFormat = getImage()->getPixelFormat();
        }

        osgGlRenderbufferStorage(GL_RENDERBUFFER_EXT,
                                 internalFormat,
                                 getWidth(), 
                                 getHeight());
    }

    return 0;
}
void BlendChunk::deactivate(DrawEnv *pEnv, UInt32 )
{
    GLenum src    = _sfSrcFactor.getValue();
    GLenum dest   = _sfDestFactor.getValue();
    GLenum asrc   = _sfAlphaSrcFactor.getValue();
    GLenum adest  = _sfAlphaDestFactor.getValue();

    Window *pWin = pEnv->getWindow();

    if((src   != GL_ONE        || dest  != GL_ZERO) ||
       (asrc  != OSG_GL_UNUSED && asrc  != GL_ONE ) || 
       (adest != OSG_GL_UNUSED && adest != GL_ZERO)   )
    {
        glDisable(GL_BLEND);
    }

    if(_sfEquation.getValue() != GL_NONE)
    {
        if(pWin->hasExtOrVersion(_extImaging, 0x0104, 0x0200))
        {
            // get "glBlendEquation" function pointer
            OSGGETGLFUNCBYID_GL3_ES( glBlendEquation, 
                                     osgGlBlendEquation,
                                    _funcBlendEquation,
                                     pWin);

            osgGlBlendEquation(GL_FUNC_ADD);
        }
        else if(pWin->hasExtOrVersion(_extBlendSubtract, 0x0102, 0x0200) ||
                pWin->hasExtOrVersion(_extBlendMinMax,   0x0102, 0x0200) ||
                pWin->hasExtOrVersion(_extBlendLogicOp,  0x0101, 0x0200)  )
        {
            // get "glBlendEquationEXT" function pointer
            OSGGETGLFUNCBYID_GL3_ES( glBlendEquation, 
                                     osgGlBlendEquation,
                                    _funcBlendEquationExt,
                                     pWin);

            osgGlBlendEquation(GL_FUNC_ADD_EXT);
        }
    }
    
#if !defined(OSG_OGL_COREONLY) || defined(OSG_CHECK_COREONLY)
    if(_sfAlphaFunc.getValue() != GL_NONE)
    {
        glDisable(GL_ALPHA_TEST);
    }
#endif
}
/*! GL object handler
    destroy it
*/
void GeoMultiPropertyData::handleDestroyGL(DrawEnv                 *pEnv, 
                               UInt32                   id, 
                               Window::GLObjectStatusE  mode)
{
    Window *pWin = pEnv->getWindow();

    osgSinkUnusedWarning(pWin);

    if(mode == Window::destroy)
    {   
        OSGGETGLFUNCBYID_GL3_ES( glDeleteBuffers, 
                                 osgGlDeleteBuffers,
                                _funcDeleteBuffers,    
                                 pWin              );

        GLuint buf = id;
        osgGlDeleteBuffers(1, &buf);

        pWin->setGLObjectId(id, 0);
    }
    else if(mode == Window::finaldestroy)
    {
        //SWARNING << "Last texture user destroyed" << std::endl;
    }
    else
    {
        SWARNING << "GeoMultiPropertyData::handleDestroyGL: Illegal mode: "
                 << mode << " for id " << id << std::endl;
    }

}
void ComputeShaderChunk::activate(DrawEnv    *pEnv,              
                                  UInt32      uiIdx)
{
    Window *pWin    = pEnv->getWindow();

    UInt32 uiValRes = pWin->validateGLObject(getGLId(), 
                                             pEnv, 
                                             KeepProgActive);    

    GLuint uiProgId = GLuint(pWin->getGLObjectId(getGLId()));

    if(uiProgId == 0)
        return;

    pEnv->setActiveShader(uiProgId);

    if(0x0000 == (uiValRes & ProgActive))
    {
        OSGGETGLFUNCBYID_GL3_ES(glUseProgram,
                                osgGlUseProgram,
                                ShaderProgram::getFuncIdUseProgram(),
                                pWin);

        osgGlUseProgram(uiProgId);
    }

    pEnv->incNumShaderChanges();
        
    updateProceduralVariables(pEnv, ShaderProcVariable::SHDAll);

}
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 ShaderStorageBufferObjRefChunk::deactivate(DrawEnv *pEnv, UInt32 idx)
{
    Window *pWin = pEnv->getWindow();

    OSGGETGLFUNCBYID_GL3_ES( glBindBuffer,
                             osgGlBindBuffer,
                            _funcBindBuffer, 
                             pWin);

    OSGGETGLFUNCBYID_GL3_ES( glBindBufferBase, 
                             osgGlBindBufferBase,
                            _funcBindBufferBase, 
                             pWin);

    osgGlBindBufferBase(GL_SHADER_STORAGE_BUFFER, idx, 0);
    osgGlBindBuffer    (GL_SHADER_STORAGE_BUFFER, 0);

    glErr("ShaderStorageBufferObjRefChunk::deactivate");
}
void ComputeShaderChunk::changeFrom(DrawEnv    *pEnv, 
                                    StateChunk *pOther, 
                                    UInt32      uiIdx)
{
    ComputeShaderChunk *pOld = dynamic_cast<ComputeShaderChunk *>(pOther);

    // pOther can be a ShaderExecutableChunk, since we share the StateClass id
    // with it
    if(pOld != NULL)
    {
        Window   *pWin     = pEnv->getWindow();
        GLuint    uiProgId = GLuint(pWin->getGLObjectId(getGLId()));

        UInt32 uiDep = ShaderProcVariable::SHDObject;

        if(uiProgId != pEnv->getActiveShader())
        {
            UInt32 uiValRes = pWin->validateGLObject(getGLId(),
                                                     pEnv,
                                                     KeepProgActive);

            uiProgId = GLuint(pWin->getGLObjectId(getGLId()));

            if(uiProgId == 0)
                return;

            pEnv->setActiveShader(uiProgId);

            if(0x0000 == (uiValRes & ProgActive))
            {
                OSGGETGLFUNCBYID_GL3_ES(glUseProgram,
                                        osgGlUseProgram,
                                        ShaderProgram::getFuncIdUseProgram(),
                                        pWin);

                osgGlUseProgram(uiProgId);
            }

            uiDep = ShaderProcVariable::SHDAll;

            pEnv->incNumShaderChanges();
        }

        updateProceduralVariables(pEnv, uiDep);
    }
    else
    {
        pOther->deactivate(pEnv, uiIdx);
        activate          (pEnv, uiIdx);

        pEnv->incNumShaderChanges();
    }
}
void ShaderStorageBufferObjRefChunk::activate(DrawEnv *pEnv, UInt32 idx)
{
    Window *pWin = pEnv->getWindow();

    validate(pEnv);
    GLuint id = this->getOpenGLId(pEnv);

    OSGGETGLFUNCBYID_GL3_ES( glBindBuffer,
                             osgGlBindBuffer,
                            _funcBindBuffer, 
                             pWin);

    OSGGETGLFUNCBYID_GL3_ES( glBindBufferBase, 
                             osgGlBindBufferBase,
                            _funcBindBufferBase, 
                             pWin);

    osgGlBindBuffer    (GL_SHADER_STORAGE_BUFFER, id);
    osgGlBindBufferBase(GL_SHADER_STORAGE_BUFFER, idx, id);

    glErr("ShaderStorageBufferObjRefChunk::activate");
}
UInt32 GeoMultiPropertyData::handleGL(DrawEnv                 *pEnv, 
                                      UInt32                   id, 
                                      Window::GLObjectStatusE  mode,
                                      UInt32                   uiOptions)
{
    Window *pWin = pEnv->getWindow();

    osgSinkUnusedWarning(pWin);

    if(mode == Window::initialize || mode == Window::reinitialize ||
       mode == Window::needrefresh )
    {
        OSGGETGLFUNCBYID_GL3_ES( glBindBuffer, 
                                 osgGlBindBuffer,
                                _funcBindBuffer,    
                                 pWin              );
        OSGGETGLFUNCBYID_GL3_ES( glBufferData,
                                 osgGlBufferData,
                                _funcBufferData,    
                                 pWin              );

        osgGlBindBuffer(GL_ARRAY_BUFFER_ARB, id);

        osgGlBufferData(  GL_ARRAY_BUFFER_ARB,
                         _mfIData.size(),
                        &_mfIData[0],
                             GL_STATIC_DRAW_ARB);

        osgGlBindBuffer(GL_ARRAY_BUFFER_ARB, 0);
    }
    else
    {
        SWARNING << "GeoMultiPropertyData(" << this 
                 << "::handleGL: Illegal mode: "
                 << mode << " for id " << id << std::endl;
    }

    return 0;
}
void RenderBuffer::bind(DrawEnv *pEnv, UInt32 index)
{
    Window *pWindow = pEnv->getWindow();

    pWindow->validateGLObject(getGLId(), pEnv);

    OSGGETGLFUNCBYID_GL3_ES( glFramebufferRenderbuffer,
                             osgGlFramebufferRenderbuffer,
                            _uiFuncFramebufferRenderbuffer,
                             pWindow);

    osgGlFramebufferRenderbuffer(GL_FRAMEBUFFER_EXT,
                                 index,
                                 GL_RENDERBUFFER_EXT, 
                                 pWindow->getGLObjectId(getGLId()));
}
void PassiveBackground::clear(DrawEnv *pEnv)
{
    if(_sfClearFrameBufferObject.getValue() == true &&
        pEnv->getActiveFBO()                != 0     )
    {
        if(_sfClearCallback.getValue()._func)
        {
            _sfClearCallback.getValue()._func(pEnv);
        }
        else
        {
            Window *win = pEnv->getWindow();

            OSGGETGLFUNCBYID_GL3_ES( glBindFramebuffer,
                                     osgGlBindFramebuffer,
                                    _uiFuncBindFramebuffer,
                                     win                  );

            OSGGETGLFUNCBYID_GL3( glBlitFramebuffer,
                                  osgGlBlitFramebuffer,
                                 _uiFuncBlitFramebuffer,
                                  win                  );

            osgGlBindFramebuffer(GL_READ_FRAMEBUFFER_EXT, 
                                 0);

            // FixMe breaks if source size != target size
            osgGlBlitFramebuffer(pEnv->getPixelLeft  (), 
                                 pEnv->getPixelBottom(), 
                                 pEnv->getPixelRight (), 
                                 pEnv->getPixelTop   (),
                             
                                 pEnv->getPixelLeft  (), 
                                 pEnv->getPixelBottom(), 
                                 pEnv->getPixelRight (), 
                                 pEnv->getPixelTop   (),
                                 
                                 (GL_COLOR_BUFFER_BIT  |
                                  GL_DEPTH_BUFFER_BIT  |
                                  GL_STENCIL_BUFFER_BIT),
                                 GL_NEAREST); 
        }
    }
}
void ComputeShaderChunk::handleDestroyGL(DrawEnv                 *pEnv, 
                                         UInt32                   id, 
                                         Window::GLObjectStatusE  mode)
{
    Window *pWin = pEnv->getWindow();

    if(!pWin->hasExtOrVersion(_arbComputeShader, 0x0403, 0xFFFF))
    {
        FWARNING(("OpenGL Shading Language is not supported, couldn't find "
                  "extension 'GL_ARB_shading_language_100'!\n"));

        pWin->setGLObjectId(id, 0);

        return;
    }

    // BUG this is not called for every window!
    if(mode == Window::destroy)
    {
        GLuint uiProgram = GLuint(pWin->getGLObjectId(id));

        if(uiProgram != 0)
        {
            OSGGETGLFUNCBYID_GL3_ES(glDeleteProgram,
                                    osgGlDeleteProgram,
                                    ShaderProgram::getFuncIdDeleteProgram(),
                                    pWin);

            osgGlDeleteProgram(uiProgram);

            pWin->setGLObjectId(id, 0);
        }
    }
    else if(mode == Window::finaldestroy)
    {
        ;//SWARNING << "Last program user destroyed" << std::endl;
    }
}
void ShaderProgram::handleDestroyGL(DrawEnv                 *pEnv, 
                                    UInt32                   id, 
                                    Window::GLObjectStatusE  mode)
{
    Window *pWin = pEnv->getWindow();

    if(!pWin->hasExtOrVersion(_extSHL, 0x0200, 0x0200))
    {
        FWARNING(("OpenGL Shading Language is not supported, couldn't find "
                  "extension 'GL_ARB_shading_language_100'!\n"));

        pWin->setGLObjectId(id, 0);

        return;
    }

    if(mode == Window::destroy)
    {
        GLuint uiShader = GLuint(pWin->getGLObjectId(id));

        if(uiShader != 0)
        {
            OSGGETGLFUNCBYID_GL3_ES(glDeleteShader,
                                    osgGlDeleteShader,
                                    FuncIdDeleteShader,
                                    pWin);
            
            osgGlDeleteShader(uiShader);

            pWin->setGLObjectId(id, 0);
        }
    }
    else if(mode == Window::finaldestroy)
    {
        ;//SWARNING << "Last program user destroyed" << std::endl;
    }
}
void RenderBuffer::handleDestroyGL(DrawEnv                 *pEnv, 
                                   UInt32                   osgid, 
                                   Window::GLObjectStatusE  mode)
{
    Window *pWindow = pEnv->getWindow();
    
    if(mode == Window::destroy)
    {
        GLuint uiBufferId =  pWindow->getGLObjectId(osgid);

        OSGGETGLFUNCBYID_GL3_ES( glDeleteRenderbuffers,
                                 osgGlDeleteRenderbuffers,
                                _uiFuncDeleteRenderbuffers,
                                 pWindow);

        osgGlDeleteRenderbuffers(1, &uiBufferId);

        pWindow->setGLObjectId(osgid, 0);
    }
    else if(mode == Window::finaldestroy)
    {
        //SWARNING << "Last texture user destroyed" << std::endl;
    }
}
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
    }
}
void GeoMultiProperty::activate(DrawEnv *pEnv, 
                                UInt32   slot )
{
    Window *win = pEnv->getWindow();
    bool isGeneric = (slot >= 16);  // !!!HACK. needs to be replaced for 2.0
    slot &= 15;
    
    if(!win->hasExtOrVersion(_extVertexBufferObject, 0x0105, 0x0200))
    {
        FWARNING(("GeoMultiProperty::activate: Window %p doesn't "
                  "support VBOs!\n", win));
                  return;
    }
    
    win->validateGLObject(getContainer()->getGLId(), pEnv);

     // get "glBindBufferARB" function pointer

    OSGGETGLFUNCBYID_GL3_ES( glBindBuffer, 
                             osgGlBindBuffer,
                            _funcBindBuffer, 
                             win);
   
    osgGlBindBuffer(GL_ARRAY_BUFFER_ARB, 
                    win->getGLObjectId(getContainer()->getGLId()));

#define BUFFER_OFFSET(i)     (static_cast<char *>(NULL) + (i))

    if(isGeneric)
    {
        OSGGETGLFUNCBYID_GL3_ES( glVertexAttribPointer, 
                                 osgGlVertexAttribPointer,
                                _funcglVertexAttribPointerARB,
                                 win);

        osgGlVertexAttribPointer(slot, 
                                 getDimension(), 
                                 getFormat(), 
                                 getNormalize(),
                                 getStride(), 
                                 BUFFER_OFFSET(getOffset()));

        OSGGETGLFUNCBYID_GL3_ES( glEnableVertexAttribArray,
                                 osgGlEnableVertexAttribArray,
                                _funcglEnableVertexAttribArrayARB,
                                 win);
 
        osgGlEnableVertexAttribArray(slot);
    }
    else
    {
#if !defined(OSG_OGL_COREONLY) || defined(OSG_CHECK_COREONLY)
        switch(slot)
        {
            case 0:     
                glVertexPointer(getDimension(), getFormat(),
                                getStride(), BUFFER_OFFSET(getOffset()));
                glEnableClientState(GL_VERTEX_ARRAY);
                break;
            case 2:     
                glNormalPointer(getFormat(),
                                getStride(), BUFFER_OFFSET(getOffset()));
                glEnableClientState(GL_NORMAL_ARRAY);
                break;
            case 3:     
                glColorPointer(getDimension(), getFormat(),
                               getStride(), BUFFER_OFFSET(getOffset()));
                glEnableClientState(GL_COLOR_ARRAY);
                break;
            case 4:     
                if (win->hasExtOrVersion(_extSecondaryColor, 0x0104))
                {
                    OSGGETGLFUNCBYID_EXT( glSecondaryColorPointer,
                                          osgGlSecondaryColorPointer,
                                         _funcglSecondaryColorPointer,
                                          win);

                    osgGlSecondaryColorPointer(getDimension(),
                                               getFormat(),
                                               getStride(), 
                                               BUFFER_OFFSET(getOffset()));

                    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_GL3_ES( glClientActiveTexture,
                                         osgGlClientActiveTexture,
                                        _funcglClientActiveTextureARB,
                                         win);

                osgGlClientActiveTexture(GL_TEXTURE0_ARB + slot - 8);

                glTexCoordPointer(getDimension(), 
                                  getFormat(),
                                  getStride(), 
                                  BUFFER_OFFSET(getOffset()));

                glEnableClientState(GL_TEXTURE_COORD_ARRAY);
            }
            break;
            default:    FWARNING(("GeoVectorProperty::activate: Non-Generic"
                                  " attribute nr. %d unknown!\n", slot));
                break;
        }     
#endif
    } // isGeneric

    osgGlBindBuffer(GL_ARRAY_BUFFER_ARB, 0);
}
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;
                }
            }
        }
    }
}
void GeoSplitVertexArrayPumpGroup::masterAttribGeoJustDrawPump(
    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::masterAttribGeoJustDrawPump\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;

    attribPumpFunc attribFunc[Geometry::MaxAttribs];
    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;

        UInt16 formatIdx = pumpData.attribPtr[i]->getFormat   () - formatBase;
        UInt16 dimIdx    = pumpData.attribPtr[i]->getDimension() - 1;

#if !defined(OSG_USE_OGLES_PROTOS) && !defined(OSG_USE_OGL3_PROTOS) && \
    !defined(OSG_USE_OGL4_PROTOS)
        UInt32 funcId    = Window::invalidFunctionID;

        if(pumpData.attribPtr[i]->getNormalize() == true)
        {
            funcId = normAttribPumpFuncIDs[formatIdx][dimIdx];

            if(funcId == Window::invalidFunctionID)
            {
                SWARNING << "GeoVertexArrayPumpGroup::masterAttribGeoPump: "
                         << "Invalid pump function for property " << i
                         << " type " << pumpData.attribPtr[i]->getDimension()
                         << "D " << formatNames[formatIdx] << " (normalizing)."
                         << endLog;

                pumpData.attribData[i] = NULL;
                pumpData.attribPtr [i] = NULL;
                continue;
            }
        }
        else
        {
            funcId = attribPumpFuncIDs[formatIdx][dimIdx];

            if(funcId == Window::invalidFunctionID)
            {
                SWARNING << "GeoVertexArrayPumpGroup::masterAttribGeoPump: "
                         << "Invalid pump function for property " << i
                         << " type " << pumpData.attribPtr[i]->getDimension()
                         << "D " << formatNames[formatIdx]
                         << endLog;

                pumpData.attribData[i] = NULL;
                pumpData.attribPtr [i] = NULL;
                continue;
            }
        }

        attribFunc[i] = reinterpret_cast<attribPumpFunc>(
            win->getFunction(funcId));

#else
        if(pumpData.attribPtr[i]->getNormalize() == true)
        {
            attribFunc[i] = attribNormPumpFuncs[formatIdx][dimIdx];
        }
        else
        {
            attribFunc[i] = attribPumpFuncs[formatIdx][dimIdx];
        }
#endif

        if(attribFunc[i] == NULL)
        {
            SWARNING << "GeoVertexArrayPumpGroup::masterAttribGeoPump: "
                     << "Extension function for property " << i
                     << " type " << pumpData.attribPtr[i]->getDimension()
                     << "D " << formatNames[formatIdx]
                     << " not supported by Window " << win
                     << endLog;

            pumpData.attribData[i] = NULL;
            pumpData.attribPtr [i] = NULL;
            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?
    for(Int16 i = 0; i < nattrib; ++i)
    {
        if(pumpData.attribData[i]         != NULL &&
           pumpData.attribPtr [i]->size() == 1      )
        {
            attribFunc[i](i, pumpData.attribData[i]);
            pumpData.attribData[i] = NULL;
        }
    }

    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;
                }
            }
        }
    }
}
void ComputeShaderChunk::updateProceduralVariables(
    DrawEnv *pEnv,
    UInt32   uiUpdateDependents)
{
    UInt32 uiProgram = pEnv->getActiveShader();

    if(uiProgram == 0)
        return;

    const ShaderProgramVariables::MFProceduralVariablesType *pMFVars = NULL;

    if(_sfVariables.getValue() != NULL)
    {
        pMFVars   = _sfVariables.getValue()->getMFProceduralVariables();
    }

    if(pMFVars == NULL || pMFVars->size() == 0)
    {
        return;
    }

    MFInt32 &vVarLocations = *this->editMFProceduralVariableLocations();

    OSG_ASSERT(pMFVars->size() == vVarLocations.size());

    MFInt32::iterator mLocIt = vVarLocations.begin();

    ShaderProgramVariables::MFProceduralVariablesType::const_iterator mVarIt  =
        pMFVars->begin();
    ShaderProgramVariables::MFProceduralVariablesType::const_iterator mVarEnd =
        pMFVars->end  ();

    Window *pWin = pEnv->getWindow();

    osgSinkUnusedWarning(pWin);

    for(; mVarIt != mVarEnd; ++mVarIt, ++mLocIt)
    {
        ShaderVariable *pVar = *mVarIt;

        switch(pVar->getTypeId())
        {
            case ShaderVariable::SHVTypeOSG:
            {
                ShaderVariableOSG *p =
                    dynamic_cast<ShaderVariableOSG *>(pVar);

                if(0x0000 == (p->getDependency() & uiUpdateDependents))
                    continue;

                if(*mLocIt == -1)
                {
                    OSGGETGLFUNCBYID_GL3_ES(
                        glGetUniformLocation,
                        osgGlGetUniformLocation,
                        ShaderProgram::getFuncIdGetUniformLocation(),
                        pWin);

                    *mLocIt = osgGlGetUniformLocation(uiProgram,
                                                      p->getName().c_str());
                }

                p->evaluate(pEnv, *mLocIt);                
            }
            break;

            case ShaderVariable::SHVTypeFunctor:
            {
                ShaderVariableFunctor *p =
                    dynamic_cast<ShaderVariableFunctor *>(pVar);

                if(0x0000 == (p->getDependency() & uiUpdateDependents))
                    continue;

                if(*mLocIt == -1)
                {
                    OSGGETGLFUNCBYID_GL3_ES(
                        glGetUniformLocation,
                        osgGlGetUniformLocation,
                        ShaderProgram::getFuncIdGetUniformLocation(),
                        pWin);

                    *mLocIt = osgGlGetUniformLocation(uiProgram,
                                                      p->getName().c_str());
                }

                p->evaluate(pEnv, *mLocIt);                
            }
            break;

            default:
                break;
        }
    }
}
UInt32 ComputeShaderChunk::handleGL(DrawEnv                 *pEnv, 
                                    UInt32                   id, 
                                    Window::GLObjectStatusE  mode,
                                    UInt64                   uiOptions)
{
    UInt32  returnValue = 0;
    Window *pWin        = pEnv->getWindow();

    if(!pWin->hasExtOrVersion(_arbComputeShader, 0x0403, 0xFFFF))
    {
        FWARNING(("OpenGL compute shader is not supported, couldn't find "
                  "extension 'GL_ARB_compute_shader'!\n"));

        pWin->setGLObjectId(getGLId(), 0);

        return returnValue;
    }

    if(mode == Window::initialize   || 
       mode == Window::reinitialize ||
       mode == Window::needrefresh   )
    {
        GLuint uiProgram = GLuint(pWin->getGLObjectId(getGLId()));;

        if(mode != Window::needrefresh)
        {
            if(uiProgram != 0)
            {
                OSGGETGLFUNCBYID_GL3_ES(glDeleteProgram,
                                        osgGlDeleteProgram,
                                        ShaderProgram::getFuncIdDeleteProgram(),
                                        pWin);

                osgGlDeleteProgram(uiProgram);
            }

            OSGGETGLFUNCBYID_GL3_ES(glCreateProgram,
                                    osgGlCreateProgram,
                                    ShaderProgram::getFuncIdCreateProgram(),
                                    pWin);

            OSGGETGLFUNCBYID_GL3_ES(glAttachShader,
                                    osgGlAttachShader,
                                    ShaderProgram::getFuncIdAttachShader(),
                                    pWin);

            OSGGETGLFUNCBYID_GL3_ES(glLinkProgram,
                                    osgGlLinkProgram,
                                    ShaderProgram::getFuncIdLinkProgram(),
                                    pWin);

            uiProgram = osgGlCreateProgram();
        
            ComputeShaderIt vIt  = _mfComputeShader.begin();
            ComputeShaderIt vEnd = _mfComputeShader.end  ();
            
            for(; vIt != vEnd; ++vIt)
            {
                (*vIt)->validate(pEnv);

                GLuint uiShader = 
                    GLuint(pWin->getGLObjectId((*vIt)->getGLId()));

                if(uiShader != 0)
                    osgGlAttachShader(uiProgram, uiShader);
            }

            osgGlLinkProgram(uiProgram);

            GLint  iInfoLength;
            Char8 *szInfoBuffer = NULL;

            OSGGETGLFUNCBYID_GL3_ES(glGetProgramiv,
                                    osgGlGetProgramiv,
                                    ShaderProgram::getFuncIdGetProgramiv(),
                                    pWin);

            osgGlGetProgramiv(uiProgram, 
                              GL_OBJECT_INFO_LOG_LENGTH_ARB, 
                              &iInfoLength);

            if(iInfoLength > 0)
            {
                szInfoBuffer = new Char8[iInfoLength];
                szInfoBuffer[0] = '\0';

                OSGGETGLFUNCBYID_GL3_ES(
                    glGetProgramInfoLog,
                    osgGlGetProgramInfoLog,
                    ShaderProgram::getFuncIdGetProgramInfoLog(),
                    pWin);

                osgGlGetProgramInfoLog( uiProgram, 
                                        iInfoLength, 
                                       &iInfoLength, 
                                        szInfoBuffer);
            }

            GLint iStatus = 0;

            osgGlGetProgramiv(uiProgram, GL_LINK_STATUS, &iStatus);

            if(iStatus == 0)
            {
                if(szInfoBuffer != NULL && szInfoBuffer[0] != '\0')
                {
                    FFATAL(("Couldn't link compute program!\n%s\n",
                            szInfoBuffer));
                }
                else
                {
                    FFATAL(("Couldn't link compute program!\n"
                            "No further info available\n"));
                }

                OSGGETGLFUNCBYID_GL3_ES(glDeleteProgram,
                                        osgGlDeleteProgram,
                                        ShaderProgram::getFuncIdDeleteProgram(),
                                        pWin);

                osgGlDeleteProgram(uiProgram);

                uiProgram = 0;
            }
            else
            {
                if(szInfoBuffer != NULL && szInfoBuffer[0] != '\0')
                {
                    FWARNING(("ComputeShaderChunk: link status: %s\n", 
                              szInfoBuffer));
                }
            }

            pWin->setGLObjectId(getGLId(), uiProgram);

            updateVariableLocations(pEnv, uiProgram);
        }

        if(uiProgram != 0)
        {
            OSGGETGLFUNCBYID_GL3_ES(glUseProgram,
                                    osgGlUseProgram,
                                    ShaderProgram::getFuncIdUseProgram(),
                                    pWin);
        
            osgGlUseProgram(uiProgram);
        
            updateVariables(pEnv, uiProgram);
        
            if(0x0000 == (uiOptions & KeepProgActive))
            {
                osgGlUseProgram(0);
            }
            else
            {
                returnValue |= ProgActive;
            }
        }
    }

    return returnValue;
}
void GeoVectorProperty::deactivate(DrawEnv *pEnv, UInt32 slot)
{
    Window *pWin   = pEnv->getWindow();

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

    slot &= 15;

    osgSinkUnusedWarning(pWin);

    if(pWin->hasExtOrVersion(_extVertexBufferObject, 
                             0x0105, 
                             0x0200                ) && isGeneric)
    {
        OSGGETGLFUNCBYID_GL3_ES( glDisableVertexAttribArray,
                                 osgGlDisableVertexAttribArray,
                                _funcDisableVertexAttribArrayARB,
                                 pWin);

        osgGlDisableVertexAttribArray(slot);
    }
    else
    {
#if !defined(OSG_OGL_COREONLY) || defined(OSG_CHECK_COREONLY)
        switch(slot)
        {
            case 0:
                glDisableClientState(GL_VERTEX_ARRAY);
                break;

            case 2: 
                glDisableClientState(GL_NORMAL_ARRAY);
                break;

            case 3: 
                glDisableClientState(GL_COLOR_ARRAY);
                break;

            case 4: 
                glDisableClientState(GL_SECONDARY_COLOR_ARRAY_EXT);
                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);

                    glDisableClientState(GL_TEXTURE_COORD_ARRAY);
                }
                else if(slot == 8)
                {
                    glDisableClientState(GL_TEXTURE_COORD_ARRAY);
                }
                else
                {
                    SWARNING << "GeoVectorProperty::deactivate: Window "
                             << "has no Multi Texture extension" << std::endl;
                }
            }
            break;

            default:    
                FWARNING(("GeoVectorProperty::deactivate: Non-Generic"
                          " attribute nr. %d unknown!\n", slot));
                break;
        }
#endif
    }
}
UInt32 ShaderProgram::handleGL(DrawEnv                 *pEnv, 
                               UInt32                   id, 
                               Window::GLObjectStatusE  mode,
                               UInt32                   uiOptions)
{
    Window *pWin = pEnv->getWindow();

    if(pWin->hasExtOrVersion(_extSHL, 0x0200, 0x0200) == false)
    {
        FWARNING(("OpenGL Shading Language is not supported, couldn't find "
                  "extension 'GL_ARB_shading_language_100'!\n"));

        pWin->setGLObjectId(id, 0);

        return 0;
    }

    if(mode == Window::initialize   || 
       mode == Window::reinitialize ||
       mode == Window::needrefresh   )
    {
        if( mode                         != Window::needrefresh && 
           _sfProgram.getValue().empty() == false                )
        {
            GLuint uiShader = GLuint(pWin->getGLObjectId(getGLId()));

#ifdef OSG_DEBUG
            if(mode == Window::initialize && uiShader != 0)
            {
                FWARNING(("ShaderProgram::handleGL: "
                          "Initialize with non-zero GL object Id.\n"));

                uiShader = 0;
            }
#endif

//            if(uiShader == 0)
            if(mode == Window::initialize)
            {      
                OSGGETGLFUNCBYID_GL3_ES(glCreateShader,
                                        osgGlCreateShader,
                                        FuncIdCreateShader,
                                        pWin);

                GLenum shaderType = _sfShaderType.getValue();

                if(_sfCgFrontEnd.getValue() == true)
                {
                    if(pWin->hasExtension(_extCG))
                    {
                        switch(shaderType)
                        {
                            case GL_VERTEX_SHADER:
                                shaderType = GL_CG_VERTEX_SHADER_EXT;
                                break;
                            case GL_FRAGMENT_SHADER:
                                shaderType = GL_CG_FRAGMENT_SHADER_EXT;
                                break;
                        }
                    }
                    else
                    {
                        FWARNING(("EXT_Cg_shader extension not supported, "
                                  "using GLSL front end!\n"));
                    }
                }

                uiShader = osgGlCreateShader(shaderType);
            }

            const Char8 *source = _sfProgram.getValue().c_str();

            OSGGETGLFUNCBYID_GL3_ES(glShaderSource,
                                    osgGlShaderSource,
                                    FuncIdShaderSource,
                                    pWin);

            OSGGETGLFUNCBYID_GL3_ES(glCompileShader,
                                    osgGlCompileShader,
                                    FuncIdCompileShader,
                                    pWin);

            OSGGETGLFUNCBYID_GL3_ES(glGetShaderiv,
                                    osgGlGetShaderiv,
                                    FuncIdGetShaderiv,
                                    pWin);

            osgGlShaderSource(uiShader, 
                              1, 
                              static_cast<const char **>(&source), 
                              0);

            osgGlCompileShader(uiShader);

            GLint iStatus = 0;

            osgGlGetShaderiv( uiShader, 
                              GL_COMPILE_STATUS, 
                             &iStatus);

            if(iStatus == 0)
            {
                Char8 *szDebug;
                GLint  iDebugLength;

                osgGlGetShaderiv( uiShader, 
                                  GL_INFO_LOG_LENGTH, 
                                 &iDebugLength);

                szDebug = new Char8[iDebugLength];

                OSGGETGLFUNCBYID_GL3_ES(glGetShaderInfoLog,
                                        osgGlGetShaderInfoLog,
                                        FuncIdGetShaderInfoLog,
                                        pWin);

                osgGlGetShaderInfoLog( uiShader, 
                                       iDebugLength, 
                                      &iDebugLength, 
                                       szDebug     );

                FFATAL(("Couldn't compile shader program (0x%x)!\n%s\n", 
                        _sfShaderType.getValue(),
                        szDebug));

                delete [] szDebug;

                OSGGETGLFUNCBYID_GL3_ES(glDeleteShader,
                                        osgGlDeleteShader,
                                        FuncIdDeleteShader,
                                        pWin);

                osgGlDeleteShader(uiShader);

                uiShader = 0;
            }

            pWin->setGLObjectId(getGLId(), uiShader);
        }

        //updateProgramParameters(win);
        //updateParameters(win,
        //*getMFParameters(),
        //true,
        //true /*mode != Window::needrefresh*/);
    }

    return 0;
}
void BlendChunk::changeFrom(DrawEnv    *pEnv, 
                            StateChunk *old_chunk, 
                            UInt32               )
{
    pEnv->incNumChunkChanges();

    BlendChunk *old = dynamic_cast<BlendChunk *>(old_chunk);

    GLenum src    = _sfSrcFactor.getValue();
    GLenum dest   = _sfDestFactor.getValue();
    GLenum osrc   =  old->_sfSrcFactor.getValue();
    GLenum odest  =  old->_sfDestFactor.getValue();
    GLenum asrc   = _sfAlphaSrcFactor.getValue();
    GLenum adest  = _sfAlphaDestFactor.getValue();
    GLenum oasrc  =  old->_sfAlphaSrcFactor.getValue();
    GLenum oadest =  old->_sfAlphaDestFactor.getValue();

    Window *pWin = pEnv->getWindow();

    if((src   != GL_ONE        || dest  != GL_ZERO) ||
       (asrc  != OSG_GL_UNUSED && asrc  != GL_ONE ) || 
       (adest != OSG_GL_UNUSED && adest != GL_ZERO)  )
    {
        if(asrc != OSG_GL_UNUSED || adest != OSG_GL_UNUSED)
        {
            if(asrc == OSG_GL_UNUSED || adest == OSG_GL_UNUSED)
            {
                FWARNING(("BlendChunk::changeFrom: only one of alpha src and"
                          " alpha dest is set. Ignored.\n"));

                glBlendFunc(src, dest);
            }
            else if(pWin->hasExtOrVersion(_extBlendFuncSeparate, 
                                           0x0104, 
                                           0x0200              ))
            {
                if(osrc  != src  || odest  != dest ||
                   oasrc != asrc || oadest != adest )
                {
                    // get "glBlendFuncSeparate" function pointer
                    OSGGETGLFUNCBYID_GL3_ES( glBlendFuncSeparate, 
                                             osgGlBlendFuncSeparate,
                                            _funcBlendFuncSeparateExt,
                                             pWin);

                    osgGlBlendFuncSeparate(src, dest, asrc, adest);
                }
            }
            else
            {
                FWARNING(("BlendChunk::changeFrom: Window %p doesn't "
                          "support EXT_blend_func_separate, ignored.\n",
                          pEnv->getWindow()));

                glBlendFunc(src, dest);
            }
        }
        else if(osrc != src || odest != dest)
        {
            glBlendFunc(src, dest);
        }

        // This is not nice, but efficient
        // As the OpenGL constants are fixed it should be safe
        if((src  >= GL_CONSTANT_COLOR_EXT && 
            src  <= GL_ONE_MINUS_CONSTANT_ALPHA_EXT ) ||
           (dest >= GL_CONSTANT_COLOR_EXT && 
            dest <= GL_ONE_MINUS_CONSTANT_ALPHA_EXT ) ||
           (asrc  >= GL_CONSTANT_COLOR_EXT && 
            asrc  <= GL_ONE_MINUS_CONSTANT_ALPHA_EXT ) ||
           (adest >= GL_CONSTANT_COLOR_EXT && 
            adest <= GL_ONE_MINUS_CONSTANT_ALPHA_EXT ) )
        {
            if(pWin->hasExtOrVersion(_extBlend, 0x0102, 0x0200))
            {
                // get "glBlendColorEXT" function pointer
                OSGGETGLFUNCBYID_GL3_ES( glBlendColor, 
                                         osgGlBlendColor,
                                        _funcBlendColor,
                                         pWin);

                osgGlBlendColor(_sfColor.getValue().red(),
                                _sfColor.getValue().green(),
                                _sfColor.getValue().blue(),
                                _sfColor.getValue().alpha());
            }
        }
        if(osrc == GL_ONE && odest == GL_ZERO)
            glEnable(GL_BLEND);
    }
    else
    {
        if((osrc   != GL_ONE        || odest  != GL_ZERO) ||
           (oasrc  != OSG_GL_UNUSED && oasrc  != GL_ONE ) || 
           (oadest != OSG_GL_UNUSED && oadest != GL_ZERO) )
        {
            glDisable(GL_BLEND);
        }
    }

    if(_sfEquation.getValue() != old->_sfEquation.getValue())
    {
        if(pWin->hasExtOrVersion(_extImaging, 0x0104, 0x0200))
        {
            // get "glBlendEquation" function pointer
            OSGGETGLFUNCBYID_GL3_ES( glBlendEquation, 
                                     osgGlBlendEquation,
                                    _funcBlendEquation,
                                     pWin);

            osgGlBlendEquation(_sfEquation.getValue());
        }
        else if(pWin->hasExtOrVersion(_extBlendSubtract, 0x0102, 0x0200) ||
                pWin->hasExtOrVersion(_extBlendMinMax,   0x0102, 0x0200) ||
                pWin->hasExtOrVersion(_extBlendLogicOp,  0x0101, 0x0200))
        {
            // get "glBlendEquationEXT" function pointer
            OSGGETGLFUNCBYID_GL3_ES( glBlendEquation, 
                                     osgGlBlendEquation,
                                    _funcBlendEquation,
                                     pWin);

            osgGlBlendEquation(_sfEquation.getValue());
        }
    }
    
#if !defined(OSG_OGL_COREONLY) || defined(OSG_CHECK_COREONLY)
    if(_sfAlphaFunc.getValue() != GL_NONE)
    {
        if(old->_sfAlphaFunc.getValue()  != _sfAlphaFunc.getValue() ||
           old->_sfAlphaValue.getValue() != _sfAlphaValue.getValue())
        {
            glAlphaFunc(_sfAlphaFunc.getValue(), _sfAlphaValue.getValue());
        }

        if(old->_sfAlphaFunc.getValue() == GL_NONE)
            glEnable(GL_ALPHA_TEST);
    }
    else
    {
        if(old->_sfAlphaFunc.getValue() != GL_NONE)
            glDisable(GL_ALPHA_TEST);        
    }
#endif    
}
Exemple #25
0
bool VboFunctions::initFunctionPointers( Window* window )
{
    assert( window );

    OSGGETGLFUNCBYID_GL3_ES(glBindBuffer, 
                            osgGlBindBuffer,
                            bindBufferId_ , 
                            window);

    bindBuffer = osgGlBindBuffer;

    OSGGETGLFUNCBYID_GL3_ES(glBufferData, 
                            osgGlBufferData,
                            bufferDataId_, 
                            window);
    
    bufferData = osgGlBufferData;

    OSGGETGLFUNCBYID_GL3_ES(glBufferSubData, 
                            osgGlBufferSubData,
                            bufferSubDataId_, 
                            window);

    bufferSubData = osgGlBufferSubData;

    OSGGETGLFUNCBYID_GL3_ES(glDeleteBuffers, 
                            osgGlDeleteBuffers,
                            deleteBuffersId_, 
                            window);

    deleteBuffers = osgGlDeleteBuffers;

    OSGGETGLFUNCBYID_GL3_ES(glGenBuffers, 
                            osgGlGenBuffers,
                            genBuffersId_, 
                            window);
    
    genBuffers = osgGlGenBuffers;

    OSGGETGLFUNCBYID_GL3_ES(glGetBufferParameteriv,
                            osgGlGetBufferParameteriv,
                            getBufferParameterivId_,
                            window);
    
    getBufferParameteriv = osgGlGetBufferParameteriv;

    OSGGETGLFUNCBYID_GL3(glGetBufferPointerv,
                         osgGlGetBufferPointerv,
                         getBufferPointervId_,
                         window);

    getBufferPointerv = osgGlGetBufferPointerv;

    OSGGETGLFUNCBYID_GL3(glGetBufferSubData,
                         osgGlGetBufferSubData,
                         getBufferSubDataId_,
                         window);

    getBufferSubData = osgGlGetBufferSubData;

    OSGGETGLFUNCBYID_GL3_ES(glIsBuffer,
                            osgGlIsBuffer,
                            isBufferId_,
                            window);
    
    isBuffer = osgGlIsBuffer;

    OSGGETGLFUNCBYID_GL3_ES(glMapBuffer, 
                            osgGlMapBuffer,
                            mapBufferId_, 
                            window);

    mapBuffer = osgGlMapBuffer;

    OSGGETGLFUNCBYID_GL3_ES(glUnmapBuffer, 
                            osgGlUnmapBuffer,
                            unmapBufferId_, 
                            window);

    unmapBuffer = osgGlUnmapBuffer;

    return ( bindBuffer != 0 ) && ( bufferData != 0 ) && ( bufferSubData != 0 ) && ( deleteBuffers != 0 ) &&
        ( genBuffers != 0 ) && ( getBufferPointerv != 0 ) && ( getBufferSubData != 0 ) && ( isBuffer != 0 ) &&
        ( mapBuffer != 0 ) && ( unmapBuffer != 0 );
}