不要在鼠标处理程序中直接渲染内容,而是更新对象位置并使用glutPostRedisplay()
排队重新绘制:
#include <GL/glut.h>
float objX = 100;
float objY = 100;
float objSize = 50;
bool dragging = false;
void mouse( int button, int state, int x, int y )
{
if( GLUT_DOWN == state )
{
bool colliding =
objX - objSize <= x && x <= objX + objSize
&&
objY - objSize <= y && y <= objY + objSize;
if( colliding )
{
dragging = true;
objX = x;
objY = y;
glutPostRedisplay();
}
}
else
{
dragging = false;
}
}
void motion( int x, int y )
{
if( dragging )
{
objX = x;
objY = y;
glutPostRedisplay();
}
}
void drawRect( float x, float y, float size )
{
glPushMatrix();
glTranslatef( x, y, 0.0f );
glScalef( size, size, 1.0f );
glBegin( GL_QUADS );
glColor3ub( 255, 255, 255 );
glVertex2f( -1, -1 );
glVertex2f( 1, -1 );
glVertex2f( 1, 1 );
glVertex2f( -1, 1 );
glEnd();
glPopMatrix();
}
void display()
{
glClearColor( 0, 0, 0, 1 );
glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
glMatrixMode( GL_PROJECTION );
glLoadIdentity();
const double w = glutGet( GLUT_WINDOW_WIDTH );
const double h = glutGet( GLUT_WINDOW_HEIGHT );
glOrtho( 0, w, h, 0, -1, 1 );
glMatrixMode( GL_MODELVIEW );
glLoadIdentity();
drawRect( objX, objY, objSize );
glutSwapBuffers();
}
int main(int argc, char **argv)
{
glutInit( &argc, argv );
glutInitDisplayMode( GLUT_RGBA | GLUT_DEPTH | GLUT_DOUBLE );
glutInitWindowSize( 600, 600 );
glutCreateWindow( "GLUT" );
glutDisplayFunc( display );
glutMouseFunc( mouse );
glutMotionFunc( motion );
glutMainLoop();
return 0;
}