OpenGL 之 Selection Mode

So far the OpenGL naming scheme has been presented. This section will show you how to enter the selection mode for picking purposes. The first step is to tell OpenGL where to store the hit records. This is accomplished with the following function:


void glSelectBuffer(GLsizei size, GLuint *buffer);

Parameters:
hit records.


You are required to call this function before entering the selection mode . Next you enter the selection mode with a call to


void glRenderMode(GLenum mode);

Parameters:


No w comes the tricky part. The application must redefine the viewing volume so that it renders only a small area around the place where the mouse was clicked. In order to do that it is necessary to set the matrix mode to GL_PROJECTION. Afterwards, the application should push the current matrix to save the normal rendering mode settings. Next initialise the matrix. The following snippet of code shows how to do this:

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

 

OK so now you have a clean projection matrix. All that is required now is to define the viewing volume so that rendering is done only in a small area around the cursor. This can be accomplished using the following function:


void gluPickMatrix(GLdouble x, GLdouble y, GLdouble witdth, GLdouble height, GLint viewport[4]);

Parameters:



Before you call the above function you have to get the current viewport. This can be done querying OpenGL for the state variable GL_VIEWPORT (use the function glGetIntegerv). Then you call gluPickMatrix, and finally set your projection (perspective or orthogonal) just as you did for the normal rendering mode. Finally get back to the modelview matrix mode, and initialise the Name Stack to start rendering. The following code shows the sequence of function calls to do just that using a perspective projection.

 

glGetIntegerv(GL_VIEWPORT,viewport);
gluPickMatrix(cursorX,viewport[
3 ] - cursorY,
        
5 , 5 ,viewport);
gluPerspective(
45 ,ratio, 0.1 , 1000 );
glMatrixMode(GL_MODELVIEW);
glInitNames();

 

Note the second parameter of gluPickMatrix. As mentioned before, OpenGL has a different origin for its window coordinates than the operation system. The second parameter provides for the conversion between the two systems, i.e. it transforms the origin from the upper left corner, as provided by GLUT for example, into the bottom left corner.

 

The picking region in this case is a 5x5 window. You may find that it is not appropriate for your application. Do some tests to find an appropriate value if you're finding it hard to pick the right objects.

 

The following function does all operations required to enter the selection mode and start picking, assuming that cursorX and cursorY are the operating system window coordinates for the location of the mouse click.

 

#define  BUFSIZE 512
GLuint selectBuf[BUFSIZE]


 
void  startPicking( int  cursorX,  int  cursorY


) {

    GLint viewport[
4 ];

    glSelectBuffer(BUFSIZE,selectBuf);
    glRenderMode(GL_SELECT);

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

    glGetIntegerv(GL_VIEWPORT,viewport);
    gluPickMatrix(cursorX,viewport[
3 ] - cursorY,
            
5 , 5 ,viewport);
    gluPerspective(
45 ,ratio, 0.1 , 1000 );
    glMatrixMode(GL_MODELVIEW);
    glInitNames();
}


You may copy and paste this function to your application, with the appropriate modifications regarding your projection. If you do that then just call this function when entering the rendering mode and before rendering any graphic primitives.

转载于:https://www.cnblogs.com/irvinow/archive/2009/11/18/1605637.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值