OpenWalnut  1.5.0dev
WFiberDrawable.cpp
1 //---------------------------------------------------------------------------
2 //
3 // Project: OpenWalnut ( http://www.openwalnut.org )
4 //
5 // Copyright 2009 OpenWalnut Community, BSV@Uni-Leipzig and CNCF@MPI-CBS
6 // For more information see http://www.openwalnut.org/copying
7 //
8 // This file is part of OpenWalnut.
9 //
10 // OpenWalnut is free software: you can redistribute it and/or modify
11 // it under the terms of the GNU Lesser General Public License as published by
12 // the Free Software Foundation, either version 3 of the License, or
13 // (at your option) any later version.
14 //
15 // OpenWalnut is distributed in the hope that it will be useful,
16 // but WITHOUT ANY WARRANTY; without even the implied warranty of
17 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 // GNU Lesser General Public License for more details.
19 //
20 // You should have received a copy of the GNU Lesser General Public License
21 // along with OpenWalnut. If not, see <http://www.gnu.org/licenses/>.
22 //
23 //---------------------------------------------------------------------------
24 
25 #include <vector>
26 
27 #include "../kernel/WKernel.h"
28 
29 #include "WFiberDrawable.h"
30 
31 // The constructor here does nothing. One thing that may be necessary is
32 // disabling display lists. This can be done by calling
33 // setSupportsDisplayList (false);
34 // Display lists should be disabled for 'Drawable's that can change over
35 // time (that is, the vertices drawn change from time to time).
37  osg::Drawable(),
38  m_useTubes( false )
39 {
40  setSupportsDisplayList( false );
41  // This contructor intentionally left blank. Duh.
42 }
43 
44 // I can't say much about the methods below, but OSG seems to expect
45 // that we implement them.
46 WFiberDrawable::WFiberDrawable( const WFiberDrawable& /*pg*/, const osg::CopyOp& /*copyop*/ ):
47  osg::Drawable()
48 {
49 }
50 
51 osg::Object* WFiberDrawable::cloneType() const
52 {
53  return new WFiberDrawable();
54 }
55 
56 osg::Object* WFiberDrawable::clone( const osg::CopyOp& copyop ) const
57 {
58  return new WFiberDrawable( *this, copyop );
59 }
60 
61 // Real work is done here. THERE IS A VERY IMPORTANT THING TO NOTE HERE:
62 // the 'drawImplementation()' method receives an 'osg::State' as
63 // parameter. This can be used to change the OpenGL state, but changing
64 // the OpenGL state here is something to be avoided as much as possible.
65 // Do this *only* if it is *absolutely* necessary to make your rendering
66 // algorithm work. The "right" (most efficient and flexible) way to change
67 // the OpenGL state in OSG is by attaching 'StateSet's to 'Node's and
68 // 'Drawable's.
69 // That said, the example below shows how to change the OpenGL state in
70 // these rare cases in which it is necessary. But always keep in mind:
71 // *Change the OpenGL state only if strictly necessary*.
72 void WFiberDrawable::drawImplementation( osg::RenderInfo& renderInfo ) const //NOLINT
73 {
74  if( m_useTubes )
75  {
76  drawTubes();
77  }
78  else
79  {
80  drawFibers( renderInfo );
81  }
82 }
83 
84 void WFiberDrawable::drawFibers( osg::RenderInfo& renderInfo ) const //NOLINT
85 {
86  osg::State& state = *renderInfo.getState();
87 
88  state.disableAllVertexArrays();
89  state.setVertexPointer( 3, GL_FLOAT , 0, &( *m_verts )[0] );
90  state.setColorPointer( 3 , GL_FLOAT , 0, &( *m_colors )[0] );
91  //state.setNormalPointer( GL_FLOAT , 0, &( *m_tangents )[0] );
92  for( size_t i = 0; i < m_active->size(); ++i )
93  {
94  if( (*m_active)[i] )
95  {
96  state.glDrawArraysInstanced( GL_LINE_STRIP, (*m_startIndexes)[i], (*m_pointsPerLine)[i], 1);
97  }
98  }
99 
100  state.disableVertexPointer();
101  state.disableColorPointer();
102 }
103 
105 {
106  // This does not work if GLES is used
107  #ifndef GL_ES_VERSION_2_0
108  for( size_t i = 0; i < m_active->size(); ++i )
109  {
110  if( (*m_active)[i] )
111  {
112  glBegin( GL_QUAD_STRIP );
113  int idx = m_startIndexes->at( i ) * 3;
114  for( size_t k = 0; k < m_pointsPerLine->at( i ); ++k )
115  {
116  glNormal3f( m_tangents->at( idx ), m_tangents->at( idx + 1 ), m_tangents->at( idx + 2 ) );
117  glColor3f( m_colors->at( idx ), m_colors->at( idx + 1 ), m_colors->at( idx + 2 ) );
118  glTexCoord1f( -1.0f );
119  glVertex3f( m_verts->at( idx ), m_verts->at( idx + 1 ), m_verts->at( idx + 2 ) );
120  glTexCoord1f( 1.0f );
121  glVertex3f( m_verts->at( idx ), m_verts->at( idx + 1 ), m_verts->at( idx + 2 ) );
122  idx += 3;
123  //
124  }
125  glEnd();
126  }
127  }
128  #endif
129 }
130 
Class implements an osg::Drawable that paints fiber representations either using lines or tubes.
std::shared_ptr< std::vector< float > > m_verts
pointer to the field of vertexes
WFiberDrawable()
The constructor here does nothing.
std::shared_ptr< std::vector< size_t > > m_pointsPerLine
pointer to the field of points per line
virtual void drawImplementation(osg::RenderInfo &renderInfo) const
Real work is done here.
std::shared_ptr< std::vector< float > > m_tangents
pointer to the field of line tangents
virtual osg::Object * clone(const osg::CopyOp &copyop) const
clones it
std::shared_ptr< std::vector< bool > > m_active
pointer to the bitfield of active fibers
virtual osg::Object * cloneType() const
See osg documentation for this.
std::shared_ptr< std::vector< size_t > > m_startIndexes
pointer to the field of line start indexes
std::shared_ptr< std::vector< float > > m_colors
pointer to the field of colors per vertex
void drawTubes() const
Draw fibers as fake tubes.
void drawFibers(osg::RenderInfo &renderInfo) const
Draw fibers as ordinary lines.