使用OpenGL中的Qt进行颜色选择

时间:2012-05-25 12:37:13

标签: c++ qt opengl picking

我一直在阅读关于采摘的教程,颜色采摘是最流行和最简单的形式。

尝试使用snowmans作为示例的一些教程,但它对我不起作用。当我运行该程序时,它只给我一个黑色的画面而没有任何画画。当我点击几次没有任何反应,除非我关闭窗口,然后它说“你还没有点击雪人”。

不知道有什么问题可以有人帮助我吗?

void GLWidget::paintGL() {
    glEnable(GL_DEPTH_TEST);
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    glLoadIdentity();

    gluLookAt(camPosx ,camPosy ,camPosz,
              camPosx + camViewx,camViewy,camPosz + camViewz,
              camUpx, camUpy, camUpz );

    draw(); //draw the normal scene

    if (mode == SELECT)
        drawPickingMode();
    else
        drawPickingMode();

    if (mode == SELECT) {
        processPick();
        mode = RENDER;
    }
    else
        QGLWidget::swapBuffers();

    // restore current matrix
    glMatrixMode( GL_MODELVIEW );
    glPopMatrix( );

}

void GLWidget::mousePressEvent(QMouseEvent * e)
{
    if(e->button() == Qt::LeftButton)
    {
        qDebug("mouse");
        qDebug("%d %d",QCursor::pos().x(),QCursor::pos().y());
        this->cursorX = QCursor::pos().x(); // set x and y cord from mouse
        this->cursorY = QCursor::pos().y();
        mode = SELECT; // set the mode to select
    }
}

void GLWidget::draw() {

// Draw ground
    glColor3f(0.9f, 0.9f, 0.9f);
    glBegin(GL_QUADS);
        glVertex3f(-100.0f, 0.0f, -100.0f);
        glVertex3f(-100.0f, 0.0f,  100.0f);
        glVertex3f( 100.0f, 0.0f,  100.0f);
        glVertex3f( 100.0f, 0.0f, -100.0f);
    glEnd();

// Draw 4 Snowmen

    glColor3f(1.0f, 1.0f, 1.0f);

    for(int i = 0; i < 2; i++)
        for(int j = 0; j < 2; j++) {
            glPushMatrix();
            glTranslatef(i*3.0,0,-j * 3.0);
            glColor3f(1.0f, 1.0f, 1.0f);
            glCallList(snowman_display_list);
            glPopMatrix();
        }

}

void GLWidget::processPick ()
{
    GLint viewport[4];
    GLubyte pixel[3];

    glGetIntegerv(GL_VIEWPORT,viewport);

    glReadPixels(cursorX,viewport[3]-cursorY,1,1,
        GL_RGB,GL_UNSIGNED_BYTE,(void *)pixel);

    printf("%d %d %d\n",pixel[0],pixel[1],pixel[2]);
    if (pixel[0] == 255)
      printf ("You picked the 1st snowman on the 1st row");
    else if (pixel[1] == 255)
      printf ("You picked the 1st snowman on the 2nd row");
    else if (pixel[2] == 255)
      printf ("You picked the 2nd snowman on the 1st row");
    else if (pixel[0] == 250)
      printf ("You picked the 2nd snowman on the 2nd row");
    else
       printf("You didn't click a snowman!");
  printf ("\n");

}

void GLWidget::drawPickingMode() {

// Draw 4 SnowMen


    glDisable(GL_DITHER);
    for(int i = 0; i < 2; i++)
           for(int j = 0; j < 2; j++) {
        glPushMatrix();

// A different color for each snowman

        switch (i*2+j) {
            case 0: glColor3ub(255,0,0);break;
            case 1: glColor3ub(0,255,0);break;
            case 2: glColor3ub(0,0,255);break;
            case 3: glColor3ub(250,0,250);break;
        }

        glTranslatef(i*3.0,0,-j * 3.0);
        glCallList(snowman_display_list);
        glPopMatrix();
       }
    glEnable(GL_DITHER);
}

void GLWidget::initializeGL() {

    loadGLTextures();
    //LoadXml();
    glEnable(GL_TEXTURE_2D);       // Enable Texture Mapping
    glShadeModel(GL_SMOOTH);       // Enable Smooth Shading
    glClearColor(0.0f, 0.0f, 0.0f, 0.5f);    // Black Background
    glClearDepth(1.0f);         // Depth Buffer Setup
    glEnable(GL_DEPTH_TEST);       // Enables Depth Testing
    glDepthFunc(GL_LEQUAL);        // The Type Of Depth Testing To Do
    glEnable(GL_LIGHT0);        // Quick And Dirty Lighting (Assumes Light0 Is Set Up)
    glEnable(GL_LIGHTING);        // Enable Lighting
    glEnable(GL_COLOR_MATERIAL);      // Enable Material Coloring
    glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); // Perspective Calculations
   // buildLists(2);                                      // Creating displaylist #
    glLoadIdentity();

    timer->start(50);
    qDebug("Init");
}

投影矩阵设置如下:

void GLWidget::resizeGL(int width, int height) {

    //set viewport
    glViewport(0,0,width,height);

    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();

    //set persepective
    //change the next line order to have a different perspective
    aspect_ratio=(GLdouble)width/(GLdouble)height;
    gluPerspective(45.0f, aspect_ratio, 0.1 , 100.0);

    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
}

2 个答案:

答案 0 :(得分:0)

虽然您没有明确指定它,但您可能正在渲染到后台缓冲区双缓冲窗口。因此,您应该通过调用glReadBuffer来设置对glReadPixels的调用,以设置从哪个缓冲区读取颜色。另外请记住,屏幕上的窗口需要进行像素所有权测试以及其他可能会影响您选择方法的事情。

答案 1 :(得分:-1)

我没有看到同花顺。这可能会导致空白屏幕,因为它正在加载以前的数据(通常是无意义的,因此是空白的)