void RenderBin::drawImplementation(osg::RenderInfo& renderInfo,RenderLeaf*& previous) { osg::State& state = *renderInfo.getState(); // OSG_NOTICE<<"begin RenderBin::drawImplementation "<<className()<<" sortMode "<<getSortMode()<<std::endl; unsigned int numToPop = (previous ? StateGraph::numToPop(previous->_parent) : 0); if (numToPop>1) --numToPop; unsigned int insertStateSetPosition = state.getStateSetStackSize() - numToPop; if (_stateset.valid()) { state.insertStateSet(insertStateSetPosition, _stateset.get()); } // draw first set of draw bins. RenderBinList::iterator rbitr; for(rbitr = _bins.begin(); rbitr!=_bins.end() && rbitr->first<0; ++rbitr) { rbitr->second->draw(renderInfo,previous); } // draw fine grained ordering. for(RenderLeafList::iterator rlitr= _renderLeafList.begin(); rlitr!= _renderLeafList.end(); ++rlitr) { RenderLeaf* rl = *rlitr; rl->render(renderInfo,previous); previous = rl; } bool draw_forward = true; //(_sortMode!=SORT_BY_STATE) || (state.getFrameStamp()->getFrameNumber() % 2)==0; // draw coarse grained ordering. if (draw_forward) { for(StateGraphList::iterator oitr=_stateGraphList.begin(); oitr!=_stateGraphList.end(); ++oitr) { for(StateGraph::LeafList::iterator dw_itr = (*oitr)->_leaves.begin(); dw_itr != (*oitr)->_leaves.end(); ++dw_itr) { RenderLeaf* rl = dw_itr->get(); rl->render(renderInfo,previous); previous = rl; } } } else { for(StateGraphList::reverse_iterator oitr=_stateGraphList.rbegin(); oitr!=_stateGraphList.rend(); ++oitr) { for(StateGraph::LeafList::iterator dw_itr = (*oitr)->_leaves.begin(); dw_itr != (*oitr)->_leaves.end(); ++dw_itr) { RenderLeaf* rl = dw_itr->get(); rl->render(renderInfo,previous); previous = rl; } } } // draw post bins. for(; rbitr!=_bins.end(); ++rbitr) { rbitr->second->draw(renderInfo,previous); } if (_stateset.valid()) { state.removeStateSet(insertStateSetPosition); // state.apply(); } // OSG_NOTICE<<"end RenderBin::drawImplementation "<<className()<<std::endl; }
void TileDrawable::drawVertexArraysImplementation(osg::RenderInfo& renderInfo) const { State& state = *renderInfo.getState(); bool handleVertexAttributes = !_geom->getVertexAttribArrayList().empty(); //bool handleVertexAttributes = !_vertexAttribList.empty(); ArrayDispatchers& arrayDispatchers = state.getArrayDispatchers(); arrayDispatchers.reset(); arrayDispatchers.setUseVertexAttribAlias(state.getUseVertexAttributeAliasing()); arrayDispatchers.setUseGLBeginEndAdapter(false); arrayDispatchers.activateNormalArray(_geom->getNormalBinding(), _geom->getNormalArray(), _geom->getNormalIndices()); arrayDispatchers.activateColorArray(_geom->getColorBinding(), _geom->getColorArray(), _geom->getColorIndices()); arrayDispatchers.activateSecondaryColorArray(_geom->getSecondaryColorBinding(), _geom->getSecondaryColorArray(), _geom->getSecondaryColorIndices()); arrayDispatchers.activateFogCoordArray(_geom->getFogCoordBinding(), _geom->getFogCoordArray(), _geom->getFogCoordIndices()); if (handleVertexAttributes) { for(unsigned int unit=0;unit < _geom->getVertexAttribArrayList().size();++unit) { const osg::Geometry::ArrayData& val = _geom->getVertexAttribArrayList()[unit]; arrayDispatchers.activateVertexAttribArray(val.binding, unit, val.array.get(), val.indices.get()); } } // dispatch any attributes that are bound overall arrayDispatchers.dispatch(_geom->BIND_OVERALL, 0); state.lazyDisablingOfVertexAttributes(); // set up arrays if( _geom->getVertexArray() ) state.setVertexPointer(_geom->getVertexArray()); //_vertexData.array.get()); if (_geom->getNormalBinding()==_geom->BIND_PER_VERTEX && _geom->getNormalArray()) state.setNormalPointer(_geom->getNormalArray()); if (_geom->getColorBinding()==_geom->BIND_PER_VERTEX && _geom->getColorArray()) state.setColorPointer(_geom->getColorArray()); if (_geom->getSecondaryColorBinding()==_geom->BIND_PER_VERTEX && _geom->getSecondaryColorArray()) state.setSecondaryColorPointer(_geom->getSecondaryColorArray()); if (_geom->getFogCoordBinding()==_geom->BIND_PER_VERTEX && _geom->getFogCoordArray()) state.setFogCoordPointer(_geom->getFogCoordArray()); for(unsigned int unit=0;unit<_geom->getTexCoordArrayList().size();++unit) { const Array* array = _geom->getTexCoordArray(unit); if (array) { state.setTexCoordPointer(unit,array); } } if ( handleVertexAttributes ) { for(unsigned int index = 0; index < _geom->getVertexAttribArrayList().size(); ++index) { const osg::Array* array = _geom->getVertexAttribArray(index); if ( array && _geom->getVertexAttribBinding(index) == _geom->BIND_PER_VERTEX ) { if (array->getPreserveDataType()) { GLenum dataType = array->getDataType(); if (dataType==GL_FLOAT) state.setVertexAttribPointer( index, array, GL_FALSE ); else if (dataType==GL_DOUBLE) state.setVertexAttribLPointer( index, array ); else state.setVertexAttribIPointer( index, array ); } else { state.setVertexAttribPointer( index, array, GL_FALSE ); } } } } state.applyDisablingOfVertexAttributes(); }
void TileDrawable::drawSurface(osg::RenderInfo& renderInfo) const { unsigned layersDrawn = 0; osg::State& state = *renderInfo.getState(); // 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(); } // safely latch if ( _geom->getNumPrimitiveSets() < 1 ) return; // cannot store these in the object since there could be multiple GCs (and multiple // PerContextPrograms) at large GLint opacityLocation = -1; GLint uidLocation = -1; GLint orderLocation = -1; GLint texMatrixLocation = -1; GLint texMatrixParentLocation = -1; GLint texParentExistsLocation = -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 ) { opacityLocation = pcp->getUniformLocation( _opacityUniformNameID ); uidLocation = pcp->getUniformLocation( _uidUniformNameID ); orderLocation = pcp->getUniformLocation( _orderUniformNameID ); texMatrixLocation = pcp->getUniformLocation( _texMatrixUniformNameID ); texMatrixParentLocation = pcp->getUniformLocation( _texMatrixParentUniformNameID ); texParentExistsLocation = pcp->getUniformLocation( _texParentExistsUniformNameID ); } float prevOpacity = -1.0f; if ( _mptex.valid() && !_mptex->getPasses().empty() ) { float prevOpacity = -1.0f; // in FFP mode, we need to enable the GL mode for texturing: if ( !pcp ) state.applyMode(GL_TEXTURE_2D, true); optional<bool> texParentExists_lastValue; for(MPTexture::Passes::const_iterator p = _mptex->getPasses().begin(); p != _mptex->getPasses().end(); ++p) { const MPTexture::Pass& pass = *p; if ( pass._layer->getVisible() && pass._layer->getOpacity() > 0.1 ) { // Apply the texture. state.setActiveTextureUnit( _textureImageUnit ); const osg::StateAttribute* lastTex = state.getLastAppliedTextureAttribute(_textureImageUnit, osg::StateAttribute::TEXTURE); if ( lastTex != pass._texture.get() ) pass._texture->apply( state ); // Apply the texture matrix. ext->glUniformMatrix4fv( texMatrixLocation, 1, GL_FALSE, pass._textureMatrix.ptr() ); bool texParentExists = pass._parentTexture.valid(); if ( texParentExists ) { // Apply the parent texture. state.setActiveTextureUnit( _textureParentImageUnit ); const osg::StateAttribute* lastTex = state.getLastAppliedTextureAttribute(_textureParentImageUnit, osg::StateAttribute::TEXTURE); if ( lastTex != pass._parentTexture.get() ) pass._parentTexture->apply( state ); // Apply the parent texture matrix. ext->glUniformMatrix4fv( texMatrixParentLocation, 1, GL_FALSE, pass._parentTextureMatrix.ptr() ); } if ( !texParentExists_lastValue.isSetTo(texParentExists) ) { texParentExists_lastValue = texParentExists; ext->glUniform1f( texParentExistsLocation, texParentExists? 1.0f : 0.0f ); } // Order uniform (TODO: evaluate whether we still need this) if ( orderLocation >= 0 ) { ext->glUniform1i( orderLocation, (GLint)layersDrawn ); } // assign the layer UID: if ( uidLocation >= 0 ) { ext->glUniform1i( uidLocation, (GLint)pass._layer->getUID() ); } // apply opacity: if ( opacityLocation >= 0 ) { float opacity = pass._layer->getOpacity(); if ( opacity != prevOpacity ) { ext->glUniform1f( opacityLocation, (GLfloat)opacity ); prevOpacity = opacity; } } _geom->getPrimitiveSet(0)->draw(state, true); ++layersDrawn; } } } // No mptex or no layers in the mptex? Draw simple. if ( layersDrawn == 0 ) { 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 ); _geom->getPrimitiveSet(0)->draw(state, true); } }
void FadeText::drawImplementation(osg::RenderInfo &renderInfo) const { osg::State &state = *renderInfo.getState(); ViewBlendColourMap::iterator itr = _viewBlendColourMap.find(renderInfo.getView()); if (itr != _viewBlendColourMap.end()) { Text::drawImplementation(*renderInfo.getState(), itr->second); } else { Text::drawImplementation(*renderInfo.getState(), osg::Vec4(1.0f, 1.0f, 1.0f, 1.0f)); } // now pass on new details FadeTextUserData *userData = dynamic_cast<FadeTextUserData*>(renderInfo.getUserData()); if (!userData) { if (renderInfo.getUserData()) { OSG_NOTICE << "Warning user data not of supported type." << std::endl; return; } userData = getGlobalFadeText()->createNewFadeTextUserData(renderInfo.getView()); if (!userData) { OSG_NOTICE << "Memory error, unable to create FadeTextUserData." << std::endl; return; } renderInfo.setUserData(userData); } unsigned int frameNumber = renderInfo.getState()->getFrameStamp()->getFrameNumber(); if (frameNumber != userData->_frameNumber) { // new frame so must reset UserData structure. userData->_frameNumber = frameNumber; userData->_fadeTextInView.clear(); } osgText::Text::AutoTransformCache &atc = _autoTransformCache[renderInfo.getContextID()]; osg::Matrix lmv = atc._matrix; lmv.postMult(state.getModelViewMatrix()); if (renderInfo.getView() && renderInfo.getView()->getCamera()) { // move from camera into the view space. lmv.postMult(state.getInitialInverseViewMatrix()); lmv.postMult(renderInfo.getView()->getCamera()->getViewMatrix()); } FadeTextData ftd(const_cast<osgText::FadeText*>(this)); ftd._vertices[0].set(osg::Vec3d(_textBB.xMin(), _textBB.yMin(), _textBB.zMin()) * lmv); ftd._vertices[1].set(osg::Vec3d(_textBB.xMax(), _textBB.yMin(), _textBB.zMin()) * lmv); ftd._vertices[2].set(osg::Vec3d(_textBB.xMax(), _textBB.yMax(), _textBB.zMin()) * lmv); ftd._vertices[3].set(osg::Vec3d(_textBB.xMin(), _textBB.yMax(), _textBB.zMin()) * lmv); userData->_fadeTextInView.push_back(ftd); }
void TileDrawable::drawVertexArraysImplementation(osg::RenderInfo& renderInfo) const { if ( !_geom.valid() ) return; State& state = *renderInfo.getState(); bool handleVertexAttributes = !_geom->getVertexAttribArrayList().empty(); ArrayDispatchers& arrayDispatchers = state.getArrayDispatchers(); arrayDispatchers.reset(); arrayDispatchers.setUseVertexAttribAlias(state.getUseVertexAttributeAliasing()); arrayDispatchers.activateNormalArray(_geom->getNormalArray()); arrayDispatchers.activateColorArray(_geom->getColorArray()); arrayDispatchers.activateSecondaryColorArray(_geom->getSecondaryColorArray()); arrayDispatchers.activateFogCoordArray(_geom->getFogCoordArray()); if (handleVertexAttributes) { for(unsigned int unit=0;unit<_geom->getVertexAttribArrayList().size();++unit) { arrayDispatchers.activateVertexAttribArray(unit, _geom->getVertexAttribArray(unit)); } } // dispatch any attributes that are bound overall arrayDispatchers.dispatch(osg::Array::BIND_OVERALL,0); state.lazyDisablingOfVertexAttributes(); // set up arrays if( _geom->getVertexArray() ) state.setVertexPointer(_geom->getVertexArray()); if (_geom->getNormalArray() && _geom->getNormalArray()->getBinding()==osg::Array::BIND_PER_VERTEX) state.setNormalPointer(_geom->getNormalArray()); if (_geom->getColorArray() && _geom->getColorArray()->getBinding()==osg::Array::BIND_PER_VERTEX) state.setColorPointer(_geom->getColorArray()); if (_geom->getSecondaryColorArray() && _geom->getSecondaryColorArray()->getBinding()==osg::Array::BIND_PER_VERTEX) state.setSecondaryColorPointer(_geom->getSecondaryColorArray()); if (_geom->getFogCoordArray() && _geom->getFogCoordArray()->getBinding()==osg::Array::BIND_PER_VERTEX) state.setFogCoordPointer(_geom->getFogCoordArray()); for(unsigned int unit=0;unit<_geom->getTexCoordArrayList().size();++unit) { const Array* array = _geom->getTexCoordArray(unit); if (array) { state.setTexCoordPointer(unit,array); } } if ( handleVertexAttributes ) { for(unsigned int index = 0; index < _geom->getVertexAttribArrayList().size(); ++index) { const Array* array = _geom->getVertexAttribArray(index); if (array && array->getBinding()==osg::Array::BIND_PER_VERTEX) { if (array->getPreserveDataType()) { GLenum dataType = array->getDataType(); if (dataType==GL_FLOAT) state.setVertexAttribPointer( index, array ); else if (dataType==GL_DOUBLE) state.setVertexAttribLPointer( index, array ); else state.setVertexAttribIPointer( index, array ); } else { state.setVertexAttribPointer( index, array ); } } } } state.applyDisablingOfVertexAttributes(); }
void CameraResetCallback::operator()( osg::RenderInfo& renderInfo ) const { osg::Camera* cam = renderInfo.getCurrentCamera(); unsigned int contextID = renderInfo.getState()->getContextID(); QueryComputation::setCscrOi( 0., cam, contextID ); }
void ScreenTexture::drawImplementation( osg::RenderInfo & renderInfo ) const { if (!_isNeededValidation) return; _isNeededValidation = false; osg::State & state = *renderInfo.getState(); const osg::Viewport * viewport = state.getCurrentViewport(); #if defined(_SCREEN_TEXTURE_DEBUG_) const unsigned texunit = state.getActiveTextureUnit(); state.setActiveTextureUnit(0); #endif // _SCREEN_TEXTURE_DEBUG_ // instead of doing copyTexImage we would do FBO blit operation to ensure it correctly handles multisampled FBO // get fbo extension which provides us with the glGenerateMipmapEXT function #if OSG_MIN_VERSION_REQUIRED(3,3,2) osg::GLExtensions * fbo_ext = renderInfo.getState()->get<osg::GLExtensions>(); #else osg::FBOExtensions * fbo_ext = osg::FBOExtensions::instance(state.getContextID(), true); #endif // get current draw binding GLint oldDrawFBO = 0; glGetIntegerv(GL_DRAW_FRAMEBUFFER_BINDING_EXT, &oldDrawFBO); // recreate FBO, is sizes were changed if (viewport->width() != _texture->getTextureWidth() || viewport->height() != _texture->getTextureHeight()) { //_resolveFbo = new osg::FrameBufferObject(); _texture->dirtyTextureObject(); _texture->setTextureSize(viewport->width(), viewport->height()); if (_blitBitMask == GL_DEPTH_BUFFER_BIT) { _resolveFbo->setAttachment(osg::Camera::DEPTH_BUFFER, osg::FrameBufferAttachment(_texture)); _resolveFbo->setAttachment(osg::Camera::COLOR_BUFFER, osg::FrameBufferAttachment(new osg::RenderBuffer(viewport->width(), viewport->height(), GL_RGB))); } else if (_blitBitMask == GL_COLOR_BUFFER_BIT) { _resolveFbo->setAttachment(osg::Camera::COLOR_BUFFER, osg::FrameBufferAttachment(_texture)); } } // apply resolve FBO for blit operation _resolveFbo->apply(state, osg::FrameBufferObject::DRAW_FRAMEBUFFER); #if defined(_SCREEN_TEXTURE_DEBUG_) GLenum status = fbo_ext->glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT); if (status != GL_FRAMEBUFFER_COMPLETE_EXT) OutputDebugString("\nCannot create FBO for texture blitting\n"); #endif // _SCREEN_TEXTURE_DEBUG_ // blit to the resolve framebuffer. fbo_ext->glBlitFramebuffer( 0, 0, static_cast<GLint>(viewport->width()), static_cast<GLint>(viewport->height()), 0, 0, static_cast<GLint>(viewport->width()), static_cast<GLint>(viewport->height()), _blitBitMask, GL_NEAREST); // restore old draw framebuffer fbo_ext->glBindFramebuffer(osg::FrameBufferObject::DRAW_FRAMEBUFFER, oldDrawFBO); // get depth settings if (_settings.valid()) { const osg::Matrix & projection = state.getProjectionMatrix(); const float znear = projection(3, 2) / (projection(2, 2) - 1.0), zfar = projection(3, 2) / (1.0 + projection(2, 2)); //double left, right, bottom, top, znear, zfar; //state.getProjectionMatrix().getFrustum(left, right, bottom, top, znear, zfar); const osg::Vec2f settings = osg::Vec2f((zfar - znear) / (zfar * znear), -1.0 / znear); _settings->set(settings); } #if defined(_SCREEN_TEXTURE_DEBUG_) glPushAttrib(GL_LIGHTING_BIT); glDisable(GL_LIGHTING); glMatrixMode(GL_PROJECTION); glPushMatrix(); glLoadIdentity(); glEnable(GL_TEXTURE_RECTANGLE); glColor4f(1.0f, 1.0f, 1.0f, 1.0f); glBegin(GL_QUADS); glTexCoord2f(0.0f, 0.0f); glVertex2f(0.0f, 0.0f); glTexCoord2f(viewport->width(), 0.0f); glVertex2f(1.0f, 0.0f); glTexCoord2f(viewport->width(), viewport->height()); glVertex2f(1.0f, 1.0f); glTexCoord2f(0.0f, viewport->height()); glVertex2f(0.0f, 1.0f); glEnd(); glDisable(GL_TEXTURE_RECTANGLE); glPopMatrix(); glMatrixMode(GL_MODELVIEW); glPopAttrib(); state.setActiveTextureUnit(texunit); state.checkGLErrors("ScreenTexture"); #endif // _SCREEN_TEXTURE_DEBUG_ }
void ScreenInterlacedTopBottom::InterlaceCallback::operator()( osg::RenderInfo &renderInfo) const { int context = renderInfo.getContextID(); const osg::GL2Extensions* extensions = osg::GL2Extensions::Get(context, true); //osg::FBOExtensions* ext = osg::FBOExtensions::instance(context,true); //ext->glBindFramebuffer(osg::FrameBufferObject::READ_DRAW_FRAMEBUFFER, 0); //glColorMask(true,true,true,true); //osgDB::writeImageFile(*screen->image,"/home/aprudhom/testImage.tif"); //exit(0); //glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); //glFinish(); //return; /*if(skip) { //screen->_camera->setClearColor(osg::Vec4(1.0,0,0,0)); skip = false; return; } else { //screen->_camera->setClearColor(osg::Vec4(0,1.0,0,0)); skip = true; }*/ if(first) { glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); } //glPushAttrib(GL_ALL_ATTRIB_BITS); //std::cerr << "Callback." << std::endl; if(!_initMap[context]) { OpenThreads::ScopedLock < OpenThreads::Mutex > lock(_initLock); std::string shaderdir = CalVR::instance()->getResourceDir() + "/shaders/"; osg::Shader * vert, *frag; if(odd) { vert = osg::Shader::readShaderFile(osg::Shader::VERTEX, osgDB::findDataFile(shaderdir + "interlace.vert")); frag = osg::Shader::readShaderFile(osg::Shader::FRAGMENT, osgDB::findDataFile(shaderdir + "interlace-odd.frag")); } else { vert = osg::Shader::readShaderFile(osg::Shader::VERTEX, osgDB::findDataFile(shaderdir + "interlace.vert")); frag = osg::Shader::readShaderFile(osg::Shader::FRAGMENT, osgDB::findDataFile(shaderdir + "interlace-even.frag")); } _programMap[context] = new osg::Program; _programMap[context]->addShader(vert); _programMap[context]->addShader(frag); _geometryMap[context] = new osg::Geometry(); osg::DrawArrays * quad = new osg::DrawArrays( osg::PrimitiveSet::TRIANGLE_STRIP,0,0); osg::Vec2Array * verts = new osg::Vec2Array(0); _geometryMap[context]->setVertexArray(verts); _geometryMap[context]->addPrimitiveSet(quad); verts->push_back(osg::Vec2(-1.0,1.0)); verts->push_back(osg::Vec2(-1.0,-1.0)); verts->push_back(osg::Vec2(1.0,1.0)); verts->push_back(osg::Vec2(1.0,-1.0)); _geometryMap[context]->setUseDisplayList(false); quad->setCount(4); /*glGenBuffers(1,&_arrayMap[context]); glBindBuffer(GL_ARRAY_BUFFER, arrayMap[context]); float points[8] = {-1.0, 1.0, -1.0, -1.0, 1.0, 1.0, 1.0, -1.0}; glBufferData(GL_ARRAY_BUFFER, 8 * sizeof(float), points, GL_STATIC_DRAW); glBindBuffer(GL_ARRAY_BUFFER, 0);*/ _initMap[context] = true; } glViewport((int)screen->_myInfo->myChannel->left, (int)screen->_myInfo->myChannel->bottom, (int)screen->_myInfo->myChannel->width, (int)screen->_myInfo->myChannel->height); glMatrixMode(GL_MODELVIEW); glPushMatrix(); glLoadIdentity(); glMatrixMode(GL_PROJECTION); glPushMatrix(); glLoadIdentity(); //GLint activeTexture,bindtex; //glGetIntegerv(GL_ACTIVE_TEXTURE,&activeTexture); unsigned int activeTexture = renderInfo.getState()->getActiveTextureUnit(); osg::Texture::TextureObject * to = _texture->getTextureObject(context); renderInfo.getState()->setActiveTextureUnit(0); //glActiveTexture(GL_TEXTURE0); //glGetIntegerv(GL_TEXTURE_BINDING_2D,&bindtex); if(to) { to->bind(); } //_texture->apply(*renderInfo.getState()); _programMap[context]->apply(*renderInfo.getState()); _geometryMap[context]->drawImplementation(renderInfo); //glBindTexture(GL_TEXTURE_2D,bindtex); extensions->glUseProgram(0); renderInfo.getState()->setLastAppliedProgramObject(0); renderInfo.getState()->setActiveTextureUnit(activeTexture); //glActiveTexture(activeTexture); /*glBegin(GL_TRIANGLE_STRIP); glColor3f(1.0,0.0,0.0); glVertex2f(-1.0,1.0); glVertex2f(-1.0,-1.0); glVertex2f(1.0,1.0); glVertex2f(1.0,-1.0); glEnd();*/ glPopMatrix(); glMatrixMode(GL_MODELVIEW); glPopMatrix(); //glPopAttrib(); }
void LightPointSpriteDrawable::drawImplementation(osg::RenderInfo& renderInfo) const { #if !defined(OSG_GLES1_AVAILABLE) && !defined(OSG_GLES2_AVAILABLE) && !defined(OSG_GL3_AVAILABLE) osg::State& state = *renderInfo.getState(); if (!state.getModeValidity(GL_POINT_SPRITE_ARB)) { LightPointDrawable::drawImplementation(renderInfo); return; } state.applyMode(GL_POINT_SMOOTH,true); state.applyMode(GL_BLEND,true); state.applyMode(GL_LIGHTING,false); state.applyTextureMode(0,GL_TEXTURE_2D,true); state.applyTextureMode(1,GL_TEXTURE_2D,false); state.applyMode(GL_POINT_SPRITE_ARB,true); state.applyTextureAttribute(0,_sprite.get()); // Assume the point sprite texture map is already specified // (typically in the owning LightPointNode StateSet). glHint(GL_POINT_SMOOTH_HINT,GL_NICEST); state.applyAttribute(_depthOn.get()); state.applyAttribute(_blendOneMinusSrcAlpha.get()); state.applyMode(GL_POINT_SMOOTH,true); SizedLightPointList::const_iterator sitr; unsigned int pointsize; for(pointsize=1,sitr=_sizedOpaqueLightPointList.begin(); sitr!=_sizedOpaqueLightPointList.end(); ++sitr,++pointsize) { const LightPointList& lpl = *sitr; if (!lpl.empty()) { glPointSize(pointsize); //glInterleavedArrays(GL_C4UB_V3F,0,&lpl.front()); state.setInterleavedArrays(GL_C4UB_V3F,0,&lpl.front()); glDrawArrays(GL_POINTS,0,lpl.size()); } } state.applyMode(GL_BLEND,true); state.applyAttribute(_depthOff.get()); state.applyAttribute(_blendOneMinusSrcAlpha.get()); for(pointsize=1,sitr=_sizedBlendedLightPointList.begin(); sitr!=_sizedBlendedLightPointList.end(); ++sitr,++pointsize) { const LightPointList& lpl = *sitr; if (!lpl.empty()) { glPointSize(pointsize); //glInterleavedArrays(GL_C4UB_V3F,0,&lpl.front()); state.setInterleavedArrays(GL_C4UB_V3F,0,&lpl.front()); glDrawArrays(GL_POINTS,0,lpl.size()); } } state.applyAttribute(_blendOne.get()); for(pointsize=1,sitr=_sizedAdditiveLightPointList.begin(); sitr!=_sizedAdditiveLightPointList.end(); ++sitr,++pointsize) { const LightPointList& lpl = *sitr; if (!lpl.empty()) { //state.applyMode(GL_POINT_SMOOTH,pointsize!=1); glPointSize(pointsize); //glInterleavedArrays(GL_C4UB_V3F,0,&lpl.front()); state.setInterleavedArrays(GL_C4UB_V3F,0,&lpl.front()); glDrawArrays(GL_POINTS,0,lpl.size()); } } glPointSize(1); glHint(GL_POINT_SMOOTH_HINT,GL_FASTEST); state.haveAppliedAttribute(osg::StateAttribute::POINT); state.dirtyAllVertexArrays(); state.disableAllVertexArrays(); // restore the state afterwards. state.apply(); #else OSG_NOTICE<<"Warning: LightPointDrawable not supported."<<std::endl; #endif }
void PrecipitationEffect::PrecipitationDrawable::drawImplementation(osg::RenderInfo& renderInfo) const { #if defined(OSG_GL_MATRICES_AVAILABLE) if (!_geometry) return; const osg::GLExtensions* extensions = renderInfo.getState()->get<osg::GLExtensions>(); // save OpenGL matrices glPushMatrix(); if (_requiresPreviousMatrix) { renderInfo.getState()->setActiveTextureUnit(0); glMatrixMode( GL_TEXTURE ); glPushMatrix(); } typedef std::vector<const CellMatrixMap::value_type*> DepthMatrixStartTimeVector; DepthMatrixStartTimeVector orderedEntries; orderedEntries.reserve(_currentCellMatrixMap.size()); for(CellMatrixMap::const_iterator citr = _currentCellMatrixMap.begin(); citr != _currentCellMatrixMap.end(); ++citr) { orderedEntries.push_back(&(*citr)); } std::sort(orderedEntries.begin(),orderedEntries.end(),LessFunctor()); for(DepthMatrixStartTimeVector::reverse_iterator itr = orderedEntries.rbegin(); itr != orderedEntries.rend(); ++itr) { extensions->glMultiTexCoord1f(GL_TEXTURE0+1, (*itr)->second.startTime); // load cells current modelview matrix if (_requiresPreviousMatrix) { glMatrixMode( GL_MODELVIEW ); glLoadMatrix((*itr)->second.modelview.ptr()); CellMatrixMap::const_iterator pitr = _previousCellMatrixMap.find((*itr)->first); if (pitr != _previousCellMatrixMap.end()) { // load previous frame modelview matrix for motion blurr effect glMatrixMode( GL_TEXTURE ); glLoadMatrix(pitr->second.modelview.ptr()); } else { // use current modelview matrix as "previous" frame value, cancelling motion blurr effect glMatrixMode( GL_TEXTURE ); glLoadMatrix((*itr)->second.modelview.ptr()); } } else { glLoadMatrix((*itr)->second.modelview.ptr()); } _geometry->draw(renderInfo); unsigned int numVertices = osg::minimum(_geometry->getVertexArray()->getNumElements(), _numberOfVertices); glDrawArrays(_drawType, 0, numVertices); } // restore OpenGL matrices if (_requiresPreviousMatrix) { glPopMatrix(); glMatrixMode( GL_MODELVIEW ); } glPopMatrix(); #else OSG_NOTICE<<"Warning: ParticleEffect::drawImplementation(..) not fully implemented."<<std::endl; #endif }
void PrecipitationEffect::compileGLObjects(osg::RenderInfo& renderInfo) const { if (_quadGeometry.valid()) { _quadGeometry->compileGLObjects(renderInfo); if (_quadGeometry->getStateSet()) _quadGeometry->getStateSet()->compileGLObjects(*renderInfo.getState()); } if (_lineGeometry.valid()) { _lineGeometry->compileGLObjects(renderInfo); if (_lineGeometry->getStateSet()) _lineGeometry->getStateSet()->compileGLObjects(*renderInfo.getState()); } if (_pointGeometry.valid()) { _pointGeometry->compileGLObjects(renderInfo); if (_pointGeometry->getStateSet()) _pointGeometry->getStateSet()->compileGLObjects(*renderInfo.getState()); } }
void RenderStageEx::drawInner(osg::RenderInfo &renderInfo, osgUtil::RenderLeaf *&previous, bool &doCopyTexture) { struct SubFunc { static void applyReadFBO(bool& apply_read_fbo, const FrameBufferObject* read_fbo, osg::State& state) { if (read_fbo->isMultisample()) { OSG_WARN << "Attempting to read from a" " multisampled framebuffer object. Set a resolve" " framebuffer on the RenderStage to fix this." << std::endl; } if (apply_read_fbo) { // Bind the monosampled FBO to read from read_fbo->apply(state, FrameBufferObject::READ_FRAMEBUFFER); apply_read_fbo = false; } } }; osg::State& state = *renderInfo.getState(); #if 1 #if OSG_MIN_VERSION_REQUIRED(3,3,7) osg::GLExtensions* fbo_ext = state.get<osg::GLExtensions>(); bool fbo_supported = fbo_ext && fbo_ext->isFrameBufferObjectSupported; bool using_multiple_render_targets = fbo_supported && _fbo.valid() && _fbo->hasMultipleRenderingTargets(); #else osg::FBOExtensions* fbo_ext = osg::FBOExtensions::instance(state.getContextID(), true); bool fbo_supported = fbo_ext && fbo_ext->isSupported(); bool using_multiple_render_targets = fbo_supported && _fbo.valid() && _fbo->hasMultipleRenderingTargets(); #endif if (fbo_supported) { if(_fbo.valid()) { if (!_fbo->hasMultipleRenderingTargets()) { #if !defined(OSG_GLES1_AVAILABLE) && !defined(OSG_GLES2_AVAILABLE) if( getDrawBufferApplyMask() ) glDrawBuffer(_drawBuffer); if( getReadBufferApplyMask() ) glReadBuffer(_readBuffer); #endif } _fbo->apply(state); } else { fbo_ext->glBindFramebuffer(osg::FrameBufferObject::READ_DRAW_FRAMEBUFFER, static_cast<StateEx *>(&state)->getDefaultFbo()); } } #else osg::FBOExtensions* fbo_ext = _fbo.valid() ? osg::FBOExtensions::instance(state.getContextID(),true) : 0; bool fbo_supported = fbo_ext && fbo_ext->isSupported(); bool using_multiple_render_targets = fbo_supported && _fbo->hasMultipleRenderingTargets(); if (!using_multiple_render_targets) { #if !defined(OSG_GLES1_AVAILABLE) && !defined(OSG_GLES2_AVAILABLE) if( getDrawBufferApplyMask() ) glDrawBuffer(_drawBuffer); if( getReadBufferApplyMask() ) glReadBuffer(_readBuffer); #endif } if (fbo_supported) { _fbo->apply(state); } #endif // GLint fboId; // glGetIntegerv(GL_DRAW_FRAMEBUFFER_BINDING_EXT, &fboId); // std::cout << fboId << std::endl; RenderBin::draw(renderInfo,previous); if(state.getCheckForGLErrors()!=osg::State::NEVER_CHECK_GL_ERRORS) { if (state.checkGLErrors("after RenderBin::draw(..)")) { if ( fbo_ext ) { GLenum fbstatus = fbo_ext->glCheckFramebufferStatus(GL_FRAMEBUFFER_EXT); if ( fbstatus != GL_FRAMEBUFFER_COMPLETE_EXT ) { OSG_NOTICE<<"RenderStage::drawInner(,) FBO status = 0x"<<std::hex<<fbstatus<<std::dec<<std::endl; } } } } const FrameBufferObject* read_fbo = fbo_supported ? _fbo.get() : 0; bool apply_read_fbo = false; if (fbo_supported && _resolveFbo.valid() && fbo_ext->glBlitFramebuffer) { GLbitfield blitMask = 0; bool needToBlitColorBuffers = false; //find which buffer types should be copied for (FrameBufferObject::AttachmentMap::const_iterator it = _resolveFbo->getAttachmentMap().begin(), end =_resolveFbo->getAttachmentMap().end(); it != end; ++it) { switch (it->first) { case Camera::DEPTH_BUFFER: blitMask |= GL_DEPTH_BUFFER_BIT; break; case Camera::STENCIL_BUFFER: blitMask |= GL_STENCIL_BUFFER_BIT; break; case Camera::PACKED_DEPTH_STENCIL_BUFFER: blitMask |= GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT; break; case Camera::COLOR_BUFFER: blitMask |= GL_COLOR_BUFFER_BIT; break; default: needToBlitColorBuffers = true; break; } } // Bind the resolve framebuffer to blit into. _fbo->apply(state, FrameBufferObject::READ_FRAMEBUFFER); _resolveFbo->apply(state, FrameBufferObject::DRAW_FRAMEBUFFER); if (blitMask) { // Blit to the resolve framebuffer. // Note that (with nvidia 175.16 windows drivers at least) if the read // framebuffer is multisampled then the dimension arguments are ignored // and the whole framebuffer is always copied. fbo_ext->glBlitFramebuffer( 0, 0, static_cast<GLint>(_viewport->width()), static_cast<GLint>(_viewport->height()), 0, 0, static_cast<GLint>(_viewport->width()), static_cast<GLint>(_viewport->height()), blitMask, GL_NEAREST); } #if !defined(OSG_GLES1_AVAILABLE) && !defined(OSG_GLES2_AVAILABLE) if (needToBlitColorBuffers) { for (FrameBufferObject::AttachmentMap::const_iterator it = _resolveFbo->getAttachmentMap().begin(), end =_resolveFbo->getAttachmentMap().end(); it != end; ++it) { osg::Camera::BufferComponent attachment = it->first; if (attachment >=osg::Camera::COLOR_BUFFER0) { glReadBuffer(GL_COLOR_ATTACHMENT0_EXT + (attachment - osg::Camera::COLOR_BUFFER0)); glDrawBuffer(GL_COLOR_ATTACHMENT0_EXT + (attachment - osg::Camera::COLOR_BUFFER0)); fbo_ext->glBlitFramebuffer( 0, 0, static_cast<GLint>(_viewport->width()), static_cast<GLint>(_viewport->height()), 0, 0, static_cast<GLint>(_viewport->width()), static_cast<GLint>(_viewport->height()), GL_COLOR_BUFFER_BIT, GL_NEAREST); } } // reset the read and draw buffers? will comment out for now with the assumption that // the buffers will be set explictly when needed elsewhere. // glReadBuffer(GL_COLOR_ATTACHMENT0_EXT); // glDrawBuffer(GL_COLOR_ATTACHMENT0_EXT); } #endif apply_read_fbo = true; read_fbo = _resolveFbo.get(); using_multiple_render_targets = read_fbo->hasMultipleRenderingTargets(); } // now copy the rendered image to attached texture. if (doCopyTexture) { if (read_fbo) SubFunc::applyReadFBO(apply_read_fbo, read_fbo, state); copyTexture(renderInfo); } std::map< osg::Camera::BufferComponent, Attachment>::const_iterator itr; for(itr = _bufferAttachmentMap.begin(); itr != _bufferAttachmentMap.end(); ++itr) { if (itr->second._image.valid()) { if (read_fbo) SubFunc::applyReadFBO(apply_read_fbo, read_fbo, state); #if !defined(OSG_GLES1_AVAILABLE) && !defined(OSG_GLES2_AVAILABLE) if (using_multiple_render_targets) { int attachment=itr->first; if (attachment==osg::Camera::DEPTH_BUFFER || attachment==osg::Camera::STENCIL_BUFFER) { // assume first buffer rendered to is the one we want glReadBuffer(read_fbo->getMultipleRenderingTargets()[0]); } else { glReadBuffer(GL_COLOR_ATTACHMENT0_EXT + (attachment - osg::Camera::COLOR_BUFFER0)); } } else { if (_readBuffer != GL_NONE) { glReadBuffer(_readBuffer); } } #endif GLenum pixelFormat = itr->second._image->getPixelFormat(); if (pixelFormat==0) pixelFormat = _imageReadPixelFormat; if (pixelFormat==0) pixelFormat = GL_RGB; GLenum dataType = itr->second._image->getDataType(); if (dataType==0) dataType = _imageReadPixelDataType; if (dataType==0) dataType = GL_UNSIGNED_BYTE; itr->second._image->readPixels(static_cast<int>(_viewport->x()), static_cast<int>(_viewport->y()), static_cast<int>(_viewport->width()), static_cast<int>(_viewport->height()), pixelFormat, dataType); } } if (fbo_supported) { if (getDisableFboAfterRender()) { // switch off the frame buffer object GLuint fboId = state.getGraphicsContext() ? state.getGraphicsContext()->getDefaultFboId() : 0; fbo_ext->glBindFramebuffer(GL_FRAMEBUFFER_EXT, fboId); } doCopyTexture = true; } if (fbo_supported && _camera.valid()) { // now generate mipmaps if they are required. const osg::Camera::BufferAttachmentMap& bufferAttachments = _camera->getBufferAttachmentMap(); for(osg::Camera::BufferAttachmentMap::const_iterator itr = bufferAttachments.begin(); itr != bufferAttachments.end(); ++itr) { if (itr->second._texture.valid() && itr->second._mipMapGeneration) { state.setActiveTextureUnit(0); state.applyTextureAttribute(0, itr->second._texture.get()); fbo_ext->glGenerateMipmap(itr->second._texture->getTextureTarget()); } } } }