ฉันจะป้องกัน viewport ไม่ให้ยืด / บิดเบี้ยวได้อย่างไร


13

โดยทั่วไปฉันต้องการทราบว่าฉันสามารถลบความบิดเบี้ยวหรือการยืดภาพที่แสดงเมื่อขนาดวิวพอร์ต / หน้าต่างเปลี่ยนไปอย่างไร

ภาพต่อไปนี้แสดงให้เห็นถึงการบิดเบือน / การยืดที่ฉันกำลังพูดถึง:

รูปภาพต้นฉบับ (หน้าต่างสี่เหลี่ยม)

ไม่มีการบิดเบือน

ภาพบิดเบี้ยว / ยืดออก (หน้าต่างรูปสี่เหลี่ยมผืนผ้า)

ด้วยการบิดเบือน

ตามหลักการแล้วภาพที่สองควรแสดงทรงกลมโดยไม่ต้องยืดออกในแนวนอนและจะทำให้ฉากกับผู้ใช้มากขึ้นเพื่ออธิบายขนาดหน้าต่างที่ใหญ่ขึ้น

สิ่งนี้สามารถทำได้?

ฉันทำงานกับ OpenGL เพื่อแสดงภาพและฉันใช้ประโยชน์จากการคาดการณ์มุมมองผ่านการโทร:

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

อัตราส่วนภาพwidth/heightเป็นไปตามเอกสาร / บทช่วยสอนทั้งหมดที่ฉันพบดังนั้นฉันไม่คาดหวังว่ามันจะไม่ถูกต้อง อย่างไรก็ตามความสงสัยของฉันคือมันส่งผลกระทบต่อปัญหาการยืด


หลังจากคิดแล้ว

ตามจริงแล้วเมื่อฉันคิดเกี่ยวกับประเด็นนี้มากขึ้นฉันก็จะเชื่อว่าการแก้ปัญหานั้นเกี่ยวข้องกับความสัมพันธ์ที่เป็นสัดส่วนโดยตรงระหว่างมุมมองในทิศทาง y กับทิศทาง fovy และอัตราส่วนภาพ

การฉายภาพมุมมอง

การใช้ภาพด้านบนเป็นข้อมูลอ้างอิงหากความกว้างเพิ่มขึ้น (ก่อให้เกิดการยืดในแนวนอน) ดูเหมือนว่าน่าจะเป็นไปได้มากที่มุม fovy ต้องเพิ่มขึ้นเพื่อทำให้เกิดการยืดแนวตั้งที่ 'แก้ไข' สัดส่วนของภาพที่แสดงผล

ในทำนองเดียวกันการลดความกว้างต้องลดลงในมุม fovy

ปรับปรุง:

ดังนั้นหลังจากตรวจสอบเรื่องนี้ต่อไปฉันได้ตัดสินใจที่จะเปลี่ยนวิธีการตั้งค่า frustum การดูเช่นนี้:

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เป็นจำนวนเต็มซึ่งทำให้อัตราส่วนกว้างยาวเป็นผลมาจากการหารจำนวนเต็ม

การหล่อมิติใดมิติหนึ่งให้ลอยนั้นทำให้ผลลัพธ์นั้นใช้การหารจุดลอยแทน

เนื่องจากอัตราส่วนกว้างยาวถูกต้องจึงไม่มีการยืดเท่าที่เห็นในโพสต์ต้นฉบับ

แก้ไข:รหัสในโพสต์ต้นฉบับ (และคำตอบ) เป็นรหัสหลอกสำหรับการโทรไปยัง GPU โปรแกรมจริงที่ใช้ในการแสดงผลภาพด้านบนเขียนด้วยภาษา Java สำหรับผู้ที่ไม่ได้ทำงานกับ Java ฉันไม่ได้ค้นคว้าเพื่อดูว่ามีการใช้งานการหารจำนวนเต็ม / ทศนิยมในลักษณะเดียวกันหรือไม่ โดยไม่คำนึงถึงวิธีการแก้ปัญหาเกี่ยวกับการทำให้แน่ใจว่าคำนวณอัตราส่วนอย่างถูกต้องแน่นอน

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.