Как реализовать FPS камеру без GLU на OSX (или кроссплатформенной) c ++ - PullRequest
1 голос
/ 05 апреля 2011

Я пытаюсь заставить работать камеру в стиле FPS, следуя примерам, приведенным в книге OpenGL SuperBible.

Все шло очень хорошо, пока я не столкнулся с проблемой, когда у вас в конечном итоге возниклабросок случается, когда вам действительно нужны только тангаж и рыскание.

Подобный вопрос

Этот вопрос в основном задает то же самое, но я надеялся, что кто-то сможетбыть немного более подробным о реализации, в идеале с опытом инфраструктуры SuperBible GLTools.

Я уже пытался реализовать код GluLookAt , который мне нужно скомпилировать, но я либо сделалошибка при дублировании необходимых функций, или я передаю неверные параметры при его использовании.

Я думаю, я нахожу это немного запутанным, так как код SuperBible немного абстрагирует работу камеры,и поэтому мне трудно реализовать это правильно.При тестировании моей текущей версии я передаю параметры, подобные этому

M3DMatrix44f mCamera;
cameraFrame.GetCameraMatrix(mCamera);   //returns the matrix of the CameraFrame.

M3DVector3f up =   { 0.0f, 1.0f, 0.0f };    
M3DVector3f look = { xHeading,yHeading,0.0f }; 

//xHeading & yHeading ranges from -1 to 1 based on mouse movement, is this correct?

Как мне управлять и передавать переменные вида?В настоящее время кажется, что значение внешнего вида остается на том же месте, и поэтому, если я двигаюсь назад, я в конечном итоге поворачиваюсь вокруг сцены.

glhLookAtf2(mCamera, mCamera, look, up);

Я чувствую, что должен лучше управлять направлением моего взгляда,и, возможно, мое местоположение камеры также.Кажется странным, что позиция взгляда не меняется.

Может кто-нибудь помочь или направить меня в направлении твердого учебного курса?Я стараюсь не делать что-то осуждаемое, но в этот момент я был бы очень рад просто заставить что-то работать.

Ответы [ 2 ]

0 голосов
/ 05 июня 2011

Спасибо за ответы на все, но у меня была проблема. В супербибле openGL я использовал их встроенный эталонный класс, и у меня была проблема с двумя функциями, одна из которых называлась rotate и rotateWorld.

Мне нужно было использовать вращение для движения вверх / вниз и rotateWorld для движения влево-вправо. Это заставило камеру вести себя правильно (летать камерой).

Это имеет смысл, поскольку независимо от того, куда вы смотрите вверх / вниз, вы хотите, чтобы весь мир всегда вращался вокруг вертикальной оси. Уф!

0 голосов
/ 05 апреля 2011

Это простая задача.Для работы с камерой вам нужно всего 3 вектора: положение, относительный LookAt и относительный вектор Up

После того, как вы настроите эти 3, вы можете задать их для gluLookAt следующим образом:

gluLookAt(camera.eye.x,camera.eye.y,camera.eye.z,
        camera.lookAt.x,camera.lookAt.y,camera.lookAt.z,
        camera.up.x,camera.up.y,camera.up.z);

don 'Не запутайтесь, camera.look - это реалистичный LookAt, добавленный с вектором глаза:

camera.lookAt = camera.eye + camera.rLookAt;

Так что это должно в основном охватывать настройку камеры.Следующее основное задание с камерой движется.Это благодаря относительной простой задаче LookAt, так как вы обновляете только глазной вектор.Возможно, вы захотите обновить также абсолютный LookAt, но это тот же фрагмент кода, который я показал выше.

Наконец, вы захотите повернуть представление.Хитрость в том, что вы можете использовать 3 интерпретации - матрицы, 3 угла или кватернины.Поскольку углы легко понять (с другой стороны, они имеют худшую производительность и страдают от блокировки карданного подвеса), я покажу вам, как это сделать.Я не буду описывать, что такое блокировка карданного подвеса, вы можете использовать Google, но чтобы избежать этого, нам нужно ограничить число поворотов.Мы будем использовать полные 360 ° для горизонтального, но только 180 ° для вертикального вращения.Если вы посмотрите на систему координации openGl, мы можем определить горизонтальные повороты вокруг оси Y и вертикальной оси X вокруг оси.Для вращения вектора в приложении мы используем следующие 2 кода:

vector3f vector3f::rotateX(const float &radians)
{
    float t_y = y;

    y = t_y*cos(radians) + z*sin(radians);
    z = t_y*-sin(radians) + z*cos(radians);
    return *this;
}

vector3f vector3f::rotateY(const float &radians)
{
    float t_x = x;

    x = t_x*cos(radians) + z*-sin(radians);
    z = t_x*sin(radians) + z*cos(radians);
    return *this;
}

Вы можете видеть, что я скопировал это из моего кода.vector3f - это просто класс, заключающий в себе все о трехмерных векторах.x, y и z являются открытыми членами, определяющими вектор.

Так что если вы хотите, чтобы высота тона была в основном rotateX и yaw rotateY.Для обновления вашей камеры вам нужно повернуть оба относительных вектора LookAt и Up, вычислить абсолютный LookAt и передать их в gluLookAt.Вот и все ..

PS: Не правда, что мало кто программирует opengl на OSX.Я никогда не запускал OSX, но openGl, как кроссплатформенный, определенно по-прежнему популярен.

PSS: я забыл упомянуть, никогда не добавляю ротации.Лучше добавлять углы, и каждый раз, когда вы поворачиваете установленные векторы в положение по умолчанию и вращаетесь с этим абсолютным углом:

rLookAt.set(0,0,-1);
rLookAt.rotateX(rotations.x);
rLookAt.rotateY(rotations.y);
lookAt = eye + rLookAt;

up.set(0,1,0);
up.rotateX(rotations.x);
up.rotateY(rotations.y);
...