Hello OSGers.
I have been trying to implement a HUD in my unorthodox application. I am currently displaying 3 models to the screen where I have everything else transparent. Thus the application works as an overlay on top of whatever other application the user wishes to run. To do this I am using the pbuffer in OSG, where I copy all the pixel info over into a struct and then pre multiply the alpha values of everything and then render it back to the screen.
Because of this I have a very specific way in which I set up my scene and camera:
Code:
osg::ref_ptr<osg::Referenced> windata = new osgViewer::GraphicsWindowWin32::WindowData(hWnd);
// Establish Viewer and Camera;
g_viewer = new osgViewer::Viewer();
g_camera = new osg::Camera;
g_camera = g_viewer->getCamera();
// Create and assignTraits for the Graphics Context
osg::ref_ptr<osg::GraphicsContext::Traits> traits = new osg::GraphicsContext::Traits;
initOSGTraits (*traits, windata);
osg::ref_ptr<osg::GraphicsContext> gc = osg::GraphicsContext::createGraphicsContext(traits.get());
//Set camera state
g_camera->setGraphicsContext (gc);
g_camera->setDrawBuffer (GL_NONE);
g_camera->setReadBuffer (GL_NONE);
g_camera->setProjectionMatrixAsPerspective (30.0f, (double)sWidth / (double)sHeight, 1.0, 1000.0);
g_camera->setViewport (new osg::Viewport(0, 0, sWidth, sHeight));
g_camera->setClearColor (osg::Vec4f(0.0f, 0.0f, 0.0f, 0.0f));
g_camera->setRenderOrder (osg::Camera::PRE_RENDER);
g_camera->setRenderTargetImplementation (osg::Camera::FRAME_BUFFER_OBJECT);
// Set camera direction and perspective
osg::Vec3d eye = osg::Vec3d(0, -100, 0); // position of the camera
osg::Vec3d center = osg::Vec3d(0, 0, 0); // where does the camera look.
osg::Vec3d up = osg::Vec3d(0, 0, 1); // the up vector of the camera
g_camera->setViewMatrixAsLookAt(eye, center, up);
// Establish PBuffer using OSG's image object. Attach it to the camera.
g_image = new osg::Image();
g_image->allocateImage(sWidth, sHeight, 1, GL_RGBA, GL_UNSIGNED_BYTE);
g_camera->attach(osg::Camera::COLOR_BUFFER, g_image);
// Set Callback for adding textures. Makes sharing textures possible.
osgDB::Registry::instance()->setReadFileCallback(new ReadAndShareImageCallback);
osgDB::Registry::instance()->getOrCreateSharedStateManager();
osg::ref_ptr<osg::Group> models = InitModels();
osg::ref_ptr<osg::Group> root = new osg::Group;
root->addChild(models);
// Run OSG optimizer for efficiency.
osgUtil::Optimizer optimizer;
optimizer.optimize(root.get());
//Set up threads to windows, getScene data and set GL mode for rescaling normals.
g_viewer->realize();
g_viewer->setSceneData(root.get());
root->getOrCreateStateSet()->setMode(GL_NORMALIZE, osg::StateAttribute::ON);
I tried using the example from the OSG for beginners book in chapter 7: Creating an HUD camera. I also tried to follow the example here (
http://trac.openscenegraph.org/projects/osg//browser/OpenSceneGraph/trunk/examples/osghud/osghud.cpp). Unfortunately none of these seemed to work for me. In fact nothing showed up on my screen at all. I was thinking it may be because of the way I define my camera matrix. Maybe not, Im a bit too much of a newbie to know.
Anyways, I figured a HUD can just as well be a quad that is right up close to the camera. So I used this code :
Code:
osg::ref_ptr<osg::Geode> geod = new osg::Geode;
osg::ref_ptr< osg::Geometry> geom = new osg::Geometry;
osg::ref_ptr<osg::Vec3Array> verts = new osg::Vec3Array;
osg::ref_ptr<osg::Vec3Array> norms = new osg::Vec3Array;
osg::ref_ptr<osg::Vec4Array> colors = new osg::Vec4Array;
float depth = -99.0f;
verts->push_back(osg::Vec3((1.0f / 3.0f), depth, (1)));
verts->push_back(osg::Vec3((1), depth, (1)));
verts->push_back(osg::Vec3((1), depth, -(1)));
verts->push_back(osg::Vec3((1.0f / 3.0f), depth, -(1)));
norms->push_back(osg::Vec3(0.0, 0.0f, 0.0f));
colors->push_back(osg::Vec4(1.0f, 1.0f, 1.0f, 0.8f));
geom->setVertexArray(verts);
geom->setNormalArray(norms, osg::Array::BIND_OVERALL);
geom->setColorArray(colors, osg::Array::BIND_OVERALL);
geom->addPrimitiveSet(new osg::DrawArrays(GL_QUADS, 0, 4));
osg::ref_ptr<osg::StateSet> stateset = geom->getOrCreateStateSet();
stateset->setMode(GL_BLEND, osg::StateAttribute::ON);
stateset->setRenderingHint(osg::StateSet::TRANSPARENT_BIN);
geod->addDrawable(geom);
After playing around I realized that the 0,0 point of the quad was in fact right in the middle of my scene. But by using the z depth of -99 which is 1 point off my camera z depth I can use the [0,1] range to make it fit where I want. Thus I get a nice horizontal bar along the left side of the screen.
Now this feels like a somewhat unusual way of doing things. How would I do this in a more professional way or standardized way, I guess I should say? Also on a side note, I only get about 36 fps with this application at the moment. If anyone feels inspired to give me some tips on how to make this more efficient that would be most appreciated.
------------------
Read this topic online here:
http://forum.openscenegraph.org/viewtopic.php?p=60885#60885
_______________________________________________
osg-users mailing list
osg-...@lists.openscenegraph.org
http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org