2015-06-23 4 views
0

Я пытаюсь сделать выбор в opengl, но он не работает. Я рисую объекты, которые я получаю от файла .obj (v, vn, f, o и таких индексов). Каждый объект состоит из «групп», и каждая группа представляет собой группу GL_POLYGON. Вот функция Жеребьевка:Выбор в OpenGL с использованием glRenderMode (GL_SELECT) и glReadPixels

void draw(GLenum mode) { 
    glBegin(GL_LINES); 
    glColor3f(1, 0, 0); 
    glVertex3f(0.0, 0.0, 0.0); 
    glVertex3f(100.0, 0.0, 0.0); 

    glColor3f(0, 0, 1); 
    glVertex3f(0.0, 0.0, 0.0); 
    glVertex3f(0.0, 100.0, 0.0); 

    glColor3f(0, 1, 0); 
    glVertex3f(0.0, 0.0, 0.0); 
    glVertex3f(0.0, 0.0, 100.0); 
    glEnd(); 

    glColor4f(1.0, 1.0, 1.0, 1.0); 

    if (changeFOV) { 
     fovAngle += fovScale; 
     changeFOV = false; 
     setTransformations(); 
    } 
    for (unsigned int i = 0; i < objects.size(); i++) { 
     objectItem currObject = objects[i]; 
     for (unsigned int j = 0; j < currObject.getGroups().size(); j++) { 
      group currGroup = currObject.getGroups().at(j); 
      for (unsigned int k = 0; k < currGroup.getFs().size(); k++) { 
       if (mode == GL_SELECT) 
        glPushName(currGroup.getName()); 
       glPushMatrix(); 
       vector<pair<int, int> > currF = currGroup.getFs()[k]; 
       glBegin(GL_POLYGON); 
       for (unsigned int kk = 0; kk < currF.size(); kk++) { 
        Vector3f currVertex = vertexes.at(
          (currF.at(kk).first - 1 >= 0) ? 
            currF.at(kk).first - 1 : 0); 

        Vector3f currNormal = vertexesNormal.at(
          (currF.at(kk).second - 1 >= 0) ? 
            currF.at(kk).second - 1 : 0); 

        glNormal3f(currNormal.x, currNormal.y, currNormal.z); 
        glVertex3f(currVertex.x/1, currVertex.y/1, 
          currVertex.z/1); 
       } 
       glEnd(); 
       glPopMatrix(); 
      } 
     } 
    } 
} 

Розыгрыш работает нормально, и я вижу объект на экране.

Это все в порядке, собирание

/*  PICKING  */ 
void processHits(GLint hits, GLuint *buffer) { 
    float z1, z2; 
    for (int i = 0; buffer[i] > 0; i += 5) { 
     z1 = buffer[i + 1]/4294967295.0; 
     z2 = buffer[i + 2]/4294967295.0; 
     printf("z1 = %f ,z2 = %f zValue = %f\n", z1, z2, zValue[0]); 
     if ((zValue[0] <= z1 + 0.0001 && zValue[0] >= z2 - 0.0001) 
       || (zValue[0] >= z1 - 0.0001 && zValue[0] <= z2 + 0.0001)) { //try to locate which name is correlated with the pressed pixel according to z value 
      ii = buffer[i + 3]; 
      jj = buffer[i + 4]; 
     } 

    } 
} 

void startPicking(GLuint *selectionBuf) { 
    glSelectBuffer(bufSize, selectionBuf); //declare buffer for input in selection mode 
    glRenderMode(GL_SELECT); //change to selecting mode 
    glInitNames();   //initialize names stack 
    glPushName(-1);   //push name 
} 

void pick(int button, int x, int y) { 
    //use selection mode to pick 
    glReadPixels(x, viewport[3] - y, 1, 1, GL_RGBA, GL_FLOAT, pix); 
    //printf("depth = %f, x = %d, y = %d\n",pixels[(viewport[3]-y)*512+x],x,viewport[3]-y); 
    glMatrixMode(GL_PROJECTION); 
    glReadPixels((GLdouble) x, (GLdouble) viewport[3] - y, 2, 2, 
      GL_DEPTH_COMPONENT, GL_FLOAT, zValue); 
    glPushMatrix(); //saves current projection matrix 
    startPicking(selectionBuf); //preper selection mode 
    glLoadIdentity(); 
    gluPickMatrix((GLdouble) x, (GLdouble) viewport[3] - y, 1, 1, viewport); //change matrices so only the area of the picking pixel can be seen. 
    gluPerspective(fovAngle, 1, near, far); //return to perspective state 
    glMatrixMode(GL_MODELVIEW); 
    draw(GL_SELECT); //draws board on background 
    hits = glRenderMode(GL_RENDER); //gets hits number 
    glMatrixMode(GL_PROJECTION); 
    glPopMatrix(); //restores projection matrix 
    glMatrixMode(GL_MODELVIEW); 
    processHits(hits, selectionBuf); //check hits 
    if(hits > 0) 
     printf("touched: %d\n",selectionBuf[3]); 
    //printf("depth %f hits: %d\n\n",pixels[(viewport[3]-y)*512+x], hits); 
    if (zValue[0] < 1.0) { 
     isPick = true; 
     xx = x; 
     yy = y; 
     if (button == GLUT_RIGHT_BUTTON) 
      zMove = true; 
     else 
      zMove = false; 
    } 
} 

функция pick вызывается при щелчке мышью (с использованием OpenGL функции мыши). Ошибка, которую я получаю, заключается в том, что ни один объект не попадает при нажатии на объект.

Я использую Ubuntu 14.04 LTS с OpenGL 3.0

Я не знаю, как спросить или что конкретно спросить, я был бы признателен за несколько входов на коде, если вы видите что-то неправильно ..

+0

Можете ли вы ввести введение в свой метод комплектования? Как это должно работать, а какая часть терпит неудачу? – jozxyqk

+0

Я добавил, скажите, если вы хотите, чтобы я добавил что-то еще @jozxyqk – Javi

ответ

0

Вы, похоже, пропустили использование glPopName()

GLNames, используемые в буфере выбора, помещаются в стек. Поэтому, если вы не вызываете glPopName(), стек никогда не будет расслабляться. Работа с ним аналогична вызовам glPushMatrix() и glPopMatrix().

Как правило, это выглядит как поток кода.

//Push the name of the primitives on top of selection stack 
glPushName(...) 
    //Set Transformations/Draw the primitives 
    .. 
    .. 
//Pop the name (Clear the stack for pushing another name) 
glPopName();