Spherical surface displayed via MonochromeSurface module.
Display a triangular surface in monochrome colors. Very minimalistic simple code.
More advanced surface renderers are PolychromeSurface, TransparentSurface and CrystalSurface_8cpp-example.html ( CrystalSurface.cpp ).
#include <ocean/plankton/VCreator.hpp> #include <ocean/GLvish/VGLRenderObject.hpp> #include <ocean/GLvish/BoundingBox.hpp> #include <ocean/GLvish/ArrayTypes.hpp> #include <ocean/GLvish/colors.hpp> //#include <ocean/shrimp/VObjectStatus.hpp> #include <ocean/shrimp/VEnum.hpp> #include <ocean/eagle/PhysicalSpace.hpp> #include <field/Cell.hpp> #include <GL/fiberGL.hpp> #include <baseop/ExpandBBox.hpp> #include <eye/retina/VSkeletonRenderObject.hpp> #include <grid/types/TriangularSurface.hpp> #include <bundle/BundleProperty.hpp> #include <bone/GridActor.hpp> using namespace Wizt; using namespace Fiber; using namespace Eagle; namespace { class MonochromeSurface : public VSkeletonRenderObject { public: struct MyState : State, TriangularSurface { using TriangularSurface::operator=; }; override RefPtr<State> newState() const { return new MyState(); } TypedSlot<rgba_float_t> SurfaceColor; TypedSlot<VEnum> SurfaceMode; MonochromeSurface(const string&name, int p, const RefPtr<VCreationPreferences>&VP) : VGLRenderObject(name,DEFAULT_OBJECT, VP) , Fish<VObject>(this) , VSkeletonRenderObject(name, DEFAULT_OBJECT, VP) , SurfaceColor(this, "color", makeColor(.8,.5,.1, 1.0),0) , SurfaceMode(this, "mode", VEnum(0, "solid", "line", "points") ) {} override void render(VGLRenderContext&Context) const; override bool update(VRequest&R, double precision); static string createChildname(const string&parent_name) { return "MonochromeSurface(" + parent_name + ")"; } }; bool MonochromeSurface::update(VRequest&Context, double precision) { RefPtr<MyState> S = myState(Context); RefPtr<Grid> G = findMostRecentGrid( Context ); if (!G) { removeState(Context); return setStatusError(Context, "No Grid found."); } /* Assign grid pointer to TriangularSurface, which investigates the Grid for properties conforming to a TriangularSurface. If the Grid is not a TriangularSurface, then the following status check witll return false. */ *S = G; if (!*S) return setStatusError(Context, "No surface available."); setBoundingBall(Context, getBoundingBox( S->CoordField ) ); return setStatusInfo(Context, "Surface ready to render."); } /* VBO render call back, allows to set the glPolygonMode . http://www.opengl.org/sdk/docs/man/xhtml/glPolygonMode.xml */ struct TriangleRenderer : VBO::Renderer { RefPtr<TriangularSurface::CellArray_t> Cells; /* GL_FRONT for front-facing polygons, GL_BACK for back-facing polygons, or GL_FRONT_AND_BACK */ GLenum face; /* Specifies how polygons will be rasterized. Accepted values are GL_POINT, GL_LINE, and GL_FILL. */ GLenum mode; void setMode(int i) { switch(i) { case 0: mode = GL_FILL; break; case 1: mode = GL_LINE; break; case 2: mode = GL_POINT; break; } } TriangleRenderer(const RefPtr<TriangularSurface::CellArray_t>&TriangleCells) : Cells(TriangleCells) , face(GL_FRONT_AND_BACK) , mode(GL_FILL) { mode = GL_LINE; } override void prefix() { glPolygonMode( face, mode); glEnable(GL_NORMALIZE); glDisable( GL_BLEND ); } override bool draw() { MultiArray<1, TriangleCell> Triangles = *Cells; glPolygonMode( face, mode); GL::DrawElements( Triangles ); return true; } }; void MonochromeSurface::render(VGLRenderContext&Context) const { RefPtr<MyState> myState = getState(Context); if (!myState) return; TriangularSurface&Surface = *myState; if (!Surface) return; if (!Surface.CoordField) { printf("Did not find coordinates :( \n"); return; } if (!Surface.CellField) { printf("Did not find cells :( \n"); // Typename( Surface.CellField->getFieldStorageType() ).c_str() ); return; } if (!Surface.CellField->getData()) { // printf("Did not find cells :( %s\n", // Typename( Surface.CellField->getFieldStorageType() ).c_str() ); // Surface.CellField.Speak(" Surface.CellField"); // Surface.CellField->getCreator().Speak(" Surface.CellField->getCreator()"); // Surface.CellField->getData().Speak(" Surface.CellField->getData()"); puts("MonochromeSurface: No triangles."); return; } // // Generic OpenGL section, these settings affect all VBO's rendered later // glEnable(GL_LIGHTING); glMaterialf( GL_FRONT, GL_SHININESS, 3 ); glMaterialf( GL_BACK , GL_SHININESS, 50 ); glMaterial( GL::FRONT_AND_BACK, GL::AMBIENT , makeColor( 0,0,.01,0) ); glMaterial( GL::FRONT_AND_BACK, GL::SPECULAR, makeColor( 0.5,0.5,.53, 0) ); glMaterial( GL::FRONT_AND_BACK, GL::EMISSION, makeColor( 0., 0.,0., 0) ); glColor4f(1,0,0, 0.5); glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, GL_TRUE); glColorMaterial( GL_FRONT_AND_BACK, GL_DIFFUSE); glEnable( GL_COLOR_MATERIAL ); rgba_float_t SurfColor( makeColor(1,0,0,0.5 ) ); SurfaceColor << Context >> SurfColor; VEnum Mode; SurfaceMode << Context >> Mode; // glEnable( GL_DEPTH_TEST ); // glEnable( GL_MULTISAMPLE_ARB ); // glEnable( GL_SAMPLE_ALPHA_TO_COVERAGE_ARB ); glColor( SurfColor ); // printf(">>>>> MonochromeSurface: RENDER cells for t=%ld, %lu Triangles\n", // myState->CellField->time_value(), Cells->nElements() ); /* Vertex Buffer Object (VBO) Access via GLCache, retrieve and re-use or generate new VBO The caching mechanism is part of the "Visualization Cascade" and described in the article: @link http://sciviz.cct.lsu.edu/papers/2009/VizCascade.pdf Beyond the Visualization Pipeline: The Visualization Cascade @endlink */ const string VBOKey = ""; // This is an additional parameter for the OpenGL Cache. // It can be an arbitrary string, and this would be the // right place to use the name of a field fragment when // support for fragmented surfaces is added. For now, // such is not supported, and we can keep this key empty. RefPtr<ValueSet> V; // This is a set of values for each of which there should // be one OpenGL cache entry generated. This means that if // a parameter is changed to a value that it already had // in the past, then the VBO that is associated with this // value will be re-used instead of newly generated. // Be *very* cautious about what values to use here, // since every cache entry eats up valueable memory at // the GPU. See documentation for class ValueSet on // how to assign values here. RefPtr<VBO> myVBO; try { // n-dimensional readonly cache indexing (see VizCascade paper) myVBO = Context( *Surface )( typeid(*this) )( V )(VERTEXBUFFER(), VBOKey); // // Call the VBO if it's there and all ready to go. // if (myVBO && !myVBO->isOlderThan( *Surface.CellField) && !myVBO->isOlderThan( *Surface.CoordField) ) { if (RefPtr<TriangleRenderer> TR = myVBO->getRenderer() ) { TR->setMode( Mode.Case("solid", "line", "points") ); if (myVBO->call() ) { return; } } } // Cellfield is newer than surface view VBO, need to re-load VBO } catch(const GLCacheError&Err) {} // // Create new VBO if it doesn't exist yet. // if (!myVBO) myVBO = Context[*Surface][ typeid(*this) ][ V ]( VERTEXBUFFER(), VBOKey); assert( myVBO ); myVBO->clear(); // // Loading fields as vertex arrays and append them to the VBO. // // Vertex arrays are loaded by appending objects that have been // derived from class BufferArray. // using namespace Eagle::PhysicalSpace; // Note: this approach does not support fragmented surfaces. myVBO->append( new TypedVertexArray<point3>( myState->getCoords()->myChunk() ) ); if (RefPtr<TriangularSurface::NormalVectorArray_t> VertexNormals = Surface.getNormals() ) { myVBO->append( new TypedNormalArray<bivector3>( VertexNormals->myChunk() )); } RefPtr<TriangleRenderer> TR = new TriangleRenderer(myState->CellField->getData() ); TR->setMode( Mode.Case("solid", "line", "points") ); myVBO->setRenderer( TR ); myVBO->call(); } // // Object Creation // struct GridInspector { static SkeletonExistence InspectionProperty() { return SkeletonExistence( TriangularSurface::ID() ); } }; static Ref<GridActor<GridInspector, MonochromeSurface> > MyMonochromeSurfaceCreator("Display/MonochromeSurface", ObjectQuality::MATURE); } // anon namespace