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 ); }
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); } }
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); }
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); }
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)); }
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()))); }
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 ); }
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()); }
// 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; }
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; } }
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); }
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 }
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() ); }
void DepthPeelBin::drawComplete( osg::State& state, unsigned int insertStateSetPosition ) { TRACEDUMP("DepthPeelBin::drawComplete"); if (_stateset.valid()) { state.removeStateSet(insertStateSetPosition); // state.apply(); } }
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; }
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); }
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); } } } }
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; }
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(); } }
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); // } }
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); } }
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); } } }
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); }
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()); } } }
// 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; }
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); }
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); } } } }
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; } } }