Textures should not be stored in the state, as it is still done here...
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