FiberVISH 0.2
Fish - The Fiber Bundle API for the Vish Visualization Shell
MonochromeSurface.cpp
Spherical surface displayed via MonochromeSurface module.
Author
werner 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/GLvish/VGLRenderObject.hpp>
#include <ocean/GLvish/BoundingBox.hpp>
#include <ocean/GLvish/ArrayTypes.hpp>
#include <ocean/GLvish/colors.hpp>
#include <ocean/shrimp/VEnum.hpp>
#include <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>
#include <ocean/Anemonia/FloatOrigin.hpp>
using namespace Wizt;
using namespace Fiber;
using namespace Eagle;
namespace
{
class MonochromeSurface : public VSkeletonRenderObject
, public FloatOrigin
{
public:
struct MyState : State, TriangularSurface
{
using TriangularSurface::operator=;
Eagle::tvector3 TranslationVector = {0,0,0};
};
RefPtr<State> newState() const override
{
return new MyState();
}
TypedSlot<double> LineWidth;
TypedSlot<VEnum> SurfaceMode;
MonochromeSurface(const string&name, int p, const RefPtr<VCreationPreferences>&VP)
, LineWidth(this, "linewidth", 1.5, 1)
, SurfaceColor(this, "color", Color(.8,.5,.1, 1.0),0)
, SurfaceMode(this, "mode", VEnum("solid", "line", "points") )
{
LineWidth.setProperty("min", 1.0);
LineWidth.setProperty("max", 10.0);
}
bool renderGL(VGLRenderContext&Context) const override;
bool update(VRequest&R, double precision) override;
/*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)
{
outVisibleGrid << Context <<= GridSelector();
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)
{
outVisibleGrid << Context <<= GridSelector();
return setStatusError(Context, "No surface available.");
}
exportVisibleGrid(Context);
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
*/
{
/*
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;
// double line_width;
void setMode(int i)
{
switch(i)
{
case 0: mode = GL_FILL; break;
case 1: mode = GL_LINE; break;
case 2: mode = GL_POINT; break;
}
}
: Cells(TriangleCells)
, mode(GL_FILL)
// , line_width( line_width_p )
{
mode = GL_LINE;
}
void prefix() override
{
glPolygonMode( face, mode);
}
bool draw() override
{
glPolygonMode( face, mode);
GL::DrawElements( Triangles );
return true;
}
void setLineWidth( double width )
{
glLineWidth( width );
glEnable(GL_POINT_SMOOTH); // make round points
glPointSize( width );
}
};
bool MonochromeSurface::renderGL(VGLRenderContext&Context) const
{
RefPtr<MyState> myState = getState(Context);
if (!myState)
return false;
if (!Surface)
return false;
if (!Surface.CoordField)
{
printf("Did not find coordinates :( \n");
return false;
}
if (!Surface.CellField)
{
printf("Did not find cells :( \n");
// Typename( Surface.CellField->getFieldStorageType() ).c_str() );
return false;
}
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 false;
}
//
// Generic OpenGL section, these settings affect all VBO's rendered later
//
glMaterial( GL::FRONT_AND_BACK, GL::AMBIENT , Color( 0,0,.01,0) );
glMaterial( GL::FRONT_AND_BACK, GL::SPECULAR, Color( 0.5,0.5,.53, 0) );
glMaterial( GL::FRONT_AND_BACK, GL::EMISSION, Color( 0., 0.,0., 0) );
glColor4f(1,0,0, 0.5);
rgba_float_t SurfColor( 1,0,0,0.5 );
VEnum Mode;
double line_width = 1.0;
if( line_width < 1.0 )
line_width = 1.0;
// glEnable( GL_DEPTH_TEST );
// glEnable( GL_MULTISAMPLE_ARB );
// glEnable( GL_SAMPLE_ALPHA_TO_COVERAGE_ARB );
// 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.
Eagle::tvector3 TranslationVector = {0,0,0};
VRenderContext::ModelViewState MVS
= getCoordinateTranslation(Context, TranslationVector);
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)
&& myState->TranslationVector == TranslationVector)
{
if (RefPtr<TriangleRenderer> TR = myVBO->getRenderer() )
{
TR->setLineWidth( line_width );
TR->setMode( Mode.Case("solid", "line", "points") );
if (myVBO->call() )
{
return true;
}
}
}
// 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);
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.
computeShiftedCoordinates( myState->getCoords()->myChunk(), TranslationVector ) ));
// myVBO->append( new TypedVertexArray<point3>( myState->getCoords()->myChunk() ) );
if (RefPtr<TriangularSurface::NormalVectorArray_t> VertexNormals = Surface.getNormals() )
{
myVBO->append( new TypedNormalArray<bivector3>( VertexNormals->myChunk() ));
}
myState->TranslationVector = TranslationVector;
RefPtr<TriangleRenderer> TR = new TriangleRenderer(myState->CellField->getData() );
TR->setLineWidth( line_width );
TR->setMode( Mode.Case("solid", "line", "points") );
myVBO->setRenderer( TR );
myVBO->call();
return true;
}
} // anon namespace
namespace
{
using namespace Panthalassa;
MyCreator( Category( "Display" ) + VIdentifier( "MonochromeSurface" ) + Application( "General" ) +
Description( "Display a triangular surface using standard rendering methods. ")
, ObjectQuality::OUTDATED);
}
An iterator with an optional DataCreator, which is just a class to intercept creation of data along a...
Definition CreativeIterator.hpp:34
Context information to select a grid from within a bundle.
Definition GridSelector.hpp:26
Base class for objects that render information given on the triangle of a Grid.
Definition TriangleRenderer.hpp:22
bool setProperty(const string &theName, const Type &theValue) const
Base class for objects rendering skeletons of a fiber bundle.
Definition VSkeletonRenderObject.hpp:21
Given a fragmented field of curvilinear coordinates, (3D array of coordinates), build a uniform Grid ...
Definition FAQ.dox:2
note: cannot derive from FloatingSkeletonRenderer as long as independent base class TriangleRenderer ...
DEFAULT_OBJECT
Definition Lytica.hpp:7
Definition GridInspector.hpp:13
A triangular surface stored on a Grid.
Definition TriangularSurface.hpp:43