/** * Copyright (C) 2026 andromeda * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . **/ module rsgl; const int MAX_BATCHES = 2028; const int MAX_VERTS = 8192; enum DebugType : char { ERROR, WARNING, INFO, } enum ErrorCode : char { NO_ERROR, ERROR_BACKEND, ERROR_QUERY_FAIL, ERROR_SHADER, INFO_BACKEND, INFO_SHADER, WARNING_BACKEND, } struct DebugInfo { DebugType type; ErrorCode code; ZString msg; } alias DebugFunc = fn void(DebugInfo*); enum TextureFormat : int { NONE, RGB, BGR, RGBA, BGRA, RED, GRAYSCALE, GRAYSCALE_ALPHA, FORMAT_COUNT, } enum TextureDataType : int { INT, FLOAT, } enum TextureFilter : int { NEAREST, LINEAR, } struct TextureBlob { void* data; usz width; usz height; TextureDataType data_type; TextureFormat data_format; TextureFormat texture_format; TextureFilter min_filter; TextureFilter mag_filter; } alias Texture = usz; alias Framebuffer = usz; struct Rect { float x; float y; float w; float h; } struct Cube { float x; float y; float z; float w; float l; float h; } struct Vec2D { float x; float y; } struct Vec3D { float x; float y; float z; } macro @triangle(#p1, #p2, #p3) => (Vec3D[3]) { #p1, #p2, #p3 }; macro @createTriangle( #p1x, #p1y, #p1z, #p2x, #p2y, #p2z, #p3x, #p3y, #p3z ) => @triangle((Vec3D) { #p1x, #p1y, #p1z }, (Vec3D) { #p2x, #p2y, #p2z }, (Vec3D) { #p3x, #p3y, #p3z }); struct Color { char a; char b; char g; char r; } macro @rgba(#r, #g, #b, #a) => (Color) { #a, #b, #g, #r }; macro @rgb(#r, #g, #b) => (Color) { 255, #b, #g, #r }; macro @color_to_hex(#color) => (uint)#color & 0xFFFFFF00; macro @rgb_to_hex(#r, #g, #b) => @color_to_hex(@rgb(#r, #g, #b)); macro @rgba_to_hex(#r, #g, #b, #a) => @color_to_hex(@rgba(#r, #g, #b, #a)); struct Mat4 { float[16] m; } enum ProjectionType : int { ORTHO_2D, ORTHO_3D, PERSPECTIVE_3D, } struct Projection2D { ProjectionType type; uint width; uint height; } struct Projection3D { ProjectionType type; float fov; float ratio; float pNear; float pFar; } union Projection { ProjectionType type; Projection2D p2D; Projection3D p3D; } enum DrawType : int { TRIANGLES, POINTS, LINES, } struct RawVerts { DrawType type; float* verts; float* tex_coords; ushort* elements; usz elm_count; usz vert_count; } constdef ShaderType : int { NONE = 0, STANDARD = 1, COMPUTE = 2, GEOMETRY = 4, } struct ProgramBlob { CChar* vertex; usz vertex_len; CChar* fragment; usz fragment_len; } struct ProgramInfo { usz program; usz perspective_view; usz model; usz vertex_position; usz vertex_tex_coord; usz vertex_color; ShaderType type; } struct Batch { usz start; usz len; usz elm_start; usz elm_count; DrawType type; Texture tex; float line_width; Mat4 matrix; } struct RenderData { float* verts; float* tex_coords; float* colors; ushort* elements; usz elements_count; usz len; Mat4 perspective; } enum BufferType : int { ARRAY_BUFFER, ELEMENT_ARRAY_BUFFER, SHADER_STORAGE_BUFFER, TEXTURE_BUFFER, UNIFORM_BUFFER, } struct RenderBuffers { usz vertex; usz color; usz texture; usz elements; usz max_verts; Batch[MAX_BATCHES] batches; usz batch_count; } struct RenderState { float* gradient; Rect source; Texture texture; uint gradient_len; Color color; Vec3D rotate; ProgramInfo* program; RenderBuffers* buffers; Vec3D center; float line_width; Mat4 model_matrix; Mat4 view_matrix; Mat4 perspective_matrix; bool force_batch; bool overflow; Framebuffer framebuffer; } struct RenderPass { ProgramInfo* program; float* matrix; RenderBuffers* buffers; Framebuffer framebuffer; } alias RendererProcSize = fn usz(); alias RendererProcDefaultBlob = fn ProgramBlob(void*); alias RendererProcInitPtr = fn void(void*, void*); alias RendererProcFreePtr = fn void(void*); alias RendererProcRender = fn void(void*, RenderPass*); alias RendererProcClear = fn void(void*, Framebuffer, float, float, float, float); alias RendererProcViewport = fn void(void*, int, int, int, int); alias RendererProcSetSurface = fn void(void*, void*); alias RendererProcCreateTexture = fn Texture(void*, TextureBlob*); alias RendererProcCopyToTexture = fn void(void*, Texture, usz, usz, TextureBlob*); alias RendererProcDeleteTexture = fn void(void*, Texture); alias RendererProcScissorStart = fn void(void*, float, float, float, float, float); alias RendererProcScissorEnd = fn void(void*); alias RendererProcCreateProgram = fn ProgramInfo(void*, ProgramBlob*); alias RendererProcDeleteProgram = fn void(void*, ProgramInfo*); alias RendererProcFindShaderVariable = fn usz(void*, ProgramInfo*, ZString, usz); alias RendererProcUpdateShaderVariable = fn void(void*, ProgramInfo*, usz, float*, char); alias RendererProcCreateComputeProgram = fn ProgramInfo(void*, ZString); alias RendererProcDispatchComputeProgram = fn void(void*, ProgramInfo*, uint, uint, uint); alias RendererProcBindComputeTexture = fn void(void*, uint, char); alias RendererProcCreateBuffer = fn void(void*, BufferType, usz, void*, usz*); alias RendererProcUpdateBuffer = fn void(void*, BufferType, usz, void*, usz, usz); alias RendererProcDeleteBuffer = fn void(void*, usz); alias RendererProcCreateFramebuffer = fn Framebuffer(void*, usz, usz); alias RendererProcAttachFramebuffer = fn void(void*, Framebuffer, Texture, char, char); alias RendererProcDeleteFramebuffer = fn void(void*, Framebuffer); struct RendererProc { RendererProcSize size; RendererProcDefaultBlob default_blob; RendererProcInitPtr init_ptr; RendererProcFreePtr free_ptr; RendererProcRender render; RendererProcClear clear; RendererProcViewport viewport; RendererProcSetSurface set_surface; RendererProcCreateTexture create_texture; RendererProcCopyToTexture copy_to_texture; RendererProcDeleteTexture delete_texture; RendererProcScissorStart scissor_start; RendererProcScissorEnd scissor_end; RendererProcCreateProgram create_program; RendererProcDeleteProgram delete_program; RendererProcFindShaderVariable find_shader_variable; RendererProcUpdateShaderVariable update_shader_variable; RendererProcCreateComputeProgram create_compute_program; RendererProcDispatchComputeProgram dispatch_compute_program; RendererProcBindComputeTexture bind_compute_texture; RendererProcCreateBuffer create_buffer; RendererProcUpdateBuffer update_buffer; RendererProcDeleteBuffer delete_buffer; RendererProcCreateFramebuffer create_framebuffer; RendererProcAttachFramebuffer attach_framebuffer; RendererProcDeleteFramebuffer delete_framebuffer; } struct Renderer { RenderData data; RenderState state; RendererProc proc; void* user_ptr; void* ctx; Texture default_texture; ProgramInfo default_program; Mat4 default_perspective_matrix; float[MAX_VERTS * 3] verts; float[MAX_VERTS * 2] tex_coords; float[MAX_VERTS * 4] colors; ushort[MAX_VERTS * 6] elements; RenderBuffers buffers; } enum ViewType : int { NONE, TWO_D, THREE_D, } struct View2D { ViewType type; Vec3D offset; Vec3D target; float rotation; float zoom; } struct View3D { ViewType type; Vec3D pos; Vec3D target; Vec3D up; } union View { ViewType type; View2D view_2D; View3D view_3D; } extern fn DebugFunc set_debug_func(DebugFunc) @cname("RSGL_setDebugCallback"); extern fn void debug_callback(DebugType, ErrorCode, ZString) @cname("RSGL_debugCallback"); extern fn Mat4 mat4_loadIdentity() @cname("RSGL_mat4_loadIdentity"); extern fn Mat4 Mat4.scale(self, float, float, float) @cname("RSGL_mat4_scale"); extern fn Mat4 Mat4.rotate(self, float, float, float, float) @cname("RSGL_mat4_rotate"); extern fn Mat4 Mat4.translate(self, float, float, float) @cname("RSGL_mat4_translate"); extern fn Mat4 Mat4.perspective(self, float, float, float, float) @cname("RSGL_mat4_perspective"); extern fn Mat4 Mat4.ortho(self, float, float, float, float, float, float) @cname("RSGL_mat4_ortho"); extern fn Mat4 Mat4.look_at(self, float, float, float, float, float, float, float, float, float) @cname("RSGL_mat4_lookAt"); extern fn Mat4 Mat4.multiply(self, Mat4) @cname("RSGL_mat4_multiply"); extern fn Vec3D Mat4.multiply_point(self, Vec3D) @cname("RSGL_mat4_multiplyPoint"); extern fn Mat4 Projection.get_matrix(&self) @cname("RSGL_projection_getMatrix"); extern fn void Renderer.get_render_state(&self, RenderState*) @cname("RSGL_renderer_getRenderState"); extern fn usz Renderer.size(&self) @cname("RSGL_renderer_size"); extern fn void renderer_initPtr(RendererProc*, void*, void*, Renderer*) @cname("RSGL_renderer_initPtr"); extern fn Renderer* renderer_init(RendererProc, void*) @cname("RSGL_renderer_init"); extern fn void Renderer.update_size(&self, usz, usz) @cname("RSGL_renderer_updateSize"); extern fn void Renderer.free_ptr(&self) @cname("RSGL_renderer_freePtr"); extern fn void Renderer.set_surface(&self, void*) @cname("RSGL_renderer_setSurface"); extern fn void Renderer.create_buffer(&self, BufferType, usz, void*, usz*) @cname("RSGL_renderer_createBuffer"); extern fn void Renderer.update_buffer(&self, BufferType, usz, void*, usz, usz) @cname("RSGL_renderer_updateBuffer"); extern fn void Renderer.delete_buffer(&self, usz) @cname("RSGL_renderer_deleteBuffer"); extern fn void Renderer.create_render_buffers(&self, usz, RenderBuffers*) @cname("RSGL_renderer_createRenderBuffers"); extern fn void Renderer.delete_render_buffers(&self, RenderBuffers*) @cname("RSGL_renderer_deleteRenderBuffers"); extern fn void Renderer.render(&self) @cname("RSGL_renderer_render"); extern fn void Renderer.update_render_buffers(&self) @cname("RSGL_renderer_updateRenderbuffers"); extern fn void Renderer.render_buffers(&self) @cname("RSGL_renderer_renderBuffers"); extern fn void Renderer.free(&self) @cname("RSGL_renderer_free"); extern fn void Renderer.set_rotate(&self, Vec3D) @cname("RSGL_renderer_setRotate"); extern fn void Renderer.set_texture(&self, Texture) @cname("RSGL_renderer_setTexture"); extern fn void Renderer.set_texture_source(&self, Texture, Rect) @cname("RSGL_renderer_setTextureSource"); extern fn void Renderer.set_color(&self, Color) @cname("RSGL_renderer_setColor"); extern fn void Renderer.set_program(&self, ProgramInfo*) @cname("RSGL_renderer_setProgram"); extern fn void Renderer.set_framebuffer(&self, Framebuffer) @cname("RSGL_renderer_setFramebuffer"); extern fn void Renderer.set_render_buffers(&self, RenderBuffers*) @cname("RSGL_renderer_setRenderBuffers"); extern fn void Renderer.set_gradent(&self, float*, usz) @cname("RSGL_renderer_setGradient"); extern fn void Renderer.set_center(&self, Vec3D) @cname("RSGL_renderer_setCenter"); extern fn void Renderer.set_overflow(&self, bool) @cname("RSGL_renderer_setOverflow"); extern fn void Renderer.clear_args(&self) @cname("RSGL_renderer_clearArgs"); extern fn Mat4 Renderer.init_draw_matrix(&self, Vec3D) @cname("RSGL_renderer_initDrawMatrix"); extern fn void Renderer.clear(&self, Color) @cname("RSGL_renderer_clear"); extern fn void Renderer.viewport(&self, Rect) @cname("RSGL_renderer_viewport"); extern fn Texture Renderer.create_texture(&self, TextureBlob*) @cname("RSGL_renderer_createTexture"); extern fn void Renderer.copy_to_texture(&self, Texture, usz, usz, TextureBlob*) @cname("RSGL_renderer_copyToTexture"); extern fn void Renderer.delete_texture(&self, Texture) @cname("RSGL_renderer_deleteTexture"); extern fn Framebuffer Renderer.create_framebuffer(&self, usz, usz) @cname("RSGL_renderer_createFramebuffer"); extern fn void Renderer.attach_framebuffer(&self, Framebuffer, Texture, char, char) @cname("RSGL_renderer_attachFramebuffer"); extern fn void Renderer.delete_framebuffer(&self, Framebuffer) @cname("RSGL_renderer_deleteFramebuffer"); extern fn void Renderer.scissor_start(&self, Rect, int) @cname("RSGL_renderer_scissorStart"); extern fn void Renderer.scissor_end(&self) @cname("RSGL_renderer_scissorEnd"); extern fn ProgramBlob Renderer.default_blob(&self) @cname("RSGL_renderer_defaultBlob"); extern fn ProgramInfo Renderer.create_program(&self, ProgramBlob*) @cname("RSGL_renderer_createProgram"); extern fn void Renderer.delete_program(&self, ProgramInfo*) @cname("RSGL_renderer_deleteProgram"); extern fn usz Renderer.find_shader_variable(&self, ProgramInfo*, ZString, usz) @cname("RSGL_renderer_findShaderVariable"); extern fn void Renderer.update_shader_variable(&self, ProgramInfo*, usz, float*, char) @cname("RSGL_renderer_updateShaderVariable"); extern fn void Renderer.force_batch(&self) @cname("RSGL_renderer_forceBatch"); extern fn void Renderer.set_perspective_matrix(&self, Mat4) @cname("RSGL_renderer_setPerspectiveMatrix"); extern fn void Renderer.set_default_perspective_matrix(&self, Mat4) @cname("RSGL_renderer_setDefaultPerspectiveMatrix"); extern fn void Renderer.set_model_matrix(&self, Mat4) @cname("RSGL_renderer_setModelMatrix"); extern fn void Renderer.reset_model_matrix(&self) @cname("RSGL_renderer_resetModelMatrix"); extern fn ProgramInfo Renderer.create_compute_program(&self, ZString) @cname("RSGL_renderer_createComputeProgram"); extern fn void Renderer.dispatch_compute_program( &self, ProgramInfo*, uint, uint, uint ) @cname("RSGL_renderer_dispatchComputeProgram"); extern fn void Renderer.bind_compute_texture(&self, uint, char) @cname("RSGL_renderer_bindComputeTexture"); extern fn int Renderer.draw_raw_verts(&self, RawVerts*) @cname("RSGL_drawRawVerts"); module rsgl @feat(HIGHLEVEL); extern fn int Renderer.draw_point(&self, Vec2D) @cname("RSGL_drawPoint"); extern fn int Renderer.draw_rect(&self, Rect) @cname("RSGL_drawRect"); extern fn int Renderer.draw_round_rect(&self, Rect, Vec2D) @cname("RSGL_drawRoundRect"); extern fn int Renderer.draw_polygon(&self, Rect, uint) @cname("RSGL_drawPolygon"); extern fn int Renderer.draw_arc(&self, Rect, Vec2D) @cname("RSGL_drawArc"); extern fn int Renderer.draw_oval(&self, Rect) @cname("RSGL_drawOval"); extern fn int Renderer.draw_line(&self, Vec2D, Vec2D, uint) @cname("RSGL_drawLine"); extern fn int Renderer.draw_triangle(&self, Vec3D[3]) @cname("RSGL_drawTriangle"); extern fn int Renderer.draw_point_3D(&self, Vec3D) @cname("RSGL_drawPoint3D"); extern fn int Renderer.draw_line_3D(&self, Vec3D, Vec3D, uint) @cname("RSGL_drawLine3D"); extern fn int Renderer.draw_cube(&self, Cube) @cname("RSGL_drawCube"); extern fn int Renderer.draw_triangle_outline(&self, Vec3D[3], uint) @cname("RSGL_drawTriangleOutline"); extern fn int Renderer.draw_rect_outline(&self, Rect, uint) @cname("RSGL_drawRectOutline"); extern fn int Renderer.draw_round_rect_outline(&self, Rect, Vec2D, uint) @cname("RSGL_drawRoundRectOutline"); extern fn int Renderer.draw_polygon_outline(&self, Rect, uint, uint) @cname("RSGL_drawPolygonOutline"); extern fn int Renderer.draw_arc_outline(&self, Rect, Vec2D, uint) @cname("RSGL_drawArcOutline"); extern fn int Renderer.draw_oval_outline(&self, Rect, uint) @cname("RSGL_drawovalOutline"); extern fn Mat4 View.get_matrix(&self) @cname("RSGL_view_getMatrix"); module rsgl::gl @feat(OPENGL); struct GlRenderer { uint vao; } extern fn RendererProc renderer_proc() @cname("RSGL_GL_rendererProc"); extern fn usz size() @cname("RSGL_GL_size"); module rsgl::rfont @feat(RFONT); import rfont; extern fn rfont::RendererProc renderer_proc() @cname("RFont_RSGL_renderer_proc"); extern fn rfont::Renderer* renderer_init(rsgl::Renderer*) @cname("RFont_RSGL_renderer_init"); extern fn void renderer_initPtr(rsgl::Renderer*, rfont::Renderer*) @cname("RFont_RSGL_renderer_initPtr"); extern fn void renderer_free(rfont::Renderer*) @cname("RFont_RSGL_renderer_free");