Hi Paul,
On Tue, 2006-03-07 at 14:17 +0100, paul Anka wrote:
> Hello
> I would like to make an IHM 2D on my scene, like an on
> screen display.
> I've read on the user-list that some of your are using
> the MatrixCamera, or the new CVS OSGOrthographic... to
> do that
> But i dont' understand how to use the OSG primitive
> (such as geometry, quad) with the MatrixCamera or the
> orthographicCamera.
> Do you have any example of that, Because i suppose
> that i don't need to add it on the scene graph, as
> it'a another render...
My recommendation would be to use a second Viewport on top of the
original one, using either a DepthClearBackground (if you want your
display to not interfere with the underlying scene at all), or a
PassiveBackground (if you want it to). That way you are totally
independent and can use whatever separate scenegraph you want.
Given that this question has come up a couple times already, I wrote a
simple example for it (attached).
> And sorry for my english.
It's much better than my French. ;)
Hope it helps
Dirk
// OpenSG Tutorial Example: Overlays
//
// This example shows how to have an overlay, i.e. a second,
// totally independent scene on top of the first one.
//
// Headers
#include <OpenSG/OSGGLUT.h>
#include <OpenSG/OSGConfig.h>
#include <OpenSG/OSGSimpleGeometry.h>
#include <OpenSG/OSGGLUTWindow.h>
#include <OpenSG/OSGSimpleSceneManager.h>
#include <OpenSG/OSGBaseFunctions.h>
#include <OpenSG/OSGTransform.h>
#include <OpenSG/OSGGroup.h>
#include <OpenSG/OSGSimpleMaterial.h>
#include <OpenSG/OSGSimpleTexturedMaterial.h>
#include <OpenSG/OSGImage.h>
// New headers
#include <OpenSG/OSGDepthClearBackground.h>
// Activate the OpenSG namespace
OSG_USING_NAMESPACE
// a separate transformation for every object
TransformPtr cyltrans, tortrans;
// The SimpleSceneManager to manage simple applications
SimpleSceneManager *mgr;
// forward declaration so we can have the interesting stuff upfront
int setupGLUT(int *argc, char *argv[]);
// redraw the window
void display(void)
{
// create the matrix
Matrix m;
Real32 t = glutGet(GLUT_ELAPSED_TIME );
// set the transforms' matrices
m.setTransform(Vec3f(0, 0, osgsin(t / 1000.f) * 1.5),
Quaternion( Vec3f (1, 0, 0), t / 500.f));
beginEditCP(cyltrans, Transform::MatrixFieldMask);
{
cyltrans->setMatrix(m);
}
endEditCP (cyltrans, Transform::MatrixFieldMask);
m.setTransform(Vec3f(osgsin(t / 1000.f), 0, 0),
Quaternion( Vec3f (0, 0, 1), t / 1000.f));
beginEditCP(tortrans, Transform::MatrixFieldMask);
{
tortrans->setMatrix(m);
}
endEditCP (tortrans, Transform::MatrixFieldMask);
mgr->redraw();
}
// Initialize GLUT & OpenSG and set up the scene
int main(int argc, char **argv)
{
// OSG init
osgInit(argc,argv);
// GLUT init
int winid = setupGLUT(&argc, argv);
// the connection between GLUT and OpenSG
GLUTWindowPtr gwin= GLUTWindow::create();
gwin->setId(winid);
gwin->init();
// create the objects
// This is taken from the materials example, you can skip to the next
// part for the new stuff
// Object 1: A cylinder
NodePtr cyl = Node::create();
GeometryPtr cylgeo = makeCylinderGeo( 1.4, .3, 8, true, true, true );
beginEditCP(cyl, Node::CoreFieldMask);
{
cyl->setCore(cylgeo);
}
endEditCP (cyl, Node::CoreFieldMask);
cyltrans = Transform::create();
NodePtr cyltransnode = Node::create();
beginEditCP(cyltransnode, Node::CoreFieldMask | Node::ChildrenFieldMask);
{
cyltransnode->setCore (cyltrans);
cyltransnode->addChild(cyl );
}
endEditCP (cyltransnode, Node::CoreFieldMask | Node::ChildrenFieldMask);
SimpleMaterialPtr m1 = SimpleMaterial::create();
beginEditCP(m1);
{
m1->setAmbient (Color3f(0.2,0.2,0.2));
m1->setDiffuse (Color3f(0.8,0.5,0.2));
m1->setEmission (Color3f(0.0,0.0,0.0));
m1->setSpecular (Color3f(1.0,1.0,1.0));
m1->setShininess (10);
m1->setTransparency (0);
m1->setColorMaterial(GL_NONE);
}
endEditCP (m1);
// assign the material to the geometry
beginEditCP(cylgeo, Geometry::MaterialFieldMask );
{
cylgeo->setMaterial(m1);
}
endEditCP (cylgeo, Geometry::MaterialFieldMask );
// Object 2: a torus
NodePtr torus = Node::create();
GeometryPtr torusgeo = makeTorusGeo( .2, 1, 8, 12 );
beginEditCP(torus, Node::CoreFieldMask);
{
torus->setCore(torusgeo);
}
endEditCP (torus, Node::CoreFieldMask);
tortrans = Transform::create();
NodePtr tortransnode = Node::create();
beginEditCP(tortransnode, Node::CoreFieldMask | Node::ChildrenFieldMask);
{
tortransnode->setCore (tortrans);
tortransnode->addChild(torus );
}
endEditCP (tortransnode, Node::CoreFieldMask | Node::ChildrenFieldMask);
ImagePtr image = Image::create();
if(argc > 1)
{
image->read(argv[1]);
}
else
{
UChar8 data[] = { 0xff, 0xff, 0xff, 0x80, 0x00, 0x00,
0x80, 0x00, 0x00, 0xff, 0xff, 0xff };
beginEditCP(image);
image->set( Image::OSG_RGB_PF, 2, 2, 1, 1, 1, 0, data );
endEditCP(image);
}
SimpleTexturedMaterialPtr m2 = SimpleTexturedMaterial::create();
beginEditCP(m2);
{
m2->setLit(false);
m2->setColorMaterial(GL_NONE);
m2->setImage (image);
m2->setMinFilter (GL_LINEAR_MIPMAP_LINEAR);
m2->setMagFilter (GL_NEAREST);
m2->setEnvMode (GL_REPLACE);
m2->setEnvMap (false);
}
endEditCP (m2);
// assign the material to the geometry
beginEditCP(torusgeo, Geometry::MaterialFieldMask );
{
torusgeo->setMaterial(m2);
}
endEditCP (torusgeo, Geometry::MaterialFieldMask );
// The interesting stuff starts here.
// We want the two objects to be in independent planes overlayed on top
// of each other. To do that we will use a second Viewport
// First we let the SSM create the first one and set up ancillary
// structures like the Camera and its beacon
mgr = new SimpleSceneManager;
// tell the manager what to manage
mgr->setWindow(gwin );
mgr->setRoot (cyltransnode);
// Now the Window has a first Viewport, which we will use as a source
// for some settings.
ViewportPtr ovp = gwin->getPort(0);
// Create the second Viewport
ViewportPtr vp = Viewport::create();
beginEditCP(vp);
// Viewport have to have a the following to work: a root, a camera,
// a background and positions/size
// Use the torus as the root.
// Note: this graph doesn't have a light (the SSM creates the headlight
// for the first viewport's, but this one is separate). If you want one
// you'd have to add it manually.
vp->setRoot(tortransnode);
// Here we share the Camera with the original Viewport. If you want
// a different view (e.g. an orthographic view), you can create a new
// camera here.
vp->setCamera(ovp->getCamera());
// We use a DepthClearBackground to prevent the new viewport from deleting
// the old one's contents, but to use an empty depth buffer.
// If you want the two to interfere, use a PassiveBackground here.
vp->setBackground(DepthClearBackground::create());
// We copy the size from the old viewport for the new one to completely
// cover it.
vp->setLeft (ovp->getLeft());
vp->setRight (ovp->getRight());
vp->setTop (ovp->getTop());
vp->setBottom(ovp->getBottom());
endEditCP(vp);
// Now add the new Viewport to the Window
beginEditCP(gwin);
gwin->addPort(vp);
endEditCP(gwin);
// show the whole scene (actually only the scene of the first viewport)
mgr->showAll();
// GLUT main loop
glutMainLoop();
return 0;
}
//
// GLUT callback functions
//
// react to size changes
void reshape(int w, int h)
{
mgr->resize(w, h);
glutPostRedisplay();
}
// react to mouse button presses
void mouse(int button, int state, int x, int y)
{
if (state)
mgr->mouseButtonRelease(button, x, y);
else
mgr->mouseButtonPress(button, x, y);
glutPostRedisplay();
}
// react to mouse motions with pressed buttons
void motion(int x, int y)
{
mgr->mouseMove(x, y);
glutPostRedisplay();
}
// react to keys
void keyboard(unsigned char k, int x, int y)
{
switch(k)
{
case 27:
{
OSG::osgExit();
exit(0);
}
break;
}
}
// setup the GLUT library which handles the windows for us
int setupGLUT(int *argc, char *argv[])
{
glutInit(argc, argv);
glutInitDisplayMode(GLUT_RGB | GLUT_DEPTH | GLUT_DOUBLE);
int winid = glutCreateWindow("OpenSG");
glutReshapeFunc(reshape);
glutDisplayFunc(display);
glutMouseFunc(mouse);
glutMotionFunc(motion);
glutKeyboardFunc(keyboard);
// call the redraw function whenever there's nothing else to do
glutIdleFunc(display);
return winid;
}