الحد الأدنى من منصة Cross Cross 2D رسام الرسومات في C Pure C باستخدام واجهة برمجة تطبيقات الرسومات الحديثة من خلال مكتبة Sokol GFX الممتازة.
Sokol GP ، أو في SGP القصير ، يرمز إلى رسام رسومات Sokol.
Sokol GFX هي مكتبة ممتازة لتقديمها باستخدام خطوط أنابيب غير مثبتة لبطاقات الرسومات الحديثة ، لكنها معقدة للغاية لاستخدامها في رسم ثنائي الأبعاد بسيط ، وواجهة برمجة التطبيقات (API) عامة ومتخصصة للغاية لتقديم ثلاثي الأبعاد. لرسم الأشياء ثنائية الأبعاد ، يحتاج المبرمج عادةً إلى إعداد تظليل مخصص عند استخدام Sokol GFX ، أو استخدام مكتبة Sokol GL إضافية ، ولكن لدى Sokol GL أيضًا واجهة برمجة تطبيقات مع وضع تصميم ثلاثي الأبعاد في الاعتبار ، مما يتحمل بعض التكاليف والقيود.
تم إنشاء هذه المكتبة لرسم بدائل ثنائية الأبعاد من خلال Sokol GFX بسهولة ، ومن خلال عدم التفكير في الاستخدام ثلاثي الأبعاد ، تم تحسينها لتقديم ثنائي الأبعاد فقط ، وعلاوة على ذلك ، فهي تتميز بمحسّن دفعات تلقائي ، وسيتم وصف المزيد من التفاصيل منه أدناه.
عند رسم المكتبة ، تنشئ قائمة انتظار أمر سحب لجميع البدائل التي لم يتم رسمها بعد ، في كل مرة يتم فيها إضافة أمر سحب جديد ، ينظر مُحسِّن الدُفعات إلى الوراء إلى أوامر السحب الثمانية الأخيرة (هذا قابل للتعديل) ، وحاول إعادة ترتيب أوامر الرسم إذا وجدت أمرًا سابقًا في السحب يفي بالمعايير التالية:
من خلال القيام بذلك ، يكون محسن الدُفعات قادرًا على سبيل المثال لدمج مكالمات السحب المحكم ، حتى لو تم رسمها مع وسائل وسيطة أخرى تعادل القوام بينهما. التأثير أكثر كفاءة عند الرسم ، لأنه سيتم إرسال مكالمات السحب الأقل إلى وحدة معالجة الرسومات ،
يمكن أن تتجنب هذه المكتبة الكثير من العمل المتمثل في إجراء نظام فعال للرسوم ثنائية الأبعاد ، عن طريق دمج مكالمات السحب تلقائيًا وراء الكواليس في وقت التشغيل ، وبالتالي فإن المبرمج لا يحتاج إلى إدارة مكالمات السحب المزدوجة يدويًا ، ولا يحتاج إلى فرز مكالمات السحب الملمس ، وستفعل المكتبة هذا خلف المشاهد.
خوارزمية التجميع سريعة ، ولكن لديها تعقيد O(n) CPU لكل أمر Draw جديد ، حيث n هو تكوين SGP_BATCH_OPTIMIZER_DEPTH . في التجارب التي تستخدم 8 لأن الافتراضي هو افتراضي جيد ، ولكن قد ترغب في تجربة قيم مختلفة اعتمادًا على قضيتك. لا ينصح باستخدام القيم المرتفعة جدًا ، لأن الخوارزمية قد تستغرق مسح أوامر السحب السابقة ، وقد تستهلك المزيد من موارد وحدة المعالجة المركزية.
يمكن تعطيل مُحسِّن الدُفعات عن طريق تعيين SGP_BATCH_OPTIMIZER_DEPTH إلى 0 ، يمكنك استخدام ذلك لقياس تأثيره.
في دليل العينات من هذا المستودع ، يوجد مثال معياري يختبر الرسم مع مُمكّن/تعطيل مُحسّن الحمام. على الجهاز الخاص بي ، تمكنت هذا المعيار من زيادة الأداء في عامل 2.2x عند تمكينه. في بعض مشاريع الألعاب الخاصة ، أثبتت مكاسب محسن الدُفعات زيادة أداء FPS أعلى من 1.5x عن طريق استبدال الواجهة الخلفية للرسومات بهذه المكتبة ، دون تغييرات داخلية على اللعبة نفسها.
تحتوي المكتبة على بعض خيارات التصميم مع وضع الأداء في الاعتبار التي سيتم مناقشتها لفترة وجيزة هنا.
مثل Sokol GFX ، لن يقوم Sokol GP أبدًا بأي تخصيص في حلقة السحب ، لذلك عند التهيئة ، يجب عليك تكوين مسبقًا الحد الأقصى لحجم مخزن قائمة انتظار أمر Draw و VECETICES.
يتم تنفيذ جميع تحويل المساحة ثنائية الأبعاد (وظائف مثل sgp_rotate ) بواسطة وحدة المعالجة المركزية وليس عن طريق وحدة معالجة الرسومات ، وهذا عن قصد لتجنب إضافة النفقات العامة الإضافية في وحدة معالجة الرسومات ، لأنه عادة ما يكون عدد رؤوس التطبيقات ثنائية الأبعاد لا تزيد عن ذلك إلى حد كبير ، وهو أكثر كفاءة في أداء جميع التحول مع وحدة المعالجة المركزية على الفور بدلاً من الضغط على GPU بشكل أكبر. وحدة المعالجة المركزية <-> GPU Bus. في المقابل ، عادة ما ترسل التطبيقات ثلاثية الأبعاد تحويلات قمة الرأس إلى وحدة معالجة الرسومات باستخدام تظليل قمة الرأس ، فهي تفعل ذلك لأن كمية رؤوس الكائنات ثلاثية الأبعاد يمكن أن تكون كبيرة جدًا وعادة ما تكون الخيار الأفضل ، ولكن هذا ليس صحيحًا لتقديم ثنائي الأبعاد.
تتوفر العديد من واجهات برمجة التطبيقات لتحويل مساحة ثنائية الأبعاد قبل رسم بدائية ، مثل الترجمة والدوران والحجم. يمكن استخدامها على نحو مماثل مثل تلك المتوفرة في واجهات برمجة تطبيقات الرسومات ثلاثية الأبعاد ، ولكن تم تصميمها لمدة 2D فقط ، على سبيل المثال عند استخدام 2D ، لا نحتاج إلى استخدام مصفوفة 4x4 أو 3x3 لإجراء تحويل قمة الرأس ، وبدلاً من ذلك ، يكون الرمز متخصصًا في 2D ويمكنه استخدام مصفوفة 2x3 ، وتوفير حسابات تعويذة إضافية.
تستخدم جميع خطوط الأنابيب دائمًا نسيجًا مرتبطًا به ، حتى عند رسم بدائيات غير محمية ، لأن هذا يقلل من خط أنابيب الرسومات يتغير عند خلط المكالمات المحكم والمكالمات غير المحمية ، وتحسين الكفاءة.
يتم ترميز المكتبة بأسلوب رؤوس Sokol GFX ، وإعادة استخدام العديد من وحدات الماكرو من هناك ، ويمكنك تغيير بعض الدلالات الخاصة بها مثل المخصص المخصص ، ووظيفة السجل المخصص ، وبعض التفاصيل الأخرى ، قراءة وثائق sokol_gfx.h للمزيد حول ذلك.
نسخ sokol_gp.h مع رؤوس Sokol الأخرى إلى نفس المجلد. قم بإعداد Sokol GFX كما تفعل عادة ، ثم إضافة مكالمة إلى sgp_setup(desc) مباشرة بعد sg_setup(desc) ، واتصل إلى sgp_shutdown() قبل sg_shutdown() . لاحظ أنه يجب عليك عادةً التحقق مما إذا كان SGP صالحًا بعد إنشائه باستخدام sgp_is_valid() والخروج بأمان مع خطأ إن لم يكن.
في وظيفة رسم الإطار الخاصة بك ، أضف sgp_begin(width, height) قبل استدعاء أي وظيفة رسم SGP ، ثم ارسم بداياتك. في نهاية الإطار (أو FrameBuffer) ، يجب عليك دائمًا استدعاء sgp_flush() بين تمريرة SOKOL GFX BEGIN/END ، ستقوم sgp_flush() بإرسال جميع أوامر الرسم إلى SOKOL GFX. ثم اتصل على sgp_end() على الفور لتجاهل قائمة انتظار أمر السحب.
سيتم عرض مثال فعلي لهذا الإعداد أدناه.
فيما يلي مثال سريع على كيفية هذه المكتبة مع تطبيق Sokol GFX و Sokol:
// This is an example on how to set up and use Sokol GP to draw a filled rectangle.
// Includes Sokol GFX, Sokol GP and Sokol APP, doing all implementations.
#define SOKOL_IMPL
#include "sokol_gfx.h"
#include "sokol_gp.h"
#include "sokol_app.h"
#include "sokol_glue.h"
#include "sokol_log.h"
#include <stdio.h> // for fprintf()
#include <stdlib.h> // for exit()
#include <math.h> // for sinf() and cosf()
// Called on every frame of the application.
static void frame ( void ) {
// Get current window size.
int width = sapp_width (), height = sapp_height ();
float ratio = width /( float ) height ;
// Begin recording draw commands for a frame buffer of size (width, height).
sgp_begin ( width , height );
// Set frame buffer drawing region to (0,0,width,height).
sgp_viewport ( 0 , 0 , width , height );
// Set drawing coordinate space to (left=-ratio, right=ratio, top=1, bottom=-1).
sgp_project ( - ratio , ratio , 1.0f , -1.0f );
// Clear the frame buffer.
sgp_set_color ( 0.1f , 0.1f , 0.1f , 1.0f );
sgp_clear ();
// Draw an animated rectangle that rotates and changes its colors.
float time = sapp_frame_count () * sapp_frame_duration ();
float r = sinf ( time ) * 0.5 + 0.5 , g = cosf ( time ) * 0.5 + 0.5 ;
sgp_set_color ( r , g , 0.3f , 1.0f );
sgp_rotate_at ( time , 0.0f , 0.0f );
sgp_draw_filled_rect ( -0.5f , -0.5f , 1.0f , 1.0f );
// Begin a render pass.
sg_pass pass = {. swapchain = sglue_swapchain ()};
sg_begin_pass ( & pass );
// Dispatch all draw commands to Sokol GFX.
sgp_flush ();
// Finish a draw command queue, clearing it.
sgp_end ();
// End render pass.
sg_end_pass ();
// Commit Sokol render.
sg_commit ();
}
// Called when the application is initializing.
static void init ( void ) {
// Initialize Sokol GFX.
sg_desc sgdesc = {
. environment = sglue_environment (),
. logger . func = slog_func
};
sg_setup ( & sgdesc );
if (! sg_isvalid ()) {
fprintf ( stderr , "Failed to create Sokol GFX context!n" );
exit ( -1 );
}
// Initialize Sokol GP, adjust the size of command buffers for your own use.
sgp_desc sgpdesc = { 0 };
sgp_setup ( & sgpdesc );
if (! sgp_is_valid ()) {
fprintf ( stderr , "Failed to create Sokol GP context: %sn" , sgp_get_error_message ( sgp_get_last_error ()));
exit ( -1 );
}
}
// Called when the application is shutting down.
static void cleanup ( void ) {
// Cleanup Sokol GP and Sokol GFX resources.
sgp_shutdown ();
sg_shutdown ();
}
// Implement application main through Sokol APP.
sapp_desc sokol_main ( int argc , char * argv []) {
( void ) argc ;
( void ) argv ;
return ( sapp_desc ){
. init_cb = init ,
. frame_cb = frame ,
. cleanup_cb = cleanup ,
. window_title = "Rectangle (Sokol GP)" ,
. logger . func = slog_func ,
};
} لتشغيل هذا المثال ، قم أولاً بنسخ رأس sokol_gp.h جنبًا إلى جنب مع رؤوس Sokol الأخرى إلى نفس المجلد ، ثم قم بتجميعها مع أي مترجم C باستخدام أعلام الربط المناسبة (اقرأ sokol_gfx.h ).
في samples المجلد ، يمكنك العثور على الأمثلة الكاملة التالية التي تغطي جميع واجهات برمجة التطبيقات للمكتبة:
sgp_begin() متعددة مع مخازن المؤقتة الإطار. يتم استخدام هذه الأمثلة كجناح اختبار للمكتبة ، يمكنك بناءها عن طريق كتابة make .
من الممكن أنه بعد العديد من مكالمات السحب ، قد يتفوق الأمر على Command أو Vertex Buffer ، في هذه الحالة ستضع المكتبة حالة خطأ خطأ وستستمر في العمل بشكل طبيعي ، ولكن عند مسح قائمة انتظار أمر الرسم باستخدام sgp_flush() لن يتم إرسال أمر رسم. يمكن أن يحدث هذا لأن المكتبة تستخدم المخازن المؤقتة المخصصة مسبقًا ، في مثل هذه الحالات ، يمكن إصلاح المشكلة عن طريق زيادة المخزن المؤقت لابد قائمة انتظار الأوامر المسبق والمخزن المؤقت للرؤوس عند استدعاء sgp_setup() .
قد يؤدي عمل عدد غير صالح من Push/pops من sgp_push_transform() و sgp_pop_transform() ، أو تعشش الكثير من sgp_begin() و sgp_end() أيضًا إلى أخطاء ، وهذا خطأ في الاستخدام.
يمكنك تمكين ماكرو SOKOL_DEBUG في مثل هذه الحالات للتصحيح ، أو التعامل مع الخطأ برمجيًا عن طريق قراءة sgp_get_last_error() بعد استدعاء sgp_end() . يُنصح أيضًا بمغادرة SOKOL_DEBUG الممكّنة عند التطوير مع Sokol ، حتى تتمكن من الالتقاط أخطاء مبكرًا.
تدعم المكتبة أكثر أوضاع المزيج المعتادة المستخدمة في 2D ، والتي هي ما يلي:
SGP_BLENDMODE_NONE - لا مزج ( dstRGBA = srcRGBA ).SGP_BLENDMODE_BLEND مزج ألفا ( dstRGB = (srcRGB * srcA) + (dstRGB * (1-srcA)) و dstA = srcA + (dstA * (1-srcA)) ))SGP_BLENDMODE_BLEND_PREMULTIPLIED مزج ألفا ما قبل الزرع ( dstRGBA = srcRGBA + (dstRGBA * (1-srcA)) ))SGP_BLENDMODE_ADD - مزج إضافي ( dstRGB = (srcRGB * srcA) + dstRGB و dstA = dstA )SGP_BLENDMODE_ADD_PREMULTIPLIED - مزج إضافي ما قبل الزرع ( dstRGB = srcRGB + dstRGB و dstA = dstA )SGP_BLENDMODE_MOD - تعديل اللون ( dstRGB = srcRGB * dstRGB و dstA = dstA )SGP_BLENDMODE_MUL -multiply color ( dstRGB = (srcRGB * dstRGB) + (dstRGB * (1-srcA)) و dstA = (srcA * dstA) + (dstA * (1-srcA)) ) يمكنك تغيير منطقة الشاشة لرسمها عن طريق الاتصال sgp_viewport(x, y, width, height) . يمكنك تغيير نظام الإحداثيات لمساحة ثنائية الأبعاد عن طريق استدعاء sgp_project(left, right, top, bottom) ، معها.
يمكنك ترجمة أو تدوير أو توسيع نطاق المساحة ثنائية الأبعاد قبل استدعاء السحب ، باستخدام وظائف التحول التي توفرها المكتبة ، مثل sgp_translate(x, y) ، sgp_rotate(theta) ، إلخ. تحقق من ورقة الغش أو الرأس لمزيد من المعلومات.
لحفظ واستعادة حالة التحويل ، يجب عليك الاتصال بـ sgp_push_transform() ثم sgp_pop_transform() لاحقًا.
توفر المكتبة وظائف الرسم لجميع البدائل الأساسية ، أي ، بالنسبة للنقاط ، الخطوط ، المثلثات والمستطيلات ، مثل sgp_draw_line() و sgp_draw_filled_rect() . تحقق من ورقة الغش أو الرأس للمزيد. كل منهم لديهم اختلافات مجنونة.
لرسم مستطيلات محكم ، يمكنك استخدام sgp_set_image(0, img) ثم sgp_draw_filled_rect() ، سيؤدي ذلك إلى رسم نسيج كامل إلى مستطيل. يجب عليك لاحقًا إعادة ضبط الصورة باستخدام sgp_reset_image(0) لاستعادة الصورة المرتبطة بالتقصير إلى الصورة البيضاء الافتراضية ، وإلا فإنك ستحصل على مواطن الخلل عند رسم لون صلب.
في حالة رغبتك في رسم مصدر معين من الملمس ، يجب عليك استخدام sgp_draw_textured_rect() بدلاً من ذلك.
يتم رسم القوام الافتراضي بشكل افتراضي باستخدام عينات مرشح أقرب بسيطة ، يمكنك تغيير أخذ العينات باستخدام sgp_set_sampler(0, smp) قبل رسم نسيج ، يوصى باستعادة العينات الافتراضية باستخدام sgp_reset_sampler(0) .
تحتوي جميع خطوط الأنابيب الشائعة على تعديل الألوان ، ويمكنك تعديل لون قبل السحب عن طريق ضبط لون الحالة الحالية باستخدام sgp_set_color(r,g,b,a) ، في وقت لاحق ، يجب إعادة تعيين اللون إلى الافتراضي (أبيض) باستخدام sgp_reset_color() .
عند استخدام تظليل مخصص ، يجب عليك إنشاء خط أنابيب له باستخدام sgp_make_pipeline(desc) ، باستخدام تظليل ، وضع مزيج وسحب بدائي مرتبط به. ثم يجب عليك الاتصال sgp_set_pipeline() قبل استدعاء السحب التظليل. أنت مسؤول عن استخدام وضع المزيج نفسه ورسم بدائي كخط أنابيب تم إنشاؤه.
يمكن تمرير الزي الرسمي المخصص إلى التظليل باستخدام sgp_set_uniform(vs_data, vs_size, fs_data, fs_size) ، حيث يجب عليك دائمًا تمرير مؤشر إلى بنية مع نفس المخطط وحجم واحد محدد في التظليلات المتمثلة في الإصدار.
على الرغم من أنه يمكنك إنشاء تظليلات مخصصة لكل الواجهة الخلفية للرسومات يدويًا ، إلا أنه يجب أن تستخدم استخدام Sokol Tader Shdc ، لأنه يمكن أن ينشئ تظليلًا للخلفيات المتعددة من ملف .glsl واحد ، وهذا يعمل بشكل جيد عادة.
بشكل افتراضي ، يحتوي العازلة الموحدة للمكتبة لكل استدعاء على 8 زي تعويم (تكوين SGP_UNIFORM_CONTENT_SLOTS ) ، وقد يكون ذلك منخفضًا جدًا لاستخدامه مع تظليلات مخصصة. هذا هو الافتراضي لأن القادمين الجدد عادة قد لا يرغبون في استخدام تظليل ثنائي الأبعاد مخصص ، وزيادة قيمة أكبر تعني المزيد من النفقات العامة. إذا كنت تستخدم تظليلًا مخصصًا ، فيرجى زيادة هذه القيمة لتكون كبيرة بما يكفي للاحتفاظ بعدد الزي الرسمي لأكبر تظليل.
يمكن تعريف وحدات الماكرو التالية قبل تغيير سلوك المكتبة:
SGP_BATCH_OPTIMIZER_DEPTH - عدد أوامر السحب التي ينظر إليها محسن الدُفعات. الافتراضي هو 8.SGP_UNIFORM_CONTENT_SLOTS - الحد الأقصى لعدد العوامات التي يمكن تخزينها في كل عازلة موحدة للاتصال. الافتراضي هو 8.SGP_TEXTURE_SLOTS - الحد الأقصى لعدد القوام الذي يمكن ربطه لكل مكالمة سحب. الافتراضي هو 4. معهد ماساتشوستس للتكنولوجيا ، راجع ملف الترخيص أو نهاية ملف sokol_gp.h .
فيما يلي قائمة سريعة لجميع وظائف المكتبة للرجوع إليها سريعة:
/* Initialization and de-initialization. */
void sgp_setup ( const sgp_desc * desc ); /* Initializes the SGP context, and should be called after `sg_setup`. */
void sgp_shutdown ( void ); /* Destroys the SGP context. */
bool sgp_is_valid ( void ); /* Checks if SGP context is valid, should be checked after `sgp_setup`. */
/* Error handling. */
sgp_error sgp_get_last_error ( void ); /* Returns last SGP error. */
const char * sgp_get_error_message ( sgp_error error ); /* Returns a message with SGP error description. */
/* Custom pipeline creation. */
sg_pipeline sgp_make_pipeline ( const sgp_pipeline_desc * desc ); /* Creates a custom shader pipeline to be used with SGP. */
/* Draw command queue management. */
void sgp_begin ( int width , int height ); /* Begins a new SGP draw command queue. */
void sgp_flush ( void ); /* Dispatch current Sokol GFX draw commands. */
void sgp_end ( void ); /* End current draw command queue, discarding it. */
/* 2D coordinate space projection */
void sgp_project ( float left , float right , float top , float bottom ); /* Set the coordinate space boundary in the current viewport. */
void sgp_reset_project ( void ); /* Resets the coordinate space to default (coordinate of the viewport). */
/* 2D coordinate space transformation. */
void sgp_push_transform ( void ); /* Saves current transform matrix, to be restored later with a pop. */
void sgp_pop_transform ( void ); /* Restore transform matrix to the same value of the last push. */
void sgp_reset_transform ( void ); /* Resets the transform matrix to identity (no transform). */
void sgp_translate ( float x , float y ); /* Translates the 2D coordinate space. */
void sgp_rotate ( float theta ); /* Rotates the 2D coordinate space around the origin. */
void sgp_rotate_at ( float theta , float x , float y ); /* Rotates the 2D coordinate space around a point. */
void sgp_scale ( float sx , float sy ); /* Scales the 2D coordinate space around the origin. */
void sgp_scale_at ( float sx , float sy , float x , float y ); /* Scales the 2D coordinate space around a point. */
/* State change for custom pipelines. */
void sgp_set_pipeline ( sg_pipeline pipeline ); /* Sets current draw pipeline. */
void sgp_reset_pipeline ( void ); /* Resets to the current draw pipeline to default (builtin pipelines). */
void sgp_set_uniform ( const void * vs_data , uint32_t vs_size , const void * fs_data , uint32_t fs_size ); /* Sets uniform buffer for a custom pipeline. */
void sgp_reset_uniform ( void ); /* Resets uniform buffer to default (current state color). */
/* State change functions for the common pipelines. */
void sgp_set_blend_mode ( sgp_blend_mode blend_mode ); /* Sets current blend mode. */
void sgp_reset_blend_mode ( void ); /* Resets current blend mode to default (no blending). */
void sgp_set_color ( float r , float g , float b , float a ); /* Sets current color modulation. */
void sgp_reset_color ( void ); /* Resets current color modulation to default (white). */
void sgp_set_image ( int channel , sg_image image ); /* Sets current bound image in a texture channel. */
void sgp_unset_image ( int channel ); /* Remove current bound image in a texture channel (no texture). */
void sgp_reset_image ( int channel ); /* Resets current bound image in a texture channel to default (white texture). */
void sgp_set_sampler ( int channel , sg_sampler sampler ); /* Sets current bound sampler in a texture channel. */
void sgp_unset_sampler ( int channel ); /* Remove current bound sampler in a texture channel (no sampler). */
void sgp_reset_sampler ( int channel ); /* Resets current bound sampler in a texture channel to default (nearest sampler). */
/* State change functions for all pipelines. */
void sgp_viewport ( int x , int y , int w , int h ); /* Sets the screen area to draw into. */
void sgp_reset_viewport ( void ); /* Reset viewport to default values (0, 0, width, height). */
void sgp_scissor ( int x , int y , int w , int h ); /* Set clip rectangle in the viewport. */
void sgp_reset_scissor ( void ); /* Resets clip rectangle to default (viewport bounds). */
void sgp_reset_state ( void ); /* Reset all state to default values. */
/* Drawing functions. */
void sgp_clear ( void ); /* Clears the current viewport using the current state color. */
void sgp_draw ( sg_primitive_type primitive_type , const sgp_vertex * vertices , uint32_t count ); /* Low level drawing function, capable of drawing any primitive. */
void sgp_draw_points ( const sgp_point * points , uint32_t count ); /* Draws points in a batch. */
void sgp_draw_point ( float x , float y ); /* Draws a single point. */
void sgp_draw_lines ( const sgp_line * lines , uint32_t count ); /* Draws lines in a batch. */
void sgp_draw_line ( float ax , float ay , float bx , float by ); /* Draws a single line. */
void sgp_draw_lines_strip ( const sgp_point * points , uint32_t count ); /* Draws a strip of lines. */
void sgp_draw_filled_triangles ( const sgp_triangle * triangles , uint32_t count ); /* Draws triangles in a batch. */
void sgp_draw_filled_triangle ( float ax , float ay , float bx , float by , float cx , float cy ); /* Draws a single triangle. */
void sgp_draw_filled_triangles_strip ( const sgp_point * points , uint32_t count ); /* Draws strip of triangles. */
void sgp_draw_filled_rects ( const sgp_rect * rects , uint32_t count ); /* Draws a batch of rectangles. */
void sgp_draw_filled_rect ( float x , float y , float w , float h ); /* Draws a single rectangle. */
void sgp_draw_textured_rects ( int channel , const sgp_textured_rect * rects , uint32_t count ); /* Draws a batch textured rectangle, each from a source region. */
void sgp_draw_textured_rect ( int channel , sgp_rect dest_rect , sgp_rect src_rect ); /* Draws a single textured rectangle from a source region. */
/* Querying functions. */
sgp_state * sgp_query_state ( void ); /* Returns the current draw state. */
sgp_desc sgp_query_desc ( void ); /* Returns description of the current SGP context. */ تم اختبار هذه المكتبة منذ عام 2020 في مشاريع خاصة ، وقد أثبتت أنها مستقرة.
تم رعاية هذه المكتبة في الأصل من قبل لعبة MMORPG Medivia Online ، أود أن أشكرهم على دعم عملي.
شكرًا @Kkukshtel على رعاية مكالمات السحب الدُحمية مع ميزة ألوان مختلفة.
تأكد من الخروج من مشروع Sokol الممتاز بواسطة floooh ، ويتميز بالعديد من مكتبات رأس C المفيدة المفيدة المصنوعة من الجودة التي يمكن استخدامها لتطوير اللعبة.
قد ترغب أيضًا في التحقق من Minicoro Library Minicoro من رأسك الفردي ، فهو يجلب coroutines مكاسبات لـ C ، وهو مفيد جدًا لتبسيط آلات الحالة المحدودة في DevLopment.
sgp_set_uniform ، أضيفت أوضاع مزيج جديد مسبقًا. فيما يلي بعض لقطات الشاشة لجميع العينات في دليل samples . انقر على أي من الصور لعرضها يتم تقديمها بالفعل في الوقت الفعلي في متصفحك.
عينة بدائية:
عينات أوضاع مزج:
عينة العازلة الإطار:
عينة المستطيل:
عينة التأثير:
عينة SDF:
أنا مطور مفتوح المصدر بدوام كامل ، سيتم تقدير أي مبلغ من التبرع من خلال جيثب الخاص بي ويمكن أن يجلب لي التشجيع على الاستمرار في دعم هذا ومشاريع المصادر الأخرى. قد أقبل رعاية لمرة واحدة للميزات الصغيرة أو التحسينات البسيطة التي تتماشى مع أهداف المشروع ، في هذه الحالة اتصل بي.