mirror of
https://github.com/Ed94/VEFontCache-Odin.git
synced 2025-08-06 23:12:43 -07:00
Manually adding thirdparty libs
This commit is contained in:
962
thirdparty/sokol/gl/gl.odin
vendored
Normal file
962
thirdparty/sokol/gl/gl.odin
vendored
Normal file
@@ -0,0 +1,962 @@
|
||||
// machine generated, do not edit
|
||||
|
||||
package sokol_gl
|
||||
|
||||
/*
|
||||
|
||||
sokol_gl.h -- OpenGL 1.x style rendering on top of sokol_gfx.h
|
||||
|
||||
Project URL: https://github.com/floooh/sokol
|
||||
|
||||
Do this:
|
||||
#define SOKOL_IMPL or
|
||||
#define SOKOL_GL_IMPL
|
||||
before you include this file in *one* C or C++ file to create the
|
||||
implementation.
|
||||
|
||||
The following defines are used by the implementation to select the
|
||||
platform-specific embedded shader code (these are the same defines as
|
||||
used by sokol_gfx.h and sokol_app.h):
|
||||
|
||||
SOKOL_GLCORE
|
||||
SOKOL_GLES3
|
||||
SOKOL_D3D11
|
||||
SOKOL_METAL
|
||||
SOKOL_WGPU
|
||||
|
||||
...optionally provide the following macros to override defaults:
|
||||
|
||||
SOKOL_ASSERT(c) - your own assert macro (default: assert(c))
|
||||
SOKOL_GL_API_DECL - public function declaration prefix (default: extern)
|
||||
SOKOL_API_DECL - same as SOKOL_GL_API_DECL
|
||||
SOKOL_API_IMPL - public function implementation prefix (default: -)
|
||||
SOKOL_UNREACHABLE() - a guard macro for unreachable code (default: assert(false))
|
||||
|
||||
If sokol_gl.h is compiled as a DLL, define the following before
|
||||
including the declaration or implementation:
|
||||
|
||||
SOKOL_DLL
|
||||
|
||||
On Windows, SOKOL_DLL will define SOKOL_GL_API_DECL as __declspec(dllexport)
|
||||
or __declspec(dllimport) as needed.
|
||||
|
||||
Include the following headers before including sokol_gl.h:
|
||||
|
||||
sokol_gfx.h
|
||||
|
||||
Matrix functions have been taken from MESA and Regal.
|
||||
|
||||
FEATURE OVERVIEW:
|
||||
=================
|
||||
sokol_gl.h implements a subset of the OpenGLES 1.x feature set useful for
|
||||
when you just want to quickly render a bunch of triangles or
|
||||
lines without having to mess with buffers and shaders.
|
||||
|
||||
The current feature set is mostly useful for debug visualizations
|
||||
and simple UI-style 2D rendering:
|
||||
|
||||
What's implemented:
|
||||
- vertex components:
|
||||
- position (x, y, z)
|
||||
- 2D texture coords (u, v)
|
||||
- color (r, g, b, a)
|
||||
- primitive types:
|
||||
- triangle list and strip
|
||||
- line list and strip
|
||||
- quad list (TODO: quad strips)
|
||||
- point list
|
||||
- one texture layer (no multi-texturing)
|
||||
- viewport and scissor-rect with selectable origin (top-left or bottom-left)
|
||||
- all GL 1.x matrix stack functions, and additionally equivalent
|
||||
functions for gluPerspective and gluLookat
|
||||
|
||||
Notable GLES 1.x features that are *NOT* implemented:
|
||||
- vertex lighting (this is the most likely GL feature that might be added later)
|
||||
- vertex arrays (although providing whole chunks of vertex data at once
|
||||
might be a useful feature for a later version)
|
||||
- texture coordinate generation
|
||||
- line width
|
||||
- all pixel store functions
|
||||
- no ALPHA_TEST
|
||||
- no clear functions (clearing is handled by the sokol-gfx render pass)
|
||||
- fog
|
||||
|
||||
Notable differences to GL:
|
||||
- No "enum soup" for render states etc, instead there's a
|
||||
'pipeline stack', this is similar to GL's matrix stack,
|
||||
but for pipeline-state-objects. The pipeline object at
|
||||
the top of the pipeline stack defines the active set of render states
|
||||
- All angles are in radians, not degrees (note the sgl_rad() and
|
||||
sgl_deg() conversion functions)
|
||||
- No enable/disable state for scissor test, this is always enabled
|
||||
|
||||
STEP BY STEP:
|
||||
=============
|
||||
--- To initialize sokol-gl, call:
|
||||
|
||||
sgl_setup(const sgl_desc_t* desc)
|
||||
|
||||
NOTE that sgl_setup() must be called *after* initializing sokol-gfx
|
||||
(via sg_setup). This is because sgl_setup() needs to create
|
||||
sokol-gfx resource objects.
|
||||
|
||||
If you're intending to render to the default pass, and also don't
|
||||
want to tweak memory usage, and don't want any logging output you can
|
||||
just keep sgl_desc_t zero-initialized:
|
||||
|
||||
sgl_setup(&(sgl_desc_t*){ 0 });
|
||||
|
||||
In this case, sokol-gl will create internal sg_pipeline objects that
|
||||
are compatible with the sokol-app default framebuffer.
|
||||
|
||||
I would recommend to at least install a logging callback so that
|
||||
you'll see any warnings and errors. The easiest way is through
|
||||
sokol_log.h:
|
||||
|
||||
#include "sokol_log.h"
|
||||
|
||||
sgl_setup(&(sgl_desc_t){
|
||||
.logger.func = slog_func.
|
||||
});
|
||||
|
||||
If you want to render into a framebuffer with different pixel-format
|
||||
and MSAA attributes you need to provide the matching attributes in the
|
||||
sgl_setup() call:
|
||||
|
||||
sgl_setup(&(sgl_desc_t*){
|
||||
.color_format = SG_PIXELFORMAT_...,
|
||||
.depth_format = SG_PIXELFORMAT_...,
|
||||
.sample_count = ...,
|
||||
});
|
||||
|
||||
To reduce memory usage, or if you need to create more then the default number of
|
||||
contexts, pipelines, vertices or draw commands, set the following sgl_desc_t
|
||||
members:
|
||||
|
||||
.context_pool_size (default: 4)
|
||||
.pipeline_pool_size (default: 64)
|
||||
.max_vertices (default: 64k)
|
||||
.max_commands (default: 16k)
|
||||
|
||||
Finally you can change the face winding for front-facing triangles
|
||||
and quads:
|
||||
|
||||
.face_winding - default is SG_FACEWINDING_CCW
|
||||
|
||||
The default winding for front faces is counter-clock-wise. This is
|
||||
the same as OpenGL's default, but different from sokol-gfx.
|
||||
|
||||
--- Optionally create additional context objects if you want to render into
|
||||
multiple sokol-gfx render passes (or generally if you want to
|
||||
use multiple independent sokol-gl "state buckets")
|
||||
|
||||
sgl_context ctx = sgl_make_context(const sgl_context_desc_t* desc)
|
||||
|
||||
For details on rendering with sokol-gl contexts, search below for
|
||||
WORKING WITH CONTEXTS.
|
||||
|
||||
--- Optionally create pipeline-state-objects if you need render state
|
||||
that differs from sokol-gl's default state:
|
||||
|
||||
sgl_pipeline pip = sgl_make_pipeline(const sg_pipeline_desc* desc)
|
||||
|
||||
...this creates a pipeline object that's compatible with the currently
|
||||
active context, alternatively call:
|
||||
|
||||
sgl_pipeline_pip = sgl_context_make_pipeline(sgl_context ctx, const sg_pipeline_desc* desc)
|
||||
|
||||
...to create a pipeline object that's compatible with an explicitly
|
||||
provided context.
|
||||
|
||||
The similarity with sokol_gfx.h's sg_pipeline type and sg_make_pipeline()
|
||||
function is intended. sgl_make_pipeline() also takes a standard
|
||||
sokol-gfx sg_pipeline_desc object to describe the render state, but
|
||||
without:
|
||||
- shader
|
||||
- vertex layout
|
||||
- color- and depth-pixel-formats
|
||||
- primitive type (lines, triangles, ...)
|
||||
- MSAA sample count
|
||||
Those will be filled in by sgl_make_pipeline(). Note that each
|
||||
call to sgl_make_pipeline() needs to create several sokol-gfx
|
||||
pipeline objects (one for each primitive type).
|
||||
|
||||
'depth.write_enabled' will be forced to 'false' if the context this
|
||||
pipeline object is intended for has its depth pixel format set to
|
||||
SG_PIXELFORMAT_NONE (which means the framebuffer this context is used
|
||||
with doesn't have a depth-stencil surface).
|
||||
|
||||
--- if you need to destroy sgl_pipeline objects before sgl_shutdown():
|
||||
|
||||
sgl_destroy_pipeline(sgl_pipeline pip)
|
||||
|
||||
--- After sgl_setup() you can call any of the sokol-gl functions anywhere
|
||||
in a frame, *except* sgl_draw(). The 'vanilla' functions
|
||||
will only change internal sokol-gl state, and not call any sokol-gfx
|
||||
functions.
|
||||
|
||||
--- Unlike OpenGL, sokol-gl has a function to reset internal state to
|
||||
a known default. This is useful at the start of a sequence of
|
||||
rendering operations:
|
||||
|
||||
void sgl_defaults(void)
|
||||
|
||||
This will set the following default state:
|
||||
|
||||
- current texture coordinate to u=0.0f, v=0.0f
|
||||
- current color to white (rgba all 1.0f)
|
||||
- current point size to 1.0f
|
||||
- unbind the current texture and texturing will be disabled
|
||||
- *all* matrices will be set to identity (also the projection matrix)
|
||||
- the default render state will be set by loading the 'default pipeline'
|
||||
into the top of the pipeline stack
|
||||
|
||||
The current matrix- and pipeline-stack-depths will not be changed by
|
||||
sgl_defaults().
|
||||
|
||||
--- change the currently active renderstate through the
|
||||
pipeline-stack functions, this works similar to the
|
||||
traditional GL matrix stack:
|
||||
|
||||
...load the default pipeline state on the top of the pipeline stack:
|
||||
|
||||
sgl_load_default_pipeline()
|
||||
|
||||
...load a specific pipeline on the top of the pipeline stack:
|
||||
|
||||
sgl_load_pipeline(sgl_pipeline pip)
|
||||
|
||||
...push and pop the pipeline stack:
|
||||
sgl_push_pipeline()
|
||||
sgl_pop_pipeline()
|
||||
|
||||
--- control texturing with:
|
||||
|
||||
sgl_enable_texture()
|
||||
sgl_disable_texture()
|
||||
sgl_texture(sg_image img, sg_sampler smp)
|
||||
|
||||
NOTE: the img and smp handles can be invalid (SG_INVALID_ID), in this
|
||||
case, sokol-gl will fall back to the internal default (white) texture
|
||||
and sampler.
|
||||
|
||||
--- set the current viewport and scissor rect with:
|
||||
|
||||
sgl_viewport(int x, int y, int w, int h, bool origin_top_left)
|
||||
sgl_scissor_rect(int x, int y, int w, int h, bool origin_top_left)
|
||||
|
||||
...or call these alternatives which take float arguments (this might allow
|
||||
to avoid casting between float and integer in more strongly typed languages
|
||||
when floating point pixel coordinates are used):
|
||||
|
||||
sgl_viewportf(float x, float y, float w, float h, bool origin_top_left)
|
||||
sgl_scissor_rectf(float x, float y, float w, float h, bool origin_top_left)
|
||||
|
||||
...these calls add a new command to the internal command queue, so
|
||||
that the viewport or scissor rect are set at the right time relative
|
||||
to other sokol-gl calls.
|
||||
|
||||
--- adjust the transform matrices, matrix manipulation works just like
|
||||
the OpenGL matrix stack:
|
||||
|
||||
...set the current matrix mode:
|
||||
|
||||
sgl_matrix_mode_modelview()
|
||||
sgl_matrix_mode_projection()
|
||||
sgl_matrix_mode_texture()
|
||||
|
||||
...load the identity matrix into the current matrix:
|
||||
|
||||
sgl_load_identity()
|
||||
|
||||
...translate, rotate and scale the current matrix:
|
||||
|
||||
sgl_translate(float x, float y, float z)
|
||||
sgl_rotate(float angle_rad, float x, float y, float z)
|
||||
sgl_scale(float x, float y, float z)
|
||||
|
||||
NOTE that all angles in sokol-gl are in radians, not in degree.
|
||||
Convert between radians and degree with the helper functions:
|
||||
|
||||
float sgl_rad(float deg) - degrees to radians
|
||||
float sgl_deg(float rad) - radians to degrees
|
||||
|
||||
...directly load the current matrix from a float[16] array:
|
||||
|
||||
sgl_load_matrix(const float m[16])
|
||||
sgl_load_transpose_matrix(const float m[16])
|
||||
|
||||
...directly multiply the current matrix from a float[16] array:
|
||||
|
||||
sgl_mult_matrix(const float m[16])
|
||||
sgl_mult_transpose_matrix(const float m[16])
|
||||
|
||||
The memory layout of those float[16] arrays is the same as in OpenGL.
|
||||
|
||||
...more matrix functions:
|
||||
|
||||
sgl_frustum(float left, float right, float bottom, float top, float near, float far)
|
||||
sgl_ortho(float left, float right, float bottom, float top, float near, float far)
|
||||
sgl_perspective(float fov_y, float aspect, float near, float far)
|
||||
sgl_lookat(float eye_x, float eye_y, float eye_z, float center_x, float center_y, float center_z, float up_x, float up_y, float up_z)
|
||||
|
||||
These functions work the same as glFrustum(), glOrtho(), gluPerspective()
|
||||
and gluLookAt().
|
||||
|
||||
...and finally to push / pop the current matrix stack:
|
||||
|
||||
sgl_push_matrix(void)
|
||||
sgl_pop_matrix(void)
|
||||
|
||||
Again, these work the same as glPushMatrix() and glPopMatrix().
|
||||
|
||||
--- perform primitive rendering:
|
||||
|
||||
...set the current texture coordinate and color 'registers' with or
|
||||
point size with:
|
||||
|
||||
sgl_t2f(float u, float v) - set current texture coordinate
|
||||
sgl_c*(...) - set current color
|
||||
sgl_point_size(float size) - set current point size
|
||||
|
||||
There are several functions for setting the color (as float values,
|
||||
unsigned byte values, packed as unsigned 32-bit integer, with
|
||||
and without alpha).
|
||||
|
||||
NOTE that these are the only functions that can be called both inside
|
||||
sgl_begin_*() / sgl_end() and outside.
|
||||
|
||||
Also NOTE that point size is currently hardwired to 1.0f if the D3D11
|
||||
backend is used.
|
||||
|
||||
...start a primitive vertex sequence with:
|
||||
|
||||
sgl_begin_points()
|
||||
sgl_begin_lines()
|
||||
sgl_begin_line_strip()
|
||||
sgl_begin_triangles()
|
||||
sgl_begin_triangle_strip()
|
||||
sgl_begin_quads()
|
||||
|
||||
...after sgl_begin_*() specify vertices:
|
||||
|
||||
sgl_v*(...)
|
||||
sgl_v*_t*(...)
|
||||
sgl_v*_c*(...)
|
||||
sgl_v*_t*_c*(...)
|
||||
|
||||
These functions write a new vertex to sokol-gl's internal vertex buffer,
|
||||
optionally with texture-coords and color. If the texture coordinate
|
||||
and/or color is missing, it will be taken from the current texture-coord
|
||||
and color 'register'.
|
||||
|
||||
...finally, after specifying vertices, call:
|
||||
|
||||
sgl_end()
|
||||
|
||||
This will record a new draw command in sokol-gl's internal command
|
||||
list, or it will extend the previous draw command if no relevant
|
||||
state has changed since the last sgl_begin/end pair.
|
||||
|
||||
--- inside a sokol-gfx rendering pass, call the sgl_draw() function
|
||||
to render the currently active context:
|
||||
|
||||
sgl_draw()
|
||||
|
||||
...or alternatively call:
|
||||
|
||||
sgl_context_draw(ctx)
|
||||
|
||||
...to render an explicitly provided context.
|
||||
|
||||
This will render everything that has been recorded in the context since
|
||||
the last call to sgl_draw() through sokol-gfx, and will 'rewind' the internal
|
||||
vertex-, uniform- and command-buffers.
|
||||
|
||||
--- each sokol-gl context tracks internal error states which can
|
||||
be obtains via:
|
||||
|
||||
sgl_error_t sgl_error()
|
||||
|
||||
...alternatively with an explicit context argument:
|
||||
|
||||
sgl_error_t sgl_context_error(ctx);
|
||||
|
||||
...this returns a struct with the following booleans:
|
||||
|
||||
.any - true if any of the below errors is true
|
||||
.vertices_full - internal vertex buffer is full (checked in sgl_end())
|
||||
.uniforms_full - the internal uniforms buffer is full (checked in sgl_end())
|
||||
.commands_full - the internal command buffer is full (checked in sgl_end())
|
||||
.stack_overflow - matrix- or pipeline-stack overflow
|
||||
.stack_underflow - matrix- or pipeline-stack underflow
|
||||
.no_context - the active context no longer exists
|
||||
|
||||
...depending on the above error state, sgl_draw() may skip rendering
|
||||
completely, or only draw partial geometry
|
||||
|
||||
--- you can get the number of recorded vertices and draw commands in the current
|
||||
frame and active sokol-gl context via:
|
||||
|
||||
int sgl_num_vertices()
|
||||
int sgl_num_commands()
|
||||
|
||||
...this allows you to check whether the vertex or command pools are running
|
||||
full before the overflow actually happens (in this case you could also
|
||||
check the error booleans in the result of sgl_error()).
|
||||
|
||||
RENDER LAYERS
|
||||
=============
|
||||
Render layers allow to split sokol-gl rendering into separate draw-command
|
||||
groups which can then be rendered separately in a sokol-gfx draw pass. This
|
||||
allows to mix/interleave sokol-gl rendering with other render operations.
|
||||
|
||||
Layered rendering is controlled through two functions:
|
||||
|
||||
sgl_layer(int layer_id)
|
||||
sgl_draw_layer(int layer_id)
|
||||
|
||||
(and the context-variant sgl_draw_layer(): sgl_context_draw_layer()
|
||||
|
||||
The sgl_layer() function sets the 'current layer', any sokol-gl calls
|
||||
which internally record draw commands will also store the current layer
|
||||
in the draw command, and later in a sokol-gfx render pass, a call
|
||||
to sgl_draw_layer() will only render the draw commands that have
|
||||
a matching layer.
|
||||
|
||||
The default layer is '0', this is active after sokol-gl setup, and
|
||||
is also restored at the start of a new frame (but *not* by calling
|
||||
sgl_defaults()).
|
||||
|
||||
NOTE that calling sgl_draw() is equivalent with sgl_draw_layer(0)
|
||||
(in general you should either use either use sgl_draw() or
|
||||
sgl_draw_layer() in an application, but not both).
|
||||
|
||||
WORKING WITH CONTEXTS:
|
||||
======================
|
||||
If you want to render to more than one sokol-gfx render pass you need to
|
||||
work with additional sokol-gl context objects (one context object for
|
||||
each offscreen rendering pass, in addition to the implicitly created
|
||||
'default context'.
|
||||
|
||||
All sokol-gl state is tracked per context, and there is always a "current
|
||||
context" (with the notable exception that the currently set context is
|
||||
destroyed, more on that later).
|
||||
|
||||
Using multiple contexts can also be useful if you only render in
|
||||
a single pass, but want to maintain multiple independent "state buckets".
|
||||
|
||||
To create new context object, call:
|
||||
|
||||
sgl_context ctx = sgl_make_context(&(sgl_context_desc){
|
||||
.max_vertices = ..., // default: 64k
|
||||
.max_commands = ..., // default: 16k
|
||||
.color_format = ...,
|
||||
.depth_format = ...,
|
||||
.sample_count = ...,
|
||||
});
|
||||
|
||||
The color_format, depth_format and sample_count items must be compatible
|
||||
with the render pass the sgl_draw() or sgL_context_draw() function
|
||||
will be called in.
|
||||
|
||||
Creating a context does *not* make the context current. To do this, call:
|
||||
|
||||
sgl_set_context(ctx);
|
||||
|
||||
The currently active context will implicitly be used by most sokol-gl functions
|
||||
which don't take an explicit context handle as argument.
|
||||
|
||||
To switch back to the default context, pass the global constant SGL_DEFAULT_CONTEXT:
|
||||
|
||||
sgl_set_context(SGL_DEFAULT_CONTEXT);
|
||||
|
||||
...or alternatively use the function sgl_default_context() instead of the
|
||||
global constant:
|
||||
|
||||
sgl_set_context(sgl_default_context());
|
||||
|
||||
To get the currently active context, call:
|
||||
|
||||
sgl_context cur_ctx = sgl_get_context();
|
||||
|
||||
The following functions exist in two variants, one which use the currently
|
||||
active context (set with sgl_set_context()), and another version which
|
||||
takes an explicit context handle instead:
|
||||
|
||||
sgl_make_pipeline() vs sgl_context_make_pipeline()
|
||||
sgl_error() vs sgl_context_error();
|
||||
sgl_draw() vs sgl_context_draw();
|
||||
|
||||
Except for using the currently active context versus a provided context
|
||||
handle, the two variants are exactlyidentical, e.g. the following
|
||||
code sequences do the same thing:
|
||||
|
||||
sgl_set_context(ctx);
|
||||
sgl_pipeline pip = sgl_make_pipeline(...);
|
||||
sgl_error_t err = sgl_error();
|
||||
sgl_draw();
|
||||
|
||||
vs
|
||||
|
||||
sgl_pipeline pip = sgl_context_make_pipeline(ctx, ...);
|
||||
sgl_error_t err = sgl_context_error(ctx);
|
||||
sgl_context_draw(ctx);
|
||||
|
||||
Destroying the currently active context is a 'soft error'. All following
|
||||
calls which require a currently active context will silently fail,
|
||||
and sgl_error() will return SGL_ERROR_NO_CONTEXT.
|
||||
|
||||
UNDER THE HOOD:
|
||||
===============
|
||||
sokol_gl.h works by recording vertex data and rendering commands into
|
||||
memory buffers, and then drawing the recorded commands via sokol_gfx.h
|
||||
|
||||
The only functions which call into sokol_gfx.h are:
|
||||
- sgl_setup()
|
||||
- sgl_shutdown()
|
||||
- sgl_draw() (and variants)
|
||||
|
||||
sgl_setup() must be called after initializing sokol-gfx.
|
||||
sgl_shutdown() must be called before shutting down sokol-gfx.
|
||||
sgl_draw() must be called once per frame inside a sokol-gfx render pass.
|
||||
|
||||
All other sokol-gl function can be called anywhere in a frame, since
|
||||
they just record data into memory buffers owned by sokol-gl.
|
||||
|
||||
What happens in:
|
||||
|
||||
sgl_setup():
|
||||
Unique resources shared by all contexts are created:
|
||||
- a shader object (using embedded shader source or byte code)
|
||||
- an 8x8 white default texture
|
||||
The default context is created, which involves:
|
||||
- 3 memory buffers are created, one for vertex data,
|
||||
one for uniform data, and one for commands
|
||||
- a dynamic vertex buffer is created
|
||||
- the default sgl_pipeline object is created, which involves
|
||||
creating 5 sg_pipeline objects
|
||||
|
||||
One vertex is 24 bytes:
|
||||
- float3 position
|
||||
- float2 texture coords
|
||||
- uint32_t color
|
||||
|
||||
One uniform block is 128 bytes:
|
||||
- mat4 model-view-projection matrix
|
||||
- mat4 texture matrix
|
||||
|
||||
One draw command is ca. 24 bytes for the actual
|
||||
command code plus command arguments.
|
||||
|
||||
Each sgl_end() consumes one command, and one uniform block
|
||||
(only when the matrices have changed).
|
||||
The required size for one sgl_begin/end pair is (at most):
|
||||
|
||||
(152 + 24 * num_verts) bytes
|
||||
|
||||
sgl_shutdown():
|
||||
- all sokol-gfx resources (buffer, shader, default-texture and
|
||||
all pipeline objects) are destroyed
|
||||
- the 3 memory buffers are freed
|
||||
|
||||
sgl_draw() (and variants)
|
||||
- copy all recorded vertex data into the dynamic sokol-gfx buffer
|
||||
via a call to sg_update_buffer()
|
||||
- for each recorded command:
|
||||
- if the layer number stored in the command doesn't match
|
||||
the layer that's to be rendered, skip to the next
|
||||
command
|
||||
- if it's a viewport command, call sg_apply_viewport()
|
||||
- if it's a scissor-rect command, call sg_apply_scissor_rect()
|
||||
- if it's a draw command:
|
||||
- depending on what has changed since the last draw command,
|
||||
call sg_apply_pipeline(), sg_apply_bindings() and
|
||||
sg_apply_uniforms()
|
||||
- finally call sg_draw()
|
||||
|
||||
All other functions only modify the internally tracked state, add
|
||||
data to the vertex, uniform and command buffers, or manipulate
|
||||
the matrix stack.
|
||||
|
||||
ON DRAW COMMAND MERGING
|
||||
=======================
|
||||
Not every call to sgl_end() will automatically record a new draw command.
|
||||
If possible, the previous draw command will simply be extended,
|
||||
resulting in fewer actual draw calls later in sgl_draw().
|
||||
|
||||
A draw command will be merged with the previous command if "no relevant
|
||||
state has changed" since the last sgl_end(), meaning:
|
||||
|
||||
- no calls to sgl_viewport() and sgl_scissor_rect()
|
||||
- the primitive type hasn't changed
|
||||
- the primitive type isn't a 'strip type' (no line or triangle strip)
|
||||
- the pipeline state object hasn't changed
|
||||
- the current layer hasn't changed
|
||||
- none of the matrices has changed
|
||||
- none of the texture state has changed
|
||||
|
||||
Merging a draw command simply means that the number of vertices
|
||||
to render in the previous draw command will be incremented by the
|
||||
number of vertices in the new draw command.
|
||||
|
||||
MEMORY ALLOCATION OVERRIDE
|
||||
==========================
|
||||
You can override the memory allocation functions at initialization time
|
||||
like this:
|
||||
|
||||
void* my_alloc(size_t size, void* user_data) {
|
||||
return malloc(size);
|
||||
}
|
||||
|
||||
void my_free(void* ptr, void* user_data) {
|
||||
free(ptr);
|
||||
}
|
||||
|
||||
...
|
||||
sgl_setup(&(sgl_desc_t){
|
||||
// ...
|
||||
.allocator = {
|
||||
.alloc_fn = my_alloc,
|
||||
.free_fn = my_free,
|
||||
.user_data = ...;
|
||||
}
|
||||
});
|
||||
...
|
||||
|
||||
If no overrides are provided, malloc and free will be used.
|
||||
|
||||
|
||||
ERROR REPORTING AND LOGGING
|
||||
===========================
|
||||
To get any logging information at all you need to provide a logging callback in the setup call,
|
||||
the easiest way is to use sokol_log.h:
|
||||
|
||||
#include "sokol_log.h"
|
||||
|
||||
sgl_setup(&(sgl_desc_t){
|
||||
// ...
|
||||
.logger.func = slog_func
|
||||
});
|
||||
|
||||
To override logging with your own callback, first write a logging function like this:
|
||||
|
||||
void my_log(const char* tag, // e.g. 'sgl'
|
||||
uint32_t log_level, // 0=panic, 1=error, 2=warn, 3=info
|
||||
uint32_t log_item_id, // SGL_LOGITEM_*
|
||||
const char* message_or_null, // a message string, may be nullptr in release mode
|
||||
uint32_t line_nr, // line number in sokol_gl.h
|
||||
const char* filename_or_null, // source filename, may be nullptr in release mode
|
||||
void* user_data)
|
||||
{
|
||||
...
|
||||
}
|
||||
|
||||
...and then setup sokol-gl like this:
|
||||
|
||||
sgl_setup(&(sgl_desc_t){
|
||||
.logger = {
|
||||
.func = my_log,
|
||||
.user_data = my_user_data,
|
||||
}
|
||||
});
|
||||
|
||||
The provided logging function must be reentrant (e.g. be callable from
|
||||
different threads).
|
||||
|
||||
If you don't want to provide your own custom logger it is highly recommended to use
|
||||
the standard logger in sokol_log.h instead, otherwise you won't see any warnings or
|
||||
errors.
|
||||
|
||||
|
||||
LICENSE
|
||||
=======
|
||||
zlib/libpng license
|
||||
|
||||
Copyright (c) 2018 Andre Weissflog
|
||||
|
||||
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.
|
||||
|
||||
*/
|
||||
import sg "../gfx"
|
||||
|
||||
import "core:c"
|
||||
|
||||
_ :: c
|
||||
|
||||
SOKOL_DEBUG :: #config(SOKOL_DEBUG, ODIN_DEBUG)
|
||||
|
||||
DEBUG :: #config(SOKOL_GL_DEBUG, SOKOL_DEBUG)
|
||||
USE_GL :: #config(SOKOL_USE_GL, false)
|
||||
USE_DLL :: #config(SOKOL_DLL, false)
|
||||
|
||||
when ODIN_OS == .Windows {
|
||||
when USE_DLL {
|
||||
when USE_GL {
|
||||
when DEBUG { foreign import sokol_gl_clib { "../sokol_dll_windows_x64_gl_debug.lib" } }
|
||||
else { foreign import sokol_gl_clib { "../sokol_dll_windows_x64_gl_release.lib" } }
|
||||
} else {
|
||||
when DEBUG { foreign import sokol_gl_clib { "../sokol_dll_windows_x64_d3d11_debug.lib" } }
|
||||
else { foreign import sokol_gl_clib { "../sokol_dll_windows_x64_d3d11_release.lib" } }
|
||||
}
|
||||
} else {
|
||||
when USE_GL {
|
||||
when DEBUG { foreign import sokol_gl_clib { "sokol_gl_windows_x64_gl_debug.lib" } }
|
||||
else { foreign import sokol_gl_clib { "sokol_gl_windows_x64_gl_release.lib" } }
|
||||
} else {
|
||||
when DEBUG { foreign import sokol_gl_clib { "sokol_gl_windows_x64_d3d11_debug.lib" } }
|
||||
else { foreign import sokol_gl_clib { "sokol_gl_windows_x64_d3d11_release.lib" } }
|
||||
}
|
||||
}
|
||||
} else when ODIN_OS == .Darwin {
|
||||
when USE_DLL {
|
||||
when USE_GL && ODIN_ARCH == .arm64 && DEBUG { foreign import sokol_gl_clib { "../dylib/sokol_dylib_macos_arm64_gl_debug.dylib" } }
|
||||
else when USE_GL && ODIN_ARCH == .arm64 && !DEBUG { foreign import sokol_gl_clib { "../dylib/sokol_dylib_macos_arm64_gl_release.dylib" } }
|
||||
else when USE_GL && ODIN_ARCH == .amd64 && DEBUG { foreign import sokol_gl_clib { "../dylib/sokol_dylib_macos_x64_gl_debug.dylib" } }
|
||||
else when USE_GL && ODIN_ARCH == .amd64 && !DEBUG { foreign import sokol_gl_clib { "../dylib/sokol_dylib_macos_x64_gl_release.dylib" } }
|
||||
else when !USE_GL && ODIN_ARCH == .arm64 && DEBUG { foreign import sokol_gl_clib { "../dylib/sokol_dylib_macos_arm64_metal_debug.dylib" } }
|
||||
else when !USE_GL && ODIN_ARCH == .arm64 && !DEBUG { foreign import sokol_gl_clib { "../dylib/sokol_dylib_macos_arm64_metal_release.dylib" } }
|
||||
else when !USE_GL && ODIN_ARCH == .amd64 && DEBUG { foreign import sokol_gl_clib { "../dylib/sokol_dylib_macos_x64_metal_debug.dylib" } }
|
||||
else when !USE_GL && ODIN_ARCH == .amd64 && !DEBUG { foreign import sokol_gl_clib { "../dylib/sokol_dylib_macos_x64_metal_release.dylib" } }
|
||||
} else {
|
||||
when USE_GL {
|
||||
when ODIN_ARCH == .arm64 {
|
||||
when DEBUG { foreign import sokol_gl_clib { "sokol_gl_macos_arm64_gl_debug.a" } }
|
||||
else { foreign import sokol_gl_clib { "sokol_gl_macos_arm64_gl_release.a" } }
|
||||
} else {
|
||||
when DEBUG { foreign import sokol_gl_clib { "sokol_gl_macos_x64_gl_debug.a" } }
|
||||
else { foreign import sokol_gl_clib { "sokol_gl_macos_x64_gl_release.a" } }
|
||||
}
|
||||
} else {
|
||||
when ODIN_ARCH == .arm64 {
|
||||
when DEBUG { foreign import sokol_gl_clib { "sokol_gl_macos_arm64_metal_debug.a" } }
|
||||
else { foreign import sokol_gl_clib { "sokol_gl_macos_arm64_metal_release.a" } }
|
||||
} else {
|
||||
when DEBUG { foreign import sokol_gl_clib { "sokol_gl_macos_x64_metal_debug.a" } }
|
||||
else { foreign import sokol_gl_clib { "sokol_gl_macos_x64_metal_release.a" } }
|
||||
}
|
||||
}
|
||||
}
|
||||
} else when ODIN_OS == .Linux {
|
||||
when USE_DLL {
|
||||
when DEBUG { foreign import sokol_gl_clib { "sokol_gl_linux_x64_gl_debug.so" } }
|
||||
else { foreign import sokol_gl_clib { "sokol_gl_linux_x64_gl_release.so" } }
|
||||
} else {
|
||||
when DEBUG { foreign import sokol_gl_clib { "sokol_gl_linux_x64_gl_debug.a" } }
|
||||
else { foreign import sokol_gl_clib { "sokol_gl_linux_x64_gl_release.a" } }
|
||||
}
|
||||
} else when ODIN_ARCH == .wasm32 || ODIN_ARCH == .wasm64p32 {
|
||||
// Feed sokol_gl_wasm_gl_debug.a or sokol_gl_wasm_gl_release.a into emscripten compiler.
|
||||
foreign import sokol_gl_clib { "env.o" }
|
||||
} else {
|
||||
#panic("This OS is currently not supported")
|
||||
}
|
||||
|
||||
@(default_calling_convention="c", link_prefix="sgl_")
|
||||
foreign sokol_gl_clib {
|
||||
// setup/shutdown/misc
|
||||
setup :: proc(#by_ptr desc: Desc) ---
|
||||
shutdown :: proc() ---
|
||||
rad :: proc(deg: f32) -> f32 ---
|
||||
deg :: proc(rad: f32) -> f32 ---
|
||||
error :: proc() -> Error ---
|
||||
context_error :: proc(ctx: Context) -> Error ---
|
||||
// context functions
|
||||
make_context :: proc(#by_ptr desc: Context_Desc) -> Context ---
|
||||
destroy_context :: proc(ctx: Context) ---
|
||||
set_context :: proc(ctx: Context) ---
|
||||
get_context :: proc() -> Context ---
|
||||
default_context :: proc() -> Context ---
|
||||
// get information about recorded vertices and commands in current context
|
||||
num_vertices :: proc() -> c.int ---
|
||||
num_commands :: proc() -> c.int ---
|
||||
// draw recorded commands (call inside a sokol-gfx render pass)
|
||||
draw :: proc() ---
|
||||
context_draw :: proc(ctx: Context) ---
|
||||
draw_layer :: proc(#any_int layer_id: c.int) ---
|
||||
context_draw_layer :: proc(ctx: Context, #any_int layer_id: c.int) ---
|
||||
// create and destroy pipeline objects
|
||||
make_pipeline :: proc(#by_ptr desc: sg.Pipeline_Desc) -> Pipeline ---
|
||||
context_make_pipeline :: proc(ctx: Context, #by_ptr desc: sg.Pipeline_Desc) -> Pipeline ---
|
||||
destroy_pipeline :: proc(pip: Pipeline) ---
|
||||
// render state functions
|
||||
defaults :: proc() ---
|
||||
viewport :: proc(#any_int x: c.int, #any_int y: c.int, #any_int w: c.int, #any_int h: c.int, origin_top_left: bool) ---
|
||||
viewportf :: proc(x: f32, y: f32, w: f32, h: f32, origin_top_left: bool) ---
|
||||
scissor_rect :: proc(#any_int x: c.int, #any_int y: c.int, #any_int w: c.int, #any_int h: c.int, origin_top_left: bool) ---
|
||||
scissor_rectf :: proc(x: f32, y: f32, w: f32, h: f32, origin_top_left: bool) ---
|
||||
enable_texture :: proc() ---
|
||||
disable_texture :: proc() ---
|
||||
texture :: proc(img: sg.Image, smp: sg.Sampler) ---
|
||||
layer :: proc(#any_int layer_id: c.int) ---
|
||||
// pipeline stack functions
|
||||
load_default_pipeline :: proc() ---
|
||||
load_pipeline :: proc(pip: Pipeline) ---
|
||||
push_pipeline :: proc() ---
|
||||
pop_pipeline :: proc() ---
|
||||
// matrix stack functions
|
||||
matrix_mode_modelview :: proc() ---
|
||||
matrix_mode_projection :: proc() ---
|
||||
matrix_mode_texture :: proc() ---
|
||||
load_identity :: proc() ---
|
||||
load_matrix :: proc(m: ^f32) ---
|
||||
load_transpose_matrix :: proc(m: ^f32) ---
|
||||
mult_matrix :: proc(m: ^f32) ---
|
||||
mult_transpose_matrix :: proc(m: ^f32) ---
|
||||
rotate :: proc(angle_rad: f32, x: f32, y: f32, z: f32) ---
|
||||
scale :: proc(x: f32, y: f32, z: f32) ---
|
||||
translate :: proc(x: f32, y: f32, z: f32) ---
|
||||
frustum :: proc(l: f32, r: f32, b: f32, t: f32, n: f32, f: f32) ---
|
||||
ortho :: proc(l: f32, r: f32, b: f32, t: f32, n: f32, f: f32) ---
|
||||
perspective :: proc(fov_y: f32, aspect: f32, z_near: f32, z_far: f32) ---
|
||||
lookat :: proc(eye_x: f32, eye_y: f32, eye_z: f32, center_x: f32, center_y: f32, center_z: f32, up_x: f32, up_y: f32, up_z: f32) ---
|
||||
push_matrix :: proc() ---
|
||||
pop_matrix :: proc() ---
|
||||
// these functions only set the internal 'current texcoord / color / point size' (valid inside or outside begin/end)
|
||||
t2f :: proc(u: f32, v: f32) ---
|
||||
c3f :: proc(r: f32, g: f32, b: f32) ---
|
||||
c4f :: proc(r: f32, g: f32, b: f32, a: f32) ---
|
||||
c3b :: proc(r: u8, g: u8, b: u8) ---
|
||||
c4b :: proc(r: u8, g: u8, b: u8, a: u8) ---
|
||||
c1i :: proc(rgba: u32) ---
|
||||
point_size :: proc(s: f32) ---
|
||||
// define primitives, each begin/end is one draw command
|
||||
begin_points :: proc() ---
|
||||
begin_lines :: proc() ---
|
||||
begin_line_strip :: proc() ---
|
||||
begin_triangles :: proc() ---
|
||||
begin_triangle_strip :: proc() ---
|
||||
begin_quads :: proc() ---
|
||||
v2f :: proc(x: f32, y: f32) ---
|
||||
v3f :: proc(x: f32, y: f32, z: f32) ---
|
||||
v2f_t2f :: proc(x: f32, y: f32, u: f32, v: f32) ---
|
||||
v3f_t2f :: proc(x: f32, y: f32, z: f32, u: f32, v: f32) ---
|
||||
v2f_c3f :: proc(x: f32, y: f32, r: f32, g: f32, b: f32) ---
|
||||
v2f_c3b :: proc(x: f32, y: f32, r: u8, g: u8, b: u8) ---
|
||||
v2f_c4f :: proc(x: f32, y: f32, r: f32, g: f32, b: f32, a: f32) ---
|
||||
v2f_c4b :: proc(x: f32, y: f32, r: u8, g: u8, b: u8, a: u8) ---
|
||||
v2f_c1i :: proc(x: f32, y: f32, rgba: u32) ---
|
||||
v3f_c3f :: proc(x: f32, y: f32, z: f32, r: f32, g: f32, b: f32) ---
|
||||
v3f_c3b :: proc(x: f32, y: f32, z: f32, r: u8, g: u8, b: u8) ---
|
||||
v3f_c4f :: proc(x: f32, y: f32, z: f32, r: f32, g: f32, b: f32, a: f32) ---
|
||||
v3f_c4b :: proc(x: f32, y: f32, z: f32, r: u8, g: u8, b: u8, a: u8) ---
|
||||
v3f_c1i :: proc(x: f32, y: f32, z: f32, rgba: u32) ---
|
||||
v2f_t2f_c3f :: proc(x: f32, y: f32, u: f32, v: f32, r: f32, g: f32, b: f32) ---
|
||||
v2f_t2f_c3b :: proc(x: f32, y: f32, u: f32, v: f32, r: u8, g: u8, b: u8) ---
|
||||
v2f_t2f_c4f :: proc(x: f32, y: f32, u: f32, v: f32, r: f32, g: f32, b: f32, a: f32) ---
|
||||
v2f_t2f_c4b :: proc(x: f32, y: f32, u: f32, v: f32, r: u8, g: u8, b: u8, a: u8) ---
|
||||
v2f_t2f_c1i :: proc(x: f32, y: f32, u: f32, v: f32, rgba: u32) ---
|
||||
v3f_t2f_c3f :: proc(x: f32, y: f32, z: f32, u: f32, v: f32, r: f32, g: f32, b: f32) ---
|
||||
v3f_t2f_c3b :: proc(x: f32, y: f32, z: f32, u: f32, v: f32, r: u8, g: u8, b: u8) ---
|
||||
v3f_t2f_c4f :: proc(x: f32, y: f32, z: f32, u: f32, v: f32, r: f32, g: f32, b: f32, a: f32) ---
|
||||
v3f_t2f_c4b :: proc(x: f32, y: f32, z: f32, u: f32, v: f32, r: u8, g: u8, b: u8, a: u8) ---
|
||||
v3f_t2f_c1i :: proc(x: f32, y: f32, z: f32, u: f32, v: f32, rgba: u32) ---
|
||||
end :: proc() ---
|
||||
}
|
||||
|
||||
Log_Item :: enum i32 {
|
||||
OK,
|
||||
MALLOC_FAILED,
|
||||
MAKE_PIPELINE_FAILED,
|
||||
PIPELINE_POOL_EXHAUSTED,
|
||||
ADD_COMMIT_LISTENER_FAILED,
|
||||
CONTEXT_POOL_EXHAUSTED,
|
||||
CANNOT_DESTROY_DEFAULT_CONTEXT,
|
||||
}
|
||||
|
||||
/*
|
||||
sgl_logger_t
|
||||
|
||||
Used in sgl_desc_t to provide a custom logging and error reporting
|
||||
callback to sokol-gl.
|
||||
*/
|
||||
Logger :: struct {
|
||||
func : proc "c" (a0: cstring, a1: u32, a2: u32, a3: cstring, a4: u32, a5: cstring, a6: rawptr),
|
||||
user_data : rawptr,
|
||||
}
|
||||
|
||||
// sokol_gl pipeline handle (created with sgl_make_pipeline())
|
||||
Pipeline :: struct {
|
||||
id : u32,
|
||||
}
|
||||
|
||||
// a context handle (created with sgl_make_context())
|
||||
Context :: struct {
|
||||
id : u32,
|
||||
}
|
||||
|
||||
/*
|
||||
sgl_error_t
|
||||
|
||||
Errors are reset each frame after calling sgl_draw(),
|
||||
get the last error code with sgl_error()
|
||||
*/
|
||||
Error :: struct {
|
||||
any : bool,
|
||||
vertices_full : bool,
|
||||
uniforms_full : bool,
|
||||
commands_full : bool,
|
||||
stack_overflow : bool,
|
||||
stack_underflow : bool,
|
||||
no_context : bool,
|
||||
}
|
||||
|
||||
/*
|
||||
sgl_context_desc_t
|
||||
|
||||
Describes the initialization parameters of a rendering context.
|
||||
Creating additional contexts is useful if you want to render
|
||||
in separate sokol-gfx passes.
|
||||
*/
|
||||
Context_Desc :: struct {
|
||||
max_vertices : c.int,
|
||||
max_commands : c.int,
|
||||
color_format : sg.Pixel_Format,
|
||||
depth_format : sg.Pixel_Format,
|
||||
sample_count : c.int,
|
||||
}
|
||||
|
||||
/*
|
||||
sgl_allocator_t
|
||||
|
||||
Used in sgl_desc_t to provide custom memory-alloc and -free functions
|
||||
to sokol_gl.h. If memory management should be overridden, both the
|
||||
alloc and free function must be provided (e.g. it's not valid to
|
||||
override one function but not the other).
|
||||
*/
|
||||
Allocator :: struct {
|
||||
alloc_fn : proc "c" (a0: c.size_t, a1: rawptr) -> rawptr,
|
||||
free_fn : proc "c" (a0: rawptr, a1: rawptr),
|
||||
user_data : rawptr,
|
||||
}
|
||||
|
||||
Desc :: struct {
|
||||
max_vertices : c.int,
|
||||
max_commands : c.int,
|
||||
context_pool_size : c.int,
|
||||
pipeline_pool_size : c.int,
|
||||
color_format : sg.Pixel_Format,
|
||||
depth_format : sg.Pixel_Format,
|
||||
sample_count : c.int,
|
||||
face_winding : sg.Face_Winding,
|
||||
allocator : Allocator,
|
||||
logger : Logger,
|
||||
}
|
||||
|
Reference in New Issue
Block a user