0

我有 2 个六边形

在此处输入图像描述

我想点击一个六边形的中心,点击的六边形将旋转 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)

        }

}

但是当我点击六边形的中心时,它会这样做

在此处输入图像描述

它旋转了我的整个图片,我只想旋转六边形,我该怎么办?

4

2 回答 2

1

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

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

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

于 2012-11-03T19:02:44.613 回答
0

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().

于 2012-11-03T20:06:44.793 回答