Пример #1
0
void DepthPeelBin::drawFSTP( osg::RenderInfo& renderInfo, osg::State& state, osg::GL2Extensions* ext, PerContextInfo& pci,
                            GLint& fstpLoc, GLint& texturePercentLoc )
{
    TRACEDUMP("DepthPeelBin::drawFSTP");

    // Set up the program and uniforms.
    state.applyAttribute( _fstpProgram.get() );
    if( fstpLoc < 0 )
#if OSG_SUPPORTS_UNIFORM_ID
        fstpLoc = state.getUniformLocation( _fstpUniform->getNameID() );
#else
        fstpLoc = state.getUniformLocation( _fstpUniform->getName() );
#endif
    _fstpUniform->apply( ext, fstpLoc );
    if( texturePercentLoc < 0 )
#if OSG_SUPPORTS_UNIFORM_ID
        texturePercentLoc = state.getUniformLocation( _texturePercentUniform->getNameID() );
#else
        texturePercentLoc = state.getUniformLocation( _texturePercentUniform->getName() );
#endif
    _texturePercentUniform->apply( ext, texturePercentLoc );

    state.setActiveTextureUnit( s_textureUnit+1 );
    glBindTexture( GL_TEXTURE_2D, pci._colorTex );
    state.applyAttribute( _fstpBlendFunc.get() );
    state.applyMode( GL_BLEND, true );
    state.applyMode( GL_DEPTH_TEST, false );

    _fstp->draw( renderInfo );

    state.setActiveTextureUnit( s_textureUnit+1 );
    glBindTexture( GL_TEXTURE_2D, 0 );
}
Пример #2
0
    virtual void apply(osg::State& state) const {
        osg::State::UniformMap::const_iterator i = state.getUniformMap().find("oe_isPickCamera");
        bool isPickCamera = false;
        if (i != state.getUniformMap().end())
        {
            if (!i->second.uniformVec.empty())
            {
                i->second.uniformVec.back().first->get(isPickCamera);
            }
        }

        if (isPickCamera)
        {
            FilterMode minFilter = _min_filter;
            FilterMode magFilter = _mag_filter;
            DrapingTexture* ncThis = const_cast<DrapingTexture*>(this);
            ncThis->_min_filter = NEAREST;
            ncThis->_mag_filter = NEAREST;
            ncThis->dirtyTextureParameters();
            osg::Texture2D::apply(state);
            ncThis->_min_filter = minFilter;
            ncThis->_mag_filter = magFilter;
            ncThis->dirtyTextureParameters();
        }
        else
        {
            osg::Texture2D::apply(state);
        }
    }
Пример #3
0
	virtual void drawImplementation(osg::State& state,const osg::Drawable* drawable) const 
	{
		static osg::TexMat *tm= new osg::TexMat();
		osg::Matrix mvm(state.getModelViewMatrix());
		osg::Quat q;
		q.set(mvm);
//		state.getorcre
		tm->setMatrix(osg::Matrix::rotate( q.inverse() ));
		state.applyTextureAttribute(1,tm);
//		drawable->getOrCreateStateSet()->
		drawable->drawImplementation(state);
	}
Пример #4
0
        virtual void apply(osg::State& state) const
        {
            osg::Matrix modelViewMatrix = state.getModelViewMatrix();

            state.applyModelViewMatrix(state.getInitialViewMatrix());

            for (unsigned int i=0; i<mLights.size(); ++i)
            {
                mLights[i]->setLightNum(i+mIndex);
                mLights[i]->apply(state);
            }

            state.applyModelViewMatrix(modelViewMatrix);
        }
Пример #5
0
unsigned int DepthPeelBin::drawInit( osg::State& state, osgUtil::RenderLeaf*& previous )
{
    TRACEDUMP("DepthPeelBin::drawInit");

    unsigned int numToPop = (previous ? osgUtil::StateGraph::numToPop(previous->_parent) : 0);
    if (numToPop>1) --numToPop;
    unsigned int insertStateSetPosition = state.getStateSetStackSize() - numToPop;

    if (_stateset.valid())
    {
        state.insertStateSet(insertStateSetPosition, _stateset.get());
    }

    return( insertStateSetPosition );
}
void RenderingEffects::applyAllGlobalUniforms( osg::State& state, osg::GL2Extensions* gl2Ext )
{
    UniformVector::iterator it;
    for( it = _globalUniformVector.begin(); it != _globalUniformVector.end(); it++ )
    {
        osg::Uniform* uniform = (*it).get();
#if OSG_SUPPORTS_UNIFORM_ID
        GLint location = state.getUniformLocation( uniform->getNameID() );
#else
        GLint location = state.getUniformLocation( uniform->getName() );
#endif
        if( location >= 0 )
            uniform->apply( gl2Ext, location );
    }
}
void AtomicCounterBufferBinding::readData(osg::State & state, osg::UIntArray & uintArray) const
{
    if (!_bufferObject) return;

    GLBufferObject* bo = _bufferObject->getOrCreateGLBufferObject( state.getContextID() );
    if (!bo) return;


    GLint previousID = 0;
    glGetIntegerv(GL_ATOMIC_COUNTER_BUFFER_BINDING, &previousID);

    if (static_cast<GLuint>(previousID) != bo->getGLObjectID())
        bo->_extensions->glBindBuffer(GL_ATOMIC_COUNTER_BUFFER, bo->getGLObjectID());

    GLubyte* src = (GLubyte*)bo->_extensions->glMapBuffer(GL_ATOMIC_COUNTER_BUFFER,
                                                          GL_READ_ONLY_ARB);
    if(src)
    {
        size_t size = osg::minimum<int>(_size, uintArray.getTotalDataSize());
        memcpy((void*) &(uintArray.front()), src+_offset, size);
        bo->_extensions->glUnmapBuffer(GL_ATOMIC_COUNTER_BUFFER);
    }

    if (static_cast<GLuint>(previousID) != bo->getGLObjectID())
        bo->_extensions->glBindBuffer(GL_ATOMIC_COUNTER_BUFFER, static_cast<GLuint>(previousID));
}
Пример #8
0
    virtual void dispatch(osg::State& state, const osg::Array* new_array, const osg::GLBufferObject* vbo)
    {
        VAS_NOTICE<<"    TexCoordArrayDispatch::dispatch("<<new_array->getNumElements()<<", vbo="<<std::hex<<vbo<<std::dec<<") unit="<<unit<<std::endl;

        state.setClientActiveTextureUnit(unit);
        glTexCoordPointer(new_array->getDataSize(), new_array->getDataType(), 0, (const GLvoid *)(vbo->getOffset(new_array->getBufferIndex())));
    }
Пример #9
0
void LODDrawCallback::drawImplementation( osg::State& state, const osg::Drawable* p_drawable ) const
{
    assert( _p_lodMesh && "lod mesh data not available!" );

    const GLuint groupname  = _p_lodMesh->getGroupName();
    const GLuint objectname = _p_lodMesh->getObjectName();
    const GLuint numpatches = _p_lodMesh->getNumPatches();

    // need for LOD adaptation?
    if ( _p_lodMesh->adaptLOD() )
    {
        glodBindObjectXform( objectname, GL_PROJECTION_MATRIX | GL_MODELVIEW_MATRIX );
        glodAdaptGroup( groupname );
        // reset the adaptation flag after every adaptation
        // the adaptation is triggered by update callback
        _p_lodMesh->setAdaptLOD( false );
    }

    // apply drawable's state
    state.apply( p_drawable->getStateSet() );
    
    // draw the object patches
    for( GLuint patch = 0; patch < numpatches; ++patch )
        glodDrawPatch( objectname, patch );
}
Пример #10
0
    virtual void dispatch(osg::State& state, const osg::Array* new_array)
    {
        VAS_NOTICE<<"    TexCoordArrayDispatch::dispatch("<<new_array->getNumElements()<<") unit="<<unit<<std::endl;

        state.setClientActiveTextureUnit(unit);
        glTexCoordPointer(new_array->getDataSize(), new_array->getDataType(), 0, new_array->getDataPointer());
    }
Пример #11
0
 // Return true to activate the shader function.
 bool operator()(const osg::State& state)
 {
     osg::Camera* camera = *state.getGraphicsContext()->getCameras().begin();
     if (!camera) return false;
     osg::Viewport* viewport = camera->getViewport();
     if (!viewport) return false;
     return viewport->width() > 1000;
 }
Пример #12
0
void Validator::apply(osg::State& state) const
{
    if (!_effect) return;

    if (_effect->_tech_selected[state.getContextID()] == 0) {
        Effect::Technique_list::iterator i;
        int j = 0;
        for (i=_effect->_techs.begin(); i!=_effect->_techs.end(); ++i, ++j) {
            if ((*i)->validate(state)) {
                _effect->_sel_tech[state.getContextID()] = j;
                _effect->_tech_selected[state.getContextID()] = 1;
                return;
            }
        }
        OSG_WARN << "Warning: osgFX::Validator: could not find any techniques compatible with the current OpenGL context" << std::endl;
    }
}
Пример #13
0
    virtual void disable(osg::State& state)
    {
        VAS_NOTICE<<"    TexCoordArrayDispatch::disable() unit="<<unit<<std::endl;

        //state.glClientActiveTexture(static_cast<GLenum>(GL_TEXTURE0+unit));
        state.setClientActiveTextureUnit(unit);
        glDisableClientState(GL_TEXTURE_COORD_ARRAY);
    }
Пример #14
0
void
MaterialGL3::apply(osg::State& state) const
{
#ifdef OSG_GL_FIXED_FUNCTION_AVAILABLE
    osg::Material::apply(state);
#else
    state.Color(_diffuseFront.r(), _diffuseFront.g(), _diffuseFront.b(), _diffuseFront.a());
#endif
}
Пример #15
0
std::string DepthPeelBin::createFileName( osg::State& state, int pass, bool depth )
{
    unsigned int contextID = state.getContextID();
    int frameNumber = state.getFrameStamp()->getFrameNumber();
    std::ostringstream ostr;
    ostr << std::setfill( '0' );
    ostr << "f" << std::setw( 6 ) << frameNumber <<
        "_c" << std::setw( 2 ) << contextID << "_";

    ostr << "peel_part" << _partitionNumber;
    if( pass == -1 )
        ostr << "_a";
    else
        ostr << "_b" << std::setw( 2 ) << pass;
    if( depth )
        ostr << "_z";
    ostr << ".png";
    return( ostr.str() );
}
Пример #16
0
void DepthPeelBin::drawComplete( osg::State& state, unsigned int insertStateSetPosition )
{
    TRACEDUMP("DepthPeelBin::drawComplete");

    if (_stateset.valid())
    {
        state.removeStateSet(insertStateSetPosition);
        // state.apply();
    }
}
Пример #17
0
bool Technique::validate(osg::State& state) const
{
    typedef std::vector<std::string> String_list;
    String_list extensions;

    getRequiredExtensions(extensions);

    for (String_list::const_iterator i=extensions.begin(); i!=extensions.end(); ++i) {
        if (!osg::isGLExtensionSupported(state.getContextID(),i->c_str())) return false;
    }

    return true;
}
Пример #18
0
void osgParticle::ParticleSystem::ArrayData::dispatchArrays(osg::State& state)
{
    osg::VertexArrayState* vas = state.getCurrentVertexArrayState();

    vas->lazyDisablingOfVertexAttributes();

    if (vertices.valid()) vas->setVertexArray(state, vertices.get());
    if (normals.valid()) vas->setNormalArray(state, normals.get());
    if (colors.valid()) vas->setColorArray(state, colors.get());
    if (texcoords2.valid()) vas->setTexCoordArray(state, 0, texcoords2.get());
    if (texcoords3.valid()) vas->setTexCoordArray(state, 0, texcoords3.get());

    vas->applyDisablingOfVertexAttributes(state);
}
Пример #19
0
void Text3D::renderPerGlyph(osg::State & state) const
{
    osg::Matrix original_modelview = state.getModelViewMatrix();

    // ** for each line, do ...
    TextRenderInfo::const_iterator itLine, endLine = _textRenderInfo.end();
    for (itLine = _textRenderInfo.begin(); itLine!=endLine; ++itLine)
    {
        // ** for each glyph in the line, do ...
        LineRenderInfo::const_iterator it, end = itLine->end();
        for (it = itLine->begin(); it!=end; ++it)
        {

            osg::ref_ptr<osg::RefMatrix> matrix = new osg::RefMatrix(original_modelview);
            matrix->preMultTranslate(osg::Vec3d(it->_position.x(), it->_position.y(), it->_position.z()));
            state.applyModelViewMatrix(matrix.get());

            // ** apply the vertex array
            state.setVertexPointer(it->_glyph->getVertexArray());

            // ** render the front face of the glyph
            state.Normal(0.0f,0.0f,1.0f);

            osg::Geometry::PrimitiveSetList & pslFront = it->_glyph->getFrontPrimitiveSetList();
            for(osg::Geometry::PrimitiveSetList::const_iterator itr=pslFront.begin(), end = pslFront.end(); itr!=end; ++itr)
            {
                (*itr)->draw(state, false);
            }

            // ** render the wall face of the glyph
            state.setNormalPointer(it->_glyph->getNormalArray());
            osg::Geometry::PrimitiveSetList & pslWall = it->_glyph->getWallPrimitiveSetList();
            for(osg::Geometry::PrimitiveSetList::const_iterator itr=pslWall.begin(), end=pslWall.end(); itr!=end; ++itr)
            {
                (*itr)->draw(state, false);
            }
            state.disableNormalPointer();

            // ** render the back face of the glyph
            state.Normal(0.0f,0.0f,-1.0f);

            osg::Geometry::PrimitiveSetList & pslBack = it->_glyph->getBackPrimitiveSetList();
            for(osg::Geometry::PrimitiveSetList::const_iterator itr=pslBack.begin(), end=pslBack.end(); itr!=end; ++itr)
            {
                (*itr)->draw(state, false);
            }
        }
    }
}
Пример #20
0
void
DepthPeelBin::PerContextInfo::cleanup( const osg::State& state )
{
    TRACEDUMP("  PerContextInfo::cleanup");

    glDeleteTextures( 3, _depthTex );
    _depthTex[ 0 ] = _depthTex[ 1 ] = _depthTex[ 2 ] = 0;

    glDeleteTextures( 1, &_colorTex );
    _colorTex = 0;

    osg::FBOExtensions* fboExt( osg::FBOExtensions::instance( state.getContextID(), true ) );
    osgwTools::glBindFramebuffer( fboExt, GL_FRAMEBUFFER_EXT, 0 );
    osgwTools::glDeleteFramebuffers( fboExt, 1, &_fbo );
    _fbo = 0;

    _glDeleteQueries( 1, &_queryID );
    _queryID = 0;

    _init = false;
}
Пример #21
0
void Font::Glyph::draw(osg::State& state) const
{
    GLuint& globj = _globjList[state.getContextID()];

    // call the globj if already set otherwise compile and execute.
    if( globj != 0 )
    {
        glCallList( globj );
    }
    else 
    {
        globj = glGenLists( 1 );
        glNewList( globj, GL_COMPILE_AND_EXECUTE );

        glPixelStorei(GL_UNPACK_ALIGNMENT,getPacking());
        glDrawPixels(s(), t(),
                     (GLenum)getPixelFormat(),
                     (GLenum)getDataType(),
                     data() );

        glEndList();
    }
}
Пример #22
0
void GlyphTexture::apply(osg::State& state) const
{
    // get the contextID (user defined ID of 0 upwards) for the 
    // current OpenGL context.
    const unsigned int contextID = state.getContextID();

    if (contextID>=_glyphsToSubload.size())
    {
        OpenThreads::ScopedLock<OpenThreads::Mutex> lock(_mutex);

        // graphics context is beyond the number of glyphsToSubloads, so
        // we must now copy the glyph list across, this is a potential
        // threading issue though is multiple applies are happening the
        // same time on this object - to avoid this condition number of
        // graphics contexts should be set before create text.
        for(unsigned int i=_glyphsToSubload.size();i<=contextID;++i)
        {
            GlyphPtrList& glyphPtrs = _glyphsToSubload[i];
            for(GlyphRefList::const_iterator itr=_glyphs.begin();
                itr!=_glyphs.end();
                ++itr)
            {
                glyphPtrs.push_back(itr->get());
            }
        }
    }


    const Extensions* extensions = getExtensions(contextID,true);
    bool generateMipMapSupported = extensions->isGenerateMipMapSupported();

    // get the texture object for the current contextID.
    TextureObject* textureObject = getTextureObject(contextID);
    
    bool newTextureObject = (textureObject == 0);

    if (newTextureObject)
    {
        GLint maxTextureSize = 256;
        glGetIntegerv(GL_MAX_TEXTURE_SIZE, &maxTextureSize);
        if (maxTextureSize < getTextureWidth() || maxTextureSize < getTextureHeight())
        {
            OSG_WARN<<"Warning: osgText::Font texture size of ("<<getTextureWidth()<<", "<<getTextureHeight()<<") too large, unable to create font texture."<<std::endl;
            OSG_WARN<<"         Maximum supported by hardward by native OpenGL implementation is ("<<maxTextureSize<<","<<maxTextureSize<<")."<<std::endl;
            OSG_WARN<<"         Please set OSG_MAX_TEXTURE_SIZE lenvironment variable to "<<maxTextureSize<<" and re-run application."<<std::endl;
            return;
        }
        
        // being bound for the first time, need to allocate the texture

        _textureObjectBuffer[contextID] = textureObject = osg::Texture::generateTextureObject(
                this, contextID,GL_TEXTURE_2D,1,GL_ALPHA,getTextureWidth(), getTextureHeight(),1,0);

        textureObject->bind();


        applyTexParameters(GL_TEXTURE_2D,state);

        
        // need to look at generate mip map extension if mip mapping required.
        switch(_min_filter)
        {
        case NEAREST_MIPMAP_NEAREST:
        case NEAREST_MIPMAP_LINEAR:
        case LINEAR_MIPMAP_NEAREST:
        case LINEAR_MIPMAP_LINEAR:
            if (generateMipMapSupported)
            {
                glTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP_SGIS,GL_TRUE);
            }
            else glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, LINEAR);
            break;
        default:
            // not mip mapping so no problems.
            break;
        }
        
        unsigned int imageDataSize = getTextureHeight()*getTextureWidth();
        unsigned char* imageData = new unsigned char[imageDataSize];
        for(unsigned int i=0; i<imageDataSize; ++i)
        {
            imageData[i] = 0;
        }
        

        // allocate the texture memory.
        glTexImage2D( GL_TEXTURE_2D, 0, GL_ALPHA,
                getTextureWidth(), getTextureHeight(), 0,
                GL_ALPHA,
                GL_UNSIGNED_BYTE,
                imageData );
                
        delete [] imageData;
    
    }
    else
    {
        // reuse texture by binding.
        textureObject->bind();
        
        if (getTextureParameterDirty(contextID))
        {
            applyTexParameters(GL_TEXTURE_2D,state);
        }


    }
    
    static const GLubyte* s_renderer = 0;
    static bool s_subloadAllGlyphsTogether = false;
    if (!s_renderer)
    {
        OpenThreads::ScopedLock<OpenThreads::Mutex> lock(_mutex);

        s_renderer = glGetString(GL_RENDERER);
        OSG_INFO<<"glGetString(GL_RENDERER)=="<<s_renderer<<std::endl;
        if (s_renderer && strstr((const char*)s_renderer,"IMPACT")!=0)
        {
            // we're running on an Octane, so need to work around its
            // subloading bugs by loading all at once.
            s_subloadAllGlyphsTogether = true;
        }
        
        if (s_renderer && 
            ((strstr((const char*)s_renderer,"Radeon")!=0) || 
            (strstr((const char*)s_renderer,"RADEON")!=0) ||
            (strstr((const char*)s_renderer,"ALL-IN-WONDER")!=0)))
        {
            // we're running on an ATI, so need to work around its
            // subloading bugs by loading all at once.
            s_subloadAllGlyphsTogether = true;
        }

        if (s_renderer && strstr((const char*)s_renderer,"Sun")!=0)
        {
            // we're running on an solaris x server, so need to work around its
            // subloading bugs by loading all at once.
            s_subloadAllGlyphsTogether = true;
        }

        const char* str = getenv("OSG_TEXT_INCREMENTAL_SUBLOADING");
        if (str)
        {
            s_subloadAllGlyphsTogether = strcmp(str,"OFF")==0 || strcmp(str,"Off")==0 || strcmp(str,"off")==0;
        }
    }


    // now subload the glyphs that are outstanding for this graphics context.
    GlyphPtrList& glyphsWereSubloading = _glyphsToSubload[contextID];

    if (!glyphsWereSubloading.empty() || newTextureObject)
    {
        OpenThreads::ScopedLock<OpenThreads::Mutex> lock(_mutex);

        if (!s_subloadAllGlyphsTogether)
        {
            if (newTextureObject)
            {
                for(GlyphRefList::const_iterator itr=_glyphs.begin();
                    itr!=_glyphs.end();
                    ++itr)
                {
                    (*itr)->subload();
                }
            }
            else // just subload the new entries.
            {            
                // default way of subloading as required.
                //std::cout<<"subloading"<<std::endl;
                for(GlyphPtrList::iterator itr=glyphsWereSubloading.begin();
                    itr!=glyphsWereSubloading.end();
                    ++itr)
                {
                    (*itr)->subload();
                }
            }
            
            // clear the list since we have now subloaded them.
            glyphsWereSubloading.clear();
            
        }
        else
        {
            OSG_INFO<<"osgText::Font loading all glyphs as a single subload."<<std::endl;

            // Octane has bugs in OGL driver which mean that subloads smaller
            // than 32x32 produce errors, and also cannot handle general alignment,
            // so to get round this copy all glyphs into a temporary image and
            // then subload the whole lot in one go.

            int tsize = getTextureHeight() * getTextureWidth();
            unsigned char *local_data = new unsigned char[tsize];
            memset( local_data, 0L, tsize);

            for(GlyphRefList::const_iterator itr=_glyphs.begin();
                itr!=_glyphs.end();
                ++itr)
            {
                //(*itr)->subload();

                // Rather than subloading to graphics, we'll write the values
                // of the glyphs into some intermediate data and subload the
                // whole thing at the end
                for( int t = 0; t < (*itr)->t(); t++ )
                {
                    for( int s = 0; s < (*itr)->s(); s++ )
                    {
                        int sindex = (t*(*itr)->s()+s);
                        int dindex =  
                            ((((*itr)->getTexturePositionY()+t) * getTextureWidth()) +
                            ((*itr)->getTexturePositionX()+s));

                        const unsigned char *sptr = &(*itr)->data()[sindex];
                        unsigned char *dptr       = &local_data[dindex];

                        (*dptr)   = (*sptr);
                    }
                }
            }

            // clear the list since we have now subloaded them.
            glyphsWereSubloading.clear();

            // Subload the image once
            glTexSubImage2D( GL_TEXTURE_2D, 0, 0, 0, 
                    getTextureWidth(),
                    getTextureHeight(),
                    GL_ALPHA, GL_UNSIGNED_BYTE, local_data );

            delete [] local_data;

        }
    }
    else
    {
//        OSG_INFO << "no need to subload "<<std::endl;
    }



//     if (generateMipMapTurnedOn)
//     {
//         glTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP_SGIS,GL_FALSE);
//     }


}
Пример #23
0
void VertexArrayState::setArray(ArrayDispatch* vad, osg::State& state, const osg::Array* new_array)
{
    if (new_array)
    {
        if (!vad->active)
        {
            vad->active = true;
            _activeDispatchers.push_back(vad);
        }

        if (vad->array==0)
        {
            GLBufferObject* vbo = isVertexBufferObjectSupported() ? new_array->getOrCreateGLBufferObject(state.getContextID()) : 0;
            if (vbo)
            {
                bindVertexBufferObject(vbo);
                vad->enable_and_dispatch(state, new_array, vbo);
            }
            else
            {
                unbindVertexBufferObject();
                vad->enable_and_dispatch(state, new_array);
            }
        }
        else if (new_array!=vad->array || new_array->getModifiedCount()!=vad->modifiedCount)
        {
            GLBufferObject* vbo = isVertexBufferObjectSupported() ? new_array->getOrCreateGLBufferObject(state.getContextID()) : 0;
            if (vbo)
            {
                bindVertexBufferObject(vbo);
                vad->dispatch(state, new_array, vbo);
            }
            else
            {
                unbindVertexBufferObject();
                vad->dispatch(state, new_array);
            }
        }

        vad->array = new_array;
        vad->modifiedCount = new_array->getModifiedCount();

    }
    else if (vad->array)
    {
        disable(vad, state);
    }
}
Пример #24
0
void
MPGeometry::renderPrimitiveSets(osg::State& state,
                                bool        usingVBOs) const
{
    // check the map frame to see if it's up to date
    if ( _frame.needsSync() )
    {
        // this lock protects a MapFrame sync when we have multiple DRAW threads.
        Threading::ScopedMutexLock exclusive( _frameSyncMutex );

        if ( _frame.needsSync() && _frame.sync() ) // always double check
        {
            // This should only happen is the layer ordering changes;
            // If layers are added or removed, the Tile gets rebuilt and
            // the point is moot.
            std::vector<Layer> reordered;
            const ImageLayerVector& layers = _frame.imageLayers();
            reordered.reserve( layers.size() );
            for( ImageLayerVector::const_iterator i = layers.begin(); i != layers.end(); ++i )
            {
                std::vector<Layer>::iterator j = std::find( _layers.begin(), _layers.end(), i->get()->getUID() );
                if ( j != _layers.end() )
                    reordered.push_back( *j );
            }
            _layers.swap( reordered );
        }
    }

    unsigned layersDrawn = 0;


    osg::ref_ptr<osg::GL2Extensions> ext = osg::GL2Extensions::Get( state.getContextID(), true );
    const osg::Program::PerContextProgram* pcp = state.getLastAppliedProgramObject();

    GLint opacityLocation;
    GLint uidLocation;
    GLint orderLocation;
    GLint texMatParentLocation;

    // yes, it's possible that the PCP is not set up yet.
    // TODO: can we optimize this so we don't need to get uni locations every time?
    if ( pcp )
    {
        opacityLocation      = pcp->getUniformLocation( _opacityUniform->getNameID() );
        uidLocation          = pcp->getUniformLocation( _layerUIDUniform->getNameID() );
        orderLocation        = pcp->getUniformLocation( _layerOrderUniform->getNameID() );
        texMatParentLocation = pcp->getUniformLocation( _texMatParentUniform->getNameID() );
    }

    // activate the tile coordinate set - same for all layers
    state.setTexCoordPointer( _imageUnit+1, _tileCoords.get() );

    if ( _layers.size() > 0 )
    {
        float prev_opacity        = -1.0f;
        float prev_alphaThreshold = -1.0f;

        // first bind any shared layers
        // TODO: optimize by pre-storing shared indexes
        for(unsigned i=0; i<_layers.size(); ++i)
        {
            const Layer& layer = _layers[i];

            // a "shared" layer binds to a secondary texture unit so that other layers
            // can see it and use it.
            if ( layer._imageLayer->isShared() )
            {
                int sharedUnit = layer._imageLayer->shareImageUnit().get();
                {
                    state.setActiveTextureUnit( sharedUnit );
                    state.setTexCoordPointer( sharedUnit, layer._texCoords.get() );
                    // bind the texture for this layer to the active share unit.
                    layer._tex->apply( state );

                    // no texture LOD blending for shared layers for now. maybe later.
                }
            }
        }

        // track the active image unit.
        int activeImageUnit = -1;

        // interate over all the image layers
        for(unsigned i=0; i<_layers.size(); ++i)
        {
            const Layer& layer = _layers[i];

            if ( layer._imageLayer->getVisible() )
            {
                // activate the visible unit if necessary:
                if ( activeImageUnit != _imageUnit )
                {
                    state.setActiveTextureUnit( _imageUnit );
                    activeImageUnit = _imageUnit;
                }

                // bind the texture for this layer:
                layer._tex->apply( state );

                // if we're using a parent texture for blending, activate that now
                if ( layer._texParent.valid() )
                {
                    state.setActiveTextureUnit( _imageUnitParent );
                    activeImageUnit = _imageUnitParent;
                    layer._texParent->apply( state );
                }

                // bind the texture coordinates for this layer.
                // TODO: can probably optimize this by sharing or using texture matrixes.
                // State::setTexCoordPointer does some redundant work under the hood.
                state.setTexCoordPointer( _imageUnit, layer._texCoords.get() );

                // apply uniform values:
                if ( pcp )
                {
                    // apply opacity:
                    float opacity = layer._imageLayer->getOpacity();
                    if ( opacity != prev_opacity )
                    {
                        _opacityUniform->set( opacity );
                        _opacityUniform->apply( ext, opacityLocation );
                        prev_opacity = opacity;
                    }

                    // assign the layer UID:
                    _layerUIDUniform->set( layer._layerID );
                    _layerUIDUniform->apply( ext, uidLocation );

                    // assign the layer order:
                    _layerOrderUniform->set( (int)layersDrawn );
                    _layerOrderUniform->apply( ext, orderLocation );

                    // assign the parent texture matrix
                    if ( layer._texParent.valid() )
                    {
                        _texMatParentUniform->set( layer._texMatParent );
                        _texMatParentUniform->apply( ext, texMatParentLocation );
                    }
                }

                // draw the primitive sets.
                for(unsigned int primitiveSetNum=0; primitiveSetNum!=_primitives.size(); ++primitiveSetNum)
                {
                    const osg::PrimitiveSet* primitiveset = _primitives[primitiveSetNum].get();
                    primitiveset->draw(state, usingVBOs);
                }

                ++layersDrawn;
            }
        }

        // prevent texture leakage
        glBindTexture( GL_TEXTURE_2D, 0 );
    }

    // if we didn't draw anything, draw the raw tiles anyway with no texture.
    if ( layersDrawn == 0 )
    {
        _opacityUniform->set( 1.0f );
        _opacityUniform->apply( ext, opacityLocation );

        _layerUIDUniform->set( (int)-1 ); // indicates a non-textured layer
        _layerUIDUniform->apply( ext, uidLocation );

        _layerOrderUniform->set( (int)0 );
        _layerOrderUniform->apply( ext, orderLocation );

        // draw the primitives themselves.
        for(unsigned int primitiveSetNum=0; primitiveSetNum!=_primitives.size(); ++primitiveSetNum)
        {
            const osg::PrimitiveSet* primitiveset = _primitives[primitiveSetNum].get();
            primitiveset->draw(state, usingVBOs);
        }
    }
}
Пример #25
0
 virtual void dispatch(osg::State& state, GLint size, GLenum type, GLsizei stride, const GLvoid *ptr, GLboolean /*normalized*/)
 {
     state.setClientActiveTextureUnit(unit);
     glTexCoordPointer(size, type, stride, ptr);
 }
Пример #26
0
void PositionalStateContainer::draw(osg::State& state,RenderLeaf*& previous, const osg::Matrix* postMultMatrix)
{

    if (previous)
    {
        StateGraph::moveToRootStateGraph(state,previous->_parent);
        state.apply();
        previous = NULL;
    }

    // apply the light list.
    for(AttrMatrixList::iterator litr=_attrList.begin();
        litr!=_attrList.end();
        ++litr)
    {
        if (postMultMatrix)
        {
            if ((*litr).second.valid())
                state.applyModelViewMatrix(new osg::RefMatrix( (*((*litr).second)) * (*postMultMatrix)));
            else
                state.applyModelViewMatrix(new osg::RefMatrix( *postMultMatrix));
        }

        else
        {
            state.applyModelViewMatrix((*litr).second.get());
        }

        // apply the light source.
        litr->first->apply(state);

        // tell state about.
        state.haveAppliedAttribute(litr->first.get());

        // set this state as a global default
        state.setGlobalDefaultAttribute(litr->first.get());
    }

    for(TexUnitAttrMatrixListMap::iterator titr=_texAttrListMap.begin();
        titr!=_texAttrListMap.end();
        ++titr)
    {
        state.setActiveTextureUnit(titr->first);

        AttrMatrixList attrList = titr->second;

        for(AttrMatrixList::iterator litr=attrList.begin();
            litr!=attrList.end();
            ++litr)
        {
            if (postMultMatrix)
            {
                if ((*litr).second.valid())
                    state.applyModelViewMatrix(new osg::RefMatrix( (*((*litr).second)) * (*postMultMatrix)));
                else
                    state.applyModelViewMatrix(new osg::RefMatrix( *postMultMatrix));
            }
            else
            {
                state.applyModelViewMatrix((*litr).second.get());
            }

            // apply the light source.
            litr->first->apply(state);

            // tell state about.
            state.haveAppliedTextureAttribute(titr->first, litr->first.get());

            // set this state as a global default
            state.setGlobalDefaultTextureAttribute(titr->first, litr->first.get());
        }

    }
}
Пример #27
0
 // Return true to activate the shader function.
 bool operator()(const osg::State& state)
 {
     const osg::Viewport* vp = state.getCurrentViewport();
     return vp && vp->x() == 0.0;
 }
Пример #28
0
 virtual void enable_and_dispatch(osg::State& state, GLint size, GLenum type, GLsizei stride, const GLvoid *ptr, GLboolean /*normalized*/)
 {
     state.setClientActiveTextureUnit(unit);
     glEnableClientState(GL_TEXTURE_COORD_ARRAY);
     glTexCoordPointer(size, type, stride, ptr);
 }
Пример #29
0
void
MPGeometry::renderPrimitiveSets(osg::State& state,
                                bool        renderColor,
                                bool        usingVBOs) const
{
    // check the map frame to see if it's up to date
    if ( _frame.needsSync() )
    {
        // this lock protects a MapFrame sync when we have multiple DRAW threads.
        Threading::ScopedMutexLock exclusive( _frameSyncMutex );

        if ( _frame.needsSync() && _frame.sync() ) // always double check
        {
            // This should only happen is the layer ordering changes;
            // If layers are added or removed, the Tile gets rebuilt and
            // the point is moot.
            std::vector<Layer> reordered;
            const ImageLayerVector& layers = _frame.imageLayers();
            reordered.reserve( layers.size() );
            for( ImageLayerVector::const_iterator i = layers.begin(); i != layers.end(); ++i )
            {
                std::vector<Layer>::iterator j = std::find( _layers.begin(), _layers.end(), i->get()->getUID() );
                if ( j != _layers.end() )
                    reordered.push_back( *j );
            }
            _layers.swap( reordered );
        }
    }

    unsigned layersDrawn = 0;

    // access the GL extensions interface for the current GC:
    const osg::Program::PerContextProgram* pcp = 0L;

#if OSG_MIN_VERSION_REQUIRED(3,3,3)
	osg::ref_ptr<osg::GLExtensions> ext;
#else
    osg::ref_ptr<osg::GL2Extensions> ext;
#endif
    unsigned contextID;

    if (_supportsGLSL)
    {
        contextID = state.getContextID();
#if OSG_MIN_VERSION_REQUIRED(3,3,3)
		ext = osg::GLExtensions::Get(contextID, true);
#else
		ext = osg::GL2Extensions::Get( contextID, true );
#endif
        pcp = state.getLastAppliedProgramObject();
    }

    // cannot store these in the object since there could be multiple GCs (and multiple
    // PerContextPrograms) at large
    GLint tileKeyLocation       = -1;
    GLint birthTimeLocation     = -1;
    GLint opacityLocation       = -1;
    GLint uidLocation           = -1;
    GLint orderLocation         = -1;
    GLint texMatParentLocation  = -1;
    GLint minRangeLocation      = -1;
    GLint maxRangeLocation      = -1;

    // The PCP can change (especially in a VirtualProgram environment). So we do need to
    // requery the uni locations each time unfortunately. TODO: explore optimizations.
    if ( pcp )
    {
        tileKeyLocation      = pcp->getUniformLocation( _tileKeyUniformNameID );
        birthTimeLocation    = pcp->getUniformLocation( _birthTimeUniformNameID );
        opacityLocation      = pcp->getUniformLocation( _opacityUniformNameID );
        uidLocation          = pcp->getUniformLocation( _uidUniformNameID );
        orderLocation        = pcp->getUniformLocation( _orderUniformNameID );
        texMatParentLocation = pcp->getUniformLocation( _texMatParentUniformNameID );
        minRangeLocation = pcp->getUniformLocation( _minRangeUniformNameID );
        maxRangeLocation = pcp->getUniformLocation( _maxRangeUniformNameID );
    }
    
    // apply the tilekey uniform once.
    if ( tileKeyLocation >= 0 )
    {
        ext->glUniform4fv( tileKeyLocation, 1, _tileKeyValue.ptr() );
    }

    // set the "birth time" - i.e. the time this tile last entered the scene in the current GC.
    if ( birthTimeLocation >= 0 )
    {
        PerContextData& pcd = _pcd[contextID];
        if ( pcd.birthTime < 0.0f )
        {
            const osg::FrameStamp* stamp = state.getFrameStamp();
            if ( stamp )
            {
                pcd.birthTime = stamp->getReferenceTime();
            }
        }
        ext->glUniform1f( birthTimeLocation, pcd.birthTime );
    }

    // activate the tile coordinate set - same for all layers
    if ( renderColor )
    {
        state.setTexCoordPointer( _imageUnit+1, _tileCoords.get() );
    }

#ifndef OSG_GLES2_AVAILABLE
    if ( renderColor )
    {
        // emit a default terrain color since we're not binding a color array:
        glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
    }
#endif

    // activate the elevation texture if there is one. Same for all layers.
    //if ( _elevTex.valid() )
    //{
    //    state.setActiveTextureUnit( 2 );
    //    state.setTexCoordPointer( 1, _tileCoords.get() ); // necessary?? since we do it above
    //    _elevTex->apply( state );
    //    // todo: probably need an elev texture matrix as well. -gw
    //}
    

    // track the active image unit.
    int activeImageUnit = -1;

    // remember whether we applied a parent texture.
    bool usedTexParent = false;

    if ( _layers.size() > 0 )
    {
        float prev_opacity        = -1.0f;

        // first bind any shared layers. We still have to do this even if we are
        // in !renderColor mode b/c these textures could be used by vertex shaders
        // to alter the geometry.
        int sharedLayers = 0;
        if ( pcp )
        {
            for(unsigned i=0; i<_layers.size(); ++i)
            {
                const Layer& layer = _layers[i];

                // a "shared" layer binds to a secondary texture unit so that other layers
                // can see it and use it.
                if ( layer._imageLayer->isShared() )
                {
                    ++sharedLayers;
                    int sharedUnit = layer._imageLayer->shareImageUnit().get();
                    {
                        state.setActiveTextureUnit( sharedUnit );

                        state.setTexCoordPointer( sharedUnit, layer._texCoords.get() );
                        // bind the texture for this layer to the active share unit.
                        layer._tex->apply( state );

                        // Shared layers need a texture matrix since the terrain engine doesn't
                        // provide a "current texture coordinate set" uniform (i.e. oe_layer_texc)
                        GLint texMatLocation = 0;
                        texMatLocation = pcp->getUniformLocation( layer._texMatUniformID );
                        if ( texMatLocation >= 0 )
                        {
                            ext->glUniformMatrix4fv( texMatLocation, 1, GL_FALSE, layer._texMat.ptr() );
                        }
                    }
                }
            }
        }
        if (renderColor)
        {
            // find the first opaque layer, top-down, and start there:
            unsigned first = 0;
            for(first = _layers.size()-1; first > 0; --first)
            {
                const Layer& layer = _layers[first];
                if (layer._opaque &&
                    //Color filters can modify the opacity
                    layer._imageLayer->getColorFilters().empty() &&
                    layer._imageLayer->getVisible() &&
                    layer._imageLayer->getOpacity() >= 1.0f)
                {
                    break;
                }
            }

            // interate over all the image layers
            for(unsigned i=first; i<_layers.size(); ++i)
            {
                const Layer& layer = _layers[i];

                if ( layer._imageLayer->getVisible() && layer._imageLayer->getOpacity() > 0.0f )
                {       
                    // activate the visible unit if necessary:
                    if ( activeImageUnit != _imageUnit )
                    {
                        state.setActiveTextureUnit( _imageUnit );
                        activeImageUnit = _imageUnit;
                    }

                    // bind the texture for this layer:
                    layer._tex->apply( state );

                    // in FFP mode, we need to enable the GL mode for texturing:
                    if ( !pcp ) //!_supportsGLSL)
                    {
                        state.applyMode(GL_TEXTURE_2D, true);
                    }

                    // if we're using a parent texture for blending, activate that now
                    if ( texMatParentLocation >= 0 && layer._texParent.valid() )
                    {
                        state.setActiveTextureUnit( _imageUnitParent );
                        activeImageUnit = _imageUnitParent;
                        layer._texParent->apply( state );
                        usedTexParent = true;
                    }

                    // bind the texture coordinates for this layer.
                    // TODO: can probably optimize this by sharing or using texture matrixes.
                    // State::setTexCoordPointer does some redundant work under the hood.
                    state.setTexCoordPointer( _imageUnit, layer._texCoords.get() );

                    // apply uniform values:
                    if ( pcp )
                    {
                        // apply opacity:
                        if ( opacityLocation >= 0 )
                        {
                            float opacity = layer._imageLayer->getOpacity();
                            if ( opacity != prev_opacity )
                            {
                                ext->glUniform1f( opacityLocation, (GLfloat)opacity );
                                prev_opacity = opacity;
                            }
                        }

                        // assign the layer UID:
                        if ( uidLocation >= 0 )
                        {
                            ext->glUniform1i( uidLocation, (GLint)layer._layerID );
                        }

                        // assign the layer order:
                        if ( orderLocation >= 0 )
                        {
                            ext->glUniform1i( orderLocation, (GLint)layersDrawn );
                        }

                        // assign the parent texture matrix
                        if ( texMatParentLocation >= 0 && layer._texParent.valid() )
                        {
                            ext->glUniformMatrix4fv( texMatParentLocation, 1, GL_FALSE, layer._texMatParent.ptr() );
                        }

                        // assign the min range
                        if ( minRangeLocation >= 0 )
                        {
                            ext->glUniform1f( minRangeLocation, layer._imageLayer->getImageLayerOptions().minVisibleRange().get() );
                        }

                        // assign the max range
                        if ( maxRangeLocation >= 0 )
                        {
                            ext->glUniform1f( maxRangeLocation, layer._imageLayer->getImageLayerOptions().maxVisibleRange().get() );
                        }
                    }

                    // draw the primitive sets.
                    for(unsigned int primitiveSetNum=0; primitiveSetNum!=_primitives.size(); ++primitiveSetNum)
                    {
                        const osg::PrimitiveSet* primitiveset = _primitives[primitiveSetNum].get();
                        if ( primitiveset )
                        {
                            primitiveset->draw(state, usingVBOs);
                        }
                        else
                        {
                            OE_WARN << LC << "Strange, MPGeometry had a 0L primset" << std::endl;
                        }
                    }

                    ++layersDrawn;
                }
            }
        }
    }

    // if we didn't draw anything, draw the raw tiles anyway with no texture.
    if ( layersDrawn == 0 )
    {
        if ( pcp )
        {
            if ( opacityLocation >= 0 )
                ext->glUniform1f( opacityLocation, (GLfloat)1.0f );
            if ( uidLocation >= 0 )
                ext->glUniform1i( uidLocation, (GLint)-1 );
            if ( orderLocation >= 0 )
                ext->glUniform1i( orderLocation, (GLint)0 );
        }

        // draw the primitives themselves.
        for(unsigned int primitiveSetNum=0; primitiveSetNum!=_primitives.size(); ++primitiveSetNum)
        {
            const osg::PrimitiveSet* primitiveset = _primitives[primitiveSetNum].get();
            primitiveset->draw(state, usingVBOs);
        }
    }

    else // at least one textured layer was drawn:
    {
        // prevent texture leakage
        // TODO: find a way to remove this to speed things up
        if ( renderColor )
        {
            glBindTexture( GL_TEXTURE_2D, 0 );

            // if a parent texture was applied, need to disable both.
            if ( usedTexParent )
            {
                state.setActiveTextureUnit(
                    activeImageUnit != _imageUnitParent ? _imageUnitParent :
                    _imageUnit );

                glBindTexture( GL_TEXTURE_2D, 0);
            }
        }
    }
}
Пример #30
0
void Shader::PerContextShader::compileShader(osg::State& state)
{
    if( ! _needsCompile ) return;
    _needsCompile = false;

#if defined(OSG_GLES2_AVAILABLE)
    if (_shader->getShaderBinary())
    {
        GLint numFormats = 0;
        glGetIntegerv(GL_NUM_SHADER_BINARY_FORMATS, &numFormats);

        if (numFormats>0)
        {
            std::vector<GLint> formats(numFormats);
            glGetIntegerv(GL_SHADER_BINARY_FORMATS, &formats[0]);

            for(GLint i=0; i<numFormats; ++i)
            {
                OSG_NOTICE<<"  format="<<formats[i]<<std::endl;
                GLenum shaderBinaryFormat = formats[i];
                glShaderBinary(1, &_glShaderHandle, shaderBinaryFormat, _shader->getShaderBinary()->getData(), _shader->getShaderBinary()->getSize());
                if (glGetError() == GL_NO_ERROR)
                {
                    _isCompiled = true;
                    return;
                }
            }

            if (_shader->getShaderSource().empty())
            {
                OSG_WARN<<"Warning: No suitable shader of supported format by GLES driver found in shader binary, unable to compile shader."<<std::endl;
                _isCompiled = false;
                return;
            }
            else
            {
                OSG_NOTICE<<"osg::Shader::compileShader(): No suitable shader of supported format by GLES driver found in shader binary, falling back to shader source."<<std::endl;
            }
        }
        else
        {
            if (_shader->getShaderSource().empty())
            {
                OSG_WARN<<"Warning: No shader binary formats supported by GLES driver, unable to compile shader."<<std::endl;
                _isCompiled = false;
                return;
            }
            else
            {
                OSG_NOTICE<<"osg::Shader::compileShader(): No shader binary formats supported by GLES driver, falling back to shader source."<<std::endl;
            }
        }
    }
#endif

    std::string source = _shader->getShaderSource();
    if (_shader->getType()==osg::Shader::VERTEX && (state.getUseVertexAttributeAliasing() || state.getUseModelViewAndProjectionUniforms()))
    {
        state.convertVertexShaderSourceToOsgBuiltIns(source);
    }


    if (osg::getNotifyLevel()>=osg::INFO)
    {
        std::string sourceWithLineNumbers = insertLineNumbers(source);
        OSG_INFO << "\nCompiling " << _shader->getTypename()
                 << " source:\n" << sourceWithLineNumbers << std::endl;
    }

    GLint compiled = GL_FALSE;
    const GLchar* sourceText = reinterpret_cast<const GLchar*>(source.c_str());
    _extensions->glShaderSource( _glShaderHandle, 1, &sourceText, NULL );
    _extensions->glCompileShader( _glShaderHandle );
    _extensions->glGetShaderiv( _glShaderHandle, GL_COMPILE_STATUS, &compiled );

    _isCompiled = (compiled == GL_TRUE);
    if( ! _isCompiled )
    {
        OSG_WARN << _shader->getTypename() << " glCompileShader \""
            << _shader->getName() << "\" FAILED" << std::endl;

        std::string infoLog;
        if( getInfoLog(infoLog) )
        {
            OSG_WARN << _shader->getTypename() << " Shader \""
                << _shader->getName() << "\" infolog:\n" << infoLog << std::endl;
        }
    }
    else
    {
        std::string infoLog;
        if( getInfoLog(infoLog) )
        {
            OSG_INFO << _shader->getTypename() << " Shader \""
                << _shader->getName() << "\" infolog:\n" << infoLog << std::endl;
        }
    }

}