OpenWalnut
1.4.0
|
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