Give this a shot:
#include <GL/glut.h>
#include <iostream>
#include <vector>
using namespace std;
struct Target
{
Target() : x(0), y(0), radius(0), angle(0) {}
bool Colliding( float tx, float ty )
{
float dx = ( tx - x );
float dy = ( ty - y );
float distSq = ( dx * dx + dy * dy );
return distSq < ( radius * radius );
}
void Draw()
{
const unsigned int sides = 6;
const float PI = 3.14159;
const float step = ( 2 * PI ) / static_cast< float >( sides );
glPushMatrix();
glTranslatef( x, y, 0 );
glRotatef( angle, 0, 0, 1 );
glScalef( radius, radius, 0 );
glBegin( GL_TRIANGLE_FAN );
glVertex2f( 0, 0 );
for( unsigned int i = 0; i <= sides; ++i )
{
if( i == 0 )
glColor3ub( 0, 0, 255 );
else
glColor3ub( 255, 0, 0 );
glVertex2f( cos( i * step ), sin( i * step ) );
}
glEnd();
glPopMatrix();
}
float x;
float y;
float radius;
float angle;
};
vector< Target > targets;
void init()
{
targets.resize( 2 );
targets[0].radius = 100;
targets[1].radius = 100;
}
void reshape( int w, int h )
{
glViewport( 0, 0, w, h );
targets[0].x = w * (1/4.0);
targets[0].y = h * (1/2.0);
targets[1].x = w * (3/4.0);
targets[1].y = h * (1/2.0);
}
void mouse( int button, int state, int x, int y )
{
if( button == GLUT_LEFT_BUTTON && state == GLUT_DOWN )
{
bool hit = false;
for( size_t i = 0; i < targets.size(); ++i )
{
if( targets[i].Colliding( x, y ) )
{
targets[i].angle += 30;
hit = true;
}
}
if( hit )
glutPostRedisplay();
}
}
void display()
{
glClear( GL_COLOR_BUFFER_BIT );
glMatrixMode( GL_PROJECTION );
glLoadIdentity();
double w = glutGet( GLUT_WINDOW_WIDTH );
double h = glutGet( GLUT_WINDOW_HEIGHT );
glOrtho( 0, w, 0, h, -1, 1);
glMatrixMode( GL_MODELVIEW );
glLoadIdentity();
for( size_t i = 0; i < targets.size(); ++i )
{
targets[i].Draw();
}
glutSwapBuffers();
}
int main( int argc, char **argv )
{
glutInit( &argc, argv );
glutInitDisplayMode( GLUT_RGBA | GLUT_DOUBLE );
glutInitWindowSize( 640, 480 );
glutCreateWindow( "Hex" );
init();
glutDisplayFunc( display );
glutMouseFunc( mouse );
glutReshapeFunc( reshape );
glutMainLoop();
return 0;
}
It's using gl{Push|Pop}Matrix()
to preserve the model-view matrix in Target::Draw()
.