Як я можу запобігти розтягуванню / викривленню вікна перегляду?


13

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

Наступні зображення ілюструють спотворення / розтягнення, про які я говорю:

Оригінальне зображення (квадратне вікно)

Без спотворень

Спотворене / розтягнуте зображення (прямокутне вікно)

З викривленням

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

Як це можна зробити?

Я працюю з OpenGL для відтворення зображення, і я використовую перспективну проекцію за допомогою дзвінків:

glMatrixMode(GL_PROJECTION)
glLoadIdentity()
gluPerspective(60, window.width/window.height, 0.01f, 100.0f)

Співвідношення сторін width/heightвідповідає усім документам / навчальним посібникам, які я зіткнувся, тому не очікую, що воно буде невірним. Однак я підозрюю, що це зачіпає проблему розтягування.


Після роздумів

Чесно кажучи, якщо я більше думаю над цим питанням, я змусив вважати, що рішення передбачає прямо пропорційну залежність між кутом зору (поле зору у напрямку Y) та співвідношенням сторін.

Перспективна проекція

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

Так само зменшення ширини вимагає зменшення кутового кута.

Оновлення:

Тож, вивчивши це далі, я вирішив змінити спосіб, яким я встановив перегляд фрустуму так:

gluPerspective(60 * (float)window.width/window.height, (float)window.width/window.height, 0.01f, 100.0f)

І мої сподівання були правильними, що вирішило питання пропорційності. Однак, це не досягає бажаних результатів. Коли ширина вікна збільшується, відтворене зображення стає меншим (але сфера дійсно кругла). Натомість сфера взагалі не повинна змінювати розмір; має змінюватися лише кількість сцени, що відображається.

Відповіді:


14

Насправді оригінальне питання - це 1 відкинутий від рішення.

Оригінальний код

glMatrixMode(GL_PROJECTION)
glLoadIdentity()
gluPerspective(60, window.width/window.height, 0.01f, 100.0f)

Фіксований код

glMatrixMode(GL_PROJECTION)
glLoadIdentity()
gluPerspective(60, (float)window.width/window.height, 0.01f, 100.0f)

Проблема полягала в тому, що window.widthі window.heightцілих числа, які викликали коефіцієнт пропорційності , щоб бути результатом цілочисельного ділення.

Передача одного з розмірів поплавцю призводить до того, що в результаті замість цього використовується поділ з плаваючою комою.

Оскільки співвідношення сторін зараз правильне, розтягування більше немає, як це було показано в оригінальній публікації.

EDIT: Код у вихідному дописі (і відповідь) є просто псевдокодом для дзвінків до GPU; фактична програма, яка використовується для виведення зображень вище, написана на Java. Для тих, хто не працює з Java, я не досліджував, чи реалізується поділ на цілі числа / з плаваючою комою таким же чином. Незважаючи на це, рішення полягає в тому, щоб переконатися, що співвідношення сторін дійсно правильно обчислено.

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