ความแตกต่างระหว่าง“ บัฟเฟอร์” และ“ อาร์เรย์” ใน OpenGL หรือไม่


12

เมื่อฉันอ่าน doc บน webGL หรือ OpenGL ฉันสามารถเห็นรูปแบบบางอย่างในวิธีการใช้ชื่อฟังก์ชั่นและวัตถุ แต่ฉันไม่เข้าใจความแตกต่างระหว่างวัตถุบัฟเฟอร์และอาร์เรย์

มี "วัตถุบัฟเฟอร์จุดสุดยอด", "วัตถุอาร์เรย์จุดสุดยอด" และแม้กระทั่ง "บัฟเฟอร์อาร์เรย์" หรือ "arraybuffer" บางชนิด

ในบริบท OpenGL บางสิ่งเมื่อเป็น "อาเรย์" และเมื่อมันควรจะเรียกว่า "บัฟเฟอร์" แทน?


มุมมองบางอย่างนึกถึงการดึงข้อมูลผ่านเครือข่ายและจัดเก็บบันทึกของทุกสิ่งที่ได้รับ คุณจำเป็นต้องอ่านซ็อกเก็ตและวางข้อมูลที่ได้รับไว้ที่ไหนสักแห่งเพื่อให้คุณสามารถผ่านไปได้นั่นคือบัฟเฟอร์ ซึ่งมักเป็นประเภทรายการแบบง่าย ๆ ที่มีการกำหนดขอบเขตแบบไดนามิก บางครั้งมันง่ายเหมือนchar* buffer = socketRead();(pseudocode) บันทึกในอีกทางหนึ่งอาศัยอยู่ในวงจรชีวิตของแอปทั้งหมด ดังนั้นคุณจึงสร้างอาเรย์ที่ไหนสักแห่งและเริ่มอ่านซ็อกเก็ตเมื่อใดก็ตามที่คุณได้รับข้อมูลที่คุณเขียนอันนั้นไปยังอาเรย์ทำให้คุณมีรายการข้อมูลทั้งหมดที่คุณได้รับเรียบร้อย
Kevin

คำตอบ:


5

การตั้งชื่อของ Vertex Array Object นั้นค่อนข้างโชคร้าย มีสามสิ่งที่แตกต่างกันซึ่งปรากฏขึ้น (เคยปรากฏ) ใน / กับ / รอบแอปพลิเคชันของคุณและมีชื่อ (แตกต่างกันไปตามประวัติศาสตร์) ด้วยชื่อ "อาร์เรย์" หรือ "บัฟเฟอร์" ในชื่อ (เช่นกันมีวัตถุเฟรมบัฟเฟอร์ด้วย แต่ฉันจะไม่สนใจมัน)

  1. ข้อมูลที่อยู่ในแอปพลิเคชันของคุณอย่างเป็นทางการและเป็นความจริง แต่ OpenGL ถูกดึงในครั้งเดียว (ซึ่งตรงกันข้ามกับจุดยอดโดยจุดยอด) นี้เป็นกาลครั้งสิ่งที่คุณจะเรียกอาร์เรย์จุดสุดยอด
    จุดประสงค์ของการทำเช่นนี้คือการทำให้การเข้าถึงมีประสิทธิภาพมากขึ้นเนื่องจาก OpenGL สามารถคัดลอกสิ่งต่าง ๆ ทั้งหมดในครั้งเดียวในเวลาที่กำหนดเมื่อคุณให้สัญญาว่าข้อมูลนั้นสอดคล้องกันและผลักมันไป AGP หรืออะไรก็ตาม สิ่งนี้ไม่มีอยู่อีกต่อไป
  2. ข้อมูลถูกบดบังและเข้าถึงได้โดยจุดจับที่สามารถ "ผูก" ได้เช่นถูกทำให้ใช้งานได้ ข้อมูลอาจอาศัยอยู่ในหน่วยความจำหลักหรือการ์ดกราฟิกหรือถูกย้ายไปยังภูมิภาคที่แมป PCIe ไม่ว่าจะด้วยวิธีใดก็ตาม แต่คุณไม่ได้เป็นเจ้าของอย่างเป็นทางการ (แม้ว่าจะอยู่ใน RAM จริงหรือว่าข้อมูลมาจากแอพพลิเคชันของคุณก็ตาม ) มัน - หากคุณยังไม่ได้ "แมป" ในปัจจุบันผ่าน API ที่เกี่ยวข้องให้เรียกตัวชี้ที่เขียนได้ (และบางครั้งสามารถอ่านได้) กลับมา นอกจากนี้คุณยังมีข้อ จำกัด ในความสามารถในการควบคุมสิ่งที่เกิดขึ้นกับข้อมูลเลย (คุณสามารถให้คำแนะนำได้บ้าง
    OpenGL อาจย้ายข้อมูลนี้ไปมาอย่างอิสระมากขึ้นหรือน้อยลงและคุณได้รับอนุญาตเท่านั้น / สามารถคัดลอกไปยัง / จากบัฟเฟอร์ผ่าน API ที่เกี่ยวข้องหรือเข้าถึงข้อมูลในขณะที่ถูกแมป นั่นคือสิ่งที่คุณเรียกว่าวัตถุบัฟเฟอร์ ( วัตถุบัฟเฟอร์จุดสุดยอดถ้ามันมีจุดยอด แต่จริงๆไม่จำเป็นต้องเป็นข้อมูลภาพหรือชุดเครื่องแบบเฉพาะจุดยอดเป็นคนแรกที่ได้รับการสนับสนุนครั้งเดียว)
    จุดประสงค์ของการทำเช่นนี้คือเพื่อรับประกันว่า OpenGL สามารถทำได้ (โดยหลักการ) ทำในสิ่งที่ต้องการมันยังสามารถผลักบัฟเฟอร์ผ่าน PCIe โดยเฉพาะก่อนที่คุณจะวาด ทำงานได้เพราะคุณไม่ได้เป็นเจ้าของข้อมูล (OpenGL ทำ!) และคุณสามารถเข้าถึงได้ผ่าน API ที่กำหนดเท่านั้นดังนั้นจึงเป็นที่รู้จักกันตลอดเวลาว่าข้อมูลนั้นถูกต้อง ไดรเวอร์ยังสามารถเลือกที่จะทิ้งหน่วยความจำบัฟเฟอร์บนการ์ดกราฟิกเมื่อต้องการหน่วยความจำสำหรับสิ่งที่แตกต่างและเรียกคืนจากสำเนาลับเมื่อจำเป็น
  3. การเรียกชื่อผิดโง่จริงๆซึ่งเป็นชื่อที่ดีมากจะเป็นสิ่งที่ชอบบัฟเฟอร์ชุดหรือบ่งชุดนี้เป็นที่น่าอับอายจุดสุดยอดวัตถุอาร์เรย์ มันคือจากมุมมองของคุณไม่มีอะไรนอกจากชุดของบัฟเฟอร์ที่จับมัดกันภายใต้การจัดการที่ชัดเจนอื่น (ซึ่งคุณสามารถผูก) ความจริงนั้นซับซ้อนกว่าเล็กน้อย ในความเป็นจริง VAO นั้นใกล้เคียงกับการทำงานของฮาร์ดแวร์จริง ๆ การ์ดกราฟิกมีจำนวนชุดเล็ก ๆ (มักจะเป็น 2, 4, หรือ 8) ของชุดคำอธิบาย (ไม่เพียง แต่สำหรับบัฟเฟอร์ แต่สำหรับตัวอย่าง) ด้วยรายการที่เป็นประโยชน์ในแต่ละรายการซึ่งสามารถสลับได้อย่างมีประสิทธิภาพมาก .
    ตอนนี้ความตั้งใจของวัตถุอาร์เรย์จุดสุดยอดคือการลดจำนวนการเรียก API และเพื่อลดจำนวนการตรวจสอบความสอดคล้องที่ OpenGL จะต้องดำเนินการภายในและแน่นอนเพื่อใช้ฮาร์ดแวร์ตามการทำงาน หากคุณผูก 5 บัฟเฟอร์จากนั้นแต่ละคนจะต้องผ่านการตรวจสอบบางอย่างที่อาจมีราคาแพงและแต่ละคนเป็นผู้สมัครสำหรับแคชหายไปในไดรเวอร์รวมทั้งแต่ละคนต้องสื่อสารกับกราฟิกการ์ดเพื่อเปลี่ยน descriptor ฯลฯ ฯลฯ หากคุณแทน ผูกหนึ่ง VAO คนขับสามารถ (บ่อยครั้ง) เพียงแค่สลับ descriptor ที่ตั้งอยู่บนการ์ดกราฟิกและทำ

8

วัตถุ Vertex Array (VAO) เป็นวัตถุที่มีวัตถุ Vertex Buffer ตั้งแต่หนึ่งรายการขึ้นไปและถูกออกแบบมาเพื่อเก็บข้อมูลสำหรับวัตถุที่ถูกเรนเดอร์ที่สมบูรณ์

(ดึงมาจากkhronos )

บัฟเฟอร์แต่ละอันมีแนวโน้มที่จะประกอบเป็นหนึ่งคุณลักษณะของอาร์เรย์จุดยอด (วัตถุ) VAO สามารถมีคุณลักษณะจุดสุดยอดจำนวนมาก (เช่นตำแหน่งสี UV) แต่ละคนอาจถูกเก็บไว้ในบัฟเฟอร์ของตัวเองโดยที่บัฟเฟอร์บ่งบอกถึงชุดที่ไม่ได้ฟอร์แมตของไบต์ที่ต่อเนื่องกันและตำแหน่งที่คุณต้องระบุขนาด (ประเภท) ต่อองค์ประกอบบัฟเฟอร์อย่างชัดเจนสำหรับการโทร OpenGL ฝั่ง CPU และการทำงานด้าน GPU

นั่นเป็นวิธีหนึ่ง วิธีอื่น ๆ ที่สามารถใช้งานได้คือ:

  • แอ็ตทริบิวต์ทั้งหมดจะถูกจัดเก็บแบบแทรกในบัฟเฟอร์เดียวหรือ
  • คุณลักษณะบางอย่างมีอยู่ในบัฟเฟอร์เฉพาะของตัวเองในขณะที่คุณสมบัติอื่น ๆ ใช้บัฟเฟอร์ร่วมกัน

แผนภาพด้านล่างแสดงตัวอย่างสองกรณีหลังนี้

ป้อนคำอธิบายรูปภาพที่นี่

Bottom line: หากวลี "vertex array" ถูกใช้อย่างไม่มีเงื่อนไขใน OpenGL คุณสามารถสรุปได้ว่ามันหมายถึง VAO ซึ่งในบริบท OpenGL (โดยเฉพาะ) นั้นเป็นสิ่งที่แตกต่างจากบัฟเฟอร์อย่างแน่นอน

แก้ไขความคิดเห็นของคุณอีกครั้ง: GL_ARRAY_BUFFERระบุความตั้งใจที่จะใช้วัตถุบัฟเฟอร์นั้นสำหรับข้อมูลแอ็ตทริบิวต์จุดยอดดังที่อธิบายไว้ข้างต้น นี้เป็นเพราะบัฟเฟอร์ไม่ได้ใช้เฉพาะสำหรับแอตทริบิวต์จุดสุดยอด อย่างไรก็ตามเนื่องจากเป็นกรณีการใช้งานทั่วไปและคุณกำลังถามเกี่ยวกับ VAO ฉันจะไม่เข้าไปเกี่ยวข้องกับคนอื่น อย่างไรก็ตามที่นี่คือรายการของบัฟเฟอร์ประเภทอื่น ๆ ที่สามารถตั้งค่าได้


ดังนั้นบัฟเฟอร์คือ: 1. อยู่ใน GPU, 2. ส่วนใหญ่มีข้อมูลหนึ่งชนิด (เฉพาะจุดยอด, สีเท่านั้น, ect), 3.Data ถูกแทรก, นั่นคือ 111122223333 4. ไม่มีวิธีการเข้าถึงข้อมูล (ไม่ใช่บัฟเฟอร์ [2] หรือบัฟเฟอร์ [vertex_3434]) ตอนนี้อาร์เรย์คือ: 1.collection of buffer, 2. ข้อมูล store เกี่ยวกับวิธีการวิเคราะห์บัฟเฟอร์ที่มีอยู่ (นั่นคือ stride store array ขนาดขององค์ประกอบ, ออฟเซ็ตดังนั้นข้อมูลจากบัฟเฟอร์สามารถเข้าถึงได้อย่างถูกต้องใช่มั้ย
coobit

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

2. ใช่และคุณต้องตรวจสอบให้แน่ใจว่าการประกาศบัฟเฟอร์ใน shader ของคุณจะตรงกับข้อกำหนดที่คุณตั้งไว้ใน VAO ของคุณในด้าน CPU: "สถานะทั้งหมดที่เกี่ยวข้องกับคำจำกัดความของข้อมูลที่ใช้โดยตัวประมวลผลจุดสุดยอดถูกห่อหุ้มในจุดสุดยอด วัตถุอาร์เรย์ " (khronos docs)
วิศวกร

ดังนั้นเพียงแค่ตบเล็บมากขึ้น ... ผู้คนทำงานอย่างไรก่อนที่ AO จะใช้ BO เท่านั้น? หรือ AO มีอยู่ใน OpenGL เสมอและมันเป็นเพียง VAO ซึ่งเปิดตัวในภายหลังจากนั้น VBO?
coobit

@coobit io7m.com/documents/history-vertex-spec - สิ่งนี้จะช่วยให้คุณได้ทราบถึงความแตกต่างระหว่างไพพ์ไลน์แบบคงที่ (โรงเรียนเก่า) OpenGL, 3Dfx เป็นต้นและทันสมัย ​​OpenGL และ Direct3D ไปป์ไลน์ที่ตั้งโปรแกรมได้
วิศวกร

5

คำศัพท์นี้มีรากฐานมาจากประวัติของ OpenGL สิ่งสำคัญที่ต้องจำไว้คือสำหรับรุ่น GL ส่วนใหญ่ที่เกี่ยวข้องที่นี่ OpenGL มีการพัฒนาเพิ่มขึ้นเรื่อย ๆ และโดยการเพิ่มฟังก์ชั่นใหม่ให้กับ API ที่มีอยู่แล้วแทนที่จะเปลี่ยน API

OpenGL เวอร์ชันแรกไม่มีประเภทวัตถุเหล่านี้ การวาดประสบความสำเร็จโดยการออกการเรียก glBegin / glEnd หลายครั้งและปัญหาหนึ่งที่เกิดขึ้นกับรุ่นนี้คือมันไม่มีประสิทธิภาพมากในแง่ของค่าใช้จ่ายในการเรียกใช้ฟังก์ชัน

OpenGL 1.1 ใช้ขั้นตอนแรกเพื่อแก้ไขปัญหานี้โดยการแนะนำอาร์เรย์จุดสุดยอด แทนที่จะระบุข้อมูลจุดสุดยอดโดยตรงคุณสามารถหาแหล่งข้อมูลได้จากอาร์เรย์ C / C ++ ซึ่งเป็นชื่อ ดังนั้นอาร์เรย์จุดยอดจึงเป็นเช่นนั้น - อาร์เรย์ของจุดยอดและสถานะ GL จำเป็นต้องระบุ

วิวัฒนาการที่สำคัญต่อไปมาพร้อมกับ GL 1.5 และอนุญาตให้จัดเก็บข้อมูลอาร์เรย์จุดสุดยอดในหน่วยความจำ GPU มากกว่าในหน่วยความจำระบบ ("ฝั่งไคลเอ็นต์") จุดอ่อนของข้อกำหนดอาร์เรย์อาเรย์ GL 1.1 คือข้อมูลจุดสุดยอดทั้งหมดต้องถูกถ่ายโอนไปยัง GPU ในแต่ละครั้งที่คุณต้องการใช้งาน ถ้ามันมีอยู่บน GPU แล้วการถ่ายโอนนี้สามารถหลีกเลี่ยงได้และเพิ่มประสิทธิภาพการทำงานที่เป็นไปได้

ดังนั้นวัตถุ GL ชนิดใหม่จึงถูกสร้างขึ้นเพื่อให้สามารถจัดเก็บข้อมูลนี้บน GPU ได้ เช่นเดียวกับวัตถุพื้นผิวที่ใช้สำหรับการจัดเก็บข้อมูลพื้นผิววัตถุบัฟเฟอร์จุดสุดยอดเก็บข้อมูลจุดสุดยอด นี่เป็นเพียงกรณีพิเศษของประเภทวัตถุบัฟเฟอร์ทั่วไปซึ่งอาจจัดเก็บข้อมูลที่ไม่เฉพาะเจาะจง

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

นี่ทำให้เราเกือบจะจบเรื่องราวของเรา API ที่ได้นั้นค่อนข้างละเอียดเมื่อมันมาถึงการระบุสถานะของจุดสุดยอดดังนั้นวิธีการเพิ่มประสิทธิภาพอีกอย่างหนึ่งก็คือการสร้างประเภทวัตถุใหม่ที่รวบรวมสถานะทั้งหมดนี้เข้าด้วยกันอนุญาตการเปลี่ยนแปลงสถานะของจุดสุดยอดหลายจุดในการเรียก API เดียวและอนุญาต GPU เพื่อทำการปรับให้เหมาะสมที่อาจเกิดขึ้นเนื่องจากสามารถทราบได้ว่าจะใช้สถานะใดก่อนเวลา

ป้อนวัตถุอาร์เรย์สุดยอดที่รวบรวมทั้งหมดนี้เข้าด้วยกัน

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


0

ฉันไม่ได้ทำงานกับ OpenGL สักพักดังนั้นฉันอาจจะไม่ถูกต้อง โดยทั่วไปการพูด: บัฟเฟอร์เก็บอาร์เรย์ของหน่วยความจำที่ไม่ฟอร์แมต อาร์เรย์เป็นศัพท์ทั่วไปของหน่วยความจำต่อเนื่อง

บัฟเฟอร์ต้องเชื่อมโยงกับบริบทในขณะที่อาร์เรย์เป็นเพียงอาร์เรย์ของข้อมูล หากฉันจำได้อย่างถูกต้องข้อมูลในบัฟเฟอร์จะถูกคัดลอกไปยังการ์ดกราฟิก

หวังว่านี่จะช่วยได้เล็กน้อย


แล้ว GL_ARRAY_BUFFER คืออะไร ทำไมมันถูกเรียกเช่นนั้น? ตามสมมติฐานของคุณมันคือ "หน่วยความจำต่อเนื่องที่ไม่
ฟอร์แมต

ตัวอย่างนี้เป็นเพียงรหัสประจำตัวของบัฟเฟอร์ (ซึ่งคุณผูกอาเรย์ของคุณ) Array Buffer (ในตัวอย่างของคุณ) ใช้สำหรับแอ็ตทริบิวต์จุดสุดยอดดังนั้นโดยทั่วไปคุณผูกอาเรย์ของแอ็ตทริบิวต์จุดสุดยอดกับบัฟเฟอร์ ฟังดูสับสนดังนั้นให้ฉันยกตัวอย่างให้คุณ คุณมีอาเรย์บนซีพียูบางตัวซึ่งอาจเป็นสี, ปกติ, ตำแหน่ง, ฯลฯ และตอนนี้คุณต้องการให้ gpu เข้าถึงมัน นั่นคือเมื่อ bindBuffer เข้ามาโดยทั่วไปจะทำการแมป "cpu-array" ของคุณกับ "gpu-array"
Juicef

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