Код, который у вас есть в настоящее время, действительно работал бы, если бы у вас было квадратное окно.
Объединив масштабирование соотношения сторон изображения и масштабирование соотношения сторон вида в один шаг, порядок операций, которые у вас есть в настоящее время по существу выглядит следующим образом:
- Масштабировать плоскость изображения по соотношению сторон изображения.
- Масштабировать все координаты xy в вашей сцене по соотношению сторон вида.
- Поворот плоскости изображения .
- Перевести плоскость изображения.
Однако вы действительно хотите масштабировать по соотношению сторон вида в самом конце. Простое упражнение, которое поможет понять, почему: представьте, что у вас есть идеально квадратное окно, в котором вы визуализируете треугольник с координатами xy (-1, -1), (1, -1), (0, 1). Теперь предположим, что ваше окно увеличилось вдвое по высоте, но вы хотите, чтобы форма оставалась прежней: очевидно, вы просто умножаете каждую координату y на 1/2. Теперь предположим, что вы хотите повернуть треугольник на 90 градусов против часовой стрелки, но опять же сохраните форму той же самой. Вы сначала поворачиваете, а затем масштабируете по соотношению сторон экрана? Или наоборот? Пройдя через оба варианта, становится ясно, что вам нужно масштабировать по соотношению сторон изображения в последнюю очередь.
Другими словами, вам нужен следующий порядок:
- Масштабировать плоскость изображения по соотношению сторон изображения.
- Повернуть плоскость изображения.
- Перевести плоскость изображения.
- Масштабировать все координаты xy в вашей сцене по соотношению сторон изображения.
Это достигается с помощью кода, который выглядит примерно так:
float xScaleImg = 1.0f;
float yScaleImg = xScaleImg / imgAspectRatio;
float xScaleView = 1.0f;
float yScaleView = viewAspectRatio;
glm::mat4 model(1.0f);
model = glm::scale(glm::mat4(1.0f), glm::vec3(xScaleView, yScaleView, 1.0f));
model = glm::translate(model, glm::vec3(0, 0, 0));
model = glm::rotate(model, glm::radians(angle), glm::vec3(0, 0, 1));
model = glm::scale(model, glm::vec3(xScaleImg, yScaleImg, 1.0f));
Первые четыре строки предполагают, как и в случае в вашем примере, что ширина вида и изображения больше, чем соответствующая высота . Вы, вероятно, захотите добавить лог c, чтобы изменить это, если верно обратное.