вращение glm с масштабированием растянутого соотношения сторон - PullRequest
0 голосов
/ 05 августа 2020

Я пытаюсь повернуть изображение текстуры с помощью glm, но результат выглядит растянутым или не повернутым по оси z. Какое может быть возможное решение для этого.

enter image description here

float imgAspectRatio = imageWidth / (float) imageHeight;
float viewAspectRatio = viewWidth / (float) viewHeight;

if (imgAspectRatio > viewAspectRatio) {
    yScale = viewAspectRatio / imgAspectRatio;
} else {
    xScale = imgAspectRatio / viewAspectRatio;
}

glm::mat4 model(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(xScale, yScale, 1.0f));

введите описание изображения здесь Некоторые предлагали умножить на glm :: ortho, но с квадратной формой

glm::mat4 projection(1.0f);    
projection = glm::ortho(
              -imgAspectRatio,             
              imgAspectRatio,              
              -1.0f,      
              1.0f,       
              -1.0f,              
              1.0f                
      );

1 Ответ

0 голосов
/ 13 августа 2020

Код, который у вас есть в настоящее время, действительно работал бы, если бы у вас было квадратное окно.

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

  1. Масштабировать плоскость изображения по соотношению сторон изображения.
  2. Масштабировать все координаты xy в вашей сцене по соотношению сторон вида.
  3. Поворот плоскости изображения .
  4. Перевести плоскость изображения.

Однако вы действительно хотите масштабировать по соотношению сторон вида в самом конце. Простое упражнение, которое поможет понять, почему: представьте, что у вас есть идеально квадратное окно, в котором вы визуализируете треугольник с координатами xy (-1, -1), (1, -1), (0, 1). Теперь предположим, что ваше окно увеличилось вдвое по высоте, но вы хотите, чтобы форма оставалась прежней: очевидно, вы просто умножаете каждую координату y на 1/2. Теперь предположим, что вы хотите повернуть треугольник на 90 градусов против часовой стрелки, но опять же сохраните форму той же самой. Вы сначала поворачиваете, а затем масштабируете по соотношению сторон экрана? Или наоборот? Пройдя через оба варианта, становится ясно, что вам нужно масштабировать по соотношению сторон изображения в последнюю очередь.

Другими словами, вам нужен следующий порядок:

  1. Масштабировать плоскость изображения по соотношению сторон изображения.
  2. Повернуть плоскость изображения.
  3. Перевести плоскость изображения.
  4. Масштабировать все координаты 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, чтобы изменить это, если верно обратное.

...