gs_idraw.h 103 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845
  1. /*==============================================================================================================
  2. * Copyright (c) 2020 John Jackson
  3. * GSIDraw: Immediate Mode Drawing Util for Gunslinger
  4. * File: gs_idraw.h
  5. * Github: https://github.com/MrFrenik/gunslinger
  6. * All Rights Reserved
  7. * MIT License
  8. * May all those that this source may reach be blessed by the LORD and find peace and joy in life.
  9. * Everyone who drinks of this water will be thirsty again; but whoever drinks of the water
  10. * that I will give him shall never thirst; John 4:13-14
  11. * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
  12. * documentation files (the "Software"), to deal in the Software without restriction, including without limitation
  13. * the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software,
  14. * and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
  15. * The above copyright, blessing, biblical verse, notice and this permission notice shall be included in all
  16. * copies or substantial portions of the Software.
  17. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
  18. * TO THE WARRANTIES OF MECHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
  19. * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
  20. * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
  21. * IN THE SOFTWARE.
  22. =================================================================================================================*/
  23. #ifndef GS_IDRAW_H
  24. #define GS_IDRAW_H
  25. /*
  26. USAGE: (IMPORTANT)
  27. =================================================================================================================
  28. Before including, define the gunslinger immediate draw implementation like this:
  29. #define GS_IMMEDIATE_DRAW_IMPL
  30. in EXACTLY ONE C or C++ file that includes this header, BEFORE the
  31. include, like this:
  32. #define GS_IMMEDIATE_DRAW_IMPL
  33. #include "gs_idraw.h"
  34. All other files should just #include "gs_idraw.h" without the #define.
  35. MUST include "gs.h" and declare GS_IMPL BEFORE this file, since this file relies on that:
  36. #define GS_IMPL
  37. #include "gs.h"
  38. #define GS_IMMEDIATE_DRAW_IMPL
  39. #include "gs_idraw.h"
  40. TODO (john):
  41. * Convert flush command to push back commands
  42. * On final flush, request update for vertex/index buffer data
  43. * Then iterate commands to submit pipelines + state to gfx backend
  44. ================================================================================================================
  45. */
  46. /*==== Interface ====*/
  47. gs_enum_decl(gsi_matrix_type,
  48. GSI_MATRIX_MODELVIEW,
  49. GSI_MATRIX_PROJECTION
  50. );
  51. typedef enum {
  52. GSI_VATTR_POSITION = 0x00,
  53. GSI_VATTR_UV,
  54. GSI_VATTR_COLOR
  55. } gsi_vattr_type;
  56. gs_enum_decl(gsi_layout_type,
  57. GSI_LAYOUT_VATTR, // Using vattr type directly
  58. GSI_LAYOUT_MESH // Using asset mesh types indirectly to be converted internally
  59. );
  60. // Need a configurable pipeline matrix
  61. /*
  62. depth | stencil | face cull | blend | prim
  63. e/d e/d e/d e/d l/t
  64. 2 ^ 5 = 32 generated pipeline choices.
  65. */
  66. enum {
  67. GSI_FLAG_NO_BIND_UNIFORMS = (1 << 0),
  68. GSI_FLAG_NO_BIND_CACHED_PIPELINES = (1 << 1)
  69. };
  70. // Hash bytes of state attr struct to get index key for pipeline
  71. typedef struct gsi_pipeline_state_attr_t
  72. {
  73. uint16_t depth_enabled;
  74. uint16_t stencil_enabled;
  75. uint16_t blend_enabled;
  76. uint16_t face_cull_enabled;
  77. uint16_t prim_type;
  78. } gsi_pipeline_state_attr_t;
  79. typedef struct gs_immediate_vert_t
  80. {
  81. gs_vec3 position;
  82. gs_vec2 uv;
  83. gs_color_t color;
  84. } gs_immediate_vert_t;
  85. typedef struct gs_immediate_cache_t
  86. {
  87. gs_dyn_array(gs_handle(gs_graphics_pipeline_t)) pipelines;
  88. gs_dyn_array(gs_mat4) modelview;
  89. gs_dyn_array(gs_mat4) projection;
  90. gs_dyn_array(gsi_matrix_type) modes;
  91. gs_vec2 uv;
  92. gs_color_t color;
  93. gs_handle(gs_graphics_texture_t) texture;
  94. gsi_pipeline_state_attr_t pipeline;
  95. } gs_immediate_cache_t;
  96. typedef struct gs_immediate_draw_static_data_t
  97. {
  98. gs_handle(gs_graphics_texture_t) tex_default;
  99. gs_asset_font_t font_default;
  100. gs_hash_table(gsi_pipeline_state_attr_t, gs_handle(gs_graphics_pipeline_t)) pipeline_table;
  101. gs_handle(gs_graphics_uniform_t) uniform;
  102. gs_handle(gs_graphics_uniform_t) sampler;
  103. gs_handle(gs_graphics_vertex_buffer_t) vbo;
  104. gs_handle(gs_graphics_index_buffer_t) ibo;
  105. } gs_immediate_draw_static_data_t;
  106. typedef struct gs_immediate_draw_t
  107. {
  108. gs_byte_buffer_t vertices;
  109. gs_dyn_array(uint16_t) indices;
  110. gs_dyn_array(gsi_vattr_type) vattributes;
  111. gs_immediate_cache_t cache;
  112. gs_command_buffer_t commands;
  113. uint32_t window_handle;
  114. gs_immediate_draw_static_data_t* data;
  115. uint32_t flags;
  116. } gs_immediate_draw_t;
  117. #ifndef GS_NO_SHORT_NAME
  118. typedef gs_immediate_draw_t gsid;
  119. #define gsi_create gs_immediate_draw_new
  120. #define gsi_free gs_immediate_draw_free
  121. #endif
  122. // Create / Init / Shutdown / Free
  123. GS_API_DECL gs_immediate_draw_t gs_immediate_draw_new();
  124. GS_API_DECL void gs_immediate_draw_free(gs_immediate_draw_t* gsi);
  125. GS_API_DECL void gs_immediate_draw_static_data_set(gs_immediate_draw_static_data_t* data);
  126. // Get pipeline from state
  127. GS_API_DECL gs_handle(gs_graphics_pipeline_t) gsi_get_pipeline(gs_immediate_draw_t* gsi, gsi_pipeline_state_attr_t state);
  128. // Get default font asset pointer
  129. GS_API_DECL gs_asset_font_t* gsi_default_font();
  130. // Core Vertex Functions
  131. GS_API_DECL void gsi_begin(gs_immediate_draw_t* gsi, gs_graphics_primitive_type type);
  132. GS_API_DECL void gsi_end(gs_immediate_draw_t* gsi);
  133. GS_API_DECL void gsi_tc2f(gs_immediate_draw_t* gsi, float u, float v);
  134. GS_API_DECL void gsi_tc2fv(gs_immediate_draw_t* gsi, gs_vec2 uv);
  135. GS_API_DECL void gsi_c4ub(gs_immediate_draw_t* gsi, uint8_t r, uint8_t g, uint8_t b, uint8_t a);
  136. GS_API_DECL void gsi_c4ubv(gs_immediate_draw_t* gsi, gs_color_t c);
  137. GS_API_DECL void gsi_v2f(gs_immediate_draw_t* gsi, float x, float y);
  138. GS_API_DECL void gsi_v2fv(gs_immediate_draw_t* gsi, gs_vec2 v);
  139. GS_API_DECL void gsi_v3f(gs_immediate_draw_t* gsi, float x, float y, float z);
  140. GS_API_DECL void gsi_v3fv(gs_immediate_draw_t* gsi, gs_vec3 v);
  141. GS_API_DECL void gsi_flush(gs_immediate_draw_t* gsi);
  142. GS_API_DECL void gsi_texture(gs_immediate_draw_t* gsi, gs_handle(gs_graphics_texture_t) texture);
  143. // Core pipeline functions
  144. GS_API_DECL void gsi_blend_enabled(gs_immediate_draw_t* gsi, bool enabled);
  145. GS_API_DECL void gsi_depth_enabled(gs_immediate_draw_t* gsi, bool enabled);
  146. GS_API_DECL void gsi_stencil_enabled(gs_immediate_draw_t* gsi, bool enabled);
  147. GS_API_DECL void gsi_face_cull_enabled(gs_immediate_draw_t* gsi, bool enabled);
  148. GS_API_DECL void gsi_defaults(gs_immediate_draw_t* gsi);
  149. GS_API_DECL void gsi_pipeline_set(gs_immediate_draw_t* gsi, gs_handle(gs_graphics_pipeline_t) pipeline); // Binds custom user pipeline, sets flag GSI_FLAG_NO_BIND_CACHED_PIPELINES
  150. GS_API_DECL void gsi_vattr_list(gs_immediate_draw_t* gsi, gsi_vattr_type* layout, size_t sz); // Sets user vertex attribute list for custom bound pipeline
  151. GS_API_DECL void gsi_vattr_list_mesh(gs_immediate_draw_t* gsi, gs_asset_mesh_layout_t* layout, size_t sz); // Same as above but uses mesh layout to determine which vertex attributes to bind and in what order
  152. // View/Scissor commands
  153. GS_API_DECL void gsi_set_view_scissor(gs_immediate_draw_t* gsi, uint32_t x, uint32_t y, uint32_t w, uint32_t h);
  154. // Final Submit / Merge
  155. GS_API_DECL void gsi_draw(gs_immediate_draw_t* gsi, gs_command_buffer_t* cb);
  156. GS_API_DECL void gsi_renderpass_submit(gs_immediate_draw_t* gsi, gs_command_buffer_t* cb, gs_vec4 viewport, gs_color_t clear_color);
  157. GS_API_DECL void gsi_renderpass_submit_ex(gs_immediate_draw_t* gsi, gs_command_buffer_t* cb, gs_vec4 viewport, gs_graphics_clear_action_t* action);
  158. // Core Matrix Functions
  159. GS_API_DECL void gsi_push_matrix(gs_immediate_draw_t* gsi, gsi_matrix_type type);
  160. GS_API_DECL void gsi_push_matrix_ex(gs_immediate_draw_t* gsi, gsi_matrix_type type, bool flush);
  161. GS_API_DECL void gsi_pop_matrix(gs_immediate_draw_t* gsi);
  162. GS_API_DECL void gsi_pop_matrix_ex(gs_immediate_draw_t* gsi, bool flush);
  163. GS_API_DECL void gsi_matrix_mode(gs_immediate_draw_t* gsi, gsi_matrix_type type);
  164. GS_API_DECL void gsi_load_matrix(gs_immediate_draw_t* gsi, gs_mat4 m);
  165. GS_API_DECL void gsi_mul_matrix(gs_immediate_draw_t* gsi, gs_mat4 m);
  166. GS_API_DECL void gsi_perspective(gs_immediate_draw_t* gsi, float fov, float aspect, float near, float far);
  167. GS_API_DECL void gsi_ortho(gs_immediate_draw_t* gsi, float left, float right, float bottom, float top, float near, float far);
  168. GS_API_DECL void gsi_rotatef(gs_immediate_draw_t* gsi, float angle, float x, float y, float z);
  169. GS_API_DECL void gsi_rotatev(gs_immediate_draw_t* gsi, float angle, gs_vec3 v);
  170. GS_API_DECL void gsi_translatef(gs_immediate_draw_t* gsi, float x, float y, float z);
  171. GS_API_DECL void gsi_translatev(gs_immediate_draw_t* gsi, gs_vec3 v);
  172. GS_API_DECL void gsi_scalef(gs_immediate_draw_t* gsi, float x, float y, float z);
  173. // Camera Utils
  174. GS_API_DECL void gsi_camera(gs_immediate_draw_t* gsi, gs_camera_t* cam, uint32_t width, uint32_t height);
  175. GS_API_DECL void gsi_camera2D(gs_immediate_draw_t* gsi, uint32_t width, uint32_t height);
  176. GS_API_DECL void gsi_camera3D(gs_immediate_draw_t* gsi, uint32_t width, uint32_t height);
  177. // Primitive Drawing Util
  178. GS_API_DECL void gsi_triangle(gs_immediate_draw_t* gsi, float x0, float y0, float x1, float y1, float x2, float y2, uint8_t r, uint8_t g, uint8_t b, uint8_t a, gs_graphics_primitive_type type);
  179. GS_API_DECL void gsi_trianglev(gs_immediate_draw_t* gsi, gs_vec2 a, gs_vec2 b, gs_vec2 c, gs_color_t color, gs_graphics_primitive_type type);
  180. GS_API_DECL void gsi_trianglex(gs_immediate_draw_t* gsi, float x0, float y0, float z0, float x1, float y1, float z1, float x2, float y2, float z2, float u0, float v0, float u1, float v1, float u2, float v2, uint8_t r, uint8_t g, uint8_t b, uint8_t a, gs_graphics_primitive_type type);
  181. GS_API_DECL void gsi_trianglevx(gs_immediate_draw_t* gsi, gs_vec3 v0, gs_vec3 v1, gs_vec3 v2, gs_vec2 uv0, gs_vec2 uv1, gs_vec2 uv2, gs_color_t color, gs_graphics_primitive_type type);
  182. GS_API_DECL void gsi_trianglevxmc(gs_immediate_draw_t* gsi, gs_vec3 v0, gs_vec3 v1, gs_vec3 v2, gs_vec2 uv0, gs_vec2 uv1, gs_vec2 uv2, gs_color_t c0, gs_color_t c1, gs_color_t c2, gs_graphics_primitive_type type);
  183. GS_API_DECL void gsi_line(gs_immediate_draw_t* gsi, float x0, float y0, float x1, float y1, uint8_t r, uint8_t g, uint8_t b, uint8_t a);
  184. GS_API_DECL void gsi_linev(gs_immediate_draw_t* gsi, gs_vec2 v0, gs_vec2 v1, gs_color_t c);
  185. GS_API_DECL void gsi_line3D(gs_immediate_draw_t* gsi, float x0, float y0, float z0, float x1, float y1, float z1, uint8_t r, uint8_t g, uint8_t b, uint8_t a);
  186. GS_API_DECL void gsi_line3Dv(gs_immediate_draw_t* gsi, gs_vec3 s, gs_vec3 e, gs_color_t color);
  187. GS_API_DECL void gsi_line3Ddir(gs_immediate_draw_t* gsi, gs_vec3 s, gs_vec3 dir, gs_color_t color);
  188. GS_API_DECL void gsi_line3Dmc(gs_immediate_draw_t* gsi, float x0, float y0, float z0, float x1, float y1, float z1, uint8_t r0, uint8_t g0, uint8_t b0, uint8_t a0, uint8_t r1, uint8_t g1, uint8_t b1, uint8_t a1);
  189. // Shape Drawing Util
  190. GS_API_DECL void gsi_rect(gs_immediate_draw_t* gsi, float x0, float y0, float x1, float y1, uint8_t r, uint8_t g, uint8_t b, uint8_t a, gs_graphics_primitive_type type);
  191. GS_API_DECL void gsi_rectv(gs_immediate_draw_t* gsi, gs_vec2 bl, gs_vec2 tr, gs_color_t color, gs_graphics_primitive_type type);
  192. GS_API_DECL void gsi_rectx(gs_immediate_draw_t* gsi, float l, float b, float r, float t, float u0, float v0, float u1, float v1, uint8_t _r, uint8_t _g, uint8_t _b, uint8_t _a, gs_graphics_primitive_type type);
  193. GS_API_DECL void gsi_rectvx(gs_immediate_draw_t* gsi, gs_vec2 bl, gs_vec2 tr, gs_vec2 uv0, gs_vec2 uv1, gs_color_t color, gs_graphics_primitive_type type);
  194. GS_API_DECL void gsi_rectvd(gs_immediate_draw_t* gsi, gs_vec2 xy, gs_vec2 wh, gs_vec2 uv0, gs_vec2 uv1, gs_color_t color, gs_graphics_primitive_type type);
  195. GS_API_DECL void gsi_rect3Dv(gs_immediate_draw_t* gsi, gs_vec3 min, gs_vec3 max, gs_vec2 uv0, gs_vec2 uv1, gs_color_t color, gs_graphics_primitive_type type);
  196. GS_API_DECL void gsi_rect3Dvd(gs_immediate_draw_t* gsi, gs_vec3 xyz, gs_vec3 whd, gs_vec2 uv0, gs_vec2 uv1, gs_color_t c, gs_graphics_primitive_type type);
  197. GS_API_DECL void gsi_circle(gs_immediate_draw_t* gsi, float cx, float cy, float radius, int32_t segments, uint8_t r, uint8_t g, uint8_t b, uint8_t a, gs_graphics_primitive_type type);
  198. GS_API_DECL void gsi_circlevx(gs_immediate_draw_t* gsi, gs_vec3 c, float radius, int32_t segments, gs_color_t color, gs_graphics_primitive_type type);
  199. GS_API_DECL void gsi_circle_sector(gs_immediate_draw_t* gsi, float cx, float cy, float radius, int32_t start_angle, int32_t end_angle, int32_t segments, uint8_t r, uint8_t g, uint8_t b, uint8_t a, gs_graphics_primitive_type type);
  200. GS_API_DECL void gsi_circle_sectorvx(gs_immediate_draw_t* gsi, gs_vec3 c, float radius, int32_t start_angle, int32_t end_angle, int32_t segments, gs_color_t color, gs_graphics_primitive_type type);
  201. GS_API_DECL void gsi_arc(gs_immediate_draw_t* gsi, float cx, float cy, float radius_inner, float radius_outer, float start_angle, float end_angle, int32_t segments, uint8_t r, uint8_t g, uint8_t b, uint8_t a,
  202. gs_graphics_primitive_type type);
  203. GS_API_DECL void gsi_box(gs_immediate_draw_t* gsi, float x0, float y0, float z0, float hx, float hy, float hz, uint8_t r, uint8_t g, uint8_t b, uint8_t a, gs_graphics_primitive_type type);
  204. GS_API_DECL void gsi_sphere(gs_immediate_draw_t* gsi, float cx, float cy, float cz, float radius, uint8_t r, uint8_t g, uint8_t b, uint8_t a, gs_graphics_primitive_type type);
  205. GS_API_DECL void gsi_icosphere(gs_immediate_draw_t* gsi, float cx, float cy, float cz, float radius, uint8_t sdivision,
  206. uint8_t r, uint8_t g, uint8_t b, uint8_t a, gs_graphics_primitive_type type);
  207. GS_API_DECL void gsi_bezier(gs_immediate_draw_t* gsi, float x0, float y0, float x1, float y1, uint8_t r, uint8_t g, uint8_t b, uint8_t a);
  208. GS_API_DECL void gsi_cylinder(gs_immediate_draw_t* gsi, float x, float y, float z, float r_top, float r_bottom, float height, int32_t sides, uint8_t r, uint8_t g, uint8_t b, uint8_t a, gs_graphics_primitive_type type);
  209. GS_API_DECL void gsi_cone(gs_immediate_draw_t* gsi, float x, float y, float z, float radius, float height, int32_t sides, uint8_t r, uint8_t g, uint8_t b, uint8_t a, gs_graphics_primitive_type type);
  210. // Draw planes/poly groups
  211. // Text Drawing Util
  212. GS_API_DECL void gsi_text(gs_immediate_draw_t* gsi, float x, float y, const char* text, const gs_asset_font_t* fp, bool32_t flip_vertical, uint8_t r, uint8_t g, uint8_t b, uint8_t a);
  213. // Paths
  214. /*
  215. GS_API_DECL void gsi_path_begin(gs_immediate_draw_t* gsi);
  216. GS_API_DECL void gsi_path_end(gs_immediate_draw_t* gsi);
  217. GS_API_DECL void gsi_path_moveto(gs_immediate_draw_t* gsi, float x, float y, float z);
  218. GS_API_DECL void gsi_path_lineto(gs_immediate_draw_t* gsi, float x, float y, float z);
  219. GS_API_DECL void gsi_path_arcto(gs_immediate_draw_t* gsi, float x, float y, float z);
  220. */
  221. // Private Internal Utilities (Not user facing)
  222. GS_API_DECL const char* GSGetDefaultCompressedFontDataTTFBase85();
  223. GS_API_DECL void GSDecode85(const unsigned char* src, unsigned char* dst);
  224. GS_API_DECL unsigned int GSDecode85Byte(char c);
  225. GS_API_DECL unsigned int gs_decompress_length(const unsigned char* input);
  226. GS_API_DECL unsigned int gs_decompress(unsigned char* output, unsigned char* input, unsigned int length);
  227. /*==== Implementation ====*/
  228. #ifdef GS_IMMEDIATE_DRAW_IMPL
  229. // Global instance of immediate draw static data
  230. gs_immediate_draw_static_data_t* g_gsi = NULL;
  231. #define GSI() g_gsi
  232. #ifndef gsi_smooth_circle_error_rate
  233. #define gsi_smooth_circle_error_rate 0.5f
  234. #endif
  235. const f32 gsi_deg2rad = (f32)GS_PI / 180.f;
  236. // Shaders
  237. #if (defined GS_PLATFORM_WEB || defined GS_PLATFORM_ANDROID)
  238. #define GSI_GL_VERSION_STR "#version 300 es\n"
  239. #else
  240. #define GSI_GL_VERSION_STR "#version 330 core\n"
  241. #endif
  242. #ifndef GSI_UNIFORM_MVP_MATRIX
  243. #define GSI_UNIFORM_MVP_MATRIX "u_mvp"
  244. #endif
  245. #ifndef GSI_UNIFORM_TEXTURE2D
  246. #define GSI_UNIFORM_TEXTURE2D "u_tex"
  247. #endif
  248. const char* gsi_v_fillsrc =
  249. GSI_GL_VERSION_STR
  250. "precision mediump float;\n"
  251. "layout(location = 0) in vec3 a_position;\n"
  252. "layout(location = 1) in vec2 a_uv;\n"
  253. "layout(location = 2) in vec4 a_color;\n"
  254. "uniform mat4 "
  255. GSI_UNIFORM_MVP_MATRIX
  256. ";\n"
  257. "out vec2 uv;\n"
  258. "out vec4 color;\n"
  259. "void main() {\n"
  260. " gl_Position = "
  261. GSI_UNIFORM_MVP_MATRIX
  262. "* vec4(a_position, 1.0);\n"
  263. " uv = a_uv;\n"
  264. " color = a_color;\n"
  265. "}\n";
  266. const char* gsi_f_fillsrc =
  267. GSI_GL_VERSION_STR
  268. "precision mediump float;\n"
  269. "in vec2 uv;\n"
  270. "in vec4 color;\n"
  271. "uniform sampler2D "
  272. GSI_UNIFORM_TEXTURE2D
  273. ";\n"
  274. "out vec4 frag_color;\n"
  275. "void main() {\n"
  276. " vec4 tex_col = texture("
  277. GSI_UNIFORM_TEXTURE2D
  278. ", uv);\n"
  279. " if (tex_col.a < 0.5) discard;\n"
  280. " frag_color = color * tex_col;\n"
  281. "}\n";
  282. gsi_pipeline_state_attr_t gsi_pipeline_state_default()
  283. {
  284. gsi_pipeline_state_attr_t attr = gs_default_val();
  285. attr.depth_enabled = false;
  286. attr.stencil_enabled = false;
  287. attr.blend_enabled = true;
  288. attr.face_cull_enabled = false;
  289. attr.prim_type = (uint16_t)GS_GRAPHICS_PRIMITIVE_TRIANGLES;
  290. return attr;
  291. }
  292. void gsi_reset(gs_immediate_draw_t* gsi)
  293. {
  294. gs_command_buffer_clear(&gsi->commands);
  295. gs_byte_buffer_clear(&gsi->vertices);
  296. gs_dyn_array_clear(gsi->indices);
  297. gs_dyn_array_clear(gsi->cache.modelview);
  298. gs_dyn_array_clear(gsi->cache.projection);
  299. gs_dyn_array_clear(gsi->cache.pipelines);
  300. gs_dyn_array_clear(gsi->cache.modes);
  301. gs_dyn_array_clear(gsi->vattributes);
  302. gs_dyn_array_push(gsi->cache.modelview, gs_mat4_identity());
  303. gs_dyn_array_push(gsi->cache.projection, gs_mat4_identity());
  304. gs_dyn_array_push(gsi->cache.modes, GSI_MATRIX_MODELVIEW);
  305. gsi->cache.texture = GSI()->tex_default;
  306. gsi->cache.pipeline = gsi_pipeline_state_default();
  307. gsi->cache.pipeline.prim_type = 0x00;
  308. gsi->cache.uv = gs_v2(0.f, 0.f);
  309. gsi->cache.color = GS_COLOR_WHITE;
  310. gsi->flags = 0x00;
  311. }
  312. void gs_immediate_draw_static_data_init()
  313. {
  314. GSI() = gs_malloc_init(gs_immediate_draw_static_data_t);
  315. // Create uniform buffer
  316. gs_graphics_uniform_layout_desc_t uldesc = gs_default_val();
  317. uldesc.type = GS_GRAPHICS_UNIFORM_MAT4;
  318. gs_graphics_uniform_desc_t udesc = gs_default_val();
  319. memcpy(udesc.name, GSI_UNIFORM_MVP_MATRIX, sizeof(GSI_UNIFORM_MVP_MATRIX));
  320. udesc.layout = &uldesc;
  321. GSI()->uniform = gs_graphics_uniform_create(&udesc);
  322. // Create sampler buffer
  323. gs_graphics_uniform_layout_desc_t sldesc = gs_default_val();
  324. sldesc.type = GS_GRAPHICS_UNIFORM_SAMPLER2D;
  325. gs_graphics_uniform_desc_t sbdesc = gs_default_val();
  326. memcpy(sbdesc.name, GSI_UNIFORM_TEXTURE2D, sizeof(GSI_UNIFORM_TEXTURE2D));
  327. sbdesc.layout = &sldesc;
  328. GSI()->sampler = gs_graphics_uniform_create(&sbdesc);
  329. // Create default texture (4x4 white)
  330. gs_color_t pixels[16] = gs_default_val();
  331. memset(pixels, 255, 16 * sizeof(gs_color_t));
  332. gs_graphics_texture_desc_t tdesc = gs_default_val();
  333. tdesc.width = 4;
  334. tdesc.height = 4;
  335. tdesc.format = GS_GRAPHICS_TEXTURE_FORMAT_RGBA8;
  336. tdesc.min_filter = GS_GRAPHICS_TEXTURE_FILTER_NEAREST;
  337. tdesc.mag_filter = GS_GRAPHICS_TEXTURE_FILTER_NEAREST;
  338. *tdesc.data = pixels;
  339. GSI()->tex_default = gs_graphics_texture_create(&tdesc);
  340. // Create shader
  341. gs_graphics_shader_source_desc_t vsrc; vsrc.type = GS_GRAPHICS_SHADER_STAGE_VERTEX; vsrc.source = gsi_v_fillsrc;
  342. gs_graphics_shader_source_desc_t fsrc; fsrc.type = GS_GRAPHICS_SHADER_STAGE_FRAGMENT; fsrc.source = gsi_f_fillsrc;
  343. gs_graphics_shader_source_desc_t gsi_sources[] = {
  344. vsrc, fsrc
  345. };
  346. gs_graphics_shader_desc_t sdesc = gs_default_val();
  347. sdesc.sources = gsi_sources;
  348. sdesc.size = sizeof(gsi_sources);
  349. memcpy(sdesc.name, "gs_immediate_default_fill_shader", sizeof("gs_immediate_default_fill_shader"));
  350. // Vertex attr layout
  351. gs_graphics_vertex_attribute_desc_t gsi_vattrs[3] = gs_default_val();
  352. gsi_vattrs[0].format = GS_GRAPHICS_VERTEX_ATTRIBUTE_FLOAT3; memcpy(gsi_vattrs[0].name, "a_position", sizeof("a_position"));
  353. gsi_vattrs[1].format = GS_GRAPHICS_VERTEX_ATTRIBUTE_FLOAT2; memcpy(gsi_vattrs[1].name, "a_uv", sizeof("a_uv"));
  354. gsi_vattrs[2].format = GS_GRAPHICS_VERTEX_ATTRIBUTE_BYTE4; memcpy(gsi_vattrs[2].name, "a_color", sizeof("a_color"));
  355. // Iterate through attribute list, then create custom pipelines requested.
  356. gs_handle(gs_graphics_shader_t) shader = gs_graphics_shader_create(&sdesc);
  357. // Pipelines
  358. for (uint16_t d = 0; d < 2; ++d) // Depth
  359. for (uint16_t s = 0; s < 2; ++s) // Stencil
  360. for (uint16_t b = 0; b < 2; ++b) // Blend
  361. for (uint16_t f = 0; f < 2; ++f) // Face Cull
  362. for (uint16_t p = 0; p < 2; ++p) // Prim Type
  363. {
  364. gsi_pipeline_state_attr_t attr = gs_default_val();
  365. attr.depth_enabled = d;
  366. attr.stencil_enabled = s;
  367. attr.blend_enabled = b;
  368. attr.face_cull_enabled = f;
  369. attr.prim_type = p ? (uint16_t)GS_GRAPHICS_PRIMITIVE_TRIANGLES : (uint16_t)GS_GRAPHICS_PRIMITIVE_LINES;
  370. // Create new pipeline based on this arrangement
  371. gs_graphics_pipeline_desc_t pdesc = gs_default_val();
  372. pdesc.raster.shader = shader;
  373. pdesc.raster.index_buffer_element_size = sizeof(uint16_t);
  374. pdesc.raster.face_culling = attr.face_cull_enabled ? GS_GRAPHICS_FACE_CULLING_BACK : (gs_graphics_face_culling_type)0x00;
  375. pdesc.raster.primitive = (gs_graphics_primitive_type)attr.prim_type;
  376. pdesc.blend.func = attr.blend_enabled ? GS_GRAPHICS_BLEND_EQUATION_ADD : (gs_graphics_blend_equation_type)0x00;
  377. pdesc.blend.src = GS_GRAPHICS_BLEND_MODE_SRC_ALPHA;
  378. pdesc.blend.dst = GS_GRAPHICS_BLEND_MODE_ONE_MINUS_SRC_ALPHA;
  379. pdesc.depth.func = d ? GS_GRAPHICS_DEPTH_FUNC_LESS : (gs_graphics_depth_func_type)0x00;
  380. pdesc.stencil.func = s ? GS_GRAPHICS_STENCIL_FUNC_ALWAYS : (gs_graphics_stencil_func_type)0x00;
  381. pdesc.stencil.ref = s ? 1 : 0x00;
  382. pdesc.stencil.comp_mask = s ? 0xFF : 0x00;
  383. pdesc.stencil.write_mask = s ? 0xFF : 0x00;
  384. pdesc.stencil.sfail = s ? GS_GRAPHICS_STENCIL_OP_KEEP : (gs_graphics_stencil_op_type)0x00;
  385. pdesc.stencil.dpfail = s ? GS_GRAPHICS_STENCIL_OP_KEEP : (gs_graphics_stencil_op_type)0x00;
  386. pdesc.stencil.dppass = s ? GS_GRAPHICS_STENCIL_OP_REPLACE : (gs_graphics_stencil_op_type)0x00;
  387. pdesc.layout.attrs = gsi_vattrs;
  388. pdesc.layout.size = sizeof(gsi_vattrs);
  389. gs_handle(gs_graphics_pipeline_t) hndl = gs_graphics_pipeline_create(&pdesc);
  390. gs_hash_table_insert(GSI()->pipeline_table, attr, hndl);
  391. }
  392. // Create default font
  393. gs_asset_font_t* f = &GSI()->font_default;
  394. stbtt_fontinfo font = gs_default_val();
  395. const char* compressed_ttf_data_base85 = GSGetDefaultCompressedFontDataTTFBase85();
  396. s32 compressed_ttf_size = (((s32)strlen(compressed_ttf_data_base85) + 4) / 5) * 4;
  397. void* compressed_ttf_data = gs_malloc((usize)compressed_ttf_size);
  398. GSDecode85((const unsigned char*)compressed_ttf_data_base85, (unsigned char*)compressed_ttf_data);
  399. const u32 buf_decompressed_size = gs_decompress_length((unsigned char*)compressed_ttf_data);
  400. unsigned char* buf_decompressed_data = (unsigned char*)gs_malloc(buf_decompressed_size);
  401. gs_decompress(buf_decompressed_data, (unsigned char*)compressed_ttf_data, (u32)compressed_ttf_size);
  402. const u32 w = 512;
  403. const u32 h = 512;
  404. const u32 num_comps = 4;
  405. u8* alpha_bitmap = (u8*)gs_malloc(w * h);
  406. u8* flipmap = (u8*)gs_malloc(w * h * num_comps);
  407. memset(alpha_bitmap, 0, w * h);
  408. memset(flipmap, 0, w * h * num_comps);
  409. s32 v = stbtt_BakeFontBitmap((u8*)buf_decompressed_data, 0, 13.f, alpha_bitmap, w, h, 32, 96, (stbtt_bakedchar*)f->glyphs); // no guarantee this fits!
  410. // Flip texture
  411. u32 r = h - 1;
  412. for (u32 i = 0; i < h; ++i)
  413. {
  414. for (u32 j = 0; j < w; ++j)
  415. {
  416. u32 i0 = i * w + j;
  417. u32 i1 = i * w * num_comps + j * num_comps;
  418. u8 a = alpha_bitmap[i0];
  419. flipmap[i1 + 0] = 255;
  420. flipmap[i1 + 1] = 255;
  421. flipmap[i1 + 2] = 255;
  422. flipmap[i1 + 3] = a;
  423. }
  424. r--;
  425. }
  426. gs_graphics_texture_desc_t desc = gs_default_val();
  427. desc.width = w;
  428. desc.height = h;
  429. *desc.data = flipmap;
  430. desc.format = GS_GRAPHICS_TEXTURE_FORMAT_RGBA8;
  431. desc.min_filter = GS_GRAPHICS_TEXTURE_FILTER_NEAREST;
  432. desc.mag_filter = GS_GRAPHICS_TEXTURE_FILTER_NEAREST;
  433. // Generate atlas texture for bitmap with bitmap data
  434. f->texture.hndl = gs_graphics_texture_create(&desc);
  435. f->texture.desc = desc;
  436. *f->texture.desc.data = NULL;
  437. // Create vertex buffer
  438. gs_graphics_vertex_buffer_desc_t vdesc = gs_default_val();
  439. vdesc.data = NULL;
  440. vdesc.size = 0;
  441. vdesc.usage = GS_GRAPHICS_BUFFER_USAGE_STREAM;
  442. GSI()->vbo = gs_graphics_vertex_buffer_create(&vdesc);
  443. gs_free(compressed_ttf_data);
  444. gs_free(buf_decompressed_data);
  445. gs_free(alpha_bitmap);
  446. gs_free(flipmap);
  447. }
  448. GS_API_DECL void
  449. gs_immediate_draw_static_data_set(gs_immediate_draw_static_data_t* data)
  450. {
  451. g_gsi = data;
  452. }
  453. // Create / Init / Shutdown / Free
  454. gs_immediate_draw_t gs_immediate_draw_new()
  455. {
  456. if (!GSI())
  457. {
  458. // Construct GSI
  459. gs_immediate_draw_static_data_init();
  460. }
  461. gs_immediate_draw_t gsi = gs_default_val();
  462. memset(&gsi, 0, sizeof(gsi));
  463. // Set gsi static data
  464. gsi.data = g_gsi;
  465. // Init cache
  466. gsi.cache.color = GS_COLOR_WHITE;
  467. // Init command buffer
  468. gsi.commands = gs_command_buffer_new(); // Not totally sure on the syntax for new vs. create
  469. gsi.vertices = gs_byte_buffer_new();
  470. // Set up cache
  471. gsi_reset(&gsi);
  472. return gsi;
  473. }
  474. GS_API_DECL void
  475. gs_immediate_draw_free(gs_immediate_draw_t* ctx)
  476. {
  477. gs_byte_buffer_free(&ctx->vertices);
  478. gs_dyn_array_free(ctx->indices);
  479. gs_dyn_array_free(ctx->vattributes);
  480. gs_command_buffer_free(&ctx->commands);
  481. gs_dyn_array_free(ctx->cache.pipelines);
  482. gs_dyn_array_free(ctx->cache.modelview);
  483. gs_dyn_array_free(ctx->cache.projection);
  484. gs_dyn_array_free(ctx->cache.modes);
  485. }
  486. GS_API_DECL gs_asset_font_t*
  487. gsi_default_font()
  488. {
  489. if (GSI()) return &GSI()->font_default;
  490. return NULL;
  491. }
  492. GS_API_DECL gs_handle(gs_graphics_pipeline_t)
  493. gsi_get_pipeline(gs_immediate_draw_t* gsi, gsi_pipeline_state_attr_t state)
  494. {
  495. // Bind pipeline
  496. gs_assert(gs_hash_table_key_exists(GSI()->pipeline_table, state));
  497. return gs_hash_table_get(GSI()->pipeline_table, state);
  498. }
  499. void gs_immediate_draw_set_pipeline(gs_immediate_draw_t* gsi)
  500. {
  501. if (gsi->flags & GSI_FLAG_NO_BIND_CACHED_PIPELINES)
  502. {
  503. return;
  504. }
  505. // Check validity
  506. if (gsi->cache.pipeline.prim_type != (uint16_t)GS_GRAPHICS_PRIMITIVE_TRIANGLES && gsi->cache.pipeline.prim_type != (uint16_t)GS_GRAPHICS_PRIMITIVE_LINES)
  507. {
  508. gsi->cache.pipeline.prim_type = (uint16_t)GS_GRAPHICS_PRIMITIVE_TRIANGLES;
  509. }
  510. gsi->cache.pipeline.depth_enabled = gs_clamp(gsi->cache.pipeline.depth_enabled, 0, 1);
  511. gsi->cache.pipeline.stencil_enabled = gs_clamp(gsi->cache.pipeline.stencil_enabled, 0, 1);
  512. gsi->cache.pipeline.face_cull_enabled = gs_clamp(gsi->cache.pipeline.face_cull_enabled, 0, 1);
  513. gsi->cache.pipeline.blend_enabled = gs_clamp(gsi->cache.pipeline.blend_enabled, 0, 1);
  514. // Bind pipeline
  515. gs_assert(gs_hash_table_key_exists(GSI()->pipeline_table, gsi->cache.pipeline));
  516. gs_graphics_pipeline_bind(&gsi->commands, gs_hash_table_get(GSI()->pipeline_table, gsi->cache.pipeline));
  517. }
  518. /* Core Vertex Functions */
  519. void gsi_begin(gs_immediate_draw_t* gsi, gs_graphics_primitive_type type)
  520. {
  521. switch (type) {
  522. default:
  523. case GS_GRAPHICS_PRIMITIVE_TRIANGLES: type = GS_GRAPHICS_PRIMITIVE_TRIANGLES; break;
  524. case GS_GRAPHICS_PRIMITIVE_LINES: type = GS_GRAPHICS_PRIMITIVE_LINES; break;
  525. }
  526. // Push a new pipeline?
  527. if (gsi->cache.pipeline.prim_type == type) {
  528. return;
  529. }
  530. // Otherwise, we need to flush previous content
  531. gsi_flush(gsi);
  532. // Set primitive type
  533. gsi->cache.pipeline.prim_type = type;
  534. // Bind pipeline
  535. gs_immediate_draw_set_pipeline(gsi);
  536. }
  537. void gsi_end(gs_immediate_draw_t* gsi)
  538. {
  539. // Not sure what to do here...
  540. }
  541. gs_mat4 gsi_get_modelview_matrix(gs_immediate_draw_t* gsi)
  542. {
  543. return gsi->cache.modelview[gs_dyn_array_size(gsi->cache.modelview) - 1];
  544. }
  545. gs_mat4 gsi_get_projection_matrix(gs_immediate_draw_t* gsi)
  546. {
  547. return gsi->cache.projection[gs_dyn_array_size(gsi->cache.projection) - 1];
  548. }
  549. gs_mat4 gsi_get_mvp_matrix(gs_immediate_draw_t* gsi)
  550. {
  551. gs_mat4* mv = &gsi->cache.modelview[gs_dyn_array_size(gsi->cache.modelview) - 1];
  552. gs_mat4* proj = &gsi->cache.projection[gs_dyn_array_size(gsi->cache.projection) - 1];
  553. return gs_mat4_mul(*proj, *mv);
  554. }
  555. void gsi_flush(gs_immediate_draw_t* gsi)
  556. {
  557. // Don't flush if verts empty
  558. if (gs_byte_buffer_empty(&gsi->vertices)) {
  559. return;
  560. }
  561. // Set up mvp matrix
  562. gs_mat4 mv = gsi->cache.modelview[gs_dyn_array_size(gsi->cache.modelview) - 1];
  563. gs_mat4 proj = gsi->cache.projection[gs_dyn_array_size(gsi->cache.projection) - 1];
  564. gs_mat4 mvp = gs_mat4_mul(proj, mv);
  565. // Update vertex buffer (command buffer version)
  566. gs_graphics_vertex_buffer_desc_t vdesc = gs_default_val();
  567. vdesc.data = gsi->vertices.data;
  568. vdesc.size = gs_byte_buffer_size(&gsi->vertices);
  569. vdesc.usage = GS_GRAPHICS_BUFFER_USAGE_STREAM;
  570. gs_graphics_vertex_buffer_request_update(&gsi->commands, GSI()->vbo, &vdesc);
  571. // Calculate draw count
  572. size_t vsz = sizeof(gs_immediate_vert_t);
  573. if (gs_dyn_array_size(gsi->vattributes))
  574. {
  575. // Calculate vertex stride
  576. size_t stride = 0;
  577. for (uint32_t i = 0; i < gs_dyn_array_size( gsi->vattributes ); ++i)
  578. {
  579. gsi_vattr_type type = gsi->vattributes[i];
  580. switch (type)
  581. {
  582. default: break;
  583. case GSI_VATTR_POSITION: stride += sizeof(gs_vec3); break;
  584. case GSI_VATTR_COLOR: stride += sizeof(gs_color_t); break;
  585. case GSI_VATTR_UV: stride += sizeof(gs_vec2); break;
  586. }
  587. }
  588. vsz = stride;
  589. }
  590. uint32_t ct = gs_byte_buffer_size(&gsi->vertices) / vsz;
  591. // Set up all binding data
  592. gs_graphics_bind_vertex_buffer_desc_t vbuffer = gs_default_val();
  593. vbuffer.buffer = GSI()->vbo;
  594. gs_graphics_bind_uniform_desc_t ubinds[2] = gs_default_val();
  595. ubinds[0].uniform = GSI()->uniform; ubinds[0].data = &mvp;
  596. ubinds[1].uniform = GSI()->sampler; ubinds[1].data = &gsi->cache.texture; ubinds[1].binding = 0;
  597. // Bindings for all buffers: vertex, uniform, sampler
  598. gs_graphics_bind_desc_t binds = gs_default_val();
  599. binds.vertex_buffers.desc = &vbuffer;
  600. // if (gs_dyn_array_empty(gsi->vattributes))
  601. if (~gsi->flags & GSI_FLAG_NO_BIND_UNIFORMS)
  602. {
  603. binds.uniforms.desc = ubinds;
  604. binds.uniforms.size = sizeof(ubinds);
  605. }
  606. // Bind bindings
  607. gs_graphics_apply_bindings(&gsi->commands, &binds);
  608. // Submit draw
  609. gs_graphics_draw_desc_t draw = gs_default_val();
  610. draw.start = 0; draw.count = ct;
  611. gs_graphics_draw(&gsi->commands, &draw);
  612. // Clear data
  613. gs_byte_buffer_clear(&gsi->vertices);
  614. }
  615. // Core pipeline functions
  616. void gsi_blend_enabled(gs_immediate_draw_t* gsi, bool enabled)
  617. {
  618. // Push a new pipeline?
  619. if (gsi->flags & GSI_FLAG_NO_BIND_CACHED_PIPELINES || gsi->cache.pipeline.blend_enabled == enabled) {
  620. return;
  621. }
  622. // Otherwise, we need to flush previous content
  623. gsi_flush(gsi);
  624. // Set primitive type
  625. gsi->cache.pipeline.blend_enabled = enabled;
  626. // Bind pipeline
  627. gs_immediate_draw_set_pipeline(gsi);
  628. }
  629. // Core pipeline functions
  630. void gsi_depth_enabled(gs_immediate_draw_t* gsi, bool enabled)
  631. {
  632. // Push a new pipeline?
  633. if (gsi->flags & GSI_FLAG_NO_BIND_CACHED_PIPELINES || gsi->cache.pipeline.depth_enabled == (uint16_t)enabled) {
  634. return;
  635. }
  636. // Otherwise, we need to flush previous content
  637. gsi_flush(gsi);
  638. // Set primitive type
  639. gsi->cache.pipeline.depth_enabled = (uint16_t)enabled;
  640. // Bind pipeline
  641. gs_immediate_draw_set_pipeline(gsi);
  642. }
  643. void gsi_stencil_enabled(gs_immediate_draw_t* gsi, bool enabled)
  644. {
  645. // Push a new pipeline?
  646. if (gsi->flags & GSI_FLAG_NO_BIND_CACHED_PIPELINES || gsi->cache.pipeline.stencil_enabled == (uint16_t)enabled) {
  647. return;
  648. }
  649. // Otherwise, we need to flush previous content
  650. gsi_flush(gsi);
  651. // Set primitive type
  652. gsi->cache.pipeline.stencil_enabled = (uint16_t)enabled;
  653. // Bind pipeline
  654. gs_immediate_draw_set_pipeline(gsi);
  655. }
  656. void gsi_face_cull_enabled(gs_immediate_draw_t* gsi, bool enabled)
  657. {
  658. // Push a new pipeline?
  659. if (gsi->flags & GSI_FLAG_NO_BIND_CACHED_PIPELINES || gsi->cache.pipeline.face_cull_enabled == (uint16_t)enabled) {
  660. return;
  661. }
  662. // Otherwise, we need to flush previous content
  663. gsi_flush(gsi);
  664. // Set primitive type
  665. gsi->cache.pipeline.face_cull_enabled = (uint16_t)enabled;
  666. // Bind pipeline
  667. gs_immediate_draw_set_pipeline(gsi);
  668. }
  669. GS_API_DECL void gsi_texture(gs_immediate_draw_t* gsi, gs_handle(gs_graphics_texture_t) texture)
  670. {
  671. // Push a new pipeline?
  672. if (gsi->cache.texture.id == texture.id) {
  673. return;
  674. }
  675. // Otherwise, we need to flush previous content
  676. gsi_flush(gsi);
  677. // Set texture
  678. gsi->cache.texture = texture.id && texture.id != UINT32_MAX ? texture : GSI()->tex_default;
  679. }
  680. GS_API_DECL void
  681. gsi_pipeline_set(gs_immediate_draw_t* gsi, gs_handle(gs_graphics_pipeline_t) pipeline)
  682. {
  683. gsi_flush(gsi);
  684. // Bind if valid
  685. if (pipeline.id)
  686. {
  687. gs_graphics_pipeline_bind(&gsi->commands, pipeline);
  688. gsi->flags |= GSI_FLAG_NO_BIND_CACHED_PIPELINES;
  689. }
  690. // Otherwise we set back to cache, clear vattributes, clear flag
  691. else
  692. {
  693. gsi->flags &= ~GSI_FLAG_NO_BIND_CACHED_PIPELINES;
  694. gs_dyn_array_clear(gsi->vattributes);
  695. gs_immediate_draw_set_pipeline(gsi);
  696. }
  697. }
  698. GS_API_DECL void
  699. gsi_vattr_list(gs_immediate_draw_t* gsi, gsi_vattr_type* list, size_t sz)
  700. {
  701. gsi_flush(gsi);
  702. gs_dyn_array_clear(gsi->vattributes);
  703. uint32_t ct = sz / sizeof(gsi_vattr_type);
  704. for (uint32_t i = 0; i < ct; ++i)
  705. {
  706. gs_dyn_array_push(gsi->vattributes, list[i]);
  707. }
  708. }
  709. GS_API_DECL void
  710. gsi_vattr_list_mesh(gs_immediate_draw_t* gsi, gs_asset_mesh_layout_t* layout, size_t sz)
  711. {
  712. gsi_flush(gsi);
  713. gs_dyn_array_clear(gsi->vattributes);
  714. #define VATTR_PUSH(TYPE)\
  715. do {\
  716. gs_dyn_array_push(gsi->vattributes, TYPE);\
  717. } while (0)
  718. uint32_t ct = sz / sizeof(gs_asset_mesh_layout_t);
  719. for (uint32_t i = 0; i < ct; ++i)
  720. {
  721. gs_asset_mesh_attribute_type type = layout[i].type;
  722. switch (type)
  723. {
  724. default:
  725. case GS_ASSET_MESH_ATTRIBUTE_TYPE_POSITION: VATTR_PUSH(GSI_VATTR_POSITION); break;
  726. case GS_ASSET_MESH_ATTRIBUTE_TYPE_TEXCOORD: VATTR_PUSH(GSI_VATTR_UV); break;
  727. case GS_ASSET_MESH_ATTRIBUTE_TYPE_COLOR: VATTR_PUSH(GSI_VATTR_COLOR); break;
  728. }
  729. }
  730. }
  731. GS_API_DECL void gsi_defaults(gs_immediate_draw_t* gsi)
  732. {
  733. gsi_flush(gsi);
  734. // Set defaults for cache
  735. gsi->cache.texture = GSI()->tex_default;
  736. gsi->cache.pipeline = gsi_pipeline_state_default();
  737. gsi->cache.pipeline.prim_type = 0x00;
  738. gsi->cache.uv = gs_v2(0.f, 0.f);
  739. gsi->cache.color = GS_COLOR_WHITE;
  740. gs_dyn_array_clear(gsi->vattributes);
  741. // Reset flags
  742. gsi->flags = 0x00;
  743. gs_immediate_draw_set_pipeline(gsi);
  744. }
  745. GS_API_DECL void gsi_tc2fv(gs_immediate_draw_t* gsi, gs_vec2 uv)
  746. {
  747. // Set cache register
  748. gsi->cache.uv = uv;
  749. }
  750. void gsi_tc2f(gs_immediate_draw_t* gsi, float u, float v)
  751. {
  752. // Set cache register
  753. gsi_tc2fv(gsi, gs_v2(u, v));
  754. }
  755. void gsi_c4ub(gs_immediate_draw_t* gsi, uint8_t r, uint8_t g, uint8_t b, uint8_t a)
  756. {
  757. // Set cache color
  758. gsi->cache.color = gs_color(r, g, b, a);
  759. }
  760. GS_API_DECL void gsi_c4ubv(gs_immediate_draw_t* gsi, gs_color_t c)
  761. {
  762. gsi_c4ub(gsi, c.r, c.g, c.b, c.a);
  763. }
  764. void gsi_v3fv(gs_immediate_draw_t* gsi, gs_vec3 p)
  765. {
  766. if (gs_dyn_array_size(gsi->vattributes))
  767. {
  768. // Iterate through attributes and push into stream
  769. for (uint32_t i = 0; i < gs_dyn_array_size(gsi->vattributes); ++i)
  770. {
  771. gsi_vattr_type type = gsi->vattributes[i];
  772. switch (type)
  773. {
  774. default:
  775. {
  776. } break;
  777. case GSI_VATTR_POSITION:
  778. {
  779. gs_byte_buffer_write(&gsi->vertices, gs_vec3, p);
  780. } break;
  781. case GSI_VATTR_COLOR:
  782. {
  783. gs_byte_buffer_write(&gsi->vertices, gs_color_t, gsi->cache.color);
  784. } break;
  785. case GSI_VATTR_UV:
  786. {
  787. gs_byte_buffer_write(&gsi->vertices, gs_vec2, gsi->cache.uv);
  788. } break;
  789. }
  790. }
  791. }
  792. else
  793. {
  794. gs_immediate_vert_t v = gs_default_val();
  795. v.position = p;
  796. v.uv = gsi->cache.uv;
  797. v.color = gsi->cache.color;
  798. gs_byte_buffer_write(&gsi->vertices, gs_immediate_vert_t, v);
  799. }
  800. }
  801. void gsi_v3f(gs_immediate_draw_t* gsi, float x, float y, float z)
  802. {
  803. // Push vert
  804. gsi_v3fv(gsi, gs_v3(x, y, z));
  805. }
  806. void gsi_v2f(gs_immediate_draw_t* gsi, float x, float y)
  807. {
  808. // Push vert
  809. gsi_v3f(gsi, x, y, 0.f);
  810. }
  811. void gsi_v2fv(gs_immediate_draw_t* gsi, gs_vec2 v)
  812. {
  813. // Push vert
  814. gsi_v3f(gsi, v.x, v.y, 0.f);
  815. }
  816. void gsi_push_matrix_ex(gs_immediate_draw_t* gsi, gsi_matrix_type type, bool flush)
  817. {
  818. // Flush
  819. if (flush)
  820. {
  821. gsi_flush(gsi);
  822. }
  823. // Push mode
  824. gs_dyn_array_push(gsi->cache.modes, type);
  825. // Pop matrix off of stack
  826. switch (gs_dyn_array_back(gsi->cache.modes))
  827. {
  828. case GSI_MATRIX_MODELVIEW:
  829. {
  830. gs_dyn_array_push(gsi->cache.modelview, gs_dyn_array_back(gsi->cache.modelview));
  831. } break;
  832. case GSI_MATRIX_PROJECTION:
  833. {
  834. gs_dyn_array_push(gsi->cache.projection, gs_dyn_array_back(gsi->cache.projection));
  835. } break;
  836. }
  837. }
  838. void gsi_push_matrix(gs_immediate_draw_t* gsi, gsi_matrix_type type)
  839. {
  840. gsi_push_matrix_ex(gsi, type, true);
  841. }
  842. void gsi_pop_matrix_ex(gs_immediate_draw_t* gsi, bool flush)
  843. {
  844. // Flush
  845. if (flush)
  846. {
  847. gsi_flush(gsi);
  848. }
  849. // Pop matrix off of stack
  850. switch (gs_dyn_array_back(gsi->cache.modes))
  851. {
  852. case GSI_MATRIX_MODELVIEW: {
  853. if (gs_dyn_array_size(gsi->cache.modelview) > 1) {
  854. gs_dyn_array_pop(gsi->cache.modelview);
  855. }
  856. } break;
  857. case GSI_MATRIX_PROJECTION: {
  858. if (gs_dyn_array_size(gsi->cache.projection) > 1) {
  859. gs_dyn_array_pop(gsi->cache.projection);
  860. }
  861. } break;
  862. }
  863. if (gs_dyn_array_size(gsi->cache.modes) > 1) {
  864. gs_dyn_array_pop(gsi->cache.modes);
  865. }
  866. }
  867. void gsi_pop_matrix(gs_immediate_draw_t* gsi)
  868. {
  869. gsi_pop_matrix_ex(gsi, true);
  870. }
  871. void gsi_load_matrix(gs_immediate_draw_t* gsi, gs_mat4 m)
  872. {
  873. // Load matrix at current mode
  874. switch (gs_dyn_array_back(gsi->cache.modes))
  875. {
  876. case GSI_MATRIX_MODELVIEW: {
  877. gs_mat4* mat = &gsi->cache.modelview[gs_dyn_array_size(gsi->cache.modelview) - 1];
  878. *mat = m;
  879. } break;
  880. case GSI_MATRIX_PROJECTION: {
  881. gs_mat4* mat = &gsi->cache.projection[gs_dyn_array_size(gsi->cache.projection) - 1];
  882. *mat = m;
  883. } break;
  884. }
  885. }
  886. void gsi_mul_matrix(gs_immediate_draw_t* gsi, gs_mat4 m)
  887. {
  888. static int i = 0;
  889. // Multiply current matrix at mode with m
  890. switch (gs_dyn_array_back(gsi->cache.modes))
  891. {
  892. case GSI_MATRIX_MODELVIEW: {
  893. gs_mat4* mat = &gsi->cache.modelview[gs_dyn_array_size(gsi->cache.modelview) - 1];
  894. *mat = gs_mat4_mul(*mat, m);
  895. } break;
  896. case GSI_MATRIX_PROJECTION: {
  897. gs_mat4* mat = &gsi->cache.projection[gs_dyn_array_size(gsi->cache.projection) - 1];
  898. *mat = gs_mat4_mul(*mat, m);
  899. } break;
  900. }
  901. }
  902. void gsi_perspective(gs_immediate_draw_t* gsi, float fov, float aspect, float n, float f)
  903. {
  904. // Set current matrix at mode to perspective
  905. gsi_load_matrix(gsi, gs_mat4_perspective(fov, aspect, n, f));
  906. }
  907. void gsi_ortho(gs_immediate_draw_t* gsi, float l, float r, float b, float t, float n, float f)
  908. {
  909. // Set current matrix at mode to ortho
  910. gsi_load_matrix(gsi, gs_mat4_ortho(l, r, b, t, n, f));
  911. }
  912. void gsi_rotatef(gs_immediate_draw_t* gsi, float angle, float x, float y, float z)
  913. {
  914. // Rotate current matrix at mode
  915. gsi_mul_matrix(gsi, gs_mat4_rotatev(angle, gs_v3(x, y, z)));
  916. }
  917. void gsi_rotatev(gs_immediate_draw_t* gsi, float angle, gs_vec3 v)
  918. {
  919. gsi_rotatef(gsi, angle, v.x, v.y, v.z);
  920. }
  921. void gsi_translatef(gs_immediate_draw_t* gsi, float x, float y, float z)
  922. {
  923. // Translate current matrix at mode
  924. gsi_mul_matrix(gsi, gs_mat4_translate(x, y, z));
  925. }
  926. void gsi_translatev(gs_immediate_draw_t* gsi, gs_vec3 v)
  927. {
  928. // Translate current matrix at mode
  929. gsi_mul_matrix(gsi, gs_mat4_translate(v.x, v.y, v.z));
  930. }
  931. void gsi_scalef(gs_immediate_draw_t* gsi, float x, float y, float z)
  932. {
  933. // Scale current matrix at mode
  934. gsi_mul_matrix(gsi, gs_mat4_scale(x, y, z));
  935. }
  936. void gsi_scalev(gs_immediate_draw_t* gsi, gs_vec3 v)
  937. {
  938. gsi_mul_matrix(gsi, gs_mat4_scalev(v));
  939. }
  940. void gsi_camera(gs_immediate_draw_t* gsi, gs_camera_t* cam, uint32_t width, uint32_t height)
  941. {
  942. // Just grab main window for now. Will need to grab top of viewport stack in future
  943. gsi_load_matrix(gsi, gs_camera_get_view_projection(cam, width, height));
  944. }
  945. void gsi_camera2D(gs_immediate_draw_t* gsi, uint32_t width, uint32_t height)
  946. {
  947. // Flush previous
  948. gsi_flush(gsi);
  949. f32 l = 0.f, r = (float)width, tp = 0.f, b = (float)height;
  950. gs_mat4 ortho = gs_mat4_ortho(
  951. l, r, b, tp, -1.f, 1.f
  952. );
  953. gsi_load_matrix(gsi, ortho);
  954. }
  955. void gsi_camera3D(gs_immediate_draw_t* gsi, uint32_t width, uint32_t height)
  956. {
  957. // Flush previous
  958. gsi_flush(gsi);
  959. gs_camera_t c = gs_camera_perspective();
  960. gsi_camera(gsi, &c, width, height);
  961. }
  962. // Shape Drawing Utils
  963. void gsi_triangle(gs_immediate_draw_t* gsi, float x0, float y0, float x1, float y1, float x2, float y2, uint8_t r, uint8_t g, uint8_t b, uint8_t a, gs_graphics_primitive_type type)
  964. {
  965. gsi_trianglex(gsi, x0, y0, 0.f, x1, y1, 0.f, x2, y2, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, r, g, b, a, type);
  966. }
  967. void gsi_trianglev(gs_immediate_draw_t* gsi, gs_vec2 a, gs_vec2 b, gs_vec2 c, gs_color_t color, gs_graphics_primitive_type type)
  968. {
  969. gsi_triangle(gsi, a.x, a.y, b.x, b.y, c.x, c.y, color.r, color.g, color.b, color.a, type);
  970. }
  971. void gsi_trianglex(gs_immediate_draw_t* gsi, float x0, float y0, float z0, float x1, float y1, float z1, float x2,
  972. float y2, float z2, float u0, float v0, float u1, float v1, float u2, float v2, uint8_t r, uint8_t g, uint8_t b, uint8_t a, gs_graphics_primitive_type type)
  973. {
  974. switch (type)
  975. {
  976. default:
  977. case GS_GRAPHICS_PRIMITIVE_TRIANGLES:
  978. {
  979. gsi_begin(gsi, GS_GRAPHICS_PRIMITIVE_TRIANGLES);
  980. gsi_c4ub(gsi, r, g, b, a);
  981. gsi_tc2f(gsi, u0, v0);
  982. gsi_v3f(gsi, x0, y0, z0);
  983. gsi_tc2f(gsi, u1, v1);
  984. gsi_v3f(gsi, x1, y1, z1);
  985. gsi_tc2f(gsi, u2, v2);
  986. gsi_v3f(gsi, x2, y2, z2);
  987. gsi_end(gsi);
  988. } break;
  989. case GS_GRAPHICS_PRIMITIVE_LINES:
  990. {
  991. gsi_line3D(gsi, x0, y0, z0, x1, y1, z1, r, g, b, a);
  992. gsi_line3D(gsi, x1, y1, z1, x2, y2, z2, r, g, b, a);
  993. gsi_line3D(gsi, x2, y2, z2, x0, y0, z0, r, g, b, a);
  994. } break;
  995. }
  996. }
  997. void gsi_trianglevx(gs_immediate_draw_t* gsi, gs_vec3 v0, gs_vec3 v1, gs_vec3 v2, gs_vec2 uv0, gs_vec2 uv1, gs_vec2 uv2, gs_color_t color, gs_graphics_primitive_type type)
  998. {
  999. gsi_trianglex(gsi, v0.x, v0.y, v0.z, v1.x, v1.y, v1.z, v2.x,
  1000. v2.y, v2.z, uv0.x, uv0.y, uv1.x, uv1.y, uv2.x, uv2.y, color.r, color.g, color.b, color.a, type);
  1001. }
  1002. GS_API_DECL void gsi_trianglevxmc(
  1003. gs_immediate_draw_t* gsi,
  1004. gs_vec3 v0, gs_vec3 v1, gs_vec3 v2,
  1005. gs_vec2 uv0, gs_vec2 uv1, gs_vec2 uv2,
  1006. gs_color_t c0, gs_color_t c1, gs_color_t c2,
  1007. gs_graphics_primitive_type type
  1008. )
  1009. {
  1010. switch (type)
  1011. {
  1012. default:
  1013. case GS_GRAPHICS_PRIMITIVE_TRIANGLES:
  1014. {
  1015. gsi_begin(gsi, GS_GRAPHICS_PRIMITIVE_TRIANGLES);
  1016. // First vert
  1017. gsi_c4ub(gsi, c0.r, c0.g, c0.b, c0.a);
  1018. gsi_tc2f(gsi, uv0.x, uv0.y);
  1019. gsi_v3f(gsi, v0.x, v0.y, v0.z);
  1020. // Second vert
  1021. gsi_c4ub(gsi, c1.r, c1.g, c1.b, c1.a);
  1022. gsi_tc2f(gsi, uv1.x, uv1.y);
  1023. gsi_v3f(gsi, v1.x, v1.y, v1.z);
  1024. // Third vert
  1025. gsi_c4ub(gsi, c2.r, c2.g, c2.b, c2.a);
  1026. gsi_tc2f(gsi, uv2.x, uv2.y);
  1027. gsi_v3f(gsi, v2.x, v2.y, v2.z);
  1028. gsi_end(gsi);
  1029. } break;
  1030. case GS_GRAPHICS_PRIMITIVE_LINES:
  1031. {
  1032. gsi_line3Dmc(gsi, v0.x, v0.y, v0.z, v1.x, v1.y, v1.z, c0.r, c0.g, c0.b, c0.a, c1.r, c1.g, c1.b, c1.a);
  1033. gsi_line3Dmc(gsi, v1.x, v1.y, v1.z, v2.x, v2.y, v2.z, c1.r, c1.g, c1.b, c1.a, c2.r, c2.g, c2.b, c2.a);
  1034. gsi_line3Dmc(gsi, v2.x, v2.y, v2.z, v0.x, v0.y, v0.z, c2.r, c2.g, c2.b, c2.a, c0.r, c0.g, c0.b, c0.a);
  1035. } break;
  1036. }
  1037. }
  1038. void gsi_line3Dmc(
  1039. gs_immediate_draw_t* gsi,
  1040. float x0, float y0, float z0,
  1041. float x1, float y1, float z1,
  1042. uint8_t r0, uint8_t g0, uint8_t b0, uint8_t a0,
  1043. uint8_t r1, uint8_t g1, uint8_t b1, uint8_t a1
  1044. )
  1045. {
  1046. gsi_begin(gsi, GS_GRAPHICS_PRIMITIVE_LINES);
  1047. gsi_tc2f(gsi, 0.f, 0.f);
  1048. // First vert
  1049. gsi_c4ub(gsi, r0, g0, b0, a0);
  1050. gsi_v3f(gsi, x0, y0, z0);
  1051. // Second vert
  1052. gsi_c4ub(gsi, r1, g1, b1, a1);
  1053. gsi_v3f(gsi, x1, y1, z1);
  1054. gsi_end(gsi);
  1055. }
  1056. void gsi_line3D(gs_immediate_draw_t* gsi, float x0, float y0, float z0, float x1, float y1, float z1, uint8_t r, uint8_t g, uint8_t b, uint8_t a)
  1057. {
  1058. gsi_begin(gsi, GS_GRAPHICS_PRIMITIVE_LINES);
  1059. gsi_tc2f(gsi, 0.f, 0.f);
  1060. gsi_c4ub(gsi, r, g, b, a);
  1061. gsi_v3f(gsi, x0, y0, z0);
  1062. gsi_v3f(gsi, x1, y1, z1);
  1063. gsi_end(gsi);
  1064. }
  1065. void
  1066. gsi_line3Dv(gs_immediate_draw_t* gsi, gs_vec3 s, gs_vec3 e, gs_color_t color)
  1067. {
  1068. gsi_line3D(gsi, s.x, s.y, s.z, e.x, e.y, e.z, color.r, color.g, color.b, color.a);
  1069. }
  1070. GS_API_DECL void
  1071. gsi_line3Ddir(gs_immediate_draw_t* gsi, gs_vec3 s, gs_vec3 d, gs_color_t color)
  1072. {
  1073. gsi_line3D(gsi, s.x, s.y, s.z, s.x + d.x, s.y + d.y, s.z + d.z, color.r, color.g, color.b, color.a);
  1074. }
  1075. void gsi_line(gs_immediate_draw_t* gsi, float x0, float y0, float x1, float y1, uint8_t r, uint8_t g, uint8_t b, uint8_t a)
  1076. {
  1077. gsi_line3D(gsi, x0, y0, 0.f, x1, y1, 0.f, r, g, b, a);
  1078. }
  1079. void gsi_linev(gs_immediate_draw_t* gsi, gs_vec2 v0, gs_vec2 v1, gs_color_t c)
  1080. {
  1081. gsi_line(gsi, v0.x, v0.y, v1.x, v1.y, c.r, c.g, c.b, c.a);
  1082. }
  1083. void gsi_rectx(gs_immediate_draw_t* gsi, float l, float b, float r, float t, float u0, float v0, float u1, float v1, uint8_t _r, uint8_t _g, uint8_t _b, uint8_t _a, gs_graphics_primitive_type type)
  1084. {
  1085. // Shouldn't use triangles, because need to declare texture coordinates.
  1086. switch (type)
  1087. {
  1088. case GS_GRAPHICS_PRIMITIVE_LINES:
  1089. {
  1090. // First triangle
  1091. gsi_line(gsi, l, b, r, b, _r, _g, _b, _a);
  1092. gsi_line(gsi, r, b, r, t, _r, _g, _b, _a);
  1093. gsi_line(gsi, r, t, l, t, _r, _g, _b, _a);
  1094. gsi_line(gsi, l, t, l, b, _r, _g, _b, _a);
  1095. // gsi_triangle(gsi, l, b, r, b, l, t, _r, _g, _b, _a, type);
  1096. // Second triangle
  1097. // gsi_triangle(gsi, r, b, r, t, l, t, _r, _g, _b, _a, type);
  1098. } break;
  1099. case GS_GRAPHICS_PRIMITIVE_TRIANGLES:
  1100. {
  1101. gsi_begin(gsi, GS_GRAPHICS_PRIMITIVE_TRIANGLES);
  1102. gsi_c4ub(gsi, _r, _g, _b, _a);
  1103. // First triangle
  1104. gsi_tc2f(gsi, u0, v0); gsi_v2f(gsi, l, b);
  1105. gsi_tc2f(gsi, u1, v0); gsi_v2f(gsi, r, b);
  1106. gsi_tc2f(gsi, u0, v1); gsi_v2f(gsi, l, t);
  1107. // Second triangle
  1108. gsi_tc2f(gsi, u1, v0); gsi_v2f(gsi, r, b);
  1109. gsi_tc2f(gsi, u1, v1); gsi_v2f(gsi, r, t);
  1110. gsi_tc2f(gsi, u0, v1); gsi_v2f(gsi, l, t);
  1111. gsi_end(gsi);
  1112. } break;
  1113. }
  1114. }
  1115. GS_API_DECL void
  1116. gsi_rect(gs_immediate_draw_t* gsi, float l, float b, float r, float t, uint8_t _r, uint8_t _g, uint8_t _b, uint8_t _a, gs_graphics_primitive_type type)
  1117. {
  1118. gsi_rectx(gsi, l, b, r, t, 0.f, 0.f, 1.f, 1.f, _r, _g, _b, _a, type);
  1119. }
  1120. GS_API_DECL void
  1121. gsi_rectv(gs_immediate_draw_t* gsi, gs_vec2 bl, gs_vec2 tr, gs_color_t color, gs_graphics_primitive_type type)
  1122. {
  1123. gsi_rectx(gsi, bl.x, bl.y, tr.x, tr.y, 0.f, 0.f, 1.f, 1.f, color.r, color.g, color.b, color.a, type);
  1124. }
  1125. GS_API_DECL void
  1126. gsi_rectvx(gs_immediate_draw_t* gsi, gs_vec2 bl, gs_vec2 tr, gs_vec2 uv0, gs_vec2 uv1, gs_color_t color, gs_graphics_primitive_type type)
  1127. {
  1128. gsi_rectx(gsi, bl.x, bl.y, tr.x, tr.y, uv0.x, uv0.y, uv1.x, uv1.y, color.r, color.g, color.b, color.a, type);
  1129. }
  1130. GS_API_DECL void
  1131. gsi_rectvd(gs_immediate_draw_t* gsi, gs_vec2 xy, gs_vec2 wh, gs_vec2 uv0, gs_vec2 uv1, gs_color_t color, gs_graphics_primitive_type type)
  1132. {
  1133. gsi_rectx(gsi, xy.x, xy.y, xy.x + wh.x, xy.y + wh.y, uv0.x, uv0.y, uv1.x, uv1.y, color.r, color.g, color.b, color.a, type);
  1134. }
  1135. GS_API_DECL void gsi_rect3Dv(gs_immediate_draw_t* gsi, gs_vec3 min, gs_vec3 max, gs_vec2 uv0, gs_vec2 uv1, gs_color_t c, gs_graphics_primitive_type type)
  1136. {
  1137. const gs_vec3 vt0 = min;
  1138. const gs_vec3 vt1 = gs_v3(max.x, min.y, min.z);
  1139. const gs_vec3 vt2 = gs_v3(min.x, max.y, max.z);
  1140. const gs_vec3 vt3 = max;
  1141. switch (type)
  1142. {
  1143. case GS_GRAPHICS_PRIMITIVE_LINES:
  1144. {
  1145. gsi_line3Dv(gsi, vt0, vt1, c);
  1146. gsi_line3Dv(gsi, vt1, vt2, c);
  1147. gsi_line3Dv(gsi, vt2, vt3, c);
  1148. gsi_line3Dv(gsi, vt3, vt0, c);
  1149. } break;
  1150. case GS_GRAPHICS_PRIMITIVE_TRIANGLES:
  1151. {
  1152. gsi_begin(gsi, GS_GRAPHICS_PRIMITIVE_TRIANGLES);
  1153. gsi_c4ub(gsi, c.r, c.g, c.b, c.a);
  1154. const float u0 = uv0.x;
  1155. const float u1 = uv1.x;
  1156. const float v0 = uv0.y;
  1157. const float v1 = uv1.y;
  1158. // First triangle
  1159. gsi_c4ub(gsi, c.r, c.g, c.b, c.a);
  1160. gsi_tc2f(gsi, u0, v0); gsi_v3fv(gsi, vt0);
  1161. gsi_tc2f(gsi, u0, v1); gsi_v3fv(gsi, vt2);
  1162. gsi_tc2f(gsi, u1, v0); gsi_v3fv(gsi, vt1);
  1163. // Second triangle
  1164. gsi_c4ub(gsi, c.r, c.g, c.b, c.a);
  1165. gsi_tc2f(gsi, u0, v1); gsi_v3fv(gsi, vt2);
  1166. gsi_tc2f(gsi, u1, v1); gsi_v3fv(gsi, vt3);
  1167. gsi_tc2f(gsi, u1, v0); gsi_v3fv(gsi, vt1);
  1168. gsi_end(gsi);
  1169. } break;
  1170. }
  1171. }
  1172. GS_API_DECL void
  1173. gsi_rect3Dvd(gs_immediate_draw_t* gsi, gs_vec3 xyz, gs_vec3 whd, gs_vec2 uv0, gs_vec2 uv1, gs_color_t c, gs_graphics_primitive_type type)
  1174. {
  1175. gsi_rect3Dv(gsi, xyz, gs_vec3_add(xyz, whd), uv0, uv1, c, type);
  1176. }
  1177. void gsi_circle_sector(gs_immediate_draw_t* gsi, float cx, float cy, float radius, int32_t start_angle,
  1178. int32_t end_angle, int32_t segments, uint8_t r, uint8_t g, uint8_t b, uint8_t a, gs_graphics_primitive_type type)
  1179. {
  1180. if (radius <= 0.0f) {
  1181. radius = 0.1f;
  1182. }
  1183. // Function expects (end_angle > start_angle)
  1184. if (end_angle < start_angle) {
  1185. // Swap values
  1186. int32_t tmp = start_angle;
  1187. start_angle = end_angle;
  1188. end_angle = tmp;
  1189. }
  1190. if (segments < 4) {
  1191. // Calculate the maximum angle between segments based on the error rate (usually 0.5f)
  1192. float th = acosf(2*powf(1 - gsi_smooth_circle_error_rate/radius, 2) - 1);
  1193. segments = (int32_t)((end_angle - start_angle)*ceilf(2*GS_PI/th)/360);
  1194. if (segments <= 0) {
  1195. segments = 4;
  1196. }
  1197. }
  1198. float step = (float)(end_angle - start_angle)/(float)segments;
  1199. float angle = (float)start_angle;
  1200. gs_for_range_i(segments)
  1201. {
  1202. gs_vec2 _a = gs_v2(cx, cy);
  1203. gs_vec2 _b = gs_v2(cx + sinf(gsi_deg2rad*angle)*radius, cy + cosf(gsi_deg2rad*angle)*radius);
  1204. gs_vec2 _c = gs_v2(cx + sinf(gsi_deg2rad*(angle + step))*radius, cy + cosf(gsi_deg2rad*(angle + step))*radius);
  1205. gsi_trianglev(gsi, _a, _b, _c, gs_color(r, g, b, a), type);
  1206. angle += step;
  1207. }
  1208. }
  1209. void gsi_circle_sectorvx(gs_immediate_draw_t* gsi, gs_vec3 c, float radius, int32_t start_angle,
  1210. int32_t end_angle, int32_t segments, gs_color_t color, gs_graphics_primitive_type type)
  1211. {
  1212. if (radius <= 0.0f) {
  1213. radius = 0.1f;
  1214. }
  1215. // Cache elements of center vector
  1216. float cx = c.x, cy = c.y, cz = c.z;
  1217. // Function expects (end_angle > start_angle)
  1218. if (end_angle < start_angle) {
  1219. // Swap values
  1220. int32_t tmp = start_angle;
  1221. start_angle = end_angle;
  1222. end_angle = tmp;
  1223. }
  1224. if (segments < 4) {
  1225. // Calculate the maximum angle between segments based on the error rate (usually 0.5f)
  1226. float th = acosf(2*powf(1 - gsi_smooth_circle_error_rate/radius, 2) - 1);
  1227. segments = (int32_t)((end_angle - start_angle)*ceilf(2*GS_PI/th)/360);
  1228. if (segments <= 0) {
  1229. segments = 4;
  1230. }
  1231. }
  1232. float step = (float)(end_angle - start_angle)/(float)segments;
  1233. float angle = (float)start_angle;
  1234. gs_for_range_i(segments)
  1235. {
  1236. gs_vec3 _a = gs_v3(cx, cy, cz);
  1237. gs_vec3 _b = gs_v3(cx + sinf(gsi_deg2rad*angle)*radius, cy + cosf(gsi_deg2rad*angle)*radius, cz);
  1238. gs_vec3 _c = gs_v3(cx + sinf(gsi_deg2rad*(angle + step))*radius, cy + cosf(gsi_deg2rad*(angle + step))*radius, cz);
  1239. gsi_trianglevx(gsi, _a, _b, _c, gs_v2s(0.f), gs_v2s(0.5f), gs_v2s(1.f), color, type);
  1240. angle += step;
  1241. }
  1242. }
  1243. void gsi_circle(gs_immediate_draw_t* gsi, float cx, float cy, float radius, int32_t segments, uint8_t r, uint8_t g, uint8_t b, uint8_t a, gs_graphics_primitive_type type)
  1244. {
  1245. gsi_circle_sector(gsi, cx, cy, radius, 0, 360, segments, r, g, b, a, type);
  1246. }
  1247. void gsi_circlevx(gs_immediate_draw_t* gsi, gs_vec3 c, float radius, int32_t segments, gs_color_t color, gs_graphics_primitive_type type)
  1248. {
  1249. gsi_circle_sectorvx(gsi, c, radius, 0, 360, segments, color, type);
  1250. }
  1251. GS_API_DECL void gsi_arc(gs_immediate_draw_t* gsi, float cx, float cy, float radius_inner, float radius_outer, float start_angle, float end_angle, int32_t segments, uint8_t r, uint8_t g, uint8_t b, uint8_t a, gs_graphics_primitive_type type)
  1252. {
  1253. if (start_angle == end_angle) return;
  1254. if (start_angle > end_angle) {
  1255. float tmp = end_angle;
  1256. end_angle = start_angle;
  1257. start_angle = tmp;
  1258. }
  1259. if (radius_outer < radius_inner) {
  1260. float tmp = radius_outer;
  1261. radius_outer = radius_inner;
  1262. radius_inner = tmp;
  1263. }
  1264. int32_t min_segments = (int32_t)((end_angle - start_angle) / 90.f);
  1265. if (segments < min_segments)
  1266. {
  1267. float th = acosf(2*powf(1 - gsi_smooth_circle_error_rate/radius_outer, 2) - 1);
  1268. segments = (int32_t)((end_angle - start_angle) * ceilf(2 * GS_PI/th)/360);
  1269. if (segments <= 0) segments = min_segments;
  1270. }
  1271. // Not a ring
  1272. if (radius_inner <= 0.0f)
  1273. {
  1274. // BALLS
  1275. gsi_circle_sector(gsi, cx, cy, radius_outer, (s32)start_angle, (s32)end_angle, segments, r, g, b, a, type);
  1276. return;
  1277. }
  1278. float step = (end_angle - start_angle)/(float)segments;
  1279. float angle = start_angle;
  1280. for (int i = 0; i < segments; i++)
  1281. {
  1282. float ar = gs_deg2rad(angle);
  1283. float ars = gs_deg2rad((angle + step));
  1284. gsi_trianglev(gsi,
  1285. gs_v2(cx + sinf(ar) * radius_inner, cy + cosf(ar) * radius_inner),
  1286. gs_v2(cx + sinf(ars) * radius_inner, cy + cosf(ars) * radius_inner),
  1287. gs_v2(cx + sinf(ar) * radius_outer, cy + cosf(ar) * radius_outer),
  1288. gs_color(r, g, b, a), type);
  1289. gsi_trianglev(gsi,
  1290. gs_v2(cx + sinf(ars) * radius_inner, cy + cosf(ars) * radius_inner),
  1291. gs_v2(cx + sinf(ars) * radius_outer, cy + cosf(ars) *radius_outer),
  1292. gs_v2(cx + sinf(ar) * radius_outer, cy + cosf(ar) * radius_outer),
  1293. gs_color(r, g, b, a), type);
  1294. angle += step;
  1295. }
  1296. }
  1297. void gsi_box(gs_immediate_draw_t* gsi, float x, float y, float z, float hx, float hy, float hz,
  1298. uint8_t r, uint8_t g, uint8_t b, uint8_t a, gs_graphics_primitive_type type)
  1299. {
  1300. float width = hx;
  1301. float height = hy;
  1302. float length = hz;
  1303. gs_vec3 v0 = gs_v3(x - width, y - height, z + length);
  1304. gs_vec3 v1 = gs_v3(x + width, y - height, z + length);
  1305. gs_vec3 v2 = gs_v3(x - width, y + height, z + length);
  1306. gs_vec3 v3 = gs_v3(x + width, y + height, z + length);
  1307. gs_vec3 v4 = gs_v3(x - width, y - height, z - length);
  1308. gs_vec3 v5 = gs_v3(x - width, y + height, z - length);
  1309. gs_vec3 v6 = gs_v3(x + width, y - height, z - length);
  1310. gs_vec3 v7 = gs_v3(x + width, y + height, z - length);
  1311. gs_color_t color = gs_color(r, g, b, a);
  1312. switch (type)
  1313. {
  1314. case GS_GRAPHICS_PRIMITIVE_TRIANGLES:
  1315. {
  1316. gsi_begin(gsi, GS_GRAPHICS_PRIMITIVE_TRIANGLES);
  1317. {
  1318. gs_vec2 uv0 = gs_v2(0.f, 0.f);
  1319. gs_vec2 uv1 = gs_v2(1.f, 0.f);
  1320. gs_vec2 uv2 = gs_v2(0.f, 1.f);
  1321. gs_vec2 uv3 = gs_v2(1.f, 1.f);
  1322. // Front Face
  1323. gsi_trianglevx(gsi, v0, v1, v2, uv0, uv1, uv2, color, type);
  1324. gsi_trianglevx(gsi, v3, v2, v1, uv3, uv2, uv1, color, type);
  1325. // Back face
  1326. gsi_trianglevx(gsi, v6, v5, v7, uv0, uv3, uv2, color, type);
  1327. gsi_trianglevx(gsi, v6, v4, v5, uv0, uv1, uv3, color, type);
  1328. // Top face
  1329. gsi_trianglevx(gsi, v7, v2, v3, uv0, uv3, uv2, color, type);
  1330. gsi_trianglevx(gsi, v7, v5, v2, uv0, uv1, uv3, color, type);
  1331. // Bottom face
  1332. gsi_trianglevx(gsi, v4, v1, v0, uv0, uv3, uv2, color, type);
  1333. gsi_trianglevx(gsi, v4, v6, v1, uv0, uv1, uv3, color, type);
  1334. // Right face
  1335. gsi_trianglevx(gsi, v1, v7, v3, uv0, uv3, uv2, color, type);
  1336. gsi_trianglevx(gsi, v1, v6, v7, uv0, uv1, uv3, color, type);
  1337. // Left face
  1338. gsi_trianglevx(gsi, v4, v2, v5, uv0, uv3, uv2, color, type);
  1339. gsi_trianglevx(gsi, v4, v0, v2, uv0, uv1, uv3, color, type);
  1340. }
  1341. gsi_end(gsi);
  1342. } break;
  1343. case GS_GRAPHICS_PRIMITIVE_LINES:
  1344. {
  1345. gs_color_t color = gs_color(r, g, b, a);
  1346. gsi_tc2f(gsi, 0.f, 0.f);
  1347. // Front face
  1348. gsi_line3Dv(gsi, v0, v1, color);
  1349. gsi_line3Dv(gsi, v1, v3, color);
  1350. gsi_line3Dv(gsi, v3, v2, color);
  1351. gsi_line3Dv(gsi, v2, v0, color);
  1352. // Back face
  1353. gsi_line3Dv(gsi, v4, v6, color);
  1354. gsi_line3Dv(gsi, v6, v7, color);
  1355. gsi_line3Dv(gsi, v7, v5, color);
  1356. gsi_line3Dv(gsi, v5, v4, color);
  1357. // Right face
  1358. gsi_line3Dv(gsi, v1, v6, color);
  1359. gsi_line3Dv(gsi, v6, v7, color);
  1360. gsi_line3Dv(gsi, v7, v3, color);
  1361. gsi_line3Dv(gsi, v3, v1, color);
  1362. // Left face
  1363. gsi_line3Dv(gsi, v4, v6, color);
  1364. gsi_line3Dv(gsi, v6, v1, color);
  1365. gsi_line3Dv(gsi, v1, v0, color);
  1366. gsi_line3Dv(gsi, v0, v4, color);
  1367. // Bottom face
  1368. gsi_line3Dv(gsi, v5, v7, color);
  1369. gsi_line3Dv(gsi, v7, v3, color);
  1370. gsi_line3Dv(gsi, v3, v2, color);
  1371. gsi_line3Dv(gsi, v2, v5, color);
  1372. // Top face
  1373. gsi_line3Dv(gsi, v0, v4, color);
  1374. gsi_line3Dv(gsi, v4, v5, color);
  1375. gsi_line3Dv(gsi, v5, v2, color);
  1376. gsi_line3Dv(gsi, v2, v0, color);
  1377. } break;
  1378. }
  1379. }
  1380. GS_API_DECL void
  1381. gsi_sphere(gs_immediate_draw_t* gsi, float cx, float cy, float cz,
  1382. float radius, uint8_t r, uint8_t g, uint8_t b, uint8_t a, gs_graphics_primitive_type type)
  1383. {
  1384. // Modified from: http://www.songho.ca/opengl/gl_sphere.html
  1385. const uint32_t stacks = 64;
  1386. const uint32_t sectors = 64;
  1387. float sector_step = 2.f * (float)GS_PI / (float)sectors;
  1388. float stack_step = (float)GS_PI / (float)stacks;
  1389. struct {
  1390. gs_vec3 p;
  1391. gs_vec2 uv;
  1392. } v0, v1, v2, v3;
  1393. gs_color_t color = gs_color(r, g, b, a);
  1394. // TODO(john): Need to get these verts to be positioned correctly (translate then rotate all verts to correct for odd 90 degree rotation)
  1395. #define make_vert(V, I, J, XZ, SECANGLE)\
  1396. do {\
  1397. /* vertex position (x, y, z) */\
  1398. V.p.x = cx + (XZ) * cosf((SECANGLE));\
  1399. V.p.z = cz + (XZ) * sinf((SECANGLE));\
  1400. /* vertex tex coord (s, t) range between [0, 1] */\
  1401. V.uv.x = (float)(J) / sectors;\
  1402. V.uv.y = (float)(I) / stacks;\
  1403. } while (0)
  1404. #define push_vert(V)\
  1405. do {\
  1406. gsi_tc2f(gsi, V.s, V.t);\
  1407. gsi_v3f(gsi, V.x, V.y, V.z);\
  1408. } while (0)
  1409. for (uint32_t i = 0; i < stacks; ++i)
  1410. {
  1411. float sa0 = GS_PI / 2.f - i * stack_step;
  1412. float sa1 = GS_PI / 2.f - (i + 1) * stack_step;
  1413. float xz0 = radius * cosf(sa0);
  1414. float xz1 = radius * cosf(sa1);
  1415. float y0 = cy + radius * sinf(sa0); // r * sin(u)
  1416. float y1 = cy + radius * sinf(sa1); // r * sin(u)
  1417. v0.p.y = y0;
  1418. v1.p.y = y0;
  1419. v2.p.y = y1;
  1420. v3.p.y = y1;
  1421. for(uint32_t j = 0; j < sectors; ++j)
  1422. {
  1423. float sca0 = j * sector_step; // starting from 0 to 2pi
  1424. float sca1 = (j + 1) * sector_step;
  1425. // Make verts
  1426. make_vert(v0, i, j, xz0, sca0);
  1427. make_vert(v1, i, j + 1, xz0, sca1);
  1428. make_vert(v2, i + 1, j, xz1, sca0);
  1429. make_vert(v3, i + 1, j + 1, xz1, sca1);
  1430. // First triangle
  1431. gsi_trianglevx(gsi, v0.p, v3.p, v2.p, v0.uv, v3.uv, v2.uv, color, type);
  1432. // Second triangle
  1433. gsi_trianglevx(gsi, v0.p, v1.p, v3.p, v0.uv, v1.uv, v3.uv, color, type);
  1434. }
  1435. }
  1436. }
  1437. GS_API_DECL void
  1438. gsi_icosphere(gs_immediate_draw_t* gsi, float cx, float cy, float cz, float radius, uint8_t sdivision,
  1439. uint8_t r, uint8_t g, uint8_t b, uint8_t a, gs_graphics_primitive_type type)
  1440. {
  1441. const float t = (1 + sqrt(5)) / 2.f; // Golden ratio
  1442. const float X = 0.525731112119133606f;
  1443. const float Z = 0.850650808352039932f;
  1444. const float N = 0.f;
  1445. const gs_color_t color = gs_color(r, g, b, a);
  1446. const float s = 1.f;
  1447. // const gs_vec3 vlist[] = {
  1448. // {-X, N, Z}, {X, N, Z}, {-X, N, -Z}, {X, N, -Z},
  1449. // {N, Z, X}, {N, Z, -X}, {N, -Z, X}, {N, -Z, -X},
  1450. // {Z, X, N}, {-Z, X, N}, {Z, -X, N}, {-Z, -X, N}
  1451. // };
  1452. const gs_vec3 vlist[] = {
  1453. {-s, t * s, 0}, {s, t * s, 0}, {-s, -t * s, 0}, {s, -t * s, 0},
  1454. {0, -s, t * s}, {0, s, t * s}, {0, -s, -t * s}, {0, s, -t * s},
  1455. {t * s, 0, -s}, {t * s, 0, s}, {-t * s, 0, -s}, {-t * s, 0, s}
  1456. };
  1457. // const gs_vec3 tlist[] = {
  1458. // {0, 4, 1}, {0, 9, 4}, {9, 5, 4}, {4, 5, 8}, {4, 8, 1},
  1459. // {8, 10, 1}, {8, 3, 10}, {5, 3, 8}, {5, 2, 3}, {2, 7, 3},
  1460. // {7, 10, 3}, {7, 6, 10}, {7, 11, 6}, {11, 0, 6}, {0, 1, 6},
  1461. // {6, 1, 10}, {9, 0, 11}, {9, 11, 2}, {9, 2, 5}, {7, 2, 11}
  1462. // };
  1463. const gs_vec3 tlist[] = {
  1464. {0, 11, 5}, {0, 5, 1}, {0, 1, 7}, {0, 7, 10}, {0, 10, 11},
  1465. {1, 5, 9}, {5, 11, 4}, {11, 10, 2}, {10, 7, 6}, {7, 1, 8},
  1466. {3, 9, 4}, {3, 4, 2}, {3, 2, 6}, {3, 6, 8}, {3, 8, 9},
  1467. {4, 9, 5}, {2, 4, 11}, {6, 2, 10}, {8, 6, 7}, {9, 8, 1}
  1468. };
  1469. const float w = 5.5f;
  1470. const float h = 3.f;
  1471. // const gs_vec2 uvlist[] = {
  1472. // {0.5f / w, 0.f}, {1.5f / w, 0.f}, {2.5f / w, 0.f}, {3.5f / w, 0.f}, {4.5f / w, 0.f},
  1473. // {0.f, 1.f / h}, {1.f / w, 1.f / h}, {2.f / w, 1.f / h}, {3.f / w, 1.f / h}, {4.f / w, 1.f / h}, {5.f / w, 1.f / h},
  1474. // {0.5f / w, 2.f / h}, {1.5f / w, 2.f / h}, {2.5f / w, 2.f / h}, {3.5f / w, 2.f / h}, {4.5f / w, 2.f / h},
  1475. // {1.f / w, 1.f}, {2.f / w, 1.f}, {3.f / w, 1.f}, {4.f / w, 1.f}, {5.f / w, 1.f}
  1476. // };
  1477. const gs_vec2 uvlist[] = {
  1478. {0.5f / w, 0},
  1479. {1.5f / w, 0},
  1480. {2.5f / w, 0},
  1481. {3.5f / w, 0},
  1482. {4.5f / w, 0},
  1483. {0, 1 / h},
  1484. {1.f / w, 1.f / h},
  1485. {2.f / w, 1.f / h},
  1486. {3.f / w, 1.f / h},
  1487. {4.f / w, 1.f / h},
  1488. {5.f / w, 1.f / h},
  1489. {0.5f / w, 2.f / h},
  1490. {1.5f / w, 2.f / h},
  1491. {2.5f / w, 2.f / h},
  1492. {3.5f / w, 2.f / h},
  1493. {4.5f / w, 2.f / h},
  1494. {1.f, 2.f / h},
  1495. {1.f / w, 1.f},
  1496. {2.f / w, 1.f},
  1497. {3.f / w, 1.f},
  1498. {4.f / w, 1.f},
  1499. {5.f / w, 1.f}
  1500. };
  1501. const gs_vec3 uvilist[] = {
  1502. //first row
  1503. {0, 5, 6}, {1, 6, 7}, {2, 7, 8}, {3, 8, 9}, {4, 9, 10},
  1504. //second row
  1505. {7, 6, 12}, {6, 5, 11}, {10, 9, 15}, {9, 8, 14}, {8, 7, 13},
  1506. //fourth row
  1507. {17, 12, 11}, {21, 16, 15}, {20, 15, 14}, {19, 14, 13}, {18, 13, 12},
  1508. //third row
  1509. {11, 12, 6}, {15, 16, 10}, {14, 15, 9}, {13, 14, 8}, {12, 13, 7}
  1510. };
  1511. // Matrix to determine UV projection
  1512. // #define UV(V)\
  1513. // gs_v2(atan2((V)->z / GS_TAU, (V)->x / GS_TAU),\
  1514. // asin((V)->y / GS_PI) + 0.5f)
  1515. #define UV(V)\
  1516. gs_v2(\
  1517. V.x / 2.f + 0.5,\
  1518. V.y / 2.f + 0.5\
  1519. )
  1520. const uint32_t cnt = sizeof(tlist) / sizeof(gs_vec3);
  1521. for (uint32_t i = 0; i < cnt; ++i) {
  1522. const gs_vec3* v0 = &vlist[(int32_t)tlist[i].x];
  1523. const gs_vec3* v1 = &vlist[(int32_t)tlist[i].y];
  1524. const gs_vec3* v2 = &vlist[(int32_t)tlist[i].z];
  1525. gs_vec3 nv0 = gs_vec3_scale(gs_vec3_norm(*v0), -1);
  1526. gs_vec3 nv1 = gs_vec3_scale(gs_vec3_norm(*v1), -1);
  1527. gs_vec3 nv2 = gs_vec3_scale(gs_vec3_norm(*v2), -1);
  1528. const gs_vec2 uv0 = UV(nv0);
  1529. const gs_vec2 uv1 = UV(nv1);
  1530. const gs_vec2 uv2 = UV(nv2);
  1531. // const gs_vec2* uv0 = &uvlist[(int32_t)uvilist[i].x];
  1532. // const gs_vec2* uv1 = &uvlist[(int32_t)uvilist[i].y];
  1533. // const gs_vec2* uv2 = &uvlist[(int32_t)uvilist[i].z];
  1534. gsi_trianglevx(gsi, *v0, *v1, *v2,
  1535. uv0, uv1, uv2, color, type);
  1536. }
  1537. }
  1538. // Modified from Raylib's implementation
  1539. void gsi_bezier(gs_immediate_draw_t* gsi, float x0, float y0, float x1, float y1, uint8_t r, uint8_t g, uint8_t b, uint8_t a)
  1540. {
  1541. gs_vec2 start = gs_v2(x0, y0);
  1542. gs_vec2 end = gs_v2(x1, y1);
  1543. gs_vec2 previous = start;
  1544. gs_vec2 current = gs_default_val();
  1545. gs_color_t color = gs_color(r, g, b, a);
  1546. const uint32_t bezier_line_divisions = 24;
  1547. for (int i = 1; i <= bezier_line_divisions; i++)
  1548. {
  1549. current.y = gs_ease_cubic_in_out((float)i, start.y, end.y - start.y, (float)bezier_line_divisions);
  1550. current.x = previous.x + (end.x - start.x)/ (float)bezier_line_divisions;
  1551. gsi_linev(gsi, previous, current, color);
  1552. previous = current;
  1553. }
  1554. }
  1555. GS_API_DECL void gsi_cylinder(gs_immediate_draw_t* gsi, float x, float y, float z, float r_top,
  1556. float r_bottom, float height, int32_t sides, uint8_t r, uint8_t g, uint8_t b, uint8_t a, gs_graphics_primitive_type type)
  1557. {
  1558. if (sides < 3) sides = 3;
  1559. int32_t numVertex = sides * 8;
  1560. const float hh = height * 0.5f;
  1561. switch (type)
  1562. {
  1563. default:
  1564. case GS_GRAPHICS_PRIMITIVE_TRIANGLES:
  1565. {
  1566. gsi_begin(gsi, GS_GRAPHICS_PRIMITIVE_TRIANGLES);
  1567. {
  1568. gsi_c4ub(gsi, r, g, b, a);
  1569. if (sides < 3) sides = 3;
  1570. numVertex = sides * 6;
  1571. if (r_top > 0)
  1572. {
  1573. // Draw Body -------------------------------------------------------------------------------------
  1574. for (int i = 0; i < 360; i += 360/sides)
  1575. {
  1576. gsi_v3f(gsi, x + sinf(gsi_deg2rad*i)*r_bottom, y - hh, z + cosf(gsi_deg2rad*i)*r_bottom); //Bottom Left
  1577. gsi_v3f(gsi, x + sinf(gsi_deg2rad*(i + 360.0f/sides))*r_bottom, y - hh, z + cosf(gsi_deg2rad*(i + 360.0f/sides))*r_bottom); //Bottom Right
  1578. gsi_v3f(gsi, x + sinf(gsi_deg2rad*(i + 360.0f/sides))*r_top, y + hh, z + cosf(gsi_deg2rad*(i + 360.0f/sides))*r_top); //Top Right
  1579. gsi_v3f(gsi, x + sinf(gsi_deg2rad*i)*r_top, y + hh, z + cosf(gsi_deg2rad*i)*r_top); //Top Left
  1580. gsi_v3f(gsi, x + sinf(gsi_deg2rad*i)*r_bottom, y - hh, z + cosf(gsi_deg2rad*i)*r_bottom); //Bottom Left
  1581. gsi_v3f(gsi, x + sinf(gsi_deg2rad*(i + 360.0f/sides))*r_top, y + hh, z + cosf(gsi_deg2rad*(i + 360.0f/sides))*r_top); //Top Right
  1582. }
  1583. // Draw Cap --------------------------------------------------------------------------------------
  1584. for (int i = 0; i < 360; i += 360/sides)
  1585. {
  1586. gsi_v3f(gsi, x + 0, y + hh, z + 0);
  1587. gsi_v3f(gsi, x + sinf(gsi_deg2rad*i)*r_top, y + hh, z + cosf(gsi_deg2rad*i)*r_top);
  1588. gsi_v3f(gsi, x + sinf(gsi_deg2rad*(i + 360.0f/sides))*r_top, y + hh, z + cosf(gsi_deg2rad*(i + 360.0f/sides))*r_top);
  1589. }
  1590. }
  1591. else
  1592. {
  1593. // Draw Cone -------------------------------------------------------------------------------------
  1594. for (int i = 0; i < 360; i += 360/sides)
  1595. {
  1596. gsi_v3f(gsi, x + 0, y + hh, z + 0);
  1597. gsi_v3f(gsi, x + sinf(gsi_deg2rad*i)*r_bottom, y - hh, z + cosf(gsi_deg2rad*i)*r_bottom);
  1598. gsi_v3f(gsi, x + sinf(gsi_deg2rad*(i + 360.0f/sides))*r_bottom, y - hh, z + cosf(gsi_deg2rad*(i + 360.0f/sides))*r_bottom);
  1599. }
  1600. }
  1601. // Draw Base -----------------------------------------------------------------------------------------
  1602. for (int i = 0; i < 360; i += 360/sides)
  1603. {
  1604. gsi_v3f(gsi, x + 0, y - hh, z + 0);
  1605. gsi_v3f(gsi, x + sinf(gsi_deg2rad*(i + 360.0f/sides))*r_bottom, y - hh, z + cosf(gsi_deg2rad*(i + 360.0f/sides))*r_bottom);
  1606. gsi_v3f(gsi, x + sinf(gsi_deg2rad*i)*r_bottom, y - hh, z + cosf(gsi_deg2rad*i)*r_bottom);
  1607. }
  1608. }
  1609. gsi_end(gsi);
  1610. } break;
  1611. case GS_GRAPHICS_PRIMITIVE_LINES:
  1612. {
  1613. gsi_begin(gsi, GS_GRAPHICS_PRIMITIVE_LINES);
  1614. {
  1615. gsi_c4ub(gsi, r, g, b, a);
  1616. for (int32_t i = 0; i < 360; i += 360/sides)
  1617. {
  1618. gsi_v3f(gsi, x + sinf(gsi_deg2rad*i)*r_bottom, y - hh, cosf(gsi_deg2rad*i)*r_bottom);
  1619. gsi_v3f(gsi, x + sinf(gsi_deg2rad*(i + 360.0f/sides))*r_bottom, y - hh, z + cosf(gsi_deg2rad*(i + 360.0f/sides))*r_bottom);
  1620. gsi_v3f(gsi, x + sinf(gsi_deg2rad*(i + 360.0f/sides))*r_bottom, y - hh, z + cosf(gsi_deg2rad*(i + 360.0f/sides))*r_bottom);
  1621. gsi_v3f(gsi, x + sinf(gsi_deg2rad*(i + 360.0f/sides))*r_top, y + hh, z + cosf(gsi_deg2rad*(i + 360.0f/sides))*r_top);
  1622. gsi_v3f(gsi, x + sinf(gsi_deg2rad*(i + 360.0f/sides))*r_top, y + hh, z + cosf(gsi_deg2rad*(i + 360.0f/sides))*r_top);
  1623. gsi_v3f(gsi, x + sinf(gsi_deg2rad*i)*r_top, y + hh, z + cosf(gsi_deg2rad*i)*r_top);
  1624. gsi_v3f(gsi, x + sinf(gsi_deg2rad*i)*r_top, y + hh, z + cosf(gsi_deg2rad*i)*r_top);
  1625. gsi_v3f(gsi, x + sinf(gsi_deg2rad*i)*r_bottom, y - hh, z + cosf(gsi_deg2rad*i)*r_bottom);
  1626. }
  1627. // Draw Top/Bottom circles
  1628. for (int i = 0; i < 360; i += 360/sides)
  1629. {
  1630. gsi_v3f(gsi, x, y - hh, z);
  1631. gsi_v3f(gsi, x + sinf(gsi_deg2rad*(i + 360.0f/sides))*r_bottom, y - hh, z + cosf(gsi_deg2rad*(i + 360.0f/sides))*r_bottom);
  1632. if (r_top) {
  1633. gsi_v3f(gsi, x + 0, y + hh, z + 0);
  1634. gsi_v3f(gsi, x + sinf(gsi_deg2rad*(i + 360.0f/sides))*r_top, y + hh, z + cosf(gsi_deg2rad*(i + 360.0f/sides))*r_top);
  1635. }
  1636. }
  1637. }
  1638. gsi_end(gsi);
  1639. } break;
  1640. }
  1641. }
  1642. GS_API_DECL void
  1643. gsi_cone(gs_immediate_draw_t* gsi, float x, float y, float z, float radius,
  1644. float height, int32_t sides, uint8_t r, uint8_t g, uint8_t b, uint8_t a, gs_graphics_primitive_type type)
  1645. {
  1646. gsi_cylinder(gsi, x, y, z, 0.f, radius, height, sides, r, g, b, a, type);
  1647. }
  1648. GS_API_DECL void
  1649. gsi_text(gs_immediate_draw_t* gsi, float x, float y, const char* text,
  1650. const gs_asset_font_t* fp, bool32_t flip_vertical, uint8_t r, uint8_t g, uint8_t b, uint8_t a)
  1651. {
  1652. // If no font, set to default
  1653. if (!fp) {
  1654. fp = &GSI()->font_default;
  1655. }
  1656. gsi_texture(gsi, fp->texture.hndl);
  1657. gs_mat4 rot = gs_mat4_rotatev(gs_deg2rad(-180.f), GS_XAXIS);
  1658. // Get total dimensions of text
  1659. gs_vec2 td = gs_asset_font_text_dimensions(fp, text, -1);
  1660. float th = gs_asset_font_max_height(fp);
  1661. // Move text to accomdate height
  1662. // y += td.y;
  1663. y += th;
  1664. // Needs to be fixed in here. Not elsewhere.
  1665. gsi_begin(gsi, GS_GRAPHICS_PRIMITIVE_TRIANGLES);
  1666. {
  1667. gsi_c4ub(gsi, r, g, b, a);
  1668. while (text[0] != '\0')
  1669. {
  1670. char c = text[0];
  1671. if (c >= 32 && c <= 127)
  1672. {
  1673. stbtt_aligned_quad q = gs_default_val();
  1674. stbtt_GetBakedQuad((stbtt_bakedchar*)fp->glyphs, fp->texture.desc.width, fp->texture.desc.height, c - 32, &x, &y, &q, 1);
  1675. gs_vec3 v0 = gs_v3(q.x0, q.y0, 0.f); // TL
  1676. gs_vec3 v1 = gs_v3(q.x1, q.y0, 0.f); // TR
  1677. gs_vec3 v2 = gs_v3(q.x0, q.y1, 0.f); // BL
  1678. gs_vec3 v3 = gs_v3(q.x1, q.y1, 0.f); // BR
  1679. if (flip_vertical) {
  1680. v0 = gs_mat4_mul_vec3(rot, v0);
  1681. v1 = gs_mat4_mul_vec3(rot, v1);
  1682. v2 = gs_mat4_mul_vec3(rot, v2);
  1683. v3 = gs_mat4_mul_vec3(rot, v3);
  1684. }
  1685. gs_vec2 uv0 = gs_v2(q.s0, q.t0); // TL
  1686. gs_vec2 uv1 = gs_v2(q.s1, q.t0); // TR
  1687. gs_vec2 uv2 = gs_v2(q.s0, q.t1); // BL
  1688. gs_vec2 uv3 = gs_v2(q.s1, q.t1); // BR
  1689. gsi_tc2fv(gsi, uv0);
  1690. gsi_v3fv(gsi, v0);
  1691. gsi_tc2fv(gsi, uv3);
  1692. gsi_v3fv(gsi, v3);
  1693. gsi_tc2fv(gsi, uv2);
  1694. gsi_v3fv(gsi, v2);
  1695. gsi_tc2fv(gsi, uv0);
  1696. gsi_v3fv(gsi, v0);
  1697. gsi_tc2fv(gsi, uv1);
  1698. gsi_v3fv(gsi, v1);
  1699. gsi_tc2fv(gsi, uv3);
  1700. gsi_v3fv(gsi, v3);
  1701. }
  1702. text++;
  1703. }
  1704. }
  1705. gsi_end(gsi);
  1706. }
  1707. // View/Scissor commands
  1708. GS_API_DECL void
  1709. gsi_set_view_scissor(gs_immediate_draw_t* gsi, uint32_t x, uint32_t y, uint32_t w, uint32_t h)
  1710. {
  1711. // Flush previous
  1712. gsi_flush(gsi);
  1713. // Set graphics viewport scissor
  1714. gs_graphics_set_view_scissor(&gsi->commands, x, y, w, h);
  1715. }
  1716. // Final Submit / Merge
  1717. GS_API_DECL void
  1718. gsi_draw(gs_immediate_draw_t* gsi, gs_command_buffer_t* cb)
  1719. {
  1720. // Final flush (if necessary)(this might be a part of gsi_end() instead)
  1721. gsi_flush(gsi);
  1722. // Merge gsi commands to end of cb
  1723. gs_byte_buffer_write_bulk(&cb->commands, gsi->commands.commands.data, gsi->commands.commands.position);
  1724. // Increase number of commands of merged buffer
  1725. cb->num_commands += gsi->commands.num_commands;
  1726. // Reset cache
  1727. gsi_reset(gsi);
  1728. }
  1729. GS_API_DECL void
  1730. gsi_renderpass_submit(gs_immediate_draw_t* gsi, gs_command_buffer_t* cb, gs_vec4 viewport, gs_color_t c)
  1731. {
  1732. gs_graphics_clear_action_t action = gs_default_val();
  1733. action.color[0] = (float)c.r / 255.f;
  1734. action.color[1] = (float)c.g / 255.f;
  1735. action.color[2] = (float)c.b / 255.f;
  1736. action.color[3] = (float)c.a / 255.f;
  1737. gs_graphics_clear_desc_t clear = gs_default_val();
  1738. clear.actions = &action;
  1739. gs_renderpass_t pass = gs_default_val();
  1740. gs_graphics_renderpass_begin(cb, pass);
  1741. gs_graphics_set_viewport(cb, (uint32_t)viewport.x, (uint32_t)viewport.y, (uint32_t)viewport.z, (uint32_t)viewport.w);
  1742. gs_graphics_clear(cb, &clear);
  1743. gsi_draw(gsi, cb);
  1744. gs_graphics_renderpass_end(cb);
  1745. }
  1746. GS_API_DECL void gsi_renderpass_submit_ex(gs_immediate_draw_t* gsi, gs_command_buffer_t* cb, gs_vec4 viewport, gs_graphics_clear_action_t* action)
  1747. {
  1748. gs_graphics_clear_desc_t clear = gs_default_val();
  1749. clear.actions = action;
  1750. gs_renderpass_t pass = gs_default_val();
  1751. gs_graphics_renderpass_begin(cb, pass);
  1752. gs_graphics_set_viewport(cb, (uint32_t)viewport.x, (uint32_t)viewport.y, (uint32_t)viewport.z, (uint32_t)viewport.w);
  1753. gs_graphics_clear(cb, &clear);
  1754. gsi_draw(gsi, cb);
  1755. gs_graphics_renderpass_end(cb);
  1756. }
  1757. //-----------------------------------------------------------------------------
  1758. // [SECTION] Default font data (ProggyClean.ttf)
  1759. //-----------------------------------------------------------------------------
  1760. // ProggyClean.ttf
  1761. // Copyright (c) 2004, 2005 Tristan Grimmer
  1762. // MIT license (see License.txt in http://www.upperbounds.net/download/ProggyClean.ttf.zip)
  1763. // Download and more information at http://upperbounds.net
  1764. //-----------------------------------------------------------------------------
  1765. // File: 'ProggyClean.ttf' (41208 bytes)
  1766. // Exported using misc/fonts/binary_to_compressed_c.cpp (with compression + base85 string encoding).
  1767. // The purpose of encoding as base85 instead of "0x00,0x01,..." style is only save on _source code_ size.
  1768. //-----------------------------------------------------------------------------
  1769. // Modified from stb lib for embedding without collisions
  1770. GS_API_DECL unsigned int gs_decompress_length(const unsigned char* input)
  1771. {
  1772. return (input[8] << 24) + (input[9] << 16) + (input[10] << 8) + input[11];
  1773. }
  1774. static unsigned char *gs__barrier;
  1775. static unsigned char *gs__barrier2;
  1776. static unsigned char *gs__barrier3;
  1777. static unsigned char *gs__barrier4;
  1778. static unsigned char *gs__dout;
  1779. static void gs__match(const unsigned char *data, unsigned int length)
  1780. {
  1781. // INVERSE of memmove... write each byte before copying the next...
  1782. assert (gs__dout + length <= gs__barrier);
  1783. if (gs__dout + length > gs__barrier) { gs__dout += length; return; }
  1784. if (data < gs__barrier4) { gs__dout = gs__barrier+1; return; }
  1785. while (length--) *gs__dout++ = *data++;
  1786. }
  1787. static void gs__lit(const unsigned char *data, unsigned int length)
  1788. {
  1789. assert (gs__dout + length <= gs__barrier);
  1790. if (gs__dout + length > gs__barrier) { gs__dout += length; return; }
  1791. if (data < gs__barrier2) { gs__dout = gs__barrier+1; return; }
  1792. memcpy(gs__dout, data, length);
  1793. gs__dout += length;
  1794. }
  1795. #define gs__in2(x) ((i[x] << 8) + i[(x)+1])
  1796. #define gs__in3(x) ((i[x] << 16) + gs__in2((x)+1))
  1797. #define gs__in4(x) ((i[x] << 24) + gs__in3((x)+1))
  1798. static unsigned char *gs_decompress_token(unsigned char *i)
  1799. {
  1800. if (*i >= 0x20) { // use fewer if's for cases that expand small
  1801. if (*i >= 0x80) gs__match(gs__dout-i[1]-1, i[0] - 0x80 + 1), i += 2;
  1802. else if (*i >= 0x40) gs__match(gs__dout-(gs__in2(0) - 0x4000 + 1), i[2]+1), i += 3;
  1803. else /* *i >= 0x20 */ gs__lit(i+1, i[0] - 0x20 + 1), i += 1 + (i[0] - 0x20 + 1);
  1804. } else { // more ifs for cases that expand large, since overhead is amortized
  1805. if (*i >= 0x18) gs__match(gs__dout-(gs__in3(0) - 0x180000 + 1), i[3]+1), i += 4;
  1806. else if (*i >= 0x10) gs__match(gs__dout-(gs__in3(0) - 0x100000 + 1), gs__in2(3)+1), i += 5;
  1807. else if (*i >= 0x08) gs__lit(i+2, gs__in2(0) - 0x0800 + 1), i += 2 + (gs__in2(0) - 0x0800 + 1);
  1808. else if (*i == 0x07) gs__lit(i+3, gs__in2(1) + 1), i += 3 + (gs__in2(1) + 1);
  1809. else if (*i == 0x06) gs__match(gs__dout-(gs__in3(1)+1), i[4]+1), i += 5;
  1810. else if (*i == 0x04) gs__match(gs__dout-(gs__in3(1)+1), gs__in2(4)+1), i += 6;
  1811. }
  1812. return i;
  1813. }
  1814. unsigned int gs_adler32(unsigned int adler32, unsigned char *buffer, unsigned int buflen)
  1815. {
  1816. const unsigned long ADLER_MOD = 65521;
  1817. unsigned long s1 = adler32 & 0xffff, s2 = adler32 >> 16;
  1818. unsigned long blocklen = buflen % 5552;
  1819. unsigned long i;
  1820. while (buflen) {
  1821. for (i=0; i + 7 < blocklen; i += 8) {
  1822. s1 += buffer[0], s2 += s1;
  1823. s1 += buffer[1], s2 += s1;
  1824. s1 += buffer[2], s2 += s1;
  1825. s1 += buffer[3], s2 += s1;
  1826. s1 += buffer[4], s2 += s1;
  1827. s1 += buffer[5], s2 += s1;
  1828. s1 += buffer[6], s2 += s1;
  1829. s1 += buffer[7], s2 += s1;
  1830. buffer += 8;
  1831. }
  1832. for (; i < blocklen; ++i)
  1833. s1 += *buffer++, s2 += s1;
  1834. s1 %= ADLER_MOD, s2 %= ADLER_MOD;
  1835. buflen -= blocklen;
  1836. blocklen = 5552;
  1837. }
  1838. return (unsigned int)(s2 << 16) + (unsigned int)s1;
  1839. }
  1840. GS_API_DECL unsigned int gs_decompress(unsigned char *output, unsigned char *i, unsigned int length)
  1841. {
  1842. uint32_t olen;
  1843. if (gs__in4(0) != 0x57bC0000) return 0;
  1844. if (gs__in4(4) != 0) return 0; // error! stream is > 4GB
  1845. olen = gs_decompress_length(i);
  1846. gs__barrier2 = i;
  1847. gs__barrier3 = i+length;
  1848. gs__barrier = output + olen;
  1849. gs__barrier4 = output;
  1850. i += 16;
  1851. gs__dout = output;
  1852. while (1) {
  1853. unsigned char *old_i = i;
  1854. i = gs_decompress_token(i);
  1855. if (i == old_i) {
  1856. if (*i == 0x05 && i[1] == 0xfa) {
  1857. assert(gs__dout == output + olen);
  1858. if (gs__dout != output + olen) return 0;
  1859. if (gs_adler32(1, output, olen) != (uint32_t) gs__in4(2))
  1860. return 0;
  1861. return olen;
  1862. } else {
  1863. assert(0); /* NOTREACHED */
  1864. return 0;
  1865. }
  1866. }
  1867. assert(gs__dout <= output + olen);
  1868. if (gs__dout > output + olen)
  1869. return 0;
  1870. }
  1871. }
  1872. GS_API_DECL unsigned int GSDecode85Byte(char c) {return c >= '\\' ? c-36 : c-35;}
  1873. GS_API_DECL void GSDecode85(const unsigned char* src, unsigned char* dst)
  1874. {
  1875. while (*src)
  1876. {
  1877. unsigned int tmp = GSDecode85Byte(src[0]) + 85 * (GSDecode85Byte(src[1]) + 85 * (GSDecode85Byte(src[2]) + 85 * (GSDecode85Byte(src[3]) + 85 * GSDecode85Byte(src[4]))));
  1878. dst[0] = ((tmp >> 0) & 0xFF); dst[1] = ((tmp >> 8) & 0xFF); dst[2] = ((tmp >> 16) & 0xFF); dst[3] = ((tmp >> 24) & 0xFF); // We can't assume little-endianness.
  1879. src += 5;
  1880. dst += 4;
  1881. }
  1882. }
  1883. static const char __gs_proggy_clean_ttf_compressed_data_base85[11980 + 1] =
  1884. "7])#######hV0qs'/###[),##/l:$#Q6>##5[n42>c-TH`->>#/e>11NNV=Bv(*:.F?uu#(gRU.o0XGH`$vhLG1hxt9?W`#,5LsCp#-i>.r$<$6pD>Lb';9Crc6tgXmKVeU2cD4Eo3R/"
  1885. "2*>]b(MC;$jPfY.;h^`IWM9<Lh2TlS+f-s$o6Q<BWH`YiU.xfLq$N;$0iR/GX:U(jcW2p/W*q?-qmnUCI;jHSAiFWM.R*kU@C=GH?a9wp8f$e.-4^Qg1)Q-GL(lf(r/7GrRgwV%MS=C#"
  1886. "`8ND>Qo#t'X#(v#Y9w0#1D$CIf;W'#pWUPXOuxXuU(H9M(1<q-UE31#^-V'8IRUo7Qf./L>=Ke$$'5F%)]0^#[email protected]<r:QLtFsLcL6##lOj)#.Y5<-R&KgLwqJfLgN&;Q?gI^#DY2uL"
  1887. "i@^rMl9t=cWq6##weg>$FBjVQTSDgEKnIS7EM9>ZY9w0#L;>>#Mx&4Mvt//L[MkA#[email protected]'[0#7RL_&#w+F%HtG9M#XL`N&.,GM4Pg;-<nLENhvx>-VsM.M0rJfLH2eTM`*oJMHRC`N"
  1888. "kfimM2J,W-jXS:)r0wK#@Fge$U>`w'N7G#$#fB#$E^$#:9:hk+eOe--6x)F7*E%?76%^GMHePW-Z5l'&GiF#$956:rS?dA#fiK:)Yr+`&#0j@'DbG&#^$PG.Ll+DNa<XCMKEV*N)LN/N"
  1889. "*b=%Q6pia-Xg8I$<MR&,VdJe$<(7G;Ckl'&hF;;$<_=X(b.RS%%)###MPBuuE1V:v&cX&#2m#(&cV]`k9OhLMbn%s$G2,B$BfD3X*sp5#l,$R#]x_X1xKX%b5U*[r5iMfUo9U`N99hG)"
  1890. "tm+/Us9pG)XPu`<0s-)WTt(gCRxIg(%6sfh=ktMKn3j)<6<b5Sk_/0(^]AaN#(p/L>&VZ>1i%h1S9u5o@YaaW$e+b<TWFn/Z:Oh(Cx2$lNEoN^e)#CFY@@I;BOQ*sRwZtZxRcU7uW6CX"
  1891. "ow0i(?$Q[cjOd[P4d)]>ROPOpxTO7Stwi1::iB1q)C_=dV26J;2,]7op$]uQr@_V7$q^%lQwtuHY]=DX,n3L#0PHDO4f9>dC@O>HBuKPpP*E,N+b3L#lpR/MrTEH.IAQk.a>D[.e;mc."
  1892. "x]Ip.PH^'/aqUO/$1WxLoW0[iLA<QT;5HKD+@qQ'NQ(3_PLhE48R.qAPSwQ0/WK?Z,[x?-J;jQTWA0X@KJ(_Y8N-:/M74:/-ZpKrUss?d#dZq]DAbkU*JqkL+nwX@@47`5>w=4h(9.`G"
  1893. "CRUxHPeR`5Mjol(dUWxZa(>STrPkrJiWx`5U7F#.g*jrohGg`cg:lSTvEY/EV_7H4Q9[Z%cnv;JQYZ5q.l7Zeas:HOIZOB?G<Nald$qs]@]L<J7bR*>gv:[7MI2k).'2($5FNP&EQ(,)"
  1894. "U]W]+fh18.vsai00);D3@4ku5P?DP8aJt+;qUM]=+b'8@;mViBKx0DE[-auGl8:PJ&Dj+M6OC]O^((##]`0i)drT;-7X`=-H3[igUnPG-NZlo.#k@h#=Ork$m>a>$-?Tm$UV(?#P6YY#"
  1895. "'/###xe7q.73rI3*pP/$1>s9)W,JrM7SN]'/4C#v$U`0#V.[0>xQsH$fEmPMgY2u7Kh(G%siIfLSoS+MK2eTM$=5,M8p`A.;_R%#u[K#$x4AG8.kK/HSB==-'Ie/QTtG?-.*^N-4B/ZM"
  1896. "_3YlQC7(p7q)&](`6_c)$/*JL(L-^(]$wIM`dPtOdGA,U3:w2M-0<q-]L_?^)1vw'.,MRsqVr.L;aN&#/EgJ)PBc[-f>+WomX2u7lqM2iEumMTcsF?-aT=Z-97UEnXglEn1K-bnEO`gu"
  1897. "Ft(c%=;Am_Qs@jLooI&NX;]0#j4#F14;gl8-GQpgwhrq8'=l_f-b49'UOqkLu7-##oDY2L(te+Mch&gLYtJ,MEtJfLh'x'M=$CS-ZZ%P]8bZ>#S?YY#%Q&q'3^Fw&?D)UDNrocM3A76/"
  1898. "/oL?#h7gl85[qW/NDOk%16ij;+:1a'iNIdb-ou8.P*w,v5#EI$TWS>Pot-R*H'-SEpA:g)f+O$%%`kA#G=8RMmG1&O`>to8bC]T&$,n.LoO>29sp3dt-52U%VM#q7'DHpg+#Z9%H[K<L"
  1899. "%a2E-grWVM3@2=-k22tL]4$##6We'8UJCKE[d_=%wI;'6X-GsLX4j^SgJ$##R*w,vP3wK#iiW&#*h^D&R?jp7+/u&#(AP##XU8c$fSYW-J95_-Dp[g9wcO&#M-h1OcJlc-*vpw0xUX&#"
  1900. "OQFKNX@QI'IoPp7nb,QU//MQ&ZDkKP)X<WSVL(68uVl&#c'[0#(s1X&xm$Y%B7*K:eDA323j998GXbA#pwMs-jgD$9QISB-A_(aN4xoFM^@C58D0+Q+q3n0#3U1InDjF682-SjMXJK)("
  1901. "h$hxua_K]ul92%'BOU&#BRRh-slg8KDlr:%L71Ka:.A;%YULjDPmL<LYs8i#XwJOYaKPKc1h:'9Ke,g)b),78=I39B;xiY$bgGw-&.Zi9InXDuYa%G*f2Bq7mn9^#p1vv%#(Wi-;/Z5h"
  1902. "o;#2:;%d&#x9v68C5g?ntX0X)pT`;%pB3q7mgGN)3%(P8nTd5L7GeA-GL@+%J3u2:(Yf>et`e;)f#Km8&+DC$I46>#Kr]]u-[=99tts1.qb#q72g1WJO81q+eN'03'eM>&1XxY-caEnO"
  1903. "j%2n8)),?ILR5^.Ibn<-X-Mq7[a82Lq:F&#ce+S9wsCK*x`569E8ew'He]h:sI[2LM$[guka3ZRd6:t%IG:;$%YiJ:Nq=?eAw;/:nnDq0(CYcMpG)qLN4$##&J<j$UpK<Q4a1]MupW^-"
  1904. "sj_$%[HK%'F####QRZJ::Y3EGl4'@%FkiAOg#p[##O`gukTfBHagL<LHw%q&OV0##F=6/:chIm0@eCP8X]:kFI%hl8hgO@RcBhS-@Qb$%+m=hPDLg*%K8ln(wcf3/'DW-$.lR?n[nCH-"
  1905. "eXOONTJlh:.RYF%3'p6sq:UIMA945&^HFS87@$EP2iG<-lCO$%c`uKGD3rC$x0BL8aFn--`ke%#HMP'vh1/R&O_J9'um,.<tx[@%wsJk&bUT2`0uMv7gg#qp/ij.L56'hl;.s5CUrxjO"
  1906. "M7-##.l+Au'A&O:-T72L]P`&=;ctp'XScX*rU.>-XTt,%OVU4)S1+R-#dg0/Nn?Ku1^0f$B*P:Rowwm-`0PKjYDDM'3]d39VZHEl4,.j']Pk-M.h^&:0FACm$maq-&sgw0t7/6(^xtk%"
  1907. "LuH88Fj-ekm>GA#_>568x6(OFRl-IZp`&b,_P'$M<Jnq79VsJW/mWS*PUiq76;]/NM_>hLbxfc$mj`,O;&%W2m`Zh:/)Uetw:aJ%]K9h:TcF]u_-Sj9,VK3M.*'&0D[Ca]J9gp8,kAW]"
  1908. "%(?A%R$f<->Zts'^kn=-^@c4%-pY6qI%J%1IGxfLU9CP8cbPlXv);C=b),<2mOvP8up,UVf3839acAWAW-W?#ao/^#%KYo8fRULNd2.>%m]UK:n%r$'sw]J;5pAoO_#2mO3n,'=H5(et"
  1909. "Hg*`+RLgv>=4U8guD$I%D:W>-r5V*%j*W:Kvej.Lp$<M-SGZ':+Q_k+uvOSLiEo(<aD/K<CCc`'Lx>'?;++O'>()jLR-^u68PHm8ZFWe+ej8h:9r6L*0//c&iH&R8pRbA#Kjm%upV1g:"
  1910. "a_#Ur7FuA#(tRh#.Y5K+@?3<-8m0$PEn;J:rh6?I6uG<-`wMU'ircp0LaE_OtlMb&1#6T.#FDKu#1Lw%u%+GM+X'e?YLfjM[VO0MbuFp7;>Q&#WIo)0@F%q7c#4XAXN-U&VB<HFF*qL("
  1911. "$/V,;(kXZejWO`<[5?\?ewY(*9=%wDc;,u<'9t3W-(H1th3+G]ucQ]kLs7df($/*JL]@*t7Bu_G3_7mp7<[email protected];x3B0lqp7Hf,^Ze7-##@/c58Mo(3;knp0%)A7?-W+eI'o8)b<"
  1912. "nKnw'Ho8C=Y>pqB>0ie&jhZ[?iLR@@_AvA-iQC(=ksRZRVp7`.=+NpBC%rh&3]R:8XDmE5^V8O(x<<aG/1N$#FX$0V5Y6x'aErI3I$7x%E`v<-BY,)%-?Psf*l?%C3.mM(=/M0:JxG'?"
  1913. "7WhH%o'a<-80g0NBxoO(GH<dM]n.+%q@jH?f.UsJ2Ggs&4<-e47&Kl+f//9@`b+?.TeN_&B8Ss?v;^Trk;f#YvJkl&w$]>-+k?'(<S:68tq*WoDfZu';mM?8X[ma8W%*`-=;D.(nc7/;"
  1914. ")g:T1=^J$&BRV(-lTmNB6xqB[@0*o.erM*<SWF]u2=st-*(6v>^](H.aREZSi,#1:[IXaZFOm<-ui#qUq2$##Ri;u75OK#(RtaW-K-F`S+cF]uN`-KMQ%rP/Xri.LRcB##=YL3BgM/3M"
  1915. "D?@f&1'BW-)Ju<L25gl8uhVm1hL$##*8###'A3/LkKW+(^rWX?5W_8g)a(m&K8P>#bmmWCMkk&#TR`C,5d>g)F;t,4:@_l8G/5h4vUd%&%950:VXD'QdWoY-F$BtUwmfe$YqL'8(PWX("
  1916. "P?^@Po3$##`MSs?DWBZ/S>+4%>fX,VWv/w'KD`LP5IbH;rTV>n3cEK8U#bX]l-/V+^lj3;vlMb&[5YQ8#pekX9JP3XUC72L,,?+Ni&co7ApnO*5NK,((W-i:$,kp'UDAO(G0Sq7MVjJs"
  1917. "bIu)'Z,*[>br5fX^:FPAWr-m2KgL<LUN098kTF&#lvo58=/vjDo;.;)Ka*hLR#/k=rKbxuV`>Q_nN6'8uTG&#1T5g)uLv:873UpTLgH+#FgpH'_o1780Ph8KmxQJ8#H72L4@768@Tm&Q"
  1918. "h4CB/5OvmA&,Q&QbUoi$a_%3M01H)4x7I^&KQVgtFnV+;[Pc>[m4k//,]1?#`VY[Jr*3&&slRfLiVZJ:]?=K3Sw=[$=uRB?3xk48@aeg<Z'<$#4H)6,>e0jT6'N#(q%.O=?2S]u*(m<-"
  1919. "V8J'(1)G][68hW$5'q[GC&5j`TE?m'esFGNRM)j,ffZ?-qx8;->g4t*:CIP/[Qap7/9'#(1sao7w-.qNUdkJ)tCF&#B^;[email protected]$m%#QvQS8U@)2Z+3K:AKM5i"
  1920. "sZ88+dKQ)W6>J%CL<KE>`.d*(B`-n8D9oK<Up]c$X$(,)M8Zt7/[rdkqTgl-0cuGMv'?>-XV1q['-5k'cAZ69e;D_?$ZPP&s^+7])$*$#@QYi9,5P&#9r+$%CE=68>K8r0=dSC%%(@p7"
  1921. ".m7jilQ02'0-VWAg<a/''3u.=4L$Y)6k/K:_[3=&jvL<L0C/2'v:^;-DIBW,B4E68:kZ;%?8(Q8BH=kO65BW?xSG&#@uU,DS*,?.+(o(#1vCS8#CHF>TlGW'b)Tq7VT9q^*^$$.:&N@@"
  1922. "$&)WHtPm*5_rO0&e%K&#-30j(E4#'Zb.o/(Tpm$>K'f@[PvFl,hfINTNU6u'0pao7%XUp9]5.>%h`8_=VYbxuel.NTSsJfLacFu3B'lQSu/m6-Oqem8T+oE--$0a/k]uj9EwsG>%veR*"
  1923. "hv^BFpQj:K'#SJ,sB-'#](j.Lg92rTw-*n%@/;39rrJF,l#qV%OrtBeC6/,;qB3ebNW[?,Hqj2L.1NP&GjUR=1D8QaS3Up&@*9wP?+lo7b?@%'k4`p0Z$22%K3+iCZj?XJN4Nm&+YF]u"
  1924. "@-W$U%VEQ/,,>>#)D<h#`)h0:<Q6909ua+&VU%n2:cG3FJ-%@Bj-DgLr`Hw&HAKjKjseK</xKT*)B,N9X3]krc12t'pgTV(Lv-tL[xg_%=M_q7a^x?7Ubd>#%8cY#YZ?=,`Wdxu/ae&#"
  1925. "w6)R89tI#6@s'(6Bf7a&?S=^ZI_kS&ai`&=tE72L_D,;^R)7[$s<Eh#c&)q.MXI%#v9ROa5FZO%sF7q7Nwb&#ptUJ:aqJe$Sl68%.D###EC><?-aF&#RNQv>o8lKN%5/$(vdfq7+ebA#"
  1926. "u1p]ovUKW&Y%q]'>$1@-[xfn$7ZTp7mM,G,Ko7a&Gu%G[RMxJs[0MM%wci.LFDK)(<c`Q8N)jEIF*+?P2a8g%)$q]o2aH8C&<SibC/q,(e:v;-b#6[$NtDZ84Je2KNvB#$P5?tQ3nt(0"
  1927. "d=j.LQf./Ll33+(;q3L-w=8dX$#WF&uIJ@-bfI>%:_i2B5CsR8&9Z&#=mPEnm0f`<&c)QL5uJ#%u%lJj+D-r;BoF&#4DoS97h5g)E#o:&S4weDF,9^Hoe`h*L+_a*NrLW-1pG_&2UdB8"
  1928. "6e%B/:=>)N4xeW.*wft-;$'58-ESqr<b?UI(_%@[P46>#U`'6AQ]m&6/`Z>#S?YY#Vc;r7U2&326d=w&H####?TZ`*4?&.MK?LP8Vxg>$[QXc%QJv92.(Db*B)gb*BM9dM*hJMAo*c&#"
  1929. "b0v=Pjer]$gG&JXDf->'StvU7505l9$AFvgYRI^&<^b68?j#q9QX4SM'RO#&sL1IM.rJfLUAj221]d##DW=m83u5;'bYx,*Sl0hL(W;;$doB&O/TQ:(Z^xBdLjL<Lni;''X.`$#8+1GD"
  1930. ":k$YUWsbn8ogh6rxZ2Z9]%nd+>V#*8U_72Lh+2Q8Cj0i:6hp&$C/:p(HK>T8Y[gHQ4`4)'$Ab(Nof%V'8hL&#<NEdtg(n'=S1A(Q1/I&4([%dM`,Iu'1:_hL>SfD07&6D<fp8dHM7/g+"
  1931. "tlPN9J*rKaPct&?'uBCem^jn%9_K)<,C5K3s=5g&GmJb*[SYq7K;TRLGCsM-$$;S%:Y@r7AK0pprpL<Lrh,q7e/%KWK:50I^+m'vi`3?%Zp+<-d+$L-Sv:@.o19n$s0&39;kn;S%BSq*"
  1932. "$3WoJSCLweV[aZ'MQIjO<7;X-X;&+dMLvu#^UsGEC9WEc[X(wI7#2.(F0jV*eZf<-Qv3J-c+J5AlrB#$p(H68LvEA'q3n0#m,[`*8Ft)FcYgEud]CWfm68,(aLA$@EFTgLXoBq/UPlp7"
  1933. ":d[/;r_ix=:TF`S5H-b<LI&HY(K=h#)]Lk$K14lVfm:x$H<3^Ql<M`$OhapBnkup'D#L$Pb_`N*g]2e;X/Dtg,bsj&K#2[-:iYr'_wgH)NUIR8a1n#S?Yej'h8^58UbZd+^FKD*T@;6A"
  1934. "7aQC[K8d-(v6GI$x:T<&'Gp5Uf>@M.*J:;$-rv29'M]8qMv-tLp,'886iaC=Hb*YJoKJ,(j%K=H`K.v9HggqBIiZu'QvBT.#=)0ukruV&.)3=(^1`o*Pj4<-<aN((^7('#Z0wK#5GX@7"
  1935. "u][`*S^43933A4rl][`*O4CgLEl]v$1Q3AeF37dbXk,.)vj#x'd`;qgbQR%FW,2(?LO=s%Sc68%NP'##Aotl8x=BE#j1UD([3$M(]UI2LX3RpKN@;/#f'f/&_mt&F)XdF<9t4)Qa.*kT"
  1936. "LwQ'(TTB9.xH'>#MJ+gLq9-##@HuZPN0]u:h7.T..G:;$/Usj(T7`Q8tT72LnYl<-qx8;-HV7Q-&Xdx%1a,hC=0u+HlsV>nuIQL-5<N?)NBS)QN*_I,?&)2'IM%L3I)X((e/dl2&8'<M"
  1937. ":^#M*Q+[T.Xri.LYS3v%fF`68h;b-X[/En'CR.q7E)p'/kle2HM,u;^%OKC-N+Ll%F9CF<Nf'^#t2L,;27W:0O@6##U6W7:$rJfLWHj$#)woqBefIZ.PK<b*t7ed;p*_m;4ExK#h@&]>"
  1938. "_>@kXQtMacfD.m-VAb8;IReM3$wf0''hra*so568'Ip&vRs849'MRYSp%:t:h5qSgwpEr$B>Q,;s(C#$)`svQuF$##-D,##,g68@2[T;.XSdN9Qe)rpt._K-#5wF)sP'##p#C0c%-Gb%"
  1939. "hd+<-j'Ai*x&&HMkT]C'OSl##5RG[JXaHN;d'uA#x._U;.`PU@(Z3dt4r152@:v,'R.Sj'w#0<-;kPI)FfJ&#AYJ&#//)>-k=m=*XnK$>=)72L]0I%>.G690a:$##<,);?;72#?x9+d;"
  1940. "^V'9;jY@;)br#q^YQpx:X#Te$Z^'=-=bGhLf:D6&bNwZ9-ZD#n^9HhLMr5G;']d&6'wYmTFmL<LD)F^%[tC'8;+9E#C$g%#5Y>q9wI>P(9mI[>kC-ekLC/R&CH+s'B;K-M6$EB%is00:"
  1941. "+A4[7xks.LrNk0&E)wILYF@2L'0Nb$+pv<(2.768/FrY&h$^3i&@+G%JT'<-,v`3;_)I9M^AE]CN?Cl2AZg+%4iTpT3<n-&%H%b<FDj2M<hH=&Eh<2Len$b*aTX=-8QxN)k11IM1c^j%"
  1942. "9s<L<NFSo)B?+<-(GxsF,^-Eh@$4dXhN$+#rxK8'je'D7k`e;)2pYwPA'_p9&@^18ml1^[@g4t*[JOa*[=Qp7(qJ_oOL^('7fB&Hq-:sf,sNj8xq^>$U4O]GKx'm9)b@p7YsvK3w^YR-"
  1943. "CdQ*:Ir<($u&)#(&?L9Rg3H)4fiEp^iI9O8KnTj,]H?D*r7'M;PwZ9K0E^k&-cpI;.p/6_vwoFMV<->#%Xi.LxVnrU(4&8/P+:hLSKj$#U%]49t'I:rgMi'FL@a:0Y-uA[39',(vbma*"
  1944. "hU%<-SRF`Tt:542R_VV$p@[p8DV[A,?1839FWdF<TddF<9Ah-6&9tWoDlh]&1SpGMq>Ti1O*H&#(AL8[_P%.M>v^-))qOT*F5Cq0`Ye%+$B6i:7@0IX<N+T+0MlMBPQ*Vj>SsD<U4JHY"
  1945. "8kD2)2fU/M#$e.)T4,_=8hLim[&);?UkK'-x?'(:siIfL<$pFM`i<?%W(mGDHM%>iWP,##P`%/L<eXi:@Z9C.7o=@(pXdAO/NLQ8lPl+HPOQa8wD8=^GlPa8TKI1CjhsCTSLJM'/Wl>-"
  1946. "S(qw%sf/@%#B6;/U7K]uZbi^Oc^2n<bhPmUkMw>%t<)'mEVE''n`WnJra$^TKvX5B>;_aSEK',(hwa0:i4G?.Bci.(X[?b*($,=-n<.Q%`(X=?+@Am*Js0&=3bh8K]mL<LoNs'6,'85`"
  1947. "0?t/'_U59@]ddF<#LdF<eWdF<OuN/45rY<-L@&#+fm>69=Lb,OcZV/);TTm8VI;?%OtJ<(b4mq7M6:u?KRdF<gR@2L=FNU-<b[(9c/ML3m;Z[$oF3g)GAWqpARc=<ROu7cL5l;-[A]%/"
  1948. "+fsd;l#SafT/f*W]0=O'$(Tb<[)*@e775R-:Yob%g*>l*:xP?Yb.5)%w_I?7uk5JC+FS(m#i'k.'a0i)9<7b'fs'59hq$*5Uhv##pi^8+hIEBF`nvo`;'l0.^S1<-wUK2/Coh58KKhLj"
  1949. "M=SO*rfO`+qC`W-On.=AJ56>>i2@2LH6A:&5q`?9I3@@'04&p2/LVa*T-4<-i3;M9UvZd+N7>b*eIwg:CC)c<>nO&#<IGe;__.thjZl<%w(Wk2xmp4Q@I#I9,DF]u7-P=.-_:YJ]aS@V"
  1950. "?6*C()dOp7:WL,b&3Rg/.cmM9&r^>$(>.Z-I&J(Q0Hd5Q%7Co-b`-c<N(6r@ip+AurK<m86QIth*#v;-OBqi+L7wDE-Ir8K['m+DDSLwK&/.?-V%U_%3:qKNu$_b*B-kp7NaD'QdWQPK"
  1951. "Yq[@>P)hI;*_F]u`Rb[.j8_Q/<&>uu+VsH$sM9TA%?)(vmJ80),P7E>)tjD%2L=-t#fK[%`v=Q8<FfNkgg^oIbah*#8/Qt$F&:K*-(N/'+1vMB,u()-a.VUU*#[e%gAAO(S>WlA2);Sa"
  1952. ">gXm8YB`1d@K#n]76-a$U,mF<fX]idqd)<3,]J7JmW4`6]uks=4-72L(jEk+:bJ0M^q-8Dm_Z?0olP1C9Sa&H[d&c$ooQUj]Exd*3ZM@-WGW2%s',B-_M%>%Ul:#/'xoFM9QX-$.QN'>"
  1953. "[%$Z$uF6pA6Ki2O5:8w*vP1<-1`[G,)-m#>0`P&#eb#.3i)rtB61(o'$?X3B</R90;eZ]%Ncq;-Tl]#F>2Qft^ae_5tKL9MUe9b*sLEQ95C&`=G?@Mj=wh*'3E>=-<)Gt*Iw)'QG:`@I"
  1954. "wOf7&]1i'S01B+Ev/Nac#9S;=;YQpg_6U`*kVY39xK,[/6Aj7:'1Bm-_1EYfa1+o&o4hp7KN_Q(OlIo@S%;jVdn0'1<Vc52=u`3^o-n1'g4v58Hj&6_t7$##?M)c<$bgQ_'SY((-xkA#"
  1955. "Y(,p'H9rIVY-b,'%bCPF7.J<Up^,(dU1VY*5#WkTU>h19w,WQhLI)3S#f$2(eb,jr*b;3Vw]*7NH%$c4Vs,eD9>XW8?N]o+(*pgC%/72LV-u<Hp,3@e^9UB1J+ak9-TN/mhKPg+AJYd$"
  1956. "MlvAF_jCK*.O-^(63adMT->W%iewS8W6m2rtCpo'RS1R84=@paTKt)>=%&1[)*vp'u+x,VrwN;&]kuO9JDbg=pO$J*.jVe;u'm0dr9l,<*wMK*Oe=g8lV_KEBFkO'oU]^=[-792#ok,)"
  1957. "i]lR8qQ2oA8wcRCZ^7w/Njh;?.stX?Q1>S1q4Bn$)K1<-rGdO'$Wr.Lc.CG)$/*JL4tNR/,SVO3,aUw'DJN:)Ss;wGn9A32ijw%FL+Z0Fn.U9;reSq)bmI32U==5ALuG&#Vf1398/pVo"
  1958. "1*c-(aY168o<`JsSbk-,1N;$>0:OUas(3:8Z972LSfF8eb=c-;>SPw7.6hn3m`9^Xkn(r.qS[0;T%&Qc=+STRxX'q1BNk3&*eu2;&8q$&x>Q#Q7^Tf+6<(d%ZVmj2bDi%.3L2n+4W'$P"
  1959. "iDDG)g,r%+?,$@?uou5tSe2aN_AQU*<h`e-GI7)?OK2A.d7_c)?wQ5AS@DL3r#7fSkgl6-++D:'A,uq7SvlB$pcpH'q3n0#_%dY#xCpr-l<F0NR@-##FEV6NTF6##$l84N1w?AO>'IAO"
  1960. "URQ##V^Fv-XFbGM7Fl(N<3DhLGF%q.1rC$#:T__&Pi68%0xi_&[qFJ(77j_&JWoF.V735&T,[R*:xFR*K5>>#`bW-?4Ne_&6Ne_&6Ne_&n`kr-#GJcM6X;uM6X;uM(.a..^2TkL%oR(#"
  1961. ";u.T%fAr%4tJ8&><1=GHZ_+m9/#H1F^R#SC#*N=BA9(D?v[UiFY>>^8p,KKF.W]L29uLkLlu/+4T<XoIB&hx=T1PcDaB&;HH+-AFr?(m9HZV)FKS8JCw;SD=6[^/DZUL`EUDf]GGlG&>"
  1962. "w$)F./^n3+rlo+DB;5sIYGNk+i1t-69Jg--0pao7Sm#K)pdHW&;LuDNH@H>#/X-TI(;P>#,Gc>#0Su>#4`1?#8lC?#<xU?#@.i?#D:%@#HF7@#LRI@#P_[@#Tkn@#Xw*A#]-=A#a9OA#"
  1963. "d<F&#*;G##.GY##2Sl##6`($#:l:$#>xL$#B.`$#F:r$#JF.%#NR@%#R_R%#Vke%#Zww%#_-4&#3^Rh%Sflr-k'MS.o?.5/sWel/wpEM0%3'/1)K^f1-d>G21&v(35>V`39V7A4=onx4"
  1964. "A1OY5EI0;6Ibgr6M$HS7Q<)58C5w,;WoA*#[%T*#`1g*#d=#+#hI5+#lUG+#pbY+#tnl+#x$),#&1;,#*=M,#.I`,#2Ur,#6b.-#;w[H#iQtA#m^0B#qjBB#uvTB##-hB#'9$C#+E6C#"
  1965. "/QHC#3^ZC#7jmC#;v)D#?,<D#C8ND#GDaD#KPsD#O]/E#g1A5#KA*1#gC17#MGd;#8(02#L-d3#rWM4#Hga1#,<w0#T.j<#O#'2#CYN1#qa^:#_4m3#o@/=#eG8=#t8J5#`+78#4uI-#"
  1966. "m3B2#SB[8#Q0@8#i[*9#iOn8#1Nm;#^sN9#qh<9#:=x-#P;K2#$%X9#bC+.#Rg;<#mN=.#MTF.#RZO.#2?)4#Y#(/#[)1/#b;L/#dAU/#0Sv;#lY$0#n`-0#sf60#(F24#wrH0#%/e0#"
  1967. "TmD<#%JSMFove:CTBEXI:<eh2g)B,3h2^G3i;#d3jD>)4kMYD4lVu`4m`:&5niUA5@(A5BA1]PBB:xlBCC=2CDLXMCEUtiCf&0g2'tN?PGT4CPGT4CPGT4CPGT4CPGT4CPGT4CPGT4CP"
  1968. "GT4CPGT4CPGT4CPGT4CPGT4CPGT4CP-qekC`.9kEg^+F$kwViFJTB&5KTB&5KTB&5KTB&5KTB&5KTB&5KTB&5KTB&5KTB&5KTB&5KTB&5KTB&5KTB&5KTB&5KTB&5o,^<-28ZI'O?;xp"
  1969. "O?;xpO?;xpO?;xpO?;xpO?;xpO?;xpO?;xpO?;xpO?;xpO?;xpO?;xpO?;xpO?;xp;7q-#lLYI:xvD=#";
  1970. GS_API_DECL const char* GSGetDefaultCompressedFontDataTTFBase85()
  1971. {
  1972. return __gs_proggy_clean_ttf_compressed_data_base85;
  1973. }
  1974. #undef GS_IMMEDIATE_DRAW_IMPL
  1975. #endif // GS_IMMEDIATE_DRAW_IMPL
  1976. /*
  1977. Sketches:
  1978. // You can push/pop pipelines?
  1979. // Push/pop vertex data
  1980. typedef struct gs_immediate_draw_i
  1981. {
  1982. gs_command_buffer_t cb;
  1983. ...
  1984. } gs_immediate_draw_i;
  1985. // Each include "shape" will have certain vertex attributes that it can upload?
  1986. // So you could render something with a different pipeline?
  1987. // Create immediate mode (just opengl style immediate mode stuff).
  1988. // Create util on top of this to allow for custom shape drawing into immediate mode.
  1989. // Could do this instead? Push flags onto stack, then ANY provided function called will use this flag set instead?
  1990. // Just have to provide functionality in draw functions to allow this.
  1991. push_vattr_flags(attr_flags*, size_t sz);
  1992. // If you call this, it will push the default "fill" pipeline on
  1993. // layout = [FLOAT_3, FLOAT_2, FLOAT_3, UINT8_4] // position, uv, normal, color
  1994. gsi_triangle();
  1995. // If you call this, or any other line function, it will push the default "line" pipeline on.
  1996. // layout = [FLOAT_3, UINT8_4] // position, color
  1997. gsi_line();
  1998. // If you call this function, the pipeline won't change. It will instead push back interleaved data (in order provided) of attributes provided.
  1999. // Can use for custom pipelines.
  2000. gsi_line_vattr(..., attr_flags*, size_t attr_flags_sz);
  2001. gsi_vattr_flags flags[] = {
  2002. GS_IVATTR_POSITION, -> Provided vattr for all shapes
  2003. GS_IVATTR_NORMAL, -> Provided vattr for all shapes
  2004. GS_IVATTR_UV, -> Provided vattr for all shapes
  2005. GS_IVATTR_COLOR, -> Provided vattr for all shapes
  2006. GS_IVATTR_FLOAT4, -> General float4 (custom)
  2007. GS_IVATTR_FLOAT3, -> General float3 (custom)
  2008. GS_IVATTR_FLOAT2, -> General float2 (custom)
  2009. GS_IVATTR_FLOAT, -> General float (custom)
  2010. GS_IVATTR_UINT4, -> General uint4 (custom)
  2011. GS_IVATTR_UINT3, -> General uint3 (custom)
  2012. GS_IVATTR_UINT2, -> General uint2 (custom)
  2013. GS_IVATTR_UINT, -> General uint (custom)
  2014. GS_IVATTR_BYTE4, -> General byte4 (custom)
  2015. GS_IVATTR_BYTE3, -> General byte3 (custom)
  2016. GS_IVATTR_BYTE2, -> General byte2 (custom)
  2017. GS_IVATTR_BYTE, -> General byte (custom)
  2018. };
  2019. // Do GSI stuff
  2020. gsi_vattr_list(gsi, &(gsi_vattr_type){
  2021. GSI_VATTR_POSITION,
  2022. GSI_VATTR_UV,
  2023. GSI_VATTR_COLOR
  2024. }, 3 * sizeof(gsi_vattr_type);
  2025. gsi_set_vattr(GSI_VATTR_POSITION, &(gs_vec3){...});
  2026. gsi_set_vattr(GSI_VATTR_FLOAT4, (float[]){...});
  2027. gsi_set_vattr(GSI_VATTR_FLOAT3, (float[]){...});
  2028. gsi_set_vattr(GSI_VATTR_FLOAT2, (float[]){...});
  2029. gsi_set_vattr(GSI_VATTR_FLOAT, (float[]){...});
  2030. gsi_flush_cb(gsi, cb);
  2031. gsi_sphere(gsi, sphere);
  2032. gsi_box(gsi, ...);
  2033. gsi_draw(gsi, cb);
  2034. gsi_reset(gsi);
  2035. // This really should be outside the scope of the immediate draw and more into a specific "immediate_shapes" area.
  2036. // Don't want this to be too fucking cheesy though...
  2037. // Also, it's not really supposed to take care of EVERYTHING. That's not the point.
  2038. // Don't want to create index/vertex buffers. That's really it.
  2039. // Just write vertex data to buffer.
  2040. uniform buffer handles, uniform data
  2041. sampler buffer handles, sampler handle, texture handle
  2042. gs_immediate_draw_i* gsi = ...;
  2043. gsi_push_pipeline(gsi);
  2044. gsi_load_pipeline(gsi, pipeline);
  2045. gsi_push_binds(gsi);
  2046. gsi_load_uniforms(gsi, hndl, uniform_data);
  2047. gsi_load_samplers(gsi, hndl, texture_handle);
  2048. size_t coffset = (3 * sizeof(f32) + 2 * sizeof(f32));
  2049. gsi_interleaveub(gsi, coffset, 4, r, g, b, a);
  2050. // v0
  2051. gsi_v3f(gsi, ...);
  2052. gsi_v2f(gsi, ...);
  2053. // v1
  2054. gsi_v3f(gsi, ...);
  2055. gsi_v2f(gsi, ...);
  2056. // v2
  2057. gsi_v3f(gsi, ...);
  2058. gsi_v2f(gsi, ...);
  2059. // Push indices as well
  2060. gsi_idxli(gsi, 6, 0, 3, 2, 0, 1, 3);
  2061. gsi_pop_binds(gsi);
  2062. gsi_pop_pipeline(gsi);
  2063. // Push/pop matrix would be useless in this - unless you bound that information for your shader.
  2064. // What kicks off an actual submission in this case?
  2065. gsi_matrixmode(GSI_MODELVIEW); // To operate on the model-view matrix
  2066. gsi_loadidentity(); // Reset model-view matrix
  2067. gsi_translatef(ballX, ballY, 0.0f); // Translate to (xPos, yPos)
  2068. // Use triangular segments to form a circle
  2069. gsi_begin(GS_PRIMITIVE_TRIANGLE_FAN);
  2070. gsi_c3f(0.0f, 0.0f, 1.0f); // Blue
  2071. gsi_v2f(0.0f, 0.0f); // Center of circle
  2072. int32_t numSegments = 100;
  2073. float angle;
  2074. for (int32_t i = 0; i <= numSegments; i++) { // Last vertex same as first vertex
  2075. angle = i * 2.0f * GS_PI / numSegments; // 360 deg for all segments
  2076. gs_v2f(cos(angle) * ballRadius, sin(angle) * ballRadius);
  2077. }
  2078. gsi_end();
  2079. // Custom stuff?
  2080. gsi_push_pipeline(custom);
  2081. push_matrix(model);
  2082. uniform_data.mvp = gs_mat_mul(gsi_matrix(vp), gsi_matrix(model));
  2083. gsi_load_uniforms(gsi, hndl, uniform_data);
  2084. gsi_load_samplers(gsi, hndl, texture_handle);
  2085. size_t coffset = (3 * sizeof(f32) + 2 * sizeof(f32));
  2086. gsi_interleaveub(gsi, coffset, 4, r, g, b, a);
  2087. gsi_v3f(gsi, ...);
  2088. gsi_v2f(gsi, ...);
  2089. gsi_v3f(gsi, ...);
  2090. gsi_v2f(gsi, ...);
  2091. gsi_v3f(gsi, ...);
  2092. gsi_v2f(gsi, ...);
  2093. // Push indices as well
  2094. gsi_idxli(gsi, 6, 0, 3, 2, 0, 1, 3);
  2095. pop_matrix(model);
  2096. gsi_pop_pipeline();
  2097. gsdbg_push_default_pipeline(type)
  2098. {
  2099. if (type == dbg.cur_type){
  2100. nothing;
  2101. }
  2102. }
  2103. gsi_idxlist();
  2104. gsi_begin(GS_PRIMITIVE_LINES);
  2105. gsi_c4ub(r, g, b, a);
  2106. gsi_tc2f(uv);
  2107. gsi_v3f(v0);
  2108. gsi_v3f(v1);
  2109. gsi_end();
  2110. gsi_begin(GS_PRIMITIVE_TRIANGLES) -> looks for a particular default pipeline in the back
  2111. gsi_c4ub(r, g, b, a) -> sets color
  2112. gsi_tc2f(u, v) -> sets uv coordinate
  2113. gsi_v3f() -> pushes vert
  2114. gsi_enable_texture(); ->
  2115. gsi_load_texture(tex); ->
  2116. gsi_end()
  2117. // Line triangle
  2118. gsi_push_matrix(model);
  2119. gsi_begin(lines);
  2120. gsi_c4ub(r, g, b, a);
  2121. gsi_v3f(0, 0, 0);
  2122. gsi_v3f(1, 0, 0);
  2123. gsi_v3f(1, 1, 0);
  2124. gsi_end();
  2125. gsi_pop_matrix();
  2126. void gsdbg_triangle(a, b, c, r, g, b, a)
  2127. {
  2128. gsi_begin(prim_type);
  2129. {
  2130. gsi_c4ub(r, g, b, a);
  2131. gsi_v3f(0, 0, 0);
  2132. gsi_v3f(1, 0, 0);
  2133. gsi_v3f(1, 1, 0);
  2134. }
  2135. gsi_end();
  2136. }
  2137. void gsdbg_triangle(a, b, c, color)
  2138. {
  2139. gsdbg_push_default_pipeline(FILL);
  2140. size_t coffset = (3 * sizeof(f32) + 2 * sizeof(f32));
  2141. gsi_interleaveub(gsi, coffset, 4, r, g, b, a);
  2142. // v0
  2143. gsi_v3f(gsi, ...);
  2144. gsi_v2f(gsi, ...);
  2145. // v1
  2146. gsi_v3f(gsi, ...);
  2147. gsi_v2f(gsi, ...);
  2148. // v2
  2149. gsi_v3f(gsi, ...);
  2150. gsi_v2f(gsi, ...);
  2151. // Push indices
  2152. gsi_idxli(gsi, 3, 0, 1, 2);
  2153. }
  2154. gsi_push_binds();
  2155. gsi_push_matrix(view_proj);
  2156. gsi_mat_mul(vp); -> view_projection matrix
  2157. gsi_push_matrix(model);
  2158. gsi_interleaveub(offset, 4, r, g, b, a); -> color
  2159. gsi_mat_transf(); -> model matrix
  2160. gsi_mat_rotatef();
  2161. gsi_mat_scalef();
  2162. gsi_v3f(x, y, z); -> multiplies by model/vp (has to be 3f or 4f)
  2163. gsi_v4f(x, y, z, w);
  2164. gsi_3f(...);
  2165. gsi_4f(...);
  2166. // Load 'lines' pipeline
  2167. gsi_begin(lines);
  2168. gsi_push_matrix(model);
  2169. gsi_mat_mul_vqs();
  2170. gsdbg_trianglelines();
  2171. gsi_pop_matrix();
  2172. gsi_push_matrix(model);
  2173. gsi_mat_mul_vqs();
  2174. gsdb_rectlines();
  2175. gsi_pop_matrix();
  2176. gsi_end();
  2177. // Will load "triangles" pipeline and render debug text, setting texture to be used
  2178. gsdbg_text(...);
  2179. // Immediate
  2180. gsi_v2f();
  2181. gsi_v3f();
  2182. gsi_n3f();
  2183. // Debug shape drawing
  2184. gsi_trianglelines();
  2185. gsi_triangle();
  2186. gsi_text();
  2187. gsi_box();
  2188. gsi_boxlines();
  2189. gsi_circle();
  2190. gsi_circlelines();
  2191. gsi_rect();
  2192. gsi_rectlines();
  2193. gsi_begin(pipeline);
  2194. gsi_push_matrix();
  2195. gsi_mat_rotatef();
  2196. gsi_mat_transf();
  2197. gsi_mat_scalef();
  2198. gsi_interleavef(0, 1, 2 * sizeof(f32)); -> will push back data to be interleaved with ALL vertex data
  2199. gsi_2f(0, 1);
  2200. gsi_2f(1, 0);
  2201. gsi_2f(1, 1);
  2202. gsi_pop_matrix();
  2203. // Binding uniforms (if at all)
  2204. // Lighting Vertices
  2205. // Materials (specularity, diffuse, abmience)
  2206. gsi_clearall(); -> clears interleaved data from backend
  2207. gsi_end();
  2208. // Triangle specification
  2209. gsi_begin(pipe); // Default pipeline? Is there a default pipeline provided?
  2210. gsi_2f(0, 0);
  2211. gsi_4f(1, 1, 1, 1);
  2212. gsi_2f(1, 0);
  2213. gsi_4f(1, 1, 1, 1);
  2214. gsi_2f(1, 1);
  2215. gsi_4f(1, 1, 1, 1);
  2216. gsi_end();
  2217. // I don't like pushing/popping matrices, really...but I should do that.
  2218. // Kind of goes against my idea of NOT having to keep this stuff internal.
  2219. gsdbg_triangle();
  2220. gsdbg_cube();
  2221. gl_begin(prim_type);
  2222. gl_v2f();
  2223. gl_v2f();
  2224. gl_v2f();
  2225. gl_end();
  2226. gs_immediate_draw_i
  2227. {
  2228. gs_dyn_array(u8) vertex_data;
  2229. };
  2230. pipe.raster.layout = {
  2231. FLOAT3, // Position
  2232. FLOAT2, // UV
  2233. FLOAT4 // COLOR,
  2234. UINT4 // CUSTOM INFO
  2235. };
  2236. gsi_begin(pipe);
  2237. // Filling out vertex data
  2238. gsi_interleavef(4, 1, 1, 1, 1, stride, offset);
  2239. gsi_interleaveu(4, 10, 100, 20, 40, stride, offset);
  2240. // Vert0
  2241. gsi_3f(0, 0, 0); -> internally work against counter for interleaves?
  2242. gsi_2f(0, 0);
  2243. check against interleaves, mod against
  2244. ct += 3 * sizeof(f32)
  2245. // Vert1
  2246. gsi_3f(1, 0, 0);
  2247. gsi_2f(1, 0);
  2248. gsi_4f(1, 1, 1, 1);
  2249. // Vert2
  2250. gsi_3f(1, 1, 0);
  2251. gsi_2f(1, 1);
  2252. gsi_4f(1, 1, 1, 1);
  2253. gsi_end(); // Clears interleaves
  2254. gsdgb_line(gsdbg_i* dbg);
  2255. layout = [FLOAT3, BYTE4]
  2256. gsdbg_line(x, y, r, g, b, a)
  2257. {
  2258. gsi_begin(line_pipeline); -> This will check against currently bound pipeline and incur draw call if different
  2259. {
  2260. gsi_enable_texture(tex, 0);
  2261. gsi_2f(x, y, 0.f);
  2262. gsi_4b(r, g, b, a);
  2263. }
  2264. gsi_end();
  2265. }
  2266. gsi_enable_texture(tex, 0);
  2267. gsdgb_line();
  2268. gsdgb_boxline();
  2269. for (line in lines) {
  2270. gsdgb_line();
  2271. }
  2272. // Another pipeline to use
  2273. gsdgb_triangle();
  2274. custom pipeline, custom vertex layout
  2275. gsdbg_vattr_type flags[] = {
  2276. GSDBG_VATTR_POSITION,
  2277. GSDBG_VATTR_COLOR,
  2278. GSDBG_VATTR_UV,
  2279. GSDBG_VATTR_FLOAT4
  2280. };
  2281. size_t stride = 3 * f32 + 4 * u8 + 2 * f32 + 4 * f32;
  2282. size_t offset = 3 * f32 + 4 * u8 + 2 * f32;
  2283. [POSITIONS, COLORS, UVS, CUSTOM...]
  2284. gsi_push_pipeline();
  2285. {
  2286. gsdb_triangle();
  2287. }
  2288. gsi_pop_pipeline();
  2289. // Line
  2290. gsdbg_line();
  2291. gsdbg_boxline();
  2292. gsdbg_sphereline();
  2293. gsdbg_circleline();
  2294. gsdbg_rectline();
  2295. gsdbg_triangleline();
  2296. // Text
  2297. gsdgb_text();
  2298. // Fill
  2299. gsdbg_rect();
  2300. gsdbg_box();
  2301. gsdbg_sphere();
  2302. gsdbg_circle();
  2303. gsdbg_triangle();
  2304. gsdbg_cylinder();
  2305. gsi_draw() // Clears everything and submits to command buffer (must be called in between renderpass_begin / renderpass_end calls)
  2306. push_pipeline(custom_pipe, attr_flags*, sz); -> will incur a draw (if any) (if attr flags are null, then use default flags for pipeline)
  2307. {
  2308. // Will draw triangle using provided attr information
  2309. gsi_triangle();
  2310. // Will interleave this data throughout the vertex declaration
  2311. float ildata[] = {1.f, 0.f, 0.f, 1.f};
  2312. push_vattr_data(attr, ildata, sizeof(ildata));
  2313. gsi_triangle();
  2314. push_vattr_data();
  2315. // Immediate mode drawing (just buffer commands, allow user to push pipeline)
  2316. // Immediate Shapes (uses immediate mode drawing to draw debug shapes using its own pipelines and commands)
  2317. // Set layout with pipeline
  2318. // Call set of functions to write raw vertex data into buffer
  2319. // Writing data into buffer stream
  2320. gsi_1f();
  2321. gsi_2f();
  2322. gsi_3f();
  2323. gsi_4f();
  2324. gsi_4u8();
  2325. gsi_3u8();
  2326. gsi_2u8();
  2327. gsi_1u8();
  2328. gsi_4ui();
  2329. gsi_3ui();
  2330. gsi_2ui();
  2331. gsi_1ui();
  2332. gsi_flist(...);
  2333. gsi_u8list(...);
  2334. gsi_ulist(...);
  2335. gsi_ilist(...);
  2336. // What does the default shader look like?
  2337. v:
  2338. vposition = mvp * a_pos
  2339. vuv = a_uv
  2340. vcolor = a_color
  2341. vnormal = a_normal
  2342. f:
  2343. fcolor = vcolor * texture(uv)
  2344. // Would be useful to just be able to push a light...
  2345. // Pushing/Popping matrices (do this to pre-multiply your verts with information)(not really necessary though)
  2346. }
  2347. pop_pipeline(); -> will incur draw (if any)
  2348. // Is immediate mode single threaded? Yes, unless you provide your own interface to use.
  2349. // Then you just have to make sure you're not using that interface in multiple places. EZ PZ.
  2350. // Is there a way for this to work with models? Or simple shapes?
  2351. // Add in new
  2352. // Begins render pass
  2353. gs_immediate_begin_pass(gi);
  2354. {
  2355. gs_immediate_push_renderpass(cb, rp, actions, actionsz);
  2356. {
  2357. // Pipeline has a specific layout, in the vertex data, you can push certain vertex information, depending on layout?
  2358. gs_immediate_push_pipeline(cb, pip);
  2359. {
  2360. gs_immediate_begin(cb);
  2361. {
  2362. // Let's say layout is this:
  2363. layout =
  2364. float3, // position
  2365. float2, // uv
  2366. uint4 // color
  2367. // Then vertex buffer is just a u8 byte buffer that can be uploaded directly to GPU
  2368. // Defines interleaved data format
  2369. gs_immediate_write_3f(cb, x, y, z);
  2370. gs_immediate_write_2f(cb, u, v);
  2371. gs_immediate_write_4ui(cb, r, g, b, a);
  2372. }
  2373. gs_immediate_end(cb);
  2374. gs_immediate_draw(cb); // Force render
  2375. }
  2376. gs_immediate_pop_pipeline(cb);
  2377. }
  2378. gs_immediate_pop_renderpass(cb);
  2379. }
  2380. gs_immediate_end_pass(cb);
  2381. gs_immediate_draw_triangle();
  2382. Immediate mode rendering utility (for debugging and simple immediate-mode UI)
  2383. Features:
  2384. Shapes:
  2385. * Line
  2386. * Triangle
  2387. * Rect
  2388. * Circle
  2389. * Cube
  2390. * Sphere
  2391. * Cone
  2392. * Cylinder
  2393. Lighting:
  2394. Matrices:
  2395. Pipeline:
  2396. */
  2397. #endif // GS_IDRAW_H