void FBOViewport::render(DrawActionBase *action) { if(getFrameBufferObject() != NULL) { DrawEnv oEnv; oEnv.setWindow(action->getWindow()); getFrameBufferObject()->activate(&oEnv); Inherited::render(action); getFrameBufferObject()->deactivate(&oEnv); } else { Inherited::render(action); } }
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(); } }
void StagedViewport::stretchTargetToFrameBuffer(RenderActionBase *action, FrameBufferObject *target) { Window *pWin = action->getWindow(); if((pWin->getDrawMode() & Window::PartitionDrawMask) == Window::SequentialPartitionDraw) { DrawEnv oEnv; oEnv.setWindow(action->getWindow()); //oEnv.setTileFullSize(getCamera()->tileGetFullSize()); //oEnv.setTileRegion (getCamera()->tileGetRegion ()); // THINKABOUTME KS: //oEnv.setDrawerId (action->getDrawerId ()); //oEnv.setDrawableId(action->getDrawableId()); glClearColor(0.0, 1.0, 0.0, 0.0); glClear(GL_COLOR_BUFFER_BIT); FrameBufferAttachment* fba = target->getColorAttachments(0); TextureObjChunk* texObj = dynamic_cast<TextureBuffer*>(fba)->getTexture(); if( texObj ) { texObj->activate(&oEnv,0); glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL); glMatrixMode(GL_PROJECTION); glPushMatrix(); glLoadIdentity(); glOrtho(0, 1, 0, 1, -1, 1 ); glMatrixMode(GL_MODELVIEW); glPushMatrix(); glLoadIdentity(); float u = 0.0f; float v = 0.0f; // glColor3f(1,1,1); glBegin(GL_QUADS); #if 0 RTsize w,h; buffer->getSize(w,h); float view[4]; view[0] = _optixViewport._viewport.x/(float)w; view[1] = _optixViewport._viewport.y/(float)h; view[2] = view[0] + _optixViewport._viewport.z/(float)w; view[3] = view[1] + _optixViewport._viewport.w/(float)h; glTexCoord2f(view[0], view[1]); glVertex2f(0.0f, 0.0f); glTexCoord2f(view[2], view[1]); glVertex2f(1.0f, 0.0f); glTexCoord2f(view[2], view[3]); glVertex2f(1.0f, 1.0f); glTexCoord2f(view[0], view[3]); glVertex2f(0.0f, 1.0f); #else glTexCoord2f(u, v); glVertex2f(0.1f, 0.1f); glTexCoord2f(1.0f, v); glVertex2f(.9f, 0.1f); glTexCoord2f(1.0f - u, 1.0f - v); glVertex2f(.9f, .9f); glTexCoord2f(u, 1.0f - v); glVertex2f(0.1f, .9f); #endif glEnd(); glMatrixMode(GL_PROJECTION); glPopMatrix(); glMatrixMode(GL_MODELVIEW); glPopMatrix(); texObj->deactivate(&oEnv,0); } } else { // TODO: ??? OSG_ASSERT(false); } }
void OcclusionCullingTreeBuilder::drawNode(OCRenderTreeNode *pNode, DrawEnv &denv, RenderPartitionBase *part) { leaveTesting(denv, part); 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; } //STATE ACTIVATION State *pNewState = pNode->getState(); StateOverride *pNewStateOverride = pNode->getStateOverride(); denv.setLightState(pNode->getLightState()); denv.activateState(pNewState, pNewStateOverride); pNode->setIsRendered(true); if(_ract->getOcclusionCullingDebug() && pNode->getNode()) { pNode->getNode()->setTravMask( pNode->getNode()->getTravMask() | _ract->getOcclusionVisibleDebugMask() ); } //DRAW DRAW DRAW if(pNode->hasFunctor() == true) { if(part->_bCorrectNegScale) { const Matrix &m = _currMatrix.second; // test for a "flipped" matrix // glFrontFace can give conflicts with the polygon chunk ... if(m[0].cross(m[1]).dot(m[2]) < 0.0) { glFrontFace(GL_CW); } else { glFrontFace(GL_CCW); } } //BoxVolume volume = pNode->getVol(); //drawVolume(volume); pNode->getFunctor()(&denv); } }
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 SortLastWindow::clientRender(RenderActionBase *action) { UInt32 p; UInt32 groupId = getMFServers()->size32(); if(getMFServers()->size()) { if(getClientWindow() != NULL) { setupNodes(groupId); /* getClientWindow()->activate(); getClientWindow()->frameInit(); */ action->setWindow(getClientWindow()); if(getComposer() != NULL) getComposer()->startFrame(); DrawEnv oEnv; oEnv.setWindow(action->getWindow()); // render all viewports for(p = 0; p < getMFPort()->size() ; ++p) { Viewport *vp=getPort(p); oEnv.setViewportDimension(vp->calcPixelLeft (), vp->calcPixelBottom (), vp->calcPixelRight (), vp->calcPixelTop (), vp->calcIsFullWindow()); if(getComposer() != NULL) { getComposer()->startViewport(vp); action->setCamera (vp->getCamera ()); action->setBackground(vp->getBackground()); action->setViewarea (vp ); action->setTravMask (vp->getTravMask ()); action->apply(vp->getRoot()); for(UInt16 i=0; i < vp->getMFForegrounds()->size(); i++) { if(dynamic_cast<StatisticsForeground *>( vp->getForegrounds(i)) == NULL) { vp->getForegrounds(i)->draw(&oEnv); } } getComposer()->composeViewport(vp); for(UInt16 i=0; i < vp->getMFForegrounds()->size(); i++) { if(dynamic_cast<StatisticsForeground *>( vp->getForegrounds(i)) != NULL) { vp->getForegrounds(i)->draw(&oEnv); } } } else { vp->render(action); } } // compose whole window if(getComposer() != NULL) getComposer()->composeWindow(); } } }
/*! client rendering */ void SortLastWindow::clientRender(DrawActionBase *action) { UInt32 p; UInt32 groupId = getServers().size(); UInt32 l,b,r,t; UInt32 front,back; SortLastWindow *clusterWindow(this); if(getServers().size()) { Connection *srcConnection= getNetwork()->getConnection(groupId); if(getClientWindow() != NULL) { setupNodes(groupId); /* getClientWindow()->activate(); getClientWindow()->frameInit(); */ action->setWindow(getClientWindow()); if(getComposer() != NULL) getComposer()->startFrame(); DrawEnv oEnv; oEnv.setWindow(action->getWindow()); // render all viewports for(p = 0; p < getPort().size() ; ++p) { Viewport *vp=getPort()[p]; if(getComposer() != NULL) { getComposer()->startViewport(vp); action->setCamera (vp->getCamera ()); action->setBackground(vp->getBackground()); action->setViewport (vp ); action->setTravMask (vp->getTravMask ()); action->apply(vp->getRoot()); for(UInt16 i=0; i < vp->getForegrounds().size(); i++) { if(dynamic_cast<StatisticsForeground *>( vp->getForegrounds(i)) == NULL) { vp->getForegrounds(i)->draw(&oEnv, vp); } } getComposer()->composeViewport(vp); for(UInt16 i=0; i < vp->getForegrounds().size(); i++) { if(dynamic_cast<StatisticsForeground *>( vp->getForegrounds(i)) != NULL) { vp->getForegrounds(i)->draw(&oEnv, vp); } } } else { vp->render(action); } } // compose whole window if(getComposer() != NULL) getComposer()->composeWindow(); } } }