VISH
0.2
|
Draw the bounding box of some VObject, if that one provides the respective information as an interface. This example demonstrates uses Render Anemone objects to perform the actual rendering. A Render Anemone is an Vish object to encapsulate rendering operations, see Wizt::Anemone for detailed documentation and the BoundingVolume.cpp example, which demonstrates drawing a Bounding Volume using raw OpenGL, without the Anemone object.
#include <ocean/plankton/VPipeline.hpp> #include <ocean/GLvish/VGLRenderObject.hpp> #include <ocean/eagle/PhysicalSpace.hpp> #include <ocean/eagle/GL/EagleGL.hpp> #include <ocean/GLvish/BoundingBox.hpp> #include <ocean/GLvish/GLFonts.hpp> using namespace Wizt; using namespace Eagle; namespace { class BoundingBoxRenderer : public VGLRenderObject { public: TypedSlot<VBoundingBox> myData; TypedSlot<double> Thickness, FontSize; TypedSlot<GLFontManager> MyFonts; BoundingBoxRenderer(const string&name, int p, const RefPtr<VCreationPreferences>&VP) : VGLRenderObject(name, p, VP) , myData( this, "source", VBoundingBox() ) , Thickness(this, "thickness", 1.5, NullPtr(), 5) , FontSize(this, "fontsize", 1.0, NullPtr(), 0) , MyFonts(this, "fonts", Empty(), 10 ) { FontSize.setProperty("max",10.0); Thickness.setProperty("max",10.0); } override bool update(VRequest&Context, double precision); override void render(VGLRenderContext&Context) const; static string createChildname(const string&parent_name) { return "BoundingVolumeOf" + parent_name; } }; bool BoundingBoxRenderer::update(VRequest&Context, double precision) { VBoundingBox BBox; myData << Context >> BBox; if (!BBox) { resetBBox( Context ); return true; } setBoundingBall(Context, BBox); return true; } class FontTentacle : public Anemone::SpecializedTentacle<Anemone::DisplayLists> { public: string text; Eagle::PhysicalSpace::point Position; double FontScale; RefPtr<GLFontManager::Font> myFont; FontTentacle(const string&txt, const Eagle::PhysicalSpace::point&thePosition, double theFontScale, const RefPtr<GLFontManager::Font>&theFont) : text(txt) , Position( thePosition ) , FontScale ( theFontScale ) , myFont( theFont ) { myFont->setSize(2); } override bool activate(const Anemone&) { float llx, lly, llz, urx, ury, urz; glPushMatrix(); glTranslate( Position ); myFont->getBBox( text.c_str(), llx, lly, llz, urx, ury, urz); glTranslatef( -FontScale*(urx-llx)/2, -(ury-lly), 0); glScalef(FontScale, FontScale, FontScale ); myFont->render(text.c_str() ); glPopMatrix(); return true; } override bool deactivate(const Anemone&) { return true; } }; void BoundingBoxRenderer::render(VGLRenderContext&Context) const { VBoundingBox IB; myData << Context >> IB; if (!IB) return; using namespace Eagle::PhysicalSpace; point P0 = IB->center(), P1 = IB->center(); RefPtr<BoundingBox> BB = IB; if (BB) { P0 = BB->mincoord(); P1 = BB->maxcoord(); } else { for(int i=0; i<P0.SIZE; i++) { P0[i] -= IB->radius(); P1[i] += IB->radius(); } } double FontScale = 1.0; FontSize << Context >> FontScale; if (FontScale>0.0) { RefPtr<Anemone> FontAnemone = new Anemone(); if (GLFontManager*V = GLFontManagerCreator::getFontManager() ) { RefPtr<GLFontManager::Font> MyFont = V->newFont("arial.ttf;Vera.ttf",';'); if (MyFont) { MyFont->setSize(2); { float front_emission[4] = { 0.3, 0.2, 0.1, 0.0 }; float front_ambient[4] = { 0.2, 0.2, 0.2, 0.0 }; float front_diffuse[4] = { 0.95, 0.95, 0.8, 0.0 }; float front_specular[4] = { 0.6, 0.6, 0.6, 0.0 }; glMaterialfv(GL_FRONT, GL_EMISSION, front_emission); glMaterialfv(GL_FRONT, GL_AMBIENT, front_ambient); glMaterialfv(GL_FRONT, GL_DIFFUSE, front_diffuse); glMaterialfv(GL_FRONT, GL_SPECULAR, front_specular); glMaterialf(GL_FRONT, GL_SHININESS, 16.0); glColor4fv(front_diffuse); glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, GL_FALSE); glColorMaterial(GL_FRONT, GL_DIFFUSE); glEnable(GL_COLOR_MATERIAL); glDisable( GL_TEXTURE_2D); glEnable( GL_DEPTH_TEST); glDisable( GL_BLEND); } glEnable( GL_NORMALIZE ); { char coords0[2048]; sprintf(coords0,"(%lg,%lg,%lg)", P0[0], P0[1], P0[2] ); Ref<FontTentacle> TextAtP0( coords0, P0, FontScale, MyFont); FontAnemone->insert( TextAtP0 ); } { char coords1[2048]; sprintf(coords1,"(%lg,%lg,%lg)", P1[0], P1[1], P1[2] ); Ref<FontTentacle> TextAtP1( coords1, P1, FontScale, MyFont); FontAnemone->insert( TextAtP1 ); } FontAnemone->wave(); } else puts("font not found"); } else puts("no font manager"); } // printf("BBOX: %lg,%lg,%lg <-> %lg,%lg,%lg\n", // P0[0], P0[1], P0[2], // P1[0], P1[1], P1[2] ); double width = 20; Thickness << Context >> width; if (width<0.01) width=0.01; point P000 ( P0.x(), P0.y(), P0.z() ), P001 ( P0.x(), P0.y(), P1.z() ), P010 ( P0.x(), P1.y(), P0.z() ), P011 ( P0.x(), P1.y(), P1.z() ), P100 ( P1.x(), P0.y(), P0.z() ), P101 ( P1.x(), P0.y(), P1.z() ), P110 ( P1.x(), P1.y(), P0.z() ), P111 ( P1.x(), P1.y(), P1.z() ); /* This code is inspired by http://www.bluevoid.com/opengl/sig00/advanced00/notes/node290.html */ glLineWidth(width); glEnable(GL_LINE_SMOOTH); glDisable(GL_LIGHTING); glEnable(GL_DEPTH_TEST); glColor3f( 0.5, 0.7, 0.6); RefPtr<Anemone> BBoxAnemone = new Anemone(); { MemVector<point> BoxVertices(24); BoxVertices[ 0] = P000; BoxVertices[ 1] = P010; BoxVertices[ 2] = P010; BoxVertices[ 3] = P011; BoxVertices[ 4] = P011; BoxVertices[ 5] = P001; BoxVertices[ 6] = P001; BoxVertices[ 7] = P000; BoxVertices[ 8] = P100; BoxVertices[ 9] = P110; BoxVertices[10] = P110; BoxVertices[11] = P111; BoxVertices[12] = P111; BoxVertices[13] = P101; BoxVertices[14] = P101; BoxVertices[15] = P100; BoxVertices[16] = P000; BoxVertices[17] = P100; BoxVertices[18] = P010; BoxVertices[19] = P110; BoxVertices[20] = P011; BoxVertices[21] = P111; BoxVertices[22] = P001; BoxVertices[23] = P101; BBoxAnemone->insert( Context.createCoordinates( BoxVertices ) ); } BBoxAnemone->insert( Context.drawPrimitives( RenderBasin::LINES ) ); // actual rendering BBoxAnemone->wave(); glEnable(GL_POINT_SMOOTH); glPointSize(width); RefPtr<Anemone> BBoxCornerAnemone = new Anemone(); { MemVector<point> BoxVertices(8, true); // reserve space for 8 points BoxVertices.push_back( P000 ); BoxVertices.push_back( P010 ); BoxVertices.push_back( P011 ); BoxVertices.push_back( P001 ); BoxVertices.push_back( P100 ); BoxVertices.push_back( P110 ); BoxVertices.push_back( P111 ); BoxVertices.push_back( P101 ); BBoxCornerAnemone->insert( Context.createCoordinates( BoxVertices ) ); } BBoxCornerAnemone->insert( Context.drawPrimitives( RenderBasin::POINTS ) ); // actual rendering BBoxCornerAnemone->wave(); } static VSink< AcceptList<VBoundingBox>, BoundingBoxRenderer> ThisIsMyGreatCreator("Display/AnemoneBoundingVolume", ObjectQuality::DEMO); }