OpenGL拾取遇到点麻烦 (找错误)

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了OpenGL拾取遇到点麻烦 (找错误)相关的知识,希望对你有一定的参考价值。

我做一个鼠标拾取的程序,但总是拾取错误。
问题简单描述下,我用的Win32做的一个图形程序,我的绘制图形的函数代码如下
void OpenGL::Draw(GLfloat position_x,GLfloat position_y,GLfloat position_z,GLfloat angle,GLfloat angle_xz,GLfloat distance,GLfloat jump)


//这个结构是主显示渲染过程


glClearColor(0.5f,0.5f,0.5f,1.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

//glLoadIdentity();
glMatrixMode(GL_MODELVIEW);
glPushMatrix();
glInitNames();
glPushName(0);

glRotatef(angle_xz,1.0f,0.0f,0.0f);
glRotatef(angle,0.0f,1.0f,0.0f);

glTranslatef(0.0f,0.0f-jump,0);
glTranslatef(position_x+0.0f,position_y-1.0f,position_z);

//glPushMatrix();
//glTranslatef(5.0f,0.0f,0.0f);
//zhuzi(1.0f,1.0f,10.0f,10,10);
//glPopMatrix();

//地面绘制
glBindTexture(GL_TEXTURE_2D, texture[0]);
glBegin(GL_QUADS);
glTexCoord2f(100,100);
glVertex3f(50.0f,0.0f,50.0f);
glTexCoord2f(-100,100);
glVertex3f(-50.0f,0.0f,50.0f);
glTexCoord2f(-100,-100);
glVertex3f(-50.0f,0.0f, -50.0f);
glTexCoord2f(100,-100);
glVertex3f(50.0f,0.0f, -50.0f);
glEnd();

glPushMatrix();

glLoadName(1);
glBegin(GL_TRIANGLES);
glVertex3f(0.0f,0.0f,0.0f);
glVertex3f(1.0f,1.0f,0.0f);
glVertex3f(1.0f,0.0f,0.0f);
glEnd();
glPopMatrix();

glPopMatrix(); //恢复最初模型矩阵


SwapBuffers(hDC);


我在响应了一个鼠标左键的电击事件,事件代码如下

GLuint selectBuff[1024];

GLint hits, viewport[4];

glSelectBuffer(1024, selectBuff);

glGetIntegerv(GL_VIEWPORT, viewport);

glMatrixMode(GL_PROJECTION);
glPushMatrix();

glRenderMode(GL_SELECT);

glLoadIdentity();
gluPickMatrix(x, viewport[3] - y, 2,2, viewport);

gluPerspective(45.0f,(GLfloat)800/(GLfloat)600,0.1f,200.0f);

gl.Draw(camera.x,camera.y,camera.z,camera.angle,camera.angle_xz,camera.distance,camera.jump);

hits = glRenderMode(GL_RENDER);

if(hits == 1)

int i = hits; //这里出问题


// Restore the projection matrix
glMatrixMode(GL_PROJECTION);
glPopMatrix();

// Go back to modelview for normal rendering
glMatrixMode(GL_MODELVIEW);

我设置了断点,发现每次拾取的时候总是拾取一个命名为0的图元,我并没有命名0号图元啊,我想拾取我绘图函数中最后一个三角形,但总不成功,我还找不到问题的所在,希望达人指点下,不胜感激~~
我想知道我程序哪里出问题了,拾取的例子我有很多,但我的程序哪里出问题了我总找不到答案,希望有人能找到我程序的问题,谢谢了

参考技术A 这是一个关于拾取的 程序
我想要鼠标移动到 每个方块时方块改变颜色 移开时颜色在回复原来的样子
可是这个 程序只是在移动到方块上时改变颜色 而移动开时没有任何的变化
想了 很久不知道该如何解决这个问题
希望各位路过的哥哥 可以帮我看看 给我个解决的方法 谢谢

#include <stdio.h>
#include <stdlib.h>
#include <GL/glut.h>

int board[3][3];

void init(void)

int i,j;
for(i=0;i<3;i++)
for(j=0;j<3;j++)
board[i][j] = 0;
glClearColor(0.0, 0.0, 0.0, 0.0);


void drawSquares(GLenum mode)

GLuint i,j;
for (i=0;i<3;i++)
if(mode == GL_SELECT)
glLoadName(i);

for(j=0;j<3;j++)
if(mode == GL_SELECT)
glPushName(j);
glColor3f((GLfloat)i/3.0, (GLfloat)j/3.0,
(GLfloat)board[i][j]/3.0);
glRecti(i,j,i+1,j+1);
if(mode == GL_SELECT)
glPopName();





void processHits(GLint hits,GLuint buffer[])

GLint i,j;
GLuint ii = 0,jj = 0,names,*ptr;

printf("hits = %d\n",hits);
ptr = (GLuint *) buffer;

for(i=0;i < hits;i++)
names = *ptr;
printf(" number of names for this hit = %d\n", names);
ptr++;
ptr++;
ptr++;

printf(" names are ");
for (j =0;j<names;j++)
printf("%d ", *ptr);
if (j==0)
ii = *ptr;
else if (j == 1)
jj = *ptr;
ptr++;


printf("\n");

board[ii][jj] = 1;


#define BUFSIZE 512

void pickSquares(int x,int y)

GLuint selectBuf[BUFSIZE];
GLuint hits;
GLint viewport[4];

//if(hits >= 10)
// return;

glGetIntegerv(GL_VIEWPORT, viewport);
glSelectBuffer(BUFSIZE,selectBuf);
(void) glRenderMode(GL_SELECT);

glInitNames();
glPushName(0);

glMatrixMode(GL_PROJECTION);
glPushMatrix();
glLoadIdentity();

gluPickMatrix((GLdouble) x,(GLdouble)(viewport[3]-y),
5.0,5.0, viewport);
gluOrtho2D(0.0,3.0,0.0,3.0);
drawSquares(GL_SELECT);

glMatrixMode(GL_PROJECTION);
glPopMatrix();
glFlush();

hits = glRenderMode(GL_RENDER);
processHits(hits,selectBuf);
glutPostRedisplay();


void display(void)

glClear(GL_COLOR_BUFFER_BIT);
drawSquares(GL_RENDER);
glFlush();



void reshape(int w,int h)

glViewport(0,0,w,h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluOrtho2D(0.0,3.0,0.0,3.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();



int main(int argc,char** argv)

glutInit(&argc,argv);
glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);
glutInitWindowSize(200,200);
glutInitWindowPosition(100,100);
glutCreateWindow(argv[0]);
init();
glutPassiveMotionFunc(pickSquares);
glutReshapeFunc(reshape);
glutDisplayFunc(display);
glutMainLoop();
return 0;


作者:eastcowboy 发表时间:2008-9-22 22:10:00

第1楼

/*

OpenGL演示程序

使用到的技术
1. 多窗口显示
2. OpenGL选择功能
3. 根据二维的窗口坐标计算出三维坐标

操作步骤
1. 程序运行后可以看到左边的“工具栏”和右边的“主窗口”
2. 在工具栏中用鼠标点击任意物体,即可选择该物体。
3. 在主窗口中移动鼠标,如果有物体被选择,则将该物体的“预览”绘制到鼠标处
4. 在主窗口中按下鼠标,如果有物体被选择,则在鼠标处添加一个与选择物体相同的物体
5. 最多可以添加MAX_OBJECT个物体

编程语言:C语言
调试环境:软件 -- Windows XP SP2 + Visual Studio 2005 SP1英文 + GLUT工具包3.7版
硬件 -- 奔腾4 3.0G + DDR 2G + IBM945G集成显卡

*/

//============================================================================
// 所需要的头文件
//============================================================================
#include <gl/glut.h>
#include <stdio.h>

//============================================================================
// 常量定义
//============================================================================

// 最大可以添加的物体数
#define MAX_OBJECT 10

//============================================================================
// 类型定义
//============================================================================

// “物体”数据,保存了物体的类型和位置
typedef struct _tag_Object
int type; // 1 - 茶壶, 2 - 球, 3 - 圆锥
GLdouble pos_x;
GLdouble pos_y;
GLdouble pos_z;
Object;

//============================================================================
// 全局变量
//============================================================================

// 当前已经添加的物体(数组)
Object object_list[MAX_OBJECT];

// 当前已经添加的物体数量
int object_count = 0;

// 主窗口中鼠标的位置(x, y)
int mouseX_AtMain = 0;
int mouseY_AtMain = 0;

// 当前选择的物体类型(0 - 未选择, 1 - 茶壶, 2 - 球, 3 - 圆锥)
int select_object_type = 0;

作者:eastcowboy 发表时间:2008-9-22 22:11:00

第2楼

//============================================================================
// 左边“菜单栏”所需要的函数
//============================================================================

// 画出三个可以选择的物体
// 注意本函数有两个地方会用到。一是正常的绘制,二是用于OpenGL选择模式。
// 因此会用glLoadName这样的函数
void __left_display()
static const GLfloat color_selected[] = 0.75f, 0.75f, 0.95f;
static const GLfloat color_unselected[] = 0.4f, 0.4f, 0.4f;

// 画一个茶壶
glLoadName(1);
glColor3fv( (select_object_type==1) ? color_selected : color_unselected );
glPushMatrix();
glTranslatef(75.0f, 470.0f*3/4, 0);
glutSolidTeapot(30);
glPopMatrix();

// 画一个球
glLoadName(2);
glColor3fv( (select_object_type==2) ? color_selected : color_unselected );
glPushMatrix();
glTranslatef(75.0f, 470.0f/2, 0);
glutSolidSphere(30.0, 20, 20);
glPopMatrix();

// 画一个圆锥
glLoadName(3);
glColor3fv( (select_object_type==3) ? color_selected : color_unselected );
glPushMatrix();
glTranslatef(75.0f, 470.0f/4, 0);
glRotatef(-90.0f, 1.0f, 0.0f, 0.0f);
glutSolidCone(30.0, 50.0, 30, 1);
glPopMatrix();


// 菜单栏需要绘制时调用此函数
void left_display(void)
glClear(GL_COLOR_BUFFER_BIT);
__left_display();
glutSwapBuffers();
glutReportErrors();


// 在鼠标点击菜单栏时调用此函数
// 函数中会使用OpenGL的选择功能来判断哪个物体被选中
void left_mouse(int button, int state, int x, int y)
GLdouble saved_projection_matrix[16];
GLint viewport[4];
GLuint select_buffer[512];
GLint buffer_count;

if( state != GLUT_DOWN )
return;

glGetDoublev(GL_PROJECTION_MATRIX, saved_projection_matrix);
glGetIntegerv(GL_VIEWPORT, viewport);
y = viewport[3] - y;

glMatrixMode(GL_PROJECTION);
glPushMatrix();
glLoadIdentity();
gluPickMatrix(x, y, 1, 1, viewport);
glMultMatrixd(saved_projection_matrix);
glMatrixMode(GL_MODELVIEW);

glSelectBuffer(
sizeof(select_buffer)/sizeof(select_buffer[0]), select_buffer);
glRenderMode(GL_SELECT);
glInitNames();
glPushName(0);
__left_display();
buffer_count = glRenderMode(GL_RENDER);
if( buffer_count < 0 )
printf("OpenGL 选择缓冲区溢出\n");
else if( buffer_count == 0 )
select_object_type = 0;
printf("未选择任何物体\n");
else
int i;
GLuint* ptr = select_buffer;
for(i=0; i<buffer_count; ++i)
int name = select_buffer[i*4+3];
switch(name)
case 1:
printf("选择了茶壶\n");
select_object_type = 1;
break;
case 2:
printf("选择了球\n");
select_object_type = 2;
break;
case 3:
printf("选择了圆锥\n");
select_object_type = 3;
break;




glMatrixMode(GL_PROJECTION);
glPopMatrix();
glMatrixMode(GL_MODELVIEW);

glutPostRedisplay();


作者:eastcowboy 发表时间:2008-9-22 22:11:00

第3楼

//============================================================================
// 左边“菜单栏”所需要的函数
//============================================================================

// 根据二维的窗口坐标计算出三维坐标,
// 计算结果放到pObj->pos_x, pObj->pos_y, pObj->pos_z中
// 注意:要正确使用本函数,必须开启深度测试。
// 即必须分配深度缓冲区,并且使用glEnable(GL_DEPTH_TEST)
void calc_xyz(int winx, int winy, Object* pObj)
GLdouble modelview_matrix[16];
GLdouble projection_matrix[16];
GLint viewport[4];
GLfloat winz;

glGetDoublev(GL_MODELVIEW_MATRIX, modelview_matrix);
glGetDoublev(GL_PROJECTION_MATRIX, projection_matrix);
glGetIntegerv(GL_VIEWPORT, viewport);

glReadPixels(winx, winy, 1, 1, GL_DEPTH_COMPONENT, GL_FLOAT, &winz);
gluUnProject(winx, winy, winz,
modelview_matrix, projection_matrix, viewport,
&(pObj->pos_x), &(pObj->pos_y), &(pObj->pos_z));


// 根据物体类型的不同,绘制出不同的物体
// 1 - 茶壶, 2 - 球, 3 - 圆锥
void draw_object(int type)
switch( type )
case 1:
glColor3f(0.2f, 0.7f, 0.5f);
glTranslatef(0.0f, 0.3f, 0.0f);
glutSolidTeapot(0.3);
break;
case 2:
glColor3f(0.3f, 0.6f, 0.8f);
glTranslatef(0.0f, 0.3f, 0.0f);
glutSolidSphere(0.3, 20, 20);
break;
case 3:
glColor3f(0.6f, 0.6f, 0.3f);
glRotatef(-90.0f, 1.0f, 0.0f, 0.0f);
glutSolidCone(0.3, 0.4, 30, 1);
break;



// 鼠标在主窗口中移动时,记录鼠标的位置
// 如果选择了物体类型,则通过glutPostRedisplay重新绘制主窗口,
// 绘制时会把所选的物体绘制在鼠标位置处
void main_passiveMotion(int x, int y)
mouseX_AtMain = x;
mouseY_AtMain = 470 - y;
if( select_object_type != 0 )
glutPostRedisplay();


// 鼠标点击主窗口,尝试添加物体
// 若添加成功则调用glutPostRedisplay重新绘制,以便让添加的物体被绘制出来
void main_mouse(int button, int state, int x, int y)
if( state != GLUT_DOWN )
return;
if( !select_object_type )
return;
if( object_count >= MAX_OBJECT )
printf("物体数量达到最大,无法再添加\n");
return;


object_list[object_count].type = select_object_type;
calc_xyz(x, 470 - y, &object_list[object_count]);
printf("在(%f, %f, %f)处增加物体。\n",
object_list[object_count].pos_x,
object_list[object_count].pos_y,
object_list[object_count].pos_z);
++object_count;

glutPostRedisplay();


// 主窗口需要绘制时调用本函数
void main_display(void)
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

// disable lighting
glDisable(GL_LIGHTING);

// ground
glColor3f(0.4f, 0.2f, 0.2f);
glBegin(GL_QUADS);
glVertex3f(-2.0f, 0.0f, -2.0f);
glVertex3f(-2.0f, 0.0f, 2.0f);
glVertex3f( 2.0f, 0.0f, 2.0f);
glVertex3f( 2.0f, 0.0f, -2.0f);
glEnd();

// mouse object
if( select_object_type != 0 )
Object dummy;
calc_xyz(mouseX_AtMain, mouseY_AtMain, &dummy);
glPushMatrix();
glTranslated(dummy.pos_x, dummy.pos_y, dummy.pos_z);
draw_object(select_object_type);
glPopMatrix();


// enable lighting
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
glEnable(GL_COLOR_MATERIAL);
glColorMaterial(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE);

// objects

int i;
glColor3f(1.0f, 1.0f, 0);
for(i=0; i<object_count; ++i)
glPushMatrix();
glTranslated(object_list[i].pos_x,
object_list[i].pos_y,
object_list[i].pos_z);
draw_object(object_list[i].type);
glPopMatrix();



glutSwapBuffers();
glutReportErrors();


// 最大的窗口在需要绘制时调用本函数
void display(void)
glClearColor(0.5f, 0.5f, 0.5f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);

glutSwapBuffers();


作者:eastcowboy 发表时间:2008-9-22 22:12:00

第4楼

// main函数
int main(int argc, char* argv[])
int window, left_window, main_window;

glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA | GLUT_DEPTH);
glutInitWindowPosition(100, 100);
glutInitWindowSize(640, 480);

// 父窗口
window = glutCreateWindow("OpenGL");
glutDisplayFunc(&display);

// 左边的子窗口
left_window = glutCreateSubWindow(window, 5, 5, 150, 470);

glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(0.0, 150.0, 0.0, 470.0, 100.0, -100.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glTranslatef(0.375f, 0.375f, 0.0f);

glutDisplayFunc(&left_display);
glutMouseFunc(&left_mouse);

// 主体的子窗口
main_window = glutCreateSubWindow(window, 165, 5, 470, 470);

glEnable(GL_DEPTH_TEST);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(60.0, 1.0, 0.5, 10.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
gluLookAt(4.0, 3.0, 3.0,
0.0, 0.0, 0.0,
0.0, 1.0, 0.0);

glutDisplayFunc(&main_display);
glutMouseFunc(&main_mouse);
glutPassiveMotionFunc(&main_passiveMotion);

glutMainLoop();
参考技术B 你解决了吗?我也遇到同样的问题?能不能告诉我怎么回事?

OpenGL ES on android 微调光线拾取代码

【中文标题】OpenGL ES on android 微调光线拾取代码【英文标题】:OpenGl ES on android fine tuning of ray picking code 【发布时间】:2012-03-07 06:07:28 【问题描述】:

我已经使用 min3d 和一些我在网上找到的代码实现了光线拾取,但是当我实现它时,我注意到它有时有点偏离,这意味着当我点击一个框时,有时会选择错误的那个。有时被选中的那个甚至不在屏幕上。这需要相当多的代码才能实现,但我调用的主要两种方法如下:

private void rayPicking(float x, float y)

    //intersection with near plane
    float[] near = new float[4];
    GLU.gluUnProject(x, scene.getViewport()[3] - y, 0f, scene.getGrabber().mModelView, 0, scene.getGrabber().mProjection, 0, scene.getViewport(), 0, near, 0);
    if (near[3] != 0)
    
        near[0] = near[0] / near[3];
        near[1] = near[1] / near[3];
        near[2] = near[2] / near[3];
    
    Number3d near3 = new Number3d(near[0], near[1], near[2]);

    //and far plane
    float[] far = new float[4];
    GLU.gluUnProject(x, scene.getViewport()[3] - y, 1f, scene.getGrabber().mModelView, 0, scene.getGrabber().mProjection, 0, scene.getViewport(), 0, far, 0);
    if (far[3] != 0)
    
        far[0] = far[0] / far[3];
        far[1] = far[1] / far[3];
        far[2] = far[2] / far[3];
    
    Number3d far3 = new Number3d(far[0], far[1], far[2]);

    Box firstPicked = null;
    Box currentModel = null;
    Number3d currentCoords = null;
    Number3d firstPickedCoords = new Number3d();

if (!sceneBoxes.isEmpty())

    //here we check each model if it was tapped and if several models were tapped, we take only that which is closer to the near clipping plane
    Iterator<Box> itr = sceneBoxes.iterator();
    while (itr.hasNext())
    
        currentModel = itr.next();
        currentCoords = new Number3d(currentModel.position().x, currentModel.position().y, currentModel.position().z);
        if (picked (far3, near3, currentCoords, 1.2f)) 
            if (firstPicked==null) 
                
                    firstPicked = currentModel;
                    firstPickedCoords.setAllFrom(currentCoords); 
                
            else if (Number3d.add(currentCoords, near3).length() < Number3d.add(firstPickedCoords, near3).length()) 
                
                    firstPicked = currentModel;
                    firstPickedCoords.setAllFrom(currentCoords);
                
    
   

    if (firstPicked != null) // if model picked
     
        String temp = firstPicked.getTitle();
        String temp2 = firstPicked.getLink();
        Log.w("3d touch working "+temp, "3d touch working "+temp);
        Intent intent = new Intent(CurAct.this, WebViewer.class);
        intent.putExtra("clkURL", temp2);
        intent.putExtra("clkUID", curr_uid);
        intent.putExtra("rid", curr_rid);
        startActivity(intent);

        firstPicked = null;
        temp = null;
        temp2 = null;

    


private boolean picked(Number3d a, Number3d b, Number3d q, float r)

    float ab = (float) Math.sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y)+(a.z-b.z)*(a.z-b.z));
    float aq = (float) Math.sqrt((a.x-q.x)*(a.x-q.x)+(a.y-q.y)*(a.y-q.y)+(a.z-q.z)*(a.z-q.z));
    float bq = (float) Math.sqrt((b.x-q.x)*(b.x-q.x)+(b.y-q.y)*(b.y-q.y)+(b.z-q.z)*(b.z-q.z));

    float p = (ab + aq + bq) / 2;

    float hh = (float) Math.sqrt(p * (p - ab) * (p - aq) * (p - bq));
    float h;
    if (ab!=0) h = 2 * hh / ab; else h = 2*hh;

    if (aq<h) h = aq;
    if (bq<h) h = bq;

    if (h<r)return true; else return false;

现在我也尝试实现截锥体剔除,但这样做会减慢速度,因为我没有做太多优化它并且它没有在本机运行。但是,如果有人可以看,也许能给我一些关于如何使它更准确的指示,那就太棒了。这里我称之为拣货方法。

 _glSurfaceView.setOnTouchListener( 
        new View.OnTouchListener() 

            @Override
            public boolean onTouch(View arg0, MotionEvent e) 

                switch (e.getAction() & MotionEvent.ACTION_MASK) 
                
                    case MotionEvent.ACTION_DOWN:
                        startX = e.getX();
                        startY = e.getY();
                        trace = 0.0f;
                        time = System.currentTimeMillis();
                        touchMode = DRAG;
                    break;

                    case MotionEvent.ACTION_UP:
                        // we use ray picking only when the tap wasn't longer than 0.5 sec and if we almost didn't move our finger
                        //Log.w("this is touch y"+e.getY()+" viewport is"+scene.getViewport()[3], "this is touch x"+e.getX());
                        if ((System.currentTimeMillis()-time < 500) && (trace<scene.getViewport()[3]*0.075)) rayPicking(e.getX(), e.getY());
                        time = 0;

                    case MotionEvent.ACTION_POINTER_UP:
                        touchMode = NONE;
                    break;
                
                return true;

            
            
        );

【问题讨论】:

【参考方案1】:

您遇到的错误听起来像是您在碰撞检测中犯了一个错误,我在点积的函数中遇到了一个错误,并导致了一些非常奇怪的结果。你能发布更多你的碰撞算法吗?

我在这里实现了光线拾取:http://android-raypick.blogspot.ca/ 我没有在此处粘贴代码,因为它有很多,请随意将您的代码与此代码进行比较,此代码已经过测试并且可以工作。

【讨论】:

我现在不记得是怎么回事了,但我能够纠正我在光线拾取准确性方面遇到的问题。根据我的记忆,我从我应该添加的某个地方减去,反之亦然,它把所有东西都扔掉了。有机会我会浏览一下我的代码并回复你。 我确认来自android-raypick.blogspot.ca 的代码正在运行,我正在我的应用程序中使用它。那里的所有计算都是正确的,但是内存分配很大。您可能需要重新设计代码,以免分配千字节的内存来检查光线与 900 个三角形的交点。 @keaukraine :我做不到,在这里发了一个问题***.com/questions/14185279/…,希望你能看看我是否走在正确的轨道上。 @Araw 如果您得到多个碰撞检测,您应该选择最接近相机的一个 - 这将是正确的一个。该代码检查与光线的交点,以便它可以选择被其他三角形遮挡的三角形。最近的一个没有被其他三角形遮挡。

以上是关于OpenGL拾取遇到点麻烦 (找错误)的主要内容,如果未能解决你的问题,请参考以下文章

OpenGL拾取 - 光线/球体相交错误

深入理解OpenGL拾取模式(OpenGL Picking)

openGL 光线拾取

OpenGL画好的线条,怎么用鼠标拾取

openGL error 跟踪

求教OPENGL达人 如何做到图像的拾取并可以随鼠标拖动 鄙人QQ664538975 不胜感激