Невідповідність перекладу ортографічної одиниці в сітці (наприклад, 64 пікселів перекладається неправильно)


14

Я шукаю деяке розуміння невеликої проблеми з перекладом одиниць у сітці.

Оновлення та вирішення

Я вирішив власне питання. Детальніше дивіться нижче. Все в цій частині допису виявилося правильним. Якщо що-небудь, це може послужити мініатюрним підручником / прикладом / допомогою для наступної людини.

Налаштування

  • FBO, VAO, VBO
  • Вікно 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) інтервал між сітками становить 64х64, і я малюю пристрій у (64, 64), однак блок малює приблизно в 10 пікс в неправильному положенні. Я спробував рівномірні розміри вікон, щоб запобігти будь-яке спотворення розміру пікселів, але тепер я трохи втратив належним чином, забезпечуючи проекцію 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
Добре побудоване запитання, але, можливо, ми могли б побачити ваші матриці проекції та світу Ви згадали їх вище, але не включили їх вміст. Проблема буде з однією з цих матриць.
Кен

@Ken Взагалі немає проблем. Я додав свої матриці проекції та світового простору. Я також включив бажаний результат та власні спроби вирішення проблеми.
Джастін Ван Хорн

Ви матриці виглядаєте добре (я порівнював їх із тими, які виробляє glOrtho та glTranslate. Схопившись на соломках тут, але opengl очікує, що її матриці будуть розташовані в порядку основного стовпця, ви робите те саме?
Кен

Гм, вони зберігаються в стовпчику головного порядку.
Джастін Ван Хорн

Відповіді:


5

Я вирішив власну проблему - і замість того, щоб просто зняти її як просте пояснення, я хочу описати кроки, які я вжив для налагодження проблеми. Я не залишив уваги, що використовував єдине FBO для спецефектів.

По-перше, виявляється, що все вище є насправді правильним, і крок, який я залишив, був проблемою.

  • Я перевірив свої ортогональні матриці наскрізь.
  • Перевірено порядок байтів всього.
  • Створено квадратну текстуру. <- Ось магія
  • Коли я створив квадратну текстуру, я помітив, що це не квадрат на екрані, а квадрат, що йде у вершину шейдера.
  • Це була моя перша підказка, що щось не так. Розміри моїх текстур на екрані не відповідали розмірам, які йшли до вершинного шейдера.
  • Я забув, що я користувався ФБО (тут приходить дурість).
  • Розмір текстури FBO з будь-якої дурної причини не відповідав розміру текстури мого огляду.
  • Відключив FBO, і результати збігалися.
  • Виправлена ​​логіка із визначенням розміру моєї текстури та wah-lah.

Дурість

Мені шкода, якщо це зайняло чийсь час. Я залишу питання навколо як гарний захід для тих, хто може зіткнутися з тією ж проблемою, не знаючи про це.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.