OpenGL焦点拾取问题

liuhailong520 2013-06-20 10:04:24
大家好,这是一个单独的模型(下图所示),我把它加载在程序中后,想做焦点选择,比如说,我点击红色部分,就会弹出个MessageBox说是红色,其它颜色也是一样,我也知道用OpenGL的拾取功能,但这是完整的一个模型,所以就不知道该怎么做了,请各位大侠赐教啊???
...全文
229 18 打赏 收藏 转发到动态 举报
写回复
用AI写文章
18 条回复
切换为时间正序
请发表友善的回复…
发表回复
liuhailong520 2013-06-28
  • 打赏
  • 举报
回复
哦,呵呵,是么,估计是,我也做了判断,但还是没有效果,那再研究研究吧!
victor_woo 2013-06-27
  • 打赏
  • 举报
回复
引用 14 楼 liuhailong520 的回复:
哥,你给我的例子依旧是OpenGL自己的拾取方式,不是射线拾取,不过还是谢谢你啦
http://blog.csdn.net/hb_zha/article/details/6761848 我看了一下,这个方法不可能比OpenGL的{glPushName()+glSelectBuffer(512, selectBuff);glRenderMode(GL_SELECT);} 方法效率更高 上面那个blog中射线和三角形求交竟然用方程组求解,效率已经很低了
liuhailong520 2013-06-27
  • 打赏
  • 举报
回复
哥,你给我的例子依旧是OpenGL自己的拾取方式,不是射线拾取,不过还是谢谢你啦
victor_woo 2013-06-27
  • 打赏
  • 举报
回复
我做的面选取程序也发现了一样的问题


鼠标在A区域移动时选中的总是面1,在B区域才能选到面2

可能和待选对象显示顺序也有关系。
liuhailong520 2013-06-27
  • 打赏
  • 举报
回复
哦,这样啊,呵呵!我用OpenGL自己的拾取也遇到了个问题,就是在拾取的时候,拾取的总是后一个模型,比如说,我简单的画两个正方形,一大一小,小的在大的上面,拾取的时候总是后面的那个在先,我也做了判断,想选择最近的,但总是有问题,也请你看看问题所在啊:
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;
	}
}
victor_woo 2013-06-26
  • 打赏
  • 举报
回复
引用 11 楼 liuhailong520 的回复:
哥,你好,请问你有OpenGL射线拣选的例子吗?我现在想用射线拾取,因为OpenGL自带的这种拾取模型效率太低了,而且还不好用。如果有的话请给我参考参考吧,谢谢啦
http://content.gpwiki.org/index.php/OpenGL:Tutorials:Picking
victor_woo 2013-06-26
  • 打赏
  • 举报
回复
引用 11 楼 liuhailong520 的回复:
哥,你好,请问你有OpenGL射线拣选的例子吗?我现在想用射线拾取,因为OpenGL自带的这种拾取模型效率太低了,而且还不好用。如果有的话请给我参考参考吧,谢谢啦
不知道什么是射线pick 我现在用的方法,效率挺高的,代码如下 鼠标移动处理方法

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仅需拾取一类有限数目的对象
liuhailong520 2013-06-26
  • 打赏
  • 举报
回复
哥,你好,请问你有OpenGL射线拣选的例子吗?我现在想用射线拾取,因为OpenGL自带的这种拾取模型效率太低了,而且还不好用。如果有的话请给我参考参考吧,谢谢啦
victor_woo 2013-06-21
  • 打赏
  • 举报
回复
如果只是特例,模型整体为一个方盒子,可获取其外包容盒,获得相关尺寸,定义4个非精确BOX和4个颜色区块重合 或者看看3DS导入类构造的对象有无其它可用信息 你不是要拾取后判别颜色么?
liuhailong520 2013-06-21
  • 打赏
  • 举报
回复
不清楚啊,我是直接用一个加载3DS的类加载模型的!请问能不能通过对不同区域颜色的判断来做拾取呢?
victor_woo 2013-06-21
  • 打赏
  • 举报
回复
引用 5 楼 liuhailong520 的回复:
我是直接用一个加载3DS的类加载模型的,贴图信息是在加载模型时就处理了。你说的为每个颜色块做一个对应ID的box,在一个模型上该怎么做呢?我还是不懂啊?如果能够为每个颜色块做一个对应ID的box,估计就好办多了,请再指教指教啊!
知不知道该模型的尺寸结构信息?
liuhailong520 2013-06-21
  • 打赏
  • 举报
回复
我是直接用一个加载3DS的类加载模型的,贴图信息是在加载模型时就处理了。你说的为每个颜色块做一个对应ID的box,在一个模型上该怎么做呢?我还是不懂啊?如果能够为每个颜色块做一个对应ID的box,估计就好办多了,请再指教指教啊!
victor_woo 2013-06-21
  • 打赏
  • 举报
回复
GL 的Pick 是对各个对象命名(设置整数值),未见直接选颜色
liuhailong520 2013-06-21
  • 打赏
  • 举报
回复
恩,是的,因为模型上颜色区分很明显吗,所以我就想能不能用颜色拾取的方法!我自己先跟进程序里看看模型的各个参数吧,看能不能想想办法!非常感谢你的解答啊,不懂的我再问你!
victor_woo 2013-06-20
  • 打赏
  • 举报
回复
你的模型的真实感还可以,我现在做的重点在计算,看就没法看
victor_woo 2013-06-20
  • 打赏
  • 举报
回复
拾取我就很熟了,建议四个颜色部分加额外的隐藏形体 ,仅在pick时render 我的问题: 完整的一个模型 怎么会有多块不同颜色组成? 贴图? 你的完整的一个模型的定义? 一个3ds文件,一个stl文件? 还是多个文件组合而成?
victor_woo 2013-06-20
  • 打赏
  • 举报
回复
引用 3 楼 liuhailong520 的回复:
呵呵,是吗,那我得好好跟你请教了,哥!这是一个独立完整的模型,也就是一个模型,是3ds格式的,只是我在这几个不同区域贴了不同颜色的图了而已!请问,你说的“四个颜色部分加额外的隐藏形体”是什么意思呢?我在网上看了很多资料,基本上都是把每个模型分配个ID号,然后再做拾取的,但我是要在一个模型上做不同区域的拾取,所以就不咋懂了。哥,我能加你QQ吗,这样也方便跟你请教啊,呵呵!我QQ是:544278025
“我在这几个不同区域” 不同颜色的图 贴图是不是要模型上的点位置信息? 看你的模型应该是每个颜色一个区域(模型上的某个部分);把每个颜色块做一个对应的BOX,但这个BOX仅在Pick Render时才显示(实际还是不可见);给BOX设置ID即可,图中模型本身不参与Pick 纹理贴图一直没弄,如果你贴图的位置参数可用,那可按以上方法解决 看你前面的进展,Pick应该没问题了 我现在把CSDN当工间休息的,还是保持泡论坛的感觉吧,CSDN也可发信的,欢迎探讨OpenGL应用问题
liuhailong520 2013-06-20
  • 打赏
  • 举报
回复
呵呵,是吗,那我得好好跟你请教了,哥!这是一个独立完整的模型,也就是一个模型,是3ds格式的,只是我在这几个不同区域贴了不同颜色的图了而已!请问,你说的“四个颜色部分加额外的隐藏形体”是什么意思呢?我在网上看了很多资料,基本上都是把每个模型分配个ID号,然后再做拾取的,但我是要在一个模型上做不同区域的拾取,所以就不咋懂了。哥,我能加你QQ吗,这样也方便跟你请教啊,呵呵!我QQ是:544278025

19,469

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 图形处理/算法
社区管理员
  • 图形处理/算法社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧