1. ホーム
  2. c

[解決済み] openGLでのglTranslatef,glScalef,glRotatefの使用方法

2022-03-04 23:54:52

質問

私はちょうどこのビデオのようなものが欲しい。 https://youtu.be/dGWtdYlryQQ を使用する方法を示しています。 glTranslate , glRotate , gluOrtho2d OpenGLで、しかし、それは私に何も教えてくれません。

私の場合、三角形の代わりに菱形を描きましたが、その条件は以下の通りです。
条件:

  1. キーボードのrまたはRを押すと、ダイヤモンドが時計回りに回転します。
  2. キーボードのtまたはTを押すと、ダイヤモンドは右側に移動します。
  3. キーボードの+を押すと、ダイヤモンドが大きくなります。

以下は私のコードです。

#include <stdlib.h>
#include <windows.h>
#include <GL/glut.h>
#include <iostream>
using namespace std;

float angle = 0;
float t,s=0.5,m=0;

void myinit(void){
    glClearColor(1.0,1.0,1.0,0.0);
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    glOrtho(0.0,1.0,0.0,1.0,-1.0,1.0);
}
void keyboard(unsigned char key, int x, int y){
        if(key==27)
        {
            exit(0);

        }else if(key == 82 || key == 114){
            angle-=0.1;

            glRotatef(angle,0,0,1);
            glutPostRedisplay();

        }else if(key == 84 || key == 116 )
        {
             t+=0.01;
             glTranslatef(t,0,0);
             glutPostRedisplay();
        }else if(key == 43){
                 s+=0.01;

               //  m-=0.1;
               //  glTranslatef(m,m,0.0);
                 glScalef(s,s,0);
                 glutPostRedisplay();
        }
        (void)(x);
        (void)(y);
}
void hut(void){

    glClear(GL_COLOR_BUFFER_BIT);

        glBegin(GL_TRIANGLE_FAN);
        glVertex3f(0.5,0.4,0.0);
        glVertex3f(0.42,0.5,0.0);    // GREEN
        glVertex3f(0.44,0.5,0.0);
    glColor3f(1.5,1.0,0.0);
        glVertex3f(0.46,0.5,0.0);
    glColor3f(0.25,0.0,0.0);
        glVertex3f(0.57,0.5,0.0);
        glEnd();
    glFlush();

    glColor3f(1.5,1.0,0.0);
        glBegin(GL_TRIANGLE_FAN);
        glVertex3f(0.44,0.55,0.0);
        glVertex3f(0.42,0.5,0.0);
        glVertex3f(0.46,0.5,0.0);
    glColor3f(0.25,0.0,0.0);
        glVertex3f(0.48,0.55,0.0);
        glEnd();

    glColor3f(1.5,1.0,0.0);
        glBegin(GL_TRIANGLE_FAN);
        glVertex3f(0.48,0.55,0.0);
        glVertex3f(0.46,0.5,0.0);
        glVertex3f(0.50,0.5,0.0);
    glColor3f(0.25,0.0,0.0);
        glVertex3f(0.52,0.55,0.0);
        glEnd();

    glColor3f(1.5,1.0,0.0);
        glBegin(GL_TRIANGLE_FAN);
        glVertex3f(0.52,0.55,0.0);
        glVertex3f(0.50,0.5,0.0);
        glVertex3f(0.54,0.5,0.0);
    glColor3f(0.25,0.0,0.0);
        glVertex3f(0.56,0.55,0.0);
        glEnd();
    glColor3f(1.5,1.0,0.0);
        glBegin(GL_TRIANGLE_FAN);
        glVertex3f(0.56,0.55,0.0);
        glVertex3f(0.54,0.5,0.0);
        glVertex3f(0.57,0.5,0.0);
        glEnd();
    glFlush();

}
int main(int argc,char** argv){
    glutInit(&argc,argv);
    glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);
    glutInitWindowPosition(100,100);
    glutInitWindowSize(640,480);
    glutCreateWindow("Polygon with viewport");
    myinit();
    glutDisplayFunc(hut);

    glutKeyboardFunc(keyboard);
    glutMainLoop();
}

そして、これが私の出力です。 https://drive.google.com/file/d/14HHRiCbOHK9ZSZtDOqSl4GP4aSy7UQLh/view?usp=sharing これと似て非なるもの https://youtu.be/dGWtdYlryQQ

解決方法は?

行列スタック上の演算は互いに関連しています。各操作の参照系は現在の変換です。

のドキュメントを参照してください。 glTranslate :

glTranslate によって翻訳を生成します。 x y z . 現在の行列 ( glMatrixMode )はこの並進行列と掛け合わされ、その積が現在の行列に置き換えられます[...]。

のドキュメントを参照してください。 glRotate :

glRotate は、ベクトルを中心に角度のついた回転を生成します。 x y z . 現在の行列 ( glMatrixMode ) に回転行列を掛け、その積を現在の行列に置き換えます。

これは、次のことを意味します。 glRotate は、現在のローカルシステムの原点を中心とした回転を行う。

一方 glRotatetf に続いて glTranslatef の結果が得られます。

glTranslatef に続いて glRotatef の結果が得られます。


オブジェクトが移動しているので、回転点が原点になるように平行移動させなければなりません。
glTranslatef(-0.5f, -0.5f, 0.0f);

そして、回転させることができます。

glRotatef(angle, 0.0f, 0.0f, 1.0f);

そして、後ろに移動させる。

glTranslatef(0.5f, 0.5f, 0.0f);

固定関数パイプライン を逆順にプッシュする必要があります。さらに GL_MODELVIEW 行列のスタックです。(参照 glMatrixMode .)

関数からすべての行列演算を削除します。 keyboard を追加し、関数に以下を追加します。 hut :

void hut(void)
{
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
    glTranslatef(t, 0.0f, 0.0f);
    glTranslatef(0.5f, 0.5f, 0.0f);
    glRotatef(angle, 0.0f, 0.0f, 1.0f);
    glScalef(s, s, 0.0f);
    glTranslatef(-0.5f, -0.5f, 0.0f);

    .....


さらに、オブジェクトはビューのアスペクト比によって破壊されます。これは、投影行列を設定する際にアスペクト比に注意することで解決できます。
float w = 640.0f;
float h = 480.0f;
glOrtho(0.0,w/h,0.0,1.0,-1.0,1.0);