OpenGL - 如何让个人旋转?

时间:2014-10-19 03:36:46

标签: opengl matrix rotation rendering instances

我在使用OpenGL矩阵系统时遇到了一些问题。

我在下面做了五个实例。我想让他们的个人工作。

C_IMGMGR cImgmgr1( 200 , 170 );
C_IMGMGR cImgmgr2( 200 , 170 );
C_IMGMGR cImgmgr3( 200 , 170 );
C_IMGMGR cImgmgr4( 200 , 170 );
C_IMGMGR cImgmgr5( 200 , 170 );

这是主要的,

int main( int argc, char** argv )
{
    int nWinSizeX = 1280;
    int nWinSizeY = 768;

    glutInit( &argc , argv );
    mainWindow = CreateMain( nWinSizeX , nWinSizeY );

    SetProjection( nWinSizeX , nWinSizeY );
    SetStateSettings();

    NowFrameMove();

    return 1;
}

和SetProjection()

void SetProjection( int nWinSizeX , int nWinSizeY )
{
    cImgmgr1.Init_Viewport( 540 , 599 , nWinSizeX , nWinSizeY );
    cImgmgr2.Init_Viewport( 40 , 299 , nWinSizeX , nWinSizeY );
    cImgmgr3.Init_Viewport( 540 , 299 , nWinSizeX , nWinSizeY );
    cImgmgr4.Init_Viewport( 1040 , 299 , nWinSizeX , nWinSizeY );
    cImgmgr5.Init_Viewport( 540 , -1 , nWinSizeX , nWinSizeY );

    glMatrixMode( GL_PROJECTION );
    glLoadIdentity();
    glOrtho( 0.0 , 1280 , 0.0 , 768 , -10000.0 , 10000.0 );

    glMatrixMode( GL_MODELVIEW );
    glLoadIdentity();
    glTranslatef( (200 / 2) , (170 / 2) , 0 );
}

和SetStateSetting()

void SetStateSettings()
{
    glEnable( GL_BLEND );
    glBlendFunc( GL_SRC_ALPHA , GL_ONE_MINUS_SRC_ALPHA );
    glEnable( GL_TEXTURE_2D );

    cImgmgr1.Init_Sprite( "data\\Image\\symbol01_Pay\\" );
    cImgmgr2.Init_Sprite( "data\\Image\\symbol01_Pay\\" );
    cImgmgr3.Init_Sprite( "data\\Image\\symbolTemp_Pay\\" );
    cImgmgr4.Init_Sprite( "data\\Image\\symbol01_Pay\\" );
    cImgmgr5.Init_Sprite( "data\\Image\\symbol01_Pay\\" );
}

这里是glutDisplayFunc()和glutIdleFunc()的更新(),

void Update()
{
    //////////////////////////////////////////////////////////////////////////
    //Process
    cImgmgr1.Process( FLIP_VERTICAL );
    cImgmgr2.Process( FLIP_HORIZONTAL );
    cImgmgr3.Process( NORMAL );
    cImgmgr4.Process( NORMAL );
    cImgmgr5.Process( NORMAL );
    //////////////////////////////////////////////////////////////////////////
    //////////////////////////////////////////////////////////////////////////
    //Render
    glClearColor( 0.0F , 0.0F , 0.0F , 0.0F );
    glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
    glClearDepth( 1.0 );

    cImgmgr1.Render_Sprite( cImgmgr1.Get_Frame() );
    cImgmgr2.Render_Sprite( cImgmgr2.Get_Frame() );
    cImgmgr3.Render_Sprite( cImgmgr3.Get_Frame() );
    cImgmgr4.Render_Sprite( cImgmgr4.Get_Frame() );
    cImgmgr5.Render_Sprite( cImgmgr5.Get_Frame() );
    //////////////////////////////////////////////////////////////////////////
    glutSwapBuffers();
}

和IMGMGR课程,

void C_IMGMGR::Process( E_RENDER_MODE eMode )
{
    if( m_nFrame >= m_nFileCount )
        m_nFrame = 0;

    switch ( eMode )
    {
    case NORMAL :
        break;
    case FLIP_VERTICAL :
        m_fRotationAngle = 1.0F;
        m_fRotationX = 1.0F;
        break;
    case FLIP_HORIZONTAL :
        m_fRotationAngle = 1.0F;
        m_fRotationY = 1.0F;
        break;
    case FAN_LEFT :
        m_fRotationAngle = 1.0F;
        m_fRotationZ = 1.0F;
        break;
    case FAN_RIGHT :
        m_fRotationAngle = 1.0F;
        m_fRotationZ = -1.0F;
        break;
    case TRANSLATE_VERTICAL :
        break;
    case TRANSLATE_HORIZONTAL :
        break;
    }
}

void C_IMGMGR::Render_Sprite( int nFrame )
{
    glBindTexture( GL_TEXTURE_2D , m_pLoadedSprite[nFrame] );

    glViewport( m_nViewPortX , m_nViewPortY , m_nScreenW , m_nScreenH );

    glPushMatrix();
    glRotatef( m_fRotationAngle , m_fRotationX , m_fRotationY , m_fRotationZ );
    glTranslatef( m_fTranslateX , m_fTranslateY , m_fTranslateZ );
    glScalef( m_fScaleX , m_fScaleY , m_fScaleZ );

    glBegin( GL_QUADS );
    glTexCoord2f( 0.0F , 1.0F); glVertex2f( -(float)m_nImgX_half , -(float)m_nImgY_half);
    glTexCoord2f( 1.0F , 1.0F); glVertex2f( (float)m_nImgX_half , -(float)m_nImgY_half);
    glTexCoord2f( 1.0F , 0.0F); glVertex2f( (float)m_nImgX_half , (float)m_nImgY_half);
    glTexCoord2f( 0.0F , 0.0F); glVertex2f( -(float)m_nImgX_half , (float)m_nImgY_half);
    glEnd();
    glPopMatrix();
}

他们一起旋转,看起来像分享FLIP_VERTICAL和FLIP_HORIZONTAL。

那么,我如何分离他们的矩阵以进行单个实例工作?

1 个答案:

答案 0 :(得分:1)

发布的代码存在一些问题:

  • OpenGL作为状态机运行。当您进行绘制调用时,它使用绘制调用时设置的状态。因此,如果应用于绘制调用,则需要在绘制调用之前 指定转换。

  • 相关,glRotatef()glTranslatef()等来电会修改当前转换矩阵。除非你对它做了些什么,否则每个调用都会将指定的转换与先前的当前转换相结合。如果您只是为每次绘制调用做一些调用,那么所有的变换都将被合并。

要解决这两个问题,您需要更改调用的顺序,并在应用特定绘制调用的转换时使用glPushMatrix()glPopMatrix()保存/恢复上一个转换。代码将如下所示:

glPushMatrix();
glRotatef( m_fRotationAngle , m_fRotationX , m_fRotationY , m_fRotationZ );
glTranslatef( m_fTranslateX , m_fTranslateY , m_fTranslateZ );
glScalef( m_fScaleX , m_fScaleY , m_fScaleZ );

glBegin( GL_QUADS );
glTexCoord2f( 0.0F , 1.0F); glVertex2f( -(float)m_nImgX_half , -(float)m_nImgY_half);
glTexCoord2f( 1.0F , 1.0F); glVertex2f( (float)m_nImgX_half , -(float)m_nImgY_half);
glTexCoord2f( 1.0F , 0.0F); glVertex2f( (float)m_nImgX_half , (float)m_nImgY_half);
glTexCoord2f( 0.0F , 0.0F); glVertex2f( -(float)m_nImgX_half , (float)m_nImgY_half);
glEnd();

glPopMatrix();

我希望您已经知道,此代码中使用的几乎所有OpenGL调用都已弃用,并且在现代版本的OpenGL中不再可用。如果您想学习当前的OpenGL,请查找OpenGL核心配置文件或OpenGL ES 2.0或更高版本的教程。