Несоответствие перевода орфографической единицы на сетке (например, 64 пикселя переводятся неправильно)

14

Я ищу некоторое понимание небольшой проблемы с переводом юнитов в сетке.

Обновление и решено

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

Настроить

  • ФБО, ВАО, ВБО
  • Окно 512x448
  • Сетка 64х64
  • gl_Position = projection * world * position;
  • projectionопределяется ortho(-w/2.0f, w/2.0f, -h/2.0f, h/2.0f);Это учебник ортогональной функции проекции.
  • world определяется фиксированной позицией камеры в (0, 0)
  • position определяется позицией спрайта.

проблема

На снимке экрана ниже (масштабирование 1: 1) интервал сетки равен 64x64, и я рисую единицу в (64, 64), однако единица рисует примерно ~ 10px в неправильной позиции. Я пробовал использовать одинаковые размеры окна, чтобы предотвратить искажение размера пикселя, но теперь я немного растерялся, предоставляя проекцию 1: 1 в пикселях на единицу мира. Во всяком случае, вот несколько быстрых изображений, чтобы помочь в решении проблемы.

64x64 Плитка на окне 512x448

Я решил наложить кучу спрайтов на то, что двигатель считает смещением в 64 раза.

64 смещения наложены

Когда это казалось неуместным, я пошел и сделал базовый случай 1 единицы. Который, казалось, выстроился, как ожидалось Желтый цвет показывает разницу в 1px в движении.

Базовый корпус 1 единицы

Что я хочу

В идеале перемещение в любом направлении 64-ю единицами выдает следующее (наложенные юниты):

Желаемый вывод

вершины

Казалось бы, вершины, входящие в вершинный шейдер, верны. Например, со ссылкой на первое изображение в VBO данные выглядят так:

      x    y           x    y
    ----------------------------    
tl | 0.0  24.0        64.0 24.0
bl | 0.0  0.0    ->   64.0 0.0
tr | 16.0 0.0         80.0 0.0
br | 16.0 24.0        80.0 24.0

Для полноты здесь приведен фактический массив, соответствующий приведенным выше движениям:

      x     y    z   w   r   g   b   a      s          t
-------------------------------------------------------------
tl | 0.0   23.0 0.0 1.0 0.0 0.0 0.0 1.0 0.14210527 0.62650603 
bl | 0.0   0.0  0.0 1.0 0.0 0.0 0.0 1.0 0.14210527 0.76506025 
tr | 16.0  0.0  0.0 1.0 0.0 0.0 0.0 1.0 0.2263158  0.76506025 
br | 16.0  23.0 0.0 1.0 0.0 0.0 0.0 1.0 0.2263158  0.62650603 
-------------------------------------------------------------
-------------------------------------------------------------
tl | 64.0  24.0 0.0 1.0 0.0 0.0 0.0 1.0 0.0        0.21084337 
bl | 64.0  0.0  0.0 1.0 0.0 0.0 0.0 1.0 0.0        0.3554217 
tr | 80.0  0.0  0.0 1.0 0.0 0.0 0.0 1.0 0.08421053 0.3554217 
br | 80.0  24.0 0.0 1.0 0.0 0.0 0.0 1.0 0.08421053 0.21084337

// side bar: I know that I have unnecessary data with having a z-axis.
//           The engine flips between perspective and orthogonal and I
//           haven't selectively started pruning data.

Проекционная матрица

Матрица проекции для окна 512x448 выглядит следующим образом:

0.00390625 0.0         0.0  0.0
0.0        0.004464286 0.0  0.0
0.0        0.0        -1.0  0.0
0.0        0.0         0.0  1.0

и построен с помощью функции ортогональной проекции учебника:

ortho(-w/2.0f, w/2.0f, -h/2.0f, h/2.0f);
// explicitly: ortho(-512/2.0f, 512/2.0f, -448/2.0f, 448.0f

ortho(float left, float right, float bottom, float top)
{
    projection.setIdentity();
    projection.m00 = 2.0f / (right - left);
    projection.m11 = 2.0f / (top - bottom);
    projection.m22 = -1;
    projection.m30 = -(right + left) / (right - left);
    projection.m31 = -(top + bottom) / (top - bottom);
    projection.m32 = 0;
}

Матрица мировоззрения

Положение камеры - это просто матрица перевода, которую в этом случае я просто сместил на -w / 2 и -h / 2, чтобы она была равна нулю относительно центра.

1.0 0.0 0.0 -256.0
0.0 1.0 0.0 -224.0
0.0 0.0 1.0 0.0
0.0 0.0 0.0 1.0

Решения, которые я пытался

  1. player.moveRight()будет двигаться на 1 единицу с соотношением сторон в уравнении. Итак: gridWidth = 64 / 1.14f. Движение не укладывалось в сетку.

  2. Принудительное окно 512x512 с соответствующей ортогональной проекцией.

  3. Пробовал различные магические числа и пытался нарисовать корреляции между ними.

После всего сказанного мне остается только поверить в то, что я опровергаю свою фактическую проекцию. Итак, я ищу какие-либо сведения о том, как сохранить проекцию пиксель-в-единицу в пропорции 1: 1.

Джастин Ван Хорн
источник
5
Хорошо продуманный вопрос, но, возможно, мы увидим ваши проекции и матрицы мира. Вы упомянули их выше, но не включили их содержимое. Проблема будет с одной из этих матриц.
Кен
@ Кен Нет проблем вообще. Я добавил свои проекции и матрицы мировоззрения. Я также включил желаемый результат и свои попытки решить проблему.
Джастин Ван Хорн
Ваши матрицы выглядят хорошо (я сравнил их с теми, которые производят glOrtho и glTranslate. Захватывает здесь соломинки, но opengl ожидает, что его матрицы расположены в порядке столбцов, вы делаете то же самое?
Кен
Хм, они хранятся в колонке-мажоре.
Джастин Ван Хорн

Ответы:

5

Я решил свою собственную проблему - и вместо простого объяснения, я хочу описать шаги, которые я предпринял для устранения проблемы. Я исключил, что я использовал один FBO для спецэффектов.

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

  • Я проверил свои ортогональные матрицы насквозь.
  • Проверено порядок байтов всего.
  • Создана квадратная текстура. <- Здесь магия
  • Когда я создал квадратную текстуру, я заметил, что это не квадрат на экране, а квадрат, идущий в вершинный шейдер.
  • Это была моя первая подсказка, что что-то не так. Размеры моих текстур на экране не совпадали с размерами вершинного шейдера.
  • Я забыл, что я использовал FBO (здесь идет глупость).
  • Размер текстуры FBO не соответствовал размеру моего окна просмотра по какой-то глупой причине.
  • Отключил FBO и результаты совпали.
  • Исправлена ​​логика с определением размера текстур и вау-лах.

Sillyness

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

Джастин Ван Хорн
источник