在做一次选择(GL_SELECT模式)后,一半Fps (OpenGL)

Half Fps (OpenGL) after doing a single selection (GL_SELECT mode)

本文关键字:模式 一半 OpenGL Fps SELECT GL 一次 选择      更新时间:2023-10-16

我知道OpenGL选择模式已被弃用,并且从未进行过硬件加速,除了在一些SGI盒和3DLabs gpu上。但是我不能摆脱它(不是我的代码)。

对于一个特定的绘图,我得到大约125帧/秒。但当我有一个(或更多)点击(选择模式工作),我试着像往常一样移动相机,我得到大约40-50帧/秒。如果没有点击,就不会发生什么奇怪的事情,我也会有同样好的帧率。

我做错了什么?

下面是c++代码:

void GLWidget::paintGL()
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
gluLookAt(objCamera->mPos.x,  objCamera->mPos.y,  objCamera->mPos.z,
          0, objCamera->mView.y, 0,
          objCamera->mUp.x,   objCamera->mUp.y,   objCamera->mUp.z);        
ourRender(scene);
}

startSelection被Qt mousePressEvent调用

void GLWidget::startSelection(int x,int y)                                                                 // This Is Where Selection Is Done
{
GLint viewport[4];
glSelectBuffer(BUFSIZE,selectBuf);
glRenderMode(GL_SELECT);
glInitNames();
glMatrixMode(GL_PROJECTION);
glPushMatrix();
glLoadIdentity();
glGetIntegerv(GL_VIEWPORT,viewport);
gluPickMatrix(x,viewport[3]-y,5,5,viewport);
gluPerspective(fov,ratio,0.1f,1000);
glMatrixMode(GL_MODELVIEW);
draw_something();
stopSelection();
}

void GLWidget::stopSelection() {
int hits;
glMatrixMode(GL_PROJECTION);      // restoring the original projection matrix
glPopMatrix();
glMatrixMode(GL_MODELVIEW);
hits = glRenderMode(GL_RENDER);      // returning to normal rendering mode
if (hits > 0){
    qDebug() << "Found " << hits << " hit(s)";
    }
}

对于一个特定的绘图,我得到大约125帧/秒。但当我有一个(或更多)点击(选择模式工作),我试着像往常一样移动相机,我得到大约40-50帧/秒。如果没有点击,就不会发生什么奇怪的事情,我也会有同样好的帧率。

想想看:没有命中意味着,没有任何东西必须被压入选择名称堆栈。很有可能,选择模式的SW实现只在有实际命中时才分配名称堆栈,即原语将在剪辑音量中被光栅化。内存分配是一个开销很大的操作。

现在你的渲染代码将不得不在名称堆栈上推送id,如果它也在"可见"渲染路径中这样做,它可能会与选择模式的内存分配交互。

这些都是纯粹的(有根据的)猜测。

我做错了什么?

我不会说"错了",而是"不开心"。我会在场景渲染代码中引入一个标志,如果不是在选择模式下,则不会在名称堆栈上推送id。

我看到你忘了初始化帧缓冲数据,现在你正在为实时帧分配空间,这使得计算时间比正常情况下长10倍。这很容易修复。

另外,我建议你修改这个:

void GLWidget::paintGL()
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
gluLookAt(objCamera->mPos.x,  objCamera->mPos.y,  objCamera->mPos.z,
          0, objCamera->mView.y, 0,
          objCamera->mUp.x,   objCamera->mUp.y,   objCamera->mUp.z);        
ourRender(scene);
}

这:

void GLWidget::paintGL()
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
glBufferInfluxinatorPrep(scene);
gluLookAt(objCamera->mPos.x,  objCamera->mPos.y,  objCamera->mPos.z,
          0, objCamera->mView.y, 0,
          objCamera->mUp.x,   objCamera->mUp.y,   objCamera->mUp.z);        
ourRender(scene);
glBufferDefluxinator(scene);
}

希望有帮助,谢谢。