Действительно ли glm::ortho() неверен?

Недавно я подумал, что было бы неплохо отказаться от старых (устаревших) функций, предоставляемых OpenGL, таких как матричные операции и фиксированный конвейер функций.

Я использую GLM в качестве библиотеки матриц, чтобы немного упростить ситуацию. Проблема в том, что это, возможно, вызвало больше проблем, чем упростило...

Перспективные проекции отлично работали с моими шейдерами и настройками, но когда я попытался переключиться на ортогональные, все сломалось. Мои очки и простые квадраты не отображались. Когда я использовал старые матрицы OpenGL, все снова заработало.

Я сузил все это до проекционной матрицы. Вот как я это назвал:

glm::mat4 projMat = glm::ortho( 0, 400, 0, 400, -1, 1 );

Я сравнил это с тем, что поставляется opengl, как только это называется"

glOrtho( 0, 400, 0, 400, -1, 1 );

Единственным отличием являются элементы [0][0] и [1][1] (которые, насколько мне известно, равны «2/ширине» и «2/высоте» соответственно). Из матрицы OpenGL значения были именно такими! Однако в матрице glm значения были равны 0.

Как только я вручную переключил значения из матрицы glm после вызова glm::ortho, все снова заработало!

Итак, мой вопрос: действительно ли функция glm::ortho() не работает, или я просто неправильно ее использую?


person Jamie Syme    schedule 01.09.2012    source источник


Ответы (1)


Не похоже, что он должен быть сломан из исходного кода (v 0.9.3.4)

template <typename valType> 
GLM_FUNC_QUALIFIER detail::tmat4x4<valType> ortho
(
    valType const & left, 
    valType const & right, 
    valType const & bottom, 
    valType const & top, 
    valType const & zNear, 
    valType const & zFar
)
{
    detail::tmat4x4<valType> Result(1);
    Result[0][0] = valType(2) / (right - left);
    Result[1][1] = valType(2) / (top - bottom);
    Result[2][2] = - valType(2) / (zFar - zNear);
    Result[3][0] = - (right + left) / (right - left);
    Result[3][1] = - (top + bottom) / (top - bottom);
    Result[3][2] = - (zFar + zNear) / (zFar - zNear);
    return Result;
}

Моя единственная мысль заключается в том, что этот шаблон может создавать матрицу целых чисел (поскольку вы передали все целые числа в функцию) и, таким образом, выполнять целочисленное деление вместо с плавающей запятой. Можете ли вы попробовать добавить .f ко всем вашим параметрам?

glm::mat4 projMat = glm::ortho( 0.f, 400.f, 0.f, 400.f, -1.f, 1.f );

person Tim    schedule 01.09.2012
comment
Вау, ты попал в точку! После изменения моих параметров на float все заработало. Спасибо, что прояснили это :) - person Jamie Syme; 01.09.2012
comment
Вместо добавления .f вы также можете явно указать искомый шаблон: glm::ortho<float>(...). Я думаю, что это также сработает только с одним аргументом, сделанным явным плавающим числом. - person Fund Monica's Lawsuit; 26.05.2018
comment
FWIW для будущих читателей, убедитесь, что ваши zNear < 0.0f и zFar > 0.0f. При переключении с орто на перспективу glm вызывает glm::radians(fov) для своего параметра, а вы переключаете zNear > 0.0f и zFar > zNear. Ваш параметр соотношения сторон может быть отключен также из-за того, что окончательный результат не является плавающим. Кроме того, OpenGL использует прототипы glm::orthoLH и glm::perspectiveLH, которые установлены по умолчанию. - person user2262111; 07.02.2019