Я пытаюсь нарисовать цилиндр в определенном направлении с помощью gluCylinder
. Однако, чтобы указать направление, которое я использую gluLookAt
, как и многие другие, я не уверен в отношении вектора «вверх» и, следовательно, не может заставить цилиндр указывать на правильное направление.Правильный gluLookAt для gluCylinder
Я прочитал от другого SO ответить, что
Интуиция за «вверх» вектор в gluLookAt прост: Посмотрите на что-нибудь. Теперь наклоните голову на 90 градусов. Там, где вы не изменились, направление, на которое вы смотрите, не изменилось, но изображение в сетчатке ясно. Какая разница? Там, где указана верхняя часть головы. Это вектор вверх.
Это простое объяснение, но в случае с моим цилиндром я чувствую, что вектор вверх абсолютно неважен. Так как цилиндр можно вращать вокруг своей оси и по-прежнему выглядеть одинаково, другой вектор вектора ничего не изменит. Таким образом, для моей проблемы должно быть бесконечно много действительных векторов до: все ортогональные к вектору от начальной точки до конечной точки.
Так это то, что я делаю:
У меня есть мир координаты, где начальный и конечная точка цилиндра должна быть,
A_world
иB_world
.Я проецировать их видовой экран координаты
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]);
Я называю
glOrtho
для сброса камеры в положение по умолчанию: Отрицательный г в картину, х вправо, у вверх:glMatrixMode(GL_PROJECTION); glLoadIdentity(); glOrtho(0, vp_edgelen, vp_edgelen, 0, 25, -25); glMatrixMode(GL_MODELVIEW); glLoadIdentity();
перевожу скоординировать
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]);
рисую цилиндр с
gluCylinder
:GLUquadricObj *gluCylObj = gluNewQuadric(); gluQuadricNormals(gluCylObj, GLU_SMOOTH); gluQuadricOrientation(gluCylObj, GLU_OUTSIDE); gluCylinder(gluCylObj, 10, 10, 50, 10, 10);
Вот неожиданный результат:
Поскольку цилиндр начинается с правильного и так как я смог нарисовать круг в позиции B_vp, единственное, что должно быть неправильно, это «вверх» вектор в gluLookAt
, правильно?
Какая у вас система? Есть ли веская причина использовать старый OpenGL? Посмотрите на новый, например. в учебнике [this] (http://open.gl). – DanceIgel
Можете ли вы разместить дополнительную информацию о контексте рендеринга? Например. как вы передаете другой материал? Проводить его в псевдокоде будет достаточно. – DanceIgel
Хорошо, я думаю, у меня есть твоя ошибка. В настоящее время вы создаете вектор вверх, который указывает на экран, но то, что вы хотите, - это вектор вверх от 'A_vp' до' B_vp'. Таким образом, вам просто нужно изменить кросс-продукт с разницей 'B_vp - A_vp' – DanceIgel