2009-11-19 2 views
3

Я пытаюсь создать 3D-робот, который должен выполнять определенные действия при нажатии некоторых частей тела. Я успешно (вроде) реализовал выбор, потому что если вы нажмете на любую часть x-plane, он зарегистрирует хит, но не где-нибудь еще. То есть он не регистрирует глубину, и если вы нажмете на нее квадратную головку, вы можете зарегистрировать только удар, щелкнув по передней части головы (лицом к вам). Очевидно, что я не совсем понимаю выбор и выбор, и я небрежно пытаюсь расшифровать то, что я знаю о 2D-выборке в 3D (мой учитель так же полезен, как камень), но я что-то оставил или не изменил что-то, относящееся к глубине. Может кто-нибудь мне помочь? Вот связанные функции.OpenGL 3D Selection

void processHits (GLint hits, GLuint buffer[]) 
{ 
    unsigned int i, j; 
    GLint n, *ptr; 

    printf ("hits = %d\n", hits); 
    ptr = (GLint *) buffer; 

    //For each hit. 
    for (i = 0; i < hits; i++) 
    { 
     n = *ptr;  //Number of names under current hit. 
     ptr+=3;   //Bypass three integers: n, z1, z2. 
     printf ("hit %d has %d name(s)\n", i, n); 

     //For each name. 
     for (j = 0; j < n; j++) 
     { 
      if(*ptr==1) printf ("Body hit.\n"); 
      else if(*ptr==2) printf ("Right shoulder hit.\n"); 
      else if(*ptr==3) printf ("Left shoulder hit.\n"); 
      else if(*ptr==4) printf ("Left arm hit.\n"); 
      else if(*ptr==5) printf ("Right arm hit.\n"); 
      else if(*ptr==6) printf ("Left leg hit.\n"); 
      else if(*ptr==7) printf ("Right leg hit.\n"); 
      else if(*ptr==8) printf ("Right foot hit.\n"); 
      else if(*ptr==9) printf ("Left foot hit.\n"); 
      else if(*ptr==10) printf ("Neck hit.\n"); 
      else if(*ptr==11) printf ("Head hit.\n"); 
      else printf ("Nothing hit.\n"); 

      ptr++; 
     } 
     printf ("\n"); 
    } 
} 

void selection(int mouse_x, int mouse_y) 
{ 
    GLuint buffer[512];      //Set up a selection buffer. 
    GLint hits;        //The number of objects we selected. 
    GLint viewport[4];      //Viewport size. [0] Is <x>, [1] Is <y>, [2] Is <length>, [3] Is <width>. 

    glGetIntegerv(GL_VIEWPORT, viewport); //Sets the array <viewport> to size and location of screen relative to window. 
    glSelectBuffer(512, buffer);   //Tell OpenGL to use our array for selection. 

    glRenderMode(GL_SELECT);    //Puts OpenGL in selection mode. Nothing will be drawn. Object IDs and extents stored in buffer. 

    glInitNames();       //Initializes name stack. 
    glPushName(0);       //Push an entry onto the stack. 

    glMatrixMode(GL_PROJECTION);   //Selects the projection matrix. 
    glPushMatrix();       //Push the projection matrix. 
    glLoadIdentity();      //Resets matrix. 

    //This creates a matrix that will zoom up to a small portion of the screen, where the mouse is. 
    gluPickMatrix((GLdouble) mouse_x, (GLdouble) (viewport[3]-mouse_y), 0.01, 0.01, viewport); 

    gluPerspective(45.0f, (GLfloat) (viewport[2]-viewport[0])/(GLfloat) (viewport[3]-viewport[1]), 0.1f, 100.0f); 
    glMatrixMode(GL_MODELVIEW);         //Select the modelview matrix. 
    drawObjects(GL_SELECT);          //Render the targets to the selection buffer. 
    glMatrixMode(GL_PROJECTION);        //Select the projection matrix. 
    glPopMatrix();            //Pop the projection matrix. 
    glMatrixMode(GL_MODELVIEW);         //Select the modelview matrix. 
    hits = glRenderMode(GL_RENDER); 
    processHits (hits, buffer); 

    //printf("%d ", hits); 

    //Post redisplay message. 
    glutPostRedisplay(); 
} 

void mouse(int button, int state, int x, int y) 
{  
    if (button == GLUT_LEFT_BUTTON && state == GLUT_DOWN) 
    { 
     selection(x, y); 
    } 
} 
+0

Что вы имеете в виду, что можете зарегистрировать только клик на части головы роботов, которая стоит перед вами? Как бы вы нажмете на то, что не обращено к вам (т. Е. Не было бы скрыто). – Jherico

+2

+1 для хорошего смеха в 1 утром: «мой учитель так же полезен, как камень» – Ricket

ответ

1

Это не совсем ясно, что вы просите. Если вы имеете в виду, что вы получаете только хит-запись для объекта, который является самым большим фронтом, то это отчасти ожидается. Полигон (ы), которые отбираются, не будет генерировать записи (записи) ударов. Если вы хотите записать записи для полигонов, которые обычно будут отбракованы, вы будете использовать glDisable(GL_CULL_FACE);, пока вы рисуете в режиме выбора. Это предотвращает отбор полигонов, поэтому они могут создавать записи о хитах.

0

Подробнее об объекте Выбор с использованием заднего буфера here. Я реализовал его один раз, и он отлично поработал.

 Смежные вопросы

  • Нет связанных вопросов^_^