Невідповідність перекладу ортографічної одиниці в сітці (наприклад, 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.