通过在OpenGL中单击它来旋转多边形

时间:2012-11-03 14:35:42

标签: opengl rotation click mouse polygon

我有2个六边形

enter image description here

我想点击一个六边形的中心,点击的六边形将旋转30度,另一个将保持静止。我试图做的是:

void myMouse( int button, int state, int x, int y ){

int selected=0;

if (x<=102 && x>=95 && y<=452 && y>=446)
    selected=1;

    if((selected == 1) &&( button == GLUT_LEFT_BUTTON ))
        {

        glTranslatef(-12, 6, 0);
        glRotatef(30,0,0,1.0);
        glTranslatef(12, -6, 0)

        }

}

但是当我点击六边形的中心时,它会执行此操作

enter image description here

它旋转了整个画面,我只想旋转六边形,我该怎么办?

2 个答案:

答案 0 :(得分:1)

OpenGL不是场景图。这是一个基于状态的绘图API。调用glRotate,glTranslate等不会影响“对象”,而是影响原始变换矩阵,这些矩阵应用于绘图。

作为一项基本规则,任何OpenGL调用都不应放在输入事件处理程序中,它们不属于那里!

在你的情况下,你所做的是改变绘制你想要影响的场景部分时使用的某个变量的值。

答案 1 :(得分:0)

试一试:

#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;
}

使用gl{Push|Pop}Matrix()保留Target::Draw()中的模型视图矩阵。