#include "Mesh.h" #include "glInterface.h" #include "OcclusionQuery.h" #include "QtGlRenderer.h" #include "ViewCellsManager.h" #include "SceneGraph.h" #include "Pvs.h" #include "Viewcell.h" #include "Beam.h" #include "KdTree.h" #include "Environment.h" #include "RssPreprocessor.h" #include "RssTree.h" #include "Trackball.h" #include "QtPreprocessorThread.h" #define USE_CG 1 #if USE_CG #include #include #endif #include namespace GtpVisibilityPreprocessor { class ViewCellsManager; static CGcontext sCgContext = NULL; static CGprogram sCgFragmentProgram = NULL; static CGprofile sCgFragmentProfile; //static vector sQueries; QtGlRendererWidget *rendererWidget = NULL; QtGlDebuggerWidget *debuggerWidget = NULL; static inline bool ilt(Intersectable *obj1, Intersectable *obj2) { return obj1->mId < obj2->mId; } #if USE_CG static void handleCgError() { Debug << "Cg error: " << cgGetErrorString(cgGetError()) << endl; exit(1); } #endif void QtGlRendererBuffer::MakeCurrent() { makeCurrent(); } void QtGlRendererBuffer::DoneCurrent() { doneCurrent(); } QtGlRendererBuffer::QtGlRendererBuffer(const int w, const int h, SceneGraph *sceneGraph, ViewCellsManager *viewcells, KdTree *tree): QGLPixelBuffer(QSize(w, h)), //QGLWidget(NULL, w, h), GlRendererBuffer(sceneGraph, viewcells, tree) { MakeCurrent(); InitGL(); DoneCurrent(); } float QtGlRendererBuffer::GetPixelError(int &pvsSize) { float pErrorPixels = -1.0f; glReadBuffer(GL_BACK); // mUseFalseColors = true; mUseFalseColors = false; unsigned int pixelCount; //static int query = -1; //if (query == -1) // glGenOcclusionQueriesNV(1, (unsigned int *)&query); OcclusionQuery query; ViewCell *viewcell = mViewCellsManager->GetViewCell(mViewPoint); if (viewcell == NULL) return 0.0f; if (mDetectEmptyViewSpace) { // now check whether any backfacing polygon would pass the depth test SetupCamera(); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glEnable( GL_CULL_FACE ); glCullFace(GL_BACK); cout<<"RS "; RenderScene(); glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE); glDepthMask(GL_FALSE); glDisable( GL_CULL_FACE ); query.BeginQuery(); cout<<"RS "; RenderScene(); cout<<"RS3 "; query.EndQuery(); // at this point, if possible, go and do some other computation glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); glDepthMask(GL_TRUE); glEnable( GL_CULL_FACE ); // reenable other state pixelCount = query.GetQueryResult(); cout<<"RS4 "; if (pixelCount > 0) return -1.0f; // backfacing polygon found -> not a valid viewspace sample } else glDisable( GL_CULL_FACE ); // ViewCell *viewcell = NULL; // PrVs prvs; // mViewCellsManager->SetMaxFilterSize(0); // mViewCellsManager->GetPrVS(mViewPoint, prvs, mViewCellsManager->GetFilterWidth()); // viewcell = prvs.mViewCell; ObjectPvs pvs; if (1) { pvs = viewcell->GetPvs(); } else { mViewCellsManager->ApplyFilter2(viewcell, false, 1.0f, pvs); } SetupCamera(); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glColorMask(GL_FALSE, GL_TRUE, GL_FALSE, GL_FALSE); // // Render PVS ObjectPvsIterator it = pvs.GetIterator(); pvsSize = pvs.GetSize(); Intersectable::NewMail(); for (; it.HasMoreEntries(); ) { ObjectPvsEntry entry = it.Next(); Intersectable *object = entry.mObject; RenderIntersectable(object); } // glColorMask(GL_TRUE, GL_FALSE, GL_FALSE, GL_FALSE); glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); mUseFalseColors = true; query.BeginQuery(); SetupCamera(); RenderScene(); query.EndQuery(); // reenable other state pixelCount = query.GetQueryResult(); pErrorPixels = ((float)pixelCount)/(GetWidth()*GetHeight()); if (mSnapErrorFrames && pErrorPixels > 0.001f) { char filename[256]; sprintf(filename, "error-frame-%04d-%0.5f.png", mFrame, pErrorPixels); QImage im = toImage(); string str = mSnapPrefix + filename; QString qstr(str.c_str()); im.save(qstr, "PNG"); if (1) { //0 && mFrame == 1543) { int x,y; int lastIndex = -1; for (y=0; y < im.height(); y++) for (x=0; x < im.width(); x++) { QRgb p = im.pixel(x,y); int index = qRed(p) + (qGreen(p)<<8) + (qBlue(p)<<16); if (qGreen(p) != 255 && index!=0) { if (index != lastIndex) { // Debug<<"ei="<GetId() == id) && !obj->Mailed()) { obj = *oit; obj->Mail(); ++ pvsSize; pvs.push_back(obj); } } } return pvsSize; } /////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////// void QtGlRendererWidget::SetupCameraProjection(const int w, const int h, const float angle) { if (!mTopView) { int ww = w; int hh = h; glViewport(0, 0, ww, hh); glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluPerspective(angle, ww/(float)hh, 0.1, 2.0*Magnitude(mSceneGraph->GetBox().Diagonal())); glMatrixMode(GL_MODELVIEW); } else { int ww = w; int hh = h; glViewport(0, 0, ww, hh); glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluPerspective(50.0, ww/(float)hh, 0.1, 20.0*Magnitude(mSceneGraph->GetBox().Diagonal())); glMatrixMode(GL_MODELVIEW); } } void QtGlRendererWidget::RenderPvs() { Intersectable::NewMail(); ViewCell *viewcell = NULL; PrVs prvs; if (1 || !mUseFilter) { viewcell = mViewCellsManager->GetViewCell(mViewPoint, true); } else { // mViewCellsManager->SetMaxFilterSize(1); mViewCellsManager->GetPrVS(mViewPoint, prvs, mViewCellsManager->GetFilterWidth()); viewcell = prvs.mViewCell; } if (viewcell) { // copy the pvs so that it can be filtered... // mPvsCache.mPvs; if (mPvsCache.mViewCell != viewcell) { mPvsCache.Reset(); mPvsCache.mViewCell = viewcell; if (mUseSpatialFilter) { // 9.11. 2006 -> experiment with new spatial filter #if 0 mViewCellsManager->ApplySpatialFilter(mKdTree, mSpatialFilterSize* Magnitude(mViewCellsManager->GetViewSpaceBox().Size()), mPvsCache.mPvs); #else // mSpatialFilter size is in range 0.001 - 0.1 mViewCellsManager->ApplyFilter2(viewcell, mUseFilter, 100*mSpatialFilterSize, mPvsCache.mPvs, &mPvsCache.filteredBoxes ); #endif } else mPvsCache.mPvs = viewcell->GetPvs(); emit PvsUpdated(); } // Render PVS if (mUseSpatialFilter && mRenderBoxes) { for (int i=0; i < mPvsCache.filteredBoxes.size(); i++) RenderBox(mPvsCache.filteredBoxes[i]); } else { ObjectPvsIterator it = mPvsCache.mPvs.GetIterator(); mPvsSize = mPvsCache.mPvs.GetSize(); for (; it.HasMoreEntries(); ) { ObjectPvsEntry entry = it.Next(); Intersectable *object = entry.mObject; if (mRenderVisibilityEstimates) { float visibility = mTransferFunction*log10(entry.mData.mSumPdf + 1); // /5.0f glColor3f(visibility, 0.0f, 0.0f); mUseForcedColors = true; RenderIntersectable(object); mUseForcedColors = false; } else { mUseForcedColors = false; RenderIntersectable(object); } } } if (mRenderFilter) { mWireFrame = true; RenderIntersectable(viewcell); glPushMatrix(); glTranslatef(mViewPoint.x, mViewPoint.y, mViewPoint.z); glScalef(5.0f,5.0f,5.0f); glPushAttrib(GL_CURRENT_BIT); glColor3f(1.0f, 0.0f, 0.0f); gluSphere((::GLUquadric *)mSphere, 1e-3*Magnitude(mViewCellsManager->GetViewSpaceBox().Size()), 6, 6); glPopAttrib(); glPopMatrix(); mWireFrame = false; } if (0 && mUseFilter) mViewCellsManager->DeleteLocalMergeTree(viewcell); } else { ObjectContainer::const_iterator oi = mObjects.begin(); for (; oi != mObjects.end(); oi++) RenderIntersectable(*oi); } } float QtGlRendererWidget::RenderErrors() { float pErrorPixels = -1.0f; glReadBuffer(GL_BACK); mUseFalseColors = true; glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); double eq[4]; eq[0] = mSceneCutPlane.mNormal.x; eq[1] = mSceneCutPlane.mNormal.y; eq[2] = mSceneCutPlane.mNormal.z; eq[3] = mSceneCutPlane.mD; if (mCutScene) { glClipPlane(GL_CLIP_PLANE0, eq); glEnable(GL_CLIP_PLANE0); } if (mDetectEmptyViewSpace) glEnable( GL_CULL_FACE ); else glDisable( GL_CULL_FACE ); ObjectContainer::const_iterator oi = mObjects.begin(); for (; oi != mObjects.end(); oi++) RenderIntersectable(*oi); ViewCell *viewcell = NULL; QImage im1, im2; QImage diff; if (viewcell) { // read back the texture im1 = grabFrameBuffer(true); RenderPvs(); // read back the texture im2 = grabFrameBuffer(true); diff = im1; int x, y; int errorPixels = 0; for (y = 0; y < im1.height(); y++) for (x = 0; x < im1.width(); x++) if (im1.pixel(x, y) == im2.pixel(x, y)) diff.setPixel(x, y, qRgba(0,0,0,0)); else { diff.setPixel(x, y, qRgba(255,128,128,255)); errorPixels++; } pErrorPixels = ((float)errorPixels)/(im1.height()*im1.width()); } // now render the pvs again SetupCamera(); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); mUseFalseColors = false; oi = mObjects.begin(); for (; oi != mObjects.end(); oi++) RenderIntersectable(*oi); // now render im1 if (viewcell) { if (0 && mTopView) { mWireFrame = true; RenderIntersectable(viewcell); mWireFrame = false; } // init ortographic projection glMatrixMode(GL_PROJECTION); glPushMatrix(); glLoadIdentity(); gluOrtho2D(0, 1.0f, 0, 1.0f); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); bindTexture(diff); glPushAttrib(GL_ENABLE_BIT); glEnable( GL_ALPHA_TEST ); glDisable( GL_CULL_FACE ); glAlphaFunc( GL_GREATER, 0.5 ); glEnable( GL_TEXTURE_2D ); glBegin(GL_QUADS); glTexCoord2f(0,0); glVertex3f(0,0,0); glTexCoord2f(1,0); glVertex3f( 1, 0, 0); glTexCoord2f(1,1); glVertex3f( 1, 1, 0); glTexCoord2f(0,1); glVertex3f(0, 1, 0); glEnd(); glPopAttrib(); // restore the projection matrix glMatrixMode(GL_PROJECTION); glPopMatrix(); glMatrixMode(GL_MODELVIEW); } glDisable(GL_CLIP_PLANE0); mRenderError = pErrorPixels; return pErrorPixels; } void QtGlRendererWidget::mousePressEvent(QMouseEvent *e) { int x = e->pos().x(); int y = e->pos().y(); mousePoint.x = x; mousePoint.y = y; } void QtGlRendererWidget::mouseMoveEvent(QMouseEvent *e) { float MOVE_SENSITIVITY = Magnitude(mSceneGraph->GetBox().Diagonal())*1e-3; float TURN_SENSITIVITY=0.1f; float TILT_SENSITIVITY=32.0 ; float TURN_ANGLE= M_PI/36.0 ; int x = e->pos().x(); int y = e->pos().y(); int diffx = -(mousePoint.x - x); int diffy = -(mousePoint.y - y); if (e->modifiers() & Qt::ControlModifier) { mViewPoint.y += (y-mousePoint.y)*MOVE_SENSITIVITY/2.0; mViewPoint.x += (x-mousePoint.x)*MOVE_SENSITIVITY/2.0; } else { mViewPoint += mViewDirection*((mousePoint.y - y)*MOVE_SENSITIVITY); float adiff = TURN_ANGLE*(x - mousePoint.x)*-TURN_SENSITIVITY; float angle = atan2(mViewDirection.x, mViewDirection.z); mViewDirection.x = sin(angle+adiff); mViewDirection.z = cos(angle+adiff); } mousePoint.x = x; mousePoint.y = y; updateGL(); } void QtGlRendererWidget::mouseReleaseEvent(QMouseEvent *) { } void QtGlRendererWidget::resizeGL(int w, int h) { SetupCameraProjection(w, h); updateGL(); } void QtGlRendererWidget::paintGL() { glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); if (1) { SetupCameraProjection(width(), height()); SetupCamera(); if (mRenderErrors) { RenderErrors(); } else { RenderPvs(); } } RenderInfo(); mFrame++; } void QtGlRendererWidget::SetupCamera() { if (!mTopView) GlRenderer::SetupCamera(); else { if (0) { float dist = Magnitude(mSceneGraph->GetBox().Diagonal())*0.05; Vector3 pos = mViewPoint - dist*Vector3(mViewDirection.x, -1, mViewDirection.y); Vector3 target = mViewPoint + dist*mViewDirection; Vector3 up(0,1,0); glLoadIdentity(); gluLookAt(pos.x, pos.y, pos.z, target.x, target.y, target.z, up.x, up.y, up.z); } else { float dist = Magnitude(mSceneGraph->GetBox().Diagonal())*mTopDistance; Vector3 pos = mViewPoint + dist*Vector3(0, 1, 0); Vector3 target = mViewPoint; Vector3 up(mViewDirection.x, 0, mViewDirection.z); glLoadIdentity(); gluLookAt(pos.x, pos.y, pos.z, target.x, target.y, target.z, up.x, up.y, up.z); } } } void QtGlRendererWidget::keyPressEvent ( QKeyEvent * e ) { switch (e->key()) { case Qt::Key_T: mTopView = !mTopView; SetupCameraProjection(width(), height()); updateGL(); break; case Qt::Key_V: mRenderViewCells = !mRenderViewCells; updateGL(); break; case Qt::Key_P: // set random viewpoint mViewCellsManager->GetViewPoint(mViewPoint); updateGL(); break; default: e->ignore(); break; } } QtGlRendererWidget::QtGlRendererWidget( SceneGraph *sceneGraph, ViewCellsManager *viewcells, KdTree *tree, QWidget * parent, const QGLWidget * shareWidget, Qt::WFlags f ) : GlRendererWidget(sceneGraph, viewcells, tree), QGLWidget(parent, shareWidget, f) { mPreprocessorThread = NULL; mTopView = false; mRenderViewCells = false; mTopDistance = 1.0f; mCutViewCells = false; mCutScene = false; mRenderErrors = false; mRenderBoxes = false; mRenderFilter = true; mRenderVisibilityEstimates = false; mTransferFunction = 0.2f; bool tmp; Environment::GetSingleton()->GetBoolValue("Preprocessor.applyVisibilityFilter", tmp ); mUseFilter = tmp; Environment::GetSingleton()->GetBoolValue("Preprocessor.applyVisibilitySpatialFilter", tmp ); mUseSpatialFilter = tmp; mShowRenderCost = false; mShowPvsSizes = false; mSpatialFilterSize = 0.01; mPvsSize = 0; mRenderError = 0.0f; mShowRays = false; mControlWidget = new QtRendererControlWidget(NULL); connect(mControlWidget, SIGNAL(SetViewCellGranularity(int)), this, SLOT(SetViewCellGranularity(int))); connect(mControlWidget, SIGNAL(SetTransferFunction(int)), this, SLOT(SetTransferFunction(int))); connect(mControlWidget, SIGNAL(UpdateAllPvs()), this, SLOT(UpdateAllPvs())); connect(mControlWidget, SIGNAL(ComputeVisibility()), this, SLOT(ComputeVisibility())); connect(mControlWidget, SIGNAL(StopComputation()), this, SLOT(StopComputation())); connect(mControlWidget, SIGNAL(SetSceneCut(int)), this, SLOT(SetSceneCut(int))); connect(mControlWidget, SIGNAL(SetTopDistance(int)), this, SLOT(SetTopDistance(int))); connect(mControlWidget, SIGNAL(SetVisibilityFilterSize(int)), this, SLOT(SetVisibilityFilterSize(int))); connect(mControlWidget, SIGNAL(SetSpatialFilterSize(int)), this, SLOT(SetSpatialFilterSize(int))); connect(mControlWidget, SIGNAL(SetShowViewCells(bool)), this, SLOT(SetShowViewCells(bool))); connect(mControlWidget, SIGNAL(SetShowRenderCost(bool)), this, SLOT(SetShowRenderCost(bool))); connect(mControlWidget, SIGNAL(SetShowPvsSizes(bool)), this, SLOT(SetShowPvsSizes(bool))); connect(mControlWidget, SIGNAL(SetTopView(bool)), this, SLOT(SetTopView(bool))); connect(mControlWidget, SIGNAL(SetCutViewCells(bool)), this, SLOT(SetCutViewCells(bool))); connect(mControlWidget, SIGNAL(SetCutScene(bool)), this, SLOT(SetCutScene(bool))); connect(mControlWidget, SIGNAL(SetRenderErrors(bool)), this, SLOT(SetRenderErrors(bool))); connect(mControlWidget, SIGNAL(SetRenderBoxes(bool)), this, SLOT(SetRenderBoxes(bool))); connect(mControlWidget, SIGNAL(SetRenderFilter(bool)), this, SLOT(SetRenderFilter(bool))); connect(mControlWidget, SIGNAL(SetRenderVisibilityEstimates(bool)), this, SLOT(SetRenderVisibilityEstimates(bool))); connect(mControlWidget, SIGNAL(SetUseFilter(bool)), this, SLOT(SetUseFilter(bool))); connect(mControlWidget, SIGNAL(SetUseSpatialFilter(bool)), this, SLOT(SetUseSpatialFilter(bool))); connect(mControlWidget, SIGNAL(SetShowRays(bool)), this, SLOT(SetShowRays(bool))); resize(1000, 500); mControlWidget->show(); } void QtGlRendererWidget::UpdateAllPvs() { // $$ does not work so far:( mViewCellsManager->UpdatePvsForEvaluation(); // mViewCellsManager->FinalizeViewCells(false); } void QtGlRendererWidget::ComputeVisibility() { cerr<<"Compute Visibility called!\n"<isRunning()) mPreprocessorThread->RunThread(); } void QtGlRendererWidget::StopComputation() { cerr<<"stop computation called!\n"<GetPreprocessor()->mStopComputation = true; } void QtGlRendererWidget::RenderRenderCost() { static vector costFunction; static float maxCost = -1; if (costFunction.size()==0) { ViewCellsTree *tree = mViewCellsManager->GetViewCellsTree(); if (tree) { tree->GetCostFunction(costFunction); maxCost = -1; for (int i=0; i < costFunction.size(); i++) { // cout<GetRoot()->mGeometry.size(); if (costFunction[i] > maxCost) maxCost = costFunction[i]; } } } int currentPos = (int)mViewCellsManager->GetViewCells().size(); float currentCost= -1; if (currentPos < costFunction.size()) currentCost = costFunction[currentPos]; #if 1 cout<<"costFunction.size()="<GetViewCells().size(); int filter = 0; if (mViewCellsManager) filter = mViewCellsManager->GetMaxFilterSize(); glColor3f(1.0f,1.0f,1.0f); s.sprintf("frame:%04d viewpoint:(%4.1f,%4.1f,%4.1f) dir:(%4.1f,%4.1f,%4.1f)", mFrame, mViewPoint.x, mViewPoint.y, mViewPoint.z, mViewDirection.x, mViewDirection.y, mViewDirection.z ); renderText(20,20,s); s.sprintf("viewcells:%04d filter:%04d pvs:%04d error:%5.5f\%", vc, filter, mPvsSize, mRenderError*100.0f); renderText(20,40,s); } void QtGlRendererWidget::SetViewCellGranularity(int number) { if (mViewCellsManager) { // mViewCellsManager->SetMaxFilterSize(number); mViewCellsManager->CollectViewCells(number); // $$ does not work so far:( // mViewCellsManager->UpdatePvsForEvaluation(); // mViewCellsManager->FinalizeViewCells(false); } updateGL(); } void QtGlRendererWidget::SetVisibilityFilterSize(int number) { if (mViewCellsManager) mViewCellsManager->SetMaxFilterSize(number); mPvsCache.Reset(); updateGL(); } void QtGlRendererWidget::SetSpatialFilterSize(int number) { mSpatialFilterSize = 1e-3*number; mPvsCache.Reset(); updateGL(); } void QtGlRendererWidget::SetSceneCut(int number) { // assume the cut plane can only be aligned with xz plane // shift it along y according to number, which is percentage of the bounding // box position if (mViewCellsManager) { AxisAlignedBox3 box = mViewCellsManager->GetViewSpaceBox(); Vector3 p = box.Min() + (number/1000.0f)*box.Max(); mSceneCutPlane.mNormal = Vector3(0,-1,0); mSceneCutPlane.mD = -DotProd(mSceneCutPlane.mNormal, p); updateGL(); } } void QtGlRendererWidget::SetTopDistance(int number) { mTopDistance = number/1000.0f; updateGL(); } void QtGlRendererWidget::RenderViewCells() { mUseFalseColors = true; glPushAttrib(GL_CURRENT_BIT | GL_ENABLE_BIT | GL_POLYGON_BIT); glEnable(GL_CULL_FACE); //glDisable(GL_CULL_FACE); glCullFace(GL_FRONT); double eq[4]; eq[0] = mSceneCutPlane.mNormal.x; eq[1] = mSceneCutPlane.mNormal.y; eq[2] = mSceneCutPlane.mNormal.z; eq[3] = mSceneCutPlane.mD; if (mCutViewCells) { glClipPlane(GL_CLIP_PLANE0, eq); glEnable(GL_CLIP_PLANE0); } int i; ViewCellContainer &viewcells = mViewCellsManager->GetViewCells(); int maxPvs = -1; for (i=0; i < viewcells.size(); i++) { ViewCell *vc = viewcells[i]; //const int p = vc->GetPvs().CountObjectsInPvs(); const int p = vc->GetPvs().GetSize(); if (p > maxPvs) maxPvs = p; } for (i=0; i < viewcells.size(); i++) { ViewCell *vc = viewcells[i]; // Mesh *m = vc->GetMesh(); RgbColor c; if (!mShowPvsSizes) { mWireFrame = true; c = vc->GetColor(); } else { // const float importance = 5.0f*mTransferFunction * ((float)vc->GetPvs().CountObjectsInPvs() / (float)maxPvs); const float importance = 5.0f*mTransferFunction * ((float)vc->GetPvs().GetSize() / (float)maxPvs); c = RgbColor(importance, 1.0f - importance, 0.0f); } glColor3f(c.r, c.g, c.b); RenderViewCell(vc); } mUseFalseColors = false; mWireFrame = false; glPopAttrib(); } /***********************************************************************/ /* QtGlDebuggerWidget implementation */ /***********************************************************************/ QtGlDebuggerWidget::QtGlDebuggerWidget(QtGlRendererBuffer *buf, QWidget *parent) : QGLWidget(QGLFormat(QGL::SampleBuffers), parent), mRenderBuffer(buf) { // create the pbuffer //pbuffer = new QGLPixelBuffer(QSize(512, 512), format(), this); timerId = startTimer(20); setWindowTitle(("OpenGL pbuffers")); } QtGlDebuggerWidget::~QtGlDebuggerWidget() { mRenderBuffer->releaseFromDynamicTexture(); glDeleteTextures(1, &dynamicTexture); DEL_PTR(mRenderBuffer); } QtRendererControlWidget::QtRendererControlWidget(QWidget * parent, Qt::WFlags f): QWidget(parent, f) { QVBoxLayout *vl = new QVBoxLayout; setLayout(vl); QWidget *vbox = new QGroupBox("ViewCells", this); layout()->addWidget(vbox); vl = new QVBoxLayout; vbox->setLayout(vl); QLabel *label = new QLabel("Granularity"); vbox->layout()->addWidget(label); QSlider *slider = new QSlider(Qt::Horizontal, vbox); vl->addWidget(slider); slider->show(); slider->setRange(1, 10000); slider->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred); slider->setValue(200); connect(slider, SIGNAL(valueChanged(int)), SIGNAL(SetViewCellGranularity(int))); label = new QLabel("Transfer function"); vbox->layout()->addWidget(label); slider = new QSlider(Qt::Horizontal, vbox); vl->addWidget(slider); slider->show(); slider->setRange(1, 1000); slider->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred); slider->setValue(100); connect(slider, SIGNAL(valueChanged(int)), SIGNAL(SetTransferFunction(int))); { QPushButton *button = new QPushButton("Update all PVSs", vbox); vbox->layout()->addWidget(button); connect(button, SIGNAL(clicked()), SLOT(UpdateAllPvs())); } label = new QLabel("Filter size"); vbox->layout()->addWidget(label); slider = new QSlider(Qt::Horizontal, vbox); vbox->layout()->addWidget(slider); slider->show(); slider->setRange(1, 100); slider->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred); slider->setValue(3); connect(slider, SIGNAL(valueChanged(int)), SIGNAL(SetVisibilityFilterSize(int))); label = new QLabel("Spatial Filter size"); vbox->layout()->addWidget(label); slider = new QSlider(Qt::Horizontal, vbox); vbox->layout()->addWidget(slider); slider->show(); slider->setRange(1, 100); slider->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred); slider->setValue(10); connect(slider, SIGNAL(valueChanged(int)), SIGNAL(SetSpatialFilterSize(int))); QWidget *hbox = new QWidget(vbox); vl->addWidget(hbox); QHBoxLayout *hlayout = new QHBoxLayout; hbox->setLayout(hlayout); QCheckBox *cb = new QCheckBox("Show viewcells", hbox); hlayout->addWidget(cb); cb->setChecked(false); connect(cb, SIGNAL(toggled(bool)), SIGNAL(SetShowViewCells(bool))); cb = new QCheckBox("Render cost curve", hbox); hlayout->addWidget(cb); cb->setChecked(false); connect(cb, SIGNAL(toggled(bool)), SIGNAL(SetShowRenderCost(bool))); cb = new QCheckBox("Show render cost", hbox); hlayout->addWidget(cb); cb->setChecked(false); connect(cb, SIGNAL(toggled(bool)), SIGNAL(SetShowPvsSizes(bool))); cb = new QCheckBox("Show rays", hbox); hlayout->addWidget(cb); cb->setChecked(false); connect(cb, SIGNAL(toggled(bool)), SIGNAL(SetShowRays(bool))); vbox->resize(800,100); vbox = new QGroupBox("Rendering", this); layout()->addWidget(vbox); vl = new QVBoxLayout; vbox->setLayout(vl); cb = new QCheckBox("Cut view cells", vbox); vbox->layout()->addWidget(cb); cb->setChecked(false); connect(cb, SIGNAL(toggled(bool)), SIGNAL(SetCutViewCells(bool))); slider = new QSlider(Qt::Horizontal, vbox); vbox->layout()->addWidget(slider); slider->show(); slider->setRange(0, 1000); slider->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred); slider->setValue(1000); connect(slider, SIGNAL(valueChanged(int)), SIGNAL(SetSceneCut(int))); cb = new QCheckBox("Cut scene", vbox); vbox->layout()->addWidget(cb); cb->setChecked(false); connect(cb, SIGNAL(toggled(bool)), SIGNAL(SetCutScene(bool))); cb = new QCheckBox("Render boxes", vbox); vbox->layout()->addWidget(cb); cb->setChecked(false); connect(cb, SIGNAL(toggled(bool)), SIGNAL(SetRenderBoxes(bool))); cb = new QCheckBox("Render visibility estimates", vbox); vbox->layout()->addWidget(cb); cb->setChecked(false); connect(cb, SIGNAL(toggled(bool)), SIGNAL(SetRenderVisibilityEstimates(bool))); cb = new QCheckBox("Render errors", vbox); vbox->layout()->addWidget(cb); cb->setChecked(false); connect(cb, SIGNAL(toggled(bool)), SIGNAL(SetRenderErrors(bool))); bool tmp; cb = new QCheckBox("Use filter", vbox); vbox->layout()->addWidget(cb); Environment::GetSingleton()->GetBoolValue("Preprocessor.applyVisibilityFilter", tmp ); cb->setChecked(tmp); connect(cb, SIGNAL(toggled(bool)), SIGNAL(SetUseFilter(bool))); cb = new QCheckBox("Use spatial filter", vbox); vbox->layout()->addWidget(cb); Environment::GetSingleton()->GetBoolValue("Preprocessor.applyVisibilitySpatialFilter", tmp ); cb->setChecked(tmp); connect(cb, SIGNAL(toggled(bool)), SIGNAL(SetUseSpatialFilter(bool))); cb = new QCheckBox("Render filter", vbox); vbox->layout()->addWidget(cb); cb->setChecked(true); connect(cb, SIGNAL(toggled(bool)), SIGNAL(SetRenderFilter(bool))); slider = new QSlider(Qt::Horizontal, vbox); vbox->layout()->addWidget(slider); slider->show(); slider->setRange(1, 1000); slider->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred); slider->setValue(500); connect(slider, SIGNAL(valueChanged(int)), SIGNAL(SetTopDistance(int))); cb = new QCheckBox("Top View", vbox); vbox->layout()->addWidget(cb); cb->setChecked(false); connect(cb, SIGNAL(toggled(bool)), SIGNAL(SetTopView(bool))); vbox = new QGroupBox("PVS Errors", this); layout()->addWidget(vbox); vl = new QVBoxLayout; vbox->setLayout(vl); QPushButton *button = new QPushButton("Compute Visibility", vbox); vbox->layout()->addWidget(button); connect(button, SIGNAL(clicked()), SLOT(ComputeVisibility())); button = new QPushButton("Stop Computation", vbox); vbox->layout()->addWidget(button); connect(button, SIGNAL(clicked()), SLOT(StopComputation())); if (0) { vbox = new QGroupBox("PVS Errors", this); layout()->addWidget(vbox); vl = new QVBoxLayout; vbox->setLayout(vl); mPvsErrorWidget = new QListWidget(vbox); vbox->layout()->addWidget(mPvsErrorWidget); connect(mPvsErrorWidget, SIGNAL(doubleClicked(const QModelIndex &)), this, SLOT(PvsErrorClicked(const QModelIndex &))); QPushButton *button = new QPushButton("Next Error Frame", vbox); vbox->layout()->addWidget(button); connect(button, SIGNAL(clicked(void)), SLOT(FocusNextPvsErrorFrame(void))); } setWindowTitle("Preprocessor Control Widget"); adjustSize(); } void QtRendererControlWidget::FocusNextPvsErrorFrame(void) { } void QtRendererControlWidget::UpdatePvsErrorItem(int row, GlRendererBuffer::PvsErrorEntry &pvsErrorEntry) { QListWidgetItem *i = mPvsErrorWidget->item(row); QString s; s.sprintf("%5.5f", pvsErrorEntry.mError); if (i) { i->setText(s); } else { new QListWidgetItem(s, mPvsErrorWidget); } mPvsErrorWidget->update(); } void QtGlDebuggerWidget::initializeGL() { glMatrixMode(GL_PROJECTION); glLoadIdentity(); glFrustum(-1, 1, -1, 1, 10, 100); glTranslatef(-0.5f, -0.5f, -0.5f); glTranslatef(0.0f, 0.0f, -15.0f); glMatrixMode(GL_MODELVIEW); glEnable(GL_CULL_FACE); initCommon(); initPbuffer(); } void QtGlDebuggerWidget::resizeGL(int w, int h) { glViewport(0, 0, w, h); } void QtGlDebuggerWidget::paintGL() { // draw a spinning cube into the pbuffer.. mRenderBuffer->makeCurrent(); BeamSampleStatistics stats; mRenderBuffer->SampleBeamContributions(mSourceObject, mBeam, mSamples, stats); glFlush(); // rendering directly to a texture is not supported on X11, unfortunately mRenderBuffer->updateDynamicTexture(dynamicTexture); // and use the pbuffer contents as a texture when rendering the // background and the bouncing cubes makeCurrent(); glBindTexture(GL_TEXTURE_2D, dynamicTexture); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // draw the background glMatrixMode(GL_MODELVIEW); glPushMatrix(); glLoadIdentity(); glMatrixMode(GL_PROJECTION); glPushMatrix(); glLoadIdentity(); glPopMatrix(); glMatrixMode(GL_MODELVIEW); glPopMatrix(); } void QtGlDebuggerWidget::initPbuffer() { // set up the pbuffer context mRenderBuffer->makeCurrent(); /*mRenderBuffer->InitGL(); glViewport(0, 0, mRenderBuffer->size().width(), mRenderBuffer->size().height()); glMatrixMode(GL_PROJECTION); glLoadIdentity(); glOrtho(-1, 1, -1, 1, -99, 99); glTranslatef(-0.5f, -0.5f, 0.0f); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);*/ // generate a texture that has the same size/format as the pbuffer dynamicTexture = mRenderBuffer->generateDynamicTexture(); // bind the dynamic texture to the pbuffer - this is a no-op under X11 mRenderBuffer->bindToDynamicTexture(dynamicTexture); makeCurrent(); } void QtGlDebuggerWidget::initCommon() { glEnable(GL_TEXTURE_2D); glEnable(GL_DEPTH_TEST); glClearColor(1.0f, 1.0f, 1.0f, 1.0f); } }