|
|
发表于 2005-8-7 19:40:00
|
显示全部楼层
Re: 怎样实现鼠标选择物体后就可以拖动
这是我做的国际象棋游戏的一些代码,你可以参考一下
下面是选择部分
int selectChess(int x, int y)
{
GLuint selectBuf[BUF_SIZE];
GLuint minDepth, name;
GLint hits;
int i;
if(chess->gameResult != -1)
{
return 0; // 游戏已结束
}
glSelectBuffer(BUF_SIZE, selectBuf);
glRenderMode(GL_SELECT);
glInitNames();
glPushName(0);
glMatrixMode(GL_PROJECTION);
glPushMatrix();
glLoadIdentity();
gluPickMatrix((GLdouble)x, (GLdouble)(viewport[3] - y), 1.0, 1.0, viewport);
gluPerspective(50.0, (GLfloat)viewport[2] / viewport[3], 1.0, 5000.0);
glMatrixMode(GL_MODELVIEW);
glPushMatrix();
glLoadIdentity();
camera.callList();
glGetDoublev(GL_MODELVIEW_MATRIX, modelMatrix);
chess->drawSolid();
glPopMatrix();
glMatrixMode(GL_PROJECTION);
glPopMatrix();
glFlush();
hits = glRenderMode(GL_RENDER);
if(hits)
{
minDepth = selectBuf[1];
name = selectBuf[3];
for(i = 0; i < hits; i++)
{
if(selectBuf[i * 4 + 1] < minDepth)
{
minDepth = selectBuf[i * 4 + 1];
name = selectBuf[i * 4 + 3];
}
}
return name;
}
return 0;
}
下面是实现拖动的部分代码
if(selectedChess)
{
glClear(GL_DEPTH_BUFFER_BIT);
glBegin(GL_QUADS);
// 画一个和棋盘一样大的矩形
//不用担心这个矩形会显示出来,因为使用了双缓冲,矩形只在显存中,等处理完拖动事件,才绘制场景,此时矩形已经被清除了
glVertex3f(GRID_WIDTH * 4, GRID_WIDTH * 4, deltaz);
glVertex3f(-GRID_WIDTH * 4, GRID_WIDTH * 4, deltaz);
glVertex3f(-GRID_WIDTH * 4, -GRID_WIDTH * 4, deltaz);
glVertex3f(GRID_WIDTH * 4, -GRID_WIDTH * 4, deltaz);
glEnd();
glReadPixels(x, viewport[3] - y, 1, 1, GL_DEPTH_COMPONENT, GL_FLOAT, &depth);
if(depth != 1.0 && x > viewport[0] && x < (viewport[0] + viewport[2]) && y > viewport[1] && y < (viewport[1] + viewport[3]))
{
gluUnProject(x, viewport[3] - y, (GLdouble)depth, modelMatrix, projMatrix, viewport, &objx, &objy, &objz);
objx -= deltax;
objy -= deltay;
objz -= deltaz;
selectedChess->x = (GLfloat)objx;
selectedChess->y = (GLfloat)objy;
selectedChess->z = (GLfloat)objz;
selectedChess->newList();
chess->setHighlight(moveRow, moveCol, CHESS_MOVE_NONE);
if(lastMoveState == CHESS_MOVE_LEFTCASTLE || lastMoveState == CHESS_MOVE_RIGHTCASTLE)
{
chess->setHighlight(moveRow, moveCol - 1, CHESS_MOVE_NONE);
chess->setHighlight(moveRow, moveCol + 1, CHESS_MOVE_NONE);
}
moveRow = (int)((GRID_WIDTH * 4 - objy) / GRID_WIDTH);
if(moveRow > 7) moveRow = 7;
moveCol = (int)((objx + GRID_WIDTH * 4) / GRID_WIDTH);
if(moveCol > 7) moveCol = 7;
lastMoveState = (selectedChess->*(selectedChess->checkMove))(moveRow, moveCol);
chess->setHighlight(moveRow, moveCol, lastMoveState);
chess->setHighlight(selectedChess->getRow(), selectedChess->getColumn(), CHESS_MOVE_FROM);
chess->newList();
glutPostRedisplay();
}
}
|
|