【问题标题】:Draw a rectangle with mouse in GLUT在 GLUT 中用鼠标绘制一个矩形
【发布时间】:2013-09-24 04:57:23
【问题描述】:

我对使用 GLUT 还很陌生,我一直在尝试编译一个程序(我找到了 here,第一个响应),它使用鼠标通过记录点击的起点和终点来绘制一个矩形 -并拖动。

作为一个干净的复制/粘贴,它会编译但不会绘制任何东西。即使将背景颜色更改为黑色(在 setup() 函数中),它也只会显示白色屏幕。我已经阅读了几个资料来验证这个程序在它的绘制和重塑功能中没有遗漏任何东西,而且一切都在那里。

我创建一个窗口,将视口设置为窗口尺寸,然后使用gluOrtho2D函数设置映射(由于窗口和视口是相同的尺寸,所以我将映射设置为窗口尺寸)。鼠标回调记录我左键单击的位置和释放左键的位置,然后调用 glutPostRedisplay() 函数以使用新坐标重绘窗口。经过一番调试,我发现坐标被适当地记录和保存,并且以像素为单位(x和y是0到窗口尺寸之间的整数),所以我应该能够从一个顶点到另一个顶点绘制一个矩形使用坐标。但是,就像我说的,它只显示一个白屏。

那么,我绘制矩形的方式有问题吗?我是否错误地映射了窗口?我迷路了,任何反馈都将不胜感激。

EDIT2:我将 glutInitDisplayMode 从 GLUT_SINGLE 更改为 GLUT_DOUBLE,从而修复了整个非交互式白屏问题。现在它将用鼠标绘制一个带有翻转 y 坐标(我已修复)的矩形,现在效果很好。非常感谢您的建议。

这是我的程序(EDIT1:添加了 cmets):

#include <cstdlib>
#include <GL/glut.h>    

using namespace std;

GLsizei width, height;

struct Position
{
    Position() : x(0), y(0) {}
    float x;
    float y;
};

Position start;  // Records left-click location
Position finish; // Records left-click release location

void display()
{
    glClear(GL_COLOR_BUFFER_BIT); // clear window

    glColor3ub(rand()%256, rand()%256, rand()%256); // generates random color
    glBegin(GL_QUADS);
        glVertex2f(start.x,start.y);
        glVertex2f(finish.x,start.y);
        glVertex2f(finish.x,finish.y);
        glVertex2f(start.x,finish.y);
    glEnd();

    glutSwapBuffers(); // display newly drawn image in window
}

void reshape( int w, int h )
{
    glViewport( 0, 0, (GLsizei)w, (GLsizei)h ); // set to size of window
    glMatrixMode( GL_PROJECTION );
    glLoadIdentity();

    gluOrtho2D( 0.0, (float)w, 0.0, (float)h );

    width = w;  // records width globally
    height = h; // records height globally

    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
}

void mouse(int button, int state, int x, int y)
{
    switch(button)
    {
    case GLUT_LEFT_BUTTON:

        if(state==GLUT_DOWN) 
        {
            start.x = x; //x1
            start.y = y; //y1                          
        }
        if(state==GLUT_UP)
        {
            finish.x = x; //x2
            finish.y = y; //y2
        }
        break;  
        glutPostRedisplay();
    }
}

void motion( int x, int y )
{
    finish.x = x;
    finish.y = y;
    glutPostRedisplay();
}

void setup()
{
    glClearColor(0.0, 0.0, 0.0, 1.0); // *should* display black background
}

int main(int argc, char** argv)
{
    glutInit(&argc,argv);
    glutInitDisplayMode(GLUT_DOUBLE|GLUT_RGB);
    glutInitWindowSize(640,480);
    glutInitWindowPosition(100,100);
    glutCreateWindow("");

    setup();

    // initializing callbacks
    glutReshapeFunc(reshape);
    glutDisplayFunc(display);
    glutMouseFunc(mouse);
    glutMotionFunc(motion);

    glutMainLoop();
    return 0;
}

【问题讨论】:

  • glutInitDisplayMode 应该是 GLUT_DOUBLE,这可能不是这里的问题,但是由于您正在调用 glutSwapBuffers,您应该指定 glut 以启用双缓冲。
  • 此外,鼠标内部的 glutPostRedisplay 可能需要在 break 之前或 switch 语句之外。同样,可能与您的原始问题无关
  • 您的第一个建议就像一个魅力,尽管将 glutPostRedisplay 放在 switch 语句之外是有道理的。非常有用的信息,谢谢。
  • 问题解决了吗?如果是这样,请发布答案以说明您为解决问题所做的工作。

标签: c++ opengl glut


【解决方案1】:

正如我的评论所建议的:

改变:

glutInitDisplayMode(GLUT_SINGLE|GLUT_RGB);

到:

glutInitDisplayMode(GLUT_DOUBLE|GLUT_RGB);

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-06-29
    • 1970-01-01
    相关资源
    最近更新 更多