จิตรกรกราฟิก 2D ที่มีประสิทธิภาพน้อยที่สุดใน Pure C โดยใช้กราฟิก API ที่ทันสมัยผ่านห้องสมุด Sokol GFX ที่ยอดเยี่ยม
Sokol GP หรือใน SGP สั้นหมายถึงจิตรกรกราฟิก Sokol
Sokol GFX เป็นห้องสมุดที่ยอดเยี่ยมสำหรับการแสดงผลโดยใช้ท่อกราฟิกที่ไม่ได้ใช้งานของการ์ดที่ทันสมัย แต่มันซับซ้อนเกินกว่าที่จะใช้สำหรับการวาดภาพ 2D แบบง่ายและ API นั้นเป็นแบบทั่วไปและเชี่ยวชาญสำหรับการเรนเดอร์ 3 มิติ ในการวาดสิ่งของ 2D โปรแกรมเมอร์มักจะต้องตั้งค่า Shaders ที่กำหนดเองเมื่อใช้ Sokol GFX หรือใช้ห้องสมุด Extra Sokol GL แต่ Sokol GL ยังมี API ที่มีการออกแบบ 3D อยู่ในใจซึ่งมีค่าใช้จ่ายและข้อ จำกัด บางประการ
ไลบรารีนี้ถูกสร้างขึ้นเพื่อวาดภาพดั้งเดิม 2D ผ่าน Sokol GFX ได้อย่างง่ายดายและไม่ได้พิจารณาการใช้งาน 3D มันจะได้รับการปรับให้เหมาะสมสำหรับการเรนเดอร์ 2D เท่านั้นนอกจากนี้ยังมี เครื่องมือเพิ่มประสิทธิภาพแบทช์อัตโนมัติ รายละเอียดเพิ่มเติมจะอธิบายไว้ด้านล่าง
เมื่อวาดไลบรารีจะสร้างคิวคำสั่งการวาดของดั้งเดิมทั้งหมดที่ยังไม่สามารถวาดได้ทุกครั้งที่มีการเพิ่มคำสั่งการวาดใหม่จะเพิ่มเครื่องมือเพิ่มประสิทธิภาพแบทช์ให้ย้อนกลับไปถึงคำสั่งการวาดล่าสุด 8 ครั้งล่าสุด (สามารถปรับได้) และพยายามจัดเรียงคำสั่งการวาดรูปแบบใหม่
ด้วยการทำเช่นนี้เครื่องมือเพิ่มประสิทธิภาพแบตช์สามารถรวมการเรียกใช้การดึงพื้นผิวแม้ว่าพวกเขาจะถูกวาดด้วยพื้นผิวที่แตกต่างกันไปเป็นตัวกลางอื่น ๆ เอฟเฟกต์มีประสิทธิภาพมากขึ้นเมื่อวาดเนื่องจากการเรียกใช้การดึงน้อยลงจะถูกส่งไปยัง GPU
ไลบรารีนี้สามารถหลีกเลี่ยงการทำงานจำนวนมากในการสร้างระบบการวาดแบบ 2D ที่มีประสิทธิภาพโดยการรวมการดึงการเรียกใช้เบื้องหลังในรันไทม์โดยอัตโนมัติดังนั้นโปรแกรมเมอร์ไม่จำเป็นต้องจัดการการเรียกใช้แบบแบทช์ด้วยตนเอง
อัลกอริทึมการแบทช์นั้นรวดเร็ว แต่มีความซับซ้อนของ CPU O(n) CPU สำหรับคำสั่ง DAIN ใหม่ทุกครั้งที่เพิ่มโดยการ n ค่า SGP_BATCH_OPTIMIZER_DEPTH ในการทดลองที่ใช้ 8 เป็นค่าเริ่มต้นเป็นค่าเริ่มต้นที่ดี แต่คุณอาจต้องการลองค่าที่แตกต่างกันขึ้นอยู่กับกรณีของคุณ ไม่แนะนำให้ใช้ค่าที่สูงเกินไปเนื่องจากอัลกอริทึมอาจใช้เวลานานเกินไปในการสแกนคำสั่งการวาดก่อนหน้านี้และอาจใช้ทรัพยากร CPU มากขึ้น
เครื่องมือเพิ่มประสิทธิภาพแบบแบทช์สามารถปิดใช้งานได้โดยการตั้งค่า SGP_BATCH_OPTIMIZER_DEPTH เป็น 0 คุณสามารถใช้สิ่งนั้นเพื่อวัดผลกระทบ
ในไดเรกทอรีตัวอย่างของที่เก็บนี้มีตัวอย่างมาตรฐานที่ทดสอบการวาดภาพด้วยการเปิดใช้งาน/ปิดใช้งาน Bath Optimizer บนเครื่องของฉันที่เกณฑ์มาตรฐานสามารถเพิ่มประสิทธิภาพในปัจจัย 2.2x เมื่อเปิดใช้งาน ในเกมส่วนตัวบางเกมผลกำไรของเครื่องมือเพิ่มประสิทธิภาพแบตช์ได้รับการพิสูจน์แล้วว่าเพิ่มประสิทธิภาพ FPS สูงกว่า 1.5x โดยเพียงแค่เปลี่ยนแบ็กเอนด์กราฟิกด้วยห้องสมุดนี้โดยไม่มีการเปลี่ยนแปลงภายในเกม
ห้องสมุดมีตัวเลือกการออกแบบบางอย่างโดยมีประสิทธิภาพในใจซึ่งจะมีการหารือสั้น ๆ ที่นี่
เช่นเดียวกับ Sokol GFX, Sokol GP จะไม่ทำการจัดสรรใด ๆ ในลูปวาดดังนั้นเมื่อเริ่มต้นคุณจะต้องกำหนดค่าขนาดสูงสุดของบัฟเฟอร์คิวคำสั่ง DARK และบัฟเฟอร์จุดยอด
การแปลงอวกาศ 2D ทั้งหมด (ฟังก์ชั่นเช่น sgp_rotate ) ทำโดย CPU และไม่ใช่โดย GPU นี่เป็นความตั้งใจที่จะหลีกเลี่ยงการเพิ่มค่าใช้จ่ายเพิ่มเติมใน GPU เพราะโดยทั่วไปแล้วจำนวนจุดยอดของแอปพลิเคชัน 2D นั้นไม่ได้เพิ่มขึ้น CPU <-> บัส GPU ในทางตรงกันข้ามแอปพลิเคชัน 3D มักจะส่งการแปลงจุดสุดยอดไปยัง GPU โดยใช้ Vertex Shader พวกเขาทำเช่นนี้เนื่องจากปริมาณของจุดยอดของวัตถุ 3 มิติอาจมีขนาดใหญ่มากและมักจะเป็นตัวเลือกที่ดีที่สุด แต่นี่ไม่เป็นความจริงสำหรับการเรนเดอร์ 2D
APIs จำนวนมากเพื่อแปลงพื้นที่ 2D ก่อนที่จะวาดรูปแบบดั้งเดิมเช่นแปลการหมุนและสเกล พวกเขาสามารถใช้งานได้เช่นเดียวกับที่มีอยู่ใน API กราฟิก 3 มิติ แต่พวกเขาถูกสร้างขึ้นมาสำหรับ 2D เท่านั้นตัวอย่างเช่นเมื่อใช้ 2D เราไม่จำเป็นต้องใช้เมทริกซ์ 4x4 หรือ 3x3 เพื่อทำการแปลงจุดยอดแทนที่จะใช้รหัสพิเศษสำหรับ 2D
ท่อทั้งหมดมักจะใช้พื้นผิวที่เกี่ยวข้องแม้ในขณะที่วาดรูปแบบดั้งเดิมที่ไม่ได้เป็นพื้นผิวเพราะสิ่งนี้จะช่วยลดการเปลี่ยนแปลงไปป์ไลน์กราฟิกเมื่อผสมการโทรที่มีพื้นผิวและการโทรที่ไม่ใช่พื้นผิวการปรับปรุงประสิทธิภาพ
ห้องสมุดมีการเข้ารหัสในรูปแบบของส่วนหัวของ 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 เริ่มต้น/สิ้นสุดการเรนเดอร์, sgp_flush() จะส่งคำสั่ง DAIN ทั้งหมดไปยัง Sokol GFX จากนั้นโทรหา sgp_end() ทันทีเพื่อยกเลิกคิวคำสั่ง DARK
ตัวอย่างจริงของการตั้งค่านี้จะแสดงด้านล่าง
ต่อไปนี้เป็นตัวอย่างอย่างรวดเร็วเกี่ยวกับวิธีการเข้าสู่ห้องสมุดนี้ด้วยแอพ 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 โฟลเดอร์คุณสามารถค้นหาตัวอย่างที่สมบูรณ์ต่อไปนี้ซึ่งครอบคลุม API ทั้งหมดของห้องสมุด:
sgp_begin() ที่มีบัฟเฟอร์เฟรม ตัวอย่างเหล่านี้ใช้เป็นชุดทดสอบสำหรับห้องสมุดคุณสามารถสร้างได้โดย make
เป็นไปได้ว่าหลังจากการวาดจำนวนมากเรียกคำสั่งหรือบัฟเฟอร์จุดสุดยอดอาจล้นในกรณีนั้นไลบรารีจะตั้งค่าสถานะข้อผิดพลาดข้อผิดพลาดและจะดำเนินการต่อไปตามปกติ แต่เมื่อล้างคิวคำสั่งการวาดด้วย sgp_flush() จะไม่มีคำสั่ง DAIND สิ่งนี้สามารถเกิดขึ้นได้เนื่องจากไลบรารีใช้บัฟเฟอร์ที่จัดสรรไว้ล่วงหน้าในกรณีเช่นนี้ปัญหาสามารถแก้ไขได้โดยการเพิ่มบัฟเฟอร์คิวคำสั่งคำนำหน้าและบัฟเฟอร์จุดยอดเมื่อโทร sgp_setup()
การทำให้จำนวนการกด/ป๊อปของ sgp_push_transform() และ sgp_pop_transform() หรือการทำรัง sgp_begin() และ sgp_end() อาจนำไปสู่ข้อผิดพลาดมากเกินไปซึ่งเป็นความผิดพลาดในการใช้งาน
คุณสามารถเปิดใช้งาน macro 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 - Modulate สี ( dstRGB = srcRGB * dstRGB และ dstA = dstA )SGP_BLENDMODE_MUL สีคูณ ( dstRGB = (srcRGB * dstRGB) + (dstRGB * (1-srcA)) และ dstA = (srcA * dstA) + (dstA * (1-srcA)) ) คุณสามารถเปลี่ยนพื้นที่หน้าจอเพื่อวาดโดยเรียก sgp_viewport(x, y, width, height) คุณสามารถเปลี่ยนระบบพิกัดของพื้นที่ 2D ได้โดยเรียก sgp_project(left, right, top, bottom) ด้วย
คุณสามารถแปลหมุนหรือปรับขนาดพื้นที่ 2D ก่อนการโทรแบบวาดโดยใช้ฟังก์ชั่นการแปลงที่ไลบรารีให้เช่น 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()
เมื่อใช้ shader ที่กำหนดเองคุณต้องสร้างไปป์ไลน์สำหรับมันด้วย sgp_make_pipeline(desc) โดยใช้ Shader, โหมดผสมผสานและการวาดแบบดั้งเดิมที่เกี่ยวข้อง จากนั้นคุณควรโทรหา sgp_set_pipeline() ก่อนที่จะมีการเรียกใช้ Shader คุณมีหน้าที่รับผิดชอบในการใช้โหมดผสมผสานและการวาดแบบดั้งเดิมเป็นไปป์ไลน์ที่สร้างขึ้น
เครื่องแบบที่กำหนดเองสามารถส่งผ่านไปยัง shader ด้วย sgp_set_uniform(vs_data, vs_size, fs_data, fs_size) ที่ซึ่งคุณควรส่งตัวชี้ไปยังโครงสร้างที่มีสคีมาและขนาดเดียวกันกับที่กำหนดไว้ในจุดสุดยอด
แม้ว่าคุณสามารถสร้าง Shaders ที่กำหนดเองสำหรับแบ็กเอนด์กราฟิกแต่ละตัวด้วยตนเอง แต่ควรใช้ SHDC คอมไพเลอร์ Sokol Shader เนื่องจากสามารถสร้าง shaders สำหรับแบ็กเอนด์หลายรายการจากไฟล์. .glsl เดียวและมักจะใช้งานได้ดี
โดยค่าเริ่มต้นบัฟเฟอร์ชุดไลบรารีต่อการเรียกใช้การเรียกใช้มีเพียง 8 ชุดลอย (การกำหนดค่า SGP_UNIFORM_CONTENT_SLOTS ) และอาจต่ำเกินไปที่จะใช้กับ Shaders ที่กำหนดเอง นี่เป็นค่าเริ่มต้นเนื่องจากโดยทั่วไปแล้วผู้มาใหม่อาจไม่ต้องการใช้ Shaders 2D แบบกำหนดเองและการเพิ่มค่าที่มากขึ้นหมายถึงค่าใช้จ่ายที่มากขึ้น หากคุณใช้ shaders ที่กำหนดเองโปรดเพิ่มค่านี้ให้ใหญ่พอที่จะเก็บจำนวนเครื่องแบบของ shader ที่ใหญ่ที่สุดของคุณ
มาโครต่อไปนี้สามารถกำหนดได้ก่อนรวมถึงการเปลี่ยนพฤติกรรมห้องสมุด:
SGP_BATCH_OPTIMIZER_DEPTH - จำนวนคำสั่ง DAIC ที่เครื่องมือเพิ่มประสิทธิภาพแบทช์มองย้อนกลับไป ค่าเริ่มต้นคือ 8SGP_UNIFORM_CONTENT_SLOTS - จำนวนสูงสุดของการลอยที่สามารถเก็บไว้ในแต่ละบัฟเฟอร์การโทรหา ค่าเริ่มต้นคือ 8SGP_TEXTURE_SLOTS - จำนวนสูงสุดของพื้นผิวที่สามารถผูกมัดต่อการโทรหา ค่าเริ่มต้นคือ 4 MIT, ดูไฟล์ใบอนุญาตหรือไฟล์ 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. */ ห้องสมุดนี้ได้รับการทดสอบตั้งแต่ปี 2563 ในโครงการส่วนตัวและพิสูจน์แล้วว่ามีเสถียรภาพ
ห้องสมุดนี้ได้รับการสนับสนุนจาก MMORPG Game Medivia Online ฉันขอขอบคุณพวกเขาที่สนับสนุนงานของฉัน
ขอบคุณ @KKUKSHTEL สำหรับการสนับสนุนการเรียกใช้แบตช์การโทรด้วยคุณลักษณะสีที่แตกต่างกัน
ตรวจสอบให้แน่ใจว่าได้ชำระเงินให้กับโครงการ Sokol ที่ยอดเยี่ยมโดย @floooh มันมีส่วนหัวส่วนหัวเดียวที่มีประโยชน์มากมายที่ทำด้วยคุณภาพที่สามารถใช้สำหรับการพัฒนาเกม
คุณอาจต้องการตรวจสอบส่วนหัวเดียวของฉัน C Minicoro ส่วนหัวเดียวของฉันมันนำ coroutines stackful สำหรับ c ซึ่งมีประโยชน์มากสำหรับการทำให้เครื่องจักรสถานะ จำกัด ในเกม devlopment ง่ายขึ้น
sgp_set_uniform API เพิ่มโหมดการผสมผสานล่วงหน้าใหม่ นี่คือภาพหน้าจอบางส่วนของตัวอย่างทั้งหมดในไดเรกทอรี samples คลิกที่ภาพใด ๆ เพื่อดูจริง ๆ แล้วจะแสดงผลแบบเรียลไทม์ในเบราว์เซอร์ของคุณ
ตัวอย่างดั้งเดิม:
ตัวอย่างโหมดผสม:
ตัวอย่างเฟรมบัฟเฟอร์:
ตัวอย่างสี่เหลี่ยมผืนผ้า:
ตัวอย่างผลกระทบ:
ตัวอย่าง SDF:
ฉันเป็นนักพัฒนาโอเพ่นซอร์สเต็มเวลาจำนวนเงินบริจาคผ่าน GitHub ของฉันจะได้รับการชื่นชมและสามารถนำกำลังใจให้ฉันเพื่อสนับสนุนโครงการนี้และโครงการโอเพ่นซอร์สอื่น ๆ ฉันอาจยอมรับการสนับสนุนครั้งเดียวสำหรับคุณสมบัติขนาดเล็กหรือการปรับปรุงเล็กน้อยสอดคล้องกับเป้าหมายของโครงการในกรณีนี้ติดต่อฉัน