OpenGL: VBO หรือ glBegin () + glEnd ()?


16

ฉันเพิ่งได้รับลิงก์นี้ไปยังไซต์การสอนจากคนที่ฉันให้ OGL Redbook ดั้งเดิมแก่ ส่วนหัวที่สามลงกล่าวอย่างชัดเจนว่าลืม glBegin () & glEnd () เป็นวิธีการเรนเดอร์ทั่วไป ฉันเรียนรู้ผ่านวิธีของ Redbook แต่ฉันเห็นประโยชน์บางอย่างใน VBOs นี่เป็นวิธีที่จะไปจริงๆหรือไม่และถ้าเป็นเช่นนั้นมีวิธีในการแปลงรหัสการเรนเดอร์และเฉดสีที่ตามมาให้เป็น VBOs และประเภทข้อมูลที่ตามมาหรือไม่?

คำตอบ:


27

ด้วย VBO's OpenGL ที่ทันสมัยเป็นวิธีที่จะไปสิ่งที่แก้ไขฟังก์ชั่น (รวมถึง glBegin / glEnd และสิ่งที่อยู่ในระหว่าง) ได้รับการคัดค้านตั้งแต่ 3.0 และลบออกตั้งแต่ 3.1

ด้วยโปรไฟล์ OpenGL Core, OpenGL ES 2.0+ และ WebGL คุณไม่สามารถเข้าถึงสิ่งเก่า ๆ ได้

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

มันไม่ได้เป็นเพียง VBO คุณต้องใช้ตัวแปลงแสงสำหรับทุกสิ่งและทำเมทริกซ์แปลงตัวคุณเอง (หรือใช้ GLM)

เหตุผลเดียวที่จะใช้ของเก่าคือถ้าคุณต้องการกำหนดเป้าหมาย OpenGL ก่อน 2.0 ซึ่งเปิดตัวในปี 2546 มีชิพเน็ตบุ๊คฝังตัวบางตัวที่มี 1.5 แต่ถึง 1.5 ควรสนับสนุน VBOs ไม่ใช่ shaders หรือ OpenGL ES 1.x ซึ่งขึ้นอยู่กับฟังก์ชั่นคงที่ (เช่นใช้กับ iPhone รุ่นเก่า) หรือOpenGL SC (สำหรับระบบที่สำคัญต่อความปลอดภัย)

ฟังก์ชั่นที่ใช้กันทั่วไปต่อไปนี้ถูกคัดค้านทั้งหมด:

  • glBegin
  • glEnd
  • glVertex *
  • glNormal *
  • glTextCoord *
  • glTranslate *
  • glRotate *
  • glScale *
  • glLoadIdenity
  • glModelViewMatrix

opengl-tutorial.orgบทเรียนมีสิ่งที่ผมคิดว่าเป็นวิธีที่ดีที่สุดที่จะไปเกี่ยวกับการเรียน OpenGL พวกเขาพึ่งพาบางสิ่งที่เข้ากันได้แบบดั้งเดิม แต่พวกเขาไม่ได้สอนให้คุณ ตัวอย่างเช่นคุณไม่ควรแสดงอะไรโดยไม่มี shader แต่ทำงานได้ และคุณต้องจัดการกับการฝึกอบรม (หมุนแปล ฯลฯ ) ด้วยตัวคุณเอง แต่โดยค่าเริ่มต้นคุณจะได้รับวิวพอร์ต 2D พื้นฐาน

นอกเหนือจากการหลีกเลี่ยงเนื้อหาที่เลิกใช้แล้วยังมีฟังก์ชั่นมากมายที่ทำให้การเข้ารหัส OpenGL ดีกว่า แต่มีหลายอย่างที่คุณต้องตัดสินใจว่าคุณโอเคต้องมีรุ่น OpenGL และฮาร์ดแวร์ที่รองรับ 3.x + รุ่นใหม่กว่าหรือไม่

มีข้อมูลเพิ่มเติมในเรื่องการโพสต์ที่ผมทำที่นี่

หากคุณต้องการรองรับ OpenGL รุ่นเก่าด้วยเหตุผลบางอย่างคุณสามารถใช้ VBOs หากเป็นไปได้และหากไม่มีให้ระบุทางเลือกที่ใช้ glBegin / glEnd และวนรอบข้อมูลจุดสุดยอดของคุณ

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


7

ด้วย VBOs คุณจะมีข้อดีสองประการ

ข้อได้เปรียบ 1 เกี่ยวข้องกับข้อมูลสแตติกทั้งหมดและมาจากความสามารถในการเก็บข้อมูลจุดสุดยอดของคุณในหน่วยความจำที่เหมาะสมที่สุดสำหรับ GPU

ข้อได้เปรียบ 2 เกี่ยวข้องกับข้อมูลแบบไดนามิกและมาจากความสามารถในการระบุข้อมูลจุดสูงสุดของคุณ ณ เวลาใด ๆ ก่อนที่จะใช้สำหรับการแสดงผลซึ่งสามารถไปป์ไลน์ที่ดีขึ้น

ข้อได้เปรียบประการที่สามมาจากการวาดแบทช์การโทร แต่ยังแชร์กับอาร์เรย์จุดสุดยอดของโรงเรียนเก่าด้วยดังนั้นฉันจึงไม่ได้โทรออกโดยเฉพาะสำหรับ VBOs การส่งข้อมูลไปยัง GPU (หรือการใช้ข้อมูลที่มีอยู่แล้วใน GPU) นั้นคล้ายคลึงกันในหลาย ๆ ทางสำหรับดิสก์ I / O และปริมาณการใช้เครือข่าย - ถ้าคุณมีแบทช์ขนาดใหญ่สองสามอัน

ที่ดี (ไม่ถูกต้อง 100% แต่เพียงพอที่จะช่วยให้คุณมีความคิด) การเปรียบเทียบนี้คือถ้าคุณเป็นคนขับรถบัสที่ต้องพาคน 50 คนจากเมืองหนึ่งไปอีกเมืองหนึ่ง คุณสามารถโหลดมันทีละครั้งและทำการเดินทาง 50 ครั้ง - นั่นคือ glBegin / glEnd อีกทางเลือกหนึ่งคือคุณสามารถวางพวกมันทั้งหมด 50 ตัวบนรถบัสและออกเดินทางเพียงครั้งเดียว - นั่นคือการรวมกันของอาร์เรย์ที่มีจุดสุดยอดหรือ VBOs (ในกรณี VBO ที่ 50 คนจะอยู่บนรถบัส;)

สิ่งนี้มาในราคาและนี่คือราคาที่คุณสูญเสียความสามารถในการระบุข้อมูลจุดสุดยอดเป็นและเมื่อคุณต้องการ เอาล่ะคุณสามารถทำได้ (ด้วยการทำงานเพิ่มเติม) แต่คุณจะไม่ได้รับประสิทธิภาพเต็มที่จากโค้ดของคุณ แต่คุณต้องคิดเกี่ยวกับข้อมูลจุดสุดยอดของคุณวิธีการใช้วิธี (และถ้า) ต้องได้รับการอัปเดตหรือไม่ภาพเคลื่อนไหวใด ๆ ที่สามารถทำได้ใน shader (ดังนั้นการเปิดใช้งานข้อมูลจะคงที่ - VBOs ต้องการ shaders สำหรับ กรณีภาพเคลื่อนไหวจำนวนมากทำงานได้ดี) หรือไม่ว่าคุณจะต้องรับรองข้อมูลจุดยอดแต่ละเฟรมกลยุทธ์การปรับปรุงที่มีประสิทธิภาพหากหลัง ฯลฯ หากคุณไม่ทำเช่นนี้และใช้การแปลงแบบไร้เดียงสาคุณก็มีความเสี่ยงสูงมาก ในการทำงานมากเท่านั้นสำหรับผลลัพธ์สุดท้ายที่จะทำงานช้าลงจริง ๆ !

นี่อาจเป็นงานที่แย่มากเมื่อคุณพบมันครั้งแรก แต่มันก็ไม่ได้จริงๆ เมื่อคุณเข้าสู่โหมดการคิดเช่นนี้คุณจะพบว่ามันง่ายอย่างเหลือเชื่อและเกือบจะเป็นธรรมชาติ แต่คุณอาจพลาดความพยายามครั้งแรกของคุณและคุณไม่ควรท้อแท้ถ้าเป็นเช่นนั้น - การพลาดโอกาสคือการเรียนรู้จากสิ่งที่คุณทำผิด

ความคิดสุดท้ายเล็กน้อย

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

บางครั้งผู้คนถูกเลื่อนออกไปหากพวกเขาเห็นการใช้งาน VBO โดยใช้หน่วยความจำมากกว่าการปรับใช้ / บีบอัด glBegin / glEnd ที่ปรับให้เหมาะสม (พวกเขาอาจอ้างถึงว่าเป็น "ขยะ") อย่าเป็นอย่างนั้น ยกเว้นในกรณีที่รุนแรงใช้หน่วยความจำมันไม่ที่สำคัญ เป็นการแลกเปลี่ยนที่ชัดเจนที่นี่ - คุณยอมรับการใช้หน่วยความจำที่สูงขึ้นเพื่อแลกเปลี่ยนกับประสิทธิภาพที่สูงขึ้นอย่างมาก นอกจากนี้ยังช่วยในการพัฒนาความคิดที่ว่าหน่วยความจำเป็นทรัพยากรราคาถูกและอุดมสมบูรณ์ที่จะมีการใช้; ประสิทธิภาพไม่ได้

และในที่สุดเกาลัดเก่า - ถ้ามันเร็วพอแล้วงานของคุณก็เสร็จเรียบร้อย หากคุณกดปุ่มเป้าหมายเป็นเฟรมหากคุณมีพื้นที่ว่างสำหรับสภาพชั่วคราวก็ถือว่าดีพอและคุณสามารถไปยังขั้นตอนต่อไปได้ คุณสามารถเสียจำนวนมากของเวลาและพลังงานบีบพิเศษ 10% จากสิ่งที่ไม่จริงต้องมัน (รับมีการกระทำที่ยังคงตกอยู่ในกับดัก) จึงมักพิจารณาสิ่งที่การใช้งานที่เหมาะสมที่สุดของเวลาของคุณเอง - เพราะเวลาโปรแกรมเมอร์นั้นถูกกว่าและมีน้อยกว่าประสิทธิภาพ!

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