Question

I'm using OpenSceneGraph in Android with GLES2.

I have two cameras: one for the scene and the other for the HUD. The scene camera is the main camera in my osgViewer. My trouble is with the HUD's camera. I am trying to add an OSG geometry to the 2D scene (HUD camera) but can't seem to get it to show up.

I'm using custom shaders to manipulate the geometry's position. To my understanding the projection matrix is correct but I think the problem may be with the view matrix since I'm using two cameras. I've tried setting the HUD's view to be the scene's initial view but to no avail. Please correct me if I am wrong in this.

   // New camera for the HUD
   hud_camera = new osg::Camera;

   // Set the camera's view properties
   hud_camera->setProjectionMatrix(
      osg::Matrix::ortho2D(0, 1280, 0, 696));
   hud_camera->setReferenceFrame(osg::Transform::ABSOLUTE_RF);
   hud_camera->setViewMatrix(osg::Matrix::identity());
   hud_camera->setViewport(0, 0, 1280, 696);

   // Clear the depth buffer
   hud_camera->setClearMask(GL_DEPTH_BUFFER_BIT);

   // Draw the subgraph after the main camera view and don't allow this camera
   // to grab evente focurs from the main camera
   hud_camera->setRenderOrder(osg::Camera::POST_RENDER);
   hud_camera->setAllowEventFocus(false);


   osg::Geode *       geode;
   osg::Geometry *    geom;
   osg::Vec3Array *   vertices;
   osg::Program *     program;

   // Create the geode and geometry to hold the crosshair image
   geode = new osg::Geode;
   geom = new osg::Geometry;
   geode->addDrawable(geom);
   hud_camera->addChild(geode);

   // Set the vertices
   vertices = new osg::Vec3Array;
   vertices->push_back(osg::Vec3(0.0, 0.0, 0.0));
   vertices->push_back(osg::Vec3(1.0, 0.0, 0.0));
   vertices->push_back(osg::Vec3(1.0, 0.0, 1.0));
   vertices->push_back(osg::Vec3(0.0, 0.0, 1.0));
   geom->setVertexArray(vertices);

   // set colors
   osg::Vec4Array* colors = new osg::Vec4Array;
   colors->push_back(osg::Vec4(1.0, 0.0, 0.0, 1.0));
   colors->push_back(osg::Vec4(0.0, 1.0, 0.0, 1.0));
   colors->push_back(osg::Vec4(0.0, 0.0, 1.0, 1.0));
   colors->push_back(osg::Vec4(1.0, 0.0, 1.0, 1.0));
   geom->setVertexAttribArray(7, colors);
   geom->setVertexAttribBinding(7, osg::Geometry::BIND_PER_VERTEX);

   // Set primitive set
   geom->addPrimitiveSet(new osg::DrawArrays(GL_QUADS, 0, 4));
   geom->setUseVertexBufferObjects(true);

   // Vertex Shader
   char vertSource[] =
   "attribute vec4 osg_Vertex;\n"
   "attribute vec4 a_col;"
   "uniform mat4 osg_ModelViewProjectionMatrix;\n"
   "uniform mat4 proj_matrix;\n"
   "uniform mat4 view_matrix;\n"
   "varying vec4 v_col;"
   "void main(void)\n"
   "{\n"
   "gl_Position = view_matrix * proj_matrix * osg_Vertex;\n"
   "v_col = a_col;\n"
   "}\n";

   // Fragment shader
   char fragSource[] =
   "precision mediump float;\n"
   "varying vec4 v_col;"
   "void main(void)\n"
   "{\n"
   "gl_FragColor = v_col;\n"
   "}\n";

   // Set the shaders
   program = new osg::Program;
   program->setName("Crosshair Shader");
   program->addShader(new osg::Shader(osg::Shader::VERTEX, vertSource));
   program->addShader(new osg::Shader(osg::Shader::FRAGMENT, fragSource));
   program->addBindAttribLocation("a_col", 7);

   osg::StateSet* state = geode->getOrCreateStateSet();
   state->addUniform(
      new osg::Uniform("proj_matrix", hud_camera->getProjectionMatrix()));
   state->addUniform(
      new osg::Uniform("view_matrix", hud_camera->getViewMatrix());

   // Add the program shaders
   geode->getOrCreateStateSet()->setAttributeAndModes(
      program, osg::StateAttribute::ON );

   // Needs no lighting or any depth for a 2D image
   geode->getOrCreateStateSet()->setMode(GL_LIGHTING, osg::StateAttribute::OFF);
   state->setMode(GL_DEPTH_TEST, osg::StateAttribute::OFF);

Afterwards I attach the hud_camera as a child to the scene data. Also the scene camera is doing nothing special other than looking at a particular point in the scene.

I do know for a fact that the geometry is being created. By using this in the vertex shader:

gl_Position = osg_ModelViewProjectionMatrx * osg_Vertex

I can see it off to the left in the scene.

Was it helpful?

Solution

First of all, you shouldn't be performing view * proj * vertex, it should be proj * view * vertex.

For a hud I think don't really need to have a view matrix at all. My understanding is that you just want to draw a flat quad on the screen?

If your projection matrix maps (0,0) to (1280,696), then you can just draw objects in this coordinate system (a quad from (0,0) to (640,696) will cover the left half of the screen, etc).

Or if you want to draw things in the space from (0,0) to (1,1) then just override the projection matrix to map this space. It doesn't make much sense to me to involve a view matrix for something as simple as a HUD.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top