`
daojin
  • 浏览: 689960 次
  • 性别: Icon_minigender_1
  • 来自: 西安
社区版块
存档分类
最新评论

OpenGL鼠标拾取的实现:终于搞定(包括细节问题)

阅读更多
void OpenGL::pickRects(){
/*	GetCursorPos(&mouse);
	ScreenToClient(hWnd,&mouse);
	GLuint pickBuffer [32];
    GLint nPicks,vpArray[4];
	glRenderMode(GL_SELECT);
		glSelectBuffer(32,pickBuffer);
		glInitNames();
		//glPushName(-1);
		glMatrixMode(GL_PROJECTION);
		glPushMatrix();		   
			//glLoadIdentity();
			glGetIntegerv(GL_VIEWPORT,vpArray);
			gluPickMatrix(GLdouble(mouse.x),GLdouble(vpArray[3]-mouse.y),5.0,5.0,vpArray);
		//	glOrtho(0,1,0,1,0,1);
			//激活拾取区域。		  	
		//	gluOrtho2D(0,0,Width,Height);
		
		rects(GL_SELECT);
		glMatrixMode(GL_PROJECTION);
		int j;
		glGetIntegerv(GL_NAME_STACK_DEPTH,&j);
		cout<<j<<endl;
		glPopMatrix();
		glFlush();
	    nPicks=glRenderMode(GL_RENDER);
	    processPicks(nPicks,pickBuffer);
        //processPicks(nPicks,pickBuffer);
		*/
   GetCursorPos(&mouse);
   ScreenToClient(hWnd,&mouse);
   GLuint selectBuf[32];
   GLint hits;
   GLint viewport[4];
  
   glGetIntegerv(GL_VIEWPORT, viewport);

   glSelectBuffer(32, selectBuf);
   (void) glRenderMode(GL_SELECT);
   glInitNames();
   glPushName(0);
   glMatrixMode(GL_PROJECTION);
//下面这段代码可有可无,只是为了确保点击测试和实际绘图用的是同一个投影阵。
 glLoadIdentity();						// 重置当前指定的矩阵为单位矩阵
   gluPerspective							// 设置透视图
		( 53.0f,							// 透视角设置为 90 度
		  (GLfloat)Width/(GLfloat)Height,	// 窗口的宽与高比
		  0.1f,								// 视野透视深度:近点1.0f
		  3000.0f							// 视野透视深度:始点0.1f远点1000.0f
		);
   glPushMatrix();
下面的代码是最关键的地方,,注意:据测试:gluPickMatrix()意思并不是仅仅绘制一个拾取窗口。同时,
它也是一个投影矩阵变换!!~~~~如果使用第二个LoadIdentity()那么:前面的拾取矩阵就会失效!!

   glLoadIdentity();
/*  create 5x5 pixel picking region near cursor location */
   gluPickMatrix((GLdouble) mouse.x, (GLdouble) (viewport[3] - mouse.y),
                 5.0, 5.0, viewport);
//这个会促使上面那个PickMatrix失效!!切记~~~~
   //glLoadIdentity();						// 重置当前指定的矩阵为单位矩阵
   gluPerspective							// 设置透视图
		( 53.0f,							// 透视角设置为 90 度
		  (GLfloat)Width/(GLfloat)Height,	// 窗口的宽与高比
		  0.1f,								// 视野透视深度:近点1.0f
		  3000.0f							// 视野透视深度:始点0.1f远点1000.0f
		);
   rects(GL_SELECT);
   glPopMatrix();
   glFlush();
   hits = glRenderMode(GL_RENDER);
   processPicks(hits, selectBuf);
   int j;
   glGetIntegerv(GL_NAME_STACK_DEPTH,&j);
   int m;
}
void OpenGL::rects(GLenum mode)
{
if (mode == GL_SELECT)
    glLoadName(30);
    glPushMatrix();
	glTranslatef(-2,-1,-15);
	glColor3f(0.6f,0.2f,0.9f);
//	glRecti(0,0,100,100);
	Font->c3dtext("离开游戏",hFont,0.25f);
	glPopMatrix();
  /* glBegin(GL_QUADS);
   glColor3f(1.0, 1.0, 0.0);
   glVertex3i(2, 0, 0);
   glVertex3i(2, 6, 0);
   glVertex3i(6, 6, 0);
   glVertex3i(6, 0, 0);
   glEnd();
   */
   if (mode == GL_SELECT)
      glLoadName(20);
   glPushMatrix();
   	  glTranslatef(-2,1,-15);
	  glColor3f(0.6f,0.2f,0.9f);
	  Font->c3dtext("开始游戏",hFont,0.25f);
   glPopMatrix();
	  /*glBegin(GL_QUADS);
   glColor3f(0.0, 1.0, 1.0);
   glVertex3i(3, 2, -1);
   glVertex3i(3, 8, -1);
   glVertex3i(8, 8, -1);
   glVertex3i(8, 2, -1);
   glEnd();
   */
   /*
   if (mode == GL_SELECT)
      glLoadName(3);
   glBegin(GL_QUADS);
   glColor3f(1.0, 0.0, 1.0);
   glVertex3i(0, 2, -2);
   glVertex3i(0, 7, -2);
   glVertex3i(5, 7, -2);
   glVertex3i(5, 2, -2);
   glEnd();
	/*
   if(mode==GL_SELECT)
	glPushName(1);
  	glPushMatrix();
//	glTranslatef(0,0,-Height);
    glColor3f(0.0,1.0,0.0);
//	glPushName(20); 
	glTranslatef(-2,-1,-15);
//	glColor3f(0.6f,0.2f,0.9f);
//	glRecti(0,0,100,100);
	Font->c3dtext("离开游戏",hFont,0.25f);
	/*glBegin(GL_QUADS);
		glTexCoord2f(0.0f, 0.0f); glVertex3f(-Width/2, -Height/2,  -0.0f);// 前
		glTexCoord2f(1.0f, 0.0f); glVertex3f( Width/2,-Height/2,  -0.0f);
		glTexCoord2f(1.0f, 1.0f); glVertex3f( Width/2,  Height/2,  -0.0f);
		glTexCoord2f(0.0f, 1.0f); glVertex3f(-Width/2,  Height/2,  -0.0f);
    glEnd();

 //   glColor3f(1.0,0.0,0.0);
//	glTranslatef(-2,1,-15);
	glColor3f(0.6f,0.2f,0.9f);
//	Font->c3dtext("开始游戏",hFont,0.25f);
	glPopMatrix();		
   if(mode==GL_SELECT)
	glPushName(2);
   	glPushMatrix();
   // glTranslatef(0,0,-Height);
//	glColor3f(0.0,1.0,0.0);
//	glPushName(20); 
	glTranslatef(-2,-1,-15);
	glColor3f(0.6f,0.2f,0.9f);
//	glRecti(0,0,100,100);
	Font->c3dtext("离开游戏",hFont,0.25f);

	glBegin(GL_QUADS);
		glTexCoord2f(0.0f, 0.0f); glVertex3f(-Width/2, -Height/2,  -0.0f);// 前
		glTexCoord2f(1.0f, 0.0f); glVertex3f( Width/2,-Height/2,  -0.0f);
		glTexCoord2f(1.0f, 1.0f); glVertex3f( Width/2,  Height/2,  -0.0f);
		glTexCoord2f(0.0f, 1.0f); glVertex3f(-Width/2,  Height/2,  -0.0f);
    glEnd();

	glPopMatrix();
	*/
}
void OpenGL::processPicks(GLint hits,GLuint buffer[]){
	rects(GL_RENDER);
	cout<<hits<<endl;
 unsigned int i, j;
   GLuint names, *ptr;
   printf("hits = %d\n", hits);
   ptr = (GLuint *) buffer;
   for (i = 0; i < hits; i++) {  
      names = *ptr;
      printf(" number of names for hit = %d\n", names); ptr++;
      printf("  z1 is %g;", (float) *ptr/0x7fffffff); ptr++;
      printf(" z2 is %g\n", (float) *ptr/0x7fffffff); ptr++;
      printf("   the name is ");
      for (j = 0; j < names; j++) {  
         printf("%d ", *ptr); ptr++;
      }
      printf("\n");
   }
}

 

分享到:
评论

相关推荐

    OPENGL鼠标拾取与选择

    OPENGL鼠标拾取与选择

    opengl+qt实现鼠标选中模型

    opengl+qt实现鼠标选中模型opengl+qt实现鼠标选中模型opengl+qt实现鼠标选中模型opengl+qt实现鼠标选中模型opengl+qt实现鼠标选中模型opengl+qt实现鼠标选中模型opengl+qt实现鼠标选中模型opengl+qt实现鼠标选中模型...

    aa.rar_OpenGL鼠标事件_opengl_opengl sphere_opengl 鼠标_site:www.pudn.c

    在这个"aa.rar"压缩包中,包含了一个名为"aa.cpp"的源代码文件,它似乎演示了如何在OpenGL环境中使用鼠标事件来操作和变换一个球体。下面我们将详细探讨OpenGL中的鼠标事件、画球体的方法以及如何结合键盘事件进行...

    Qt加OpenGL实现鼠标控制视角

    在本文中,我们将深入探讨如何使用Qt结合OpenGL来实现鼠标控制视角的功能。Qt是一个功能强大的C++库,广泛用于创建跨平台的图形用户界面。而OpenGL是一个开放标准的图形库,用于渲染2D和3D图形。将两者结合,我们...

    opengl中鼠标拾取操作

    然后,我们定义了 Selection 函数来实现拾取操作。 在 Selection 函数中,我们首先获取视口的大小,并将其存储在 viewport 变量中。然后,我们使用 glSelectBuffer 函数来告诉 OpenGL 使用我们的数组来进行选择。...

    两种OpenGL拾取 名字栈拾取 射线拾取 源码注释

    通过阅读和理解这些源码,你可以更深入地了解如何在实际的OpenGL程序中实现拾取功能。代码中的注释将为你提供关于每一步操作的解释,包括数学计算的细节以及如何优化性能。同时,对于数学基础较弱的开发者,这也将是...

    iphone下opengl射线拾取

    总结,实现iPhone上的OpenGL射线拾取,尤其是支持贴图模型的拾取,需要对OpenGL ES有深入理解,包括坐标变换、投影和视图矩阵的运用,以及几何体的交点检测算法。同时,熟悉iOS开发环境和相应的图形库将极大地方便这...

    OpenGL图形拾取

    本文将深入探讨OpenGL图形拾取的原理、实现方法以及如何在VC6.0中应用。 首先,OpenGL图形拾取的基本思想是利用深度缓冲区(Z-Buffer)和颜色缓冲区(Color Buffer)来确定鼠标点击位置对应的3D对象。当绘制场景时...

    opengl拾取操作

    在OpenGL中实现拾取操作,通常涉及到将屏幕坐标转换为世界坐标,以便确定用户点击了哪个对象。 首先,我们需要理解OpenGL的基本坐标系统。在OpenGL中,有三种主要的坐标系统:顶点坐标系统(Vertex Coordinate ...

    OpenGL拾取代码范例

    5. **单缓冲区与双缓冲区**:在实现拾取时,可能需要使用单缓冲区或双缓冲区策略。双缓冲能防止闪烁,因为它先在后台缓冲区渲染,然后一次性显示到前景缓冲区。 6. **glRenderMode() 和 glSelectBuffer()**:OpenGL...

    openGL的拾取程序

    openGL的拾取操作程序,程序关键部分都有汉字说明。

    GPU鼠标拾取ShadowEditor:基于WebGL、Three.js、Go语言和MongoDB的跨平台3D场景编辑器

    名称:ShadowEditor跨平台3D场景编辑器(含GPU鼠标拾取功能) 版本:v0.6.1 (开发中) 简介:基于WebGL、Three.js、Go语言和MongoDB的跨平台的3D场景编辑器,采用OpenGL ES 2.0(WebGL)开发。 其中已包含three.js利用gpu...

    一个简单的opengl拾取例子

    通过阅读和分析这些代码,可以更深入地理解OpenGL拾取的实现细节。 总之,OpenGL拾取技术是图形用户界面中的一个重要特性,使得用户能与3D场景进行交互。这个简单的例子提供了一个基础的实现,通过左键点击屏幕来...

    opengl 鼠标拾取和不同绘图模式FPS对比

    用opengl C++写的一个小程序,可以用鼠标拾取其中的对象并变色,还可以对比各种绘图模式下FPS的不同

    pick-opengl.zip_OPENGL 二维_opengl pick_opengl 拾取_opengl 拾取_open

    在"pick_opengl"和"拾取_open"的标签中,我们可以推测代码中包含了实现这些功能的关键函数和方法。文件列表中未提供具体文件名,但通常一个这样的项目可能会包含以下几个文件: - `main.cpp`:主程序,包含窗口创建...

    OpenGL拾取例子[太阳系 OpenGL拾取例子[太阳系

    OpenGL拾取例子[太阳系 OpenGL拾取例子[太阳系

    OpenGL 顶点数组+拾取

    在这个实验“OpenGL 顶点数组+拾取”中,我们将深入探讨两个重要的概念:顶点数组和拾取技术。 **顶点数组**是OpenGL中的一个关键特性,用于提高渲染性能。在传统的OpenGL编程中,每个顶点都需要单独发送到GPU,这...

    opengl 拾取

    在基于Qt的程序中,OpenGL拾取通常用于实现用户与3D图形的交互,例如点击屏幕上的某个点以选择对应的3D物体。下面我们将详细探讨OpenGL拾取的原理、实现方式以及如何在Qt环境中集成这一功能。 1. OpenGL拾取的基本...

    OpenGL实现鼠标绕任意轴旋转/平移/缩放

    OpenGL实现鼠标绕任意轴旋转/平移/缩放 自己封装的鼠标封装的鼠标场景漫游工具类RoamingScenceManager,跟界面没有任何关系,压缩包里面有三个工程,分别是Qt,Win32(原生OpenGL界面),MFC 三个环境,里面都用到了...

    opengl显示点云实现鼠标旋转滚轮大小缩放

    opengl显示点云实现鼠标旋转滚轮大小缩放,需要64位freeglut去我的资源中找

Global site tag (gtag.js) - Google Analytics