Display a set of lines as specified by the Edge skeleton of a grid. Refinement levels and fragmented fields not implemented.
#include <bone/FishGrid.hpp> #include <ocean/plankton/VCreator.hpp> #include <ocean/GLvish/VGLRenderObject.hpp> #include <ocean/GLvish/BoundingBox.hpp> #include <ocean/GLvish/GlossyTexture.hpp> #include <ocean/eagle/PhysicalSpace.hpp> #include <ocean/shrimp/TimeDependent.hpp> #include <GL/fieldGL.hpp> #include <GL/FieldBuffer.hpp> #include <baseop/ExpandBBox.hpp> #include <ocean/shrimp/VObjectStatus.hpp> #include <grid/types/LineSet.hpp> #include <bundle/BundleProperty.hpp> #include <GL/LineSetRenderer.hpp> #include <bone/GridActor.hpp> using namespace Wizt; using namespace Fiber; using namespace Eagle; namespace { class GlossyLines : public VGLRenderObject, public TimeDependent { public: GlossyTexture::Parameters GlossyParameters; struct FieldState : State { WeakPtr<Grid> theGridOfInterest; }; override RefPtr<State> newState() const { return new FieldState(); } TypedSlot<Grid> LineGrid; TypedSlot<double> Thickness; TypedSlot<int> WhichLine, nLines; GlossyLines(const string&name, int p, const RefPtr<VCreationPreferences>&VP) : VGLRenderObject(name, DEFAULT_OBJECT, VP) , TimeDependent(this) , GlossyParameters(this) , LineGrid(this, "grid") , Thickness(this, "thickness", 1.0) , WhichLine(this, "lineid", -1, 1) , nLines(this, "nlines", 1, 2) { Thickness.setProperty( "max", 10.0); WhichLine.setProperty( "min", -1); } override bool update(VRequest&R, double precision); override void render(VGLRenderContext&Context) const; static string createChildname(const string&parent_name) { return "GlossyLinesOf" + parent_name; } }; // // Update function, is called whenever some input is changed // It extracts the fields required for rendering and deposits them // in the context-relative state object. This state object is // available then during rendering. // bool GlossyLines::update(VRequest&Context, double precision) { // puts("\n\n************************************GlossyLines::update() enter\n");fflush(stdout); GridSelector GS; LineGrid << Context >> GS; Info<Skeleton> SI = GS.getRefinementLevel( getTime(Context), 0, 0 ); double time = SI.getTime(); if (!SI.getGrid()) return setStatusError(Context,"No grid object found at T=" + String(time) ); setBoundingBall( Context, getBoundingBox( *SI.getGrid() ) ); RefPtr<FieldState> S = myState(Context); LineSet LS = SI.getGrid(); if (!LS) { return setStatusError(Context,"No line grid found at T=" + String(time) ); } S->theGridOfInterest = SI.getGrid(); return setStatusInfo(Context, "Lines ready."); } /* The render routine. Takes care of vertex buffer objects and calls its render routines. */ void GlossyLines::render(VGLRenderContext&Context) const { RefPtr<FieldState> S = getState(Context); if (!S) return; if (!S->theGridOfInterest) return; RefPtr<ValueSet> GlossyValues = new ValueSet(); RefPtr<GlossyTexture> LineTexture; // try to get a LineTexture object cached at the Status try { LineTexture = Context( *S )( this ) ( GlossyValues ) ( TEXTURE() ); } catch(const GLError&) {} // if none is there, then create one if (!LineTexture) { LineTexture = new GlossyTexture(0); LineTexture->enlighten(); LineTexture->enlighten(GlossyParameters, Context); GLCHECK( LineTexture->enlighten ); Context[ *S ][ this ][ GlossyValues ] ( TEXTURE() ) = LineTexture; } double width = 1.0; Thickness << Context >> width; if (width<=0.0) width=0.01; glEnable(GL_LINE_SMOOTH); glEnable(GL_POINT_SMOOTH); glDisable(GL_LIGHTING); glColor3f(.9,.4,.9); glEnable( GL_DEPTH_TEST ); glLineWidth(width); // GLCHECK( glLineWidth(width) ); // glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); // glBlendFunc(GL_ONE, GL_ONE); // glEnable( GL_BLEND ); glDisable( GL_BLEND ); glEnable ( GL_COLOR_MATERIAL ); { // Enable the glossy texture for all subsequent OpenGL operations GlossyTexture::Render LINERENDER( *LineTexture, Context.CameraSettings ); RefPtr<ValueSet> myCacheableValues = new ValueSet(); string VBOKey = ""; // fragment ID here in future extension RefPtr<VBO> myVBO; Intercube&CacheObject = *S->theGridOfInterest; // try to get a VBO try { myVBO = Context( CacheObject )( typeid(*this) )( myCacheableValues )( VERTEXBUFFER(), VBOKey ); } catch(...){} LineSet LS(S->theGridOfInterest); // if none, need to create one if (!myVBO || !myVBO->getRenderer() || (LS.Coords && myVBO->isOlderThan( *LS.Coords) ) || (LS.LineIndices && myVBO->isOlderThan( *LS.LineIndices) ) ) { RefPtr<MemBase> Pts = LS.Coords->getData(); assert(Pts); RefPtr<VertexArray> VA = GL::FieldBuffer<VertexArray>::create( Pts, true ); myVBO = Context[ CacheObject ][ typeid(*this) ][ myCacheableValues ] ( VERTEXBUFFER(), VBOKey ); myVBO->clear(); // printf("GlossyLines: VBO %p is %d yet, add %d vertices (%d points)\n", // &*myVBO, myVBO->NumberOfElements(), VA->NumberOfElements(), Pts->nElements() ); myVBO->append(VA ); #if 1 if (RefPtr<LineSet::TangentialVector_t> TV = LS.getTangentialVectors() ) { // printf("GlossyLines: %d vertices, add %d tangential vectors\n", // Pts->nElements(), TV->nElements() ); assert( TV->nElements() == Pts->nElements() ); const int TextureUnit = 0; RefPtr<TexCoordArray> TCA = GL::FieldBuffer<TypedTexCoordArray<Eagle::tvector3> >::createParam( TextureUnit, TV, false, NullPtr()); myVBO->append( TCA ); // puts("appended tangential arrays");fflush(stdout); } // else puts("GlossyLines: NO Tangential Vectors Available :("); #endif myVBO->setRenderer( new GL::LineSetRenderer( S->theGridOfInterest ) ); } // if (myVBO->isOlderThan( *S->theGridOfInterest ) ) {puts("GlossyLines: RENDERER is outdated!");} RefPtr<GL::LineSetRenderer> R = myVBO->getRenderer(); if (!R) { puts("GlossyLines: Renderer Problem"); return; } WhichLine << Context >> R->WhichOneOnly; nLines << Context >> R->nLines; // finally just call the VBO myVBO->call(); } } // // Object Creation // struct GridInspector { static SkeletonExistence InspectionProperty() { return SkeletonExistence( LineSet::ID() ); } }; static Ref<GridActor<GridInspector, GlossyLines> > MyGlossyLinesCreator( "Display/GlossyLines", ObjectQuality::MATURE); } // anon namespace