2016-05-17 3 views
-2

まあ、OpenGL用に以下のC(GLUTプロジェクト)があります。私はCodeBlocksを使ってそれをコンパイルします(余分なmain()関数ファイルを削除しています)。 私はOpenGLを書いた方法が悪い場合、私はいくつかの例に基づいて、ごめんなさい。主なことは、それをうまく動作させることです。OpenGL(C言語):キーボードで移動する形状を作成する(歪み問題)

私が必要とするのは、「Mr Robot」のすべての形(頭、体、手、脚)をキーボードの矢印キーで移動することです。それは期待どおりに動作しますが、いくつかの点からは、いくつかの形状が歪んでいます。私はそれを修正する理由と方法を知らない。

あなたが画面上で正しく所望の形状を描くからプログラムを防止するための問題以下のいる
#include <GL/glut.h> 

GLuint kefali_x1=5, kefali_y1=30, kefali_x2=15, kefali_y2=30, kefali_x3=15, kefali_y3=40, kefali_x4=5,kefali_y4=40; 
GLuint soma_x1=0, soma_y1=10, soma_x2=20, soma_y2=10, soma_x3=20, soma_y3=30, soma_x4=0, soma_y4=30; 
GLuint podia_x1=10, podia_y1=10, podia_x2=20, podia_y2=0, podia_x3=10, podia_y3=-5, podia_x4=0, podia_y4=0; 
GLuint dexi_xeri_x1=20, dexi_xeri_y1=30, dexi_xeri_x2=30, dexi_xeri_y2=27.5, dexi_xeri_x3=20, dexi_xeri_y3=25; 
GLuint aristero_xeri_x1=-10, aristero_xeri_y1=27.5, aristero_xeri_x2=0, aristero_xeri_y2=30, aristero_xeri_x3=0, aristero_xeri_y3=25; 


// σύνθετο σχήμα 
GLuint listID; 

void MrRobot(GLsizei displayListID) 
{ 
    glNewList(displayListID,GL_COMPILE); 

    //Save current colour state 
    glPushAttrib(GL_CURRENT_BIT); 

    // σώμα 
    glColor3f(0.5,0.5,0.5); 
    glBegin(GL_POLYGON); 
    glVertex2f(soma_x1,soma_y1); 
    glVertex2f(soma_x2,soma_y2); 
    glVertex2f(soma_x3,soma_y3); 
    glVertex2f(soma_x4,soma_y4); 
    glEnd(); 

    // κεφάλι 
    glColor3f(0,0,1); 
    glBegin(GL_POLYGON); 
    glVertex2f(kefali_x1,kefali_y1); 
    glVertex2f(kefali_x2,kefali_y2); 
    glVertex2f(kefali_x3,kefali_y3); 
    glVertex2f(kefali_x4,kefali_y4); 
    glEnd(); 

    // πόδια 
    glColor3f(1,0,0); 
    glBegin(GL_TRIANGLE_FAN); 
    glVertex2f(podia_x1,podia_y1); 
    glVertex2f(podia_x2,podia_y2); 
    glVertex2f(podia_x3,podia_y3); 
    glVertex2f(podia_x4,podia_y4); 
    glEnd(); 

    // δεξί χέρι 
    glColor3f(0,1,0); 
    glBegin(GL_TRIANGLES); 
    glVertex2f(dexi_xeri_x1,dexi_xeri_y1); 
    glVertex2f(dexi_xeri_x2,dexi_xeri_y2); 
    glVertex2f(dexi_xeri_x3,dexi_xeri_y3); 
    glEnd(); 

    // αριστερό χέρι 
    glColor3f(0,1,0); 
    glBegin(GL_TRIANGLES); 
    glVertex2f(aristero_xeri_x1,aristero_xeri_y1); 
    glVertex2f(aristero_xeri_x2,aristero_xeri_y2); 
    glVertex2f(aristero_xeri_x3,aristero_xeri_y3); 
    glEnd(); 

    //Recall saved colour state 
    glPopAttrib(); 

    glEndList(); 
} 

void display() 
{ 
    glClearColor(0,0,0,0); 

    glClear(GL_COLOR_BUFFER_BIT); 

    glColor3f(1,0,0); 

    listID=glGenLists(1); 

    MrRobot(listID); 

    //Execute the display list (the modelview matrix will be applied) 
    glCallList(listID); 

    glFlush(); 
} 

void keyboard(unsigned char key,int x, int y) 
{ 
    printf("\nKeyboard event detected. \nCharacter key: %c\nMouse pointer position: x=%d y=%d",key,x,y); 

    if (key==GLUT_KEY_UP) 
    { 
     kefali_y1++; 
     kefali_y2++; 
     kefali_y3++; 
     kefali_y4++; 

     soma_y1++; 
     soma_y2++; 
     soma_y3++; 
     soma_y4++; 

     podia_y1++; 
     podia_y2++; 
     podia_y3++; 
     podia_y4++; 

     dexi_xeri_y1++; 
     dexi_xeri_y2++; 
     dexi_xeri_y3++; 

     aristero_xeri_y1++; 
     aristero_xeri_y2++; 
     aristero_xeri_y3++; 
    } 
    if (key==GLUT_KEY_DOWN) 
    { 
     kefali_y1--; 
     kefali_y2--; 
     kefali_y3--; 
     kefali_y4--; 

     soma_y1--; 
     soma_y2--; 
     soma_y3--; 
     soma_y4--; 

     podia_y1--; 
     podia_y2--; 
     podia_y3--; 
     podia_y4--; 

     dexi_xeri_y1--; 
     dexi_xeri_y2--; 
     dexi_xeri_y3--; 

     aristero_xeri_y1--; 
     aristero_xeri_y2--; 
     aristero_xeri_y3--; 
    } 
    if (key==GLUT_KEY_LEFT) 
    { 
     kefali_x1--; 
     kefali_x2--; 
     kefali_x3--; 
     kefali_x4--; 

     soma_x1--; 
     soma_x2--; 
     soma_x3--; 
     soma_x4--; 

     podia_x1--; 
     podia_x2--; 
     podia_x3--; 
     podia_x4--; 

     dexi_xeri_x1--; 
     dexi_xeri_x2--; 
     dexi_xeri_x3--; 

     aristero_xeri_x1--; 
     aristero_xeri_x2--; 
     aristero_xeri_x3--; 
    } 
    if (key==GLUT_KEY_RIGHT) 
    { 
     kefali_x1++; 
     kefali_x2++; 
     kefali_x3++; 
     kefali_x4++; 

     soma_x1++; 
     soma_x2++; 
     soma_x3++; 
     soma_x4++; 

     podia_x1++; 
     podia_x2++; 
     podia_x3++; 
     podia_x4++; 

     dexi_xeri_x1++; 
     dexi_xeri_x2++; 
     dexi_xeri_x3++; 

     aristero_xeri_x1++; 
     aristero_xeri_x2++; 
     aristero_xeri_x3++; 
    } 

    glutPostRedisplay(); 
} 

int main(int argc, char** argv) 
{ 
    glutInit(&argc,argv); 
    glutInitWindowPosition(50,50); 
    glutInitWindowSize(800,600); 
    glutInitDisplayMode(GLUT_SINGLE|GLUT_RGB); 
    glutCreateWindow("MrROBOT"); 

    glMatrixMode(GL_MODELVIEW); 
    gluOrtho2D(-10,50,-10,50); 

    glScalef(0.4,0.4,0.4); 

    glutDisplayFunc(display); 
    glutSpecialFunc(keyboard); 
    glutMainLoop(); 

    return 0; 
} 
+0

なぜディスプレイリストを使用していますか?つまり、なぜ次のステップで呼び出すために描画関数内に表示リストを作成するのですか?表示リストの目的は、あなたが何度も何度も何度も何度も何度も何度も何度も何度も何度も何度も何度も何度も何度も何度も使ってみることでした。あなたがやることは、さまざまな表示リストを作成し、変更したものです(古いものは削除しません)。あなたのプログラムの表示リストは、ますます多くのリソースを消費する以外の目的はありません。それを取り除く! – datenwolf

+0

コーディングスタイルについて:あなたは 'struct'sが何であるか知っていますか?また、なぜあなたにはたくさんの変数がありますか?すべて同じ変更が適用されますか?これを3つの浮動小数点にすることができ、変換行列を使用して残りの処理を実行できます。 – datenwolf

+0

私はこの質問に同意しないことになっています。 OPの英語がどれほど貧弱であっても、2つの長方形、2つの三角形、1つの三角形を描画し、矢印キーを使用して画面全体にシェイプを移動させることが望ましい動作であることは明らかです。これは、UBを引き起こすデータ型の不一致の明確な例でもあり、描画ルーチンを破壊します。答えの1つは、そのようなサンプルプログラムの全体的なコーディングがどのように根本的に改善されるかを示すことです。私が閉会に反対する特権がないので、これが私の意見を表明する唯一の方法です。 – user3078414

答えて

0

:彼らはGLfloatであるかのようにそれらを描画GLuintデータ型

  • として頂点を宣言し、インクリメント

    • をこれは上記と矛盾し、未定義の動作を引き起こします。

    それぞれの指定を修正してくださいこのタイプのカチオン:

    glVertex2i(…_xi,…_yi); 
    

    glVertex2f(…_xi,…_yi); 
    

    これは "歪曲" 問題を修正する必要があります。

    また、この回答はコーディングスタイルには適していないことをご理解ください。 SOはチュートリアルサイトではありません。あなたの記事へのコメントを見てください。

  • 1

    申し訳ありませんが、私はOpenGLを書いた方法が悪いです。主なことは、それをうまく動作させることです。

    これら2つは通常手に入ります。あなたの(OpenGL)コードが悪い場合、あなたのプログラムは "うまく"動かないでしょう。きれいなコードを書いてください。あなたのプログラムは適切に動作するはるかに良い機会です。

    ここにいくつかの問題があります:なぜ、xyzのための膨大な量の別々の(グローバルな)変数ですか?構造体を使用してください!なぜ即時描画にディスプレイリストを使用しますか?これはディスプレイリストの対象ではありませんので、使用しないでください!単純に変換を変更するのではなく、頂点の位置の値を一様に変更するのはなぜですか?

    クリーンなコード構造は、すべてプログラムの理由を説明できることです。プログラムに問題がある場合、デバッグする最善の方法の1つはコードをクリーンアップすることです。あなたが「ああ、ちょっと速いハックだよ」と思って自分を欺くのであれば、通常はすべての悪いことが明白になるでしょう。

    これははるかに理解しにくいですか?また動作します

    #include <stddef.h> 
    #include <stdio.h> 
    #include <GL/glut.h> 
    
    float robot_x = 0, robot_y = 0; 
    
    typedef GLfloat vec2[2]; 
    
    enum { kefali_len = 4 }; 
    vec2 const kefali[kefali_len] = { {5, 30}, {15, 30}, {15, 40}, {5, 40} }; 
    
    enum { soma_len = 4 }; 
    vec2 const soma[soma_len] = { {0, 10}, {20, 10}, {20, 30}, {0, 30} }; 
    
    enum { podia_len = 4 }; 
    vec2 const podia[podia_len] = { {10, 10}, {20, 0}, {10, -5}, {0, 0} }; 
    
    enum { dexi_len = 3 }; 
    vec2 const dexi[dexi_len] = { {20, 30}, {30, 27.5}, {20, 25} }; 
    
    enum { aristero_len = 3}; 
    vec2 const aristero[aristero_len] = { {-10, 27.5}, {0, 30}, {0, 25} }; 
    
    static 
    void draw_vertices2(GLenum mode, vec2 const * const v, size_t n) 
    { 
        size_t i; 
        /* use of glBegin + glVertex is outdated since 1997. Whoever teaches 
        * is these days should either bring their coursework up to date 
        * or consider retirement. */ 
        glBegin(mode); 
        for(i=0; i < n; ++i) { 
         glVertex2fv(v[i]); 
        } 
        glEnd(); 
    } 
    
    
    static 
    void MrRobot(void) 
    { 
        //Save current colour state 
        glPushAttrib(GL_CURRENT_BIT); 
    
        // σώμα 
        glColor3f(0.5,0.5,0.5); 
        draw_vertices2(GL_POLYGON, soma, soma_len); 
    
        // κεφάλι 
        glColor3f(0,0,1); 
        draw_vertices2(GL_POLYGON, kefali, kefali_len); 
        glBegin(GL_POLYGON); 
    
        // πόδια 
        glColor3f(1,0,0); 
        draw_vertices2(GL_TRIANGLE_FAN, podia, podia_len); 
    
        // δεξί χέρι 
        glColor3f(0,1,0); 
        draw_vertices2(GL_TRIANGLES, dexi, dexi_len); 
    
        // αριστερό χέρι 
        glColor3f(0,1,0); 
        draw_vertices2(GL_TRIANGLES, aristero, aristero_len); 
    
        //Recall saved colour state 
        glPopAttrib(); 
    } 
    
    
    static 
    GLuint generate_display_list_robot(void) 
    { 
        GLuint const list = glGenLists(1); 
        if(list) { 
         glNewList(list, GL_COMPILE); 
         MrRobot(); 
         glEndList(); 
        } 
        return list; 
    } 
    
    static GLuint display_list_robot = 0; 
    
    static 
    void display(void) 
    { 
        glClearColor(0,0,0,0); 
        glClear(GL_COLOR_BUFFER_BIT); 
    
        glViewport(0, 0, glutGet(GLUT_WINDOW_WIDTH), glutGet(GLUT_WINDOW_HEIGHT)); 
    
        glMatrixMode(GL_PROJECTION); 
        glLoadIdentity(); 
        gluOrtho2D(-10,50,-10,50); 
    
        glMatrixMode(GL_MODELVIEW); 
        glLoadIdentity(); 
        glScalef(0.4,0.4,0.4); 
    
        glPushMatrix(); 
        glTranslatef(robot_x, robot_y, 0); 
        if(display_list_robot) { 
         glCallList(display_list_robot); 
        } else { 
         MrRobot(); 
        } 
        glPopMatrix(); 
    
        glutSwapBuffers(); 
    } 
    
    static 
    void keyboard(int key, int pointer_x, int pointer_y) 
    { 
        fprintf(stderr, 
         "\nKeyboard event.\nCharacter: %d\nMouse pointer position: x=%d y=%d", 
         (int)key, 
         (int)pointer_x, 
         (int)pointer_y); 
    
        switch(key) { 
        case GLUT_KEY_UP: ++robot_y; break; 
        case GLUT_KEY_DOWN: --robot_y; break; 
        case GLUT_KEY_RIGHT: ++robot_x; break; 
        case GLUT_KEY_LEFT: --robot_x; break; 
        } 
        glutPostRedisplay(); 
    } 
    
    int main(int argc, char** argv) 
    { 
        size_t i; 
        glutInit(&argc,argv); 
        glutInitWindowPosition(50,50); 
        glutInitWindowSize(800,600); 
        glutInitDisplayMode(GLUT_DOUBLE|GLUT_RGB); 
        glutCreateWindow("MrROBOT"); 
    
        /* argv[0] is program name */ 
        for(i = 1; i < argc; ++i) { 
         if('d' == argv[i][0]) { 
          if(!display_list_robot) { 
           display_list_robot = generate_display_list_robot(); 
          } 
         } 
        } 
    
        glutDisplayFunc(display); 
        glutSpecialFunc(keyboard); 
    
        glutMainLoop(); 
    
        return 0; 
    } 
    
    関連する問題