19,469
社区成员
发帖
与我相关
我的任务
分享
void COpenGLView::ProcessSelection(int xPos, int yPos)
{
GLuint selectBuff[64]={0}; // 定义检选缓冲区
GLint viewport[4]; // 用于存放视口信息
GLint selectedObj; // 当前鼠标选中的物体ID
glSelectBuffer(64, selectBuff); // 设置检选缓冲区
glRenderMode(GL_SELECT); // 设置为检选模式
glGetIntegerv(GL_VIEWPORT, viewport); // 获得当前视口数据
glMatrixMode(GL_PROJECTION); // 切换到投影矩阵模式
glPushMatrix(); // 保存当前投影矩阵
glLoadIdentity(); // 重置投影矩阵
gluPickMatrix(xPos, viewport[3] - yPos, 1, 1, viewport); // 定义矩形检选区域
gluPerspective(40.0F, aspect_ratio, 1.0F, 1000.0F); // 设置透视投影
glMatrixMode(GL_MODELVIEW); // 切换到模型视图矩阵
RenderScene(); // 调用RenderScene()绘制物体,但它并不会被光栅化
glMatrixMode(GL_PROJECTION);
glPopMatrix(); // 恢复原投影矩阵
glMatrixMode(GL_MODELVIEW);
selectedObj=glRenderMode(GL_RENDER); // 设置光栅模式为渲染模式
GLuint modelselect = 0; //离眼睛最近的物件的名字(ID)
if (selectedObj >0)
{
int n=0; GLuint minz=selectBuff[1];
for(int i=1;i<selectedObj;i++)
{
if (selectBuff[1+i*4]<minz) {n=i;minz=selectBuff[1+i*4];}
}
modelselect = selectBuff[3+n*4];
}
static bool state=false;
switch(modelselect)
{
case PXJHEI:
m_tip.AddTool(this,TTS_ALWAYSTIP);
m_tip.UpdateTipText("黑色",this);
break;
case PXJHONG:
m_tip.AddTool(this,TTS_ALWAYSTIP);
m_tip.UpdateTipText("红色",this);
break;
}
}
void GCVPTrajectorySelector::OnMouseMove ( QMouseEvent* evnt)
{
if(WORKPLANE==NULL)
{
PLANE_POSITION_HOVERED_ID = -1;
return;
}
int xPos = evnt->x();
int yPos = evnt->y();
GLuint selectBuff[512];
for(int i=0;i<512;i++)
selectBuff[i] = 0;
glSelectBuffer(512, selectBuff);
glRenderMode(GL_SELECT);
glPushMatrix();
this->m_pManager->getGLView()->getCamera()->setSelectModeProjectionAndView(xPos, yPos); //采用和正常显示不一样的ModelView矩阵设置
BOX->renderPlaneTrajectorys4Pick();
glPopMatrix();
GLint hits = glRenderMode(GL_RENDER);
int selectedNameID = -1;
if(hits>0)
{
if(selectBuff[0]>0)
selectedNameID = selectBuff[3];
if(hits>1)
{
int indexbase = 3+selectBuff[0];
int toCompared = selectBuff[indexbase+3];
if(selectBuff[1]>selectBuff[indexbase+1])
selectedNameID = toCompared;
}
}
PLANE_POSITION_HOVERED_ID = selectedNameID;
this->m_pManager->getGLView()->notifyViewInvalidate();
}
与Pick相关的设置及对照方法
void GCPerspectiveCamera::setSelectModeProjectionAndView(int px,int py)
{
glMatrixMode(GL_PROJECTION);
glLoadIdentity( );
int viewport[] = {0, 0, m_nViewportWidth, m_nViewportHeight};
gluPickMatrix(px, m_nViewportHeight-py, 1, 1, viewport); //就多这一句?
gluPerspective(m_dProjectionAngle
,m_dAspect
,m_dProjectionNear
,m_dProjectionFar
);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
gluLookAt(POSITION->X(),POSITION->Y(),POSITION->Z()
,FOCUS->X(), FOCUS->Y(), FOCUS->Z()
,UP->X(), UP->Y(), UP->Z());
}
void GCPerspectiveCamera::setProjectionAndView()
{
//投影设置
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
::glViewport(0, 0, m_nViewportWidth, m_nViewportHeight);
gluPerspective(m_dProjectionAngle
,m_dAspect
,m_dProjectionNear
,m_dProjectionFar
);
glMatrixMode(GL_MODELVIEW);
//视点和模型空间设置
glLoadIdentity();
gluLookAt(POSITION->X(),POSITION->Y(),POSITION->Z()
,FOCUS->X(), FOCUS->Y(), FOCUS->Z()
,UP->X(), UP->Y(), UP->Z());
}
拾取对象显示
//20130311 23:54 Add for position pick tool
void GCGLCanvasBoxOfSpraying::renderPlaneTrajectorys4Pick()
{
if(m_pWorkingPlane==NULL)
return;
if(m_pWorkingPlane->getSelectedPoint()->getCount()<1)
return;
GCPoint3DXOLPGroup* pts = m_pWorkingPlane->getSelectedPoint();
glInitNames();
while(pts->next())
{
GCPoint3DX* t = pts->get();
GCPosition4D* p2 = t->MIRRORPOSITION;
glPushName(t->getIndex());
glPushMatrix();
glTranslated(p2->X(),p2->Y(),p2->Z());
glutSolidSphere(4,16,16);
glPopMatrix();
glPopName();
}
}
在鼠标移动函数中 调用拾取对象显示方法,此方法只显示那些你想拾取的对象
以上代码均修改自网络资源代码,大部分来源于google查询结果, 参考其处理流程即可
效率么? 几十个小球还算实时,上百个也没问题,再多就不清楚了
通过封装MouseTool 每个Tool仅需拾取一类有限数目的对象