游戏开发论坛

 找回密码
 立即注册
搜索
查看: 3378|回复: 4

关于OpenGL拾取的问题

[复制链接]

1

主题

2

帖子

8

积分

新手上路

Rank: 1

积分
8
发表于 2005-11-19 16:26:00 | 显示全部楼层 |阅读模式
小弟刚开始学OpenGL ,在编写顶点拾取程序时,发现我通过鼠标拾取的名字始终是第一个定点的名字,而且,我没有加入名字列表的点也能拾取到第一个顶点的名字,郁闷。
我把代码贴出来,请大哥们帮忙指点一下。

extern CWTPSApp theApp;
int GraphType = 0;
static int gs_iCurName = 1; //当前的名字

/************************************************************************/
void DrawSence(GLenum mode)
{
       
        COpenGL *pGL = theApp.m_pOpenGL;
        CGLVertex origin;
        origin.x = 0.0f;
        origin.y = 0.0f;
        origin.z = 0.0f;
//        pGL->DrawAxis(origin);
//        glScalef(pGL->m_fScaleX,pGL->m_fScaleY,pGL->m_fScaleZ);
        int Count = pGL->GetDSCount();
       
        if(mode == GL_SELECT)//是否为选择模式
        {
                glInitNames();
                glPushName(0);
                gs_iCurName = 1;
        }
       
        for(int i=0;i<Count ;i++)
        {               
               
                if(mode == GL_SELECT)
                {
                        DrawSelectableVertex(pGL->m_pDS);
                }
                DrawLineStrip(pGL->m_pDS);
        }

}


/*************************************************************************/
// 功能说明://画可通过鼠标选择的顶点
// 参数说明:
// 作    者: ZRB
// 修改纪录: 2005-11-17 create;
/************************************************************************/
void DrawSelectableVertex(CGLDataSet &DS)
{

        COpenGL *pGL = theApp.m_pOpenGL;
        int Count = DS.GetVertexCount();
        float *pfVertex = NULL;       
        TVertex *pVertex = NULL;
        float x,y,z;
        for(int i=0;i<Count;i++)
        {   
                DS.m_Vertexs.NameID = gs_iCurName;
                glPushMatrix();
                glLoadName(gs_iCurName++);
                glColor4fv(DS.m_pfColor);
                glPointSize(5);
                glBegin(GL_POINTS);
                        pfVertex = DS.m_Vertexs.Coord;
                        x = pfVertex[0];
                        y = pfVertex[1];
                        z = pfVertex[2];
                        glVertex3f(x,y,z);
                        //glVertex3fv(pfVertex);
                glEnd();
                glPopMatrix();
        }
       
       
}

///////////////////////////////////////////////////////////
// Process the mouse click
void MouseCallback(int button, int state, int x, int y)
{
        if(button == GLUT_LEFT_BUTTON && state == GLUT_DOWN)
                ProcessSelection(x, y);
}


#define  BUFFER_LENGTH 64        //1024               
void  ProcessSelection(int xPos,int yPos)
{
        GLfloat fAspect;
        COpenGL *pGL = theApp.m_pOpenGL;
        // 选择缓冲区的空间
        GLuint selectBuff[BUFFER_LENGTH];
       
        // 点击计数器和视口存储
        GLint hits, viewport[4];
       
        // Setup selection buffer
        glSelectBuffer(BUFFER_LENGTH, selectBuff);
       
        // Get the viewport
        glGetIntegerv(GL_VIEWPORT, viewport);
       
        // Switch to projection and save the matrix
        glMatrixMode(GL_PROJECTION);
        glPushMatrix();
       
        // Change render mode
        hits = glRenderMode(GL_SELECT);
       
        // 围绕鼠标点建立新的单位立方体裁减区,
        //并在水平和垂直方向扩展2个像素
        glLoadIdentity();
        gluPickMatrix(xPos, viewport[3] - yPos, 2,2, viewport);
        pGL->reProject(viewport[3],viewport[4]);//相当于glOrtho(-5,5,-5,5,-1,1);
        // Draw the scene
        DrawSence(GL_SELECT);

        // Restore the projection matrix
        glMatrixMode(GL_PROJECTION);
        glPopMatrix();
        // 恢复到模型视图,以便进行正常的渲染
        glMatrixMode(GL_MODELVIEW);       
       
        //  收集点击纪录
        hits = glRenderMode(GL_RENDER);
        ProcessHits(hits,selectBuff);
       


}

//////////////////////////////////////////////////////////////////////////////

//处理点击事件
void ProcessHits(GLint hits,GLuint buffer[])
{
        COpenGL *pGL = theApp.m_pOpenGL;
        TVertex *pVertex = NULL;
        int Count = 0 ,Name = -1;
        Count = buffer[0];
        if(Count > 1)
                AfxMessageBox("有多个测压点被选中,无法进行修改压力值");
        else
        {
                Name = buffer[3];
                //pVertex = pGL->GetVertex(Name);
                CString temp ;
                temp.Format("Name : %d",Name);
                //if(pVertex)
                        AfxMessageBox(temp);
                }
}

sf_20051119162621.rar

1.58 KB, 下载次数:

6

主题

37

帖子

37

积分

注册会员

Rank: 2

积分
37
发表于 2005-11-21 17:37:00 | 显示全部楼层

Re:关于OpenGL拾取的问题

好像是因为用了LoadName换成PushName试试

1

主题

2

帖子

8

积分

新手上路

Rank: 1

积分
8
 楼主| 发表于 2005-11-25 11:35:00 | 显示全部楼层

Re:关于OpenGL拾取的问题

我试过还是不可以。再问一句 loadName 与 pushname的区别是什么? 谢谢。

6

主题

37

帖子

37

积分

注册会员

Rank: 2

积分
37
发表于 2005-11-25 11:40:00 | 显示全部楼层

Re:关于OpenGL拾取的问题

loadName是替换掉当前栈顶数据而pushName是将数据压入堆栈

6

主题

37

帖子

37

积分

注册会员

Rank: 2

积分
37
发表于 2005-11-25 11:44:00 | 显示全部楼层

Re:关于OpenGL拾取的问题

我也在做选择与拾取的例子,看了好多例子,可是自己的那个始终选择不正确,也挺郁闷的,不知是为什么额?呵呵,慢慢来吧,俺也是菜鸟一个,嘻嘻!
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

作品发布|文章投稿|广告合作|关于本站|游戏开发论坛 ( 闽ICP备17032699号-3 )

GMT+8, 2026-1-22 18:15

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表