我在使用选择缓冲区的OpenGL的选择机制中遇到了相当困难的时间。具体来说,我希望能够在选定的对象中进行子选择。我的测试世界上有散落的多个对象,每个对象有四个呈现“面临着”,类似这样的:使用SelectBuffer选择多个名称OpenGL
void drawObject(int i)
{
renderFace0(i);
renderFace1(i);
renderFace2(i);
renderFace3(i);
}
一切都很好,至今。参数i
只是说索引是什么,因为我的“对象”只是存储在数组中的数据。每个对象都是基于其索引唯一标识的。然后,我添加了采摘功能,其目标正在指向更新(我用的是屏幕的中心,其采点的对象):
void pickObject()
{
unsigned int selectBuffer[200];
int viewport[4];
int hits;
glGetIntegerv(GL_VIEWPORT, viewport);
glSelectBuffer(200, selectBuffer);
glRenderMode(GL_SELECT);
glInitNames();
glPushName(0);
glMatrixMode(GL_PROJECTION);
glPushMatrix();
glLoadIdentity();
gluPerspective(45.0f, (double)width/(double)height, 0.05f, 100.0f);
double centerX = (double)width/2.0;
double centerY = (double)height/2.0;
gluPickMatrix(centerX, centerY, 5.0f, 5.0f, viewport);
transformWorld();
int i;
for(i = 0; i < NUM_OBJECTS; i ++)
{
glLoadName(i + 1);
drawObject(i);
}
hits = glRenderMode(GL_RENDER);
if(hits > 0)
{
int znear;
znear = selectBuffer[2];
selected = selectBuffer[3];
for(i = 1; i < hits; i ++)
{
if(selectBuffer[4 * i + 2] > znear)
{
znear = selectBuffer[4 * i + 2];
selected = selectBuffer[4 * i + 3];
}
}
} else selected = -1;
glPopName();
glPopMatrix();
glFlush();
}
我应该在这一点上,我的工作请注意完全在C中。再一次,所有这些工作都很好。最近的对象被选择正确(我知道这是因为我使用selected
变量在我的渲染函数中为当前选中的对象着色。但是这些信息并不足够,因为基于此,屏幕中心的指针可能指向任何一个对象的脸部。我希望能够选择对象上的个人脸部,同时也能够识别对象本身被选中。到目前为止,我尝试的两件事是:1)使用glPushName
和glPopName
而不是glLoadName
来绘制pickObject
函数中的每个对象,然后对drawObject
函数中的每个单独的面具有glPushName
和glPopName
,但是没有得到结果我想,并且2)制作一个完全独立的函数pickFace
,我在pickObject
函数后面运行。它做同样的事情,但只渲染当前选定的对象并设置变量selectedFace
而不是selected
。我的猜测是,这是实现我想要的最低效的方式,但是,尽管它有效,但我想知道是否有更好的选择。