Я ищу некоторое понимание небольшой проблемы с переводом юнитов в сетке.
Обновление и решено
Я решил свою проблему. Смотрите ниже для деталей. Все в этой части поста оказалось правильным. Во всяком случае, это может действовать как миниатюрное руководство / пример / помощь для следующего человека.
Настроить
- ФБО, ВАО, ВБО
- Окно 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 в пикселях на единицу мира. Во всяком случае, вот несколько быстрых изображений, чтобы помочь в решении проблемы.
Я решил наложить кучу спрайтов на то, что двигатель считает смещением в 64 раза.
Когда это казалось неуместным, я пошел и сделал базовый случай 1 единицы. Который, казалось, выстроился, как ожидалось Желтый цвет показывает разницу в 1px в движении.
Что я хочу
В идеале перемещение в любом направлении 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
Решения, которые я пытался
player.moveRight()
будет двигаться на 1 единицу с соотношением сторон в уравнении. Итак:gridWidth = 64 / 1.14f
. Движение не укладывалось в сетку.Принудительное окно 512x512 с соответствующей ортогональной проекцией.
Пробовал различные магические числа и пытался нарисовать корреляции между ними.
После всего сказанного мне остается только поверить в то, что я опровергаю свою фактическую проекцию. Итак, я ищу какие-либо сведения о том, как сохранить проекцию пиксель-в-единицу в пропорции 1: 1.