เมื่อใดที่จะใช้อาร์เรย์จุดสุดยอดและเมื่อใดที่จะใช้ VBO


14

ฉันพยายามเรียนรู้เกี่ยวกับอาร์เรย์จุดยอดและวัตถุบัฟเฟอร์จุดสุดยอดแต่ฉันไม่เข้าใจความแตกต่างในแง่ของ:

  • กรณีใช้งาน (เรขาคณิตคงที่เช่นภูมิประเทศเรขาคณิตที่เปลี่ยนแปลงทุกเฟรมเช่นระบบอนุภาค ฯลฯ )
  • ประสิทธิภาพ
  • พกพาได้ (การ์ดกราฟิกเก่าคอนโซลอุปกรณ์เช่น Android หรือ iPhone ฯลฯ )

ชี้แจงบ้างไหม?


3
สำหรับคนอื่นที่มาถึงที่นี่ลองดูคำตอบที่โหวตแล้วที่สุดได้ที่นี่ .... stackoverflow.com/questions/430555/
afuzzyllama

คำตอบ:


14

นี่คือการเขียนที่ดีเกี่ยวกับ VBOs

ประสิทธิภาพ

นี่เป็นภาพรวมที่ดีของซีแมนทิกส์การโทร

ที่นี่นี่เป็นอีกภาพรวมที่ดีของปัญหาด้านประสิทธิภาพ ในนั้นเราจะเห็นว่า VBOs มีประสิทธิภาพมากกว่าอาร์เรย์

เหตุผลที่เราชอบ VBOs คือข้อมูลถูกโหลดลงบนการ์ดและคุณไม่จำเป็นต้องถ่ายโอนทุกเฟรม ขึ้นอยู่กับประเภทของ VBO ที่สร้างขึ้นคุณสามารถให้คำแนะนำเกี่ยวกับการใช้งานไดรฟเวอร์กราฟิกได้

การใช้

VBOs ดีมากสำหรับรูปทรงเรขาคณิตแบบคงที่เช่นภูมิประเทศที่คุณไม่คาดหวังว่าจะเปลี่ยนแปลงหรือสำหรับรูปทรงเรขาคณิตที่ทันสมัย

เวอร์เท็กซ์อาร์เรย์เหมาะสำหรับข้อมูลที่เปลี่ยนแปลงบ่อย แต่ยังอ่านได้จากเครื่องโฮสต์ - ดังนั้นสำหรับการเรนเดอร์ข้อมูลโดยตรงที่ถูกควบคุม (ตัวอย่างเช่นเลเซอร์เรนจ์ไฟนเดอเรเตอร์บัฟเฟอร์เป็นที่ที่ฉันใช้บ่อย) หากคุณสามารถออกไปโดยไม่อ่านข้อมูลบนอุปกรณ์โฮสต์ (ดังนั้นเพียงแค่กดลงบนการ์ด) VBOs ในโหมดเขียนอย่างเดียวเป็นตัวเลือกที่ดี

ความเบา

อาร์เรย์จุดสุดยอดฝั่งไคลเอ็นต์ มีอยู่ใน OpenGL ก่อนหน้า 3.0, เลิกใช้แล้วใน 3.0 และหายไปใน 3.1+ OpenGL ES สนับสนุนพวกเขา (OpenGL ES 2 ไม่ได้)

VBOs สามารถใช้งานได้หลังจาก OpenGL 1.5 นี่เป็นวิธีเดียวในการเก็บข้อมูลเรขาคณิตใน OpenGL ES 2 (และอื่น ๆ , WebGL)


2
ใน PerformanceTuning.pdf นั้นกล่าวว่า VBOs "สามารถทำร้ายประสิทธิภาพในกรณีที่ไม่เหมาะสมที่สุด" ... แต่ไม่ได้อธิบายอย่างละเอียด ความคิดใดที่กรณีเหล่านั้นคืออะไร? ฉันมีกรณีที่ฉันต้องอัปเดตเรขาคณิตทุกเฟรมดังนั้นฉันสงสัยว่าอาร์เรย์ยอดจะดีกว่าหรือแย่กว่า VBO ในกรณีนั้นหรือไม่ ขอบคุณ.
sidewinderguy

1
อ่านopengl.org/sdk/docs/man/xhtml/glDrawElements.xmlและopengl.org/wiki/GlDrawElements - Vertex Arrays AREN'T ไม่สนับสนุนหรือลบออกพวกเขายังคงรองรับ OpenGL 4.x; รับข้อเท็จจริงของคุณตรงเพื่อนเพราะสิ่งที่คุณกำลังแพร่กระจายเป็นเพียงข้อมูลที่ผิด

1
@vaxquis อาร์เรย์อาร์เรย์ฝั่งไคลเอ็นต์จะถูกคัดค้าน อาร์เรย์จุดสุดยอดฝั่งเซิร์ฟเวอร์ไม่ใช่ VAO เป็นสิ่งที่แตกต่างกันและมีไว้เพื่อบันทึกสถานะ ไม่มีอะไรผิดปกติในการโพสต์ แต่อาจมีความแม่นยำมากขึ้นถ้ามันระบุด้านลูกค้า แต่ฉันคิดว่านั่นเป็นนัย
concept3d

1
"อาร์เรย์จุดสุดยอดฝั่งไคลเอ็นต์จะเลิกใช้แล้วอาร์เรย์จุดสุดยอดฝั่งเซิร์ฟเวอร์ไม่ได้" "Array Vertex มีให้ใน OpenGL ก่อน 3.0, เลิกใช้ใน 3.0 และหายไปใน 3.1+" "คุณสามารถ prespecify อาร์เรย์ของ vertices ที่แยกต่างหาก (... ) และใช้เพื่อสร้างลำดับของ primitives ด้วยการเรียก glDrawElements ครั้งเดียว Core ในเวอร์ชัน 4.4" - ฉันเห็นความขัดแย้งในข้อความเหล่านี้

2
นอกจากนี้ก่อนที่จะพูดอะไรบางอย่าง "เลิกใช้แล้ว" ให้ระบุแหล่งที่มาของข้อความดังกล่าวโดยเฉพาะอย่างยิ่งในเอกสารทางการ การชี้จาก StackExchange ไปยัง StackOverflow เป็นข้อพิสูจน์ไม่ใช่วิธีการทำงานของวิทยาศาสตร์และการปกป้องด้วย "ฉันเดาว่ามันเป็นนัย" ไม่ใช่ข้อโต้แย้ง ไม่มีใครถามเกี่ยวกับอาเรย์ของลูกค้า / เซิร์ฟเวอร์คำถามเกี่ยวกับอาเรย์จุดสุดยอดในแง่ที่กว้างที่สุดเมื่อเทียบกับ VBO Btw ฉันไม่ได้พูดอะไรเกี่ยวกับ VAO ความคิดนั้นมาจากไหน

11

(ฉันเพิ่มที่นี่เนื่องจากความจริงที่ว่าคำตอบของ ChrisE นั้นคลุมเครืออย่างมากซึ่งน่าเสียดายเนื่องจากความคลุมเครือของคำถามเดิมอย่างไรก็ตามฉันจะถือว่าคำถามของ OP ควรได้รับการตั้งชื่อว่า "เมื่อใช้VAOsและเมื่อใดควรใช้VBO ")

V ertex B uffer O bjects (ซึ่งไม่ได้แตกต่างจากb uffer Oประเภทอื่น ๆเช่นU niform B uffer O bjects ) เป็นวิธีการอัปโหลดข้อมูลเวอร์เท็กซ์ไปยังฮาร์ดแวร์กราฟิก

V ertex rray O bjects จะใช้ในการนอกเหนือไปจาก VBO s เพื่อปรับปรุงฝั่งไคลเอ็นต์ (CPU ฝั่ง) ประสิทธิภาพการทำงานโดยการลดจำนวนการโทรที่จำเป็นในการ rebind บัฟเฟอร์จุดสุดยอดของแต่ละบุคคลและจุดสุดยอดอีกชุดแอตทริบิวต์ของเวลาที่คุณต้องการทุก เปลี่ยนเพื่อแสดงผลในบางวิธี แทนที่จะทำทุกอย่างที่ทำงานได้ทุกเฟรมคุณทำได้เพียงครั้งเดียว (ตอนเริ่มต้น) จากนั้นเพียงแค่เชื่อมโยงVAOที่เหมาะสมสำหรับแต่ละสาย (ชุด) วาดการโทรที่ใช้แอตทริบิวต์จุดสุดยอดที่เกี่ยวข้อง

อย่างไรก็ตามการใช้VAOไม่ได้เป็นการปลดปล่อยคุณจากความรับผิดชอบเพิ่มเติมที่ต้องทำglBindBuffer+ glBufferDataสำหรับข้อมูลใด ๆ ที่เปลี่ยนแปลงแต่ละเฟรมเช่นตำแหน่งเอนทิตีเกม / การหมุนเวียน / การแปลงเมทริกซ์ เมื่อคุณมีข้อมูลสแตติกทั้งหมดที่คุณต้องทำglBindVertexArray(&vao) -> glDraw*(...) -> glBindVertexArray(0)เพื่อแสดงเท่านั้น


+1 VAO เป็นชื่อที่แย่และสับสนและทำให้ฉันนึกถึงสิ่งที่ openGL ยุ่งเหยิง
concept3d

1
ฉันยังจำได้ว่าจะมีการอภิปรายเกี่ยวกับคำถามนี้ (ส่วนใหญ่จะถูกลบ) ปัญหาอีกครั้งคือคำศัพท์ที่น่ากลัวของ OpenGL ฉันยังแก้ไขคำตอบของ Chris ให้แม่นยำยิ่งขึ้น
concept3d
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.