2017-11-05 23 views
1

OpenGL Glutでポリゴンをマウス操作で描きたいと思ったら、クリックするたびに頂点になり、すべての頂点の間に線が引かれます。右マウスがクリックされると、ポリゴンは最後の頂点から最初の頂点まで直線を描くのを閉じます。私はこれを思いついたが、うまくいかないようだ。OpenGL GLUTでマウスを使ってポリゴンを描く

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

    bool right_pushed = 0; 
    glClear(GL_COLOR_BUFFER_BIT); 
    glBegin(GL_POINTS); 

    if (button == GLUT_LEFT_BUTTON && state == GLUT_DOWN) { 
     p1.x = x; 
     p1.y = 480 - y; 

     //if right is clicked draw a line to here 
     first.x = x; 
     first.y = 480 - y; 
    } 

    while (right_pushed == false) { 

     if (button == GLUT_LEFT_BUTTON && state == GLUT_DOWN) { 
      p2.x = x; 
      p2.y = 480 - y; 
     } 

     GLfloat dx = p2.x - p1.x; 
     GLfloat dy = p2.y - p1.y; 

     GLfloat x1 = p1.x; 
     GLfloat y1 = p1.y; 

     GLfloat step = 0; 

     if (abs(dx) > abs(dy)) { 
      step = abs(dx); 
     } 
     else { 
      step = abs(dy); 
     } 

     GLfloat xInc = dx/step; 
     GLfloat yInc = dy/step; 


     for (float i = 1; i <= step; i++) { 
      glVertex2i(x1, y1); 
      x1 += xInc; 
      y1 += yInc; 
     } 


     p1.x = p2.x; 
     p1.y = 480 - y; 

     if (button == GLUT_RIGHT_BUTTON && state == GLUT_DOWN) { 

      right_pushed = 1; 
      p2.x = first.x; 
      p2.y = first.y; 

      dx = p2.x - p1.x; 
      dy = p2.y - p1.y; 

      x1 = p1.x; 
      y1 = p1.y; 

      step = 0; 

      if (abs(dx) > abs(dy)) { 
       step = abs(dx); 
      } 
      else { 
       step = abs(dy); 
      } 

      xInc = dx/step; 
      yInc = dy/step; 


      for (float i = 1; i <= step; i++) { 

       glVertex2i(x1, y1); 
       x1 += xInc; 
       y1 += yInc; 

      } 

     } 
    } 

    glEnd(); 
    glFlush(); 


} 

int main(int argc, char **argv) { 
    glutInit(&argc, argv); 
    glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB); 
    glutInitWindowPosition(200, 200); 
    glutInitWindowSize(640, 480); 
    glutCreateWindow("windows"); 
    glutDisplayFunc(display); 
    glutMouseFunc(draw_polygon);// 
    init(); 
    glutMainLoop(); 
    return 0; 
} 

私も、私はメニューから選択するとき、私は、頂点を選択することができる方法でそれを編集するために、このポリゴンを作成から行くことができるとfunctionallityを追加arroundのそれを移動する方法を見つけるためにしようとしています、それに応じて形状が変化する。

+0

あなたのマウス機能で描画されています。これをしないでください。変数にポリゴンを保存します(例:点のリスト)。次に、マウス機能でこのリストを変更すると、表示機能でレンダリングできます。ポリゴンの変更は同様に行うことができます。 Btw、OpenGLの学習を始めたばかりの場合は、 'glBegin/glEnd/glVertex ...'で廃止予定の固定機能パイプラインを学ばないでください。 –

答えて

2

マウスイベントと描画機能を分離する必要があります。

マウスイベントでは、入力を収集するだけです。私はこれにstd::vectorを使用することを提案します。以下の関数は、左マウスボタンが押された場合に、std::vectorにポイントを追加します。右ボタンが押されると、ポリゴンはクローズとマークされます。再度左ボタンを押すと、ポリゴンがクリアされ、プロセスが再開します。あなたが継続的に現在のポイント間の線を描くことができ、あなたのメインループでは

void mouse_move(int x, int y) 
{ 
    currentPt = std::array<int, 2>{x, vp_height-y}; 
    glutPostRedisplay(); 
} 

:あなたは現在のマウスの位置を追跡することができ、マウス移動イベント機能では

#include <vector> 
#include <array> 

int vp_width = 640; 
int vp_height = 480; 

std::array<int, 2> currentPt; 
std::vector<std::array<int, 2>> pts; 
bool closed = false; 

void draw_polygon(int button, int state, int x, int y) 
{ 
    currentPt = std::array<int, 2>{x, vp_height-y}; 

    if (button == GLUT_LEFT_BUTTON && state == GLUT_DOWN) 
    { 
     if (closed) 
      pts.clear(); // restart if last action was close 
     closed = false; 
     pts.push_back(currentPt); 
    } 
    if (button == GLUT_RIGHT_BUTTON && state == GLUT_DOWN) 
     closed = true; 
} 

。 fllowing関数は、点のリストの間に線を引いています。 "cloesd"フラグがセットされている場合、ポリゴンは閉じられます。それ以外の場合は、リストの最後の点から現在のマウス位置までの線が描画されます。

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

    if (!pts.empty()) 
    { 
     glBegin(GL_LINE_STRIP); 
     for (auto &pt : pts) 
      glVertex2f((float)pt[0], (float)pt[1]); 
     auto &endPt = closed ? pts.front() : currentPt; 
     glVertex2f((float)endPt[0], (float)endPt[1]); 
     glEnd(); 
    } 

    //glFlush(); 
    glutSwapBuffers(); 
} 
int main() 
{ 
    ..... 
    glutDisplayFunc(display); 
    glutPassiveMotionFunc (mouse_move); 
    glutMouseFunc(draw_polygon); 

    glMatrixMode(GL_PROJECTION); 
    glOrtho(0.0f, (float)vp_width, 0.0f, (float)vp_height, -1.0, 1.0); 
    ..... 
} 


プレビュー:

preview

+0

それははるかに明確です、私はこれらの事に関するチュートリアルと例を見つけることができません。描画ポリゴン関数ではキャンバスでもっと多くの図形を作ろうとしていますので、pts.clear()関数を削除して再帰的に描画を追加して結合することができます。これは良いアイデアですか? – LegalizePasta

関連する問題