TexturedStreamLines.cpp

Like SimpleStreamline but uses multitextring and texturebase illumination to draw nicer streamlines.

Textures should not be stored in the state, as it is still done here...

See also:
Required tutorials: - SimpleStreamline.cpp
00001 #include <ocean/GLvish/VRenderObject.hpp>
00002 #include <fish/lakeview/bone/FishField.hpp>
00003 
00004 #include <ocean/GLvish/Colormap.hpp> // use of color_t
00005 
00006 #include <eagle/FixedArray.hpp>
00007 #include <field/DirectProductArray.hpp>
00008 #include <ocean/GLvish/BoundingBox.hpp>
00009 
00010 #include <fish/fiber/vector/Interpolate.hpp>
00011 #include <fish/fiber/vector/LinearIpol.hpp>
00012 #include <fish/fiber/vector/CubicIpol.hpp>
00013 
00014 #include <ocean/GLvish/GlossyTexture.hpp>
00015 
00016 #include <ocean/plankton/VOperatorCache.hpp>
00017 
00018 
00019 
00020 using namespace Wizt;
00021 using namespace Fiber;
00022 
00034 /*
00035   bla
00036 */
00037 class   RampTexture : public GLTexture1D
00038 {
00039         typedef FixedArray<float,3> rgb;
00040 
00041 public: 
00042         RampTexture(const int tex_unit):GLTexture1D(tex_unit){}
00043 
00044 
00045         void enlighten()
00046                 {
00047                 rgb     texture[512]; 
00048                 rgb col; 
00049                         col = 0,0,0;
00050 
00051                         for(int i = 0; i < 512 ; i++)
00052                         {
00053                                 col[0] = (float)i/512; 
00054                                 col[1] = 1 - col[0];
00055                                 texture[i] = col; 
00056                         } 
00057 
00058                         bind(); 
00059                         GL::TexImage1D( texture, 512, GL_RGB); 
00060                         glTexParameteri( GL_TEXTURE_1D, GL_TEXTURE_WRAP_T, GL_CLAMP); 
00061                         glTexParameteri( GL_TEXTURE_1D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); 
00062                         glTexParameteri( GL_TEXTURE_1D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); 
00063                 }
00064 
00065         void prerender()
00066                 {
00067                         enable(); 
00068                         //glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); //not really nesseccasy ? 
00069                         bind();  // should do corresponding glActiveTexture(GL_TEXTURE1);  ?? automatically ??
00070                 }
00071         
00072 };
00073 
00074 
00075 class TexturedStreamLines : public virtual VRenderObject,  
00076 //                          public virtual Fish<Grid>, 
00077                             public virtual Fish<Field>
00078 {
00079 public:
00080         typedef MemArray<3, tvector>           VectorArray_t; 
00081         typedef MemArray<3, point>             CoordsArray_t; 
00082         typedef DirectProductMemArray<point>   ProceduralArray_t; 
00083 
00084         typedef FixedArray<float,3> rgb; 
00085 
00086         GlossyTexture::Parameters  GlossyParameters;
00087 
00088         // define data type for storing a line
00089         typedef std::vector<point> Line_t;
00090 
00091         // prepare caching of computed lines
00092         typedef VOperatorCache<std::vector<Line_t> > OpCache_t;
00093 
00094         TypedSlot<int> LineLength;
00095         TypedSlot<int> LineWidth;
00096         TypedSlot<int> PointSize;
00097         TypedSlot<int> LineNumber;
00098         TypedSlot<double> StepSize;
00099         TypedSlot<double> FanDelta;
00100 
00101         TypedSlot<double> X,
00102                           Y,
00103                           Z;
00104 
00105         // Inner class to save local state Information. Besides the control parameters also 
00106         // pointers to the vector and coordinate data are saved here.
00107         // This causes an error when exiting vish, because the textures must be freed inside the openGL context, 
00108         // which is then not longer available.
00109         struct  MyState : State
00110         {
00111                 RefPtr<RampTexture>   MyTexture;     
00112                 RefPtr<GlossyTexture> LineTexture;
00113         };
00114 
00115         override RefPtr<State> newState() const
00116         {
00117                 return new MyState();
00118         }
00119 
00120 
00121 
00122         TexturedStreamLines(const string&name, int p, const RefPtr<VCreationPreferences>&VP)
00123         : VRenderObject(name, p, VP)
00124         , Fish<VObject>(this)
00125         , Fish<Field>("datafield")
00126         , GlossyParameters(this)
00127         , LineLength(this, "LineLength", 40)
00128         , LineWidth(this, "LineWidth", 2)
00129         , PointSize(this, "PointSize", 2)
00130         , LineNumber(this, "LineNumber", 10)
00131         , StepSize(this, "StepSize", 0.1)
00132         , FanDelta(this, "FanDelta", 0.05)
00133         , X(this, "X", 0.271)
00134         , Y(this, "Y", 0.294)
00135         , Z(this, "Z", 0.531)
00136         {
00137                 LineLength.setProperty("max", 100); 
00138                 LineLength.setProperty("min", 1); 
00139                 LineWidth.setProperty("max", 20); 
00140                 PointSize.setProperty("max", 20); 
00141                 LineNumber.setProperty("min", 1);
00142                 X.setProperty("max", 1.0); 
00143                 Y.setProperty("max", 1.0); 
00144                 Z.setProperty("max", 1.0); 
00145         }
00146 
00147 
00148         override bool update( VRequest&R, double precision );
00149         override void render( VRenderContext&R ) const;
00150 
00151         void getCoordinates(const point& float_index, point& position_cordinates);
00152 };
00153 
00154 
00159 bool TexturedStreamLines::update( VRequest&R, double precision )
00160 {
00161         printf("TexturedStreamLines::update(): updating\n");
00162 
00163 FieldSelector FS = getFieldSelector(R);
00164 
00165 // get the grid of the fiber bundle 
00166 RefPtr<Grid>  G = FS.GridSource();
00167         if (!G)
00168                 return true;
00169 
00170 // get the coordinates of the grid
00171 RefPtr<Field> Coords  = G->CartesianPositions();
00172         if (!Coords)  { puts("SimpleStreamline::update(): No coord field!"); return true; } 
00173 
00174 
00175 // get the vector data of the grid
00176 RefPtr<Field> Vectors = FS.getField();
00177         if (!Vectors) { puts("SimpleStreamline::update(): No vector field!"); return true; } 
00178 
00179 
00180 
00181 // associate the caching object to the field. As long as the field is valid the 
00182 // cached lines can by used. If a new field is load (e.g. from another time step)
00183 RefPtr<OpCache_t>&OC = OpCache_t::retrieve( *Vectors ) [ self() ]; 
00184        if (!OC) OC = new OpCache_t(); 
00185 
00186 // get the actual state object
00187 RefPtr<MyState> S = myState(R); 
00188 
00189         assert(S); 
00190 
00191         RefPtr<VectorArray_t> Vctrs = Vectors->getData(); 
00192 
00193         if( !Vctrs)
00194         {
00195                 printf("TexturedStreamLines::update(): Could get vector field data yet!\n"); 
00196                 if (OC)
00197                 {
00198                         OC->resize( 0 );
00199                         GLCache::clear( *OC );
00200                 }
00201                 return true;
00202         } 
00203         else
00204                 printf("TexturedStreamLines::update(): Gotvector field data!\n"); 
00205 
00206         RefPtr<ProceduralArray_t>   PCrds = Coords->getData(); 
00207         RefPtr<CoordsArray_t>       Crds  = Coords->getData(); 
00208         if (!(Crds || PCrds))
00209                 {
00210                         printf("TexturedStreamLines::update(): Did not find any coordinates :  %s\n",
00211                                Typename( Coords->getType() ).c_str() ); 
00212                         return true;
00213                 } 
00214 
00215 
00216 
00217 
00218 RefPtr<ValueSet> Changeables = new ValueSet(); 
00219 Changeables & R += X, Y, Z, LineLength, PointSize, StepSize, FanDelta, LineNumber; 
00220 
00221 
00222 int line_number = 1; 
00223         LineNumber << R >> line_number; 
00224 
00225 
00226         if (OC->unchanged( Changeables ) )
00227         {
00228                 printf("TexturedStreamLines::update(): Line Calc Skipped, Lines in Cache...\n");
00229                 return true;
00230         } 
00231 
00232         OC->resize( line_number ); // resize std::vector to number of lines
00233         GLCache::clear( *OC );
00234 
00235 // Now do the Interpolation of the Coordinates 
00236 // Get index Range of Data (and Coordinates)
00237         MultiIndex<3> FieldSize = Vctrs->Size(); 
00238 
00239 
00240 double x, y, z; 
00241 point float_index; 
00242 point max_float_index; 
00243 point vertex; 
00244 int line_length; 
00245 double hh; 
00246 double fan_delta;
00247 
00248         LineLength << R >> line_length; 
00249         //LineNumber << R >> line_number; 
00250         StepSize << R >> hh; 
00251         FanDelta<< R >> fan_delta;
00252 
00253 // Get user specified position ranging from 0 to 1.0 in each coordinate covering the whole dataset 
00254         X << R >> x; 
00255         Y << R >> y; 
00256         Z << R >> z; 
00257 
00258         max_float_index = FieldSize[0] - 1, FieldSize[1] - 1, FieldSize[2] - 1;
00259         float_index = x * FieldSize[0] - 1, y * FieldSize[1] -1 , z * FieldSize[2] - 1; 
00260 
00261 // Clamp wrong inputs
00262         for (int i = 0; i < 3; i++)
00263         {
00264                 if( float_index[i] < 0 )
00265                         float_index[i] = 0.0; 
00266 
00267                 if( float_index[i] >= FieldSize[i] )
00268                         float_index[i] = FieldSize[i] - 1;
00269         } 
00270 
00271 // assume uniform PCrds here (noch auszuweiten) 
00272 point DomainStart = PCrds->first(); 
00273 point DomaintEnd = PCrds->last(); 
00274 
00275 tvector DomainDiagonal = DomaintEnd - DomainStart; 
00276 
00277 
00278 // Calc StartPoint 
00279 std::vector<point> StartVertex; 
00280 StartVertex.resize(line_number);
00281 StartVertex[0] = ( DomainStart + tvector(component_wise( component_wise(DomainDiagonal, max_float_index, Eagle::Operator<'/'>() ), float_index, Eagle::Operator<'*'>() ) ) ); 
00282 
00283 
00284 tvector CurrentDir; 
00285 point CurrentVertex; 
00286 point CurrentFloatIndex; 
00287 tvector FanOffset; 
00288         FanOffset = 1, 0, 0;
00289 
00290         resetBBox( R ); 
00291         embrace( R, StartVertex[0]);
00292 
00293         for(int l = 0; l < line_number; l++)
00294         {
00295                 //printf("update: line: %d\n", l);
00296                 StartVertex[l] = StartVertex[0] + FanOffset * l * fan_delta;
00297                 
00298         Line_t&myLine = (*OC)[l]; 
00299                 myLine.clear(); 
00300                 
00301                 for(int i = 0; i < line_length; i++)
00302                 {
00303                         if (i == 0)
00304                         {
00305                                 CurrentVertex = StartVertex[l]; 
00306 
00307                                 Interpolate<3, tvector, CubicIpol <tvector> > VecField(*Vctrs, float_index); 
00308                                 CurrentDir = VecField.eval(); 
00309                         }
00310                         else
00311                         {
00312                                 CurrentFloatIndex = point( tvector( component_wise(component_wise(CurrentVertex - DomainStart, DomainDiagonal, Eagle::Operator<'/'>() ), max_float_index, Eagle::Operator<'*'>()) )); 
00313 
00314                                 if(CurrentFloatIndex [0] < 0.0 ||CurrentFloatIndex [0] > max_float_index[0])
00315                                         break; 
00316                                 if(CurrentFloatIndex [1] < 0.0 ||CurrentFloatIndex [1] > max_float_index[1])
00317                                         break; 
00318                                 if(CurrentFloatIndex [2] < 0.0 ||CurrentFloatIndex [2] > max_float_index[2])
00319                                         break; 
00320                                 Interpolate<3, tvector, CubicIpol <tvector> > VecField(*Vctrs, CurrentFloatIndex); 
00321                                 CurrentDir = VecField.eval(); 
00322                         } 
00323 
00324                         
00325                                 CurrentVertex += CurrentDir * hh; 
00326                                 myLine.push_back(CurrentVertex); 
00327                                 embrace( R, CurrentVertex); 
00328                 }
00329         } 
00330 
00331         printf("TexturedStreamLines::update(): Integrated into Cache\n");
00332         closeBBox( R ); 
00333         
00334         return true;
00335 }
00336 
00337 
00338 void TexturedStreamLines::render( VRenderContext& Context ) const
00339 {
00340         //printf("TexturedStreamLines::render: START\n");
00341 
00342         //printf("TexturedStreamLines::render(): starting to render\n");
00343 
00344  RefPtr<Field> Vectors = getField( Context ); 
00345         if (!Vectors) 
00346         {
00347                 puts("void TexturedStreamLines::render(VRenderContext&RenderContext): NO VECTORS");
00348                 return;
00349         } 
00350 const RefPtr<OpCache_t>&OC = OpCache_t::retrieve( *Vectors ) ( self() );
00351         if (!OC)
00352         {
00353                 puts("void TexturedStreamLines::render(VRenderContext&RenderContext): NO LINE CACHE"); 
00354                 return;
00355         } 
00356         if (OC->size()<1)
00357         {
00358                 puts("void TexturedStreamLines::render(VRenderContext&RenderContext): NO LINES in CACHE"); 
00359                 return;
00360         } 
00361 
00362 int line_width, point_size; 
00363 int line_length  = 1; 
00364 
00365         LineWidth  << Context >> line_width; 
00366         PointSize  << Context >> point_size; 
00367         LineLength << Context >> line_length;
00368 
00369         if(line_width < 1)
00370                 line_width = 1; 
00371 
00372         glEnable(GL_DEPTH_TEST); 
00373         glDisable(GL_LIGHTING); 
00374 
00375         glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); 
00376         glBlendFunc(GL_ONE, GL_ONE); 
00377 //      glEnable( GL_BLEND ); 
00378 
00379         glEnable ( GL_COLOR_MATERIAL );
00380         glLineWidth( line_width ); 
00381 
00382         if(point_size > 0)
00383                 glPointSize( point_size ); 
00384         else
00385                 glPointSize( 1 ); 
00386 
00387         RefPtr<MyState>  state = myState(Context); 
00388 
00389         if(!state)
00390         {
00391                 printf("TexturedStreamLines::render(): Invalid State!\n");
00392                 return; 
00393         } 
00394 
00395         if (!state->LineTexture)
00396         {
00397                 //glActiveTexture(GL_TEXTURE0); 
00398                 state->LineTexture = new GlossyTexture(0);
00399                 state->LineTexture->enlighten(); 
00400                 state->LineTexture->enlighten(GlossyParameters, Context); 
00401         } 
00402 
00403         if (!state->MyTexture)
00404         {
00405                 printf("TexturedStreamLines::render, new RampTexture Created\n"); 
00406                 //glActiveTexture(GL_TEXTURE1); 
00407                 state->MyTexture = new RampTexture(1); 
00408                 state->MyTexture->enlighten(); 
00409         } 
00410 
00411         RefPtr<ValueSet> RenderParameterSpace = new ValueSet(); 
00412         RefPtr<DisplayList> DL; 
00413         try{
00414                 DL = Context(*OC)(this)( RenderParameterSpace ); 
00415         } 
00416         catch(...){}
00417         RefPtr<ValueSet> Changeables = new ValueSet(); 
00418 Changeables & Context += LineLength, LineNumber, StepSize; 
00419 
00420 
00421 
00422         // glActiveTexture(GL_TEXTURE0); 
00423 //      state->LineTexture->beginRender( Context.CameraSettings ); 
00424 
00425 
00426 GlossyTexture::Render RenderLineTexture( *state->LineTexture, Context.CameraSettings ); 
00427 
00428         glActiveTexture(GL_TEXTURE1); 
00429         state->MyTexture->prerender(); 
00430         //glActiveTexture(GL_TEXTURE0); 
00431 
00432         if ( DL && OC->unchanged( Changeables  ))   //call display list if availlable/  
00433         {
00434                 printf("TexturedStreamLines::render(): Calling List\n"); 
00435                 DL->call(); 
00436         } 
00437         else                                                   //prepare display list
00438         {
00439                 printf("TexturedStreamLines::render(): Rendering List\n");
00440  
00441                 DL = Context[*OC][this][ RenderParameterSpace ]; 
00442                 if (!DL) throw "TexturedStreamLines::render() No Display List!?"; 
00443 
00444                 glCompile( *DL ) 
00445                 {
00446                 int l = 0; 
00447                 int p = 0; 
00448                        
00449                         for( OpCache_t::const_iterator lbit = OC->begin(); lbit != OC->end(); lbit++ )
00450                         {
00451                                 p = 0; 
00452                                 //printf("TexturedStreamLines::render()> :Line %d\n", l);
00453                         Line_t::const_iterator lit = lbit->begin(); 
00454 
00455                                 if (lit == lbit->end() )
00456                                         break; 
00457 
00458                                 glBegin( GL_LINE_STRIP );    // GLCHECK must not be used in between a glBegin and glEnd statement
00459                         bivector dir;
00460 
00461                                 for(; lit != lbit->end();)
00462                                 {
00463 //                                      printf("TexturedStreamLines::render()> :point %d\n", p);
00464                                 point   P = *lit; 
00465                                         lit++; 
00466                                         if (lit != lbit->end()) 
00467                                                 dir = (*lit - P).unit(); 
00468 
00469                                         glMultiTexCoord3dv(GL_TEXTURE0, dir.ptr()) ; 
00470                                         glMultiTexCoord1d (GL_TEXTURE1,  (double)p/lbit->size()); 
00471                                         glVertex( P ); 
00472 
00473                                         p++;
00474                                 } 
00475 
00476                                 l++; 
00477                                 glEnd(); 
00478                         } 
00479 
00480                         glEnable( GL_BLEND ); 
00481 
00482                         if(point_size > 0 )
00483                         {
00484                                 for( OpCache_t::const_iterator lbit = OC->begin(); lbit != OC->end(); lbit++ ) 
00485                                 {
00486                                         p = 0; 
00487                                         //printf("TexturedStreamLines::render()> :Line %d\n", l); 
00488                                         Line_t::const_iterator lit = lbit->begin(); 
00489 
00490                                         if (lit == lbit->end() ) 
00491                                                 break; 
00492 
00493                                 tvector dir; 
00494                                         glBegin(GL_POINTS); 
00495 
00496                                         for(; lit != lbit->end();)
00497                                         {
00498                                                 //printf("TexturedStreamLines::render()> :point %d\n", p);
00499                                         point   P = *lit; 
00500                                                 lit++; 
00501                                                 if (lit != lbit->end())
00502                                                         dir = (*lit - P).unit(); 
00503 
00504                                                 glMultiTexCoord3dv(GL_TEXTURE0, dir.ptr()) ; 
00505                                                 glMultiTexCoord1d (GL_TEXTURE1,  (double)p/lbit->size()); 
00506                                                 glVertex( P ); 
00507 
00508                                                 p++;
00509                                         } 
00510                                         glEnd(); 
00511                                 } 
00512                         }
00513                 }
00514         } 
00515 
00516         //printf("TexturedStreamLines::render: END\n"); 
00517 //      glActiveTexture(GL_TEXTURE0); 
00518 //      state->LineTexture->endRender(); 
00519 
00520         state->touch(); // synchinozes state, prevents unneccessary calls of the update function.
00521 }
00522 
00523 
00524 static Ref< VCreator<TexturedStreamLines, AcceptList<Fiber::Field> > > myCreator("Tutorial/TexturedStreamLines");
00525 
00526 VISH_DEFAULT_INIT

Generated on Thu Apr 2 18:58:48 2009 for VISHTutorial by  doxygen 1.4.7