void OcclusionCullingTreeBuilder::drawTestResults(DrawEnv &denv, RenderPartitionBase *part) { OCRenderTreeNode* pNode; while (!_testPendingNodes.empty()) { pNode = _testPendingNodes.front(); //DRAW DRAW DRAW if(pNode->hasFunctor() == true && !pNode->getIsRendered()) { Window* win = denv.getWindow(); GetQueryObjectuivT getquiv = reinterpret_cast<GetQueryObjectuivT>( win->getFunction(_funcGetQueryObjectuivARB)); GLuint available = 0; getquiv(_testSamples[pNode->getResultNum()], GL_QUERY_RESULT_AVAILABLE_ARB, &available); if (!available) { //std::cout << "Waiting on " << pNode->getResultNum() << " buf size:" << _testPendingNodes.size() << std::endl; return; } GLuint sampleCount = 1; //XXX: Set to what it should be from calc above. getquiv(_testSamples[pNode->getResultNum()], GL_QUERY_RESULT_ARB, &sampleCount); if(sampleCount > _visPixelThreshold) { drawNode(pNode, denv, part); } else { StatCollector *sc = _ract->getStatCollector(); if(sc != NULL) sc->getElem(statNOccInvisible)->inc(); DrawableStatsAttachment *st = DrawableStatsAttachment::get(pNode->getNode()->getCore()); st->validate(); if(sc != NULL) sc->getElem(statNOccTriangles)-> add(st->getTriangles()); if(_ract->getOcclusionCullingDebug() && pNode->getNode()) { pNode->getNode()->setTravMask( pNode->getNode()->getTravMask() | _ract->getOcclusionCulledDebugMask() ); } } } //std::cout << "Popped: " << pNode->getResultNum() << " buf size now: " << _testPendingNodes.size() - 1 << std::endl; _testPendingNodes.pop(); } }
int main(int argc, char *argv[]) { osgLogP->setLogLevel(LOG_NOTICE); osgInit(argc, argv); int winid = setupGLUT(&argc, argv); // create a GLUT window GLUTWindowPtr gwin = GLUTWindow::create(); gwin->setId(winid); gwin->init(); osgLogP->setLogLevel(LOG_DEBUG); // build the test scene NodePtr pRoot = Node ::create(); GroupPtr pRootCore = Group::create(); NodePtr pRayGeo = Node ::create(); NodePtr pScene = buildGraph(); GroupPtr pSceneCore = Group::create(); Time tStart; Time tStop; Time tDFTotal = 0.0; Time tDFSTotal = 0.0; Time tPTotal = 0.0; Time tOTotal = 0.0; StatCollector statP; StatCollector statDF; StatCollector statDFS; beginEditCP(pRoot, Node::CoreFieldId | Node::ChildrenFieldId); pRoot->setCore (pRootCore ); pRoot->addChild(pScene ); pRoot->addChild(pRayGeo ); endEditCP (pRoot, Node::CoreFieldId | Node::ChildrenFieldId); createRays(uiNumRays, testRays); // build the geometry to visualize the rays pPoints = GeoPositions3f::create(); beginEditCP(pPoints); pPoints->addValue(Pnt3f(0.0, 0.0, 0.0)); pPoints->addValue(Pnt3f(0.0, 0.0, 0.0)); pPoints->addValue(Pnt3f(0.0, 0.0, 0.0)); pPoints->addValue(Pnt3f(0.0, 0.0, 0.0)); pPoints->addValue(Pnt3f(0.0, 0.0, 0.0)); endEditCP (pPoints); GeoIndicesUI32Ptr pIndices = GeoIndicesUI32::create(); beginEditCP(pIndices); pIndices->addValue(0); pIndices->addValue(1); pIndices->addValue(2); pIndices->addValue(3); pIndices->addValue(4); endEditCP (pIndices); GeoPLengthsPtr pLengths = GeoPLengthsUI32::create(); beginEditCP(pLengths); pLengths->addValue(2); pLengths->addValue(3); endEditCP (pLengths); GeoPTypesPtr pTypes = GeoPTypesUI8::create(); beginEditCP(pTypes); pTypes->addValue(GL_LINES ); pTypes->addValue(GL_TRIANGLES); endEditCP (pTypes); GeoColors3fPtr pColors = GeoColors3f::create(); beginEditCP(pColors); pColors->addValue(Color3f(1.0, 1.0, 1.0)); pColors->addValue(Color3f(1.0, 0.0, 0.0)); pColors->addValue(Color3f(1.0, 0.0, 0.0)); pColors->addValue(Color3f(1.0, 0.0, 0.0)); pColors->addValue(Color3f(1.0, 0.0, 0.0)); endEditCP (pColors); SimpleMaterialPtr pMaterial = SimpleMaterial::create(); beginEditCP(pMaterial); pMaterial->setLit(false); endEditCP (pMaterial); GeometryPtr pRayGeoCore = Geometry::create(); beginEditCP(pRayGeoCore); pRayGeoCore->setPositions(pPoints ); pRayGeoCore->setIndices (pIndices ); pRayGeoCore->setLengths (pLengths ); pRayGeoCore->setTypes (pTypes ); pRayGeoCore->setColors (pColors ); pRayGeoCore->setMaterial (pMaterial); endEditCP (pRayGeoCore); beginEditCP(pRayGeo, Node::CoreFieldId); pRayGeo->setCore(pRayGeoCore); endEditCP (pRayGeo, Node::CoreFieldId); IntersectActor::regDefaultClassEnter( osgTypedFunctionFunctor2CPtr< NewActionTypes::ResultE, NodeCorePtr, ActorBase::FunctorArgumentType & >(enterDefault)); NewActionBase *pDFAction = DepthFirstAction ::create(); NewActionBase *pDFSAction = DepthFirstStateAction::create(); NewActionBase *pPAction = PriorityAction ::create(); IntersectActor *pIActorDF = IntersectActor ::create(); IntersectActor *pIActorDFS = IntersectActor ::create(); IntersectActor *pIActorP = IntersectActor ::create(); pDFAction ->setStatistics(&statDF ); pDFSAction->setStatistics(&statDFS); pPAction ->setStatistics(&statP ); // IntersectActor with DFS-Action does not need leave calls pIActorDFS->setLeaveNodeFlag(false); pDFAction ->addActor(pIActorDF ); pDFSAction->addActor(pIActorDFS); pPAction ->addActor(pIActorP ); // create old action IntersectAction *pIntAction = IntersectAction ::create(); // make sure bv are up to date pScene->updateVolume(); SINFO << "-=< Intersect >=-" << endLog; std::vector<Line>::iterator itRays = testRays.begin(); std::vector<Line>::iterator endRays = testRays.end (); for(; itRays != endRays; ++itRays) { // DepthFirst tStart = getSystemTime(); pIActorDF->setRay (*itRays); pIActorDF->setMaxDistance(10000.0); pIActorDF->reset ( ); pDFAction->apply(pScene); tStop = getSystemTime(); tDFTotal += (tStop - tStart); if(pIActorDF->getHit() == true) { IntersectResult result; result._hit = true; result._pObj = pIActorDF->getHitObject (); result._tri = pIActorDF->getHitTriangleIndex(); result._dist = pIActorDF->getHitDistance (); result._time = (tStop - tStart); resultsDF.push_back(result); } else { IntersectResult result; result._hit = false; result._pObj = NullFC; result._tri = -1; result._dist = 0.0; result._time = (tStop - tStart); resultsDF.push_back(result); } std::string strStatDF; statDF.putToString(strStatDF); //SINFO << "stat DF: " << strStatDF << endLog; // Depth First State tStart = getSystemTime(); pIActorDFS->setRay (*itRays); pIActorDFS->setMaxDistance(10000.0); pIActorDFS->reset ( ); pDFSAction->apply(pScene); tStop = getSystemTime(); tDFSTotal += (tStop - tStart); if(pIActorDFS->getHit() == true) { IntersectResult result; result._hit = true; result._pObj = pIActorDFS->getHitObject (); result._tri = pIActorDFS->getHitTriangleIndex(); result._dist = pIActorDFS->getHitDistance (); result._time = (tStop - tStart); resultsDFS.push_back(result); } else { IntersectResult result; result._hit = false; result._pObj = NullFC; result._tri = -1; result._dist = 0.0; result._time = (tStop - tStart); resultsDFS.push_back(result); } std::string strStatDFS; statDFS.putToString(strStatDFS); //SINFO << "stat DFS: " << strStatDFS << endLog; // Priority tStart = getSystemTime(); pIActorP->setRay (*itRays); pIActorP->setMaxDistance(10000.0); pIActorP->reset ( ); pPAction->apply(pScene); tStop = getSystemTime(); tPTotal += (tStop - tStart); if(pIActorP->getHit() == true) { IntersectResult result; result._hit = true; result._pObj = pIActorP->getHitObject (); result._tri = pIActorP->getHitTriangleIndex(); result._dist = pIActorP->getHitDistance (); result._time = (tStop - tStart); resultsP.push_back(result); } else { IntersectResult result; result._hit = false; result._pObj = NullFC; result._tri = -1; result._dist = 0.0; result._time = (tStop - tStart); resultsP.push_back(result); } std::string strStatP; statP.putToString(strStatP); //SINFO << "stat P: " << strStatP << endLog; // Old tStart = getSystemTime(); pIntAction->setLine(*itRays, 100000); pIntAction->apply (pScene ); tStop = getSystemTime(); tOTotal += (tStop - tStart); if(pIntAction->didHit() == true) { IntersectResult result; result._hit = true; result._pObj = pIntAction->getHitObject (); result._tri = pIntAction->getHitTriangle(); result._dist = pIntAction->getHitT (); result._time = (tStop - tStart); resultsO.push_back(result); } else { IntersectResult result; result._hit = false; result._pObj = NullFC; result._tri = -1; result._dist = 0.0; result._time = (tStop - tStart); resultsO.push_back(result); } } UInt32 DFwins = 0; UInt32 DFwinsHit = 0; UInt32 DFwinsMiss = 0; UInt32 DFSwins = 0; UInt32 DFSwinsHit = 0; UInt32 DFSwinsMiss = 0; UInt32 Pwins = 0; UInt32 PwinsHit = 0; UInt32 PwinsMiss = 0; UInt32 Owins = 0; UInt32 OwinsHit = 0; UInt32 OwinsMiss = 0; UInt32 failCount = 0; UInt32 passCount = 0; UInt32 hitCount = 0; UInt32 missCount = 0; for(UInt32 i = 0; i < uiNumRays; ++i) { bool DFfastest = ((resultsDF [i]._time <= resultsDFS[i]._time) && (resultsDF [i]._time <= resultsP [i]._time) && (resultsDF [i]._time <= resultsO [i]._time) ); bool DFSfastest = ((resultsDFS[i]._time <= resultsDF [i]._time) && (resultsDFS[i]._time <= resultsP [i]._time) && (resultsDFS[i]._time <= resultsO [i]._time) ); bool Pfastest = ((resultsP [i]._time <= resultsDF [i]._time) && (resultsP [i]._time <= resultsDFS[i]._time) && (resultsP [i]._time <= resultsO [i]._time) ); bool Ofastest = ((resultsO [i]._time <= resultsDF [i]._time) && (resultsO [i]._time <= resultsDFS[i]._time) && (resultsO [i]._time <= resultsP [i]._time) ); if((resultsDF [i]._hit == resultsDFS[i]._hit) && (resultsDFS[i]._hit == resultsP [i]._hit) && (resultsP [i]._hit == resultsO [i]._hit) ) { if((osgabs(resultsDF [i]._dist - resultsDFS[i]._dist) >= 0.001) || (osgabs(resultsDFS[i]._dist - resultsP [i]._dist) >= 0.001) || (osgabs(resultsP [i]._dist - resultsO [i]._dist) >= 0.001) || (osgabs(resultsO [i]._dist - resultsDF [i]._dist) >= 0.001) ) { ++failCount; SINFO << "FAIL: df: " << resultsDF [i]._dist << " dfs: " << resultsDFS[i]._dist << " p: " << resultsP [i]._dist << " o: " << resultsO [i]._dist << endLog; SINFO << "FAIL: df: " << resultsDF [i]._tri << " dfs: " << resultsDFS[i]._tri << " p: " << resultsP [i]._tri << " o: " << resultsO [i]._tri << endLog; } else { ++passCount; } if(resultsDF[i]._hit == true) { ++hitCount; DFwinsHit = DFfastest ? DFwinsHit + 1 : DFwinsHit; DFSwinsHit = DFSfastest ? DFSwinsHit + 1 : DFSwinsHit; PwinsHit = Pfastest ? PwinsHit + 1 : PwinsHit; OwinsHit = Ofastest ? OwinsHit + 1 : OwinsHit; } else { ++missCount; DFwinsMiss = DFfastest ? DFwinsMiss + 1 : DFwinsMiss; DFSwinsMiss = DFSfastest ? DFSwinsMiss + 1 : DFSwinsMiss; PwinsMiss = Pfastest ? PwinsMiss + 1 : PwinsMiss; OwinsMiss = Ofastest ? OwinsMiss + 1 : OwinsMiss; } DFwins = DFfastest ? DFwins + 1 : DFwins; DFSwins = DFSfastest ? DFSwins + 1 : DFSwins; Pwins = Pfastest ? Pwins + 1 : Pwins; Owins = Ofastest ? Owins + 1 : Owins; } else { ++failCount; } //SINFO << i << " \t" << (DFfastest ? "D ->" : " ") << " hit: " << resultsDF [i]._hit << " time: " << resultsDF [i]._time << endLog; //SINFO << " \t" << (DFSfastest ? "S ->" : " ") << " hit: " << resultsDFS[i]._hit << " time: " << resultsDFS[i]._time << endLog; //SINFO << " \t" << (Pfastest ? "P ->" : " ") << " hit: " << resultsP [i]._hit << " time: " << resultsP [i]._time << endLog; //SINFO << " \t" << (Ofastest ? "O ->" : " ") << " hit: " << resultsO [i]._hit << " time: " << resultsO [i]._time << endLog; } SINFO << " df total: " << tDFTotal << (tDFTotal < tDFSTotal && tDFTotal < tPTotal && tDFTotal < tOTotal ? " *" : " ") << " wins: " << DFwins << " (" << (static_cast<Real32>(DFwins) / static_cast<Real32>(passCount)) * 100.0 << "%)\t" << " wins on hit: " << DFwinsHit << " (" << (static_cast<Real32>(DFwinsHit) / static_cast<Real32>(hitCount )) * 100.0 << "%)\t" << " wins on miss: " << DFwinsMiss << " (" << (static_cast<Real32>(DFwinsMiss) / static_cast<Real32>(missCount)) * 100.0 << "%)" << endLog; SINFO << " dfs total: " << tDFSTotal << (tDFSTotal < tDFTotal && tDFSTotal < tPTotal && tDFSTotal < tOTotal ? " *" : " ") << " wins: " << DFSwins << " (" << (static_cast<Real32>(DFSwins) / static_cast<Real32>(passCount)) * 100.0 << "%)\t" << " wins on hit: " << DFSwinsHit << " (" << (static_cast<Real32>(DFSwinsHit) / static_cast<Real32>(hitCount )) * 100.0 << "%)\t" << " wins on miss: " << DFSwinsMiss << " (" << (static_cast<Real32>(DFSwinsMiss) / static_cast<Real32>(missCount)) * 100.0 << "%)" << endLog; SINFO << " p total: " << tPTotal << (tPTotal < tDFTotal && tPTotal < tDFSTotal && tPTotal < tOTotal ? " *" : " ") << " wins: " << Pwins << " (" << (static_cast<Real32>(Pwins) / static_cast<Real32>(passCount)) * 100.0 << "%)\t" << " wins on hit: " << PwinsHit << " (" << (static_cast<Real32>(PwinsHit) / static_cast<Real32>(hitCount )) * 100.0 << "%)\t" << " wins on miss: " << PwinsMiss << " (" << (static_cast<Real32>(PwinsMiss) / static_cast<Real32>(missCount)) * 100.0 << "%)" << endLog; SINFO << " o total: " << tOTotal << (tOTotal < tDFTotal && tOTotal < tDFSTotal && tOTotal < tPTotal ? " *" : " ") << " wins: " << Owins << " (" << (static_cast<Real32>(Owins) / static_cast<Real32>(passCount)) * 100.0 << "%)\t" << " wins on hit: " << OwinsHit << " (" << (static_cast<Real32>(OwinsHit) / static_cast<Real32>(hitCount )) * 100.0 << "%)\t" << " wins on miss: " << OwinsMiss << " (" << (static_cast<Real32>(OwinsMiss) / static_cast<Real32>(missCount)) * 100.0 << "%)" << endLog; SINFO << "pass: "******" fail: " << failCount << " hit: " << hitCount << " miss: " << missCount << endLog; osgLogP->setLogLevel(LOG_NOTICE); #if 0 // create the SimpleSceneManager helper mgr = new SimpleSceneManager; // tell the manager what to manage mgr->setWindow(gwin ); mgr->setRoot (pRoot); // show the whole scene mgr->showAll(); // GLUT main loop glutMainLoop(); #endif return 0; }
// 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(); // load the scene if(argc < 2) { FWARNING(("No file given!\n")); FWARNING(("Supported file formats:\n")); std::list<const char*> suffixes; SceneFileHandler::the().getSuffixList(suffixes); for(std::list<const char*>::iterator it = suffixes.begin(); it != suffixes.end(); ++it) { FWARNING(("%s\n", *it)); } std::vector<std::string> suffixesVec; suffixesVec = FCFileHandler::the()->getSuffixList(); for(std::vector<std::string>::iterator it = suffixesVec.begin(); it != suffixesVec.end(); ++it) { FWARNING(("%s\n", *it)); } RootNodes.push_back( makeTorus(.5, 2, 16, 16) ); glutSetWindowTitle("No file Loaded"); } else { glutSetWindowTitle(argv[1]); Load(std::string(argv[1]), RootNodes, Cameras); if(RootNodes.size() < 1) { std::cout << "There are no root nodes defined." << std::endl; return 0; } } //Create Statistics Foreground SimpleStatisticsForegroundPtr TheStatForeground = SimpleStatisticsForeground::create(); beginEditCP(TheStatForeground); TheStatForeground->setSize(25); TheStatForeground->setColor(Color4f(0,1,0,0.7)); TheStatForeground->addElement(RenderAction::statDrawTime, "Draw FPS: %r.3f"); TheStatForeground->addElement(DrawActionBase::statTravTime, "TravTime: %.3f s"); TheStatForeground->addElement(RenderAction::statDrawTime, "DrawTime: %.3f s"); TheStatForeground->addElement(DrawActionBase::statCullTestedNodes, "%d Nodes culltested"); TheStatForeground->addElement(DrawActionBase::statCulledNodes, "%d Nodes culled"); TheStatForeground->addElement(RenderAction::statNMaterials, "%d material changes"); TheStatForeground->addElement(RenderAction::statNMatrices, "%d matrix changes"); TheStatForeground->addElement(RenderAction::statNGeometries, "%d Nodes drawn"); TheStatForeground->addElement(RenderAction::statNTransGeometries, "%d transparent Nodes drawn"); TheStatForeground->addElement(Drawable::statNTriangles, "%d triangles drawn"); TheStatForeground->addElement(Drawable::statNLines, "%d lines drawn"); TheStatForeground->addElement(Drawable::statNPoints, "%d points drawn"); TheStatForeground->addElement(Drawable::statNPrimitives, "%d primitive groups drawn"); TheStatForeground->addElement(Drawable::statNVertices, "%d vertices transformed"); TheStatForeground->addElement(Drawable::statNGeoBytes, "%d bytes of geometry used"); TheStatForeground->addElement(RenderAction::statNTextures, "%d textures used"); TheStatForeground->addElement(RenderAction::statNTexBytes, "%d bytes of texture used"); endEditCP(TheStatForeground); //Set up Selection SelectedRootNode = 0; SelectedCamera = -1; // create the SimpleSceneManager helper mgr = new SimpleSceneManager; // tell the manager what to manage mgr->setWindow(gwin ); mgr->setRoot (RootNodes[SelectedRootNode]); mgr->turnHeadlightOff(); beginEditCP(mgr->getWindow()->getPort(0), Viewport::ForegroundsFieldMask); mgr->getWindow()->getPort(0)->getForegrounds().push_back(TheStatForeground); endEditCP(mgr->getWindow()->getPort(0), Viewport::ForegroundsFieldMask); StatCollector *collector = &TheStatForeground->getCollector(); // add optional elements collector->getElem(Drawable::statNTriangles); mgr->getAction()->setStatistics(collector); // show the whole scene mgr->showAll(); // GLUT main loop glutMainLoop(); return 0; }
void OcclusionCullingTreeBuilder::drawTestNode(OCRenderTreeNode *pNode, DrawEnv &denv, RenderPartitionBase *part) { //std::cout << "Front: " << _currSample << " Back: " << _currSampleBack << std::endl; while(_testPendingNodes.size() == _numTestSamples - 1) { drawTestResults(denv, part); //std::cout << "NOW: Front: " << _currSample << " Back: " << _currSampleBack << std::endl; } //DRAW DRAW DRAW Window* win = denv.getWindow(); pNode->setIsRendered(false); if(_ract->getOcclusionCullingDebug() && pNode->getNode()) { pNode->getNode()->setTravMask( pNode->getNode()->getTravMask() | _ract->getOcclusionTestedDebugMask() ); } const BoxVolume &volume = pNode->getVolume(); Pnt3f min,max; volume.getBounds(min, max); static GLfloat n[6][3] = { {-1.0, 0.0, 0.0}, {0.0, 1.0, 0.0}, {1.0, 0.0, 0.0}, {0.0, -1.0, 0.0}, {0.0, 0.0, 1.0}, {0.0, 0.0, -1.0} }; static GLint faces[6][4] = { { 0, 1, 2, 3}, { 3, 2, 6, 7}, { 7, 6, 5, 4}, { 4, 5, 1, 0}, { 5, 6, 2, 1}, { 7, 4, 0, 3} }; GLfloat v[8][3]; v[0][0] = v[1][0] = v[2][0] = v[3][0] = min[0]; v[4][0] = v[5][0] = v[6][0] = v[7][0] = max[0]; v[0][1] = v[1][1] = v[4][1] = v[5][1] = min[1]; v[2][1] = v[3][1] = v[6][1] = v[7][1] = max[1]; v[0][2] = v[3][2] = v[4][2] = v[7][2] = min[2]; v[1][2] = v[2][2] = v[5][2] = v[6][2] = max[2]; if(_currSample == _numTestSamples - 1) { _currSample = 0; } _currSample++; StatCollector *sc = _ract->getStatCollector(); if(sc != NULL) sc->getElem(statNOccTests )->inc(); enterTesting(denv, part); BeginQueryT beginq = reinterpret_cast<BeginQueryT>( win->getFunction(_funcBeginQueryARB)); //std::cout << "Push: " << _currSample << std::endl; pNode->setResultNum(_currSample); beginq(GL_SAMPLES_PASSED_ARB, _testSamples[_currSample]); glBegin(GL_QUADS); for(UInt32 i = 0; i<6; i++) { glNormal3fv(&n[i][0]); glVertex3fv(&v[faces[i][0]][0]); glNormal3fv(&n[i][0]); glVertex3fv(&v[faces[i][1]][0]); glNormal3fv(&n[i][0]); glVertex3fv(&v[faces[i][2]][0]); glNormal3fv(&n[i][0]); glVertex3fv(&v[faces[i][3]][0]); } glEnd(); EndQueryT endq = reinterpret_cast<EndQueryT>( win->getFunction(_funcEndQueryARB)); endq(GL_SAMPLES_PASSED_ARB); _testPendingNodes.push(pNode); }
void OcclusionCullingTreeBuilder::testNode(OCRenderTreeNode *pNode, DrawEnv &denv, RenderPartitionBase *part, Real32 &scr_percent) { while (pNode != NULL) { //MATRIX SETUP UInt32 uiNextMatrix = pNode->getMatrixStore().first; if(uiNextMatrix != 0 && uiNextMatrix != _uiActiveMatrix) { glLoadMatrixf(pNode->getMatrixStore().second.getValues()); _uiActiveMatrix = uiNextMatrix; _currMatrix.second = pNode->getMatrixStore().second; updateTopMatrix(denv); denv.setObjectToWorld(_accMatrix); ++part->_uiNumMatrixChanges; } const BoxVolume &volume = pNode->getVolume(); Pnt3f min,max; volume.getBounds(min, max); Pnt3f p[8]; p[0].setValues(min[0],min[1],min[2]); p[1].setValues(max[0],min[1],min[2]); p[2].setValues(min[0],max[1],min[2]); p[3].setValues(min[0],min[1],max[2]); p[4].setValues(max[0],max[1],min[2]); p[5].setValues(max[0],min[1],max[2]); p[6].setValues(min[0],max[1],max[2]); p[7].setValues(max[0],max[1],max[2]); //std::cout << "OtoW:" << std::endl; //std::cout << denv.getObjectToWorld() << std::endl; //std::cout << "WtoC:" << std::endl; //std::cout << worldToCam << std::endl; for(UInt32 i = 0; i<8;i++) { // std::cout << p[i] << "=>"; denv.getObjectToWorld().mult (p[i], p[i]); _worldToScreen .multFull(p[i], p[i]); //std::cout << p[i] << " "; } min=p[0]; max=p[0]; for(UInt32 i = 0; i<8; i++) { for(UInt32 j=0; j<2; j++) { if(p[i][j] < min[j]) { min[j] = p[i][j]; } if(p[i][j] > max[j]) { max[j] = p[i][j]; } } } max[0] = osgClamp(-1.f, max[0], 1.f); max[1] = osgClamp(-1.f, max[1], 1.f); min[0] = osgClamp(-1.f, min[0], 1.f); min[1] = osgClamp(-1.f, min[1], 1.f); // cbb is the percent of the screen real estate this would cover Real32 cbb = (max[0] - min[0]) * (max[1] - min[1]) / 4.f; //std::cout << cur_node << ":" << pix << " "; //std::cout << pNode->getScalar() << std::endl; //Make decision if(pNode->hasFunctor() == false) //Nothing to do { //renderNode drawNode(pNode, denv, part); } else { //make decision //if(0 > 1) if(cbb > scr_percent) // Rendering major occluders { drawNode(pNode, denv, part); //scr_percent+=cbb; } else { Real32 pcov; pcov = sqrt(scr_percent) - sqrt(cbb); pcov *= pcov; //std::cout << "cbb:" << cbb << " scr_percent:" << scr_percent <<" pcov:" << pcov << std::endl; //if(scr_percent - pcov > 0.001) if(pcov > _coveredProbThreshold || cbb < 0.001) // If within threshold or reall small { //Get triangles DrawableStatsAttachment *st = DrawableStatsAttachment::get(pNode->getNode()->getCore()); st->validate(); UInt32 triangles = st->getTriangles(); if(cbb * _vpWidth * _vpHeight < _minFeatureSize) //small feature culling { StatCollector *sc = _ract->getStatCollector(); if(sc != NULL) sc->getElem(statNOccTriangles)-> add(triangles); if(_ract->getOcclusionCullingDebug() && pNode->getNode()) { pNode->getNode()->setTravMask( pNode->getNode()->getTravMask() | _ract->getOcclusionCulledDebugMask() ); } pNode->setIsRendered(true); } else if( triangles <= _minTriangleCount ) { drawNode(pNode, denv, part); } else if((_testPendingNodes.size() == _numTestSamples - 1)) // Make sure we have room to draw a test { drawTestResults(denv, part); if(_testPendingNodes.size() == _numTestSamples - 1) // If we are waiting on a result, draw a node { drawNode(pNode, denv, part); } else { drawTestNode(pNode, denv, part); // Made room, go ahead and draw a test node } } else { drawTestNode(pNode, denv, part); //Plenty of room in buffer to draw a test node } } else { drawNode(pNode, denv, part); // Probably not being covered up...draw the real node //scr_percent+=cbb; } } scr_percent += ((1.0 - scr_percent) * cbb); } //DRAW CHILDREN OR GO TO TOP AND DO IT AGAIN if(pNode->getFirstChild() != NULL) { OCRenderTreeNode *child = static_cast<OCRenderTreeNode *>(pNode->getFirstChild()); testNode(child, denv, part, scr_percent); } pNode = static_cast<OCRenderTreeNode *>(pNode->getBrother()); } }
void OcclusionCullingTreeBuilder::draw(DrawEnv &denv, RenderPartitionBase *part) { #if 1 //CHECK_ENV_ACTION //std::cout << "Frame Start" << std::endl; Window* win = denv.getWindow(); if(_sortMode == ModeAdaptiveBucket) { // Merge all the buckets to a tree for(UInt32 i = 0; i < _numBuckets; ++i) { if(_buckets[i] != NULL) { _pRoot->addChild(_buckets[i]); } } } if(!win->hasExtension(_extOcclusionQuery)) { // Don't have it, just draw the whole tree. SLOG << "Missing OCC GL extensions!!" << endLog; _uiActiveMatrix = 0; Inherited::drawNode(_pRoot, denv, part); return; } //SETUP // done in add, action should never change // _ract = dynamic_cast<RenderAction*>(denv.getAction()); if(!_ract) { FFATAL(("OcclusionCullingTreeBuilder::draw: Action in denv is not a " "RenderAction!\n")); return; } _uiActiveMatrix = 0; Real32 screenCoveredPercentage = 0.f; if(_ract->getOcclusionCullingQueryBufferSize() != _numTestSamples || !_occInitialized) { _numTestSamples = _ract->getOcclusionCullingQueryBufferSize(); //std::cout << "Buf size: " << _numTestSamples << std::endl; _testSamples.resize(_numTestSamples); //std::cout << "Performing OCC on " << _numNodes << " nodes." << std::endl; GenQueryT genquer = reinterpret_cast<GenQueryT>( win->getFunction(_funcGenQueriesARB)); genquer(_numTestSamples, &(_testSamples.front())); _occInitialized = true; } if(!_isOccStateCreated) { _isOccStateCreated = true; // register an exit function to clean up the State object addPreFactoryExitFunction(&releaseTestingState); // Create an empty state to render test nodes. _testingStatePtr = State::create(); DepthChunkUnrecPtr dc = DepthChunk::create(); dc->setReadOnly(true); _testingStatePtr->addChunk(dc); ColorMaskChunkUnrecPtr cc = ColorMaskChunk::create(); cc->setMaskR(false); cc->setMaskG(false); cc->setMaskB(false); cc->setMaskA(false); _testingStatePtr->addChunk(cc); PolygonChunkUnrecPtr pc = PolygonChunk::create(); pc->setCullFace(GL_BACK); _testingStatePtr->addChunk(pc); commitChanges(); } //glGenQueriesARB(_numNodes, queries); //std::cout << "Calculated Pixels" << std::endl; _vpWidth = denv.getPixelWidth(); _vpHeight = denv.getPixelHeight(); _worldToScreen = denv.getVPWorldToScreen(); _testingState = &*_testingStatePtr; _minFeatureSize = _ract->getOcclusionCullingMinimumFeatureSize(); _visPixelThreshold = _ract->getOcclusionCullingVisibilityThreshold(); _coveredProbThreshold = _ract->getOcclusionCullingCoveredThreshold(); _minTriangleCount = _ract->getOcclusionCullingMinimumTriangleCount(); _inTesting = false; _currSample = 0; //DRAW / TEST / RE-DRAW ON BUFFER FULL testNode(_pRoot, denv, part, screenCoveredPercentage); StatCollector *sc = _ract->getStatCollector(); if(sc != NULL) sc->getElem(statNOccNodes)->add(_numNodes); _numNodes=0; _uiActiveMatrix = 0; leaveTesting(denv, part); //RESULTS / RE-DRAW while( !_testPendingNodes.empty() ) { drawTestResults(denv, part); } //std::cout << "Calc Pixels" << std::endl; if(sc != NULL) { Real32 percentage = Real32(sc->getElem(statNOccInvisible)->get()) / Real32(sc->getElem(statNOccTests)->get()); sc->getElem(statNOccSuccessTestPer)->set(percentage); } //std::cout << "Real pixels " << std::endl; //std::cout << std::endl; // screen_covered_percentage = 1.0; // drawNode(_pRoot, denv, part, screen_covered_percentage); _numNodes=0; _currSample = 0; //std::cout << "Frame End" << std::endl; #endif }
void VRWindowManager::updateWindows() { if (rendering_paused) return; auto scene = VRScene::getCurrent(); if (scene) scene->allowScriptThreads(); ract->setResetStatistics(false); StatCollector* sc = ract->getStatCollector(); if (sc) { sc->reset(); sc->getElem(VRGlobals::FRAME_RATE.statFPS)->add(VRGlobals::FRAME_RATE.fps); sc->getElem(VRGlobals::UPDATE_LOOP1.statFPS)->add(VRGlobals::UPDATE_LOOP1.fps); sc->getElem(VRGlobals::UPDATE_LOOP2.statFPS)->add(VRGlobals::UPDATE_LOOP2.fps); sc->getElem(VRGlobals::UPDATE_LOOP3.statFPS)->add(VRGlobals::UPDATE_LOOP3.fps); sc->getElem(VRGlobals::UPDATE_LOOP4.statFPS)->add(VRGlobals::UPDATE_LOOP4.fps); sc->getElem(VRGlobals::UPDATE_LOOP5.statFPS)->add(VRGlobals::UPDATE_LOOP5.fps); sc->getElem(VRGlobals::UPDATE_LOOP6.statFPS)->add(VRGlobals::UPDATE_LOOP6.fps); sc->getElem(VRGlobals::UPDATE_LOOP7.statFPS)->add(VRGlobals::UPDATE_LOOP7.fps); sc->getElem(VRGlobals::RENDER_FRAME_RATE.statFPS)->add(VRGlobals::RENDER_FRAME_RATE.fps); sc->getElem(VRGlobals::SLEEP_FRAME_RATE.statFPS)->add(VRGlobals::SLEEP_FRAME_RATE.fps); sc->getElem(VRGlobals::SWAPB_FRAME_RATE.statFPS)->add(VRGlobals::SWAPB_FRAME_RATE.fps); sc->getElem(VRGlobals::WINDOWS_FRAME_RATE.statFPS)->add(VRGlobals::WINDOWS_FRAME_RATE.fps); sc->getElem(VRGlobals::SCRIPTS_FRAME_RATE.statFPS)->add(VRGlobals::SCRIPTS_FRAME_RATE.fps); sc->getElem(VRGlobals::PHYSICS_FRAME_RATE.statFPS)->add(VRGlobals::PHYSICS_FRAME_RATE.fps); sc->getElem(VRGlobals::GTK1_FRAME_RATE.statFPS)->add(VRGlobals::GTK1_FRAME_RATE.fps); sc->getElem(VRGlobals::GTK2_FRAME_RATE.statFPS)->add(VRGlobals::GTK2_FRAME_RATE.fps); sc->getElem(VRGlobals::SMCALLBACKS_FRAME_RATE.statFPS)->add(VRGlobals::SMCALLBACKS_FRAME_RATE.fps); sc->getElem(VRGlobals::SETUP_FRAME_RATE.statFPS)->add(VRGlobals::SETUP_FRAME_RATE.fps); sc->getElem(VRGlobals::SCRIPTS_FRAME_RATE.statFPS)->add(VRGlobals::SCRIPTS_FRAME_RATE.fps); } //TODO: use barrier->getnumwaiting to make a state machine, allways ensure all are waiting!! BarrierRefPtr barrier = Barrier::get("PVR_rendering", true); auto updateSceneLinks = [&]() { for (auto view : VRSetup::getCurrent()->getViews()) { if (auto r = view->getRenderingL()) r->updateSceneLink(); if (auto r = view->getRenderingR()) r->updateSceneLink(); } }; auto wait = [&](int timeout = -1) { int pID = VRProfiler::get()->regStart("window manager barrier"); if (timeout > 0) { size_t tEnter = time(0); while (barrier->getNumWaiting() < VRWindow::active_window_count) { usleep(1); size_t tNow = time(0); int delta = tNow - tEnter; if (delta >= timeout) { cout << "WARNING! skipping barrier!" << endl; return false; } } } barrier->enter(VRWindow::active_window_count+1); VRProfiler::get()->regStop(pID); return true; }; //TODO: // [0423/180710:WARNING:message_in_transit_queue.cc(18)] Destroying nonempty message queue auto tryRender = [&]() { if (barrier->getNumWaiting() != VRWindow::active_window_count) return true; if (!wait()) return false; /** let the windows clear their change lists **/ if (!wait()) return false; auto clist = Thread::getCurrentChangeList(); auto Ncreated = clist->getNumCreated(); VRGlobals::NCHANGED = clist->getNumChanged(); VRGlobals::NCREATED = Ncreated; if (Ncreated > 50) doRenderSync = true; // to reduce memory issues with big scenes for (auto w : getWindows() ) if (auto win = dynamic_pointer_cast<VRMultiWindow>(w.second)) if (win->getState() == VRMultiWindow::INITIALIZING) win->initialize(); commitChanges(); if (!wait()) return false; /** let the windows merge the change lists **/ if (!wait()) return false; //if (clist->getNumCreated() > 0) cout << "VRWindowManager::updateWindows " << clist->getNumCreated() << " " << clist->getNumChanged() << endl; for (auto w : getWindows() ) if (auto win = dynamic_pointer_cast<VRGtkWindow>(w.second)) win->render(); clist->clear(); if (doRenderSync) if (!wait(60)) return false; doRenderSync = false; return true; //sleep(1); }; updateSceneLinks(); if (!tryRender()) { cout << "WARNING! a remote window hangs or something!\n"; for (auto w : getWindows() ) { auto win = dynamic_pointer_cast<VRMultiWindow>(w.second); if (!win) continue; if (win->isWaiting()) continue; cout << "WARNING! window " << win->getName() << " is hanging, state: " << win->getStateString() << endl; WARN("WARNING! Lost connection with " + win->getName()); win->reset(); } } if (scene) scene->blockScriptThreads(); }
/*! Draw the statistics lines. */ void SimpleStatisticsForeground::draw(DrawEnv *pEnv, Viewport *pPort) { if(getActive() == false) return; if(_face == 0) initText(getFamily(), getSize()); if ((getCollector() == NULL) || (!getCollector()->getNumOfElems() && !getMFElementIDs()->size())) return; // nothing to do Real32 pw = Real32(pPort->getPixelWidth ()); Real32 ph = Real32(pPort->getPixelHeight()); if(pw < 1 || ph < 1) return; glPushAttrib(GL_LIGHTING_BIT | GL_POLYGON_BIT | GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT); glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); glDisable(GL_DEPTH_TEST); glDisable(GL_COLOR_MATERIAL); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glEnable(GL_BLEND); glMatrixMode(GL_MODELVIEW); glPushMatrix(); glLoadIdentity(); glMatrixMode(GL_PROJECTION); glPushMatrix(); glLoadIdentity(); // Set viewport. We want to map one unit to one pixel on the // screen. Some sources in the internet say that we should // add an offset of -0.375 to prevent rounding errors. Don't // know if that is true, but it seems to work. glOrtho(0 - 0.375, pw - 0.375, 0 - 0.375, ph - 0.375, 0, 1); // retrieve text std::vector < std::string > stat; StatCollector *col = this->getCollector(); StatElem *el; if(getMFElementIDs()->size() != 0) { for(UInt32 i = 0; i < getMFElementIDs()->size(); ++i) { Int32 id(getElementIDs(i)); el = ((id >= 0) ? col->getElem(id) : 0); stat.resize(stat.size() + 1); std::vector < std::string >::iterator str = stat.end() - 1; const char *format = NULL; if(i < getMFFormats()->size() && getFormats(i).length()) { format = getFormats(i).c_str(); } if (el) el->putToString(*str, format); else *str = format; } } else // fallback, show all elements { for(UInt32 i = 0; i < col->getNumOfElems(); ++i) { el = col->getElem(i, false); if(el) { std::string desc(el->getDesc()->getName()), eltext; el->putToString(eltext); desc = desc + " : " + eltext; stat.resize(stat.size() + 1); std::vector < std::string >::iterator str = stat.end() - 1; *str = desc; } } } TextLayoutParam layoutParam; layoutParam.spacing = 1.1f; layoutParam.majorAlignment = TextLayoutParam::ALIGN_BEGIN; layoutParam.minorAlignment = TextLayoutParam::ALIGN_BEGIN; TextLayoutResult layoutResult; _face->layout(stat, layoutParam, layoutResult); Real32 scale = 1 / _face->getScale(); Real32 size = _face->getParam().size; Real32 textWidth = layoutResult.textBounds.x() * scale + size + getTextMargin().x() * 2.0f; Real32 textHeight = layoutResult.textBounds.y() * scale + size + getTextMargin().y() * 2.0f; // Let's do some simple form of layout management Real32 orthoX = 0, orthoY = ph; switch ( getHorizontalAlign() ) { case Right: orthoX = pw - textWidth; break; case Middle: orthoX = (pw - textWidth) * 0.5; break; case Left: default: break; } switch ( getVerticalAlign() ) { case Bottom: orthoY = textHeight; break; case Center: orthoY = (ph - textHeight) * 0.5 + textHeight; break; case Top: default: break; } glTranslatef(orthoX, orthoY, 0.0); // draw background glColor4fv(static_cast<const GLfloat *>(getBgColor().getValuesRGBA())); glBegin(GL_QUADS); glVertex2f(0, -textHeight); glVertex2f(textWidth, -textHeight); glVertex2f(textWidth, 0); glVertex2f(0, 0); glEnd(); // draw border if(getBorderColor().alpha() >= 0.0f) { glColor4fv( static_cast<const GLfloat *>(getBorderColor().getValuesRGBA())); glBegin(GL_LINE_LOOP); glVertex2f(getBorderOffset().x(), -textHeight + 1 + getBorderOffset().y()); glVertex2f(textWidth - 1 - getBorderOffset().x(), -textHeight + 1 + getBorderOffset().y()); glVertex2f(textWidth - 1 - getBorderOffset().x(), -1 - getBorderOffset().y()); glVertex2f(getBorderOffset().x(), -1 - getBorderOffset().y()); glEnd(); } glTranslatef( 0.5 * size + getTextMargin().x(), -0.5 * size - getTextMargin().y(), 0.0); _texchunk ->activate(pEnv); _texenvchunk->activate(pEnv); // draw text shadow glColor4fv(static_cast<const GLfloat *>(getShadowColor().getValuesRGBA())); glPushMatrix(); glTranslatef(getShadowOffset().x(), getShadowOffset().y(), 0); glScalef(scale, scale, 1); _face->drawCharacters(layoutResult); // draw text glColor4fv(static_cast<const GLfloat *>(getColor().getValuesRGBA())); glPopMatrix(); glScalef(scale, scale, 1); _face->drawCharacters(layoutResult); _texchunk ->deactivate(pEnv); _texenvchunk->deactivate(pEnv); glMatrixMode(GL_PROJECTION); glPopMatrix(); glMatrixMode(GL_MODELVIEW); glPopMatrix(); glPopAttrib(); }
/// \brief Drawing the DynamicTerrain Action::ResultE DynamicTerrain::drawPrimitives( DrawActionBase* action ) { // do frustum culling here.. extract frustum from the current camera: RenderAction* renderAction = dynamic_cast< RenderAction* >( action ); if( needInitialize_ ) { if( getHeightData() != NullFC ) { if( getLevelSize() < 3 ) { SWARNING << "DynamicTerrain: LevelSize is below minimum (using default)!" << std::endl; setLevelSize( 63 ); } // todo: choose the correct height-/texturedata source: geoClipmaps_.initialize( getLevelSize(), &imageHeightSource_, getTextureSource() ); } needInitialize_ = false; } if( !geoClipmaps_.isValid() ) { // no valid data yet return Action::Continue; } // todo: get the viewport of the RenderAction, check if the camera already has a terrain attachment: // if not: create a new TerrainView and attach it to the camera // update/render the view if( renderAction ) { // frustum culling const FrustumVolume& frustum = renderAction->getFrustum(); // make an update right here: Matrix camera = renderAction->getCameraToWorld(); Matrix toworld = renderAction->top_matrix(); toworld.invert(); camera.multLeft(toworld); Pnt3f eyePoint( camera[ 3 ][ 0 ], camera[ 3 ][ 1 ], camera[ 3 ][ 2 ] ); // transform the eyePoint to the unscaled sample space: const WorldTransformation worldTransform = getWorldTransform(); const Pnt3f worldOffset( worldTransform.offset[ 0 ], 0.0f, worldTransform.offset[ 1 ] ); const Pnt3f localEyePoint = componentDivide( ( eyePoint - worldOffset ), worldTransform.sampleDistance ); if( !getDisableUpdate() ) { geoClipmaps_.update( localEyePoint ); } // and now draw what we have: ClipmapRenderParameters renderParams; renderParams.renderAction = renderAction; renderParams.window = renderAction->getWindow(); renderParams.viewFrustum = frustum; renderParams.enableFrustumCulling = getEnableFrustumCulling(); renderParams.showTransitionRegions = getShowTransitionRegions(); renderParams.useVboExtension = getUseVboExtension(); renderParams.globalTexture = globalTexture_; renderParams.heightColorTexture = getHeightColorTexture(); renderParams.worldTransform = worldTransform; ClipmapRenderStatistics renderStats; geoClipmaps_.render( renderParams, renderStats ); if( getShowBoundingBoxes() ) { //drawBox( } // update stats: StatCollector* statCollector = action->getStatistics(); if( statCollector ) { StatIntElem* statTriangleCount = statCollector->getElem( Drawable::statNTriangles, false ); StatIntElem* statVertexCount = statCollector->getElem( Drawable::statNVertices, false ); if( statTriangleCount ) { statTriangleCount->add( renderStats.drawnTriangleCount ); } if( statVertexCount ) { statVertexCount->add( renderStats.transformedVertexCount ); } } } else { //todo: can this ever happen?! SLOG << "Test\n"; } return Action::Continue; }