โหมดทันที, ผู้ไม่เชื่อเรื่องพระเจ้า, API Drawing Drawing Lightweight สำหรับ C ++
ซอฟต์แวร์นี้อยู่ในโดเมนสาธารณะ ในกรณีที่ไม่ได้รับการยอมรับการอุทิศตนคุณจะได้รับใบอนุญาตที่ไม่สามารถเพิกถอนได้ตลอดเวลาเพื่อคัดลอกแจกจ่ายและแก้ไขซอร์สโค้ดตามที่คุณเห็น
ซอร์สโค้ดมีให้ "ตามสภาพ" โดยไม่มีการรับประกันใด ๆ โดยชัดแจ้งหรือโดยนัย ไม่จำเป็นต้องมีการระบุแหล่งที่มา แต่มีการกล่าวถึงผู้แต่ง
Debug Draw เป็นไลบรารีไฟล์ต้นฉบับเดียวดังนั้นการประกาศไปข้างหน้า "ส่วนหัว" และการใช้งานมีอยู่ในไฟล์เดียวกัน ( debug_draw.hpp ) สิ่งนี้ควรอำนวยความสะดวกในการปรับใช้และรวมเข้ากับโครงการของคุณเอง สิ่งที่คุณต้องทำคือ #include ไฟล์ไลบรารีในไฟล์ต้นฉบับของคุณและกำหนด DEBUG_DRAW_IMPLEMENTATION ในไฟล์นั้นเพื่อสร้างการใช้งาน คุณยังสามารถรวมห้องสมุดในที่อื่น ๆ เมื่อไม่ได้กำหนด DEBUG_DRAW_IMPLEMENTATION มันจะทำหน้าที่เป็นไฟล์ส่วนหัว C ++ ปกติ ตัวอย่าง:
ใน my_program.cpp :
# define DEBUG_DRAW_IMPLEMENTATION
# include " debug_draw.hpp " ตอนนี้ใน my_program.hpp หรือไฟล์ส่วนหัวหรือไฟล์อื่น ๆ คุณสามารถรวมไว้เป็นส่วนหัว C ++ ปกติ:
# include " debug_draw.hpp "ตอนนี้คุณควรจะสามารถสร้าง Debug Draw ลงในแอปพลิเคชันของคุณเอง
Debug Draw ไม่ได้ตั้งสมมติฐานเกี่ยวกับการแสดงผล api underlayer ดังนั้นจึงสามารถรวมเข้าด้วยกันได้อย่างง่ายดายด้วย Direct3D หรือ OpenGL หรือกลไกการเรนเดอร์อื่น ๆ ที่คุณเลือก สิ่งที่จำเป็นทั้งหมดคือคุณให้การใช้งานสำหรับคลาสบทคัดย่อ dd::RenderInterface ซึ่งให้การตรวจแก้จุดบกพร่องด้วยวิธีการพื้นฐานในการวาดจุดเส้นและร่ายมนตร์อักขระ ต่อไปนี้คือสิ่งที่ dd::RenderInterface มีลักษณะอย่างไร:
class RenderInterface
{
public:
virtual void beginDraw ();
virtual void endDraw ();
virtual GlyphTextureHandle createGlyphTexture ( int width, int height, const void * pixels);
virtual void destroyGlyphTexture (GlyphTextureHandle glyphTex);
virtual void drawPointList ( const DrawVertex * points, int count, bool depthEnabled);
virtual void drawLineList ( const DrawVertex * lines, int count, bool depthEnabled);
virtual void drawGlyphList ( const DrawVertex * glyphs, int count, GlyphTextureHandle glyphTex);
virtual ~RenderInterface () = 0 ;
}; ไม่ต้องใช้วิธีการบางอย่างคุณตัดสินใจว่าจะสนับสนุนคุณสมบัติใดที่จะสนับสนุน! ดูที่ซอร์สโค้ดสำหรับการประกาศของ RenderInterface แต่ละวิธีมีความคิดเห็นที่ดีและอธิบายพฤติกรรมที่คาดหวังที่คุณควรนำไปใช้ สำหรับการใช้งานอ้างอิงของ RenderInterface โดยใช้ APIs มาตรฐานเช่น OpenGL โปรดดู samples/ ไดเรกทอรีในโครงการนี้
เมื่อคุณใช้งาน RenderInterface สำหรับ Renderer ของคุณสิ่งที่คุณต้องทำก่อนที่จะเริ่มใช้ Debug Draw คือการโทร dd::initialize() ส่งผ่านตัวชี้ไปยัง RenderInterface ที่กำหนดเอง:
MyRenderInterface renderIface;
dd::initialize (&renderIface); หมายเหตุอย่างไรก็ตามการดีบักวาดแบทช์ดั้งเดิมทั้งหมดเพื่อลดจำนวนการโทรไปยัง RenderInterface ดังนั้นการวาดภาพจะเกิดขึ้นจริงตามเวลาที่คุณเรียก dd::flush() ซึ่งโดยปกติจะทำในตอนท้ายของเฟรมก่อนที่จะพลิกบัฟเฟอร์หน้าจอ:
// You only have to pass the current time if you have timed debug
// draws in the queues. Otherwise just omit the argument or pass 0.
dd::flush (getTimeMilliseconds());ดังนั้นการตั้งค่าโดยรวมควรมีลักษณะดังต่อไปนี้:
class MyRenderInterface : public dd ::RenderInterface
{
// Cherrypick the methods you want to implement or implement them all
...
};
int main ()
{
MyRenderInterface renderIface;
dd::initialize (&renderIface);
while (!quitting)
{
// Any other drawing that you already do
...
// Call any dd:: functions to add debug primitives to the draw queues
...
dd::flush ( getTimeMilliseconds ());
// Swap buffers to present the scene
...
}
dd::shutdown ();
} Debug Draw ให้สวิตช์คอมไพเลอร์หลายตัวสำหรับการกำหนดค่าไลบรารีและการปรับแต่ง ตรวจสอบเอกสารใน debug_draw.hpp สำหรับรายการสวิตช์ทั้งหมดพร้อมคำอธิบายโดยละเอียดของแต่ละรายการ
ห้องสมุดมีข้อกำหนดด้านภาษาน้อยมาก หนึ่งในเป้าหมายหลักของมันคือการไม่เจ็บปวดในการรวมและพกพา ข้อกำหนดเพียงอย่างเดียวคือคอมไพเลอร์ C ++ ล่าสุดที่มีการรองรับห้องสมุดมาตรฐานน้อยที่สุด มีการสันนิษฐานว่ามีคุณสมบัติ C ++ 11 เช่น nullptr และ <cstdint> ตัวอย่างรวมถึงการใช้ไลบรารีมาตรฐาน C ++ ที่หนักกว่าเพื่อแสดงให้เห็นถึงการดีบักการใช้งานด้วยเธรด
ไม่ได้ใช้ ข้อยกเว้น RTTI และ C ++ ดังนั้นคุณไม่ควรมีปัญหาในการรวมไลบรารีเข้ากับโครงการที่ปิดการใช้งานคุณสมบัติเหล่านั้น
รอยเท้าหน่วยความจำยังมีขนาดเล็กและคุณสามารถจัดการจำนวนหน่วยความจำที่ได้รับความมุ่งมั่นต่อคิวภายในผ่านคำสั่งประมวลผลล่วงหน้า ขณะนี้เราจัดสรรหน่วยความจำแบบไดนามิกจำนวนเล็กน้อยที่การเริ่มต้นไลบรารีเพื่อคลายตัวอักษรตัวอักษรสำหรับฟังก์ชั่นการวาดข้อความดีบั๊กและสำหรับการวาดคิวและข้อมูลบริบทของไลบรารี
โดยค่าเริ่มต้น Debug Draw จะใช้บริบทระดับโลกแบบคงที่ภายในโดยให้ API สไตล์ ขั้นตอนที่ไม่ปลอดภัย นี่คือโหมดการตรวจแก้จุดบกพร่องแบบ "คลาสสิก" ซึ่งง่ายที่สุดในการใช้งานและตั้งค่า แต่ไลบรารียังรองรับสองโหมดอื่น ๆ ที่มีเธรดที่ปลอดภัยและกำหนดค่าได้ในเวลาคอมไพล์:
DEBUG_DRAW_PER_THREAD_CONTEXT : หากสิ่งนี้ถูกกำหนดก่อนการใช้งานไลบรารีจะใช้บริบทเธรดท้องถิ่นแทนค่าเริ่มต้นที่แชร์ทั่วโลก สิ่งนี้ช่วยให้การเรียกไลบรารีจากเธรดที่แตกต่างกันเนื่องจากแต่ละบริบทจะเก็บบริบทส่วนตัวและวาดคิว โหมดนี้ให้อินเทอร์เฟซไลบรารีสาธารณะเดียวกัน แต่ต้องการการรองรับ TLS (Thread Local Storage) จากคอมไพเลอร์
DEBUG_DRAW_EXPLICIT_CONTEXT : หากสิ่งนี้ถูกกำหนดก่อนการใช้งานไลบรารีคาดว่าผู้ใช้จะจัดหาด้ามจับให้กับบริบท โหมดนี้แสดงประเภท dd::ContextHandle และเปลี่ยนแปลงแต่ละฟังก์ชั่นในไลบรารีเพื่อใช้งานนี้เป็นอาร์กิวเมนต์แรก โหมดนี้ทำให้ไลบรารีไร้สัญชาติอย่างสมบูรณ์เพื่อให้แต่ละเธรดการเรนเดอร์ที่เรียกเข้าสู่ไลบรารีสามารถสร้างและรักษาอินสแตนซ์ของการตรวจแก้จุดบกพร่อง
โหมดบริบทที่ชัดเจนคือ API ที่สะอาดและใช้งานได้ดีขึ้นและควรเป็นโหมดที่ต้องการสำหรับผู้ใช้ใหม่ โหมดขั้นตอนยังคงถูกเก็บไว้เป็นค่าเริ่มต้นสำหรับความเข้ากันได้กับเวอร์ชันไลบรารีรุ่นเก่า แต่ขอแนะนำให้คุณใช้โหมดบริบทที่ชัดเจนโดยการเพิ่ม #define DEBUG_DRAW_EXPLICIT_CONTEXT ร่วมกับ DEBUG_DRAW_IMPLEMENTATION ในอนาคต API ของรัฐขั้นตอนจะเลิกใช้เพื่อสนับสนุนอย่างชัดเจน
วาดกล่องที่มีชุดแกนพิกัดอยู่ตรงกลาง:
const ddVec3 boxColor = { 0 . 0f , 0 . 8f , 0 . 8f };
const ddVec3 boxCenter = { 0 . 0f , 0 . 0f , 3 . 0f };
dd::box (boxCenter, boxColor, 1 . 5f , 1 . 5f , 1 . 5f );
dd::cross (boxCenter, 1 . 0f ); ในการแสดงภาพการแปลงเมทริกซ์คุณสามารถใช้ dd::axisTriad() เพื่อวาดการแปลงเป็นสามลูกศร:
const ddMat4x4 transform = { // The identity matrix
1 . 0f , 0 . 0f , 0 . 0f , 0 . 0f ,
0 . 0f , 1 . 0f , 0 . 0f , 0 . 0f ,
0 . 0f , 0 . 0f , 1 . 0f , 0 . 0f ,
0 . 0f , 0 . 0f , 0 . 0f , 1 . 0f
};
dd::axisTriad (transform, 0 . 3f , 2 . 0f ); ตัวอย่างและตัวอย่างที่ซับซ้อนมากขึ้นเกี่ยวกับวิธีการรวมการตรวจแก้จุดบกพร่องกับการเรนเดอร์ของคุณเองสามารถพบได้ภายใน samples/ ไดเรกทอรี แต่ละฟังก์ชั่นที่มีให้ใน API สาธารณะยังได้รับการบันทึกไว้อย่างดีในไฟล์ส่วนหัว คุณจะพบความคิดเห็นส่วนหัวเชิงพรรณนาก่อนที่ต้นแบบของแต่ละฟังก์ชั่นสาธารณะที่ส่งออกโดยห้องสมุด