diff options
| -rw-r--r-- | flake.nix | 2 | ||||
| -rw-r--r-- | include/RSGL.h | 1925 | ||||
| -rw-r--r-- | include/RSGL_gl.h | 1001 | ||||
| -rw-r--r-- | main.c3 | 54 | ||||
| -rw-r--r-- | project.json | 2 | ||||
| -rw-r--r-- | rgfw.c3 | 83 | ||||
| -rw-r--r-- | rsgl.c3 | 95 | ||||
| -rw-r--r-- | shim.c | 11 |
8 files changed, 3123 insertions, 50 deletions
@@ -27,8 +27,8 @@ ]; nativeBuildInputs = [ pkgs.libxkbcommon - pkgs.libGL pkgs.wayland + pkgs.libGL ]; configurePhase = '' wayland-scanner client-header ${pkgs.wayland-protocols}/share/wayland-protocols/stable/xdg-shell/xdg-shell.xml include/xdg-shell.h diff --git a/include/RSGL.h b/include/RSGL.h new file mode 100644 index 0000000..3c28e44 --- /dev/null +++ b/include/RSGL.h @@ -0,0 +1,1925 @@ +/* +* +* Copyright (c) 2021-25 ColleagueRiley ColleagueRiley@gmail.com +* +* This software is provided 'as-is', without any express or implied +* warranty. In no event will the authors be held liable for any damages +* arising from the use of this software. +* +* Permission is granted to anyone to use this software for any purpose, +* including commercial applications, and to alter it and redistribute it +* freely, subject to the following restrictions: +* +* 1. The origin of this software must not be misrepresented; you must not +* claim that you wrote the original software. If you use this software +* in a product, an acknowledgment in the product documentation would be +* appreciated but is not required. +* 2. Altered source versions must be plainly marked as such, and must not be +* misrepresented as being the original software. +* 3. This notice may not be removed or altered from any source distribution. +* +* +*/ + +/* + define args + (MAKE SURE RSGL_IMPLEMENTATION is in exactly one header or you use -DRSGL_IMPLEMENTATION) + #define RSGL_IMPLEMENTATION - makes it so source code is included with header + + #define RSGL_RFONT - do include functions to help with integrating RFont and RSGL + #define RSGL_MAX_BATCHES [number of batches] - set max number of batches to be allocated + #define RSGL_MAX_VERTS [number of verts] - set max number of verts to be allocated (global, not per batch) +*/ +#include <stdint.h> +#ifndef RSGL_MAX_BATCHES +#define RSGL_MAX_BATCHES 2028 +#endif +#ifndef RSGL_MAX_VERTS +#define RSGL_MAX_VERTS 8192 +#endif + +#ifndef RSGL_MALLOC +#include <stdlib.h> +#define RSGL_MALLOC malloc +#define RSGL_REALLOC realloc +#define RSGL_FREE free +#endif + +#ifndef RSGL_SIN +#include <math.h> +#define RSGL_SIN sinf +#define RSGL_COS cosf +#endif + +#ifndef RSGL_UNUSED +#define RSGL_UNUSED(x) (void) (x); +#endif + +#ifndef RSGL_MEMCPY + #include <string.h> + #define RSGL_MEMCPY(dest, src, count) memcpy(dest, src, count) + #define RSGL_MEMSET(ptr, value, num) memset(ptr, value, num) +#endif + +#ifndef RSGL_H +#define RSGL_H +#ifndef RSGLDEF +#ifdef __APPLE__ +#define RSGLDEF extern inline +#else +#define RSGLDEF inline +#endif +#endif + +#ifndef RSGL_INT_DEFINED + #define RSGL_INT_DEFINED + #if defined(_MSC_VER) || defined(__SYMBIAN32__) + typedef unsigned char u8; + typedef signed char i8; + typedef unsigned short u16; + typedef signed short i16; + typedef unsigned int u32; + typedef signed int i32; + typedef unsigned long long u64; + typedef signed long long i64; + #else + #include <stdint.h> + + typedef uint8_t u8; + typedef int8_t i8; + typedef uint16_t u16; + typedef int16_t i16; + typedef uint32_t u32; + typedef int32_t i32; + typedef uint64_t u64; + typedef int64_t i64; + #endif +#endif + +#ifndef RSGL_BOOL_DEFINED +#define RSGL_BOOL_DEFINED + +#include <stdbool.h> +typedef bool RSGL_bool; +#endif + +#define RSGL_TRUE (RSGL_bool)1 +#define RSGL_FALSE (RSGL_bool)0 + +typedef enum RSGL_textureFormat { + RSGL_formatNone = 0, + RSGL_formatRGB, /*!< 8-bit RGB (3 channels) */ + RSGL_formatBGR, /*!< 8-bit BGR (3 channels) */ + RSGL_formatRGBA, /*!< 8-bit RGBA (4 channels) */ + RSGL_formatBGRA, /*!< 8-bit BGRA (4 channels) */ + RSGL_formatRed, /*!< 8-bit RED (1 channel) */ + RSGL_formatGrayscale, /*!< 8-bit grayscale (1 channel) */ + RSGL_formatGrayscaleAlpha, /*!< 8-bit grayscale alpha (1 channel) */ + RSGL_formatCount +} RSGL_textureFormat; + +typedef enum RSGL_textureDataType { + RSGL_textureDataInt = 0, + RSGL_textureDataFloat +} RSGL_textureDataType; + +typedef enum RSGL_textureFilter { + RSGL_filterNearest = 0, + RSGL_filterLinear +} RSGL_textureFilter; + +typedef struct RSGL_textureBlob { + void* data; /* input data */ + size_t width; /* width of the texture */ + size_t height; /* height of the texture */ + RSGL_textureDataType dataType; + RSGL_textureFormat dataFormat; /* format of the input data */ + RSGL_textureFormat textureFormat; /* final format for the texture */ + RSGL_textureFilter minFilter; /* filter used when rendering a surface smaller than the base texture */ + RSGL_textureFilter magFilter; /* filter used when rendering a surface bigger than the base texture */ +} RSGL_textureBlob; + +#ifndef RSGL_texture +#define RSGL_texture size_t +#endif + +#ifndef RSGL_framebuffer +#define RSGL_framebuffer size_t +#endif + +/* +******* +RSGL shapes +******* +*/ + +#ifndef RSGL_rect +typedef struct RSGL_rect { float x, y, w, h; } RSGL_rect; +#endif + +#define RSGL_RECT(x, y, w, h) (RSGL_rect){(float)x, (float)y, (float)w, (float)h} + +#ifndef RSGL_cube +typedef struct RSGL_cube { float x, y, z, w, h, l; } RSGL_cube; +#endif + +#define RSGL_CUBE(x, y, z, w, h, l) (RSGL_cube){(float)x, (float)y, (float)z, (float)w, (float)h, (float)l} + +#ifndef RSGL_vec2D +typedef struct RSGL_vec2D { float x, y; } RSGL_vec2D; +#endif +#define RSGL_VEC2D(x, y) (RSGL_vec2D){(float)x, (float)y} + +#ifndef RSGL_vec3D +typedef struct RSGL_vec3D { float x, y, z; } RSGL_vec3D; +#endif + +#define RSGL_VEC3D(x, y, z) (RSGL_vec3D){(float)x, (float)y, (float)z} + +#define RSGL_TRIANGLE(p1, p2, p3) (RSGL_vec3D[3]){p1, p2, p3} +#define RSGL_createTriangle(p1x, p1y, p1z, p2x, p2y, p2z, p3x, p3y, p3z) RSGL_TRIANGLE3D(RSGL_VEC3D(p1x, p1y, p1z), RSGL_VEC3D(p2x, p2y, p2z), RSGL_VEC3D(p3x, p3y, p3z)) + +/* +the color stucture is in +ABGR by default for performance reasons +(converting color to hex for example) +*/ +#ifndef RSGL_color +typedef struct RSGL_color { + u8 a, b, g, r; +} RSGL_color; +#endif + +#define RSGL_RGBA(r, g, b, a) ((RSGL_color){(u8)(a), (u8)(b), (u8)(g), (u8)(r)}) +#define RSGL_RGB(r, g, b) ((RSGL_color){255, (u8)(b), (u8)(g), (u8)(r)}) + +#define RSGL_COLOR_TO_HEX(color) ((u32)(color) & 0xFFFFFF00) +#define RSGL_RGB_TO_HEX(r, g, b, a) (RSGL_COLOR_TO_HEX(RSGL_RGBA(r, g, b, a))) +#define RSGL_RGBA_TO_HEX(r, g, b) (RSGL_COLOR_TO_HEX(RSGL_RGB(r, g, b, a))) + +/* +********************* +RSGL matrix math +********************* +*/ + +#ifndef RSGL_mat4 +typedef struct RSGL_mat4 { + float m[16]; +} RSGL_mat4; +#endif + +RSGLDEF RSGL_mat4 RSGL_mat4_loadIdentity(void); +RSGLDEF RSGL_mat4 RSGL_mat4_scale(float matrix[16], float x, float y, float z); +RSGLDEF RSGL_mat4 RSGL_mat4_rotate(float matrix[16], float angle, float x, float y, float z); +RSGLDEF RSGL_mat4 RSGL_mat4_translate(float matrix[16], float x, float y, float z); +RSGLDEF RSGL_mat4 RSGL_mat4_perspective(float matrix[16], float fovY, float aspect, float zNear, float zFar); +RSGLDEF RSGL_mat4 RSGL_mat4_ortho(float matrix[16], float left, float right, float bottom, float top, float znear, float zfar); +RSGLDEF RSGL_mat4 RSGL_mat4_lookAt(float matrix[16], float eyeX, float eyeY, float eyeZ, float targetX, float targetY, float targetZ, float upX, float upY, float upZ); + +RSGLDEF RSGL_mat4 RSGL_mat4_multiply(float left[16], float right[16]); + +RSGLDEF RSGL_vec3D RSGL_mat4_multiplyPoint(RSGL_mat4 matrix, RSGL_vec3D point); + +/* +******* +RSGL_perspective +******* +*/ + +typedef enum RSGL_projectionType { + RSGL_projectionOrtho2D = 0, + RSGL_projectionOrtho3D, + RSGL_projectionPerspective3D, +} RSGL_projectionType; + +typedef struct RSGL_projection2D { + RSGL_projectionType type; + u32 width; + u32 height; +} RSGL_projection2D; + +typedef struct RSGL_projection3D { + RSGL_projectionType type; + float fov; + float ratio; + float pNear; + float pFar; +} RSGL_projection3D; + +typedef union RSGL_projection { + RSGL_projectionType type; + RSGL_projection2D p2D; + RSGL_projection3D p3D; +} RSGL_projection; + +RSGLDEF RSGL_mat4 RSGL_projection_getMatrix(const RSGL_projection* projection); + +/* +********************* +RSGL renderer +********************* +*/ + +/* used internally for RSGL_deleteProgram */ +typedef enum RSGL_shaderType { + RSGL_shaderTypeNone = 0, + RSGL_shaderTypeStandard = 1, /* standard vertex+fragment shader */ + RSGL_shaderTypeCompute = 2, + RSGL_shaderTypeGeometry = 4, /* unimplemented as of now */ +} RSGL_shaderType; + +/* shader program and blob */ +typedef struct RSGL_programBlob { + const char* vertex; + size_t vertexLen; + const char* fragment; + size_t fragmentLen; +} RSGL_programBlob; + +typedef struct RSGL_programInfo { + size_t program; + size_t perspectiveView; + size_t model; + size_t vertexPosition; + size_t vertexTexCoord; + size_t vertexColor; + + RSGL_shaderType type; +} RSGL_programInfo; + +typedef struct RSGL_BATCH { + size_t start, len; /* when batch starts and it's length */ + size_t elmStart, elmCount; /* when element batch starts and it's length */ + u32 type; + RSGL_texture tex; + float lineWidth; + RSGL_mat4 matrix; +} RSGL_BATCH; /* batch data type for rendering */ + +typedef struct RSGL_renderData { + float* verts; + float* texCoords; + float* colors; + u16* elements; + size_t elements_count; + size_t len; /* number of verts */ + + RSGL_mat4 perspective; /* perspective matrix */ +} RSGL_renderData; + +typedef enum RSGL_bufferType { + RSGL_arrayBuffer = 0, + RSGL_elementArrayBuffer, + RSGL_shaderStorageBuffer, + RSGL_textureBuffer, + RSGL_uniformBuffer +} RSGL_bufferType; + +typedef struct RSGL_renderBuffers { + size_t vertex, color, texture, elements; + size_t maxVerts; + + RSGL_BATCH batches[RSGL_MAX_BATCHES]; + size_t batchCount; +} RSGL_renderBuffers; + +typedef struct RSGL_renderState { + float* gradient; /* does not allocate any memory */ + + RSGL_rect source; + RSGL_texture texture; + u32 gradient_len; + + RSGL_color color; + + RSGL_vec3D rotate; + RSGL_programInfo* program; + RSGL_renderBuffers* buffers; + + RSGL_vec3D center; + float lineWidth; + RSGL_mat4 modelMatrix; + RSGL_mat4 viewMatrix; + RSGL_mat4 perspectiveMatrix; + RSGL_bool forceBatch; + RSGL_bool overflow; + RSGL_framebuffer framebuffer; +} RSGL_renderState; + +typedef struct RSGL_renderPass { + RSGL_programInfo* program; + float* matrix; + RSGL_renderBuffers* buffers; + RSGL_framebuffer framebuffer; +} RSGL_renderPass; + +typedef struct RSGL_rendererProc { + size_t (*size)(void); /* get the size of the renderer's internal struct */ + RSGL_programBlob (*defaultBlob)(void* ctx); + void (*initPtr)(void* ctx, void* proc); /* init render backend */ + void (*freePtr)(void* ctx); /* free render backend */ + void (*render)(void* ctx, const RSGL_renderPass* pass); + void (*clear)(void* ctx, RSGL_framebuffer framebuffer, float r, float g, float b, float a); + void (*viewport)(void* ctx, i32 x, i32 y, i32 w, i32 h); + void (*setSurface)(void* ctx, void* surface); + RSGL_texture (*createTexture)(void* ctx, const RSGL_textureBlob* blob); + void (*copyToTexture)(void* ctx, RSGL_texture texture, size_t x, size_t y, const RSGL_textureBlob* blob); + void (*deleteTexture)(void* ctx, RSGL_texture tex); + void (*scissorStart)(void* ctx, float x, float y, float w, float h, float renderer_height); + void (*scissorEnd)(void* ctx); + RSGL_programInfo (*createProgram)(void* ctx, RSGL_programBlob* blob); + void (*deleteProgram)(void* ctx, const RSGL_programInfo* program); + size_t (*findShaderVariable)(void*, const RSGL_programInfo*, const char*, size_t); + void (*updateShaderVariable)(void*, const RSGL_programInfo*, size_t, const float[], u8); + RSGL_programInfo (*createComputeProgram)(void* ctx, const char* CShaderCode); + void (*dispatchComputeProgram)(void* ctx, const RSGL_programInfo* program, u32 groups_x, u32 groups_y, u32 groups_z); + void (*bindComputeTexture)(void* ctx, u32 texture, u8 format); + void (*createBuffer)(void* ctx, RSGL_bufferType type, size_t size, const void* data, size_t* buffer); + void (*updateBuffer)(void* ctx, RSGL_bufferType type, size_t buffer, void* data, size_t start, size_t len); + void (*deleteBuffer)(void* ctx, size_t buffer); + RSGL_framebuffer (*createFramebuffer)(void* ctx, size_t width, size_t height); + void (*attachFramebuffer)(void* ctx, RSGL_framebuffer fbo, RSGL_texture tex, u8 attachType, u8 mipLevel); + void (*deleteFramebuffer)(void* ctx, RSGL_framebuffer fbo); +} RSGL_rendererProc; + +typedef struct RSGL_renderer { + RSGL_renderData data; + RSGL_renderState state; + RSGL_rendererProc proc; + void* userPtr; + void* ctx; /* pointer for the renderer backend to store any internal data it wants/needs */ + + RSGL_texture defaultTexture; + RSGL_programInfo defaultProgram; + RSGL_mat4 defaultPerspectiveMatrix; + + float verts[RSGL_MAX_VERTS * 3]; + float texCoords[RSGL_MAX_VERTS * 2]; + float colors[RSGL_MAX_VERTS * 4]; + u16 elements[RSGL_MAX_VERTS * 6]; + RSGL_renderBuffers buffers; +} RSGL_renderer; + +RSGLDEF void RSGL_renderer_getRenderState(RSGL_renderer* renderer, RSGL_renderState* state); + +RSGLDEF size_t RSGL_renderer_size(RSGL_renderer* renderer); + +RSGLDEF void RSGL_renderer_initPtr(RSGL_rendererProc proc, + void* loader, /* opengl prozc address ex. wglProcAddress */ + void* ptr, /* pointer to allocate backend data */ + RSGL_renderer* renderer + ); + +RSGLDEF RSGL_renderer* RSGL_renderer_init(RSGL_rendererProc proc, void* loader); +RSGLDEF void RSGL_renderer_updateSize(RSGL_renderer* renderer, size_t width, size_t height); +RSGLDEF void RSGL_renderer_freePtr(RSGL_renderer* renderer); + +RSGLDEF void RSGL_renderer_setSurface(RSGL_renderer* renderer, void* surface); + +RSGLDEF void RSGL_renderer_createBuffer(RSGL_renderer* renderer, RSGL_bufferType type, size_t size, const void* data, size_t* buffer); +RSGLDEF void RSGL_renderer_updateBuffer(RSGL_renderer* renderer, RSGL_bufferType type, size_t buffer, void* data, size_t start, size_t len); +RSGLDEF void RSGL_renderer_deleteBuffer(RSGL_renderer* renderer, size_t buffer); + +RSGLDEF void RSGL_renderer_createRenderBuffers(RSGL_renderer* renderer, size_t size, RSGL_renderBuffers* buffers); +RSGLDEF void RSGL_renderer_deleteRenderBuffers(RSGL_renderer* renderer, RSGL_renderBuffers* buffers); + +RSGLDEF void RSGL_renderer_render(RSGL_renderer* renderer); /* draw current batch */ +RSGLDEF void RSGL_renderer_updateRenderBuffers(RSGL_renderer* renderer); +RSGLDEF void RSGL_renderer_renderBuffers(RSGL_renderer* renderer); + +RSGLDEF void RSGL_renderer_free(RSGL_renderer* renderer); + +RSGLDEF void RSGL_renderer_setRotate(RSGL_renderer* renderer, RSGL_vec3D rotate); /* apply rotation to drawing */ +RSGLDEF void RSGL_renderer_setTexture(RSGL_renderer* renderer, RSGL_texture texture); /* apply texture to drawing */ +RSGLDEF void RSGL_renderer_setTextureSource(RSGL_renderer* renderer, RSGL_texture texture, RSGL_rect rect); /* apply texture to drawing (limited to the given rect) */ +RSGLDEF void RSGL_renderer_setColor(RSGL_renderer* renderer, RSGL_color color); /* apply color to drawing */ +RSGLDEF void RSGL_renderer_setProgram(RSGL_renderer* renderer, RSGL_programInfo* program); /* use shader program for drawing */ +RSGLDEF void RSGL_renderer_setFramebuffer(RSGL_renderer* renderer, RSGL_framebuffer framebuffer); +RSGLDEF void RSGL_renderer_setRenderBuffers(RSGL_renderer* renderer, RSGL_renderBuffers* buffers); +RSGLDEF void RSGL_renderer_setGradient(RSGL_renderer* renderer, + float* gradient, /* array of gradients */ + size_t len /* length of array */ + ); /* apply gradient to drawing, based on color list*/ +RSGLDEF void RSGL_renderer_setCenter(RSGL_renderer* renderer, RSGL_vec3D center); /* the center of the drawing (or shape), this is used for rotation */ +RSGLDEF void RSGL_renderer_setOverflow(RSGL_renderer* renderer, RSGL_bool overflow); +/* args clear after a draw function by default, this toggles that */ +RSGLDEF void RSGL_renderer_clearArgs(RSGL_renderer* renderer); /* clears the args */ + +RSGLDEF RSGL_mat4 RSGL_renderer_initDrawMatrix(RSGL_renderer* renderer, RSGL_vec3D center); + +/* renders the current batches */ +RSGLDEF void RSGL_renderer_clear(RSGL_renderer* renderer, RSGL_color color); +RSGLDEF void RSGL_renderer_viewport(RSGL_renderer* renderer, RSGL_rect rect); +/* create a texture based on a given bitmap, this must be freed later using RSGL_deleteTexture or opengl*/ +RSGLDEF RSGL_texture RSGL_renderer_createTexture(RSGL_renderer* renderer, const RSGL_textureBlob* blob); +/* updates an existing texture wiht a new bitmap */ +RSGLDEF void RSGL_renderer_copyToTexture(RSGL_renderer* renderer, RSGL_texture texture, size_t x, size_t y, const RSGL_textureBlob* blob); +/* delete a texture */ +RSGLDEF void RSGL_renderer_deleteTexture(RSGL_renderer* renderer, RSGL_texture tex); +RSGLDEF RSGL_framebuffer RSGL_renderer_createFramebuffer(RSGL_renderer* renderer, size_t width, size_t height); +RSGLDEF void RSGL_renderer_attachFramebuffer(RSGL_renderer* renderer, RSGL_framebuffer fbo, RSGL_texture tex, u8 attachType, u8 mipLevel); +RSGLDEF void RSGL_renderer_deleteFramebuffer(RSGL_renderer* renderer, RSGL_framebuffer fbo); +/* starts scissoring */ +RSGLDEF void RSGL_renderer_scissorStart(RSGL_renderer* renderer, RSGL_rect scissor, i32 height); +/* stops scissoring */ +RSGLDEF void RSGL_renderer_scissorEnd(RSGL_renderer* renderer); +/* custom shader program */ +RSGLDEF RSGL_programBlob RSGL_renderer_defaultBlob(RSGL_renderer* ctx); +RSGLDEF RSGL_programInfo RSGL_renderer_createProgram(RSGL_renderer* renderer, RSGL_programBlob* blob); +RSGLDEF void RSGL_renderer_deleteProgram(RSGL_renderer* renderer, const RSGL_programInfo* program); +RSGLDEF size_t RSGL_renderer_findShaderVariable(RSGL_renderer* renderer, const RSGL_programInfo* program, const char* var, size_t len); +RSGLDEF void RSGL_renderer_updateShaderVariable(RSGL_renderer* renderer, const RSGL_programInfo* program, size_t var, const float value[], u8 len); +RSGLDEF void RSGL_renderer_forceBatch(RSGL_renderer* renderer); + +RSGLDEF void RSGL_renderer_setPerspectiveMatrix(RSGL_renderer* renderer, RSGL_mat4 matrix); +RSGLDEF void RSGL_renderer_setDefaultPerspectiveMatrix(RSGL_renderer* renderer, RSGL_mat4 matrix); + +RSGLDEF void RSGL_renderer_setModelMatrix(RSGL_renderer* renderer, RSGL_mat4 matrix); +RSGLDEF void RSGL_renderer_resetModelMatrix(RSGL_renderer* renderer); + +RSGLDEF RSGL_programInfo RSGL_renderer_createComputeProgram(RSGL_renderer* renderer, const char *CShaderCode); +RSGLDEF void RSGL_renderer_dispatchComputeProgram(RSGL_renderer* renderer, const RSGL_programInfo* program, u32 groups_x, u32 groups_y, u32 groups_z); +RSGLDEF void RSGL_renderer_bindComputeTexture(RSGL_renderer* renderer, u32 texture, u8 format); + +/* +******* +RSGL_draw low level +******* +RSGL_drawRawVerts is a function used internally by RSGL, but you can use it yourself +RSGL_drawRawVerts batches a given set of points based on th data to be rendered +*/ + +typedef enum RSGL_drawType { + RSGL_TRIANGLES = 0, + RSGL_POINTS = 1, + RSGL_LINES = 2 +} RSGL_drawType; + +typedef struct RSGL_rawVerts { + RSGL_drawType type; + float* verts; + float* texCoords; + u16* elements; + size_t elmCount; + size_t vert_count; +} RSGL_rawVerts; + +RSGLDEF i32 RSGL_drawRawVerts(RSGL_renderer* renderer, const RSGL_rawVerts* data); + +/* + ****** + * Rfont_RSGL RFont integration * + ****** + * */ + +#ifdef RSGL_RFONT +RSGLDEF struct RFont_renderer_proc RFont_RSGL_renderer_proc(void); + +RSGLDEF struct RFont_renderer* RFont_RSGL_renderer_init(struct RSGL_renderer* ptr); +RSGLDEF void RFont_RSGL_renderer_initPtr(struct RSGL_renderer* ptr, struct RFont_renderer* renderer); +RSGLDEF void RFont_RSGL_renderer_free(struct RFont_renderer* renderer); +#endif + +#endif /* ndef RSGL_H */ + +/* +******* +RSGL high level API +******* +*/ + +#if !defined(RSGL_NO_HIGHLEVEL) && !defined(RSGL_HIGHLEVEL_H) + + +/* +******* +RSGL_draw primitives +******* +*/ + +/* 2D shape drawing */ +/* in the function names, F means float */ + +RSGLDEF i32 RSGL_drawPoint(RSGL_renderer* renderer, RSGL_vec2D p); + +RSGLDEF i32 RSGL_drawRect(RSGL_renderer* renderer, RSGL_rect r); + +RSGLDEF i32 RSGL_drawRoundRect(RSGL_renderer* renderer, RSGL_rect r, RSGL_vec2D rounding); + +RSGLDEF i32 RSGL_drawPolygon(RSGL_renderer* renderer, RSGL_rect r, u32 sides); + +RSGLDEF i32 RSGL_drawArc(RSGL_renderer* renderer, RSGL_rect o, RSGL_vec2D arc); + +RSGLDEF i32 RSGL_drawOval(RSGL_renderer* renderer, RSGL_rect o); + +RSGLDEF i32 RSGL_drawLine(RSGL_renderer* renderer, RSGL_vec2D p1, RSGL_vec2D p2, u32 thickness); + +/* 3D objects */ +RSGLDEF i32 RSGL_drawTriangle(RSGL_renderer* renderer, RSGL_vec3D[3]); +RSGLDEF i32 RSGL_drawPoint3D(RSGL_renderer* renderer, RSGL_vec3D p); +RSGLDEF i32 RSGL_drawLine3D(RSGL_renderer* renderer, RSGL_vec3D p1, RSGL_vec3D p2, u32 thickness); +RSGLDEF i32 RSGL_drawCube(RSGL_renderer* renderer, RSGL_cube cube); + +/* 2D outlines */ + +/* thickness means the thickness of the line */ +RSGLDEF i32 RSGL_drawTriangleOutline(RSGL_renderer* renderer, RSGL_vec3D triangle[3], u32 thickness); + +RSGLDEF i32 RSGL_drawRectOutline(RSGL_renderer* renderer, RSGL_rect r, u32 thickness); +RSGLDEF i32 RSGL_drawRectOutline(RSGL_renderer* renderer, RSGL_rect r, u32 thickness); + +RSGLDEF i32 RSGL_drawRoundRectOutline(RSGL_renderer* renderer, RSGL_rect r, RSGL_vec2D rounding, u32 thickness); +RSGLDEF i32 RSGL_drawRoundRectOutline(RSGL_renderer* renderer, RSGL_rect r, RSGL_vec2D rounding, u32 thickness); + +RSGLDEF i32 RSGL_drawPolygonOutline(RSGL_renderer* renderer, RSGL_rect r, u32 sides, u32 thickness); +RSGLDEF i32 RSGL_drawPolygonOutline(RSGL_renderer* renderer, RSGL_rect r, u32 sides, u32 thickness); + +RSGLDEF i32 RSGL_drawArcOutline(RSGL_renderer* renderer, RSGL_rect o, RSGL_vec2D arc, u32 thickness); +RSGLDEF i32 RSGL_drawArcOutline(RSGL_renderer* renderer, RSGL_rect o, RSGL_vec2D arc, u32 thickness); + +RSGLDEF i32 RSGL_drawOvalOutline(RSGL_renderer* renderer, RSGL_rect o, u32 thickness); + +/* +******* +RSGL_view +******* +*/ + +typedef enum RSGL_viewType { + RSGL_viewTypeNone = 0, + RSGL_viewType2D, + RSGL_viewType3D, +} RSGL_viewType; + +typedef struct RSGL_view2D { + RSGL_viewType type; + RSGL_vec3D offset; + RSGL_vec3D target; + float rotation; + float zoom; +} RSGL_view2D; + +/* RSGL translation */ +typedef struct RSGL_view3D { + RSGL_viewType type; + RSGL_vec3D pos; + RSGL_vec3D target; + RSGL_vec3D up; +} RSGL_view3D; + +typedef union RSGL_view { + RSGL_viewType type; + RSGL_view2D view2D; + RSGL_view3D view3D; +} RSGL_view; + +RSGLDEF RSGL_mat4 RSGL_view_getMatrix(const RSGL_view* view); + +#endif /* ndef RSGL_HIGHLEVEL_H && ndef RSGL_NO_HIGHLEVEL */ + +#ifdef RSGL_IMPLEMENTATION + +#ifndef M_PI + #define M_PI 3.14159265358979323846f +#endif +#ifndef DEG2RAD + #define DEG2RAD (float)(M_PI / 180.0f) +#endif +#ifndef RAD2DEG + #define RAD2DEG (float)(180.0f / M_PI) +#endif + +#define RSGL_GET_MATRIX_X(x, y, z) (float)(matrix.m[0] * x + matrix.m[4] * y + matrix.m[8] * z + matrix.m[12]) +#define RSGL_GET_MATRIX_Y(x, y, z) (float)(matrix.m[1] * x + matrix.m[5] * y + matrix.m[9] * z + matrix.m[13]) +#define RSGL_GET_MATRIX_Z(x, y, z) (float)(matrix.m[2] * x + matrix.m[6] * y + matrix.m[10] * z + matrix.m[14]) +#define RSGL_GET_MATRIX_W(x, y, z) (float)(matrix.m[2] * x + matrix.m[7] * y + matrix.m[11] * z + matrix.m[15]) + +#define RSGL_GET_MATRIX_POINT(x, y, z) \ + RSGL_GET_MATRIX_X((x), (y), (z)) / RSGL_GET_MATRIX_W((x), (y), (z)), \ + RSGL_GET_MATRIX_Y((x), (y), (z)) / RSGL_GET_MATRIX_W((x), (y), (z)), \ + RSGL_GET_MATRIX_Z((x), (y), (z)) / RSGL_GET_MATRIX_W((x), (y), (z)) + +#define RSGL_GET_MATRIX_POINTW(x, y, z) \ + RSGL_GET_MATRIX_X(x, y, z), \ + RSGL_GET_MATRIX_Y(x, y, z), \ + RSGL_GET_MATRIX_Z(x, y, z), \ + RSGL_GET_MATRIX_W(x, y, z) \ + +void RSGL_renderer_forceBatch(RSGL_renderer* renderer) { + renderer->state.forceBatch = RSGL_TRUE; +} + +void RSGL_renderer_setPerspectiveMatrix(RSGL_renderer* renderer, RSGL_mat4 matrix) { + renderer->state.perspectiveMatrix = matrix; +} + +void RSGL_renderer_setDefaultPerspectiveMatrix(RSGL_renderer* renderer, RSGL_mat4 matrix) { + renderer->defaultPerspectiveMatrix = matrix; +} + +void RSGL_renderer_setViewMatrix(RSGL_renderer* renderer, RSGL_mat4 matrix) { + renderer->state.viewMatrix = matrix; +} +void RSGL_renderer_resetViewMatrix(RSGL_renderer* renderer) { + RSGL_renderer_setViewMatrix(renderer, RSGL_mat4_loadIdentity()); +} + +void RSGL_renderer_setModelMatrix(RSGL_renderer* renderer, RSGL_mat4 matrix) { + renderer->state.modelMatrix = matrix; + renderer->state.forceBatch = RSGL_TRUE; +} + + +void RSGL_renderer_resetModelMatrix(RSGL_renderer* renderer) { + RSGL_renderer_setModelMatrix(renderer, RSGL_mat4_loadIdentity()); +} + +void RSGL_renderer_getRenderState(RSGL_renderer* renderer, RSGL_renderState* state) { + if (state) *state = renderer->state; +} + +void RSGL_renderer_setOverflow(RSGL_renderer* renderer, RSGL_bool overflow) { + renderer->state.overflow = overflow; +} +#include <stdio.h> +i32 RSGL_drawRawVerts(RSGL_renderer* renderer, const RSGL_rawVerts* data) { + if ((renderer->state.buffers->batchCount + 1 >= RSGL_MAX_BATCHES || renderer->data.len + data->vert_count >= renderer->state.buffers->maxVerts) && renderer->state.overflow) { + RSGL_renderer_render(renderer); + } + + RSGL_BATCH* batch = NULL; + RSGL_color c = renderer->state.color; + + if ( + renderer->state.buffers->batchCount == 0 || + renderer->state.buffers->batches[renderer->state.buffers->batchCount - 1].tex != renderer->state.texture || + renderer->state.buffers->batches[renderer->state.buffers->batchCount - 1].lineWidth != renderer->state.lineWidth || + renderer->state.buffers->batches[renderer->state.buffers->batchCount - 1].type != data->type || + renderer->state.forceBatch + ) { + renderer->state.forceBatch = RSGL_FALSE; + renderer->state.buffers->batchCount += 1; + + batch = &renderer->state.buffers->batches[renderer->state.buffers->batchCount - 1]; + batch->start = renderer->data.len; + batch->len = 0; + batch->elmStart = renderer->data.elements_count; + batch->elmCount = 0; + batch->type = data->type; + batch->tex = renderer->state.texture; + batch->lineWidth = renderer->state.lineWidth; + batch->matrix = renderer->state.modelMatrix; + } else { + batch = &renderer->state.buffers->batches[renderer->state.buffers->batchCount - 1]; + } + + if (batch == NULL) { + return -1; + } + + batch->elmCount += data->elmCount; + batch->len += data->vert_count; + + RSGL_MEMCPY(&renderer->data.verts[renderer->data.len * 3], data->verts, data->vert_count * sizeof(float) * 3); + RSGL_MEMCPY(&renderer->data.texCoords[renderer->data.len * 2], data->texCoords, data->vert_count * sizeof(float) * 2); + + size_t i; + for (i = 0; i < data->elmCount; i++) { + size_t index = renderer->data.elements_count + i; + u16 elm = data->elements[i] + (u16)renderer->data.len; + renderer->data.elements[index] = elm; + } + + renderer->data.elements_count += data->elmCount; + + float color[4] = {c.r / 255.0f, c.g / 255.0f, c.b / 255.0f, c.a / 255.0f}; + + if (renderer->state.gradient_len && renderer->state.gradient && (i64)(data->vert_count - 1) > 0) { + RSGL_MEMCPY(&renderer->data.colors[renderer->data.len * 4], color, sizeof(float) * 4); + RSGL_MEMCPY(&renderer->data.colors[renderer->data.len * 4 + 4], renderer->state.gradient, (data->vert_count - 1) * sizeof(float) * 4); + } + else { + size_t i; + for (i = 0; i < data->vert_count * 4; i += 4) + RSGL_MEMCPY(&renderer->data.colors[(renderer->data.len * 4) + i], color, sizeof(float) * 4); + } + + renderer->data.len += data->vert_count; + return renderer->state.buffers->batchCount - 1; +} + +/* +********************* +RSGL_GRAPHICS_CONTEXT +********************* +*/ + +void RSGL_renderer_setSurface(RSGL_renderer* renderer, void* surface) { + renderer->proc.setSurface(renderer->ctx, surface); +} + +void RSGL_renderer_createBuffer(RSGL_renderer* renderer, RSGL_bufferType type, size_t size, const void* data, size_t* buffer) { + if (renderer->proc.createBuffer) { + renderer->proc.createBuffer(renderer->ctx, type, size, data, buffer); + } +} + +void RSGL_renderer_deleteRenderBuffers(RSGL_renderer* renderer, RSGL_renderBuffers* buffers) { + RSGL_renderer_deleteBuffer(renderer, buffers->elements); + RSGL_renderer_deleteBuffer(renderer, buffers->vertex); + RSGL_renderer_deleteBuffer(renderer, buffers->color); + RSGL_renderer_deleteBuffer(renderer, buffers->texture); +} + +void RSGL_renderer_createRenderBuffers(RSGL_renderer* renderer, size_t size, RSGL_renderBuffers* buffers) { + buffers->maxVerts = size; + renderer->proc.createBuffer(renderer->ctx, RSGL_arrayBuffer, size * 3 * sizeof(float), NULL, &buffers->vertex); + renderer->proc.createBuffer(renderer->ctx, RSGL_arrayBuffer, size * 4 * sizeof(float), NULL, &buffers->color); + renderer->proc.createBuffer(renderer->ctx, RSGL_arrayBuffer, size * 2 * sizeof(float), NULL, &buffers->texture); + renderer->proc.createBuffer(renderer->ctx, RSGL_elementArrayBuffer, size * 6 * sizeof(u16), NULL, &buffers->elements); +} + +void RSGL_renderer_updateBuffer(RSGL_renderer* renderer, RSGL_bufferType type, size_t buffer, void* data, size_t start, size_t len) { + if (renderer->proc.updateBuffer) + renderer->proc.updateBuffer(renderer->ctx, type, buffer, data, start, len); +} + +void RSGL_renderer_deleteBuffer(RSGL_renderer* renderer, size_t buffer) { + if (renderer->proc.deleteBuffer) + renderer->proc.deleteBuffer(renderer->ctx, buffer); +} + +void RSGL_renderer_updateRenderBuffers(RSGL_renderer* renderer) { + RSGL_renderer_updateBuffer(renderer, RSGL_arrayBuffer, renderer->state.buffers->vertex, renderer->data.verts, 0, renderer->data.len * 3 * sizeof(float)); + RSGL_renderer_updateBuffer(renderer, RSGL_arrayBuffer, renderer->state.buffers->color, renderer->data.colors, 0, renderer->data.len * 4 * sizeof(float)); + RSGL_renderer_updateBuffer(renderer, RSGL_arrayBuffer, renderer->state.buffers->texture, renderer->data.texCoords, 0, renderer->data.len * 2 * sizeof(float)); + RSGL_renderer_updateBuffer(renderer, RSGL_elementArrayBuffer, renderer->state.buffers->elements, renderer->data.elements, 0, renderer->data.elements_count * sizeof(u16)); +} + +void RSGL_renderer_renderBuffers(RSGL_renderer* renderer) { + RSGL_mat4 matrix = RSGL_mat4_multiply(renderer->defaultPerspectiveMatrix.m, renderer->state.perspectiveMatrix.m); + matrix = RSGL_mat4_multiply(matrix.m, renderer->state.viewMatrix.m); + + + RSGL_renderPass pass; + pass.program = renderer->state.program; + pass.matrix = matrix.m; + pass.buffers = renderer->state.buffers; + pass.framebuffer = renderer->state.framebuffer; + + if (renderer->proc.render) + renderer->proc.render(renderer->ctx, &pass); + + renderer->data.len = 0; + renderer->data.elements_count = 0; +} + +void RSGL_renderer_render(RSGL_renderer* renderer) { + if (renderer->data.len && renderer->state.buffers->batchCount) { + RSGL_renderer_updateRenderBuffers(renderer); + } + + RSGL_renderer_renderBuffers(renderer); + + renderer->state.buffers->batchCount = 0; +} + +size_t RSGL_renderer_size(RSGL_renderer* renderer) { + if (renderer->proc.size) return renderer->proc.size(); + return 0; +} + +void RSGL_renderer_initPtr(RSGL_rendererProc proc, void* loader, void* data, RSGL_renderer* renderer) { + renderer->ctx = data; + renderer->proc = proc; + RSGL_renderer_clearArgs(renderer); + renderer->state.color = RSGL_RGBA(0, 0, 0, 255); + + renderer->state.modelMatrix = RSGL_mat4_loadIdentity(); + renderer->data.verts = renderer->verts; + renderer->data.texCoords = renderer->texCoords; + renderer->data.elements = renderer->elements; + renderer->data.colors = renderer->colors; + renderer->data.len = 0; + renderer->data.elements_count = 0; + + if (renderer->proc.initPtr) + renderer->proc.initPtr(renderer->ctx, loader); + + RSGL_renderer_setFramebuffer(renderer, 0); + + RSGL_programBlob pBlob = RSGL_renderer_defaultBlob(renderer); + renderer->defaultProgram = RSGL_renderer_createProgram(renderer, &pBlob); + RSGL_renderer_setProgram(renderer, &renderer->defaultProgram); + + u8 white[4] = {255, 255, 255, 255}; + RSGL_textureBlob blob; + blob.data = white; + blob.width = 1; + blob.height = 1; + blob.dataType = RSGL_textureDataInt; + blob.dataFormat = RSGL_formatRGBA; + blob.textureFormat = RSGL_formatRGBA; + renderer->defaultTexture = RSGL_renderer_createTexture(renderer, &blob); + + RSGL_renderer_setTexture(renderer, renderer->defaultTexture); + + RSGL_renderer_createRenderBuffers(renderer, RSGL_MAX_VERTS, &renderer->buffers); + renderer->buffers.batchCount = 0; + renderer->state.buffers = &renderer->buffers; + + RSGL_renderer_setModelMatrix(renderer, RSGL_mat4_loadIdentity()); + RSGL_renderer_resetViewMatrix(renderer); + RSGL_renderer_setPerspectiveMatrix(renderer, RSGL_mat4_loadIdentity()); +} + + +RSGL_renderer* RSGL_renderer_init(RSGL_rendererProc proc, void* loader) { + RSGL_renderer* renderer = (RSGL_renderer*)RSGL_MALLOC(sizeof(RSGL_renderer)); + void* data = RSGL_MALLOC(proc.size()); + RSGL_renderer_initPtr(proc, loader, data, renderer); + return renderer; +} + +void RSGL_renderer_freePtr(RSGL_renderer* renderer) { + RSGL_renderer_deleteRenderBuffers(renderer, &renderer->buffers); + + if (renderer->proc.freePtr) + renderer->proc.freePtr(renderer->ctx); + + renderer->state.buffers->batchCount = 0; + renderer->data.len = 0; + renderer->data.elements_count = 0; +} + +void RSGL_renderer_free(RSGL_renderer* renderer) { + RSGL_renderer_freePtr(renderer); + if (renderer->ctx) + RSGL_FREE(renderer->ctx); + RSGL_FREE(renderer); +} + +void RSGL_renderer_clear(RSGL_renderer* renderer, RSGL_color color) { + if (renderer->proc.clear) + renderer->proc.clear(renderer->ctx, renderer->state.framebuffer, ((float)color.r) / 255.0f, ((float)color.g) / 255.0f, ((float)color.b) / 255.0f, ((float)color.a) / 255.0f); +} +void RSGL_renderer_viewport(RSGL_renderer* renderer, RSGL_rect rect) { renderer->proc.viewport(renderer->ctx, rect.x, rect.y, rect.w, rect.h); } +RSGL_texture RSGL_renderer_createTexture(RSGL_renderer* renderer, const RSGL_textureBlob* blob) { + RSGL_texture tex = 0; + if (renderer->proc.createTexture) tex = renderer->proc.createTexture(renderer->ctx, blob); + return tex; +} +void RSGL_renderer_copyToTexture(RSGL_renderer* renderer, RSGL_texture texture, size_t x, size_t y, const RSGL_textureBlob* blob) { + return renderer->proc.copyToTexture(renderer->ctx, texture, x, y, blob); +} +void RSGL_renderer_deleteTexture(RSGL_renderer* renderer, RSGL_texture tex) { renderer->proc.deleteTexture(renderer->ctx, tex); } +void RSGL_renderer_scissorStart(RSGL_renderer* renderer, RSGL_rect scissor, i32 height) { + renderer->proc.scissorStart(renderer->ctx, scissor.x, scissor.y, scissor.w, scissor.h, height); +} + +RSGL_framebuffer RSGL_renderer_createFramebuffer(RSGL_renderer* renderer, size_t width, size_t height) { + RSGL_framebuffer framebuffer = 0; + if (renderer->proc.createFramebuffer) { + framebuffer = renderer->proc.createFramebuffer(renderer->ctx, width, height); + } + return framebuffer; +} + +void RSGL_renderer_attachFramebuffer(RSGL_renderer* renderer, RSGL_framebuffer fbo, RSGL_texture tex, u8 attachType, u8 mipLevel) { + if (renderer->proc.attachFramebuffer) + renderer->proc.attachFramebuffer(renderer->ctx, fbo, tex, attachType, mipLevel); +} + +void RSGL_renderer_deleteFramebuffer(RSGL_renderer* renderer, RSGL_framebuffer fbo) { + if (renderer->proc.deleteFramebuffer) + renderer->proc.deleteFramebuffer(renderer->ctx, fbo); +} + +void RSGL_renderer_scissorEnd(RSGL_renderer* renderer) { + renderer->proc.scissorEnd(renderer->ctx); +} +RSGL_programBlob RSGL_renderer_defaultBlob(RSGL_renderer* renderer) { + RSGL_programBlob blob; + RSGL_MEMSET(&blob, 0, sizeof(blob)); + + if (renderer->proc.defaultBlob) { + blob = renderer->proc.defaultBlob(renderer); + } + + return blob; +} +RSGL_programInfo RSGL_renderer_createProgram(RSGL_renderer* renderer, RSGL_programBlob* blob) { + RSGL_programInfo info; + RSGL_MEMSET(&info, 0, sizeof(info)); + + if (blob->fragment == NULL || blob->vertex == NULL) { + RSGL_programBlob pBlob = RSGL_renderer_defaultBlob(renderer); + renderer->defaultProgram = RSGL_renderer_createProgram(renderer, &pBlob); + + if (blob->vertex == NULL) { + blob->vertex = pBlob.vertex; + blob->vertexLen = pBlob.vertexLen; + } + + if (blob->fragment == NULL) { + blob->fragment = pBlob.fragment; + blob->fragmentLen = pBlob.fragmentLen; + } + } + + if (renderer->proc.createProgram) { + info = renderer->proc.createProgram(renderer->ctx, blob); + } + + return info; +} +void RSGL_renderer_deleteProgram(RSGL_renderer* renderer, const RSGL_programInfo* program) { return renderer->proc.deleteProgram(renderer->ctx, program); } + +size_t RSGL_renderer_findShaderVariable(RSGL_renderer* renderer, const RSGL_programInfo* program, const char* var, size_t len) { + return renderer->proc.findShaderVariable(renderer->ctx, program, var, len); +} + +void RSGL_renderer_updateShaderVariable(RSGL_renderer* renderer, const RSGL_programInfo* program, size_t var, const float value[], u8 len) { + if (renderer->proc.updateShaderVariable) { + renderer->proc.updateShaderVariable(renderer->ctx, program, var, value, len); + } +} + +RSGL_programInfo RSGL_renderer_createComputeProgram(RSGL_renderer* renderer, const char* CShaderCode) { + return renderer->proc.createComputeProgram(renderer->ctx, CShaderCode); +} + +void RSGL_renderer_dispatchComputeProgram(RSGL_renderer* renderer, const RSGL_programInfo* program, u32 groups_x, u32 groups_y, u32 groups_z) { + renderer->proc.dispatchComputeProgram(renderer->ctx, program, groups_x, groups_y, groups_z); +} + +void RSGL_renderer_bindComputeTexture(RSGL_renderer* renderer, u32 texture, u8 format) { + renderer->proc.bindComputeTexture(renderer->ctx, texture, format); +} + +void RSGL_renderer_updateSize(RSGL_renderer* renderer, size_t width, size_t height) { + RSGL_projection projection; + projection.p2D.type = RSGL_projectionOrtho2D; + projection.p2D.width = width; + projection.p2D.height = height; + + RSGL_mat4 matrix = RSGL_projection_getMatrix(&projection); + RSGL_renderer_setDefaultPerspectiveMatrix(renderer, matrix); +} + +void RSGL_renderer_setRotate(RSGL_renderer* renderer, RSGL_vec3D rotate){ + renderer->state.rotate = RSGL_VEC3D(rotate.x * DEG2RAD, rotate.y * DEG2RAD, rotate.z * DEG2RAD); +} +void RSGL_renderer_setTexture(RSGL_renderer* renderer, RSGL_texture texture) { + if (texture == 0) + renderer->state.texture = renderer->defaultTexture; + else + renderer->state.texture = texture; + + renderer->state.source = RSGL_RECT(0, 0, 1, 1); +} + +void RSGL_renderer_setTextureSource(RSGL_renderer* renderer, RSGL_texture texture, RSGL_rect rect) { + RSGL_renderer_setTexture(renderer, texture); + renderer->state.source = rect; +} + +void RSGL_renderer_setColor(RSGL_renderer* renderer, RSGL_color color) { + renderer->state.color = color; +} + +void RSGL_renderer_setRenderBuffers(RSGL_renderer* renderer, RSGL_renderBuffers* buffers) { + if (buffers == NULL) + renderer->state.buffers = &renderer->buffers; + else + renderer->state.buffers = buffers; +} + +void RSGL_renderer_setProgram(RSGL_renderer* renderer, RSGL_programInfo* program) { + if (program == NULL) + renderer->state.program = &renderer->defaultProgram; + else + renderer->state.program = program; +} + +void RSGL_renderer_setFramebuffer(RSGL_renderer* renderer, RSGL_framebuffer framebuffer) { + renderer->state.framebuffer = framebuffer; +} + +void RSGL_renderer_setGradient(RSGL_renderer* renderer, float gradient[], size_t len) { + renderer->state.gradient_len = len; + renderer->state.gradient = gradient; +} +void RSGL_renderer_setCenter(RSGL_renderer* renderer, RSGL_vec3D center) { + renderer->state.center = center; +} + +RSGL_mat4 RSGL_renderer_initDrawMatrix(RSGL_renderer* renderer, RSGL_vec3D center) { + RSGL_mat4 matrix = RSGL_mat4_loadIdentity(); + + if (renderer->state.rotate.x || renderer->state.rotate.y || renderer->state.rotate.z) { + if (renderer->state.center.x != -1 && renderer->state.center.y != -1 && renderer->state.center.z != -1) + center = renderer->state.center; + + matrix = RSGL_mat4_translate(matrix.m, center.x, center.y, center.z); + matrix = RSGL_mat4_rotate(matrix.m, renderer->state.rotate.z, 0, 0, 1); + matrix = RSGL_mat4_rotate(matrix.m, renderer->state.rotate.y, 0, 1, 0); + matrix = RSGL_mat4_rotate(matrix.m, renderer->state.rotate.x, 1, 0, 0); + matrix = RSGL_mat4_translate(matrix.m, -center.x, -center.y, -center.z); + } + + return matrix; +} + +void RSGL_renderer_clearArgs(RSGL_renderer* renderer) { + RSGL_MEMSET(&renderer->state, 0, sizeof(renderer->state)); + renderer->state.center = RSGL_VEC3D(-1, -1, -1); + renderer->state.overflow = RSGL_TRUE; +} + +/* +**** +RFont_RSGL integration +**** +*/ + +#ifdef RSGL_RFONT + +#ifndef RFONT_H + +#ifdef RSGL_INT_DEFINED + #ifndef RFONT_INT_DEFINED + #define RFONT_INT_DEFINED + #endif +#endif + +#include "RFont.h" +#endif + +struct RFont_renderer* RFont_RSGL_renderer_init(struct RSGL_renderer* ptr) { + RFont_renderer* renderer = (RFont_renderer*)RFONT_MALLOC(sizeof(RFont_renderer)); + RFont_renderer_initPtr(RFont_RSGL_renderer_proc(), ptr, renderer); + return renderer; +} +void RFont_RSGL_renderer_initPtr(struct RSGL_renderer* ptr, struct RFont_renderer* renderer) { RFont_renderer_initPtr(RFont_RSGL_renderer_proc(), ptr, renderer); } + +void RFont_RSGL_renderer_free(struct RFont_renderer* renderer) { + RFONT_FREE(renderer); +} + +void RFont_RSGL_render_text(RSGL_renderer* renderer, const RFont_render_data* src) { + RSGL_texture save = renderer->state.texture; + RSGL_renderer_setTexture(renderer, src->atlas); + + RSGL_rawVerts data; + data.type = RSGL_TRIANGLES; + data.verts = src->verts; + data.texCoords = src->tcoords; + data.elements = src->elements; + data.elmCount = src->nelements; + data.vert_count = src->nverts; + i32 batch = RSGL_drawRawVerts(renderer, &data); + RSGL_UNUSED(batch); + + RSGL_renderer_setTexture(renderer, save); +} + +RFont_texture RFont_RSGL_createAtlas(RSGL_renderer* renderer, u32 atlasWidth, u32 atlasHeight) { + RSGL_textureBlob blob; + blob.data = NULL; + blob.width = atlasWidth; + blob.height = atlasWidth; + blob.dataType = RSGL_textureDataInt; + blob.dataFormat = RSGL_formatRGBA; //RSGL_formatRGBA; + blob.textureFormat = RSGL_formatRGBA;//RSGL_formatRGBA; + RFont_texture id = RSGL_renderer_createTexture(renderer, &blob); + return id; +} + +void RFont_RSGL_deleteAtlas(RSGL_renderer* renderer, RFont_texture atlas) { + RSGL_renderer_deleteTexture(renderer, atlas); +} + +void RFont_RSGL_bitmapToAtlas(RSGL_renderer* renderer, RFont_texture atlas, u32 atlasWidth, u32 atlasHeight, u32 maxHeight, u8* bitmap, float w, float h, float* x, float* y) { + RSGL_UNUSED(atlasHeight); + if (((*x) + w) >= atlasWidth) { + *x = 0; + *y += (float)maxHeight; + } + + RSGL_textureBlob blob; + blob.width = w; + blob.height = h; + blob.dataType = RSGL_textureDataInt; + blob.dataFormat = RSGL_formatRGBA; + blob.textureFormat = blob.dataFormat; + + u8* newBitmap = (u8*)RSGL_MALLOC(w * h * 4); + + for (size_t indexY = 0; indexY < (size_t)h; indexY++) { + for (size_t indexX = 0; indexX < (size_t)w; indexX++) { + size_t index = ((indexY * (size_t)w * 4) + indexX * 4); + size_t oIndex = ((indexY * (size_t)w) + indexX); + + u8 value = bitmap[oIndex]; + + newBitmap[index + 0] = value; + newBitmap[index + 1] = value; + newBitmap[index + 2] = value; + newBitmap[index + 3] = value; + } + } + + blob.data = newBitmap; + + RSGL_renderer_copyToTexture(renderer, atlas, (size_t)(*x), (size_t)(*y), &blob); + + RSGL_FREE(newBitmap); + + *x += w; +} + +void RFont_RSGL_setFrameBuffer(RSGL_renderer* renderer, u32 width, u32 height) { + RSGL_renderer_updateSize(renderer, width, height); +} + +void RFont_RSGL_setColor(RSGL_renderer* renderer, float r, float g, float b, float a) { + RSGL_renderer_setColor(renderer, RSGL_RGBA(r * 255.0f, g * 255.0f, b * 255.0f, a * 255.0f)); +} + +RFont_renderer_proc RFont_RSGL_renderer_proc(void) { + RFont_renderer_proc proc; + RSGL_MEMSET(&proc, 0, sizeof(proc)); + proc.create_atlas = (RFont_texture (*)(void* ctx, u32 atlasWidth, u32 atlasHeight))RFont_RSGL_createAtlas; + proc.free_atlas = (void (*)(void*, RSGL_texture))RFont_RSGL_deleteAtlas; + proc.bitmap_to_atlas = (void(*)(void*, RFont_texture, u32, u32, u32, u8*, float, float, float*, float*))RFont_RSGL_bitmapToAtlas; + proc.render = (void (*)(void*, const RFont_render_data* data))RFont_RSGL_render_text; + proc.set_framebuffer = (void (*)(void*, u32, u32))RFont_RSGL_setFrameBuffer; + proc.set_color = (void (*)(void*, float, float, float, float))RFont_RSGL_setColor; + return proc; +} + +#endif + +#if !defined(RSGL_NO_HIGHLEVEL) + +/* +**** +RSGL_draw +**** +*/ + +i32 RSGL_drawPoint(RSGL_renderer* renderer, RSGL_vec2D p) { + RSGL_mat4 matrix = RSGL_renderer_initDrawMatrix(renderer, RSGL_VEC3D(p.x, p.y, 0.0f)); + + float points[] = {RSGL_GET_MATRIX_POINT((float)p.x, (float)p.y, 0.0f)}; + float texPoints[] = { renderer->state.source.x, renderer->state.source.y }; + u16 elements[] = { 0 }; + + RSGL_rawVerts data; + data.type = RSGL_POINTS; + data.verts = points; + data.texCoords = texPoints; + data.elements = elements; + data.elmCount = 1; + data.vert_count = 1; + + return RSGL_drawRawVerts(renderer, &data); +} + +i32 RSGL_drawRect(RSGL_renderer* renderer, RSGL_rect r) { + float texPoints[] = { + renderer->state.source.x, renderer->state.source.y, + renderer->state.source.x, renderer->state.source.y + renderer->state.source.h, + renderer->state.source.x + renderer->state.source.w, renderer->state.source.y, + renderer->state.source.x + renderer->state.source.w, renderer->state.source.y + renderer->state.source.h, + }; + + RSGL_vec3D center = (RSGL_vec3D){r.x + (r.w / 2.0f), r.y + (r.h / 2.0f), 0.0f}; + RSGL_mat4 matrix = RSGL_renderer_initDrawMatrix(renderer, center); + + float points[] = { + RSGL_GET_MATRIX_POINT(r.x, r.y, 0.0f), + RSGL_GET_MATRIX_POINT(r.x, r.y + r.h, 0.0f), + RSGL_GET_MATRIX_POINT(r.x + r.w, r.y, 0.0f), + RSGL_GET_MATRIX_POINT(r.x + r.w, r.y + r.h, 0.0f), + }; + + u16 elements[] = { + 0, 1, 2, + 3, 2, 1 + }; + + RSGL_rawVerts data; + data.type = RSGL_TRIANGLES; + data.verts = points; + data.texCoords = texPoints; + data.elements = elements; + data.elmCount = 6; + data.vert_count = 4; + + return RSGL_drawRawVerts(renderer, &data); +} + +i32 RSGL_drawRoundRect(RSGL_renderer* renderer, RSGL_rect r, RSGL_vec2D rounding) { + RSGL_drawRect(renderer, RSGL_RECT(r.x + (rounding.x / 2), r.y, r.w - rounding.x, r.h)); + RSGL_drawRect(renderer, RSGL_RECT(r.x, r.y + (rounding.y / 2), r.w, r.h - rounding.y)); + + RSGL_drawArc(renderer, RSGL_RECT(r.x, r.y, rounding.x, rounding.y), (RSGL_vec2D){180, 270}); + RSGL_drawArc(renderer, RSGL_RECT(r.x + (r.w - rounding.x), r.y, rounding.x, rounding.y), (RSGL_vec2D){90, 180}); + RSGL_drawArc(renderer, RSGL_RECT(r.x + (r.w - rounding.x), r.y + (r.h - rounding.y), rounding.x, rounding.y), (RSGL_vec2D){0, 90}); + return RSGL_drawArc(renderer, RSGL_RECT(r.x, r.y + (r.h - rounding.y), rounding.x, rounding.y), (RSGL_vec2D){270, 360}); +} + +i32 RSGL_drawPolygonOutlineEx(RSGL_renderer* renderer, RSGL_rect o, u32 sides, RSGL_vec2D arc); + +i32 RSGL_drawPolygonEx(RSGL_renderer* renderer, RSGL_rect o, u32 sides, RSGL_vec2D arc) { + static float verts[360 * 3]; + static float texcoords[360 * 2]; + static u16 elements[360 * 6]; + + RSGL_vec3D center = (RSGL_vec3D){o.x + (o.w / 2.0f), o.y + (o.h / 2.0f), 0}; + + o = (RSGL_rect){o.x, o.y, o.w / 2, o.h / 2}; + RSGL_mat4 matrix = RSGL_renderer_initDrawMatrix(renderer, center); + + float displacement = 360.0f / (float)sides; + float angle = displacement * arc.x; + + size_t vIndex = 0; + size_t tIndex = 0; + size_t iIndex = 0; + + float texCenterX = (0.5 * (renderer->state.source.w)); + float texCenterY = (0.5 * (renderer->state.source.h)); + + RSGL_UNUSED(texCenterX); + RSGL_UNUSED(texCenterY); + + { + RSGL_vec2D p = {center.x, center.y}; + + texcoords[tIndex] = (renderer->state.source.x) + texCenterX; + texcoords[tIndex + 1] = (renderer->state.source.y) + texCenterY; + float temp[3] = { RSGL_GET_MATRIX_POINT(p.x, p.y, 0.0) }; + memcpy(verts + vIndex, temp, 3 * sizeof(float)); + + angle += displacement; + tIndex += 2; + vIndex += 3; + } + + u32 i; + for (i = 0; i < sides + 1; i++) { + RSGL_vec2D p = {RSGL_COS(angle * DEG2RAD), RSGL_SIN(angle * DEG2RAD)}; + + texcoords[tIndex] = ((p.x + 1.0f) * texCenterX) + (renderer->state.source.x) ; + texcoords[tIndex + 1] = ((p.y + 1.0f) * texCenterY) + (renderer->state.source.y); + + float temp[3] = { RSGL_GET_MATRIX_POINT(o.x + o.w + (p.x * o.w), o.y + o.h + (p.y * o.h), 0.0) }; + memcpy(&verts[vIndex], temp, 3 * sizeof(float)); + + elements[iIndex + 0] = i; + + if (i < sides) + elements[iIndex + 1] = i + 1; + else + elements[iIndex + 1] = 1; + + elements[iIndex + 2] = 0; + + angle += displacement; + tIndex += 2; + vIndex += 3; + iIndex += 3; + } + + RSGL_rawVerts data; + data.type = RSGL_TRIANGLES; + data.verts = verts; + data.texCoords = texcoords; + data.elements = elements; + data.elmCount = iIndex; + data.vert_count = (vIndex / 3); + + i32 out = RSGL_drawRawVerts(renderer, &data); + return out; +} + +i32 RSGL_drawPolygon(RSGL_renderer* renderer, RSGL_rect o, u32 sides) { return RSGL_drawPolygonEx(renderer, o, sides, (RSGL_vec2D){0, (float)sides}); } + + +i32 RSGL_drawArc(RSGL_renderer* renderer, RSGL_rect o, RSGL_vec2D arc) { + u32 verts = (u32)((float)((2 * M_PI * ((o.w + o.h) / 2.0f)) / 10) + 0.5); + verts %= 360; + + return RSGL_drawPolygonEx(renderer, o, verts, arc); +} + +i32 RSGL_drawOval(RSGL_renderer* renderer, RSGL_rect o) { + float verts = ((2 * M_PI * ((o.w + o.h) / 2.0f)) / 10); + verts = (verts > 360 ? 360 : verts); + + return RSGL_drawPolygonEx(renderer, o, verts, (RSGL_vec2D){0, verts}); +} + +/* + 3D +*/ + +i32 RSGL_drawPoint3D(RSGL_renderer* renderer, RSGL_vec3D p) { + RSGL_mat4 matrix = RSGL_renderer_initDrawMatrix(renderer, p); + + float points[] = {RSGL_GET_MATRIX_POINT((float)p.x, (float)p.y, (float)p.z)}; + float texPoints[] = { renderer->state.source.x, renderer->state.source.y }; + u16 elements[] = { 0, }; + + RSGL_rawVerts data; + data.type = RSGL_POINTS; + data.verts = points; + data.texCoords = texPoints; + data.elements = elements; + data.elmCount = 1; + data.vert_count = 1; + + return RSGL_drawRawVerts(renderer, &data); +} + +i32 RSGL_drawLine3D(RSGL_renderer* renderer, RSGL_vec3D p1, RSGL_vec3D p2, u32 thickness) { + renderer->state.lineWidth = thickness; + + RSGL_vec3D center = {(p1.x + p2.x) / 2.0f, (p1.y + p2.y) / 2.0f, (p1.z + p2.z) / 2.0f}; + RSGL_mat4 matrix = RSGL_renderer_initDrawMatrix(renderer, center); + + float points[] = {RSGL_GET_MATRIX_POINT(p1.x, p1.y, p1.z), RSGL_GET_MATRIX_POINT(p2.x, p2.y, p2.z)}; + float texPoints[] = { renderer->state.source.x, renderer->state.source.y, renderer->state.source.x + renderer->state.source.w, renderer->state.source.y + renderer->state.source.h}; + u16 elements[] = { 0, 1 }; + + RSGL_rawVerts data; + data.type = RSGL_LINES; + data.verts = points; + data.texCoords = texPoints; + data.elements = elements; + data.elmCount = 4; + data.vert_count = 2; + + return RSGL_drawRawVerts(renderer, &data); +} + +i32 RSGL_drawTriangle(RSGL_renderer* renderer, RSGL_vec3D t[3]) { + RSGL_vec3D center = {t[2].x, (t[2].y + t[0].y) / 2.0f, t[1].z}; + RSGL_mat4 matrix = RSGL_renderer_initDrawMatrix(renderer, center); + + float points[] = { + RSGL_GET_MATRIX_POINT(t[0].x, t[0].y, t[0].z), + RSGL_GET_MATRIX_POINT(t[1].x, t[1].y, t[1].z), + RSGL_GET_MATRIX_POINT(t[2].x, t[2].y, t[2].z) + }; + + float texPoints[] = { + renderer->state.source.x, renderer->state.source.y + renderer->state.source.h, + renderer->state.source.x + renderer->state.source.w, renderer->state.source.y + renderer->state.source.h, + ((float)(t[2].x - t[0].x)/t[1].x < 1) ? (renderer->state.source.x + (float)(t[2].x - t[0].x) / t[1].x) : renderer->state.source.x, renderer->state.source.y, + }; + + u16 elements[] = { + 0, 1, 2, + }; + + RSGL_rawVerts data; + data.type = RSGL_TRIANGLES; + data.verts = points; + data.texCoords = texPoints; + data.elements = elements; + data.elmCount = 3; + data.vert_count = 3; + + return RSGL_drawRawVerts(renderer, &data); +} + +i32 RSGL_drawCube(RSGL_renderer* renderer, RSGL_cube cube) { + float texPoints[] = { + renderer->state.source.x, renderer->state.source.y, + renderer->state.source.x, renderer->state.source.y + renderer->state.source.h, + renderer->state.source.x + renderer->state.source.w, renderer->state.source.y, + renderer->state.source.x + renderer->state.source.w, renderer->state.source.y + renderer->state.source.h, + + renderer->state.source.x, renderer->state.source.y, + renderer->state.source.x, renderer->state.source.y + renderer->state.source.h, + renderer->state.source.x + renderer->state.source.w, renderer->state.source.y, + renderer->state.source.x + renderer->state.source.w, renderer->state.source.y + renderer->state.source.h, + + renderer->state.source.x, renderer->state.source.y, + renderer->state.source.x, renderer->state.source.y + renderer->state.source.h, + renderer->state.source.x + renderer->state.source.w, renderer->state.source.y, + renderer->state.source.x + renderer->state.source.w, renderer->state.source.y + renderer->state.source.h, + + renderer->state.source.x, renderer->state.source.y, + renderer->state.source.x, renderer->state.source.y + renderer->state.source.h, + renderer->state.source.x + renderer->state.source.w, renderer->state.source.y, + renderer->state.source.x + renderer->state.source.w, renderer->state.source.y + renderer->state.source.h, + + renderer->state.source.x, renderer->state.source.y, + renderer->state.source.x, renderer->state.source.y + renderer->state.source.h, + renderer->state.source.x + renderer->state.source.w, renderer->state.source.y, + renderer->state.source.x + renderer->state.source.w, renderer->state.source.y + renderer->state.source.h, + + renderer->state.source.x, renderer->state.source.y, + renderer->state.source.x, renderer->state.source.y + renderer->state.source.h, + renderer->state.source.x + renderer->state.source.w, renderer->state.source.y, + renderer->state.source.x + renderer->state.source.w, renderer->state.source.y + renderer->state.source.h, + }; + + RSGL_vec3D center = { + cube.x + (cube.w / 2.0f), + cube.y + (cube.h / 2.0f), + cube.z + }; + + RSGL_mat4 matrix = RSGL_renderer_initDrawMatrix(renderer, center); + + float points[] = { + // Front face + RSGL_GET_MATRIX_POINT(cube.x, cube.y, cube.z), + RSGL_GET_MATRIX_POINT(cube.x, cube.y + cube.h, cube.z), + RSGL_GET_MATRIX_POINT(cube.x + cube.w, cube.y, cube.z), + RSGL_GET_MATRIX_POINT(cube.x + cube.w, cube.y + cube.h, cube.z), + // Back face + RSGL_GET_MATRIX_POINT(cube.x + cube.w, cube.y, cube.z + cube.l), + RSGL_GET_MATRIX_POINT(cube.x + cube.w, cube.y + cube.h, cube.z + cube.l), + RSGL_GET_MATRIX_POINT(cube.x, cube.y, cube.z + cube.l), + RSGL_GET_MATRIX_POINT(cube.x, cube.y + cube.h, cube.z + cube.l), + // Left face + RSGL_GET_MATRIX_POINT(cube.x, cube.y, cube.z + cube.l), + RSGL_GET_MATRIX_POINT(cube.x, cube.y + cube.h, cube.z + cube.l), + RSGL_GET_MATRIX_POINT(cube.x, cube.y, cube.z), + RSGL_GET_MATRIX_POINT(cube.x, cube.y + cube.h, cube.z), + // Right face + RSGL_GET_MATRIX_POINT(cube.x + cube.w, cube.y, cube.z), + RSGL_GET_MATRIX_POINT(cube.x + cube.w, cube.y + cube.h, cube.z), + RSGL_GET_MATRIX_POINT(cube.x + cube.w, cube.y, cube.z + cube.l), + RSGL_GET_MATRIX_POINT(cube.x + cube.w, cube.y + cube.h, cube.z + cube.l), + // Top face + RSGL_GET_MATRIX_POINT(cube.x, cube.y + cube.h, cube.z), + RSGL_GET_MATRIX_POINT(cube.x, cube.y + cube.h, cube.z + cube.l), + RSGL_GET_MATRIX_POINT(cube.x + cube.w, cube.y + cube.h, cube.z), + RSGL_GET_MATRIX_POINT(cube.x + cube.w, cube.y + cube.h, cube.z + cube.l), + // Bottom face + RSGL_GET_MATRIX_POINT(cube.x, cube.y, cube.z + cube.l), + RSGL_GET_MATRIX_POINT(cube.x, cube.y, cube.z), + RSGL_GET_MATRIX_POINT(cube.x + cube.w, cube.y, cube.z + cube.l), + RSGL_GET_MATRIX_POINT(cube.x + cube.w, cube.y, cube.z), + }; + + u16 elements[] = { + 0, 1, 2, + 3, 2, 1, + + 4, 5, 6, + 7, 6, 5, + + 8, 9, 10, + 11, 10, 9, + + 12, 13, 14, + 15, 14, 13, + + 16, 17, 18, + 19, 18, 17, + + 20, 21, 22, + 23, 21, 22, + }; + + RSGL_rawVerts data; + data.type = RSGL_TRIANGLES; + data.verts = points; + data.texCoords = texPoints; + data.elements = elements; + data.elmCount = sizeof(elements) / sizeof(u16); + data.vert_count = sizeof(points) / sizeof(float) / 3; + + return RSGL_drawRawVerts(renderer, &data); +} + +/* +outlines +*/ + +i32 RSGL_drawLine(RSGL_renderer* renderer, RSGL_vec2D p1, RSGL_vec2D p2, u32 thickness) { + renderer->state.lineWidth = thickness; + + RSGL_vec3D center = {(p1.x + p2.x) / 2.0f, (p1.y + p2.y) / 2.0f, 0.0f}; + RSGL_mat4 matrix = RSGL_renderer_initDrawMatrix(renderer, center); + + float points[] = {RSGL_GET_MATRIX_POINT(p1.x, p1.y, 0.0f), RSGL_GET_MATRIX_POINT(p2.x, p2.y, 0.0f)}; + float texPoints[] = { renderer->state.source.x, renderer->state.source.y, renderer->state.source.x + renderer->state.source.w, renderer->state.source.y + renderer->state.source.h}; + + u16 elements[] = { 0, 1 }; + + RSGL_rawVerts data; + data.type = RSGL_LINES; + data.verts = points; + data.texCoords = texPoints; + data.elements = elements; + data.elmCount = 4; + data.vert_count = 2; + + return RSGL_drawRawVerts(renderer, &data); +} + +i32 RSGL_drawTriangleOutline(RSGL_renderer* renderer, RSGL_vec3D t[3], u32 thickness) { + renderer->state.lineWidth = thickness; + RSGL_vec3D center = {t[2].x, (t[2].y + t[0].y) / 2.0f, 0}; + RSGL_mat4 matrix = RSGL_renderer_initDrawMatrix(renderer, center); + + float points[] = {RSGL_GET_MATRIX_POINT(t[2].x, t[2].y, t[2].z), + RSGL_GET_MATRIX_POINT(t[0].x, t[0].y,t[0].z), + RSGL_GET_MATRIX_POINT(t[0].x, t[0].y, t[0].z), + RSGL_GET_MATRIX_POINT(t[1].x, t[1].y,t[1].z), + RSGL_GET_MATRIX_POINT(t[1].x, t[1].y, t[1].z), + RSGL_GET_MATRIX_POINT(t[2].x, t[2].y, t[2].z)}; + + float texCoords[18]; + + u16 elements[] = { + 0, 1, 2, + 3, 2, 1 + }; + + RSGL_rawVerts data; + data.type = RSGL_LINES; + data.verts = points; + data.texCoords = texCoords; + data.elements = elements; + data.elmCount = 6; + data.vert_count = 6; + + return RSGL_drawRawVerts(renderer, &data); +} +i32 RSGL_drawRectOutline(RSGL_renderer* renderer, RSGL_rect r, u32 thickness) { + RSGL_renderer_setCenter(renderer, (RSGL_vec3D){r.x + (r.w / 2.0f), r.y + (r.h / 2.0f), 0.0f}); + RSGL_drawLine(renderer, (RSGL_vec2D){r.x, r.y}, (RSGL_vec2D){r.x + r.w, r.y}, thickness); + + RSGL_renderer_setCenter(renderer, (RSGL_vec3D){r.x + (r.w / 2.0f), r.y + (r.h / 2.0f), 0.0f}); + RSGL_drawLine(renderer, (RSGL_vec2D){r.x, r.y}, (RSGL_vec2D){r.x, r.y + r.h}, thickness); + + RSGL_renderer_setCenter(renderer, (RSGL_vec3D){r.x + (r.w / 2.0f), r.y + (r.h / 2.0f), 0.0f}); + RSGL_drawLine(renderer, (RSGL_vec2D){r.x, r.y + r.h}, (RSGL_vec2D){r.x + r.w, r.y + r.h}, thickness); + + RSGL_renderer_setCenter(renderer, (RSGL_vec3D){r.x + (r.w / 2.0f), r.y + (r.h / 2.0f), 0.0f}); + return RSGL_drawLine(renderer, (RSGL_vec2D){r.x + r.w, r.y}, (RSGL_vec2D){r.x + r.w, r.y + r.h}, thickness); +} +i32 RSGL_drawRoundRectOutline(RSGL_renderer* renderer, RSGL_rect r, RSGL_vec2D rounding, u32 thickness) { + RSGL_drawRect(renderer, RSGL_RECT(r.x + (rounding.x/2), r.y, r.w - rounding.x, (int)(thickness + !thickness))); + RSGL_drawRect(renderer, RSGL_RECT(r.x + (rounding.x/2), r.y + r.h, r.w - rounding.x, (int)(thickness + !thickness))); + RSGL_drawRect(renderer, RSGL_RECT(r.x, r.y + (rounding.y/2), (int)(thickness + !thickness), r.h - rounding.y)); + RSGL_drawRect(renderer, RSGL_RECT(r.x + r.w, r.y + (rounding.y/2), (int)(thickness + !thickness), r.h - rounding.y)); + + RSGL_drawArcOutline(renderer, RSGL_RECT(r.x, r.y, rounding.x, rounding.y), (RSGL_vec2D){180, 270}, thickness); + RSGL_drawArcOutline(renderer, RSGL_RECT(r.x + (r.w - rounding.x), r.y, rounding.x, rounding.y), (RSGL_vec2D){90, 180}, thickness); + RSGL_drawArcOutline(renderer, RSGL_RECT(r.x + (r.w - rounding.x), r.y + (r.h - rounding.y) - 1, rounding.x, rounding.y + 2), (RSGL_vec2D){0, 90}, thickness); + return RSGL_drawArcOutline(renderer, RSGL_RECT(r.x + 1, r.y + (r.h - rounding.y) - 1, rounding.x, rounding.y + 2), (RSGL_vec2D){270, 360}, thickness); +} + +i32 RSGL_drawPolygonOutlineEx(RSGL_renderer* renderer, RSGL_rect o, u32 sides, RSGL_vec2D arc) { + static float verts[360 * 2 * 3]; + static float texCoords[360 * 2 * 2]; + + RSGL_vec3D center = (RSGL_vec3D) {o.x + (o.w / 2.0f), o.y + (o.h / 2.0f), 0.0f}; + RSGL_mat4 matrix = RSGL_renderer_initDrawMatrix(renderer, center); + + o = (RSGL_rect){o.x + (o.w / 2), o.y + (o.h / 2), o.w / 2, o.h / 2}; + + float displacement = 360.0f / (float)sides; + float centralAngle = displacement * arc.x; + + i32 i; + u32 j; + size_t index = 0; + + for (i = arc.x; i < arc.y; i++) { + for (j = 0; j < 2; j++) { + float temp[3] = { + RSGL_GET_MATRIX_POINT( + o.x + (RSGL_SIN(DEG2RAD * centralAngle) * o.w), + o.y + (RSGL_COS(DEG2RAD * centralAngle) * o.h), + (0.0) + ) + }; + memcpy(verts + index, temp, sizeof(float) * 3); + + if (!j) centralAngle += displacement; + index += 3; + } + } + + u16 elements[] = { + 0, 1, 2, + 3, 2, 1 + }; + + RSGL_rawVerts data; + data.type = RSGL_LINES; + data.verts = verts; + data.texCoords = texCoords; + data.elements = elements; + data.elmCount = 6; + data.vert_count = 6; + + return RSGL_drawRawVerts(renderer, &data); +} + +i32 RSGL_drawPolygonOutline(RSGL_renderer* renderer, RSGL_rect o, u32 sides, u32 thickness) { + renderer->state.lineWidth = thickness; + return RSGL_drawPolygonOutlineEx(renderer, o, sides, (RSGL_vec2D){0, (float)sides}); +} +i32 RSGL_drawArcOutline(RSGL_renderer* renderer, RSGL_rect o, RSGL_vec2D arc, u32 thickness) { + float verts = ((2 * M_PI * ((o.w + o.h) / 2.0f)) / 10); + verts = (verts > 360 ? 360 : verts); + + renderer->state.lineWidth = thickness; + return RSGL_drawPolygonOutlineEx(renderer, o, verts, arc); +} + +i32 RSGL_drawOvalOutline(RSGL_renderer* renderer, RSGL_rect o, u32 thickness) { + float verts = ((2 * M_PI * ((o.w + o.h) / 2.0f)) / 10); + verts = (verts > 360 ? 360 : verts); + + renderer->state.lineWidth = thickness; + return RSGL_drawPolygonOutlineEx(renderer, o, verts, (RSGL_vec2D){0, verts}); +} + +/* +****** +RSGL_view +****** +*/ + +/* Multiply the current matrix by a rotation matrix */ +RSGL_mat4 RSGL_projection_getMatrix(const RSGL_projection* projection) { + RSGL_mat4 matrix = RSGL_mat4_loadIdentity(); + switch (projection->type) { + case RSGL_projectionPerspective3D: + matrix = RSGL_mat4_perspective(matrix.m, projection->p3D.fov, projection->p3D.ratio, projection->p3D.pNear, projection->p3D.pFar); + break; + case RSGL_projectionOrtho3D: { + double top = projection->p3D.fov / 2.0; + double right = top * projection->p3D.ratio; + + matrix = RSGL_mat4_ortho(matrix.m, -right, right, -top, top, projection->p3D.pNear, projection->p3D.pFar); + break; + } + case RSGL_projectionOrtho2D: + matrix = RSGL_mat4_ortho(matrix.m, 0, projection->p2D.width, projection->p2D.height, 0, 0, 1.0); + break; + default: break; + } + + return matrix; +} + + +RSGL_mat4 RSGL_view_getMatrix(const RSGL_view* view) { + RSGL_mat4 matrix = RSGL_mat4_loadIdentity(); + switch (view->type) { + case RSGL_viewType2D: + matrix = RSGL_mat4_translate(matrix.m, -view->view2D.target.x, -view->view2D.target.y, -view->view2D.target.z); + matrix = RSGL_mat4_rotate(matrix.m, view->view2D.rotation, 0, 0, 1); + matrix = RSGL_mat4_scale(matrix.m, view->view2D.zoom, view->view2D.zoom, 1.0f); + matrix = RSGL_mat4_translate(matrix.m, view->view2D.offset.x, view->view2D.offset.y, view->view2D.offset.z); + break; + case RSGL_viewType3D: + matrix = RSGL_mat4_lookAt(matrix.m, view->view3D.pos.x, view->view3D.pos.y, view->view3D.pos.z, view->view3D.target.x, view->view3D.target.y, view->view3D.target.z, + view->view3D.up.x, view->view3D.up.y, view->view3D.up.z); + break; + default: break; + } + + return matrix; +} + +#endif + +/* +****** +RSGL_Matrix +****** +*/ + + +RSGL_mat4 RSGL_mat4_lookAt(float matrix[16], float eyeX, float eyeY, float eyeZ, float targetX, float targetY, float targetZ, float upX, float upY, float upZ) { + float matLookAt[16]; + + float length = 0.0f; + float ilength = 0.0f; + + RSGL_vec3D vz = { eyeX - targetX, eyeY - targetY, eyeZ - targetZ }; + + RSGL_vec3D v = vz; + length = sqrtf(v.x*v.x + v.y*v.y + v.z*v.z); + if (length == 0.0f) length = 1.0f; + ilength = 1.0f/length; + vz.x *= ilength; + vz.y *= ilength; + vz.z *= ilength; + + RSGL_vec3D vx = { upY*vz.z - upZ*vz.y, upZ*vz.x - upX*vz.z, upX*vz.y - upY*vz.x }; + + v = vx; + length = sqrtf(v.x*v.x + v.y*v.y + v.z*v.z); + if (length == 0.0f) length = 1.0f; + ilength = 1.0f/length; + vx.x *= ilength; + vx.y *= ilength; + vx.z *= ilength; + + RSGL_vec3D vy = { vz.y*vx.z - vz.z*vx.y, vz.z*vx.x - vz.x*vx.z, vz.x*vx.y - vz.y*vx.x }; + + matLookAt[0] = vx.x; + matLookAt[1] = vy.x; + matLookAt[2] = vz.x; + matLookAt[3] = 0.0f; + matLookAt[4] = vx.y; + matLookAt[5] = vy.y; + matLookAt[6] = vz.y; + matLookAt[7] = 0.0f; + matLookAt[8] = vx.z; + matLookAt[9] = vy.z; + matLookAt[10] = vz.z; + matLookAt[11] = 0.0f; + matLookAt[12] = -(vx.x*eyeX + vx.y*eyeY + vx.z*eyeZ); + matLookAt[13] = -(vy.x*eyeX + vy.y*eyeY + vy.z*eyeZ); + matLookAt[14] = -(vz.x*eyeX + vz.y*eyeY + vz.z*eyeZ); + matLookAt[15] = 1.0f; + + return RSGL_mat4_multiply(matrix, matLookAt); +} + +RSGL_mat4 RSGL_mat4_ortho(float matrix[16], float left, float right, float bottom, float top, float znear, float zfar) { + float rl = (float)(right - left); + float tb = (float)(top - bottom); + float fn = (float)(zfar - znear); + + float matOrtho[16] = { + (2.0f / rl), 0.0f, 0.0f, 0.0f, + 0.0f, (2.0f / tb), 0.0f, 0.00, + 0.0f, 0.0f, (-2.0f / fn), 0.0f, + (-((float)left + (float)right) / rl), -((float)top + (float)bottom)/tb, (-((float)zfar + (float)znear) / fn), 1.0f + }; + + return RSGL_mat4_multiply(matrix, matOrtho); +} + +RSGL_mat4 RSGL_mat4_scale(float matrix[16], float x, float y, float z) { + RSGL_mat4 result; + + for (int i = 0; i < 16; ++i) { + result.m[i] = matrix[i]; + } + + result.m[0] += matrix[0]*x + matrix[4]*y + matrix[8]*z; + result.m[13] += matrix[1]*x + matrix[5]*y + matrix[9]*z; + result.m[10] += matrix[2]*x + matrix[6]*y + matrix[10]*z; + result.m[11] += matrix[2] + matrix[6] + matrix[10]; + + return result; +} + + + +/* Multiply the current matrix by a translation matrix */ +RSGL_mat4 RSGL_mat4_translate(float matrix[16], float x, float y, float z) { + RSGL_mat4 result; + + for (int i = 0; i < 16; ++i) { + result.m[i] = matrix[i]; + } + + result.m[12] += matrix[0]*x + matrix[4]*y + matrix[8]*z; + result.m[13] += matrix[1]*x + matrix[5]*y + matrix[9]*z; + result.m[14] += matrix[2]*x + matrix[6]*y + matrix[10]*z; + + return result; +} + +RSGL_mat4 RSGL_mat4_loadIdentity(void) { + RSGL_mat4 matrix = (RSGL_mat4) { + { + 1.0f, 0.0f, 0.0f, 0.0f, + 0.0f, 1.0f, 0.0f, 0.0f, + 0.0f, 0.0f, 1.0f, 0.0f, + 0.0f, 0.0f, 0.0f, 1.0f + } + }; + + return matrix; +} + +RSGL_mat4 RSGL_mat4_rotate(float matrix[16], float angle, float x, float y, float z) { + /* Axis vector (x, y, z) normalization */ + float lengthSquared = x * x + y * y + z * z; + if ((lengthSquared != 1.0f) && (lengthSquared != 0.0f)) { + float inverseLength = 1.0f / sqrtf(lengthSquared); + x *= inverseLength; + y *= inverseLength; + z *= inverseLength; + } + + /* Rotation matrix generation */ + float sinres = RSGL_SIN(angle); + float cosres = RSGL_COS(angle); + float t = 1.0f - cosres; + + float matRotation[16] = { + x * x * t + cosres, y * x * t + z * sinres, z * x * t - y * sinres, 0.0f, + x * y * t - z * sinres, y * y * t + cosres, z * y * t + x * sinres, 0.0f, + x * z * t + y * sinres, y * z * t - x * sinres, z * z * t + cosres, 0.0f, + 0.0f, 0.0f, 0.0f, 1.0f + }; + + return RSGL_mat4_multiply(matRotation, matrix); +} + +RSGL_mat4 RSGL_mat4_perspective(float matrix[16], float fovY, float aspect, float zNear, float zFar) { + fovY = (fovY * DEG2RAD) / 2.0f; + const float f = (RSGL_COS(fovY) / RSGL_SIN(fovY)); + + float perspective[16] = { + (f / aspect), 0.0f, 0.0f, 0.0f, + 0, f, 0.0f, 0.0f, + 0.0f, 0.0f, (zFar + zNear) / (zNear - zFar), -1.0f, + 0.0f, 0.0f, (2.0f * zFar * zNear) / (zNear - zFar), 0.0f + }; + + return RSGL_mat4_multiply(matrix, perspective); +} + +RSGL_vec3D RSGL_mat4_multiplyPoint(RSGL_mat4 matrix, RSGL_vec3D point) { + return (RSGL_vec3D){RSGL_GET_MATRIX_POINT(point.x, point.y, point.z)}; +} + +RSGL_mat4 RSGL_mat4_multiply(float left[16], float right[16]) { + return (RSGL_mat4) { + { + left[0] * right[0] + left[1] * right[4] + left[2] * right[8] + left[3] * right[12], + left[0] * right[1] + left[1] * right[5] + left[2] * right[9] + left[3] * right[13], + left[0] * right[2] + left[1] * right[6] + left[2] * right[10] + left[3] * right[14], + left[0] * right[3] + left[1] * right[7] + left[2] * right[11] + left[3] * right[15], + left[4] * right[0] + left[5] * right[4] + left[6] * right[8] + left[7] * right[12], + left[4] * right[1] + left[5] * right[5] + left[6] * right[9] + left[7] * right[13], + left[4] * right[2] + left[5] * right[6] + left[6] * right[10] + left[7] * right[14], + left[4] * right[3] + left[5] * right[7] + left[6] * right[11] + left[7] * right[15], + left[8] * right[0] + left[9] * right[4] + left[10] * right[8] + left[11] * right[12], + left[8] * right[1] + left[9] * right[5] + left[10] * right[9] + left[11] * right[13], + left[8] * right[2] + left[9] * right[6] + left[10] * right[10] + left[11] * right[14], + left[8] * right[3] + left[9] * right[7] + left[10] * right[11] + left[11] * right[15], + left[12] * right[0] + left[13] * right[4] + left[14] * right[8] + left[15] * right[12], + left[12] * right[1] + left[13] * right[5] + left[14] * right[9] + left[15] * right[13], + left[12] * right[2] + left[13] * right[6] + left[14] * right[10] + left[15] * right[14], + left[12] * right[3] + left[13] * right[7] + left[14] * right[11] + left[15] * right[15] + } + }; +} +#endif /* RSGL_IMPLEMENTATION */ diff --git a/include/RSGL_gl.h b/include/RSGL_gl.h new file mode 100644 index 0000000..a28242a --- /dev/null +++ b/include/RSGL_gl.h @@ -0,0 +1,1001 @@ +#ifndef RSGL_H
+#include "RSGL.h"
+#endif
+
+// WebGL doesn't support compute shaders iirc so yeah
+#if defined(__EMSCRIPTEN__) && defined(RSGL_USE_COMPUTE)
+#undef RSGL_USE_COMPUTE
+#endif
+
+#if defined(__EMSCRIPTEN__)
+ #define RSGL_GLES2
+#endif
+
+#if defined(RSGL_GLES3) || defined(RSGL_GLES2)
+ #ifndef RSGL_NO_GL_LOADER
+ #define RSGL_NO_GL_LOADER
+ #endif
+#endif
+
+#if !defined(RSGL_GLES3) && !defined(RSGL_GLES2) && !defined(RSGL_GL2) && !defined(RSGL_GL3)
+ #define RSGL_GL3
+#endif
+
+#ifndef RSGL_GL_H
+#define RSGL_GL_H
+
+typedef struct RSGL_glRenderer {
+ u32 vao;
+} RSGL_glRenderer;
+
+RSGLDEF RSGL_rendererProc RSGL_GL_rendererProc(void);
+RSGLDEF size_t RSGL_GL_size(void);
+
+RSGLDEF RSGL_renderer* RSGL_GL_renderer_init(void* loader);
+RSGLDEF void RSGL_GL_renderer_initPtr(void* loader, RSGL_glRenderer* ptr, RSGL_renderer* renderer);
+RSGLDEF void RSGL_GL_render(RSGL_glRenderer* ctx, const RSGL_renderPass* pass);
+RSGLDEF void RSGL_GL_initPtr(RSGL_glRenderer* ctx, void* proc); /* init render backend */
+RSGLDEF void RSGL_GL_freePtr(RSGL_glRenderer* ctx); /* free render backend */
+RSGLDEF void RSGL_GL_clear(RSGL_glRenderer* ctx, RSGL_framebuffer framebuffer, float r, float g, float b, float a);
+RSGLDEF void RSGL_GL_viewport(RSGL_glRenderer* ctx, i32 x, i32 y, i32 w, i32 h);
+RSGLDEF void RSGL_GL_createBuffer(RSGL_glRenderer* ctx, RSGL_bufferType type, size_t size, const void* data, size_t* buffer);
+RSGLDEF void RSGL_GL_updateBuffer(RSGL_glRenderer* ctx, RSGL_bufferType type, size_t buffer, const void* data, size_t start, size_t end);
+RSGLDEF void RSGL_GL_deleteBuffer(RSGL_glRenderer* ctx, size_t buffer);
+RSGLDEF RSGL_programBlob RSGL_GL_defaultBlob(RSGL_glRenderer* ctx);
+/* create a texture based on a given bitmap, this must be freed later using RSGL_deleteTexture or opengl*/
+RSGLDEF RSGL_texture RSGL_GL_createTexture(RSGL_glRenderer* ctx, const RSGL_textureBlob* blob);
+/* updates an existing texture wiht a new bitmap */
+RSGLDEF void RSGL_GL_copyToTexture(RSGL_glRenderer* ctx, RSGL_texture texture, size_t x, size_t y, const RSGL_textureBlob* blob);
+/* delete a texture */
+RSGLDEF void RSGL_GL_deleteTexture(RSGL_glRenderer* ctx, RSGL_texture tex);
+/* starts scissoring */
+RSGLDEF void RSGL_GL_scissorStart(RSGL_glRenderer* ctx, float x, float y, float w, float h, float renderer_height);
+/* stops scissoring */
+RSGLDEF void RSGL_GL_scissorEnd(RSGL_glRenderer* ctx);
+/* program loading */
+RSGLDEF RSGL_programInfo RSGL_GL_createProgram(RSGL_glRenderer* ctx, RSGL_programBlob* blob);
+RSGLDEF void RSGL_GL_deleteProgram(RSGL_glRenderer* ctx, const RSGL_programInfo* program);
+RSGLDEF size_t RSGL_GL_findShaderVariable(RSGL_glRenderer* ctx, const RSGL_programInfo* program, const char* var, const size_t len);
+RSGLDEF void RSGL_GL_updateShaderVariable(RSGL_glRenderer* ctx, const RSGL_programInfo* program, size_t var, const float value[], u8 len);
+
+RSGLDEF RSGL_framebuffer RSGL_GL_createFramebuffer(RSGL_glRenderer* renderer, size_t width, size_t height);
+RSGLDEF void RSGL_GL_attachFramebuffer(RSGL_glRenderer* renderer, RSGL_framebuffer fbo, RSGL_texture tex, u8 attachType, u8 mipLevel);
+RSGLDEF void RSGL_GL_deleteFramebuffer(RSGL_glRenderer* renderer, RSGL_framebuffer fbo);
+
+#ifdef RSGL_USE_COMPUTE
+RSGLDEF RSGL_programInfo RSGL_GL_createComputeProgram(RSGL_glRenderer* ctx, const char* CShaderCode);
+RSGLDEF void RSGL_GL_dispatchComputeProgram(RSGL_glRenderer* ctx, RSGL_programInfo program, u32 groups_x, u32 groups_y, u32 groups_z);
+RSGLDEF void RSGL_GL_bindComputeTexture(RSGL_glRenderer* ctx, u32 texture, u8 format);
+#endif
+#endif
+
+#ifdef RSGL_IMPLEMENTATION
+
+RSGL_renderer* RSGL_GL_renderer_init(void* loader) { return RSGL_renderer_init(RSGL_GL_rendererProc(), loader); }
+void RSGL_GL_renderer_initPtr(void* loader, RSGL_glRenderer* ptr, RSGL_renderer* renderer) { return RSGL_renderer_initPtr(RSGL_GL_rendererProc(), loader, ptr, renderer); }
+
+
+/* prevent winapi conflicts (opengl includes windows.h for some reason) */
+#define OEMRESOURCE
+
+#define GL_GLEXT_PROTOTYPES
+
+#ifndef __APPLE__
+#include <GL/gl.h>
+#else
+#include <OpenGL/gl.h>
+#include <OpenGL/glext.h>
+#endif
+
+#if defined(RSGL_GLES3)
+ #include <GLES3/gl3.h>
+#elif defined(RSGL_GLES2)
+ #include <GLES2/gl2.h>
+#endif
+
+#if defined(_WIN32)
+typedef char GLchar;
+typedef int GLsizei;
+#include <GL/glext.h>
+#endif
+
+#ifndef RSGL_NO_GL_LOADER
+
+typedef void (*RSGL_gl_proc)(void); // function pointer equivalent of void*
+#define RSGL_PROC_DEF(proc, name) name##SRC = (name##PROC)(RSGL_gl_proc)proc(#name)
+
+typedef void (*RSGLapiproc)(void);
+typedef RSGLapiproc (*RSGLloadfunc)(const char *name);
+
+typedef void (*glShaderSourcePROC) (GLuint shader, GLsizei count, const GLchar *const*string, const GLint *length);
+typedef GLuint (*glCreateShaderPROC) (GLenum type);
+typedef void (*glCompileShaderPROC) (GLuint shader);
+typedef GLuint (*glCreateProgramPROC) (void);
+typedef void (*glAttachShaderPROC) (GLuint program, GLuint shader);
+typedef void (*glBindAttribLocationPROC) (GLuint program, GLuint index, const GLchar *name);
+typedef void (*glLinkProgramPROC) (GLuint program);
+typedef void (*glBindBufferPROC) (GLenum target, GLuint buffer);
+typedef void (*glBufferDataPROC) (GLenum target, GLsizeiptr size, const void *data, GLenum usage);
+typedef void (*glEnableVertexAttribArrayPROC) (GLuint index);
+typedef void (*glVertexAttribPointerPROC) (GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const void *pointer);
+typedef void (*glDisableVertexAttribArrayPROC) (GLuint index);
+typedef void (*glDeleteBuffersPROC) (GLsizei n, const GLuint *buffers);
+typedef void (*glUseProgramPROC) (GLuint program);
+typedef void (*glDetachShaderPROC) (GLuint program, GLuint shader);
+typedef void (*glDeleteShaderPROC) (GLuint shader);
+typedef void (*glDeleteProgramPROC) (GLuint program);
+typedef void (*glBufferSubDataPROC) (GLenum target, GLintptr offset, GLsizeiptr size, const void *data);
+typedef void (*glGetShaderivPROC)(GLuint shader, GLenum pname, GLint *params);
+typedef void (*glGetShaderInfoLogPROC)(GLuint shader, GLsizei bufSize, GLsizei *length, GLchar *infoLog);
+typedef void (*glGetProgramivPROC)(GLuint program, GLenum pname, GLint *params);
+typedef void (*glGetProgramInfoLogPROC)(GLuint program, GLsizei bufSize, GLsizei *length, GLchar *infoLog);
+typedef void (*glGenBuffersPROC)(GLsizei n, GLuint *buffers);
+typedef GLint (*glGetUniformLocationPROC)(GLuint program, const GLchar *name);
+typedef GLint (*glGetAttribLocationPROC)(GLuint program, const GLchar *name);
+typedef void (*glUniformMatrix4fvPROC)(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+typedef void (*glTexImage2DPROC)(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const void *pixels);
+typedef void (*glActiveTexturePROC) (GLenum texture);
+typedef void (*glUniform1fPROC) (GLint location, GLfloat v0);
+typedef void (*glUniform2fPROC) (GLint location, GLfloat v0, GLfloat v1);
+typedef void (*glUniform3fPROC) (GLint location, GLfloat v0, GLfloat v1, GLfloat v2);
+typedef void (*glUniform4fPROC) (GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3);
+
+#if defined(RSGL_GLES3) || defined(RSGL_GL3)
+ typedef void (*glGenVertexArraysPROC)(GLsizei n, GLuint *arrays);
+ typedef void (*glBindVertexArrayPROC)(GLuint array);
+ typedef void (*glDeleteVertexArraysPROC) (GLsizei n, const GLuint *arrays);
+
+ glGenVertexArraysPROC glGenVertexArraysSRC = NULL;
+ glBindVertexArrayPROC glBindVertexArraySRC = NULL;
+ glDeleteVertexArraysPROC glDeleteVertexArraysSRC = NULL;
+#endif
+
+glShaderSourcePROC glShaderSourceSRC = NULL;
+glCreateShaderPROC glCreateShaderSRC = NULL;
+glCompileShaderPROC glCompileShaderSRC = NULL;
+glCreateProgramPROC glCreateProgramSRC = NULL;
+glAttachShaderPROC glAttachShaderSRC = NULL;
+glBindAttribLocationPROC glBindAttribLocationSRC = NULL;
+glLinkProgramPROC glLinkProgramSRC = NULL;
+glBindBufferPROC glBindBufferSRC = NULL;
+glBufferDataPROC glBufferDataSRC = NULL;
+glEnableVertexAttribArrayPROC glEnableVertexAttribArraySRC = NULL;
+glVertexAttribPointerPROC glVertexAttribPointerSRC = NULL;
+glDisableVertexAttribArrayPROC glDisableVertexAttribArraySRC = NULL;
+glDeleteBuffersPROC glDeleteBuffersSRC = NULL;
+glUseProgramPROC glUseProgramSRC = NULL;
+glDetachShaderPROC glDetachShaderSRC = NULL;
+glDeleteShaderPROC glDeleteShaderSRC = NULL;
+glDeleteProgramPROC glDeleteProgramSRC = NULL;
+glBufferSubDataPROC glBufferSubDataSRC = NULL;
+glGetShaderivPROC glGetShaderivSRC = NULL;
+glGetShaderInfoLogPROC glGetShaderInfoLogSRC = NULL;
+glGetProgramivPROC glGetProgramivSRC = NULL;
+glGetProgramInfoLogPROC glGetProgramInfoLogSRC = NULL;
+glGenBuffersPROC glGenBuffersSRC = NULL;
+glGetUniformLocationPROC glGetUniformLocationSRC = NULL;
+glGetAttribLocationPROC glGetAttribLocationSRC = NULL;
+glUniformMatrix4fvPROC glUniformMatrix4fvSRC = NULL;
+glActiveTexturePROC glActiveTextureSRC = NULL;
+glUniform1fPROC glUniform1fSRC = NULL;
+glUniform2fPROC glUniform2fSRC = NULL;
+glUniform3fPROC glUniform3fSRC = NULL;
+glUniform4fPROC glUniform4fSRC = NULL;
+
+typedef void (*glBindFramebufferPROC) (GLenum target, GLuint framebuffer);
+typedef void (*glGenFramebuffersPROC) (GLsizei n, GLuint *ids);
+typedef void (*glDeleteFramebuffersPROC) (GLsizei n, GLuint *framebuffers);
+typedef void (*glFramebufferTexture2DPROC) (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level);
+
+#ifdef RSGL_USE_COMPUTE
+typedef void (*glDispatchComputePROC)(GLuint x, GLuint y, GLuint z);
+glDispatchComputePROC glDispatchComputeSRC = NULL;
+
+typedef void (*glMemoryBarrierPROC)(GLenum e);
+glMemoryBarrierPROC glMemoryBarrierSRC = NULL;
+
+typedef void (*glBindImageTexturePROC)(GLuint unit, GLuint texture, GLint level, GLboolean layered, GLint layer, GLenum access, GLenum format);
+glBindImageTexturePROC glBindImageTextureSRC = NULL;
+
+#endif
+
+glBindFramebufferPROC glBindFramebufferSRC = NULL;
+glGenFramebuffersPROC glGenFramebuffersSRC = NULL;
+glDeleteFramebuffersPROC glDeleteFramebuffersSRC = NULL;
+glFramebufferTexture2DPROC glFramebufferTexture2DSRC = NULL;
+
+#define glUniform1f glUniform1fSRC
+#define glUniform2f glUniform2fSRC
+#define glUniform3f glUniform3fSRC
+#define glUniform4f glUniform4fSRC
+#define glActiveTexture glActiveTextureSRC
+#define glShaderSource glShaderSourceSRC
+#define glCreateShader glCreateShaderSRC
+#define glCompileShader glCompileShaderSRC
+#define glCreateProgram glCreateProgramSRC
+#define glAttachShader glAttachShaderSRC
+#define glBindAttribLocation glBindAttribLocationSRC
+#define glLinkProgram glLinkProgramSRC
+#define glBindBuffer glBindBufferSRC
+#define glBufferData glBufferDataSRC
+#define glEnableVertexAttribArray glEnableVertexAttribArraySRC
+#define glVertexAttribPointer glVertexAttribPointerSRC
+#define glDisableVertexAttribArray glDisableVertexAttribArraySRC
+#define glDeleteBuffers glDeleteBuffersSRC
+#define glUseProgram glUseProgramSRC
+#define glDetachShader glDetachShaderSRC
+#define glDeleteShader glDeleteShaderSRC
+#define glDeleteProgram glDeleteProgramSRC
+#define glBufferSubData glBufferSubDataSRC
+#define glGetShaderiv glGetShaderivSRC
+#define glGetShaderInfoLog glGetShaderInfoLogSRC
+#define glGetProgramiv glGetProgramivSRC
+#define glGetProgramInfoLog glGetProgramInfoLogSRC
+#define glGenBuffers glGenBuffersSRC
+#define glGetUniformLocation glGetUniformLocationSRC
+#define glGetAttribLocation glGetAttribLocationSRC
+#define glUniformMatrix4fv glUniformMatrix4fvSRC
+#define glBindFramebuffer glBindFramebufferSRC
+#define glGenFramebuffers glGenFramebuffersSRC
+#define glDeleteFramebuffers glDeleteFramebuffersSRC
+#define glFramebufferTexture2D glFramebufferTexture2DSRC
+
+#if defined(RSGL_GLES3) || defined(RSGL_GL3)
+ #define glGenVertexArrays glGenVertexArraysSRC
+ #define glBindVertexArray glBindVertexArraySRC
+ #define glDeleteVertexArrays glDeleteVertexArraysSRC
+#endif
+
+#ifdef RSGL_USE_COMPUTE
+#define glMemoryBarrier glMemoryBarrierSRC
+#define glDispatchCompute glDispatchComputeSRC
+#define glBindImageTexture glBindImageTextureSRC
+#endif
+
+#ifndef GL_TEXTURE_SWIZZLE_RGBA
+ #define GL_TEXTURE_SWIZZLE_RGBA 0x8E46
+#endif
+
+extern int RSGL_loadGLModern(RSGLloadfunc proc);
+#endif
+
+#define RSGL_MULTILINE_STR(...) #__VA_ARGS__
+size_t RSGL_GL_size(void) {
+ return sizeof(RSGL_glRenderer);
+}
+
+RSGL_rendererProc RSGL_GL_rendererProc() {
+ RSGL_rendererProc proc;
+ RSGL_MEMSET(&proc, 0, sizeof(proc));
+
+ proc.render = (void (*)(void*, const RSGL_renderPass* pass))RSGL_GL_render;
+ proc.size = (size_t (*)(void))RSGL_GL_size;
+ proc.initPtr = (void (*)(void*, void*))RSGL_GL_initPtr;
+ proc.freePtr = (void (*)(void*))RSGL_GL_freePtr;
+ proc.clear = (void (*)(void*, RSGL_framebuffer, float, float, float, float))RSGL_GL_clear;
+ proc.viewport = (void (*)(void*, i32, i32, i32, i32))RSGL_GL_viewport;
+ proc.createTexture = (RSGL_texture (*)(void*, const RSGL_textureBlob* blob))RSGL_GL_createTexture;
+ proc.copyToTexture = (void (*)(void*, RSGL_texture, size_t, size_t, const RSGL_textureBlob* blob))RSGL_GL_copyToTexture;
+ proc.deleteTexture = (void (*)(void*, RSGL_texture))RSGL_GL_deleteTexture;
+ proc.scissorStart = (void (*)(void*, float, float, float, float, float))RSGL_GL_scissorStart;
+ proc.scissorEnd = (void (*)(void*))RSGL_GL_scissorEnd;
+ proc.createProgram = (RSGL_programInfo (*)(void*, RSGL_programBlob* blob))RSGL_GL_createProgram;
+ proc.deleteProgram = (void (*)(void*, const RSGL_programInfo*))RSGL_GL_deleteProgram;
+ proc.findShaderVariable = (size_t (*)(void*, const RSGL_programInfo*, const char*, size_t))RSGL_GL_findShaderVariable;
+ proc.updateShaderVariable = (void (*)(void*, const RSGL_programInfo*, size_t, const float[], u8))RSGL_GL_updateShaderVariable;
+ proc.createBuffer = (void (*)(void*, RSGL_bufferType, size_t, const void*, size_t*))RSGL_GL_createBuffer;
+ proc.updateBuffer = (void (*)(void*, RSGL_bufferType, size_t, void*, size_t, size_t))RSGL_GL_updateBuffer;
+ proc.deleteBuffer = (void (*)(void*, size_t))RSGL_GL_deleteBuffer;
+ proc.defaultBlob = (RSGL_programBlob (*)(void*))RSGL_GL_defaultBlob;
+ proc.createFramebuffer = (RSGL_framebuffer (*)(void*, size_t, size_t))RSGL_GL_createFramebuffer;
+ proc.attachFramebuffer = (void (*)(void*, RSGL_framebuffer, RSGL_texture, u8, u8))RSGL_GL_attachFramebuffer;
+ proc.deleteFramebuffer = (void (*)(void*, RSGL_framebuffer))RSGL_GL_deleteFramebuffer;
+
+
+// proc.setSurface = (void (*)(void*, void*))RSGL_GL_setSurface;
+#ifdef RSGL_USE_COMPUTE
+ proc.createComputeProgram = (RSGL_programInfo (*)(void*, const char*))RSGL_GL_createComputeProgram;
+ proc.dispatchComputeProgram = (void (*)(void*, const RSGL_programInfo*, u32, u32, u32))RSGL_GL_dispatchComputeProgram;
+ proc.bindComputeTexture = (void (*)(void*, u32, u8))RSGL_GL_bindComputeTexture;
+#else
+ proc.createComputeProgram = NULL;
+ proc.dispatchComputeProgram = NULL;
+ proc.bindComputeTexture = NULL;
+#endif
+ return proc;
+}
+
+void RSGL_GL_deleteTexture(RSGL_glRenderer* ctx, RSGL_texture tex) { glDeleteTextures(1, (u32*)&tex); }
+void RSGL_GL_viewport(RSGL_glRenderer* ctx, i32 x, i32 y, i32 w, i32 h) { glViewport(x, y, w ,h); }
+
+void RSGL_GL_clear(RSGL_glRenderer* ctx, RSGL_framebuffer framebuffer, float r, float g, float b, float a) {
+ glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
+
+ glClearColor(r, g, b, a);
+ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+
+ glBindFramebuffer(GL_FRAMEBUFFER, 0);
+}
+
+GLuint RSGL_GL_bufferTypeToNative(RSGL_bufferType type) {
+ switch (type) {
+ case RSGL_arrayBuffer: return GL_ARRAY_BUFFER;
+ case RSGL_elementArrayBuffer: return GL_ELEMENT_ARRAY_BUFFER;
+ #if !defined(__APPLE__)
+ case RSGL_shaderStorageBuffer: return GL_SHADER_STORAGE_BUFFER;
+ #endif
+ #if !defined(__APPLE__) || defined(RSGL_GLES3)
+ case RSGL_textureBuffer: return GL_TEXTURE_BUFFER;
+ case RSGL_uniformBuffer: return GL_UNIFORM_BUFFER;
+ #endif
+ default: break;
+ }
+
+ return GL_ARRAY_BUFFER;
+}
+
+void RSGL_GL_createBuffer(RSGL_glRenderer* ctx, RSGL_bufferType type, size_t size, const void* data, size_t* buffer) {
+ glGenBuffers(1, (u32*)buffer);
+
+ GLenum usage = GL_STATIC_DRAW;
+ if (data == NULL)
+ usage = GL_DYNAMIC_DRAW;
+
+ glBindBuffer(RSGL_GL_bufferTypeToNative(type), *(u32*)buffer);
+ glBufferData(RSGL_GL_bufferTypeToNative(type), size, data, usage);
+}
+
+void RSGL_GL_updateBuffer(RSGL_glRenderer* ctx, RSGL_bufferType type, size_t buffer, const void* data, size_t start, size_t end) {
+ glBindBuffer(RSGL_GL_bufferTypeToNative(type), *(u32*)&buffer);
+ glBufferSubData(RSGL_GL_bufferTypeToNative(type), start, end, data);
+}
+
+void RSGL_GL_deleteBuffer(RSGL_glRenderer* ctx, size_t buffer) {
+ glDeleteBuffers(1, (u32*)&buffer);
+}
+
+RSGL_programBlob RSGL_GL_defaultBlob(RSGL_glRenderer* ctx) {
+#ifdef RSGL_GL3
+
+ static const char *defaultVShaderCode = RSGL_MULTILINE_STR(
+ \x23version 330 \n
+ in vec3 vertexPosition; \n
+ in vec2 vertexTexCoord; \n
+ in vec4 vertexColor; \n
+ out vec2 fragTexCoord; \n
+ out vec4 fragColor; \n
+ uniform mat4 model; \n
+ uniform mat4 pv; \n
+ void main() {
+ fragTexCoord = vertexTexCoord;
+ fragColor = vertexColor;
+ gl_Position = pv * model * vec4(vertexPosition, 1.0);
+ }
+ );
+
+ static const char* defaultFShaderCode = RSGL_MULTILINE_STR(
+ \x23version 330 \n
+ in vec2 fragTexCoord;
+ in vec4 fragColor;
+ out vec4 finalColor;
+ uniform sampler2D texture0;
+ void main() {
+ finalColor = texture(texture0, fragTexCoord) * fragColor;
+ }
+ );
+
+#elif defined(RSGL_GLES3)
+
+ static const char *defaultVShaderCode = RSGL_MULTILINE_STR(
+ \x23version 300 es \n
+ in vec3 vertexPosition; \n
+ in vec2 vertexTexCoord; \n
+ in vec4 vertexColor; \n
+ out vec2 fragTexCoord; \n
+ out vec4 fragColor; \n
+ uniform mat4 model; \n
+ uniform mat4 pv; \n
+ void main() {
+ fragTexCoord = vertexTexCoord;
+ fragColor = vertexColor;
+ gl_Position = pv * model * vec4(vertexPosition, 1.0);
+ }
+ );
+
+ static const char* defaultFShaderCode = RSGL_MULTILINE_STR(
+ \x23version 300 es \n
+ precision mediump float; \n
+ in vec2 fragTexCoord;
+ in vec4 fragColor;
+ out vec4 finalColor;
+ uniform sampler2D texture0;
+ void main() {
+ finalColor = texture(texture0, fragTexCoord) * fragColor;
+ }
+ );
+
+#elif defined(RSGL_GLES2) || defined(RSGL_GL2)
+
+ static const char *defaultVShaderCode = RSGL_MULTILINE_STR(
+ \x23version 100 \n
+ attribute vec3 vertexPosition; \n
+ attribute vec2 vertexTexCoord; \n
+ attribute vec4 vertexColor; \n
+ varying vec2 fragTexCoord; \n
+ varying vec4 fragColor; \n
+ uniform mat4 model; \n
+ uniform mat4 pv; \n
+ void main() {
+ fragTexCoord = vertexTexCoord;
+ fragColor = vertexColor;
+ gl_Position = pv * model * vec4(vertexPosition, 1.0);
+ }
+ );
+
+ static const char* defaultFShaderCode = RSGL_MULTILINE_STR(
+ \x23version 100 \n
+ precision mediump float; \n
+ varying vec2 fragTexCoord; \n
+ varying vec4 fragColor; \n
+ vec4 finalColor;
+ uniform sampler2D texture0;
+ void main() {
+ gl_FragColor= texture2D(texture0, fragTexCoord) * fragColor;
+ }
+ );
+#endif
+
+ RSGL_programBlob blob;
+ blob.vertex = defaultVShaderCode;
+ blob.vertexLen = sizeof(defaultVShaderCode);
+ blob.fragment = defaultFShaderCode;
+ blob.fragmentLen = sizeof(defaultFShaderCode );
+
+ return blob;
+}
+
+/*
+print matrix array code snippet
+ for (size_t iy = 0; iy < 4; iy++) {
+ for (size_t ix = 0; ix < 4; ix++) {
+ printf("%f, ", matrix[(iy * 4) + ix]);
+ }
+ printf("\n");
+ }
+
+ printf("\n\n");
+*/
+
+
+
+void RSGL_GL_initPtr(RSGL_glRenderer* ctx, void* proc) {
+ #if !defined(__EMSCRIPTEN__) && !defined(RSGL_NO_GL_LOADER)
+ if (RSGL_loadGLModern((RSGLloadfunc)proc)) {
+ #ifdef RSGL_DEBUG
+ printf("Failed to load an OpenGL 3.3 Context, reverting to OpenGL Legacy\n");
+ #endif
+ return;
+ }
+ #else
+ RSGL_UNUSED(proc);
+ #endif
+
+#ifdef RSGL_DEBUG
+ printf("OpenGL Vendor: %s\n", glGetString(GL_VENDOR));
+ printf("OpenGL Renderer: %s\n", glGetString(GL_RENDERER));
+ printf("OpenGL Version: %s\n", glGetString(GL_VERSION));
+ printf("GLSL Version: %s\n", glGetString(GL_SHADING_LANGUAGE_VERSION));
+#endif
+
+#if defined(RSGL_GLES3) || defined(RSGL_GL3)
+ glGenVertexArrays(1, &ctx->vao);
+#endif
+
+ glEnable(GL_BLEND);
+ glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+}
+
+void RSGL_GL_freePtr(RSGL_glRenderer* ctx) {
+#if defined(RSGL_GLES3) || defined(RSGL_GL3)
+ glDeleteVertexArrays(0, &ctx->vao);
+#endif
+}
+
+void RSGL_GL_render(RSGL_glRenderer* ctx, const RSGL_renderPass* pass) {
+ glBindFramebuffer(GL_FRAMEBUFFER, pass->framebuffer);
+
+#if defined(RSGL_GLES3) || defined(RSGL_GL3)
+ glBindVertexArray(ctx->vao);
+#endif
+
+ glBindBuffer(GL_ARRAY_BUFFER, pass->buffers->vertex);
+ glEnableVertexAttribArray(pass->program->vertexPosition);
+ glVertexAttribPointer(pass->program->vertexPosition, 3, GL_FLOAT, 0, 0, 0);
+
+ glBindBuffer(GL_ARRAY_BUFFER, pass->buffers->texture);
+ glEnableVertexAttribArray(pass->program->vertexTexCoord);
+ glVertexAttribPointer(pass->program->vertexTexCoord, 2, GL_FLOAT, 0, 0, 0);
+
+ glBindBuffer(GL_ARRAY_BUFFER, pass->buffers->color);
+ glEnableVertexAttribArray(pass->program->vertexColor);
+ glVertexAttribPointer(pass->program->vertexColor, 4, GL_FLOAT, 0, 0, 0);
+
+ glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, pass->buffers->elements);
+
+ glUseProgram(pass->program->program);
+ glUniformMatrix4fv(pass->program->perspectiveView, 1, GL_FALSE, pass->matrix);
+
+ u32 i;
+ for (i = 0; i < pass->buffers->batchCount; i++) {
+ GLenum mode = GL_TRIANGLES;
+ glBindTexture(GL_TEXTURE_2D, pass->buffers->batches[i].tex);
+
+ if (pass->buffers->batches[i].lineWidth)
+ glLineWidth(pass->buffers->batches[i].lineWidth);
+
+ glUniformMatrix4fv(pass->program->model, 1, GL_FALSE, pass->buffers->batches[i].matrix.m);
+
+ switch (pass->buffers->batches[i].type) {
+ case RSGL_TRIANGLES: mode = GL_TRIANGLES; break;
+ case RSGL_POINTS: mode = GL_POINTS; break;
+ case RSGL_LINES: mode = GL_LINES; break;
+ default: break;
+ }
+
+ glDrawElements(mode, (i32)pass->buffers->batches[i].elmCount, GL_UNSIGNED_SHORT, (void*)(pass->buffers->batches[i].elmStart * sizeof(u16)));
+ }
+
+ glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
+ glBindBuffer(GL_ARRAY_BUFFER, 0);
+ glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
+ glBindTexture(GL_TEXTURE_2D, 0);
+ glUseProgram(0);
+
+#if defined(RSGL_GLES3) || defined(RSGL_GL3)
+ glBindVertexArray(0);
+#endif
+
+ glBindFramebuffer(GL_FRAMEBUFFER, 0);
+}
+
+void RSGL_GL_scissorStart(RSGL_glRenderer* ctx, float x, float y, float w, float h, float renderer_height) {
+ glEnable(GL_SCISSOR_TEST);
+
+ glScissor(x, renderer_height - (y + h), w, h);
+}
+
+void RSGL_GL_scissorEnd(RSGL_glRenderer* ctx) {
+ glDisable(GL_SCISSOR_TEST);
+}
+
+GLuint RSGL_GL_textureFormatToNative(RSGL_textureFormat format) {
+ switch (format) {
+ case RSGL_formatRGB: return GL_RGB;
+ case RSGL_formatBGR: return GL_BGR;
+ case RSGL_formatRGBA: return GL_RGBA;
+ case RSGL_formatBGRA: return GL_BGRA;
+ case RSGL_formatRed: return GL_RED;
+ case RSGL_formatGrayscale: return GL_RED;
+ case RSGL_formatGrayscaleAlpha: return GL_RED;
+ default: break;
+ }
+
+ return GL_RGBA;
+}
+
+GLuint RSGL_GL_textureDataTypeToNative(RSGL_textureDataType type) {
+ switch (type) {
+ case RSGL_textureDataInt: return GL_UNSIGNED_BYTE;
+ case RSGL_textureDataFloat: return GL_FLOAT;
+ default: break;
+ }
+
+ return GL_UNSIGNED_BYTE;
+}
+
+GLuint RSGL_GL_textureFilterToNative(RSGL_textureFilter filter) {
+ switch (filter) {
+ case RSGL_filterNearest: return GL_NEAREST;
+ case RSGL_filterLinear: return GL_LINEAR;
+ default: break;
+ }
+
+ return GL_LINEAR;
+}
+
+/* textures / images */
+RSGL_texture RSGL_GL_createTexture(RSGL_glRenderer* ctx, const RSGL_textureBlob* blob) {
+ unsigned int id = 0;
+
+ glBindTexture(GL_TEXTURE_2D, 0);
+ glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
+ glGenTextures(1, &id);
+ glBindTexture(GL_TEXTURE_2D, id);
+
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, RSGL_GL_textureFilterToNative(blob->minFilter));
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, RSGL_GL_textureFilterToNative(blob->magFilter));
+
+#ifndef RSGL_GLES2
+ glPixelStorei(GL_UNPACK_ROW_LENGTH, blob->width);
+#endif
+
+#if defined(RSGL_GLES2)
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+#else
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
+#endif
+
+ u32 dataFormat = RSGL_GL_textureFormatToNative(blob->dataFormat);
+ u32 textureFormat = RSGL_GL_textureFormatToNative(blob->textureFormat);
+ u32 dataType = RSGL_GL_textureDataTypeToNative(blob->dataType);
+
+#ifndef RSGL_GLES2
+ if (blob->dataFormat == RSGL_formatGrayscale) {
+ static GLint swizzleRgbaParams[4] = { GL_RED, GL_RED, GL_RED, GL_ONE };
+ glTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_RGBA, swizzleRgbaParams);
+ } else if (blob->dataFormat == RSGL_formatGrayscaleAlpha) {
+ static GLint swizzleRgbaParams[4] = { GL_ONE, GL_ONE, GL_ONE, GL_RED };
+ glTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_RGBA, swizzleRgbaParams);
+ }
+#endif
+
+ glTexImage2D(GL_TEXTURE_2D, 0, dataFormat, blob->width, blob->height, 0, textureFormat, dataType, blob->data);
+ glBindTexture(GL_TEXTURE_2D, 0);
+
+ return id;
+}
+
+void RSGL_GL_copyToTexture(RSGL_glRenderer* ctx, RSGL_texture texture, size_t x, size_t y, const RSGL_textureBlob* blob) {
+ glBindTexture(GL_TEXTURE_2D, texture);
+
+#ifndef RSGL_GLES2
+ glPixelStorei(GL_UNPACK_ROW_LENGTH, blob->width);
+#endif
+
+ u32 dataFormat = RSGL_GL_textureFormatToNative(blob->dataFormat);
+
+ u32 dataType = RSGL_GL_textureDataTypeToNative(blob->dataType);
+
+#ifndef RSGL_GLES2
+ if (blob->dataFormat == RSGL_formatGrayscale) {
+ static GLint swizzleRgbaParams[4] = { GL_RED, GL_RED, GL_RED, GL_ONE };
+ glTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_RGBA, swizzleRgbaParams);
+ } else if (blob->dataFormat == RSGL_formatGrayscaleAlpha) {
+ static GLint swizzleRgbaParams[4] = { GL_ONE, GL_ONE, GL_ONE, GL_RED };
+ glTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_RGBA, swizzleRgbaParams);
+ }
+#endif
+
+ glTexSubImage2D(GL_TEXTURE_2D, 0, x, y, (i32)blob->width, (i32)blob->height, dataFormat, dataType, blob->data);
+ glBindTexture(GL_TEXTURE_2D, 0);
+}
+
+#ifndef GL_DEBUG_TYPE_ERROR
+#define GL_DEBUG_TYPE_ERROR 0x824C
+#define GL_DEBUG_OUTPUT 0x92E0
+#define GL_DEBUG_OUTPUT_SYNCHRONOUS 0x8242
+#define GL_COMPILE_STATUS 0x8B81
+#define GL_LINK_STATUS 0x8B82
+#define GL_INFO_LOG_LENGTH 0x8B84
+#endif
+
+#ifdef RSGL_DEBUG
+void RSGL_opengl_getError(void) {
+ GLenum err;
+ while ((err = glGetError()) != GL_NO_ERROR) {
+ switch (err) {
+ case GL_INVALID_ENUM:
+ printf("OpenGL error: GL_INVALID_ENUM\n");
+ break;
+ case GL_INVALID_VALUE:
+ printf("OpenGL error: GL_INVALID_VALUE\n");
+ break;
+ case GL_INVALID_OPERATION:
+ printf("OpenGL error: GL_INVALID_OPERATION\n");
+ break;
+ case GL_STACK_OVERFLOW:
+ printf("OpenGL error: GL_STACK_OVERFLOW\n");
+ break;
+ case GL_STACK_UNDERFLOW:
+ printf("OpenGL error: GL_STACK_UNDERFLOW\n");
+ break;
+ default:
+ printf("OpenGL error: Unknown error code 0x%x\n", err);
+ break;
+ }
+ }
+}
+
+
+void RSGL_debug_shader(u32 src, const char *shader, const char *action) {
+ GLint status;
+ if (action[0] == 'l')
+ glGetProgramiv(src, GL_LINK_STATUS, &status);
+ else
+ glGetShaderiv(src, GL_COMPILE_STATUS, &status);
+
+ if (status == GL_TRUE)
+ printf("%s Shader %s successfully.\n", shader, action);
+ else {
+ printf("%s Shader failed to %s.\n", shader, action);
+
+ GLchar infoLog[512];
+ if (action[0] == 'c') {
+ glGetShaderInfoLog(src, 512, NULL, infoLog);
+ printf("%s Shader info log:\n%s\n", shader, infoLog);
+ } else {
+ glGetProgramInfoLog(src, 512, NULL, infoLog);
+ printf("%s info log:\n%s\n", shader, infoLog);
+ }
+
+ RSGL_opengl_getError();
+ }
+}
+#endif
+
+RSGL_programInfo RSGL_GL_createProgram(RSGL_glRenderer* ctx, RSGL_programBlob* blob) {
+ RSGL_programInfo program;
+ u32 vShader, fShader;
+
+ /* compile vertex shader */
+ vShader = glCreateShader(GL_VERTEX_SHADER);
+ glShaderSource(vShader, 1, &blob->vertex, NULL);
+ glCompileShader(vShader);
+
+#ifdef RSGL_DEBUG
+ RSGL_debug_shader(vShader, "Vertex", "compile");
+#endif
+
+ /* compile fragment shader */
+ fShader = glCreateShader(GL_FRAGMENT_SHADER);
+ glShaderSource(fShader, 1, &blob->fragment, NULL);
+ glCompileShader(fShader);
+
+#ifdef RSGL_DEBUG
+ RSGL_debug_shader(fShader, "Fragment", "compile");
+#endif
+
+ /* create program and link vertex and fragment shaders */
+ program.program = glCreateProgram();
+
+ glAttachShader(program.program, vShader);
+ glAttachShader(program.program, fShader);
+ glLinkProgram(program.program);
+
+#ifdef RSGL_DEBUG
+ RSGL_debug_shader(program.program, "Program", "link");
+#endif
+
+ glDeleteShader(vShader);
+ glDeleteShader(fShader);
+
+ glUseProgram(program.program);
+
+ program.vertexPosition = glGetAttribLocation(program.program, "vertexPosition");
+ program.vertexTexCoord = glGetAttribLocation(program.program, "vertexTexCoord");
+ program.vertexColor = glGetAttribLocation(program.program, "vertexColor");
+
+ program.perspectiveView = glGetUniformLocation(program.program, "pv");
+ program.model = glGetUniformLocation(program.program, "model");
+
+ #ifdef RSGL_DEBUG
+ if (program.perspectiveView < 0 || program.model < 0) {
+ printf("Failed to locate the shader variables\n");
+ }
+ #endif
+
+ glUseProgram(0);
+
+ program.type = RSGL_shaderTypeStandard;
+ return program;
+}
+
+void RSGL_GL_deleteProgram(RSGL_glRenderer* ctx, const RSGL_programInfo* program) {
+ glUseProgram(0);
+ glDeleteProgram(program->program);
+}
+
+size_t RSGL_GL_findShaderArray(RSGL_glRenderer* ctx, const RSGL_programInfo* program, const char* var, const size_t len) {
+ glUseProgram(program->program);
+ int loc = glGetAttribLocation(program->program, var);
+ glUseProgram(0);
+ return loc;
+}
+
+size_t RSGL_GL_findShaderVariable(RSGL_glRenderer* ctx, const RSGL_programInfo* program, const char* var, const size_t len) {
+ glUseProgram(program->program);
+ int loc = glGetUniformLocation(program->program, var);
+ glUseProgram(0);
+ return loc;
+}
+
+void RSGL_GL_updateShaderVariable(RSGL_glRenderer* ctx, const RSGL_programInfo* program, size_t var, const float value[], u8 len) {
+ glUseProgram(program->program);
+ int loc = (int)var;
+
+ switch (len) {
+ case 1: glUniform1f(loc, value[0]); break;
+ case 2: glUniform2f(loc, value[0], value[1]); break;
+ case 3: glUniform3f(loc, value[0], value[1], value[2]); break;
+ case 4: glUniform4f(loc, value[0], value[1], value[2], value[3]); break;
+ case 16: glUniformMatrix4fv(loc, 1, GL_FALSE, value); break;
+ default: break;
+ }
+
+ glUseProgram(0);
+}
+
+RSGL_framebuffer RSGL_GL_createFramebuffer(RSGL_glRenderer* ctx, size_t width, size_t height) {
+ u32 result = 0;
+ glGenFramebuffers(1, &result);
+ return (RSGL_framebuffer)result;
+}
+
+void RSGL_GL_attachFramebuffer(RSGL_glRenderer* ctx, RSGL_framebuffer fbo, RSGL_texture tex, u8 attachType, u8 mipLevel) {
+ glBindFramebuffer(GL_FRAMEBUFFER, fbo);
+
+ if (attachType < 8)
+ glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + attachType, GL_TEXTURE_2D, tex, mipLevel);
+
+ if (attachType == 100)
+ glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, tex, mipLevel);
+
+ if (attachType == 200)
+ glFramebufferTexture2D(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_TEXTURE_2D, tex, mipLevel);
+
+ glBindFramebuffer(GL_FRAMEBUFFER, 0);
+}
+
+void RSGL_GL_deleteFramebuffer(RSGL_glRenderer* ctx, RSGL_framebuffer fbo) {
+ u32 value = fbo;
+ glDeleteFramebuffers(1, &value);
+}
+
+#ifdef RSGL_USE_COMPUTE
+
+#ifndef GL_RG8
+#define GL_RG8 0x822B
+#endif
+
+#ifndef GL_READ_WRITE
+#define GL_READ_WRITE 0x88BA
+#endif
+
+#ifndef GL_COMPUTE_SHADER
+#define GL_COMPUTE_SHADER 0x91B9
+#endif
+
+#ifndef GL_SHADER_IMAGE_ACCESS_BARRIER_BIT
+#define GL_SHADER_IMAGE_ACCESS_BARRIER_BIT 0x00000020
+#endif
+
+RSGL_programInfo RSGL_GL_createComputeProgram(RSGL_glRenderer* ctx, const char* CShaderCode) {
+ RSGL_programInfo program;
+ program.type = RSGL_shaderTypeCompute;
+
+ u32 compute = glCreateShader(GL_COMPUTE_SHADER);
+ glShaderSource(compute, 1, &CShaderCode, NULL);
+ glCompileShader(compute);
+
+#ifdef RSGL_DEBUG
+ RSGL_debug_shader(compute, "Compute", "compile");
+#endif
+
+ program.program = glCreateProgram();
+ glAttachShader(program.program, compute);
+ glLinkProgram(program.program);
+#ifdef RSGL_DEBUG
+ RSGL_debug_shader(program.program, "Program", "link");
+#endif
+
+ glDeleteShader(compute);
+
+ return program;
+}
+
+void RSGL_GL_dispatchComputeProgram(RSGL_glRenderer* ctx, RSGL_programInfo program, u32 groups_x, u32 groups_y, u32 groups_z) {
+ glUseProgram(program.program);
+ glDispatchCompute(groups_x, groups_y, groups_z);
+ glMemoryBarrier(GL_SHADER_IMAGE_ACCESS_BARRIER_BIT);
+}
+
+
+void RSGL_GL_bindComputeTexture(RSGL_glRenderer* ctx, u32 texture, u8 format) {
+ u16 c = 0;
+ switch (format) {
+ case 2: c = GL_RG8; break;
+ case 3: c = GL_RGB8; break;
+ case 4: c = GL_RGBA8; break;
+ default: break;
+ }
+ glBindImageTexture(0, texture, 0, GL_FALSE, 0, GL_READ_WRITE, c);
+}
+
+#endif
+
+#ifndef RSGL_NO_GL_LOADER
+int RSGL_loadGLModern(RSGLloadfunc proc) {
+ RSGL_PROC_DEF(proc, glShaderSource);
+ RSGL_PROC_DEF(proc, glCreateShader);
+ RSGL_PROC_DEF(proc, glCompileShader);
+ RSGL_PROC_DEF(proc, glCreateProgram);
+ RSGL_PROC_DEF(proc, glAttachShader);
+ RSGL_PROC_DEF(proc, glBindAttribLocation);
+ RSGL_PROC_DEF(proc, glLinkProgram);
+ RSGL_PROC_DEF(proc, glBindBuffer);
+ RSGL_PROC_DEF(proc, glBufferData);
+ RSGL_PROC_DEF(proc, glEnableVertexAttribArray);
+ RSGL_PROC_DEF(proc, glVertexAttribPointer);
+ RSGL_PROC_DEF(proc, glDisableVertexAttribArray);
+ RSGL_PROC_DEF(proc, glDeleteBuffers);
+ RSGL_PROC_DEF(proc, glUseProgram);
+ RSGL_PROC_DEF(proc, glDetachShader);
+ RSGL_PROC_DEF(proc, glDeleteShader);
+ RSGL_PROC_DEF(proc, glDeleteProgram);
+ RSGL_PROC_DEF(proc, glBufferSubData);
+ RSGL_PROC_DEF(proc, glGetShaderiv);
+ RSGL_PROC_DEF(proc, glGetShaderInfoLog);
+ RSGL_PROC_DEF(proc, glGetProgramiv);
+ RSGL_PROC_DEF(proc, glGetProgramInfoLog);
+ RSGL_PROC_DEF(proc, glGenBuffers);
+ RSGL_PROC_DEF(proc, glGetUniformLocation);
+ RSGL_PROC_DEF(proc, glGetAttribLocation);
+ RSGL_PROC_DEF(proc, glUniformMatrix4fv);
+ RSGL_PROC_DEF(proc, glActiveTexture);
+ RSGL_PROC_DEF(proc, glUniform1f);
+ RSGL_PROC_DEF(proc, glUniform2f);
+ RSGL_PROC_DEF(proc, glUniform3f);
+ RSGL_PROC_DEF(proc, glUniform4f);
+ RSGL_PROC_DEF(proc, glBindFramebuffer);
+ RSGL_PROC_DEF(proc, glGenFramebuffers);
+ RSGL_PROC_DEF(proc, glDeleteFramebuffers);
+ RSGL_PROC_DEF(proc, glFramebufferTexture2D);
+#if defined(RSGL_GLES3) || defined(RSGL_GL3)
+ RSGL_PROC_DEF(proc, glBindVertexArray);
+ RSGL_PROC_DEF(proc, glGenVertexArrays);
+ RSGL_PROC_DEF(proc, glDeleteVertexArrays);
+#endif
+#ifdef RSGL_USE_COMPUTE
+ RSGL_PROC_DEF(proc, glDispatchCompute);
+ RSGL_PROC_DEF(proc, glMemoryBarrier);
+ RSGL_PROC_DEF(proc, glBindImageTexture);
+#endif
+
+ if (
+ glShaderSourceSRC == NULL ||
+ glCreateShaderSRC == NULL ||
+ glCompileShaderSRC == NULL ||
+ glCreateProgramSRC == NULL ||
+ glAttachShaderSRC == NULL ||
+ glBindAttribLocationSRC == NULL ||
+ glLinkProgramSRC == NULL ||
+ glBindBufferSRC == NULL ||
+ glBufferDataSRC == NULL ||
+ glVertexAttribPointerSRC == NULL ||
+ glDisableVertexAttribArraySRC == NULL ||
+ glDeleteBuffersSRC == NULL ||
+ glUseProgramSRC == NULL ||
+ glDetachShaderSRC == NULL ||
+ glDeleteShaderSRC == NULL ||
+ glDeleteProgramSRC == NULL ||
+ glBufferSubDataSRC == NULL ||
+ glGetShaderivSRC == NULL ||
+ glGetShaderInfoLogSRC == NULL ||
+ glGetProgramivSRC == NULL ||
+ glGetProgramInfoLogSRC == NULL ||
+ glGenBuffersSRC == NULL ||
+ glGetUniformLocationSRC == NULL ||
+ glUniformMatrix4fvSRC == NULL ||
+ glBindFramebufferSRC == NULL ||
+ glGenFramebuffersSRC == NULL ||
+ glDeleteFramebuffersSRC == NULL ||
+ glFramebufferTexture2DSRC == NULL
+ )
+ return 1;
+ return 0;
+}
+#endif
+
+#endif /* RSGL_IMPLEMENTATION */
@@ -1,53 +1,25 @@ module c3term; -import std::io; - -alias RGFW_window = void; - -constdef RGFW_windowFlags : uint -{ - RGFW_WINDOW_NO_BORDER = 1 << 0, - RGFW_WINDOW_NO_RESIZE = 1 << 1, - RGFW_WINDOW_ALLOW_DND = 1 << 2, - RGFW_WINDOW_HIDE_MOUSE = 1 << 3, - RGFW_WINDOW_FULLSCREEN = 1 << 4, - RGFW_WINDOW_TRANSLUCENT = 1 << 5, - RGFW_WINDOW_TRANSPARENT = RGFW_WINDOW_TRANSLUCENT, - RGFW_WINDOW_CENTER = 1 << 6, - RGFW_WINDOW_RAW_MOUSE = 1 << 7, - RGFW_WINDOW_SCALE_TO_MONITOR = 1 << 8, - RGFW_WINDOW_HIDE = 1 << 9, - RGFW_WINDOW_MAXIMIZE = 1 << 10, - RGFW_WINDOW_CENTER_CURSOR = 1 << 11, - RGFW_WINDOW_FLOATING = 1 << 12, - RGFW_WINDOW_FOCUS_ON_SHOW = 1 << 13, - RGFW_WINDOW_MINIMIZE = 1 << 14, - RGFW_WINDOW_FOCUS = 1 << 15, - RGFW_WINDOW_CAPTURE_MOUSE = 1 << 16, - RGFW_WINDOW_OPENGL = 1 << 17, - RGFW_WINDOW_EGL = 1 << 18, - RGFW_NO_DEINIT_ON_CLOSE = 1 << 19, - RGFW_WINDOWED_FULLSCREEN = RGFW_WINDOW_NO_BORDER | RGFW_WINDOW_MAXIMIZE, - RGFW_WINDOW_CAPTURE_RAW_MOUSE = RGFW_WINDOW_CAPTURE_MOUSE | RGFW_WINDOW_RAW_MOUSE, -} - -extern fn RGFW_window* rgfw_createWindow(ZString, int, int, int, int, RGFW_windowFlags) @cname("RGFW_createWindow"); -extern fn bool rgfw_window_shouldClose(RGFW_window*) @cname("RGFW_window_shouldClose"); -extern fn bool rgfw_window_close(RGFW_window*) @cname("RGFW_window_close"); -extern fn void rgfw_pollEvents() @cname("RGFW_pollEvents"); +import rgfw; +import rsgl; fn int main(String[] args) { - io::printn("init"); + GlHints* hints = rgfw::getGlobalHints_OpenGL(); + hints.major = 3; + hints.minor = 3; + hints.profile = GlProfile.GL_COMPATIBILITY; + rgfw::setGlobalHints_OpenGL(hints); + + Window* window = rgfw::createWindow("window title", 0, 0, 800, 400, WindowFlags.WINDOW_CENTER | WindowFlags.WINDOW_NO_RESIZE | WindowFlags.WINDOW_OPENGL); - RGFW_window* window = rgfw_createWindow("window title", 0, 0, 800, 400, RGFW_WINDOW_CENTER | RGFW_WINDOW_NO_RESIZE); + Renderer* renderer = rsgl::renderer_init(rsgl::gl_rendererProc(), &rgfw::getProcAddress_OpenGL); - while (!rgfw_window_shouldClose(window)) + while (!rgfw::window_shouldClose(window)) { - rgfw_pollEvents(); + rgfw::pollEvents(); } - rgfw_window_close(window); + rgfw::window_close(window); - io::printn("tschuess"); return(0); } diff --git a/project.json b/project.json index 2da8fe4..4f20d87 100644 --- a/project.json +++ b/project.json @@ -4,7 +4,7 @@ "authors": [ "Andromeda-fp" ], "version": "0.1.0", "sources": [ "**" ], - "linked-libraries": [ "wayland-client", "xkbcommon", "wayland-cursor", "wayland-egl", "m"], + "linked-libraries": [ "wayland-client", "xkbcommon", "wayland-cursor", "wayland-egl", "m", "GL"], "c-sources": [ "**" ], "c-include-dirs": [ "include" ], "build-dir": "build", @@ -0,0 +1,83 @@ +module rgfw; + +alias Window = void; +alias GlContext = void; +alias EglContext = void; +alias Proc = fn void (); + +enum GlReleaseBehavior: int +{ + GL_RELEASE_FLUSH, + GL_RELEASE_NONE, +} + +enum GlProfile: int +{ + GL_CORE, + GL_FORWARD_COMPATIBILITY, + GL_COMPATIBILITY, + GL_ES, +} + +enum GlRenderer: int +{ + GL_ACCELERATED, + GL_SOFTWARE, +} + +constdef WindowFlags : uint +{ + WINDOW_NO_BORDER = 1 << 0, + WINDOW_NO_RESIZE = 1 << 1, + WINDOW_ALLOW_DND = 1 << 2, + WINDOW_HIDE_MOUSE = 1 << 3, + WINDOW_FULLSCREEN = 1 << 4, + WINDOW_TRANSLUCENT = 1 << 5, + WINDOW_TRANSPARENT = WINDOW_TRANSLUCENT, + WINDOW_CENTER = 1 << 6, + WINDOW_RAW_MOUSE = 1 << 7, + WINDOW_SCALE_TO_MONITOR = 1 << 8, + WINDOW_HIDE = 1 << 9, + WINDOW_MAXIMIZE = 1 << 10, + WINDOW_CENTER_CURSOR = 1 << 11, + WINDOW_FLOATING = 1 << 12, + WINDOW_FOCUS_ON_SHOW = 1 << 13, + WINDOW_MINIMIZE = 1 << 14, + WINDOW_FOCUS = 1 << 15, + WINDOW_CAPTURE_MOUSE = 1 << 16, + WINDOW_OPENGL = 1 << 17, + WINDOW_EGL = 1 << 18, + NO_DEINIT_ON_CLOSE = 1 << 19, + WINDOWED_FULLSCREEN = WINDOW_NO_BORDER | WINDOW_MAXIMIZE, + WINDOW_CAPTURE_RAW_MOUSE = WINDOW_CAPTURE_MOUSE | WINDOW_RAW_MOUSE, +} + +struct GlHints +{ + int stencil; + int samples; + int stereo; + int auxBuffers; + int doubleBuffer; + int red; int green; int blue; int alpha; + int depth; + int accumRed; int accumGreen; int accumBlue; int accumAlpha; + bool sRGB; + bool robustness; + bool debug; + bool noError; + GlReleaseBehavior releaseBehavior; + GlProfile profile; + int major; int minor; + GlContext* share; + EglContext* shareEGL; + GlRenderer renderer; +} + +extern fn Window* createWindow(ZString, int, int, int, int, WindowFlags) @cname("RGFW_createWindow"); +extern fn bool window_shouldClose(Window*) @cname("RGFW_window_shouldClose"); +extern fn bool window_close(Window*) @cname("RGFW_window_close"); +extern fn void pollEvents() @cname("RGFW_pollEvents"); +extern fn GlHints* getGlobalHints_OpenGL() @cname("RGFW_getGlobalHints_OpenGL"); +extern fn void setGlobalHints_OpenGL(GlHints*) @cname("RGFW_setGlobalHints_OpenGL"); +extern fn Proc getProcAddress_OpenGL(ZString) @cname("RGFW_getProcAddress_OpenGL"); @@ -0,0 +1,95 @@ +module rsgl; + +alias Renderer = void; +alias RenderPass = void; +alias TextureBlob = void; + +alias Framebuffer = usz; +alias Texture = usz; + +enum BufferType +{ + ARRAY_BUFFER, + ELEMENT_ARRAY_BUFFER, + SHADER_STORAGE_BUFFER, + TEXTURE_BUFFER, + UNIFORM_BUFFER, +} + +struct ProgramBlob +{ + ZString vertex; + usz vertexLen; + ZString fragment; + usz fragmentLen; +} + +struct ProgramInfo +{ + usz program; + usz perspectiveView; + usz model; + usz vertexPosition; + usz vertexTexCoord; + usz vertexColor; +} + +alias RendererProc_size = fn usz (); +alias RendererProc_defaultBlob = fn ProgramBlob (void*); +alias RendererProc_initPtr = fn void (void*, void*); +alias RendererProc_freePtr = fn void (void*); +alias RendererProc_render = fn void (void*, RenderPass*); +alias RendererProc_clear = fn void (void*, Framebuffer, float, float, float, float); +alias RendererProc_viewport = fn void (void*, int, int, int, int); +alias RendererProc_setSurface = fn void (void*, void*); +alias RendererProc_createTexture = fn Texture (void*, TextureBlob*); +alias RendererProc_copyToTexture = fn void (void*, Texture, usz, usz, TextureBlob*); +alias RendererProc_deleteTexture = fn void (void*, Texture); +alias RendererProc_scissorStart = fn void (void*, float, float, float, float, float); +alias RendererProc_scissorEnd = fn void (void*); +alias RendererProc_createProgram = fn ProgramInfo (void*, ProgramBlob*); +alias RendererProc_deleteProgram = fn void (void*, ProgramInfo*); +alias RendererProc_findShaderVariable = fn usz (void*, ProgramInfo*, ZString, usz); +alias RendererProc_updateShaderVariable = fn void (void*, ProgramInfo*, usz, float*, char); +alias RendererProc_createComputeProgram = fn ProgramInfo (void*, ZString); +alias RendererProc_dispatchComputeProgram = fn void (void*, ProgramInfo*, uint, uint, uint); +alias RendererProc_bindComputeTexture = fn void (void*, uint, char); +alias RendererProc_createBuffer = fn void (void*, BufferType, usz, void*, usz*); +alias RendererProc_updateBuffer = fn void (void*, BufferType, usz, void*, usz, usz); +alias RendererProc_deleteBuffer = fn void (void*, usz); +alias RendererProc_createFramebuffer = fn Framebuffer (void*, usz, usz); +alias RendererProc_attachFramebuffer = fn void (void*, Framebuffer, Texture, char, char); +alias RendererProc_deleteFramebuffer = fn void (void*, Framebuffer); + +struct RendererProc +{ + RendererProc_size size; + RendererProc_defaultBlob defaultBlob; + RendererProc_initPtr initPtr; + RendererProc_freePtr freePtr; + RendererProc_render render; + RendererProc_clear clear; + RendererProc_viewport viewport; + RendererProc_setSurface setSurface; + RendererProc_createTexture createTexture; + RendererProc_copyToTexture copyToTexture; + RendererProc_deleteTexture deleteTexture; + RendererProc_scissorStart scissorStart; + RendererProc_scissorEnd scissorEnd; + RendererProc_createProgram createProgram; + RendererProc_deleteProgram deleteProgram; + RendererProc_findShaderVariable findShaderVariable; + RendererProc_updateShaderVariable updateShaderVariable; + RendererProc_createComputeProgram createComputeProgram; + RendererProc_dispatchComputeProgram dispatchComputeProgram; + RendererProc_bindComputeTexture bindComputeTexture; + RendererProc_createBuffer createBuffer; + RendererProc_updateBuffer updateBuffer; + RendererProc_deleteBuffer deleteBuffer; + RendererProc_createFramebuffer createFramebuffer; + RendererProc_attachFramebuffer attachFramebuffer; + RendererProc_deleteFramebuffer deleteFramebuffer; +} + +extern fn Renderer* renderer_init(RendererProc, void*) @cname("RSGL_renderer_init"); +extern fn RendererProc gl_rendererProc() @cname("RSGL_GL_rendererProc"); @@ -1,12 +1,9 @@ #define RGFW_IMPLEMENTATION - #define RGFW_WAYLAND #define RGFW_NO_X11 - #define RGFW_OPENGL -#define RGFW_IMPORT - -// same as in C3 -#define RGFW_bool u8 - #include "RGFW.h" + +#define RSGL_IMPLEMENTATION +#include "RSGL.h" +#include "RSGL_gl.h" |
