2015-08-13 2 views
0

Я пытаюсь нарисовать цилиндр в определенном направлении с помощью gluCylinder. Однако, чтобы указать направление, которое я использую gluLookAt, как и многие другие, я не уверен в отношении вектора «вверх» и, следовательно, не может заставить цилиндр указывать на правильное направление.Правильный gluLookAt для gluCylinder

Я прочитал от другого SO ответить, что

Интуиция за «вверх» вектор в gluLookAt прост: Посмотрите на что-нибудь. Теперь наклоните голову на 90 градусов. Там, где вы не изменились, направление, на которое вы смотрите, не изменилось, но изображение в сетчатке ясно. Какая разница? Там, где указана верхняя часть головы. Это вектор вверх.

Это простое объяснение, но в случае с моим цилиндром я чувствую, что вектор вверх абсолютно неважен. Так как цилиндр можно вращать вокруг своей оси и по-прежнему выглядеть одинаково, другой вектор вектора ничего не изменит. Таким образом, для моей проблемы должно быть бесконечно много действительных векторов до: все ортогональные к вектору от начальной точки до конечной точки.

Так это то, что я делаю:

  1. У меня есть мир координаты, где начальный и конечная точка цилиндра должна быть, A_world и B_world.

  2. Я проецировать их видовой экран координаты A_vp и B_vp с gluProject:

    GLdouble A_vp[3], B_vp[3], up[3], model[16], projection[16]; 
    GLint gl_viewport[4]; 
    glGetDoublev(GL_MODELVIEW_MATRIX, &model[0]); 
    glGetDoublev(GL_PROJECTION_MATRIX, &projection[0]); 
    glGetIntegerv(GL_VIEWPORT, gl_viewport); 
    
    gluProject(A_world[0], A_world[1], A_world[2], &model[0], &projection[0], &gl_viewport[0], &A_vp[0], &A_vp[1], &A_vp[2]); 
    
    gluProject(B_world[0], B_world[1], B_world[2], &model[0], &projection[0], &gl_viewport[0], &B_vp[0], &B_vp[1], &B_vp[2]); 
    
  3. Я называю glOrtho для сброса камеры в положение по умолчанию: Отрицательный г в картину, х вправо, у вверх:

    glMatrixMode(GL_PROJECTION); 
    glLoadIdentity(); 
    glOrtho(0, vp_edgelen, vp_edgelen, 0, 25, -25); 
    glMatrixMode(GL_MODELVIEW); 
    glLoadIdentity(); 
    
  4. перевожу скоординировать A_vp, вычислить вверх вектор как нормали к вектору A_vp — B_vp и указать вид с gluLookAt:

    glTranslatef(A_vp[0], gl_viewport[2] - A_vp[1], A_vp[2]); 
    glMatrixMode(GL_MODELVIEW); 
    
    GLdouble[] up = {A_vp[1] * B_vp[2] - A_vp[2] * B_vp[1], 
           A_vp[2] * B_vp[0] - A_vp[0] * B_vp[2], 
           A_vp[0] * B_vp[1] - A_vp[1] * B_vp[0]}; 
    
    gluLookAt(0, 0, 0, 
          B_vp[0], gl_viewport[2] - B_vp[1], B_vp[2], 
          up[0], up[1], up[2]); 
    
  5. рисую цилиндр с gluCylinder:

    GLUquadricObj *gluCylObj = gluNewQuadric(); 
    gluQuadricNormals(gluCylObj, GLU_SMOOTH); 
    gluQuadricOrientation(gluCylObj, GLU_OUTSIDE); 
    gluCylinder(gluCylObj, 10, 10, 50, 10, 10); 
    

Вот неожиданный результат:

enter image description here

Поскольку цилиндр начинается с правильного и так как я смог нарисовать круг в позиции B_vp, единственное, что должно быть неправильно, это «вверх» вектор в gluLookAt, правильно?

+0

Какая у вас система? Есть ли веская причина использовать старый OpenGL? Посмотрите на новый, например. в учебнике [this] (http://open.gl). – DanceIgel

+0

Можете ли вы разместить дополнительную информацию о контексте рендеринга? Например. как вы передаете другой материал? Проводить его в псевдокоде будет достаточно. – DanceIgel

+0

Хорошо, я думаю, у меня есть твоя ошибка. В настоящее время вы создаете вектор вверх, который указывает на экран, но то, что вы хотите, - это вектор вверх от 'A_vp' до' B_vp'. Таким образом, вам просто нужно изменить кросс-продукт с разницей 'B_vp - A_vp' – DanceIgel

ответ

0

gluLookAt() не требуется для достижения надлежащей перспективы. Достаточно повернуть текущий z-вектор, чтобы указать направление, на которое указывает цилиндр.