не видя, что вы делаете в Вершинный шейдер мы можем только догадываться.Однако Вы можете использовать те же матрицы в новом OpenGL, что и в старом.Единственная матрица, которой у вас, вероятно, нет, - gluPerspective
, так что вы можете реализовать ее самостоятельно (если у вас больше нет glu.h).Я делаю это так:
void glPerspective(double fovy,double aspect,double zNear,double zFar)
{
double per[16],f;
for (int i=0;i<16;i++) per[i]=0.0;
// original gluProjection
// f=divide(1.0,tan(0.5*fovy*deg))
// per[ 0]=f/aspect;
// per[ 5]=f;
// corrected gluProjection
f=divide(1.0,tan(0.5*fovy*deg*aspect));
per[ 0]=f;
per[ 5]=f*aspect;
// z range
per[10]=divide(zFar+zNear,zNear-zFar);
per[11]=-1.0;
per[14]=divide(2.0*zFar*zNear,zNear-zFar);
glLoadMatrixd(per);
// zNear=divide(-per[11],per[10]); // get znear from perspective projection matrix
}
Это более или менее имитирует gluPerspective
, но оно исправило неточный tan
, что вызывало проблемы при объединении нескольких фрустримов вместе.В закомментированных строках показано, как вычислить исходный gluPerspective
(также с tan
восстановленным), а в последнем комментарии показано, как получить znear
из матрицы (для трассировщиков лучей)
Грубого вместо glLoadMatrixd(per);
васиспользуйте per
, как вам нужно ... (например, отправьте как uniform
)
Теперь, чтобы реализовать lookat, вы просто создаете матрицу самостоятельно.См .:
Таким образом, вы просто вычисляете векторы X,Y,Z
и O
исходную позицию
Z = -forward
X = +right
Y = +up
O = +camera_position - znear
и подайте их в вашу матрицу в нужных местах ...
Теперь, если ваша lookat
- это позиция целевого объекта, чем
Z = normalize(camera_position-lookat)
Y = up
X = cross(Y,Z)
Не уверен, если X
должно быть + или - просто попробуйте, и если сцена зеркальная, отмените ее.