<div dir="ltr"><br><div>Greetings OSG'ers.</div><div><br></div><div>I have a program which utilizes CompositeViewer to render a "corner window" view of my scene graph, within a bigger main window view. To achieve a boarder effect around the corner window viewport, a HUD overlay used to render a grey box underneath the 2nd view corner window. </div><div><br></div><div>It worked without a hitch  in an older version, 2.8.5 win32 of OpenSceneGraph (build with VisualStudio).</div><div><br></div><div>But when I recompiled the program with a later built version (CMake.exe/VS 2013), I get rather strange object rendering order problems with the objects in the same scene graph with the **2nd, corner window**  of the osgCompositeViewer.  The **first main window** renders perfectly fine. The essence of the code is below. A lot of extra code  is used for determining the appropriate window and HUD boarder 'frame' dimensions and camera view frustums, but barring that,  it is pretty straight forward and not much to it, I think.</div><div><br></div><div>To simplify the code a little bit for brevity, I have the removed Trackball code because with much testing on various configurations this doesn't change the observed behavior anyway (nor does any lighting mode). <br></div><div><br></div><div>I did try clone(osg::CopyOp::SHALLOW_COPY) of the entire scene graph model, and even re-creating parts ofit from scratch and the same</div><div>strange rendering order behavior resulted.</div><div> </div><div>Any advice or insights would be greatly appreciated,</div><div><br></div><div>thanks all,</div><div><br></div><div>ted</div><div><br></div><div><br></div><div><snip></div><div><div><span class="" style="white-space:pre">        </span>.</div><div><span class="" style="white-space:pre">  </span>.</div><div><span class="" style="white-space:pre">  </span>.</div><div><span class="" style="white-space:pre">  </span>// osgViewers decl on the heap</div><div><span style="white-space:pre">        osg::ref_ptr<osgViewer::Viewer>  m_viewer;</span></div><div><span class="" style="white-space:pre">        </span>osg::ref_ptr<osgViewer::Viewer>  m_OVERLAYviewer;</div><div><span class="" style="white-space:pre">   </span>osg::ref_ptr<osgViewer::CompositeViewer>  m_dualviewer;</div><div><span class="" style="white-space:pre">     </span>osg::Camera  * m_HUDcam;<span class="" style="white-space:pre"> </span></div><div><span class="" style="white-space:pre">   </span></div><div><span class="" style="white-space:pre">   </span>// view manipulators configured and constrained as appropriate...</div><div><span class="" style="white-space:pre">  </span>// <-- code removed for brevity...></div><div><span class="" style="white-space:pre">  </span>osgGA::NodeTrackerManipulator   * m_Camera_followcar;</div><div><span class="" style="white-space:pre">     </span>osgGA::NodeTrackerManipulator::TrackerMode   m_trackerMode;</div><div><span class="" style="white-space:pre">       </span>osgGA::NodeTrackerManipulator::RotationMode  m_rotationMode;</div><div><span class="" style="white-space:pre">      </span>osgGA::TrackballManipulator  * m_tbm;</div><div><span style="white-space:pre"><br></span></div><div><span class="" style="white-space:pre"> </span>// NOTE: gw is a wxWidgets OpenGL context canvas set up earlier...</div><div><span class="" style="white-space:pre"> </span>m_viewer->getCamera()->setGraphicsContext(gw);</div><div><span class="" style="white-space:pre">       </span>m_viewer->getCamera()->setClearColor(osg::Vec4(153./0xff, 216./0xff, 238./0xff, 1.0));</div><div><span class="" style="white-space:pre">       </span></div><div><span class="" style="white-space:pre">   </span>// use CullMask to hide rendering of specific nodes in the scene</div><div><span class="" style="white-space:pre">   </span>m_viewer->getCamera()->setCullMask(0x04); </div><div><span class="" style="white-space:pre">  </span>m_viewer->getCamera()->setComputeNearFarMode(osg::CullSettings::DO_NOT_COMPUTE_NEAR_FAR);</div><div><span style="white-space:pre"><br></span></div><div><span class="" style="white-space:pre">        </span>// create a camera to set up the projection and model view matrices, and the subgraph to drawn in the HUD</div><div><span style="white-space:pre">    osg::Camera* camera = new osg::Camera;</span></div><div><span style="white-space:pre"><br></span></div><div><span style="white-space:pre">    // set the projection matrix</span></div><div><span style="white-space:pre">    //camera->setProjectionMatrix(osg::Matrix::ortho2D(0,1280,0,1024));</span></div><div><span class="" style="white-space:pre">      </span>m_width_fraction_of_mainW  = 0.225;  // 0.25;</div><div><span class="" style="white-space:pre">    </span>m_height_fraction_of_mainW = 0.275; //(1.0/3.0);</div><div><span class="" style="white-space:pre">   </span></div><div><span class="" style="white-space:pre">   </span>// ll => "lower left", ur => "upper right"</div><div><span class="" style="white-space:pre">       </span>int xll = -(int)(m_width_fraction_of_mainW  * m_viewersize.GetX())/2;</div><div><span class="" style="white-space:pre">     </span>int yll = -(int)(m_height_fraction_of_mainW * m_viewersize.GetY())/2;</div><div><span class="" style="white-space:pre">      </span>int yur = -yll;</div><div><span class="" style="white-space:pre">    </span>double left = (double)xll/(double)(yur-yll);</div><div><span class="" style="white-space:pre">       </span>double right = -left;</div><div><span class="" style="white-space:pre">      </span>double bottom = -0.5;</div><div><span class="" style="white-space:pre">      </span>double top = 0.5;</div><div><span class="" style="white-space:pre">  </span>double zfar = 13000.0; // make arbitrarily huge ... but not too big so for things like a skydome won't get clipped</div><div><span class="" style="white-space:pre">     </span>double znear = 4.5;</div><div><span class="" style="white-space:pre">        </span>// scale everything so clipping plane is about 0.25 meters</div><div><span class="" style="white-space:pre"> </span>double scale_fac = 0.5/znear;</div><div><span style="white-space:pre"><br></span></div><div><span class="" style="white-space:pre">  </span>znear  *= scale_fac;</div><div><span class="" style="white-space:pre">      </span>left   *= scale_fac;</div><div><span class="" style="white-space:pre">      </span>right  *= scale_fac;</div><div><span class="" style="white-space:pre">      </span>top    *= scale_fac;</div><div><span class="" style="white-space:pre">     </span>bottom *= scale_fac;</div><div><span style="white-space:pre"><br></span></div><div><span class="" style="white-space:pre">   </span>camera->setClearMask(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);</div><div><span style="white-space:pre">    // draw subgraph after main camera view.</span></div><div><span style="white-space:pre"><br></span></div><div><span style="white-space:pre">    // we don't want the camera to grab event focus from the viewers main camera(s).</span></div><div><span style="white-space:pre">    //camera->setAllowEventFocus(true);</span></div><div><span class="" style="white-space:pre">  </span>camera->setAllowEventFocus(false);</div><div><span style="white-space:pre"><br></span></div><div><span class="" style="white-space:pre">  </span>double cornerX0 = 1.0 - m_width_fraction_of_mainW;</div><div><span class="" style="white-space:pre"> </span>double cornerY0 = 1.0 - m_height_fraction_of_mainW;</div><div><span class="" style="white-space:pre">        </span>camera->setViewport( </div><div><span class="" style="white-space:pre">          </span>                 (int)( cornerX0 * m_viewersize.GetX()+5 ),</div><div><span class="" style="white-space:pre">                </span>                 (int)( cornerY0 * m_viewersize.GetY()+5 ),</div><div><span class="" style="white-space:pre">                                                </span> (int)( m_width_fraction_of_mainW *  m_viewersize.GetX()-5 ),</div><div><span class="" style="white-space:pre">                                             </span> (int)( m_height_fraction_of_mainW * m_viewersize.GetY()-5 ) </div><div><span class="" style="white-space:pre">                                             </span>);</div><div><span class="" style="white-space:pre"> </span>zfar = 10000;</div><div><span class="" style="white-space:pre">      </span>camera->setProjectionMatrixAsFrustum(left,right, bottom, top, znear, zfar);</div><div><span class="" style="white-space:pre">     </span>camera->setComputeNearFarMode(osg::CullSettings::DO_NOT_COMPUTE_NEAR_FAR);</div><div><span class="" style="white-space:pre">      </span>camera->setGraphicsContext(gw);</div><div><span class="" style="white-space:pre"> </span>camera->setCullMask(0x02);</div><div><span class="" style="white-space:pre">      </span>camera->setRenderOrder(osg::Camera::POST_RENDER,1);</div><div><span class="" style="white-space:pre">     </span>// =false: we don't want the camera to grab event focus from the viewers main camera(s).</div><div><span class="" style="white-space:pre">       </span>camera->setAllowEventFocus(true); //(false);</div><div><span class="" style="white-space:pre">    </span>m_OVERLAYviewer->setCamera(camera);</div><div><span class="" style="white-space:pre">     </span>m_OVERLAYviewer->getCamera()->setGraphicsContext(gw);</div><div><span style="white-space:pre"><br></span></div><div><span class="" style="white-space:pre">    </span>// <!-- basic NodeTracker manipulator code removed for brevety... --></div><div><span class="" style="white-space:pre">        </span>m_Camera_followcar = new osgGA::NodeTrackerManipulator;</div><div><span class="" style="white-space:pre">    </span>.</div><div><span class="" style="white-space:pre">  </span>.</div><div><span class="" style="white-space:pre">  </span>.</div><div><span class="" style="white-space:pre">  </span></div><div><span class="" style="white-space:pre">   </span>// set up the scene for the camera and camera view using the loaded scene</div><div><span class="" style="white-space:pre">  </span>// model</div><div><span class="" style="white-space:pre">   </span>m_OVERLAYviewer->setSceneData(themodel);</div><div><span class="" style="white-space:pre">        </span></div><div><span class="" style="white-space:pre">   </span>// try HUD slave cam for drawing a boarder</div><div><span class="" style="white-space:pre"> </span>m_HUDcam = new osg::Camera;</div><div><span style="white-space:pre"><br></span></div><div><span class="" style="white-space:pre">    </span>//HUDcam->setProjectionMatrixAsOrtho(0.5*xll,0.5*xur,0.5*yll, 0.5*yur, -1000.0,1000.0);</div><div><span class="" style="white-space:pre"> </span>m_HUDcam->setProjectionMatrix( osg::Matrix::ortho2D(0, m_viewersize.GetX(),0, m_viewersize.GetY()));</div><div><span class="" style="white-space:pre">    </span>// don't let other cam influence this camera's transform view matrix    </div><div><span style="white-space:pre">    m_HUDcam->setReferenceFrame(osg::Transform::ABSOLUTE_RF);</span></div><div><span style="white-space:pre">    </span></div><div><span style="white-space:pre">    // only clear the depth buffer for HUD, so other pixels behind it don't get erased.</span></div><div><span style="white-space:pre">    m_HUDcam->setClearMask(GL_DEPTH_BUFFER_BIT);</span></div><div><span style="white-space:pre"><br></span></div><div><span class="" style="white-space:pre">  </span>// draw subgraph after main camera view.</div><div><span style="white-space:pre">    m_HUDcam->setRenderOrder(osg::Camera::POST_RENDER,0);</span></div><div><span class="" style="white-space:pre">   </span>m_HUDcam->setAllowEventFocus(false);</div><div><span style="white-space:pre"><br></span></div><div><span class="" style="white-space:pre">        </span>// create the frame</div><div><span class="" style="white-space:pre">        </span>osg::MatrixTransform * matrixtransfm = new osg::MatrixTransform;</div><div><span class="" style="white-space:pre">   </span>matrixtransfm->setMatrix(osg::Matrix::identity());</div><div><span class="" style="white-space:pre">      </span></div><div><span class="" style="white-space:pre">   </span>// create the Geode (Geometry Node) to contain all our osg::Geometry objects.</div><div><span style="white-space:pre">    osg::Geode* geode = new osg::Geode();</span></div><div><span class="" style="white-space:pre"> </span>osg::StateSet* stateset = geode->getOrCreateStateSet();</div><div><span style="white-space:pre">    stateset->setMode(GL_LIGHTING,osg::StateAttribute::OFF);</span></div><div><span class="" style="white-space:pre">      </span>matrixtransfm->addChild(geode);</div><div><span style="white-space:pre"><br></span></div><div><span class="" style="white-space:pre">     </span>osg::ref_ptr<osg::Vec4Array> shared_colors = new osg::Vec4Array;</div><div><span class="" style="white-space:pre">     </span>shared_colors->push_back(osg::Vec4(0.75f,0.75f,0.75f,1.0f));</div><div><span class="" style="white-space:pre">    </span></div><div><span class="" style="white-space:pre">   </span>// same trick for shared normal.</div><div><span style="white-space:pre">    osg::ref_ptr<osg::Vec3Array> shared_normals = new osg::Vec3Array;</span></div><div><span style="white-space:pre">    shared_normals->push_back(osg::Vec3(0.0f,-1.0f,0.0f));</span></div><div><span style="white-space:pre"><br></span></div><div><span class="" style="white-space:pre">       </span>// create POLYGON</div><div><span class="" style="white-space:pre">  </span>{</div><div><span style="white-space:pre">        // create Geometry object to store all the vertices and lines primitive.</span></div><div><span style="white-space:pre">        osg::Geometry* polyGeom = new osg::Geometry();</span></div><div><span style="white-space:pre">        </span></div><div><span style="white-space:pre">        // this time we'll a C arrays to initialize the vertices.</span></div><div><span style="white-space:pre">        // note, anticlockwise ordering.</span></div><div><span style="white-space:pre">        // note II, OpenGL polygons must be convex plan polygons, otherwise </span></div><div><span style="white-space:pre">        // undefined results will occur.  If you have concave polygons or ones</span></div><div><span style="white-space:pre">        // that cross over themselves then use the osgUtil::Tessellator to fix</span></div><div><span style="white-space:pre">        // the polygons into a set of valid polygons.</span></div><div><span class="" style="white-space:pre">         </span>double xll =  -2.0;</div><div><span class="" style="white-space:pre">               </span>double yll =  -2.0;</div><div><span class="" style="white-space:pre">               </span>double xlr =  m_width_fraction_of_mainW  * m_viewersize.GetX()+2;</div><div><span class="" style="white-space:pre">                </span>double yur =  m_height_fraction_of_mainW * m_viewersize.GetY()+2;</div><div><span style="white-space:pre">        osg::Vec3 myCoords[] =</span></div><div><span style="white-space:pre">        {</span></div><div><span style="white-space:pre">            osg::Vec3( xll,yll, 0),</span></div><div><span style="white-space:pre">            osg::Vec3( xlr, yll, 0),</span></div><div><span style="white-space:pre">            osg::Vec3( xlr, yur, 0),</span></div><div><span style="white-space:pre">            osg::Vec3(xll, yur, 0)</span></div><div><span style="white-space:pre">        };</span></div><div><span style="white-space:pre"> </span></div><div><span class="" style="white-space:pre">             </span>m_HUDxaxis = xlr - xll;</div><div><span class="" style="white-space:pre">            </span>m_HUDyaxis = yur - yll;</div><div><span style="white-space:pre"><br></span></div><div><span style="white-space:pre">        int numCoords = sizeof(myCoords)/sizeof(osg::Vec3);</span></div><div><span style="white-space:pre">        </span></div><div><span style="white-space:pre">        osg::Vec3Array* vertices = new osg::Vec3Array(numCoords,myCoords);</span></div><div><span style="white-space:pre">       </span></div><div><span style="white-space:pre">        // pass the created vertex array to the points geometry object.</span></div><div><span style="white-space:pre">        polyGeom->setVertexArray(vertices);</span></div><div><span style="white-space:pre">        </span></div><div><span style="white-space:pre">        // use the shared color array.</span></div><div><span style="white-space:pre">        polyGeom->setColorArray(shared_colors.get());</span></div><div><span style="white-space:pre">        polyGeom->setColorBinding(osg::Geometry::BIND_OVERALL);</span></div><div><span style="white-space:pre">        </span></div><div><span style="white-space:pre"><br></span></div><div><span style="white-space:pre">        // use the shared normal array.</span></div><div><span style="white-space:pre">        polyGeom->setNormalArray(shared_normals.get());</span></div><div><span style="white-space:pre">        polyGeom->setNormalBinding(osg::Geometry::BIND_OVERALL);</span></div><div><span style="white-space:pre"> </span></div><div><span style="white-space:pre">        // This time we simply use primitive, and hardwire the number of coords to use </span></div><div><span style="white-space:pre">        // since we know up front,</span></div><div><span style="white-space:pre">        polyGeom->addPrimitiveSet(new osg::DrawArrays(osg::PrimitiveSet::POLYGON,0,numCoords));</span></div><div><span style="white-space:pre"><br></span></div><div><span style="white-space:pre">        // add the points geometry to the geode.</span></div><div><span style="white-space:pre">        geode->addDrawable(polyGeom);</span></div><div><span style="white-space:pre">    }</span></div><div><span class="" style="white-space:pre">     </span>matrixtransfm->setMatrix(osg::Matrix::translate(-200.0,-200.0,0.0));</div><div><span class="" style="white-space:pre">    </span>m_HUDcam->addChild(matrixtransfm);</div><div><span style="white-space:pre"><br></span></div><div><span class="" style="white-space:pre">  </span>m_HUDcam->setViewport(  0 ,0, m_viewersize.GetX(), m_viewersize.GetY());</div><div><span style="white-space:pre"><br></span></div><div><span class="" style="white-space:pre">   </span>m_HUDcam->setGraphicsContext(gw);</div><div><span style="white-space:pre"><br></span></div><div><span class="" style="white-space:pre">   </span>m_viewer->addSlave(m_HUDcam, false);</div><div><span style="white-space:pre"><br></span></div><div><span class="" style="white-space:pre">        </span>// <!-- basic trackball manipulator code removed for brevety... --></div><div><span class="" style="white-space:pre">  </span>m_tbm = new osgGA::TrackballManipulator;<span class="" style="white-space:pre">  </span></div><div><span class="" style="white-space:pre">   </span>.</div><div><span class="" style="white-space:pre">  </span>.</div><div><span style="white-space:pre">        .</span></div><div><span class="" style="white-space:pre">      </span>// take the loaded scene graph, "themodel" and associate with the 'main window' osgViewer</div><div><span class="" style="white-space:pre">        </span>m_viewer->setSceneData(themodel);</div><div><span style="white-space:pre"><br></span></div><div><span class="" style="white-space:pre">   </span>m_viewer->getCamera()->setViewport(0,0,m_viewersize.GetWidth(),m_viewersize.GetHeight());</div><div><span class="" style="white-space:pre">    </span>m_viewer->addEventHandler(new osgViewer::StatsHandler);</div><div><span style="white-space:pre">    m_viewer->setThreadingModel(osgViewer::Viewer::SingleThreaded);</span></div><div><span class="" style="white-space:pre">       </span></div><div><span style="white-space:pre">    double zfocal = 1.5; // w.r.t normalized screen coords were min/max vertical= -0.5/+0.5</span></div><div><span class="" style="white-space:pre">    </span>this->AdjustPerspective(zfocal);</div><div><span class="" style="white-space:pre">        </span>int width = m_viewersize.GetWidth();</div><div><span style="white-space:pre"><br></span></div><div><span class="" style="white-space:pre">   </span>m_dualviewer = new osgViewer::CompositeViewer;</div><div><span class="" style="white-space:pre">     </span>m_dualviewer->addView(m_viewer);</div><div><span class="" style="white-space:pre">        </span>m_dualviewer->addView(m_OVERLAYviewer);</div></div><div><snip></div></div>