//--------------------------------------------------------------------------- // // Project: OpenWalnut ( http://www.openwalnut.org ) // // Copyright 2009 OpenWalnut Community, BSV@Uni-Leipzig and CNCF@MPI-CBS // For more information see http://www.openwalnut.org/copying // // This file is part of OpenWalnut. // // OpenWalnut is free software: you can redistribute it and/or modify // it under the terms of the GNU Lesser General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // OpenWalnut is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public License // along with OpenWalnut. If not, see . // //--------------------------------------------------------------------------- #include #include "../../dataHandler/WDataSetFibers.h" #include "../../kernel/WKernel.h" #include "WTubeDrawable.h" // The constructor here does nothing. One thing that may be necessary is // disabling display lists. This can be done by calling // setSupportsDisplayList (false); // Display lists should be disabled for 'Drawable's that can change over // time (that is, the vertices drawn change from time to time). WTubeDrawable::WTubeDrawable(): osg::Drawable(), m_useTubes( false ), m_globalColoring( true ) { setSupportsDisplayList( false ); // This contructor intentionally left blank. Duh. } // I can't say much about the methods below, but OSG seems to expect // that we implement them. WTubeDrawable::WTubeDrawable( const WTubeDrawable& /*pg*/, const osg::CopyOp& /*copyop*/ ): osg::Drawable() { } osg::Object* WTubeDrawable::cloneType() const { return new WTubeDrawable(); } osg::Object* WTubeDrawable::clone( const osg::CopyOp& copyop ) const { return new WTubeDrawable( *this, copyop ); } // Real work is done here. THERE IS A VERY IMPORTANT THING TO NOTE HERE: // the 'drawImplementation()' method receives an 'osg::State' as // parameter. This can be used to change the OpenGL state, but changing // the OpenGL state here is something to be avoided as much as possible. // Do this *only* if it is *absolutely* necessary to make your rendering // algorithm work. The "right" (most efficient and flexible) way to change // the OpenGL state in OSG is by attaching 'StateSet's to 'Node's and // 'Drawable's. // That said, the example below shows how to change the OpenGL state in // these rare cases in which it is necessary. But always keep in mind: // *Change the OpenGL state only if strictly necessary*. void WTubeDrawable::drawImplementation( osg::RenderInfo& renderInfo ) const //NOLINT { if ( m_useTubes ) { drawTubes(); } else { drawFibers( renderInfo ); } } void WTubeDrawable::setDataset( boost::shared_ptr< const WDataSetFibers > dataset ) { m_dataset = dataset; } void WTubeDrawable::setUseTubes( bool flag ) { m_useTubes = flag; } void WTubeDrawable::setColoringMode( bool globalColoring ) { m_globalColoring = globalColoring; } bool WTubeDrawable::getColoringMode() const { return m_globalColoring; } void WTubeDrawable::drawFibers( osg::RenderInfo& /* renderInfo */ ) const //NOLINT { boost::shared_ptr< std::vector< size_t > > startIndexes = m_dataset->getLineStartIndexes(); boost::shared_ptr< std::vector< size_t > > pointsPerLine = m_dataset->getLineLengths(); boost::shared_ptr< std::vector< float > > verts = m_dataset->getVertices(); boost::shared_ptr< std::vector< float > > colors = ( m_globalColoring ? m_dataset->getGlobalColors() : m_dataset->getLocalColors() ); boost::shared_ptr< std::vector< bool > > active = WKernel::getRunningKernel()->getRoiManager()->getBitField(); #if 0 glEnableClientState( GL_VERTEX_ARRAY ); glEnableClientState( GL_COLOR_ARRAY ); glVertexPointer( 3, GL_FLOAT, 0, &(*verts)[0] ); //NOLINT glColorPointer( 3, GL_FLOAT, 0, &(*colors)[0] ); //NOLINT for ( size_t i = 0; i < active->size(); ++i ) { if ( (*active)[i] ) { glDrawArrays( GL_LINE_STRIP, (*startIndexes)[i] * 3, (*pointsPerLine)[i] ); } } glDisableClientState( GL_VERTEX_ARRAY ); glDisableClientState( GL_COLOR_ARRAY ); #else for ( size_t i = 0; i < active->size(); ++i ) { if ( (*active)[i] ) { glBegin( GL_LINE_STRIP ); int idx = (*startIndexes)[i] * 3; for ( size_t k = 0; k < pointsPerLine->at( i ); ++k ) { glColor3f( (*colors)[idx], (*colors)[idx + 1], (*colors)[idx + 2] ); glVertex3f( (*verts)[idx], (*verts)[idx + 1], (*verts)[idx + 2] ); idx += 3; } glEnd(); } } #endif } void WTubeDrawable::drawTubes() const { boost::shared_ptr< std::vector< size_t > > startIndexes = m_dataset->getLineStartIndexes(); boost::shared_ptr< std::vector< size_t > > pointsPerLine = m_dataset->getLineLengths(); boost::shared_ptr< std::vector< float > > verts = m_dataset->getVertices(); boost::shared_ptr< std::vector< float > > tangents = m_dataset->getTangents(); boost::shared_ptr< std::vector< float > > colors = ( m_globalColoring ? m_dataset->getGlobalColors() : m_dataset->getLocalColors() ); boost::shared_ptr< std::vector< bool > > active = WKernel::getRunningKernel()->getRoiManager()->getBitField(); for( size_t i = 0; i < active->size(); ++i ) { if ( active->at( i ) ) { glBegin( GL_QUAD_STRIP ); int idx = startIndexes->at( i ) * 3; for ( size_t k = 0; k < pointsPerLine->at( i ); ++k ) { glNormal3f( tangents->at( idx ), tangents->at( idx + 1 ), tangents->at( idx + 2 ) ); glColor3f( colors->at( idx ), colors->at( idx + 1 ), colors->at( idx + 2 ) ); glTexCoord1f( -1.0f ); glVertex3f( verts->at( idx ), verts->at( idx + 1 ), verts->at( idx + 2 ) ); glTexCoord1f( 1.0f ); glVertex3f( verts->at( idx ), verts->at( idx + 1 ), verts->at( idx + 2 ) ); idx += 3; // } glEnd(); } } }