OpenWalnut  1.4.0
WFiberDrawable.cpp
00001 //---------------------------------------------------------------------------
00002 //
00003 // Project: OpenWalnut ( http://www.openwalnut.org )
00004 //
00005 // Copyright 2009 OpenWalnut Community, BSV@Uni-Leipzig and CNCF@MPI-CBS
00006 // For more information see http://www.openwalnut.org/copying
00007 //
00008 // This file is part of OpenWalnut.
00009 //
00010 // OpenWalnut is free software: you can redistribute it and/or modify
00011 // it under the terms of the GNU Lesser General Public License as published by
00012 // the Free Software Foundation, either version 3 of the License, or
00013 // (at your option) any later version.
00014 //
00015 // OpenWalnut is distributed in the hope that it will be useful,
00016 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00017 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00018 // GNU Lesser General Public License for more details.
00019 //
00020 // You should have received a copy of the GNU Lesser General Public License
00021 // along with OpenWalnut. If not, see <http://www.gnu.org/licenses/>.
00022 //
00023 //---------------------------------------------------------------------------
00024 
00025 #include <vector>
00026 
00027 #include "../kernel/WKernel.h"
00028 
00029 #include "WFiberDrawable.h"
00030 
00031 // The constructor here does nothing. One thing that may be necessary is
00032 // disabling display lists. This can be done by calling
00033 //    setSupportsDisplayList (false);
00034 // Display lists should be disabled for 'Drawable's that can change over
00035 // time (that is, the vertices drawn change from time to time).
00036 WFiberDrawable::WFiberDrawable():
00037     osg::Drawable(),
00038     m_useTubes( false )
00039 {
00040     setSupportsDisplayList( false );
00041     // This contructor intentionally left blank. Duh.
00042 }
00043 
00044 // I can't say much about the methods below, but OSG seems to expect
00045 // that we implement them.
00046 WFiberDrawable::WFiberDrawable( const WFiberDrawable& /*pg*/, const osg::CopyOp& /*copyop*/ ):
00047     osg::Drawable()
00048 {
00049 }
00050 
00051 osg::Object* WFiberDrawable::cloneType() const
00052 {
00053     return new WFiberDrawable();
00054 }
00055 
00056 osg::Object* WFiberDrawable::clone( const osg::CopyOp& copyop ) const
00057 {
00058     return new WFiberDrawable( *this, copyop );
00059 }
00060 
00061 // Real work is done here. THERE IS A VERY IMPORTANT THING TO NOTE HERE:
00062 // the 'drawImplementation()' method receives an 'osg::State' as
00063 // parameter. This can be used to change the OpenGL state, but changing
00064 // the OpenGL state here is something to be avoided as much as possible.
00065 // Do this *only* if it is *absolutely* necessary to make your rendering
00066 // algorithm work. The "right" (most efficient and flexible) way to change
00067 // the OpenGL state in OSG is by attaching 'StateSet's to 'Node's and
00068 // 'Drawable's.
00069 // That said, the example below shows how to change the OpenGL state in
00070 // these rare cases in which it is necessary. But always keep in mind:
00071 // *Change the OpenGL state only if strictly necessary*.
00072 void WFiberDrawable::drawImplementation( osg::RenderInfo& renderInfo ) const //NOLINT
00073 {
00074     if( m_useTubes )
00075     {
00076         drawTubes();
00077     }
00078     else
00079     {
00080         drawFibers( renderInfo );
00081     }
00082 }
00083 
00084 void WFiberDrawable::drawFibers( osg::RenderInfo& renderInfo ) const //NOLINT
00085 {
00086     osg::State& state = *renderInfo.getState();
00087 
00088     state.disableAllVertexArrays();
00089     state.setVertexPointer( 3, GL_FLOAT , 0, &( *m_verts )[0] );
00090     state.setColorPointer( 3 , GL_FLOAT , 0, &( *m_colors )[0] );
00091     //state.setNormalPointer( GL_FLOAT , 0, &( *m_tangents )[0] );
00092     for( size_t i = 0; i < m_active->size(); ++i )
00093     {
00094         if( (*m_active)[i] )
00095         {
00096             state.glDrawArraysInstanced( GL_LINE_STRIP, (*m_startIndexes)[i], (*m_pointsPerLine)[i], 1);
00097         }
00098     }
00099 
00100     state.disableVertexPointer();
00101     state.disableColorPointer();
00102 }
00103 
00104 void WFiberDrawable::drawTubes() const
00105 {
00106     // This does not work if GLES is used
00107     #ifndef GL_ES_VERSION_2_0
00108     for( size_t i = 0; i < m_active->size(); ++i )
00109     {
00110         if( (*m_active)[i] )
00111         {
00112             glBegin( GL_QUAD_STRIP );
00113             int idx = m_startIndexes->at( i ) * 3;
00114             for( size_t k = 0; k < m_pointsPerLine->at( i ); ++k )
00115             {
00116                 glNormal3f( m_tangents->at( idx ), m_tangents->at( idx + 1 ), m_tangents->at( idx + 2 ) );
00117                 glColor3f( m_colors->at( idx ), m_colors->at( idx + 1 ), m_colors->at( idx + 2 ) );
00118                 glTexCoord1f( -1.0f );
00119                 glVertex3f( m_verts->at( idx ), m_verts->at( idx + 1 ), m_verts->at( idx + 2 ) );
00120                 glTexCoord1f( 1.0f );
00121                 glVertex3f( m_verts->at( idx ), m_verts->at( idx + 1 ), m_verts->at( idx + 2 ) );
00122                 idx += 3;
00123                 //
00124             }
00125             glEnd();
00126         }
00127     }
00128     #endif
00129 }
00130