【问题标题】:Draw a square in opengl at mouse position在鼠标位置在opengl中绘制一个正方形
【发布时间】:2011-04-21 18:27:24
【问题描述】:

我试图在使用 opengl/glut 按下鼠标左键的任何地方绘制一个简单的正方形。我的程序运行完美,除了它在我单击鼠标左键的地方绘制正方形的部分:)。有人能指出我做错了什么吗?

#include <stdlib.h> 
#include <glut.h>

GLsizei WIDTH = 1300, HEIGHT = 700;
GLsizei MOUSEx, MOUSEy;
GLfloat SIDE=1;

GLfloat RED[3] = {1,0,0};
GLfloat GREEN[3] = {0,1,0};
GLfloat BLUE[3] = {0,0,1};
GLfloat WHITE[3] = {1,1,1};
GLfloat BLACK[3] = {0,0,0};
GLfloat YELLOW[3] = {1,1,0};
GLfloat CYAN[3] = {0,1,1};
GLfloat MAGENTA[3] = {1,0,1};

void drawSquare(int x, int y)
{
    glColor3fv(YELLOW);
    glBegin(GL_POLYGON);
        glVertex3f(x+SIDE, y+SIDE,0);
        glVertex3f(x-SIDE, y+SIDE,0);
        glVertex3f(x-SIDE, y-SIDE,0);
        glVertex3f(x+SIDE, y-SIDE,0);
    glEnd();
    glFlush();
}

void drawSquare1()
{
    int x=0,y=0;
    glColor3fv(BLUE);
    glBegin(GL_POLYGON);
        glVertex3f(x+SIDE, y+SIDE,0);
        glVertex3f(x-SIDE, y+SIDE,0);
        glVertex3f(x-SIDE, y-SIDE,0);
        glVertex3f(x+SIDE, y-SIDE,0);
    glEnd();
    glFlush();
}

void display (void) {
    glClearColor (0.0,0.0,0.0,1.0);
    glClear (GL_COLOR_BUFFER_BIT);
    glLoadIdentity(); 
    glTranslatef(0,0,-5);
    drawSquare1();
    glFlush();
}

void reshape (int w, int h) {
    glViewport (0, 0, (GLsizei)w, (GLsizei)h);
    glMatrixMode (GL_PROJECTION);
    glLoadIdentity ();
    gluPerspective (60, (GLfloat)w / (GLfloat)h, 1.0, 100.0);
    glMatrixMode (GL_MODELVIEW);
    WIDTH=w;
    HEIGHT=h;
}

void setX(int x)
{
    MOUSEx=x;
}

void setY(int y)
{
    MOUSEy=y;
}

void mouse(int btn, int state, int x, int y)
{
    if(btn==GLUT_LEFT_BUTTON && state==GLUT_DOWN)   
    {
        setX(x);
        setY(y);
        drawSquare(MOUSEx,HEIGHT-MOUSEy);
        glutPostRedisplay();
    }
    if(btn==GLUT_RIGHT_BUTTON && state==GLUT_DOWN)   
    {
        exit(1);
    }
}

int main (int argc, char **argv) {
    glutInit (&argc, argv);
    glutInitDisplayMode (GLUT_SINGLE | GLUT_RGB);
    glutInitWindowSize (WIDTH, HEIGHT);
    glutInitWindowPosition (10, 10);
    glutCreateWindow ("New Window");
    glutDisplayFunc (display);
    glutReshapeFunc (reshape);
    glutMouseFunc(mouse);
    //glutMotionFunc(drawSquare);
    glutMainLoop ();
    return 0;
}

【问题讨论】:

    标签: opengl glut


    【解决方案1】:

    简而言之:OpenGL 不是场景图。这意味着鼠标处理程序中发出的那些绘图命令不会创建某种“持久性”。

    您应该将位置存储在列表/数组中,然后在显示函数中根据该列表中的值绘制正方形,而不是单击鼠标。

    【讨论】:

    • 这与你画的东西的数量无关。这是一个概念性的东西。 OpenGL“只是”一个复杂的绘图 API。一旦您将几何图形发送到 OpenGL,就会被光栅化并忘记它。
    • 我明白,但我刚刚看到另一段代码,其中有人通过单击鼠标两次(用于对角)进行绘图,并且他能够在不使用任何数组或列表的情况下绘制多个矩形,两个 x,y 位置只有四个全局变量。这似乎也几乎是我想要做的。
    • @Rizwan:我怀疑那个人只是没有清除 OpenGL 帧缓冲区,也没有使用双缓冲(或使用渲染到纹理)。问题是,这是相当不稳定的,因为只需将另一个窗口移动到 OpenGL 窗口上就会清除它。 OpenGL 没有为你做持久性,你必须自己做。像您所指的代码是糟糕的 OpenGL 教程的一个示例,我对此感到非常不满。请考虑我的建议:不要那样做!
    • 感谢您的帮助和耐心。
    【解决方案2】:

    我对这个编码很陌生,但我做到了。

    这是我的代码,它将起作用。

    #include <GL/glut.h>
    GLsizei MOUSEx=0, MOUSEy=0;
    GLfloat SIDE=50;
    GLfloat BLUE[3] = {0,0,1};
    
    void drawSquare1()
    {
        glColor3fv(BLUE);
        glBegin(GL_POLYGON);
            glVertex3f(MOUSEx, MOUSEy,0);
            glVertex3f(MOUSEx+SIDE, MOUSEy,0);
            glVertex3f(MOUSEx+SIDE, MOUSEy+SIDE,0);
            glVertex3f(MOUSEx, MOUSEy+SIDE,0);
        glEnd();
        glFlush();
    }   
    
    void display(void)
    {   
        glClearColor (0.0,0.0,0.0,1.0);
        glClear (GL_COLOR_BUFFER_BIT);
        glLoadIdentity(); 
        drawSquare1();
        glFlush();
    }
    void reshape(int w, int h)
    {   
        glViewport(0,0,(GLsizei)w,(GLsizei)h);
        glMatrixMode(GL_PROJECTION);
        glLoadIdentity();
         //gluPerspective (60, (GLfloat)w / (GLfloat)h, 1.0, 100.0);
        glOrtho(0.0,1368,768,0,-1.0,1.0);
        glMatrixMode(GL_MODELVIEW);
        glLoadIdentity();
    }
    
    void spindisplay(void)
    {       
        glutPostRedisplay();
    }
    
    void setX(int x)
    {
        MOUSEx=x;
    }
    
    void setY(int y)
    {
        MOUSEy=y;
    }
    void mouse(int btn, int state, int x, int y)
    {
        if(btn==GLUT_LEFT_BUTTON && state==GLUT_DOWN)   
        {
            setX(x);
            setY(y);
            //drawSquare(MOUSEx,HEIGHT-MOUSEy);
            glutPostRedisplay();
        }
        if(btn==GLUT_RIGHT_BUTTON && state==GLUT_DOWN)   
        {
            exit(1);   // To Exit the Program
        }
    }
    int main(int argc, char **argv)
    {   glutInit(&argc,argv);
        glutInitDisplayMode(GLUT_SINGLE|GLUT_RGB);
        glutInitWindowSize(1366,768);
        glutInitWindowPosition(0,0);
        glutCreateWindow("Moving squares");
        glutDisplayFunc(display);
        glutReshapeFunc(reshape);
        glutMouseFunc(mouse);
        glutIdleFunc(spindisplay);
        glutMainLoop();
    }
    

    【讨论】:

      【解决方案3】:

      以下是取自OpenGL Projects 的示例代码。尝试执行此操作,我认为您在 OpenGL 中绘制正方形的问题将很容易解决。如有任何问题欢迎提问。

      #include<stdlib.h>
          #include<glut.h>
          GLsizei wh=500,ww=500;
          GLfloat size=3.0;
      
          void display()
          {
          glFlush();
          }
      
          void myInit()
          {
              glViewport(0,0,ww,wh);
              glMatrixMode(GL_PROJECTION);
              glLoadIdentity();
              gluOrtho2D(0.0,(GLdouble)ww,0.0,(GLdouble)wh);
              glMatrixMode(GL_MODELVIEW);
              glClearColor(0.0,0.0,0.0,1.0);
              glColor3f(1.0,0.0,0.0);
          }
      
          void myReshape(GLsizei w,GLsizei h)
          {
              glMatrixMode(GL_PROJECTION);
              glLoadIdentity();
              gluOrtho2D(0.0,(GLdouble)w,0.0,(GLdouble)h);
              glMatrixMode(GL_MODELVIEW);
              glLoadIdentity();
              glViewport(0,0,w,h);
              ww=w;
              wh=h;
          }
      
          void drawSquare(int x,int y)
          {
      
              y=wh-y;
              glBegin(GL_POLYGON);
              glVertex2f(x+size,y+size);
              glVertex2f(x-size,y+size);
              glVertex2f(x-size,y-size);
              glVertex2f(x+size,y-size);
              glEnd();
              glFlush();
      
          }
      
          void size_menu(int id)
          {
              switch(id)
              {
              case 2: size=size*2;
                      break;
              case 3:if(size>1) size=size/2;
              break;
              }
              glutPostRedisplay();
          }
      
          void top_menu(int id)
          {
              switch(id)
              {
              case 1:exit(0);break;
              }
              glutPostRedisplay();
          }
      
          void myMouse(int button,int state,int x,int y)
          {
              if(button==GLUT_LEFT_BUTTON&&state==GLUT_DOWN)
              drawSquare(x,y);
              if(button==GLUT_RIGHT_BUTTON&&state==GLUT_DOWN)
                  exit(0);
          }
      
          int main(int argc,char **argv)
          {
              int sub_menu;
              glutInit(&argc,argv);
              glutInitDisplayMode(GLUT_SINGLE|GLUT_RGB);
              glutInitWindowSize(500,500);
              glutCreateWindow("Hierarchical Menus to Draw Squares");
              glutDisplayFunc(display);
              myInit();
              glutMouseFunc(myMouse);
              sub_menu=glutCreateMenu(size_menu);
              glutAddMenuEntry("Increase Square Size",2);
              glutAddMenuEntry("Decrease Square Size",3);
              glutCreateMenu(top_menu);
              glutAddMenuEntry("Quit",1);
              glutAddSubMenu("Resize",sub_menu);
              glutAttachMenu(GLUT_RIGHT_BUTTON);
              glutReshapeFunc(myReshape);
              glClear(GL_COLOR_BUFFER_BIT);
              glutMainLoop();
              return 0;
          }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-10-29
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-04-21
        相关资源
        最近更新 更多