![]() |
VR-Vantage 1.4.1 API Class Documentation
|
This example shows how to add a 2D Overlay to a channel.
We will add a logo to the bottom left hand corner of the channel.
It is important to understand the concept of overlay's in VR-Vantage. An overlay is a 2D scene that is drawn on top of a 3D scene. The 2D scene can contain any number of the 2D primitives which include: DtLineSegment, DtQuad, DtFilledPolygon and DtOutlinedPolygon. To draw an overlay we need to add something to the scene. In this case we add a DtOverlayDrawable to the scene. The DtOverlayDrawable is responsible for telling overlays to render themselves at the appropriate time. The class that implements the overlay concept is the DtOverlayRenderer. The DtOverlayRenderer does the actual drawing of the graphical primitives. The DtOverlayDrawable is told which DtOverlayRenderer it should draw. During the render phase, the DtOverlayDrawable tells the DtOverlayRenderer to render itself and the graphics primitives are then rendered.
So to draw our logo we create a DtOverlayDrawable, give it a DtOverlayRenderer to render, then add a DtQuad to the DtOverlayRenderer. Here's how that looks in code...
1. Create the DtOverlayDrawable. Creating the DtOverlayDrawable requires a DtOsgOverlayManager and a DtChannel. Additionally, drawables need to be added to osg::Geodes and somehow added to the scene. Here we add the geode to the scene as a child of the channel's overlay camera. The overlay camera uses an orthographic projection matrix. This has the effect of drawing the graphical primitives in 2D on channel.
// First get the DtChannel we wish to draw the logo on. In this case, just get the first window, // and the first channel. DtChannel* channel = 0; const DtWindowManager::WindowList& windows = de.display()->windowManager().windows(); if ( windows.size() > 0 ) { DtWindow* window = windows.front(); if ( window ) { const DtChannelManager::ChannelMap& channels = window->channelManager().channels(); DtChannelManager::ChannelMap::const_iterator curIter = channels.begin(); channel = curIter->second; if ( ! channel ) { return; } } } DtOsgChannel* osgChannel = dynamic_cast<DtOsgChannel*>(channel); if(!osgChannel) { return; } // Get the DtOsgOverlayManager from the DtDe. DtOsgOverlayManager* osgOverlayManager = (DtOsgOverlayManager*)&de.renderer().overlayManager(); if(!osgOverlayManager) { return; } // A DtOverlayDrawable is the thing added to the scene graph that tells a DtOverlayRenderer when to render. osg::ref_ptr<DtOverlayDrawable> overlayDrawer = new DtOverlayDrawable(*osgOverlayManager, *channel); // Create a geod to add the drawable to. osg::ref_ptr<osg::Geode> geod = new osg::Geode; geod->addDrawable(overlayDrawer); // Add the geod to the scenegraph under the 2D Overlay camera. osgChannel->overlayCamera()->addChild( geod.get() ); // Set the coordinate system of the drawable to be whatever the camera's system is // in this case the overlay camera's system is 2D pixel space overlayDrawer->setProjectionCamera(osgChannel->overlayCamera());
2. Create the DtOverlayRenderer (commonly referred to as the "overlay"). DtOverlayRenderers can be "lazily created" by asking for one that doesn't yet exist. Here we also tell the DtOverlayDrawable to render that specific overlay via the setOverlayToRender call.
// Lazily create a new overlay for the drawable to render. DtOverlayRenderer& overlay = osgOverlayManager->overlayRenderer(DtOverlayManager::Channel_SpecificStart + 0); // Set this drawable to only draw this overlay. overlayDrawer->setOverlayToRender(&overlay);
3. Create the DtQuad on the overlay,assign a texture to it, then position and size it.
// Create a DtQuad to render the logo. Use the DtOsgOverlayManager to get the DtQuadRenderer for the DtQuad
VR-Vantage includes pre-built versions of the example application. To build it yourself, follow the instructions at Building VR-Vantage Examples, Applications, and Plug-ins.
This example is an application. You can run it by running ./bin/exampleLogopage.exe (on Windows) or ./bin/exampleLogopage (on Linux). For more information about running examples, please see Running Applications and Examples.
// /****************************************************************************** // ** Copyright (c) 2010 MAK Technologies, Inc. // ** All rights reserved. // ******************************************************************************/ // /****************************************************************************** // ** $RCSfile: exampleLogo.cxx,v $ $Revision: 1.10 $ $State: Exp $ // ******************************************************************************/ #include <vrvCore/DtDe.h> #include <vrvCore/DtVrvApplication.h> #include <vrvCore/DtChannel.h> #include <vrvCore/DtRenderer.h> #include <vrvCore/DtChannelManager.h> #include <vrvCore/DtWindowManager.h> #include <vrvCore/DtWindow.h> #include <vrvCore/DtDisplay.h> #include <vrvGraphics/DtQuad.h> #include <vrvGraphics/DtBoundingBox.h> #include <vrvOsg/DtOsgOverlayManager.h> #include <vrvOsg/DtOsgFileCache.h> #include <vrvOsg/DtOverlayDrawable.h> #include <vrvOsg/DtOsgChannel.h> #include <vrvOsg/DtOsgModelInstance.h> #include <osg/Geode> using namespace makVrv; void addLogo( DtDe& de ) { if ( ! de.display() ) { return; } // First get the DtChannel we wish to draw the logo on. In this case, just get the first window, // and the first channel. DtChannel* channel = 0; const DtWindowManager::WindowList& windows = de.display()->windowManager().windows(); if ( windows.size() > 0 ) { DtWindow* window = windows.front(); if ( window ) { const DtChannelManager::ChannelMap& channels = window->channelManager().channels(); DtChannelManager::ChannelMap::const_iterator curIter = channels.begin(); channel = curIter->second; if ( ! channel ) { return; } } } DtOsgChannel* osgChannel = dynamic_cast<DtOsgChannel*>(channel); if(!osgChannel) { return; } // Get the DtOsgOverlayManager from the DtDe. DtOsgOverlayManager* osgOverlayManager = (DtOsgOverlayManager*)&de.renderer().overlayManager(); if(!osgOverlayManager) { return; } // A DtOverlayDrawable is the thing added to the scene graph that tells a DtOverlayRenderer when to render. osg::ref_ptr<DtOverlayDrawable> overlayDrawer = new DtOverlayDrawable(*osgOverlayManager, *channel); // Create a geod to add the drawable to. osg::ref_ptr<osg::Geode> geod = new osg::Geode; geod->addDrawable(overlayDrawer); // Add the geod to the scenegraph under the 2D Overlay camera. osgChannel->overlayCamera()->addChild( geod.get() ); // Set the coordinate system of the drawable to be whatever the camera's system is // in this case the overlay camera's system is 2D pixel space overlayDrawer->setProjectionCamera(osgChannel->overlayCamera()); // Lazily create a new overlay for the drawable to render. DtOverlayRenderer& overlay = osgOverlayManager->overlayRenderer(DtOverlayManager::Channel_SpecificStart + 0); // Set this drawable to only draw this overlay. overlayDrawer->setOverlayToRender(&overlay); // Create a DtQuad to render the logo. Use the DtOsgOverlayManager to get the DtQuadRenderer for the DtQuad // to be drawn on. DtQuad* logoQuad = new DtQuad(osgOverlayManager->overlayRenderer(DtOverlayManager::Channel_SpecificStart + 0)); logoQuad->setFillType(DtQuad::Fill_Texture); // Create the texture and assign it to the quad. DtOsgFileCache* osgFileCache = dynamic_cast<DtOsgFileCache*>(de.fileCache()); if(osgFileCache) { std::string logoFilename("../data/Overlays/VtMakLogoTransparent.png"); osg::ref_ptr<osg::Texture> tex = osgFileCache->getTextureInstance(logoFilename, osg::Texture::NEAREST,osg::Texture::LINEAR,osg::Texture::REPEAT,osg::Texture::REPEAT, de.fileCache()->defaultOptions()); //The texture holder will keep the texture object alive. As texture are //referrenced counted and quads do not support reference counting. DtCachedTextureHolder* textureHolder = new DtCachedTextureHolder(de,tex.get()); de.registerInstance("logoQuadTexture",textureHolder); logoQuad->setTextureParameter(tex.get()); } float lowerLeftX = 50.0; float lowerLeftY = 50.0; float imageWidth = 184.0; float imageHeight = 60.0; logoQuad->setPosition(lowerLeftX, lowerLeftY, 0.0, 0.0); float points[8]; DtBoundingBox box(lowerLeftX, lowerLeftY, lowerLeftX+imageWidth, lowerLeftY+imageHeight); box.toPoints(points); logoQuad->setPoints(points); } int main( int argc, char** argv ) { DtVrvApplication igApp; igApp.initialize( argc, argv ); addLogo( igApp.de() ); igApp.run(); }