opengl rubberbanded box没有显示

时间:2013-11-22 21:01:56

标签: c++ opengl glut rubber-band

我正在尝试在使用glDrawPixels绘制的图像上绘制一个选择框,但我无法显示它。为了表示盒子的坐标,我有4个全局整数,我在鼠标操作上更新(点击时的前2个,拖动鼠标时的其他2个),然后我在绘图功能中使用它。我确信拖动鼠标时会调用绘图函数,并且至少会更新四个值,因为我每次调用绘图函数时都会尝试打印它们。 我主要的OpenGL调用是:

glutInit(&argc, argv);
glutInitWindowSize(WINDOW_DIM, WINDOW_DIM);
glutInitWindowPosition(0, 0);
glutInitDisplayMode(GLUT_RGB|GLUT_DOUBLE);
glutCreateWindow("Window");
glutDisplayFunc(display);
glutMouseFunc(mouse);
glutMotionFunc(motion);
glClearColor(0.0, 0.0, 0.0, 1.0);
glDisable(GL_DEPTH_TEST);
glutMainLoop();

和我的显示功能:

void display()
{
    printf("calling display\n");
    for(unsigned int i=0; i<WINDOW_DIM*WINDOW_DIM; ++i)
    {
        pixels[i]=colors[img[i]];
    }
    glClear(GL_COLOR_BUFFER_BIT);
    glDrawPixels(WINDOW_DIM, WINDOW_DIM, GL_RGB, GL_FLOAT, (float*)pixels);
    glutSwapBuffers();
    if(upd_xmin!=0 || upd_ymin!=0 || upd_xmax!=0 || upd_ymax!=0)
    {
        glDrawBuffer(GL_FRONT);
        glLogicOp(GL_XOR);
        glEnable(GL_COLOR_LOGIC_OP);
        printf("drawing selection\n");
        printf("coords %d %d %d %d\n", upd_xmin, upd_ymin, upd_xmax, upd_ymax);
        glColor3f(1.0, 1.0, 1.0);
        glLineWidth(3.0);
        glBegin(GL_LINE_LOOP);
        glVertex2i(upd_xmin, upd_ymin);
        glVertex2i(upd_xmin, upd_ymax);
        glVertex2i(upd_xmax, upd_ymax);
        glVertex2i(upd_xmax, upd_ymin);
        glEnd();
        glDisable(GL_COLOR_LOGIC_OP);
        glDrawBuffer(GL_BACK);
    }
}

正如我所说,我不认为问题出在鼠标和动作功能上,看看当有鼠标事件时盒子的坐标(上面代码中的upd_x和upd_y变量)如何更新,但是如果我也可以发布这些内容。

2 个答案:

答案 0 :(得分:3)

不要在中间交换缓冲区。只需在后缓冲区上绘制选择框,就像其他所有内容一样:

selection

#include <GL/glut.h>

int StartX = -1;
int StartY = -1;
int EndX = -1;
int EndY = -1;

void mouse( int button, int state, int x, int y )
{
    if( button == GLUT_LEFT && state == GLUT_DOWN )
    {
        StartX = x;
        StartY = y;
    }
    if( button == GLUT_LEFT && state == GLUT_UP )
    {
        StartX = -1;
        StartY = -1;
        EndX = -1;
        EndY = -1;
    }
}

void motion( int x, int y )
{
    EndX = x;
    EndY = y;
    glutPostRedisplay();
}

void display()
{
    double w = glutGet( GLUT_WINDOW_WIDTH );
    double h = glutGet( GLUT_WINDOW_HEIGHT );

    glClear( GL_COLOR_BUFFER_BIT );

    glMatrixMode( GL_PROJECTION );
    glLoadIdentity();
    double ar = w / h;
    glOrtho( -2 * ar, 2 * ar, -2, 2, -1, 1 );

    glMatrixMode( GL_MODELVIEW );
    glLoadIdentity();

    glBegin( GL_TRIANGLES );
    glColor3ub( 255, 0, 0 );
    glVertex2i( -1, -1 );
    glColor3ub( 0, 255, 0 );
    glVertex2i(  1, -1 );
    glColor3ub( 0, 0, 255 );
    glVertex2i(  0,  1 );
    glEnd();

    glMatrixMode( GL_PROJECTION );
    glLoadIdentity();
    glOrtho( 0, w, h, 0, -1, 1 );

    glMatrixMode( GL_MODELVIEW );
    glLoadIdentity();

    if( StartX > 0 && StartY > 0 && EndX > 0 && EndY > 0 )
    {
        glLogicOp(GL_XOR);
        glEnable(GL_COLOR_LOGIC_OP);
        glColor3f(1.0, 1.0, 1.0);
        glLineWidth(3.0);
        glBegin(GL_LINE_LOOP);
        glVertex2i(StartX, StartY);
        glVertex2i(EndX, StartY);
        glVertex2i(EndX, EndY);
        glVertex2i(StartX, EndY);
        glEnd();
        glDisable(GL_COLOR_LOGIC_OP);
    }

    glutSwapBuffers();
}

int main( int argc, char **argv )
{
    glutInit( &argc, argv );
    glutInitDisplayMode( GLUT_RGBA | GLUT_DOUBLE );
    glutInitWindowSize( 640, 480 );
    glutCreateWindow( "GLUT" );
    glutDisplayFunc( display );
    glutMouseFunc( mouse );
    glutMotionFunc( motion );
    glutMainLoop();
    return 0;
}

由于您没有指定它们,我添加了投影和模型视图矩阵。

答案 1 :(得分:1)

我认为问题出在这里:

glClear(GL_COLOR_BUFFER_BIT);
glDrawPixels(WINDOW_DIM, WINDOW_DIM, GL_RGB, GL_FLOAT, (float*)pixels);
glutSwapBuffers();
rest of drawing

您的渲染调用应如下所示:

clear
render
swap buffers

render是您所有的平局调用(包括glDrawPixels)。

此外,在OpenGL 3.2中删除了glDrawPixels。除非您绝对需要使用该特定方法,否则为什么不使用正交投影来绘制GUI元素(选择框可以是哪个)?

编辑:另外,请注意,如果您在glDrawPixels之后进行绘制调用,则可能会覆盖您使用glDrawPixels绘制的内容。