คำแนะนำนี้ไม่เฉพาะเจาะจงสำหรับการเรนเดอร์ แต่ควรช่วยในการสร้างระบบที่แยกสิ่งต่าง ๆ ออกเป็นส่วนใหญ่ ก่อนอื่นให้พยายามเก็บข้อมูล 'GameObject' แยกจากข้อมูลตำแหน่ง
เป็นที่น่าสังเกตว่าข้อมูลตำแหน่ง XYZ แบบง่าย ๆ อาจไม่ง่ายนัก หากคุณใช้เอ็นจิ้นฟิสิกส์คุณสามารถเก็บข้อมูลตำแหน่งไว้ในเอ็นจิ้นบุคคลที่สามได้ คุณอาจต้องการซิงโครไนซ์ระหว่างพวกเขา (ซึ่งจะเกี่ยวข้องกับการคัดลอกหน่วยความจำที่ไม่มีจุดหมายมากมาย) หรือสอบถามข้อมูลโดยตรงจากเอ็นจิ้น แต่วัตถุบางอย่างไม่จำเป็นต้องใช้ฟิสิกส์บางอย่างจะได้รับการแก้ไขเพื่อให้ชุดของโฟลตที่เรียบง่ายทำงานได้ดีที่นั่น บางคนอาจติดกับวัตถุอื่นดังนั้นตำแหน่งของพวกเขาจึงเป็นจริงของตำแหน่งอื่น ในการตั้งค่าขั้นสูงคุณอาจมีตำแหน่งที่เก็บไว้ใน GPU เพียงครั้งเดียวเท่านั้นที่จะต้องใช้คอมพิวเตอร์ในการเขียนสคริปต์การจัดเก็บและการจำลองเครือข่าย ดังนั้นคุณน่าจะมีตัวเลือกที่เป็นไปได้หลายอย่างสำหรับข้อมูลตำแหน่งของคุณ ที่นี่มันเหมาะสมที่จะใช้มรดก
แทนที่จะเป็นวัตถุที่เป็นเจ้าของตำแหน่งแทนวัตถุนั้นควรเป็นเจ้าของโครงสร้างข้อมูลการทำดัชนี ตัวอย่างเช่น 'ระดับ' อาจมี Octree หรืออาจเป็น 'ฉาก' ของเครื่องมือฟิสิกส์ เมื่อคุณต้องการแสดงผล (หรือตั้งค่าฉากเรนเดอร์) คุณจะค้นหาโครงสร้างพิเศษของคุณสำหรับวัตถุที่มองเห็นได้ด้วยกล้อง
นอกจากนี้ยังช่วยให้การจัดการหน่วยความจำที่ดี วิธีนี้วัตถุที่ไม่ได้อยู่ในพื้นที่จริง ๆ ไม่มีตำแหน่งที่เหมาะสมแทนที่จะส่งคืน 0.0 coords หรือ coords ที่มีเมื่ออยู่ในพื้นที่
หากคุณไม่ได้เก็บพิกัดไว้ในวัตถุอีกต่อไปแทนที่จะเป็น object.getX () คุณจะต้องมีระดับ level.getX (วัตถุ) ปัญหาของการค้นหาวัตถุในระดับนั้นน่าจะเป็นการดำเนินการที่ช้าเนื่องจากจะต้องตรวจสอบวัตถุทั้งหมดและจับคู่กับการสอบถามของคุณ
เพื่อหลีกเลี่ยงการที่ฉันอาจจะสร้างคลาส 'ลิงก์' พิเศษ หนึ่งที่ผูกระหว่างระดับและวัตถุ ฉันเรียกมันว่า "ตำแหน่งที่ตั้ง" นี้จะมีพิกัด xyz เช่นเดียวกับที่จับในระดับและการจัดการกับวัตถุ ลิงค์คลาสนี้จะถูกเก็บไว้ในโครงสร้าง / ระดับพิเศษและวัตถุจะมีการอ้างอิงที่อ่อนแอ (ถ้าระดับ / สถานที่ถูกทำลายการอ้างอิงวัตถุจำเป็นต้องได้รับการอัปเดตเป็นโมฆะ 'เจ้าของ' วัตถุด้วยวิธีนี้หากระดับถูกลบไปดังนั้นโครงสร้างดัชนีพิเศษสถานที่ที่มีและวัตถุ
typedef std::tuple<Level, Object, PositionXYZ> Location;
ตอนนี้ข้อมูลตำแหน่งจะถูกเก็บไว้ในที่เดียวเท่านั้น ไม่ซ้ำกันระหว่างวัตถุโครงสร้างการจัดทำดัชนีพิเศษเรนเดอร์และอื่น ๆ
โครงสร้างข้อมูลพิเศษเช่น Octrees มักไม่จำเป็นต้องมีพิกัดของวัตถุที่เก็บไว้ มีตำแหน่งถูกเก็บไว้ในตำแหน่งสัมพัทธ์ของโหนดในโครงสร้างตัวเอง (มันอาจจะคิดว่าเป็นเหมือนการบีบอัดแบบสูญเสียเสียสละความแม่นยำสำหรับการค้นหาครั้งเร็ว) ด้วยวัตถุที่ตั้งใน Octree แล้วจะพบพิกัดจริงภายในเมื่อมีการสอบถาม
หรือถ้าคุณใช้เอ็นจิ้นฟิสิกส์เพื่อจัดการตำแหน่งวัตถุของคุณหรือส่วนผสมระหว่างสองคลาสคลาส Location ควรจัดการสิ่งนั้นอย่างโปร่งใสในขณะที่รักษาโค้ดทั้งหมดของคุณไว้ในที่เดียว
ข้อดีอีกประการคือตอนนี้ตำแหน่งและการอ้างอิงถึงระดับจะถูกเก็บไว้ในตำแหน่งเดียวกัน คุณสามารถใช้ object.TeleportTo (other_object) และทำให้มันทำงานข้ามระดับได้ การค้นหาเส้นทางของ AI ในทำนองเดียวกันสามารถติดตามบางสิ่งในพื้นที่อื่น
เกี่ยวกับการเรนเดอร์ การเรนเดอร์ของคุณสามารถมีผลผูกพันกับตำแหน่งได้ ยกเว้นว่าจะมีสิ่งที่แสดงเฉพาะในนั้น คุณอาจไม่ต้องการ 'วัตถุ' หรือ 'ระดับ' เพื่อเก็บไว้ในโครงสร้างนี้ วัตถุอาจมีประโยชน์หากคุณพยายามทำบางอย่างเช่นการเลือกสีหรือการแสดงผล hitbar ที่ลอยอยู่เหนือวัตถุเป็นต้น แต่มิฉะนั้นโหมดแสดงภาพจะให้ความสำคัญกับตาข่ายและเช่นนั้น RenderableStuff น่าจะเป็น Mesh ก็สามารถมี bounding boxes ได้เช่นกัน
typedef std::pair<RenderableStuff, PositionXYZ> RenderThing;
renderer.render(level, camera);
renderer: object = level.getVisibleObjects(camera);
level: physics.getObjectsInArea(physics.getCameraFrustrum(camera));
for(object in objects) {
//This could be depth sorted, meshes could be broken up and sorted by material for batch rendering or whatever
rendering_que.addObjectToRender(object);
}
คุณอาจไม่จำเป็นต้องทำสิ่งนี้ทุกเฟรมคุณสามารถมั่นใจได้ว่าคุณจะได้พื้นที่ที่ใหญ่กว่าที่กล้องแสดงอยู่ แคชติดตามการเคลื่อนไหวของวัตถุเพื่อดูว่ามีกล่องขอบเขตอยู่ในระยะหรือไม่ติดตามการเคลื่อนไหวของกล้องและอื่น ๆ แต่อย่าเริ่มยุ่งกับสิ่งนั้นจนกว่าคุณจะทำการเปรียบเทียบ
เอ็นจิ้นฟิสิกส์ของคุณเองอาจมีนามธรรมที่คล้ายกันเนื่องจากมันไม่ต้องการข้อมูล Object เพียงแค่คุณสมบัติการชนกันของตาข่ายและคุณสมบัติทางฟิสิกส์
ข้อมูลวัตถุหลักทั้งหมดของคุณจะมีชื่อของตาข่ายที่วัตถุใช้ เอ็นจิ้นของเกมสามารถไปข้างหน้าและโหลดสิ่งนี้ในรูปแบบใดก็ได้โดยไม่ต้องสร้างภาระวัตถุของคุณด้วยการเรนเดอร์สิ่งต่าง ๆ ที่เฉพาะเจาะจง (ซึ่งอาจเฉพาะเจาะจงกับ API การเรนเดอร์ของคุณเช่น DirectX vs OpenGL)
นอกจากนี้ยังแยกส่วนประกอบต่าง ๆ สิ่งนี้ทำให้ง่ายต่อการทำสิ่งต่าง ๆ เช่นแทนที่เครื่องยนต์ฟิสิกส์ของคุณเนื่องจากสิ่งเหล่านั้นส่วนใหญ่มีอยู่ในที่เดียว นอกจากนี้ยังทำให้ง่ายขึ้น คุณสามารถทดสอบสิ่งต่าง ๆ เช่นเคียวรีฟิสิกส์โดยไม่จำเป็นต้องตั้งค่าวัตถุปลอมใด ๆ เนื่องจากสิ่งที่คุณต้องการคือคลาสที่ตั้ง นอกจากนี้คุณยังสามารถปรับปรุงสิ่งต่าง ๆ ได้ง่ายขึ้น มันทำให้ชัดเจนมากขึ้นว่าแบบสอบถามที่คุณต้องดำเนินการกับสิ่งที่เรียนและสถานที่เดียวเพื่อเพิ่มประสิทธิภาพพวกเขา (เช่นระดับดังกล่าวข้างต้น getVisibleObject จะเป็นที่ที่คุณสามารถแคชสิ่งถ้ากล้องไม่ได้ย้ายไปมาก)
m_renderable
สมาชิกนั้น ด้วยวิธีนี้คุณสามารถแยกตรรกะของคุณได้ดีขึ้น อย่าบังคับใช้ "อินเทอร์เฟซ" ที่สามารถเรนเดอร์ได้บนวัตถุทั่วไปที่มีฟิสิกส์, ไอและอะไรก็ได้ .. หลังจากนั้นคุณสามารถจัดการเรนเดอร์แยกได้ คุณต้องการเลเยอร์ของการทำให้เป็นนามธรรมผ่านการเรียกใช้ฟังก์ชัน OpenGL เพื่อแยกสิ่งต่าง ๆ มากขึ้น ดังนั้นอย่าคาดหวังว่าเอ็นจิ้นที่ดีจะมีการเรียก GL API ภายในการปรับใช้ที่สามารถแสดงผลได้หลากหลาย แค่นั้นแหละ