mirror of
https://github.com/Ed94/VEFontCache-Odin.git
synced 2025-08-06 06:52:44 -07:00
Manually adding thirdparty libs
This commit is contained in:
15
thirdparty/sokol/.gitignore
vendored
Normal file
15
thirdparty/sokol/.gitignore
vendored
Normal file
@@ -0,0 +1,15 @@
|
||||
.vscode/
|
||||
build/
|
||||
*.a
|
||||
*.o
|
||||
*.lib
|
||||
*.obj
|
||||
*.pdb
|
||||
*.bin
|
||||
*.exp
|
||||
*.ilk
|
||||
*.dll
|
||||
*.dylib
|
||||
*.exe
|
||||
*.dSYM/
|
||||
ols.json
|
12
thirdparty/sokol/CHANGELOG.md
vendored
Normal file
12
thirdparty/sokol/CHANGELOG.md
vendored
Normal file
@@ -0,0 +1,12 @@
|
||||
## CHANGELOG
|
||||
|
||||
> NOTE: this changelog is only for changes to the sokol-odin 'scaffolding'.
|
||||
For actual Sokol header changes, see the
|
||||
[sokol changelog](https://github.com/floooh/sokol/blob/master/CHANGELOG.md).
|
||||
|
||||
### 13-Apr-2024
|
||||
|
||||
Merged PR https://github.com/floooh/sokol-odin/pull/11, this changes the
|
||||
directory structure of the bindings repository, adds support to build
|
||||
the Windows bindings as a DLL and a couple of smaller things
|
||||
detailed here: https://github.com/floooh/sokol/pull/1023
|
22
thirdparty/sokol/LICENSE
vendored
Normal file
22
thirdparty/sokol/LICENSE
vendored
Normal file
@@ -0,0 +1,22 @@
|
||||
zlib/libpng license
|
||||
|
||||
Copyright (c) 2022 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.
|
81
thirdparty/sokol/README.md
vendored
Normal file
81
thirdparty/sokol/README.md
vendored
Normal file
@@ -0,0 +1,81 @@
|
||||
[](https://github.com/floooh/sokol-odin/actions/workflows/main.yml)
|
||||
|
||||
Auto-generated [Odin](https://github.com/odin-lang/odin) bindings for the [sokol headers](https://github.com/floooh/sokol).
|
||||
|
||||
To include sokol in your project you can copy the [sokol](sokol/) directory.
|
||||
|
||||
## BUILD
|
||||
|
||||
Supported platforms are: Windows, macOS, Linux (with X11)
|
||||
|
||||
On Linux install the following packages: libglu1-mesa-dev, mesa-common-dev, xorg-dev, libasound-dev
|
||||
(or generally: the dev packages required for X11, GL and ALSA development)
|
||||
|
||||
1. First build the required static link libraries:
|
||||
|
||||
```
|
||||
cd sokol
|
||||
# on macOS:
|
||||
./build_clibs_macos.sh
|
||||
# on Linux:
|
||||
./build_clibs_linux.sh
|
||||
# on Windows with MSVC (from a 'Visual Studio Developer Command Prompt')
|
||||
build_clibs_windows.cmd
|
||||
cd ..
|
||||
```
|
||||
|
||||
2. Create a build directory and cd into it:
|
||||
```
|
||||
mkdir build
|
||||
cd build
|
||||
```
|
||||
|
||||
3. Build and run the samples:
|
||||
```
|
||||
odin run ../examples/clear -debug
|
||||
odin run ../examples/triangle -debug
|
||||
odin run ../examples/quad -debug
|
||||
odin run ../examples/bufferoffsets -debug
|
||||
odin run ../examples/cube -debug
|
||||
odin run ../examples/noninterleaved -debug
|
||||
odin run ../examples/texcube -debug
|
||||
odin run ../examples/shapes -debug
|
||||
odin run ../examples/offscreen -debug
|
||||
odin run ../examples/instancing -debug
|
||||
odin run ../examples/mrt -debug
|
||||
odin run ../examples/blend -debug
|
||||
odin run ../examples/debugtext -debug
|
||||
odin run ../examples/debugtext-print -debug
|
||||
odin run ../examples/debugtext-userfont -debug
|
||||
odin run ../examples/saudio -debug
|
||||
odin run ../examples/sgl -debug
|
||||
odin run ../examples/sgl-points -debug
|
||||
odin run ../examples/sgl-context -debug
|
||||
odin run ../examples/vertexpull -debug
|
||||
```
|
||||
|
||||
By default, the backend 3D API will be selected based on the target platform:
|
||||
|
||||
- macOS: Metal
|
||||
- Windows: D3D11
|
||||
- Linux: GL
|
||||
|
||||
To force the GL backend on macOS or Windows, build with ```-define:SOKOL_USE_GL=true```:
|
||||
|
||||
```
|
||||
odin run ../examples/clear -debug -define:SOKOL_USE_GL=true
|
||||
```
|
||||
|
||||
The ```clear``` sample prints the selected backend to the terminal:
|
||||
|
||||
```
|
||||
odin run ../examples/clear -debug -define:SOKOL_USE_GL=true
|
||||
>> using GL backend
|
||||
```
|
||||
|
||||
On Windows, you can get rid of the automatically opened terminal window
|
||||
by building with the ```-subsystem:windows``` option:
|
||||
|
||||
```
|
||||
odin build ../examples/clear -subsystem:windows
|
||||
```
|
2033
thirdparty/sokol/app/app.odin
vendored
Normal file
2033
thirdparty/sokol/app/app.odin
vendored
Normal file
File diff suppressed because it is too large
Load Diff
649
thirdparty/sokol/audio/audio.odin
vendored
Normal file
649
thirdparty/sokol/audio/audio.odin
vendored
Normal file
@@ -0,0 +1,649 @@
|
||||
// machine generated, do not edit
|
||||
|
||||
package sokol_audio
|
||||
|
||||
/*
|
||||
|
||||
sokol_audio.h -- cross-platform audio-streaming API
|
||||
|
||||
Project URL: https://github.com/floooh/sokol
|
||||
|
||||
Do this:
|
||||
#define SOKOL_IMPL or
|
||||
#define SOKOL_AUDIO_IMPL
|
||||
before you include this file in *one* C or C++ file to create the
|
||||
implementation.
|
||||
|
||||
Optionally provide the following defines with your own implementations:
|
||||
|
||||
SOKOL_DUMMY_BACKEND - use a dummy backend
|
||||
SOKOL_ASSERT(c) - your own assert macro (default: assert(c))
|
||||
SOKOL_AUDIO_API_DECL- public function declaration prefix (default: extern)
|
||||
SOKOL_API_DECL - same as SOKOL_AUDIO_API_DECL
|
||||
SOKOL_API_IMPL - public function implementation prefix (default: -)
|
||||
|
||||
SAUDIO_RING_MAX_SLOTS - max number of slots in the push-audio ring buffer (default 1024)
|
||||
SAUDIO_OSX_USE_SYSTEM_HEADERS - define this to force inclusion of system headers on
|
||||
macOS instead of using embedded CoreAudio declarations
|
||||
|
||||
If sokol_audio.h is compiled as a DLL, define the following before
|
||||
including the declaration or implementation:
|
||||
|
||||
SOKOL_DLL
|
||||
|
||||
On Windows, SOKOL_DLL will define SOKOL_AUDIO_API_DECL as __declspec(dllexport)
|
||||
or __declspec(dllimport) as needed.
|
||||
|
||||
Link with the following libraries:
|
||||
|
||||
- on macOS: AudioToolbox
|
||||
- on iOS: AudioToolbox, AVFoundation
|
||||
- on FreeBSD: asound
|
||||
- on Linux: asound
|
||||
- on Android: aaudio
|
||||
- on Windows with MSVC or Clang toolchain: no action needed, libs are defined in-source via pragma-comment-lib
|
||||
- on Windows with MINGW/MSYS2 gcc: compile with '-mwin32' and link with -lole32
|
||||
|
||||
FEATURE OVERVIEW
|
||||
================
|
||||
You provide a mono- or stereo-stream of 32-bit float samples, which
|
||||
Sokol Audio feeds into platform-specific audio backends:
|
||||
|
||||
- Windows: WASAPI
|
||||
- Linux: ALSA
|
||||
- FreeBSD: ALSA
|
||||
- macOS: CoreAudio
|
||||
- iOS: CoreAudio+AVAudioSession
|
||||
- emscripten: WebAudio with ScriptProcessorNode
|
||||
- Android: AAudio
|
||||
|
||||
Sokol Audio will not do any buffer mixing or volume control, if you have
|
||||
multiple independent input streams of sample data you need to perform the
|
||||
mixing yourself before forwarding the data to Sokol Audio.
|
||||
|
||||
There are two mutually exclusive ways to provide the sample data:
|
||||
|
||||
1. Callback model: You provide a callback function, which will be called
|
||||
when Sokol Audio needs new samples. On all platforms except emscripten,
|
||||
this function is called from a separate thread.
|
||||
2. Push model: Your code pushes small blocks of sample data from your
|
||||
main loop or a thread you created. The pushed data is stored in
|
||||
a ring buffer where it is pulled by the backend code when
|
||||
needed.
|
||||
|
||||
The callback model is preferred because it is the most direct way to
|
||||
feed sample data into the audio backends and also has less moving parts
|
||||
(there is no ring buffer between your code and the audio backend).
|
||||
|
||||
Sometimes it is not possible to generate the audio stream directly in a
|
||||
callback function running in a separate thread, for such cases Sokol Audio
|
||||
provides the push-model as a convenience.
|
||||
|
||||
SOKOL AUDIO, SOLOUD AND MINIAUDIO
|
||||
=================================
|
||||
The WASAPI, ALSA and CoreAudio backend code has been taken from the
|
||||
SoLoud library (with some modifications, so any bugs in there are most
|
||||
likely my fault). If you need a more fully-featured audio solution, check
|
||||
out SoLoud, it's excellent:
|
||||
|
||||
https://github.com/jarikomppa/soloud
|
||||
|
||||
Another alternative which feature-wise is somewhere inbetween SoLoud and
|
||||
sokol-audio might be MiniAudio:
|
||||
|
||||
https://github.com/mackron/miniaudio
|
||||
|
||||
GLOSSARY
|
||||
========
|
||||
- stream buffer:
|
||||
The internal audio data buffer, usually provided by the backend API. The
|
||||
size of the stream buffer defines the base latency, smaller buffers have
|
||||
lower latency but may cause audio glitches. Bigger buffers reduce or
|
||||
eliminate glitches, but have a higher base latency.
|
||||
|
||||
- stream callback:
|
||||
Optional callback function which is called by Sokol Audio when it
|
||||
needs new samples. On Windows, macOS/iOS and Linux, this is called in
|
||||
a separate thread, on WebAudio, this is called per-frame in the
|
||||
browser thread.
|
||||
|
||||
- channel:
|
||||
A discrete track of audio data, currently 1-channel (mono) and
|
||||
2-channel (stereo) is supported and tested.
|
||||
|
||||
- sample:
|
||||
The magnitude of an audio signal on one channel at a given time. In
|
||||
Sokol Audio, samples are 32-bit float numbers in the range -1.0 to
|
||||
+1.0.
|
||||
|
||||
- frame:
|
||||
The tightly packed set of samples for all channels at a given time.
|
||||
For mono 1 frame is 1 sample. For stereo, 1 frame is 2 samples.
|
||||
|
||||
- packet:
|
||||
In Sokol Audio, a small chunk of audio data that is moved from the
|
||||
main thread to the audio streaming thread in order to decouple the
|
||||
rate at which the main thread provides new audio data, and the
|
||||
streaming thread consuming audio data.
|
||||
|
||||
WORKING WITH SOKOL AUDIO
|
||||
========================
|
||||
First call saudio_setup() with your preferred audio playback options.
|
||||
In most cases you can stick with the default values, these provide
|
||||
a good balance between low-latency and glitch-free playback
|
||||
on all audio backends.
|
||||
|
||||
You should always provide a logging callback to be aware of any
|
||||
warnings and errors. The easiest way is to use sokol_log.h for this:
|
||||
|
||||
#include "sokol_log.h"
|
||||
// ...
|
||||
saudio_setup(&(saudio_desc){
|
||||
.logger = {
|
||||
.func = slog_func,
|
||||
}
|
||||
});
|
||||
|
||||
If you want to use the callback-model, you need to provide a stream
|
||||
callback function either in saudio_desc.stream_cb or saudio_desc.stream_userdata_cb,
|
||||
otherwise keep both function pointers zero-initialized.
|
||||
|
||||
Use push model and default playback parameters:
|
||||
|
||||
saudio_setup(&(saudio_desc){ .logger.func = slog_func });
|
||||
|
||||
Use stream callback model and default playback parameters:
|
||||
|
||||
saudio_setup(&(saudio_desc){
|
||||
.stream_cb = my_stream_callback
|
||||
.logger.func = slog_func,
|
||||
});
|
||||
|
||||
The standard stream callback doesn't have a user data argument, if you want
|
||||
that, use the alternative stream_userdata_cb and also set the user_data pointer:
|
||||
|
||||
saudio_setup(&(saudio_desc){
|
||||
.stream_userdata_cb = my_stream_callback,
|
||||
.user_data = &my_data
|
||||
.logger.func = slog_func,
|
||||
});
|
||||
|
||||
The following playback parameters can be provided through the
|
||||
saudio_desc struct:
|
||||
|
||||
General parameters (both for stream-callback and push-model):
|
||||
|
||||
int sample_rate -- the sample rate in Hz, default: 44100
|
||||
int num_channels -- number of channels, default: 1 (mono)
|
||||
int buffer_frames -- number of frames in streaming buffer, default: 2048
|
||||
|
||||
The stream callback prototype (either with or without userdata):
|
||||
|
||||
void (*stream_cb)(float* buffer, int num_frames, int num_channels)
|
||||
void (*stream_userdata_cb)(float* buffer, int num_frames, int num_channels, void* user_data)
|
||||
Function pointer to the user-provide stream callback.
|
||||
|
||||
Push-model parameters:
|
||||
|
||||
int packet_frames -- number of frames in a packet, default: 128
|
||||
int num_packets -- number of packets in ring buffer, default: 64
|
||||
|
||||
The sample_rate and num_channels parameters are only hints for the audio
|
||||
backend, it isn't guaranteed that those are the values used for actual
|
||||
playback.
|
||||
|
||||
To get the actual parameters, call the following functions after
|
||||
saudio_setup():
|
||||
|
||||
int saudio_sample_rate(void)
|
||||
int saudio_channels(void);
|
||||
|
||||
It's unlikely that the number of channels will be different than requested,
|
||||
but a different sample rate isn't uncommon.
|
||||
|
||||
(NOTE: there's an yet unsolved issue when an audio backend might switch
|
||||
to a different sample rate when switching output devices, for instance
|
||||
plugging in a bluetooth headset, this case is currently not handled in
|
||||
Sokol Audio).
|
||||
|
||||
You can check if audio initialization was successful with
|
||||
saudio_isvalid(). If backend initialization failed for some reason
|
||||
(for instance when there's no audio device in the machine), this
|
||||
will return false. Not checking for success won't do any harm, all
|
||||
Sokol Audio function will silently fail when called after initialization
|
||||
has failed, so apart from missing audio output, nothing bad will happen.
|
||||
|
||||
Before your application exits, you should call
|
||||
|
||||
saudio_shutdown();
|
||||
|
||||
This stops the audio thread (on Linux, Windows and macOS/iOS) and
|
||||
properly shuts down the audio backend.
|
||||
|
||||
THE STREAM CALLBACK MODEL
|
||||
=========================
|
||||
To use Sokol Audio in stream-callback-mode, provide a callback function
|
||||
like this in the saudio_desc struct when calling saudio_setup():
|
||||
|
||||
void stream_cb(float* buffer, int num_frames, int num_channels) {
|
||||
...
|
||||
}
|
||||
|
||||
Or the alternative version with a user-data argument:
|
||||
|
||||
void stream_userdata_cb(float* buffer, int num_frames, int num_channels, void* user_data) {
|
||||
my_data_t* my_data = (my_data_t*) user_data;
|
||||
...
|
||||
}
|
||||
|
||||
The job of the callback function is to fill the *buffer* with 32-bit
|
||||
float sample values.
|
||||
|
||||
To output silence, fill the buffer with zeros:
|
||||
|
||||
void stream_cb(float* buffer, int num_frames, int num_channels) {
|
||||
const int num_samples = num_frames * num_channels;
|
||||
for (int i = 0; i < num_samples; i++) {
|
||||
buffer[i] = 0.0f;
|
||||
}
|
||||
}
|
||||
|
||||
For stereo output (num_channels == 2), the samples for the left
|
||||
and right channel are interleaved:
|
||||
|
||||
void stream_cb(float* buffer, int num_frames, int num_channels) {
|
||||
assert(2 == num_channels);
|
||||
for (int i = 0; i < num_frames; i++) {
|
||||
buffer[2*i + 0] = ...; // left channel
|
||||
buffer[2*i + 1] = ...; // right channel
|
||||
}
|
||||
}
|
||||
|
||||
Please keep in mind that the stream callback function is running in a
|
||||
separate thread, if you need to share data with the main thread you need
|
||||
to take care yourself to make the access to the shared data thread-safe!
|
||||
|
||||
THE PUSH MODEL
|
||||
==============
|
||||
To use the push-model for providing audio data, simply don't set (keep
|
||||
zero-initialized) the stream_cb field in the saudio_desc struct when
|
||||
calling saudio_setup().
|
||||
|
||||
To provide sample data with the push model, call the saudio_push()
|
||||
function at regular intervals (for instance once per frame). You can
|
||||
call the saudio_expect() function to ask Sokol Audio how much room is
|
||||
in the ring buffer, but if you provide a continuous stream of data
|
||||
at the right sample rate, saudio_expect() isn't required (it's a simple
|
||||
way to sync/throttle your sample generation code with the playback
|
||||
rate though).
|
||||
|
||||
With saudio_push() you may need to maintain your own intermediate sample
|
||||
buffer, since pushing individual sample values isn't very efficient.
|
||||
The following example is from the MOD player sample in
|
||||
sokol-samples (https://github.com/floooh/sokol-samples):
|
||||
|
||||
const int num_frames = saudio_expect();
|
||||
if (num_frames > 0) {
|
||||
const int num_samples = num_frames * saudio_channels();
|
||||
read_samples(flt_buf, num_samples);
|
||||
saudio_push(flt_buf, num_frames);
|
||||
}
|
||||
|
||||
Another option is to ignore saudio_expect(), and just push samples as they
|
||||
are generated in small batches. In this case you *need* to generate the
|
||||
samples at the right sample rate:
|
||||
|
||||
The following example is taken from the Tiny Emulators project
|
||||
(https://github.com/floooh/chips-test), this is for mono playback,
|
||||
so (num_samples == num_frames):
|
||||
|
||||
// tick the sound generator
|
||||
if (ay38910_tick(&sys->psg)) {
|
||||
// new sample is ready
|
||||
sys->sample_buffer[sys->sample_pos++] = sys->psg.sample;
|
||||
if (sys->sample_pos == sys->num_samples) {
|
||||
// new sample packet is ready
|
||||
saudio_push(sys->sample_buffer, sys->num_samples);
|
||||
sys->sample_pos = 0;
|
||||
}
|
||||
}
|
||||
|
||||
THE WEBAUDIO BACKEND
|
||||
====================
|
||||
The WebAudio backend is currently using a ScriptProcessorNode callback to
|
||||
feed the sample data into WebAudio. ScriptProcessorNode has been
|
||||
deprecated for a while because it is running from the main thread, with
|
||||
the default initialization parameters it works 'pretty well' though.
|
||||
Ultimately Sokol Audio will use Audio Worklets, but this requires a few
|
||||
more things to fall into place (Audio Worklets implemented everywhere,
|
||||
SharedArrayBuffers enabled again, and I need to figure out a 'low-cost'
|
||||
solution in terms of implementation effort, since Audio Worklets are
|
||||
a lot more complex than ScriptProcessorNode if the audio data needs to come
|
||||
from the main thread).
|
||||
|
||||
The WebAudio backend is automatically selected when compiling for
|
||||
emscripten (__EMSCRIPTEN__ define exists).
|
||||
|
||||
https://developers.google.com/web/updates/2017/12/audio-worklet
|
||||
https://developers.google.com/web/updates/2018/06/audio-worklet-design-pattern
|
||||
|
||||
"Blob URLs": https://www.html5rocks.com/en/tutorials/workers/basics/
|
||||
|
||||
Also see: https://blog.paul.cx/post/a-wait-free-spsc-ringbuffer-for-the-web/
|
||||
|
||||
THE COREAUDIO BACKEND
|
||||
=====================
|
||||
The CoreAudio backend is selected on macOS and iOS (__APPLE__ is defined).
|
||||
Since the CoreAudio API is implemented in C (not Objective-C) on macOS the
|
||||
implementation part of Sokol Audio can be included into a C source file.
|
||||
|
||||
However on iOS, Sokol Audio must be compiled as Objective-C due to it's
|
||||
reliance on the AVAudioSession object. The iOS code path support both
|
||||
being compiled with or without ARC (Automatic Reference Counting).
|
||||
|
||||
For thread synchronisation, the CoreAudio backend will use the
|
||||
pthread_mutex_* functions.
|
||||
|
||||
The incoming floating point samples will be directly forwarded to
|
||||
CoreAudio without further conversion.
|
||||
|
||||
macOS and iOS applications that use Sokol Audio need to link with
|
||||
the AudioToolbox framework.
|
||||
|
||||
THE WASAPI BACKEND
|
||||
==================
|
||||
The WASAPI backend is automatically selected when compiling on Windows
|
||||
(_WIN32 is defined).
|
||||
|
||||
For thread synchronisation a Win32 critical section is used.
|
||||
|
||||
WASAPI may use a different size for its own streaming buffer then requested,
|
||||
so the base latency may be slightly bigger. The current backend implementation
|
||||
converts the incoming floating point sample values to signed 16-bit
|
||||
integers.
|
||||
|
||||
The required Windows system DLLs are linked with #pragma comment(lib, ...),
|
||||
so you shouldn't need to add additional linker libs in the build process
|
||||
(otherwise this is a bug which should be fixed in sokol_audio.h).
|
||||
|
||||
THE ALSA BACKEND
|
||||
================
|
||||
The ALSA backend is automatically selected when compiling on Linux
|
||||
('linux' is defined).
|
||||
|
||||
For thread synchronisation, the pthread_mutex_* functions are used.
|
||||
|
||||
Samples are directly forwarded to ALSA in 32-bit float format, no
|
||||
further conversion is taking place.
|
||||
|
||||
You need to link with the 'asound' library, and the <alsa/asoundlib.h>
|
||||
header must be present (usually both are installed with some sort
|
||||
of ALSA development package).
|
||||
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
...
|
||||
saudio_setup(&(saudio_desc){
|
||||
// ...
|
||||
.allocator = {
|
||||
.alloc_fn = my_alloc,
|
||||
.free_fn = my_free,
|
||||
.user_data = ...,
|
||||
}
|
||||
});
|
||||
...
|
||||
|
||||
If no overrides are provided, malloc and free will be used.
|
||||
|
||||
This only affects memory allocation calls done by sokol_audio.h
|
||||
itself though, not any allocations in OS libraries.
|
||||
|
||||
Memory allocation will only happen on the same thread where saudio_setup()
|
||||
was called, so you don't need to worry about thread-safety.
|
||||
|
||||
|
||||
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"
|
||||
|
||||
saudio_setup(&(saudio_desc){ .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. 'saudio'
|
||||
uint32_t log_level, // 0=panic, 1=error, 2=warn, 3=info
|
||||
uint32_t log_item_id, // SAUDIO_LOGITEM_*
|
||||
const char* message_or_null, // a message string, may be nullptr in release mode
|
||||
uint32_t line_nr, // line number in sokol_audio.h
|
||||
const char* filename_or_null, // source filename, may be nullptr in release mode
|
||||
void* user_data)
|
||||
{
|
||||
...
|
||||
}
|
||||
|
||||
...and then setup sokol-audio like this:
|
||||
|
||||
saudio_setup(&(saudio_desc){
|
||||
.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 "core:c"
|
||||
|
||||
_ :: c
|
||||
|
||||
SOKOL_DEBUG :: #config(SOKOL_DEBUG, ODIN_DEBUG)
|
||||
|
||||
DEBUG :: #config(SOKOL_AUDIO_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_audio_clib { "../sokol_dll_windows_x64_gl_debug.lib" } }
|
||||
else { foreign import sokol_audio_clib { "../sokol_dll_windows_x64_gl_release.lib" } }
|
||||
} else {
|
||||
when DEBUG { foreign import sokol_audio_clib { "../sokol_dll_windows_x64_d3d11_debug.lib" } }
|
||||
else { foreign import sokol_audio_clib { "../sokol_dll_windows_x64_d3d11_release.lib" } }
|
||||
}
|
||||
} else {
|
||||
when USE_GL {
|
||||
when DEBUG { foreign import sokol_audio_clib { "sokol_audio_windows_x64_gl_debug.lib" } }
|
||||
else { foreign import sokol_audio_clib { "sokol_audio_windows_x64_gl_release.lib" } }
|
||||
} else {
|
||||
when DEBUG { foreign import sokol_audio_clib { "sokol_audio_windows_x64_d3d11_debug.lib" } }
|
||||
else { foreign import sokol_audio_clib { "sokol_audio_windows_x64_d3d11_release.lib" } }
|
||||
}
|
||||
}
|
||||
} else when ODIN_OS == .Darwin {
|
||||
when USE_DLL {
|
||||
when USE_GL && ODIN_ARCH == .arm64 && DEBUG { foreign import sokol_audio_clib { "../dylib/sokol_dylib_macos_arm64_gl_debug.dylib" } }
|
||||
else when USE_GL && ODIN_ARCH == .arm64 && !DEBUG { foreign import sokol_audio_clib { "../dylib/sokol_dylib_macos_arm64_gl_release.dylib" } }
|
||||
else when USE_GL && ODIN_ARCH == .amd64 && DEBUG { foreign import sokol_audio_clib { "../dylib/sokol_dylib_macos_x64_gl_debug.dylib" } }
|
||||
else when USE_GL && ODIN_ARCH == .amd64 && !DEBUG { foreign import sokol_audio_clib { "../dylib/sokol_dylib_macos_x64_gl_release.dylib" } }
|
||||
else when !USE_GL && ODIN_ARCH == .arm64 && DEBUG { foreign import sokol_audio_clib { "../dylib/sokol_dylib_macos_arm64_metal_debug.dylib" } }
|
||||
else when !USE_GL && ODIN_ARCH == .arm64 && !DEBUG { foreign import sokol_audio_clib { "../dylib/sokol_dylib_macos_arm64_metal_release.dylib" } }
|
||||
else when !USE_GL && ODIN_ARCH == .amd64 && DEBUG { foreign import sokol_audio_clib { "../dylib/sokol_dylib_macos_x64_metal_debug.dylib" } }
|
||||
else when !USE_GL && ODIN_ARCH == .amd64 && !DEBUG { foreign import sokol_audio_clib { "../dylib/sokol_dylib_macos_x64_metal_release.dylib" } }
|
||||
} else {
|
||||
when USE_GL {
|
||||
when ODIN_ARCH == .arm64 {
|
||||
when DEBUG { foreign import sokol_audio_clib { "sokol_audio_macos_arm64_gl_debug.a", "system:AudioToolbox.framework" } }
|
||||
else { foreign import sokol_audio_clib { "sokol_audio_macos_arm64_gl_release.a", "system:AudioToolbox.framework" } }
|
||||
} else {
|
||||
when DEBUG { foreign import sokol_audio_clib { "sokol_audio_macos_x64_gl_debug.a", "system:AudioToolbox.framework" } }
|
||||
else { foreign import sokol_audio_clib { "sokol_audio_macos_x64_gl_release.a", "system:AudioToolbox.framework" } }
|
||||
}
|
||||
} else {
|
||||
when ODIN_ARCH == .arm64 {
|
||||
when DEBUG { foreign import sokol_audio_clib { "sokol_audio_macos_arm64_metal_debug.a", "system:AudioToolbox.framework" } }
|
||||
else { foreign import sokol_audio_clib { "sokol_audio_macos_arm64_metal_release.a", "system:AudioToolbox.framework" } }
|
||||
} else {
|
||||
when DEBUG { foreign import sokol_audio_clib { "sokol_audio_macos_x64_metal_debug.a", "system:AudioToolbox.framework" } }
|
||||
else { foreign import sokol_audio_clib { "sokol_audio_macos_x64_metal_release.a", "system:AudioToolbox.framework" } }
|
||||
}
|
||||
}
|
||||
}
|
||||
} else when ODIN_OS == .Linux {
|
||||
when USE_DLL {
|
||||
when DEBUG { foreign import sokol_audio_clib { "sokol_audio_linux_x64_gl_debug.so", "system:asound", "system:dl", "system:pthread" } }
|
||||
else { foreign import sokol_audio_clib { "sokol_audio_linux_x64_gl_release.so", "system:asound", "system:dl", "system:pthread" } }
|
||||
} else {
|
||||
when DEBUG { foreign import sokol_audio_clib { "sokol_audio_linux_x64_gl_debug.a", "system:asound", "system:dl", "system:pthread" } }
|
||||
else { foreign import sokol_audio_clib { "sokol_audio_linux_x64_gl_release.a", "system:asound", "system:dl", "system:pthread" } }
|
||||
}
|
||||
} else when ODIN_ARCH == .wasm32 || ODIN_ARCH == .wasm64p32 {
|
||||
// Feed sokol_audio_wasm_gl_debug.a or sokol_audio_wasm_gl_release.a into emscripten compiler.
|
||||
foreign import sokol_audio_clib { "env.o" }
|
||||
} else {
|
||||
#panic("This OS is currently not supported")
|
||||
}
|
||||
|
||||
@(default_calling_convention="c", link_prefix="saudio_")
|
||||
foreign sokol_audio_clib {
|
||||
// setup sokol-audio
|
||||
setup :: proc(#by_ptr desc: Desc) ---
|
||||
// shutdown sokol-audio
|
||||
shutdown :: proc() ---
|
||||
// true after setup if audio backend was successfully initialized
|
||||
isvalid :: proc() -> bool ---
|
||||
// return the saudio_desc.user_data pointer
|
||||
userdata :: proc() -> rawptr ---
|
||||
// return a copy of the original saudio_desc struct
|
||||
query_desc :: proc() -> Desc ---
|
||||
// actual sample rate
|
||||
sample_rate :: proc() -> c.int ---
|
||||
// return actual backend buffer size in number of frames
|
||||
buffer_frames :: proc() -> c.int ---
|
||||
// actual number of channels
|
||||
channels :: proc() -> c.int ---
|
||||
// return true if audio context is currently suspended (only in WebAudio backend, all other backends return false)
|
||||
suspended :: proc() -> bool ---
|
||||
// get current number of frames to fill packet queue
|
||||
expect :: proc() -> c.int ---
|
||||
// push sample frames from main thread, returns number of frames actually pushed
|
||||
push :: proc(frames: ^f32, #any_int num_frames: c.int) -> c.int ---
|
||||
}
|
||||
|
||||
Log_Item :: enum i32 {
|
||||
OK,
|
||||
MALLOC_FAILED,
|
||||
ALSA_SND_PCM_OPEN_FAILED,
|
||||
ALSA_FLOAT_SAMPLES_NOT_SUPPORTED,
|
||||
ALSA_REQUESTED_BUFFER_SIZE_NOT_SUPPORTED,
|
||||
ALSA_REQUESTED_CHANNEL_COUNT_NOT_SUPPORTED,
|
||||
ALSA_SND_PCM_HW_PARAMS_SET_RATE_NEAR_FAILED,
|
||||
ALSA_SND_PCM_HW_PARAMS_FAILED,
|
||||
ALSA_PTHREAD_CREATE_FAILED,
|
||||
WASAPI_CREATE_EVENT_FAILED,
|
||||
WASAPI_CREATE_DEVICE_ENUMERATOR_FAILED,
|
||||
WASAPI_GET_DEFAULT_AUDIO_ENDPOINT_FAILED,
|
||||
WASAPI_DEVICE_ACTIVATE_FAILED,
|
||||
WASAPI_AUDIO_CLIENT_INITIALIZE_FAILED,
|
||||
WASAPI_AUDIO_CLIENT_GET_BUFFER_SIZE_FAILED,
|
||||
WASAPI_AUDIO_CLIENT_GET_SERVICE_FAILED,
|
||||
WASAPI_AUDIO_CLIENT_SET_EVENT_HANDLE_FAILED,
|
||||
WASAPI_CREATE_THREAD_FAILED,
|
||||
AAUDIO_STREAMBUILDER_OPEN_STREAM_FAILED,
|
||||
AAUDIO_PTHREAD_CREATE_FAILED,
|
||||
AAUDIO_RESTARTING_STREAM_AFTER_ERROR,
|
||||
USING_AAUDIO_BACKEND,
|
||||
AAUDIO_CREATE_STREAMBUILDER_FAILED,
|
||||
COREAUDIO_NEW_OUTPUT_FAILED,
|
||||
COREAUDIO_ALLOCATE_BUFFER_FAILED,
|
||||
COREAUDIO_START_FAILED,
|
||||
BACKEND_BUFFER_SIZE_ISNT_MULTIPLE_OF_PACKET_SIZE,
|
||||
}
|
||||
|
||||
/*
|
||||
saudio_logger
|
||||
|
||||
Used in saudio_desc to provide a custom logging and error reporting
|
||||
callback to sokol-audio.
|
||||
*/
|
||||
Logger :: struct {
|
||||
func : proc "c" (a0: cstring, a1: u32, a2: u32, a3: cstring, a4: u32, a5: cstring, a6: rawptr),
|
||||
user_data : rawptr,
|
||||
}
|
||||
|
||||
/*
|
||||
saudio_allocator
|
||||
|
||||
Used in saudio_desc to provide custom memory-alloc and -free functions
|
||||
to sokol_audio.h. If memory management should be overridden, both the
|
||||
alloc_fn and free_fn 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 {
|
||||
sample_rate : c.int,
|
||||
num_channels : c.int,
|
||||
buffer_frames : c.int,
|
||||
packet_frames : c.int,
|
||||
num_packets : c.int,
|
||||
stream_cb : proc "c" (a0: ^f32, a1: c.int, a2: c.int),
|
||||
stream_userdata_cb : proc "c" (a0: ^f32, a1: c.int, a2: c.int, a3: rawptr),
|
||||
user_data : rawptr,
|
||||
allocator : Allocator,
|
||||
logger : Logger,
|
||||
}
|
||||
|
49
thirdparty/sokol/build_clibs_linux.sh
vendored
Normal file
49
thirdparty/sokol/build_clibs_linux.sh
vendored
Normal file
@@ -0,0 +1,49 @@
|
||||
set -e
|
||||
|
||||
build_lib_x64_release() {
|
||||
src=$1
|
||||
dst=$2
|
||||
backend=$3
|
||||
echo $dst
|
||||
# static
|
||||
cc -pthread -c -O2 -DNDEBUG -DIMPL -D$backend c/$src.c
|
||||
ar rcs $dst.a $src.o
|
||||
# shared
|
||||
cc -pthread -shared -O2 -fPIC -DNDEBUG -DIMPL -D$backend -o $dst.so c/$src.c
|
||||
}
|
||||
|
||||
build_lib_x64_debug() {
|
||||
src=$1
|
||||
dst=$2
|
||||
backend=$3
|
||||
echo $dst
|
||||
# static
|
||||
cc -pthread -c -g -DIMPL -D$backend c/$src.c
|
||||
ar rcs $dst.a $src.o
|
||||
# shared
|
||||
cc -pthread -shared -g -fPIC -DIMPL -D$backend -o $dst.so c/$src.c
|
||||
}
|
||||
|
||||
# x64 + GL + Release
|
||||
build_lib_x64_release sokol_log log/sokol_log_linux_x64_gl_release SOKOL_GLCORE
|
||||
build_lib_x64_release sokol_gfx gfx/sokol_gfx_linux_x64_gl_release SOKOL_GLCORE
|
||||
build_lib_x64_release sokol_app app/sokol_app_linux_x64_gl_release SOKOL_GLCORE
|
||||
build_lib_x64_release sokol_glue glue/sokol_glue_linux_x64_gl_release SOKOL_GLCORE
|
||||
build_lib_x64_release sokol_time time/sokol_time_linux_x64_gl_release SOKOL_GLCORE
|
||||
build_lib_x64_release sokol_audio audio/sokol_audio_linux_x64_gl_release SOKOL_GLCORE
|
||||
build_lib_x64_release sokol_debugtext debugtext/sokol_debugtext_linux_x64_gl_release SOKOL_GLCORE
|
||||
build_lib_x64_release sokol_shape shape/sokol_shape_linux_x64_gl_release SOKOL_GLCORE
|
||||
build_lib_x64_release sokol_gl gl/sokol_gl_linux_x64_gl_release SOKOL_GLCORE
|
||||
|
||||
# x64 + GL + Debug
|
||||
build_lib_x64_debug sokol_log log/sokol_log_linux_x64_gl_debug SOKOL_GLCORE
|
||||
build_lib_x64_debug sokol_gfx gfx/sokol_gfx_linux_x64_gl_debug SOKOL_GLCORE
|
||||
build_lib_x64_debug sokol_app app/sokol_app_linux_x64_gl_debug SOKOL_GLCORE
|
||||
build_lib_x64_debug sokol_glue glue/sokol_glue_linux_x64_gl_debug SOKOL_GLCORE
|
||||
build_lib_x64_debug sokol_time time/sokol_time_linux_x64_gl_debug SOKOL_GLCORE
|
||||
build_lib_x64_debug sokol_audio audio/sokol_audio_linux_x64_gl_debug SOKOL_GLCORE
|
||||
build_lib_x64_debug sokol_debugtext debugtext/sokol_debugtext_linux_x64_gl_debug SOKOL_GLCORE
|
||||
build_lib_x64_debug sokol_shape shape/sokol_shape_linux_x64_gl_debug SOKOL_GLCORE
|
||||
build_lib_x64_debug sokol_gl gl/sokol_gl_linux_x64_gl_debug SOKOL_GLCORE
|
||||
|
||||
rm *.o
|
127
thirdparty/sokol/build_clibs_macos.sh
vendored
Normal file
127
thirdparty/sokol/build_clibs_macos.sh
vendored
Normal file
@@ -0,0 +1,127 @@
|
||||
set -e
|
||||
|
||||
build_lib_arm64_release() {
|
||||
src=$1
|
||||
dst=$2
|
||||
backend=$3
|
||||
echo $dst
|
||||
MACOSX_DEPLOYMENT_TARGET=10.13 clang -c -O2 -x objective-c -arch arm64 -DNDEBUG -DIMPL -D$backend c/$src.c
|
||||
ar rcs $dst.a $src.o
|
||||
}
|
||||
|
||||
build_lib_arm64_debug() {
|
||||
src=$1
|
||||
dst=$2
|
||||
backend=$3
|
||||
echo $dst
|
||||
MACOSX_DEPLOYMENT_TARGET=10.13 clang -c -g -x objective-c -arch arm64 -DIMPL -D$backend c/$src.c
|
||||
ar rcs $dst.a $src.o
|
||||
}
|
||||
|
||||
build_lib_x64_release() {
|
||||
src=$1
|
||||
dst=$2
|
||||
backend=$3
|
||||
echo $dst
|
||||
MACOSX_DEPLOYMENT_TARGET=10.13 clang -c -O2 -x objective-c -arch x86_64 -DNDEBUG -DIMPL -D$backend c/$src.c
|
||||
ar rcs $dst.a $src.o
|
||||
}
|
||||
|
||||
build_lib_x64_debug() {
|
||||
src=$1
|
||||
dst=$2
|
||||
backend=$3
|
||||
echo $dst
|
||||
MACOSX_DEPLOYMENT_TARGET=10.13 clang -c -g -x objective-c -arch x86_64 -DIMPL -D$backend c/$src.c
|
||||
ar rcs $dst.a $src.o
|
||||
}
|
||||
|
||||
# ARM + Metal + Release
|
||||
build_lib_arm64_release sokol_log log/sokol_log_macos_arm64_metal_release SOKOL_METAL
|
||||
build_lib_arm64_release sokol_gfx gfx/sokol_gfx_macos_arm64_metal_release SOKOL_METAL
|
||||
build_lib_arm64_release sokol_app app/sokol_app_macos_arm64_metal_release SOKOL_METAL
|
||||
build_lib_arm64_release sokol_glue glue/sokol_glue_macos_arm64_metal_release SOKOL_METAL
|
||||
build_lib_arm64_release sokol_time time/sokol_time_macos_arm64_metal_release SOKOL_METAL
|
||||
build_lib_arm64_release sokol_audio audio/sokol_audio_macos_arm64_metal_release SOKOL_METAL
|
||||
build_lib_arm64_release sokol_debugtext debugtext/sokol_debugtext_macos_arm64_metal_release SOKOL_METAL
|
||||
build_lib_arm64_release sokol_shape shape/sokol_shape_macos_arm64_metal_release SOKOL_METAL
|
||||
build_lib_arm64_release sokol_gl gl/sokol_gl_macos_arm64_metal_release SOKOL_METAL
|
||||
|
||||
# ARM + Metal + Debug
|
||||
build_lib_arm64_debug sokol_log log/sokol_log_macos_arm64_metal_debug SOKOL_METAL
|
||||
build_lib_arm64_debug sokol_gfx gfx/sokol_gfx_macos_arm64_metal_debug SOKOL_METAL
|
||||
build_lib_arm64_debug sokol_app app/sokol_app_macos_arm64_metal_debug SOKOL_METAL
|
||||
build_lib_arm64_debug sokol_glue glue/sokol_glue_macos_arm64_metal_debug SOKOL_METAL
|
||||
build_lib_arm64_debug sokol_time time/sokol_time_macos_arm64_metal_debug SOKOL_METAL
|
||||
build_lib_arm64_debug sokol_audio audio/sokol_audio_macos_arm64_metal_debug SOKOL_METAL
|
||||
build_lib_arm64_debug sokol_debugtext debugtext/sokol_debugtext_macos_arm64_metal_debug SOKOL_METAL
|
||||
build_lib_arm64_debug sokol_shape shape/sokol_shape_macos_arm64_metal_debug SOKOL_METAL
|
||||
build_lib_arm64_debug sokol_gl gl/sokol_gl_macos_arm64_metal_debug SOKOL_METAL
|
||||
|
||||
# x64 + Metal + Release
|
||||
build_lib_x64_release sokol_log log/sokol_log_macos_x64_metal_release SOKOL_METAL
|
||||
build_lib_x64_release sokol_gfx gfx/sokol_gfx_macos_x64_metal_release SOKOL_METAL
|
||||
build_lib_x64_release sokol_app app/sokol_app_macos_x64_metal_release SOKOL_METAL
|
||||
build_lib_x64_release sokol_glue glue/sokol_glue_macos_x64_metal_release SOKOL_METAL
|
||||
build_lib_x64_release sokol_time time/sokol_time_macos_x64_metal_release SOKOL_METAL
|
||||
build_lib_x64_release sokol_audio audio/sokol_audio_macos_x64_metal_release SOKOL_METAL
|
||||
build_lib_x64_release sokol_debugtext debugtext/sokol_debugtext_macos_x64_metal_release SOKOL_METAL
|
||||
build_lib_x64_release sokol_shape shape/sokol_shape_macos_x64_metal_release SOKOL_METAL
|
||||
build_lib_x64_release sokol_gl gl/sokol_gl_macos_x64_metal_release SOKOL_METAL
|
||||
|
||||
# x64 + Metal + Debug
|
||||
build_lib_x64_debug sokol_log log/sokol_log_macos_x64_metal_debug SOKOL_METAL
|
||||
build_lib_x64_debug sokol_gfx gfx/sokol_gfx_macos_x64_metal_debug SOKOL_METAL
|
||||
build_lib_x64_debug sokol_app app/sokol_app_macos_x64_metal_debug SOKOL_METAL
|
||||
build_lib_x64_debug sokol_glue glue/sokol_glue_macos_x64_metal_debug SOKOL_METAL
|
||||
build_lib_x64_debug sokol_time time/sokol_time_macos_x64_metal_debug SOKOL_METAL
|
||||
build_lib_x64_debug sokol_audio audio/sokol_audio_macos_x64_metal_debug SOKOL_METAL
|
||||
build_lib_x64_debug sokol_debugtext debugtext/sokol_debugtext_macos_x64_metal_debug SOKOL_METAL
|
||||
build_lib_x64_debug sokol_shape shape/sokol_shape_macos_x64_metal_debug SOKOL_METAL
|
||||
build_lib_x64_debug sokol_gl gl/sokol_gl_macos_x64_metal_debug SOKOL_METAL
|
||||
|
||||
# ARM + GL + Release
|
||||
build_lib_arm64_release sokol_log log/sokol_log_macos_arm64_gl_release SOKOL_GLCORE
|
||||
build_lib_arm64_release sokol_gfx gfx/sokol_gfx_macos_arm64_gl_release SOKOL_GLCORE
|
||||
build_lib_arm64_release sokol_app app/sokol_app_macos_arm64_gl_release SOKOL_GLCORE
|
||||
build_lib_arm64_release sokol_glue glue/sokol_glue_macos_arm64_gl_release SOKOL_GLCORE
|
||||
build_lib_arm64_release sokol_time time/sokol_time_macos_arm64_gl_release SOKOL_GLCORE
|
||||
build_lib_arm64_release sokol_audio audio/sokol_audio_macos_arm64_gl_release SOKOL_GLCORE
|
||||
build_lib_arm64_release sokol_debugtext debugtext/sokol_debugtext_macos_arm64_gl_release SOKOL_GLCORE
|
||||
build_lib_arm64_release sokol_shape shape/sokol_shape_macos_arm64_gl_release SOKOL_GLCORE
|
||||
build_lib_arm64_release sokol_gl gl/sokol_gl_macos_arm64_gl_release SOKOL_GLCORE
|
||||
|
||||
# ARM + GL + Debug
|
||||
build_lib_arm64_debug sokol_log log/sokol_log_macos_arm64_gl_debug SOKOL_GLCORE
|
||||
build_lib_arm64_debug sokol_gfx gfx/sokol_gfx_macos_arm64_gl_debug SOKOL_GLCORE
|
||||
build_lib_arm64_debug sokol_app app/sokol_app_macos_arm64_gl_debug SOKOL_GLCORE
|
||||
build_lib_arm64_debug sokol_glue glue/sokol_glue_macos_arm64_gl_debug SOKOL_GLCORE
|
||||
build_lib_arm64_debug sokol_time time/sokol_time_macos_arm64_gl_debug SOKOL_GLCORE
|
||||
build_lib_arm64_debug sokol_audio audio/sokol_audio_macos_arm64_gl_debug SOKOL_GLCORE
|
||||
build_lib_arm64_debug sokol_debugtext debugtext/sokol_debugtext_macos_arm64_gl_debug SOKOL_GLCORE
|
||||
build_lib_arm64_debug sokol_shape shape/sokol_shape_macos_arm64_gl_debug SOKOL_GLCORE
|
||||
build_lib_arm64_debug sokol_gl gl/sokol_gl_macos_arm64_gl_debug SOKOL_GLCORE
|
||||
|
||||
# x64 + GL + Release
|
||||
build_lib_x64_release sokol_log log/sokol_log_macos_x64_gl_release SOKOL_GLCORE
|
||||
build_lib_x64_release sokol_gfx gfx/sokol_gfx_macos_x64_gl_release SOKOL_GLCORE
|
||||
build_lib_x64_release sokol_app app/sokol_app_macos_x64_gl_release SOKOL_GLCORE
|
||||
build_lib_x64_release sokol_glue glue/sokol_glue_macos_x64_gl_release SOKOL_GLCORE
|
||||
build_lib_x64_release sokol_time time/sokol_time_macos_x64_gl_release SOKOL_GLCORE
|
||||
build_lib_x64_release sokol_audio audio/sokol_audio_macos_x64_gl_release SOKOL_GLCORE
|
||||
build_lib_x64_release sokol_debugtext debugtext/sokol_debugtext_macos_x64_gl_release SOKOL_GLCORE
|
||||
build_lib_x64_release sokol_shape shape/sokol_shape_macos_x64_gl_release SOKOL_GLCORE
|
||||
build_lib_x64_release sokol_gl gl/sokol_gl_macos_x64_gl_release SOKOL_GLCORE
|
||||
|
||||
# x64 + GL + Debug
|
||||
build_lib_x64_debug sokol_log log/sokol_log_macos_x64_gl_debug SOKOL_GLCORE
|
||||
build_lib_x64_debug sokol_gfx gfx/sokol_gfx_macos_x64_gl_debug SOKOL_GLCORE
|
||||
build_lib_x64_debug sokol_app app/sokol_app_macos_x64_gl_debug SOKOL_GLCORE
|
||||
build_lib_x64_debug sokol_glue glue/sokol_glue_macos_x64_gl_debug SOKOL_GLCORE
|
||||
build_lib_x64_debug sokol_time time/sokol_time_macos_x64_gl_debug SOKOL_GLCORE
|
||||
build_lib_x64_debug sokol_audio audio/sokol_audio_macos_x64_gl_debug SOKOL_GLCORE
|
||||
build_lib_x64_debug sokol_debugtext debugtext/sokol_debugtext_macos_x64_gl_debug SOKOL_GLCORE
|
||||
build_lib_x64_debug sokol_shape shape/sokol_shape_macos_x64_gl_debug SOKOL_GLCORE
|
||||
build_lib_x64_debug sokol_gl gl/sokol_gl_macos_x64_gl_debug SOKOL_GLCORE
|
||||
|
||||
rm *.o
|
50
thirdparty/sokol/build_clibs_macos_dylib.sh
vendored
Normal file
50
thirdparty/sokol/build_clibs_macos_dylib.sh
vendored
Normal file
@@ -0,0 +1,50 @@
|
||||
set -e
|
||||
|
||||
FRAMEWORKS_METAL="-framework Metal -framework MetalKit"
|
||||
FRAMEWORKS_OPENGL="-framework OpenGL"
|
||||
FRAMEWORKS_CORE="-framework Foundation -framework CoreGraphics -framework Cocoa -framework QuartzCore -framework CoreAudio -framework AudioToolbox"
|
||||
|
||||
build_lib_release() {
|
||||
src=$1
|
||||
dst=$2
|
||||
backend=$3
|
||||
arch=$4
|
||||
frameworks=""
|
||||
if [ $backend = "SOKOL_METAL" ]; then
|
||||
frameworks="${frameworks} ${FRAMEWORKS_METAL}"
|
||||
else
|
||||
frameworks="${frameworks} ${FRAMEWORKS_OPENGL}"
|
||||
fi
|
||||
echo $dst
|
||||
MACOSX_DEPLOYMENT_TARGET=10.13 clang -c -O2 -x objective-c -arch $arch -DNDEBUG -DIMPL -D$backend c/$src.c
|
||||
clang -dynamiclib -arch $arch $FRAMEWORKS_CORE $frameworks -o $dst.dylib $src.o $dep
|
||||
}
|
||||
|
||||
build_lib_debug() {
|
||||
src=$1
|
||||
dst=$2
|
||||
backend=$3
|
||||
arch=$4
|
||||
frameworks=""
|
||||
if [ $backend = "SOKOL_METAL" ]; then
|
||||
frameworks="${frameworks} ${FRAMEWORKS_METAL}"
|
||||
else
|
||||
frameworks="${frameworks} ${FRAMEWORKS_OPENGL}"
|
||||
fi
|
||||
echo $dst
|
||||
MACOSX_DEPLOYMENT_TARGET=10.13 clang -c -g -x objective-c -arch $arch -DIMPL -D$backend c/$src.c
|
||||
clang -dynamiclib -arch $arch $FRAMEWORKS_CORE $frameworks -o $dst.dylib $src.o $dep
|
||||
}
|
||||
|
||||
mkdir -p dylib
|
||||
|
||||
build_lib_release sokol dylib/sokol_dylib_macos_arm64_metal_release SOKOL_METAL arm64
|
||||
build_lib_debug sokol dylib/sokol_dylib_macos_arm64_metal_debug SOKOL_METAL arm64
|
||||
build_lib_release sokol dylib/sokol_dylib_macos_x64_metal_release SOKOL_METAL x86_64
|
||||
build_lib_debug sokol dylib/sokol_dylib_macos_x64_metal_debug SOKOL_METAL x86_64
|
||||
build_lib_release sokol dylib/sokol_dylib_macos_arm64_gl_release SOKOL_GLCORE arm64
|
||||
build_lib_debug sokol dylib/sokol_dylib_macos_arm64_gl_debug SOKOL_GLCORE arm64
|
||||
build_lib_release sokol dylib/sokol_dylib_macos_x64_gl_release SOKOL_GLCORE x86_64
|
||||
build_lib_debug sokol dylib/sokol_dylib_macos_x64_gl_debug SOKOL_GLCORE x86_64
|
||||
|
||||
rm *.o
|
19
thirdparty/sokol/build_clibs_wasm.bat
vendored
Normal file
19
thirdparty/sokol/build_clibs_wasm.bat
vendored
Normal file
@@ -0,0 +1,19 @@
|
||||
@echo off
|
||||
|
||||
set sources=log app gfx glue time audio debugtext shape gl
|
||||
|
||||
REM Debug
|
||||
for %%s in (%sources%) do (
|
||||
echo %%s\sokol_%%s_wasm_gl_debug.a
|
||||
call emcc -c -g -DIMPL -DSOKOL_GLES3 c\sokol_%%s.c
|
||||
call emar rcs %%s\sokol_%%s_wasm_gl_debug.a sokol_%%s.o
|
||||
del sokol_%%s.o
|
||||
)
|
||||
|
||||
REM Release
|
||||
for %%s in (%sources%) do (
|
||||
echo %%s\sokol_%%s_wasm_gl_release.a
|
||||
call emcc -c -O2 -DNDEBUG -DIMPL -DSOKOL_GLES3 c\sokol_%%s.c
|
||||
call emar rcs %%s\sokol_%%s_wasm_gl_release.a sokol_%%s.o
|
||||
del sokol_%%s.o
|
||||
)
|
20
thirdparty/sokol/build_clibs_wasm.sh
vendored
Normal file
20
thirdparty/sokol/build_clibs_wasm.sh
vendored
Normal file
@@ -0,0 +1,20 @@
|
||||
#!/bin/bash
|
||||
set -e
|
||||
|
||||
declare -a libs=("log" "gfx" "app" "glue" "time" "audio" "debugtext" "shape" "gl")
|
||||
|
||||
for l in "${libs[@]}"
|
||||
do
|
||||
echo "${l}/sokol_${l}_wasm_gl_debug.a"
|
||||
emcc -c -g -DIMPL -DSOKOL_GLES3 c/sokol_$l.c
|
||||
emar rcs $l/sokol_${l}_wasm_gl_debug.a sokol_$l.o
|
||||
rm sokol_$l.o
|
||||
done
|
||||
|
||||
for l in "${libs[@]}"
|
||||
do
|
||||
echo "${l}/sokol_${l}_wasm_gl_release.a"
|
||||
emcc -c -O2 -DNDEBUG -DIMPL -DSOKOL_GLES3 c/sokol_$l.c
|
||||
emar rcs $l/sokol_${l}_wasm_gl_release.a sokol_$l.o
|
||||
rm sokol_$l.o
|
||||
done
|
45
thirdparty/sokol/build_clibs_windows.cmd
vendored
Normal file
45
thirdparty/sokol/build_clibs_windows.cmd
vendored
Normal file
@@ -0,0 +1,45 @@
|
||||
@echo off
|
||||
|
||||
set sources=log app gfx glue time audio debugtext shape gl
|
||||
|
||||
REM D3D11 Debug
|
||||
for %%s in (%sources%) do (
|
||||
cl /c /D_DEBUG /DIMPL /DSOKOL_D3D11 c\sokol_%%s.c /Z7
|
||||
lib /OUT:%%s\sokol_%%s_windows_x64_d3d11_debug.lib sokol_%%s.obj
|
||||
del sokol_%%s.obj
|
||||
)
|
||||
|
||||
REM D3D11 Release
|
||||
for %%s in (%sources%) do (
|
||||
cl /c /O2 /DNDEBUG /DIMPL /DSOKOL_D3D11 c\sokol_%%s.c
|
||||
lib /OUT:%%s\sokol_%%s_windows_x64_d3d11_release.lib sokol_%%s.obj
|
||||
del sokol_%%s.obj
|
||||
)
|
||||
|
||||
REM GL Debug
|
||||
for %%s in (%sources%) do (
|
||||
cl /c /D_DEBUG /DIMPL /DSOKOL_GLCORE c\sokol_%%s.c /Z7
|
||||
lib /OUT:%%s\sokol_%%s_windows_x64_gl_debug.lib sokol_%%s.obj
|
||||
del sokol_%%s.obj
|
||||
)
|
||||
|
||||
REM GL Release
|
||||
for %%s in (%sources%) do (
|
||||
cl /c /O2 /DNDEBUG /DIMPL /DSOKOL_GLCORE c\sokol_%%s.c
|
||||
lib /OUT:%%s\sokol_%%s_windows_x64_gl_release.lib sokol_%%s.obj
|
||||
del sokol_%%s.obj
|
||||
)
|
||||
|
||||
REM D3D11 Debug DLL
|
||||
cl /D_DEBUG /DIMPL /DSOKOL_DLL /DSOKOL_D3D11 c\sokol.c /Z7 /LDd /MDd /DLL /Fe:sokol_dll_windows_x64_d3d11_debug.dll /link /INCREMENTAL:NO
|
||||
|
||||
REM D3D11 Release DLL
|
||||
cl /D_DEBUG /DIMPL /DSOKOL_DLL /DSOKOL_D3D11 c\sokol.c /LD /MD /DLL /Fe:sokol_dll_windows_x64_d3d11_release.dll /link /INCREMENTAL:NO
|
||||
|
||||
REM GL Debug DLL
|
||||
cl /D_DEBUG /DIMPL /DSOKOL_DLL /DSOKOL_GLCORE c\sokol.c /Z7 /LDd /MDd /DLL /Fe:sokol_dll_windows_x64_gl_debug.dll /link /INCREMENTAL:NO
|
||||
|
||||
REM GL Release DLL
|
||||
cl /D_DEBUG /DIMPL /DSOKOL_DLL /DSOKOL_GLCORE c\sokol.c /LD /MD /DLL /Fe:sokol_dll_windows_x64_gl_release.dll /link /INCREMENTAL:NO
|
||||
|
||||
del sokol.obj
|
30
thirdparty/sokol/build_shaders_macos.sh
vendored
Normal file
30
thirdparty/sokol/build_shaders_macos.sh
vendored
Normal file
@@ -0,0 +1,30 @@
|
||||
set -e
|
||||
|
||||
sokol_tools_root=../sokol-tools-bin
|
||||
|
||||
build_shader() {
|
||||
name=$1
|
||||
dir=examples/$name
|
||||
if [[ $(arch) =~ "arm64" ]]
|
||||
then
|
||||
shdc=$sokol_tools_root/bin/osx_arm64/sokol-shdc
|
||||
else
|
||||
shdc=$sokol_tools_root/bin/osx/sokol-shdc
|
||||
fi
|
||||
echo $dir
|
||||
$shdc -i $dir/shader.glsl -o $dir/shader.odin -l glsl430:metal_macos:hlsl5 -f sokol_odin
|
||||
}
|
||||
|
||||
build_shader blend
|
||||
build_shader bufferoffsets
|
||||
build_shader cube
|
||||
build_shader instancing
|
||||
build_shader instancing-compute
|
||||
build_shader mrt
|
||||
build_shader noninterleaved
|
||||
build_shader offscreen
|
||||
build_shader quad
|
||||
build_shader shapes
|
||||
build_shader texcube
|
||||
build_shader triangle
|
||||
build_shader vertexpull
|
16
thirdparty/sokol/c/sokol.c
vendored
Normal file
16
thirdparty/sokol/c/sokol.c
vendored
Normal file
@@ -0,0 +1,16 @@
|
||||
#if defined(IMPL)
|
||||
#define SOKOL_IMPL
|
||||
#endif
|
||||
|
||||
#include "sokol_defines.h"
|
||||
|
||||
#include "sokol_audio.h"
|
||||
#include "sokol_app.h"
|
||||
#include "sokol_gfx.h"
|
||||
#include "sokol_log.h"
|
||||
#include "sokol_time.h"
|
||||
#include "sokol_glue.h"
|
||||
|
||||
#include "sokol_gl.h"
|
||||
#include "sokol_shape.h"
|
||||
#include "sokol_debugtext.h"
|
5
thirdparty/sokol/c/sokol_app.c
vendored
Normal file
5
thirdparty/sokol/c/sokol_app.c
vendored
Normal file
@@ -0,0 +1,5 @@
|
||||
#if defined(IMPL)
|
||||
#define SOKOL_APP_IMPL
|
||||
#endif
|
||||
#include "sokol_defines.h"
|
||||
#include "sokol_app.h"
|
12437
thirdparty/sokol/c/sokol_app.h
vendored
Normal file
12437
thirdparty/sokol/c/sokol_app.h
vendored
Normal file
File diff suppressed because it is too large
Load Diff
6
thirdparty/sokol/c/sokol_audio.c
vendored
Normal file
6
thirdparty/sokol/c/sokol_audio.c
vendored
Normal file
@@ -0,0 +1,6 @@
|
||||
#if defined(IMPL)
|
||||
#define SOKOL_AUDIO_IMPL
|
||||
#endif
|
||||
#include "sokol_defines.h"
|
||||
#include "sokol_audio.h"
|
||||
|
2310
thirdparty/sokol/c/sokol_audio.h
vendored
Normal file
2310
thirdparty/sokol/c/sokol_audio.h
vendored
Normal file
File diff suppressed because it is too large
Load Diff
7
thirdparty/sokol/c/sokol_debugtext.c
vendored
Normal file
7
thirdparty/sokol/c/sokol_debugtext.c
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
#if defined(IMPL)
|
||||
#define SOKOL_DEBUGTEXT_IMPL
|
||||
#endif
|
||||
#include "sokol_defines.h"
|
||||
#include "sokol_gfx.h"
|
||||
#include "sokol_debugtext.h"
|
||||
|
4989
thirdparty/sokol/c/sokol_debugtext.h
vendored
Normal file
4989
thirdparty/sokol/c/sokol_debugtext.h
vendored
Normal file
File diff suppressed because it is too large
Load Diff
8
thirdparty/sokol/c/sokol_defines.h
vendored
Normal file
8
thirdparty/sokol/c/sokol_defines.h
vendored
Normal file
@@ -0,0 +1,8 @@
|
||||
#define SOKOL_NO_ENTRY
|
||||
#if defined(_WIN32)
|
||||
#define SOKOL_WIN32_FORCE_MAIN
|
||||
#endif
|
||||
// FIXME: macOS Zig HACK without this, some C stdlib headers throw errors
|
||||
#if defined(__APPLE__)
|
||||
#include <TargetConditionals.h>
|
||||
#endif
|
5
thirdparty/sokol/c/sokol_gfx.c
vendored
Normal file
5
thirdparty/sokol/c/sokol_gfx.c
vendored
Normal file
@@ -0,0 +1,5 @@
|
||||
#if defined(IMPL)
|
||||
#define SOKOL_GFX_IMPL
|
||||
#endif
|
||||
#include "sokol_defines.h"
|
||||
#include "sokol_gfx.h"
|
21518
thirdparty/sokol/c/sokol_gfx.h
vendored
Normal file
21518
thirdparty/sokol/c/sokol_gfx.h
vendored
Normal file
File diff suppressed because it is too large
Load Diff
6
thirdparty/sokol/c/sokol_gl.c
vendored
Normal file
6
thirdparty/sokol/c/sokol_gl.c
vendored
Normal file
@@ -0,0 +1,6 @@
|
||||
#if defined(IMPL)
|
||||
#define SOKOL_GL_IMPL
|
||||
#endif
|
||||
#include "sokol_defines.h"
|
||||
#include "sokol_gfx.h"
|
||||
#include "sokol_gl.h"
|
4811
thirdparty/sokol/c/sokol_gl.h
vendored
Normal file
4811
thirdparty/sokol/c/sokol_gl.h
vendored
Normal file
File diff suppressed because it is too large
Load Diff
7
thirdparty/sokol/c/sokol_glue.c
vendored
Normal file
7
thirdparty/sokol/c/sokol_glue.c
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
#if defined(IMPL)
|
||||
#define SOKOL_GLUE_IMPL
|
||||
#endif
|
||||
#include "sokol_defines.h"
|
||||
#include "sokol_app.h"
|
||||
#include "sokol_gfx.h"
|
||||
#include "sokol_glue.h"
|
162
thirdparty/sokol/c/sokol_glue.h
vendored
Normal file
162
thirdparty/sokol/c/sokol_glue.h
vendored
Normal file
@@ -0,0 +1,162 @@
|
||||
#if defined(SOKOL_IMPL) && !defined(SOKOL_GLUE_IMPL)
|
||||
#define SOKOL_GLUE_IMPL
|
||||
#endif
|
||||
#ifndef SOKOL_GLUE_INCLUDED
|
||||
/*
|
||||
sokol_glue.h -- glue helper functions for sokol headers
|
||||
|
||||
Project URL: https://github.com/floooh/sokol
|
||||
|
||||
Do this:
|
||||
#define SOKOL_IMPL or
|
||||
#define SOKOL_GLUE_IMPL
|
||||
before you include this file in *one* C or C++ file to create the
|
||||
implementation.
|
||||
|
||||
...optionally provide the following macros to override defaults:
|
||||
|
||||
SOKOL_ASSERT(c) - your own assert macro (default: assert(c))
|
||||
SOKOL_GLUE_API_DECL - public function declaration prefix (default: extern)
|
||||
SOKOL_API_DECL - same as SOKOL_GLUE_API_DECL
|
||||
SOKOL_API_IMPL - public function implementation prefix (default: -)
|
||||
|
||||
If sokol_glue.h is compiled as a DLL, define the following before
|
||||
including the declaration or implementation:
|
||||
|
||||
SOKOL_DLL
|
||||
|
||||
On Windows, SOKOL_DLL will define SOKOL_GLUE_API_DECL as __declspec(dllexport)
|
||||
or __declspec(dllimport) as needed.
|
||||
|
||||
OVERVIEW
|
||||
========
|
||||
sokol_glue.h provides glue helper functions between sokol_gfx.h and sokol_app.h,
|
||||
so that sokol_gfx.h doesn't need to depend on sokol_app.h but can be
|
||||
used with different window system glue libraries.
|
||||
|
||||
PROVIDED FUNCTIONS
|
||||
==================
|
||||
|
||||
sg_environment sglue_environment(void)
|
||||
|
||||
Returns an sg_environment struct initialized by calling sokol_app.h
|
||||
functions. Use this in the sg_setup() call like this:
|
||||
|
||||
sg_setup(&(sg_desc){
|
||||
.environment = sglue_environment(),
|
||||
...
|
||||
});
|
||||
|
||||
sg_swapchain sglue_swapchain(void)
|
||||
|
||||
Returns an sg_swapchain struct initialized by calling sokol_app.h
|
||||
functions. Use this in sg_begin_pass() for a 'swapchain pass' like
|
||||
this:
|
||||
|
||||
sg_begin_pass(&(sg_pass){ .swapchain = sglue_swapchain(), ... });
|
||||
|
||||
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.
|
||||
*/
|
||||
#define SOKOL_GLUE_INCLUDED
|
||||
|
||||
#if defined(SOKOL_API_DECL) && !defined(SOKOL_GLUE_API_DECL)
|
||||
#define SOKOL_GLUE_API_DECL SOKOL_API_DECL
|
||||
#endif
|
||||
#ifndef SOKOL_GLUE_API_DECL
|
||||
#if defined(_WIN32) && defined(SOKOL_DLL) && defined(SOKOL_GLUE_IMPL)
|
||||
#define SOKOL_GLUE_API_DECL __declspec(dllexport)
|
||||
#elif defined(_WIN32) && defined(SOKOL_DLL)
|
||||
#define SOKOL_GLUE_API_DECL __declspec(dllimport)
|
||||
#else
|
||||
#define SOKOL_GLUE_API_DECL extern
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef SOKOL_GFX_INCLUDED
|
||||
#error "Please include sokol_gfx.h before sokol_glue.h"
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
SOKOL_GLUE_API_DECL sg_environment sglue_environment(void);
|
||||
SOKOL_GLUE_API_DECL sg_swapchain sglue_swapchain(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
#endif /* SOKOL_GLUE_INCLUDED */
|
||||
|
||||
/*-- IMPLEMENTATION ----------------------------------------------------------*/
|
||||
#ifdef SOKOL_GLUE_IMPL
|
||||
#define SOKOL_GLUE_IMPL_INCLUDED (1)
|
||||
#include <string.h> /* memset */
|
||||
|
||||
#ifndef SOKOL_APP_INCLUDED
|
||||
#error "Please include sokol_app.h before the sokol_glue.h implementation"
|
||||
#endif
|
||||
|
||||
#ifndef SOKOL_API_IMPL
|
||||
#define SOKOL_API_IMPL
|
||||
#endif
|
||||
|
||||
|
||||
SOKOL_API_IMPL sg_environment sglue_environment(void) {
|
||||
sg_environment env;
|
||||
memset(&env, 0, sizeof(env));
|
||||
env.defaults.color_format = (sg_pixel_format) sapp_color_format();
|
||||
env.defaults.depth_format = (sg_pixel_format) sapp_depth_format();
|
||||
env.defaults.sample_count = sapp_sample_count();
|
||||
env.metal.device = sapp_metal_get_device();
|
||||
env.d3d11.device = sapp_d3d11_get_device();
|
||||
env.d3d11.device_context = sapp_d3d11_get_device_context();
|
||||
env.wgpu.device = sapp_wgpu_get_device();
|
||||
return env;
|
||||
}
|
||||
|
||||
SOKOL_API_IMPL sg_swapchain sglue_swapchain(void) {
|
||||
sg_swapchain swapchain;
|
||||
memset(&swapchain, 0, sizeof(swapchain));
|
||||
swapchain.width = sapp_width();
|
||||
swapchain.height = sapp_height();
|
||||
swapchain.sample_count = sapp_sample_count();
|
||||
swapchain.color_format = (sg_pixel_format)sapp_color_format();
|
||||
swapchain.depth_format = (sg_pixel_format)sapp_depth_format();
|
||||
swapchain.metal.current_drawable = sapp_metal_get_current_drawable();
|
||||
swapchain.metal.depth_stencil_texture = sapp_metal_get_depth_stencil_texture();
|
||||
swapchain.metal.msaa_color_texture = sapp_metal_get_msaa_color_texture();
|
||||
swapchain.d3d11.render_view = sapp_d3d11_get_render_view();
|
||||
swapchain.d3d11.resolve_view = sapp_d3d11_get_resolve_view();
|
||||
swapchain.d3d11.depth_stencil_view = sapp_d3d11_get_depth_stencil_view();
|
||||
swapchain.wgpu.render_view = sapp_wgpu_get_render_view();
|
||||
swapchain.wgpu.resolve_view = sapp_wgpu_get_resolve_view();
|
||||
swapchain.wgpu.depth_stencil_view = sapp_wgpu_get_depth_stencil_view();
|
||||
swapchain.gl.framebuffer = sapp_gl_get_framebuffer();
|
||||
return swapchain;
|
||||
}
|
||||
|
||||
#endif /* SOKOL_GLUE_IMPL */
|
5
thirdparty/sokol/c/sokol_log.c
vendored
Normal file
5
thirdparty/sokol/c/sokol_log.c
vendored
Normal file
@@ -0,0 +1,5 @@
|
||||
#if defined(IMPL)
|
||||
#define SOKOL_LOG_IMPL
|
||||
#endif
|
||||
#include "sokol_defines.h"
|
||||
#include "sokol_log.h"
|
334
thirdparty/sokol/c/sokol_log.h
vendored
Normal file
334
thirdparty/sokol/c/sokol_log.h
vendored
Normal file
@@ -0,0 +1,334 @@
|
||||
#if defined(SOKOL_IMPL) && !defined(SOKOL_LOG_IMPL)
|
||||
#define SOKOL_LOG_IMPL
|
||||
#endif
|
||||
#ifndef SOKOL_LOG_INCLUDED
|
||||
/*
|
||||
sokol_log.h -- common logging callback for sokol headers
|
||||
|
||||
Project URL: https://github.com/floooh/sokol
|
||||
|
||||
Example code: https://github.com/floooh/sokol-samples
|
||||
|
||||
Do this:
|
||||
#define SOKOL_IMPL or
|
||||
#define SOKOL_LOG_IMPL
|
||||
before you include this file in *one* C or C++ file to create the
|
||||
implementation.
|
||||
|
||||
Optionally provide the following defines when building the implementation:
|
||||
|
||||
SOKOL_ASSERT(c) - your own assert macro (default: assert(c))
|
||||
SOKOL_UNREACHABLE() - a guard macro for unreachable code (default: assert(false))
|
||||
SOKOL_LOG_API_DECL - public function declaration prefix (default: extern)
|
||||
SOKOL_API_DECL - same as SOKOL_GFX_API_DECL
|
||||
SOKOL_API_IMPL - public function implementation prefix (default: -)
|
||||
|
||||
Optionally define the following for verbose output:
|
||||
|
||||
SOKOL_DEBUG - by default this is defined if _DEBUG is defined
|
||||
|
||||
|
||||
OVERVIEW
|
||||
========
|
||||
sokol_log.h provides a default logging callback for other sokol headers.
|
||||
|
||||
To use the default log callback, just include sokol_log.h and provide
|
||||
a function pointer to the 'slog_func' function when setting up the
|
||||
sokol library:
|
||||
|
||||
For instance with sokol_audio.h:
|
||||
|
||||
#include "sokol_log.h"
|
||||
...
|
||||
saudio_setup(&(saudio_desc){ .logger.func = slog_func });
|
||||
|
||||
Logging output goes to stderr and/or a platform specific logging subsystem
|
||||
(which means that in some scenarios you might see logging messages duplicated):
|
||||
|
||||
- Windows: stderr + OutputDebugStringA()
|
||||
- macOS/iOS/Linux: stderr + syslog()
|
||||
- Emscripten: console.info()/warn()/error()
|
||||
- Android: __android_log_write()
|
||||
|
||||
On Windows with sokol_app.h also note the runtime config items to make
|
||||
stdout/stderr output visible on the console for WinMain() applications
|
||||
via sapp_desc.win32_console_attach or sapp_desc.win32_console_create,
|
||||
however when running in a debugger on Windows, the logging output should
|
||||
show up on the debug output UI panel.
|
||||
|
||||
In debug mode, a log message might look like this:
|
||||
|
||||
[sspine][error][id:12] /Users/floh/projects/sokol/util/sokol_spine.h:3472:0:
|
||||
SKELETON_DESC_NO_ATLAS: no atlas object provided in sspine_skeleton_desc.atlas
|
||||
|
||||
The source path and line number is formatted like compiler errors, in some IDEs (like VSCode)
|
||||
such error messages are clickable.
|
||||
|
||||
In release mode, logging is less verbose as to not bloat the executable with string data, but you still get
|
||||
enough information to identify the type and location of an error:
|
||||
|
||||
[sspine][error][id:12][line:3472]
|
||||
|
||||
RULES FOR WRITING YOUR OWN LOGGING FUNCTION
|
||||
===========================================
|
||||
- must be re-entrant because it might be called from different threads
|
||||
- must treat **all** provided string pointers as optional (can be null)
|
||||
- don't store the string pointers, copy the string data instead
|
||||
- must not return for log level panic
|
||||
|
||||
LICENSE
|
||||
=======
|
||||
zlib/libpng license
|
||||
|
||||
Copyright (c) 2023 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.
|
||||
*/
|
||||
#define SOKOL_LOG_INCLUDED (1)
|
||||
#include <stdint.h>
|
||||
|
||||
#if defined(SOKOL_API_DECL) && !defined(SOKOL_LOG_API_DECL)
|
||||
#define SOKOL_LOG_API_DECL SOKOL_API_DECL
|
||||
#endif
|
||||
#ifndef SOKOL_LOG_API_DECL
|
||||
#if defined(_WIN32) && defined(SOKOL_DLL) && defined(SOKOL_LOG_IMPL)
|
||||
#define SOKOL_LOG_API_DECL __declspec(dllexport)
|
||||
#elif defined(_WIN32) && defined(SOKOL_DLL)
|
||||
#define SOKOL_LOG_API_DECL __declspec(dllimport)
|
||||
#else
|
||||
#define SOKOL_LOG_API_DECL extern
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*
|
||||
Plug this function into the 'logger.func' struct item when initializing any of the sokol
|
||||
headers. For instance for sokol_audio.h it would look like this:
|
||||
|
||||
saudio_setup(&(saudio_desc){
|
||||
.logger = {
|
||||
.func = slog_func
|
||||
}
|
||||
});
|
||||
*/
|
||||
SOKOL_LOG_API_DECL void slog_func(const char* tag, uint32_t log_level, uint32_t log_item, const char* message, uint32_t line_nr, const char* filename, void* user_data);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif
|
||||
#endif // SOKOL_LOG_INCLUDED
|
||||
|
||||
// ██ ███ ███ ██████ ██ ███████ ███ ███ ███████ ███ ██ ████████ █████ ████████ ██ ██████ ███ ██
|
||||
// ██ ████ ████ ██ ██ ██ ██ ████ ████ ██ ████ ██ ██ ██ ██ ██ ██ ██ ██ ████ ██
|
||||
// ██ ██ ████ ██ ██████ ██ █████ ██ ████ ██ █████ ██ ██ ██ ██ ███████ ██ ██ ██ ██ ██ ██ ██
|
||||
// ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██
|
||||
// ██ ██ ██ ██ ███████ ███████ ██ ██ ███████ ██ ████ ██ ██ ██ ██ ██ ██████ ██ ████
|
||||
//
|
||||
// >>implementation
|
||||
#ifdef SOKOL_LOG_IMPL
|
||||
#define SOKOL_LOG_IMPL_INCLUDED (1)
|
||||
|
||||
#ifndef SOKOL_API_IMPL
|
||||
#define SOKOL_API_IMPL
|
||||
#endif
|
||||
#ifndef SOKOL_DEBUG
|
||||
#ifndef NDEBUG
|
||||
#define SOKOL_DEBUG
|
||||
#endif
|
||||
#endif
|
||||
#ifndef SOKOL_ASSERT
|
||||
#include <assert.h>
|
||||
#define SOKOL_ASSERT(c) assert(c)
|
||||
#endif
|
||||
|
||||
#ifndef _SOKOL_PRIVATE
|
||||
#if defined(__GNUC__) || defined(__clang__)
|
||||
#define _SOKOL_PRIVATE __attribute__((unused)) static
|
||||
#else
|
||||
#define _SOKOL_PRIVATE static
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef _SOKOL_UNUSED
|
||||
#define _SOKOL_UNUSED(x) (void)(x)
|
||||
#endif
|
||||
|
||||
// platform detection
|
||||
#if defined(__APPLE__)
|
||||
#define _SLOG_APPLE (1)
|
||||
#elif defined(__EMSCRIPTEN__)
|
||||
#define _SLOG_EMSCRIPTEN (1)
|
||||
#elif defined(_WIN32)
|
||||
#define _SLOG_WINDOWS (1)
|
||||
#elif defined(__ANDROID__)
|
||||
#define _SLOG_ANDROID (1)
|
||||
#elif defined(__linux__) || defined(__unix__)
|
||||
#define _SLOG_LINUX (1)
|
||||
#else
|
||||
#error "sokol_log.h: unknown platform"
|
||||
#endif
|
||||
|
||||
#include <stdlib.h> // abort
|
||||
#include <stdio.h> // fputs
|
||||
#include <stddef.h> // size_t
|
||||
|
||||
#if defined(_SLOG_EMSCRIPTEN)
|
||||
#include <emscripten/emscripten.h>
|
||||
#elif defined(_SLOG_WINDOWS)
|
||||
#ifndef WIN32_LEAN_AND_MEAN
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#endif
|
||||
#ifndef NOMINMAX
|
||||
#define NOMINMAX
|
||||
#endif
|
||||
#include <windows.h>
|
||||
#elif defined(_SLOG_ANDROID)
|
||||
#include <android/log.h>
|
||||
#elif defined(_SLOG_LINUX) || defined(_SLOG_APPLE)
|
||||
#include <syslog.h>
|
||||
#endif
|
||||
|
||||
// size of line buffer (on stack!) in bytes including terminating zero
|
||||
#define _SLOG_LINE_LENGTH (512)
|
||||
|
||||
_SOKOL_PRIVATE char* _slog_append(const char* str, char* dst, char* end) {
|
||||
if (str) {
|
||||
char c;
|
||||
while (((c = *str++) != 0) && (dst < (end - 1))) {
|
||||
*dst++ = c;
|
||||
}
|
||||
}
|
||||
*dst = 0;
|
||||
return dst;
|
||||
}
|
||||
|
||||
_SOKOL_PRIVATE char* _slog_itoa(uint32_t x, char* buf, size_t buf_size) {
|
||||
const size_t max_digits_and_null = 11;
|
||||
if (buf_size < max_digits_and_null) {
|
||||
return 0;
|
||||
}
|
||||
char* p = buf + max_digits_and_null;
|
||||
*--p = 0;
|
||||
do {
|
||||
*--p = '0' + (x % 10);
|
||||
x /= 10;
|
||||
} while (x != 0);
|
||||
return p;
|
||||
}
|
||||
|
||||
#if defined(_SLOG_EMSCRIPTEN)
|
||||
EM_JS(void, slog_js_log, (uint32_t level, const char* c_str), {
|
||||
const str = UTF8ToString(c_str);
|
||||
switch (level) {
|
||||
case 0: console.error(str); break;
|
||||
case 1: console.error(str); break;
|
||||
case 2: console.warn(str); break;
|
||||
default: console.info(str); break;
|
||||
}
|
||||
})
|
||||
#endif
|
||||
|
||||
SOKOL_API_IMPL void slog_func(const char* tag, uint32_t log_level, uint32_t log_item, const char* message, uint32_t line_nr, const char* filename, void* user_data) {
|
||||
_SOKOL_UNUSED(user_data);
|
||||
|
||||
const char* log_level_str;
|
||||
switch (log_level) {
|
||||
case 0: log_level_str = "panic"; break;
|
||||
case 1: log_level_str = "error"; break;
|
||||
case 2: log_level_str = "warning"; break;
|
||||
default: log_level_str = "info"; break;
|
||||
}
|
||||
|
||||
// build log output line
|
||||
char line_buf[_SLOG_LINE_LENGTH];
|
||||
char* str = line_buf;
|
||||
char* end = line_buf + sizeof(line_buf);
|
||||
char num_buf[32];
|
||||
if (tag) {
|
||||
str = _slog_append("[", str, end);
|
||||
str = _slog_append(tag, str, end);
|
||||
str = _slog_append("]", str, end);
|
||||
}
|
||||
str = _slog_append("[", str, end);
|
||||
str = _slog_append(log_level_str, str, end);
|
||||
str = _slog_append("]", str, end);
|
||||
str = _slog_append("[id:", str, end);
|
||||
str = _slog_append(_slog_itoa(log_item, num_buf, sizeof(num_buf)), str, end);
|
||||
str = _slog_append("]", str, end);
|
||||
// if a filename is provided, build a clickable log message that's compatible with compiler error messages
|
||||
if (filename) {
|
||||
str = _slog_append(" ", str, end);
|
||||
#if defined(_MSC_VER)
|
||||
// MSVC compiler error format
|
||||
str = _slog_append(filename, str, end);
|
||||
str = _slog_append("(", str, end);
|
||||
str = _slog_append(_slog_itoa(line_nr, num_buf, sizeof(num_buf)), str, end);
|
||||
str = _slog_append("): ", str, end);
|
||||
#else
|
||||
// gcc/clang compiler error format
|
||||
str = _slog_append(filename, str, end);
|
||||
str = _slog_append(":", str, end);
|
||||
str = _slog_append(_slog_itoa(line_nr, num_buf, sizeof(num_buf)), str, end);
|
||||
str = _slog_append(":0: ", str, end);
|
||||
#endif
|
||||
}
|
||||
else {
|
||||
str = _slog_append("[line:", str, end);
|
||||
str = _slog_append(_slog_itoa(line_nr, num_buf, sizeof(num_buf)), str, end);
|
||||
str = _slog_append("] ", str, end);
|
||||
}
|
||||
if (message) {
|
||||
str = _slog_append("\n\t", str, end);
|
||||
str = _slog_append(message, str, end);
|
||||
}
|
||||
str = _slog_append("\n\n", str, end);
|
||||
if (0 == log_level) {
|
||||
str = _slog_append("ABORTING because of [panic]\n", str, end);
|
||||
(void)str;
|
||||
}
|
||||
|
||||
// print to stderr?
|
||||
#if defined(_SLOG_LINUX) || defined(_SLOG_WINDOWS) || defined(_SLOG_APPLE)
|
||||
fputs(line_buf, stderr);
|
||||
#endif
|
||||
|
||||
// platform specific logging calls
|
||||
#if defined(_SLOG_WINDOWS)
|
||||
OutputDebugStringA(line_buf);
|
||||
#elif defined(_SLOG_ANDROID)
|
||||
int prio;
|
||||
switch (log_level) {
|
||||
case 0: prio = ANDROID_LOG_FATAL; break;
|
||||
case 1: prio = ANDROID_LOG_ERROR; break;
|
||||
case 2: prio = ANDROID_LOG_WARN; break;
|
||||
default: prio = ANDROID_LOG_INFO; break;
|
||||
}
|
||||
__android_log_write(prio, "SOKOL", line_buf);
|
||||
#elif defined(_SLOG_EMSCRIPTEN)
|
||||
slog_js_log(log_level, line_buf);
|
||||
#endif
|
||||
if (0 == log_level) {
|
||||
abort();
|
||||
}
|
||||
}
|
||||
#endif // SOKOL_LOG_IMPL
|
6
thirdparty/sokol/c/sokol_shape.c
vendored
Normal file
6
thirdparty/sokol/c/sokol_shape.c
vendored
Normal file
@@ -0,0 +1,6 @@
|
||||
#if defined(IMPL)
|
||||
#define SOKOL_SHAPE_IMPL
|
||||
#endif
|
||||
#include "sokol_defines.h"
|
||||
#include "sokol_gfx.h"
|
||||
#include "sokol_shape.h"
|
1431
thirdparty/sokol/c/sokol_shape.h
vendored
Normal file
1431
thirdparty/sokol/c/sokol_shape.h
vendored
Normal file
File diff suppressed because it is too large
Load Diff
5
thirdparty/sokol/c/sokol_time.c
vendored
Normal file
5
thirdparty/sokol/c/sokol_time.c
vendored
Normal file
@@ -0,0 +1,5 @@
|
||||
#if defined(IMPL)
|
||||
#define SOKOL_TIME_IMPL
|
||||
#endif
|
||||
#include "sokol_defines.h"
|
||||
#include "sokol_time.h"
|
319
thirdparty/sokol/c/sokol_time.h
vendored
Normal file
319
thirdparty/sokol/c/sokol_time.h
vendored
Normal file
@@ -0,0 +1,319 @@
|
||||
#if defined(SOKOL_IMPL) && !defined(SOKOL_TIME_IMPL)
|
||||
#define SOKOL_TIME_IMPL
|
||||
#endif
|
||||
#ifndef SOKOL_TIME_INCLUDED
|
||||
/*
|
||||
sokol_time.h -- simple cross-platform time measurement
|
||||
|
||||
Project URL: https://github.com/floooh/sokol
|
||||
|
||||
Do this:
|
||||
#define SOKOL_IMPL or
|
||||
#define SOKOL_TIME_IMPL
|
||||
before you include this file in *one* C or C++ file to create the
|
||||
implementation.
|
||||
|
||||
Optionally provide the following defines with your own implementations:
|
||||
SOKOL_ASSERT(c) - your own assert macro (default: assert(c))
|
||||
SOKOL_TIME_API_DECL - public function declaration prefix (default: extern)
|
||||
SOKOL_API_DECL - same as SOKOL_TIME_API_DECL
|
||||
SOKOL_API_IMPL - public function implementation prefix (default: -)
|
||||
|
||||
If sokol_time.h is compiled as a DLL, define the following before
|
||||
including the declaration or implementation:
|
||||
|
||||
SOKOL_DLL
|
||||
|
||||
On Windows, SOKOL_DLL will define SOKOL_TIME_API_DECL as __declspec(dllexport)
|
||||
or __declspec(dllimport) as needed.
|
||||
|
||||
void stm_setup();
|
||||
Call once before any other functions to initialize sokol_time
|
||||
(this calls for instance QueryPerformanceFrequency on Windows)
|
||||
|
||||
uint64_t stm_now();
|
||||
Get current point in time in unspecified 'ticks'. The value that
|
||||
is returned has no relation to the 'wall-clock' time and is
|
||||
not in a specific time unit, it is only useful to compute
|
||||
time differences.
|
||||
|
||||
uint64_t stm_diff(uint64_t new, uint64_t old);
|
||||
Computes the time difference between new and old. This will always
|
||||
return a positive, non-zero value.
|
||||
|
||||
uint64_t stm_since(uint64_t start);
|
||||
Takes the current time, and returns the elapsed time since start
|
||||
(this is a shortcut for "stm_diff(stm_now(), start)")
|
||||
|
||||
uint64_t stm_laptime(uint64_t* last_time);
|
||||
This is useful for measuring frame time and other recurring
|
||||
events. It takes the current time, returns the time difference
|
||||
to the value in last_time, and stores the current time in
|
||||
last_time for the next call. If the value in last_time is 0,
|
||||
the return value will be zero (this usually happens on the
|
||||
very first call).
|
||||
|
||||
uint64_t stm_round_to_common_refresh_rate(uint64_t duration)
|
||||
This oddly named function takes a measured frame time and
|
||||
returns the closest "nearby" common display refresh rate frame duration
|
||||
in ticks. If the input duration isn't close to any common display
|
||||
refresh rate, the input duration will be returned unchanged as a fallback.
|
||||
The main purpose of this function is to remove jitter/inaccuracies from
|
||||
measured frame times, and instead use the display refresh rate as
|
||||
frame duration.
|
||||
NOTE: for more robust frame timing, consider using the
|
||||
sokol_app.h function sapp_frame_duration()
|
||||
|
||||
Use the following functions to convert a duration in ticks into
|
||||
useful time units:
|
||||
|
||||
double stm_sec(uint64_t ticks);
|
||||
double stm_ms(uint64_t ticks);
|
||||
double stm_us(uint64_t ticks);
|
||||
double stm_ns(uint64_t ticks);
|
||||
Converts a tick value into seconds, milliseconds, microseconds
|
||||
or nanoseconds. Note that not all platforms will have nanosecond
|
||||
or even microsecond precision.
|
||||
|
||||
Uses the following time measurement functions under the hood:
|
||||
|
||||
Windows: QueryPerformanceFrequency() / QueryPerformanceCounter()
|
||||
MacOS/iOS: mach_absolute_time()
|
||||
emscripten: emscripten_get_now()
|
||||
Linux+others: clock_gettime(CLOCK_MONOTONIC)
|
||||
|
||||
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.
|
||||
*/
|
||||
#define SOKOL_TIME_INCLUDED (1)
|
||||
#include <stdint.h>
|
||||
|
||||
#if defined(SOKOL_API_DECL) && !defined(SOKOL_TIME_API_DECL)
|
||||
#define SOKOL_TIME_API_DECL SOKOL_API_DECL
|
||||
#endif
|
||||
#ifndef SOKOL_TIME_API_DECL
|
||||
#if defined(_WIN32) && defined(SOKOL_DLL) && defined(SOKOL_TIME_IMPL)
|
||||
#define SOKOL_TIME_API_DECL __declspec(dllexport)
|
||||
#elif defined(_WIN32) && defined(SOKOL_DLL)
|
||||
#define SOKOL_TIME_API_DECL __declspec(dllimport)
|
||||
#else
|
||||
#define SOKOL_TIME_API_DECL extern
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
SOKOL_TIME_API_DECL void stm_setup(void);
|
||||
SOKOL_TIME_API_DECL uint64_t stm_now(void);
|
||||
SOKOL_TIME_API_DECL uint64_t stm_diff(uint64_t new_ticks, uint64_t old_ticks);
|
||||
SOKOL_TIME_API_DECL uint64_t stm_since(uint64_t start_ticks);
|
||||
SOKOL_TIME_API_DECL uint64_t stm_laptime(uint64_t* last_time);
|
||||
SOKOL_TIME_API_DECL uint64_t stm_round_to_common_refresh_rate(uint64_t frame_ticks);
|
||||
SOKOL_TIME_API_DECL double stm_sec(uint64_t ticks);
|
||||
SOKOL_TIME_API_DECL double stm_ms(uint64_t ticks);
|
||||
SOKOL_TIME_API_DECL double stm_us(uint64_t ticks);
|
||||
SOKOL_TIME_API_DECL double stm_ns(uint64_t ticks);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
#endif // SOKOL_TIME_INCLUDED
|
||||
|
||||
/*-- IMPLEMENTATION ----------------------------------------------------------*/
|
||||
#ifdef SOKOL_TIME_IMPL
|
||||
#define SOKOL_TIME_IMPL_INCLUDED (1)
|
||||
#include <string.h> /* memset */
|
||||
|
||||
#ifndef SOKOL_API_IMPL
|
||||
#define SOKOL_API_IMPL
|
||||
#endif
|
||||
#ifndef SOKOL_ASSERT
|
||||
#include <assert.h>
|
||||
#define SOKOL_ASSERT(c) assert(c)
|
||||
#endif
|
||||
#ifndef _SOKOL_PRIVATE
|
||||
#if defined(__GNUC__) || defined(__clang__)
|
||||
#define _SOKOL_PRIVATE __attribute__((unused)) static
|
||||
#else
|
||||
#define _SOKOL_PRIVATE static
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if defined(_WIN32)
|
||||
#ifndef WIN32_LEAN_AND_MEAN
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#endif
|
||||
#include <windows.h>
|
||||
typedef struct {
|
||||
uint32_t initialized;
|
||||
LARGE_INTEGER freq;
|
||||
LARGE_INTEGER start;
|
||||
} _stm_state_t;
|
||||
#elif defined(__APPLE__) && defined(__MACH__)
|
||||
#include <mach/mach_time.h>
|
||||
typedef struct {
|
||||
uint32_t initialized;
|
||||
mach_timebase_info_data_t timebase;
|
||||
uint64_t start;
|
||||
} _stm_state_t;
|
||||
#elif defined(__EMSCRIPTEN__)
|
||||
#include <emscripten/emscripten.h>
|
||||
typedef struct {
|
||||
uint32_t initialized;
|
||||
double start;
|
||||
} _stm_state_t;
|
||||
#else /* anything else, this will need more care for non-Linux platforms */
|
||||
#ifdef ESP8266
|
||||
// On the ESP8266, clock_gettime ignores the first argument and CLOCK_MONOTONIC isn't defined
|
||||
#define CLOCK_MONOTONIC 0
|
||||
#endif
|
||||
#include <time.h>
|
||||
typedef struct {
|
||||
uint32_t initialized;
|
||||
uint64_t start;
|
||||
} _stm_state_t;
|
||||
#endif
|
||||
static _stm_state_t _stm;
|
||||
|
||||
/* prevent 64-bit overflow when computing relative timestamp
|
||||
see https://gist.github.com/jspohr/3dc4f00033d79ec5bdaf67bc46c813e3
|
||||
*/
|
||||
#if defined(_WIN32) || (defined(__APPLE__) && defined(__MACH__))
|
||||
_SOKOL_PRIVATE int64_t _stm_int64_muldiv(int64_t value, int64_t numer, int64_t denom) {
|
||||
int64_t q = value / denom;
|
||||
int64_t r = value % denom;
|
||||
return q * numer + r * numer / denom;
|
||||
}
|
||||
#endif
|
||||
|
||||
SOKOL_API_IMPL void stm_setup(void) {
|
||||
memset(&_stm, 0, sizeof(_stm));
|
||||
_stm.initialized = 0xABCDABCD;
|
||||
#if defined(_WIN32)
|
||||
QueryPerformanceFrequency(&_stm.freq);
|
||||
QueryPerformanceCounter(&_stm.start);
|
||||
#elif defined(__APPLE__) && defined(__MACH__)
|
||||
mach_timebase_info(&_stm.timebase);
|
||||
_stm.start = mach_absolute_time();
|
||||
#elif defined(__EMSCRIPTEN__)
|
||||
_stm.start = emscripten_get_now();
|
||||
#else
|
||||
struct timespec ts;
|
||||
clock_gettime(CLOCK_MONOTONIC, &ts);
|
||||
_stm.start = (uint64_t)ts.tv_sec*1000000000 + (uint64_t)ts.tv_nsec;
|
||||
#endif
|
||||
}
|
||||
|
||||
SOKOL_API_IMPL uint64_t stm_now(void) {
|
||||
SOKOL_ASSERT(_stm.initialized == 0xABCDABCD);
|
||||
uint64_t now;
|
||||
#if defined(_WIN32)
|
||||
LARGE_INTEGER qpc_t;
|
||||
QueryPerformanceCounter(&qpc_t);
|
||||
now = (uint64_t) _stm_int64_muldiv(qpc_t.QuadPart - _stm.start.QuadPart, 1000000000, _stm.freq.QuadPart);
|
||||
#elif defined(__APPLE__) && defined(__MACH__)
|
||||
const uint64_t mach_now = mach_absolute_time() - _stm.start;
|
||||
now = (uint64_t) _stm_int64_muldiv((int64_t)mach_now, (int64_t)_stm.timebase.numer, (int64_t)_stm.timebase.denom);
|
||||
#elif defined(__EMSCRIPTEN__)
|
||||
double js_now = emscripten_get_now() - _stm.start;
|
||||
now = (uint64_t) (js_now * 1000000.0);
|
||||
#else
|
||||
struct timespec ts;
|
||||
clock_gettime(CLOCK_MONOTONIC, &ts);
|
||||
now = ((uint64_t)ts.tv_sec*1000000000 + (uint64_t)ts.tv_nsec) - _stm.start;
|
||||
#endif
|
||||
return now;
|
||||
}
|
||||
|
||||
SOKOL_API_IMPL uint64_t stm_diff(uint64_t new_ticks, uint64_t old_ticks) {
|
||||
if (new_ticks > old_ticks) {
|
||||
return new_ticks - old_ticks;
|
||||
}
|
||||
else {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
SOKOL_API_IMPL uint64_t stm_since(uint64_t start_ticks) {
|
||||
return stm_diff(stm_now(), start_ticks);
|
||||
}
|
||||
|
||||
SOKOL_API_IMPL uint64_t stm_laptime(uint64_t* last_time) {
|
||||
SOKOL_ASSERT(last_time);
|
||||
uint64_t dt = 0;
|
||||
uint64_t now = stm_now();
|
||||
if (0 != *last_time) {
|
||||
dt = stm_diff(now, *last_time);
|
||||
}
|
||||
*last_time = now;
|
||||
return dt;
|
||||
}
|
||||
|
||||
// first number is frame duration in ns, second number is tolerance in ns,
|
||||
// the resulting min/max values must not overlap!
|
||||
static const uint64_t _stm_refresh_rates[][2] = {
|
||||
{ 16666667, 1000000 }, // 60 Hz: 16.6667 +- 1ms
|
||||
{ 13888889, 250000 }, // 72 Hz: 13.8889 +- 0.25ms
|
||||
{ 13333333, 250000 }, // 75 Hz: 13.3333 +- 0.25ms
|
||||
{ 11764706, 250000 }, // 85 Hz: 11.7647 +- 0.25
|
||||
{ 11111111, 250000 }, // 90 Hz: 11.1111 +- 0.25ms
|
||||
{ 10000000, 500000 }, // 100 Hz: 10.0000 +- 0.5ms
|
||||
{ 8333333, 500000 }, // 120 Hz: 8.3333 +- 0.5ms
|
||||
{ 6944445, 500000 }, // 144 Hz: 6.9445 +- 0.5ms
|
||||
{ 4166667, 1000000 }, // 240 Hz: 4.1666 +- 1ms
|
||||
{ 0, 0 }, // keep the last element always at zero
|
||||
};
|
||||
|
||||
SOKOL_API_IMPL uint64_t stm_round_to_common_refresh_rate(uint64_t ticks) {
|
||||
uint64_t ns;
|
||||
int i = 0;
|
||||
while (0 != (ns = _stm_refresh_rates[i][0])) {
|
||||
uint64_t tol = _stm_refresh_rates[i][1];
|
||||
if ((ticks > (ns - tol)) && (ticks < (ns + tol))) {
|
||||
return ns;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
// fallthrough: didn't fit into any buckets
|
||||
return ticks;
|
||||
}
|
||||
|
||||
SOKOL_API_IMPL double stm_sec(uint64_t ticks) {
|
||||
return (double)ticks / 1000000000.0;
|
||||
}
|
||||
|
||||
SOKOL_API_IMPL double stm_ms(uint64_t ticks) {
|
||||
return (double)ticks / 1000000.0;
|
||||
}
|
||||
|
||||
SOKOL_API_IMPL double stm_us(uint64_t ticks) {
|
||||
return (double)ticks / 1000.0;
|
||||
}
|
||||
|
||||
SOKOL_API_IMPL double stm_ns(uint64_t ticks) {
|
||||
return (double)ticks;
|
||||
}
|
||||
#endif /* SOKOL_TIME_IMPL */
|
||||
|
740
thirdparty/sokol/debugtext/debugtext.odin
vendored
Normal file
740
thirdparty/sokol/debugtext/debugtext.odin
vendored
Normal file
@@ -0,0 +1,740 @@
|
||||
// machine generated, do not edit
|
||||
|
||||
package sokol_debugtext
|
||||
|
||||
/*
|
||||
|
||||
sokol_debugtext.h - simple ASCII debug text rendering on top of sokol_gfx.h
|
||||
|
||||
Project URL: https://github.com/floooh/sokol
|
||||
|
||||
Do this:
|
||||
#define SOKOL_IMPL or
|
||||
#define SOKOL_DEBUGTEXT_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_VSNPRINTF - the function name of an alternative vsnprintf() function (default: vsnprintf)
|
||||
SOKOL_ASSERT(c) - your own assert macro (default: assert(c))
|
||||
SOKOL_DEBUGTEXT_API_DECL - public function declaration prefix (default: extern)
|
||||
SOKOL_API_DECL - same as SOKOL_DEBUGTEXT_API_DECL
|
||||
SOKOL_API_IMPL - public function implementation prefix (default: -)
|
||||
SOKOL_UNREACHABLE() - a guard macro for unreachable code (default: assert(false))
|
||||
|
||||
If sokol_debugtext.h is compiled as a DLL, define the following before
|
||||
including the declaration or implementation:
|
||||
|
||||
SOKOL_DLL
|
||||
|
||||
On Windows, SOKOL_DLL will define SOKOL_DEBUGTEXT_API_DECL as __declspec(dllexport)
|
||||
or __declspec(dllimport) as needed.
|
||||
|
||||
Include the following headers before including sokol_debugtext.h:
|
||||
|
||||
sokol_gfx.h
|
||||
|
||||
FEATURES AND CONCEPTS
|
||||
=====================
|
||||
- renders 8-bit ASCII text as fixed-size 8x8 pixel characters
|
||||
- comes with 6 embedded 8-bit home computer fonts (each taking up 2 KBytes)
|
||||
- easily plug in your own fonts
|
||||
- create multiple contexts for rendering text in different layers or render passes
|
||||
|
||||
STEP BY STEP
|
||||
============
|
||||
|
||||
--- to initialize sokol-debugtext, call sdtx_setup() *after* initializing
|
||||
sokol-gfx:
|
||||
|
||||
sdtx_setup(&(sdtx_desc_t){ ... });
|
||||
|
||||
To see any warnings and errors, you should always install a logging callback.
|
||||
The easiest way is via sokol_log.h:
|
||||
|
||||
#include "sokol_log.h"
|
||||
|
||||
sdtx_setup(&(sdtx_desc_t){
|
||||
.logger.func = slog_func,
|
||||
});
|
||||
|
||||
--- configure sokol-debugtext by populating the sdtx_desc_t struct:
|
||||
|
||||
.context_pool_size (default: 8)
|
||||
The max number of text contexts that can be created.
|
||||
|
||||
.printf_buf_size (default: 4096)
|
||||
The size of the internal text formatting buffer used by
|
||||
sdtx_printf() and sdtx_vprintf().
|
||||
|
||||
.fonts (default: none)
|
||||
An array of sdtx_font_desc_t structs used to configure the
|
||||
fonts that can be used for rendering. To use all builtin
|
||||
fonts call sdtx_setup() like this (in C99):
|
||||
|
||||
sdtx_setup(&(sdtx_desc_t){
|
||||
.fonts = {
|
||||
[0] = sdtx_font_kc853(),
|
||||
[1] = sdtx_font_kc854(),
|
||||
[2] = sdtx_font_z1013(),
|
||||
[3] = sdtx_font_cpc(),
|
||||
[4] = sdtx_font_c64(),
|
||||
[5] = sdtx_font_oric()
|
||||
}
|
||||
});
|
||||
|
||||
For documentation on how to use you own font data, search
|
||||
below for "USING YOUR OWN FONT DATA".
|
||||
|
||||
.context
|
||||
The setup parameters for the default text context. This will
|
||||
be active right after sdtx_setup(), or when calling
|
||||
sdtx_set_context(SDTX_DEFAULT_CONTEXT):
|
||||
|
||||
.max_commands (default: 4096)
|
||||
The max number of render commands that can be recorded
|
||||
into the internal command buffer. This directly translates
|
||||
to the number of render layer changes in a single frame.
|
||||
|
||||
.char_buf_size (default: 4096)
|
||||
The number of characters that can be rendered per frame in this
|
||||
context, defines the size of an internal fixed-size vertex
|
||||
buffer. Any additional characters will be silently ignored.
|
||||
|
||||
.canvas_width (default: 640)
|
||||
.canvas_height (default: 480)
|
||||
The 'virtual canvas size' in pixels. This defines how big
|
||||
characters will be rendered relative to the default framebuffer
|
||||
dimensions. Each character occupies a grid of 8x8 'virtual canvas
|
||||
pixels' (so a virtual canvas size of 640x480 means that 80x60 characters
|
||||
fit on the screen). For rendering in a resizeable window, you
|
||||
should dynamically update the canvas size in each frame by
|
||||
calling sdtx_canvas(w, h).
|
||||
|
||||
.tab_width (default: 4)
|
||||
The width of a tab character in number of character cells.
|
||||
|
||||
.color_format (default: 0)
|
||||
.depth_format (default: 0)
|
||||
.sample_count (default: 0)
|
||||
The pixel format description for the default context needed
|
||||
for creating the context's sg_pipeline object. When
|
||||
rendering to the default framebuffer you can leave those
|
||||
zero-initialized, in this case the proper values will be
|
||||
filled in by sokol-gfx. You only need to provide non-default
|
||||
values here when rendering to render targets with different
|
||||
pixel format attributes than the default framebuffer.
|
||||
|
||||
--- Before starting to render text, optionally call sdtx_canvas() to
|
||||
dynamically resize the virtual canvas. This is recommended when
|
||||
rendering to a resizeable window. The virtual canvas size can
|
||||
also be used to scale text in relation to the display resolution.
|
||||
|
||||
Examples when using sokol-app:
|
||||
|
||||
- to render characters at 8x8 'physical pixels':
|
||||
|
||||
sdtx_canvas(sapp_width(), sapp_height());
|
||||
|
||||
- to render characters at 16x16 physical pixels:
|
||||
|
||||
sdtx_canvas(sapp_width()/2.0f, sapp_height()/2.0f);
|
||||
|
||||
Do *not* use integer math here, since this will not look nice
|
||||
when the render target size isn't divisible by 2.
|
||||
|
||||
--- Optionally define the origin for the character grid with:
|
||||
|
||||
sdtx_origin(x, y);
|
||||
|
||||
The provided coordinates are in character grid cells, not in
|
||||
virtual canvas pixels. E.g. to set the origin to 2 character tiles
|
||||
from the left and top border:
|
||||
|
||||
sdtx_origin(2, 2);
|
||||
|
||||
You can define fractions, e.g. to start rendering half
|
||||
a character tile from the top-left corner:
|
||||
|
||||
sdtx_origin(0.5f, 0.5f);
|
||||
|
||||
--- Optionally set a different font by calling:
|
||||
|
||||
sdtx_font(font_index)
|
||||
|
||||
sokol-debugtext provides 8 font slots which can be populated
|
||||
with the builtin fonts or with user-provided font data, so
|
||||
'font_index' must be a number from 0 to 7.
|
||||
|
||||
--- Position the text cursor with one of the following calls. All arguments
|
||||
are in character grid cells as floats and relative to the
|
||||
origin defined with sdtx_origin():
|
||||
|
||||
sdtx_pos(x, y) - sets absolute cursor position
|
||||
sdtx_pos_x(x) - only set absolute x cursor position
|
||||
sdtx_pos_y(y) - only set absolute y cursor position
|
||||
|
||||
sdtx_move(x, y) - move cursor relative in x and y direction
|
||||
sdtx_move_x(x) - move cursor relative only in x direction
|
||||
sdtx_move_y(y) - move cursor relative only in y direction
|
||||
|
||||
sdtx_crlf() - set cursor to beginning of next line
|
||||
(same as sdtx_pos_x(0) + sdtx_move_y(1))
|
||||
sdtx_home() - resets the cursor to the origin
|
||||
(same as sdtx_pos(0, 0))
|
||||
|
||||
--- Set a new text color with any of the following functions:
|
||||
|
||||
sdtx_color3b(r, g, b) - RGB 0..255, A=255
|
||||
sdtx_color3f(r, g, b) - RGB 0.0f..1.0f, A=1.0f
|
||||
sdtx_color4b(r, g, b, a) - RGBA 0..255
|
||||
sdtx_color4f(r, g, b, a) - RGBA 0.0f..1.0f
|
||||
sdtx_color1i(uint32_t rgba) - ABGR (0xAABBGGRR)
|
||||
|
||||
--- Output 8-bit ASCII text with the following functions:
|
||||
|
||||
sdtx_putc(c) - output a single character
|
||||
|
||||
sdtx_puts(str) - output a null-terminated C string, note that
|
||||
this will *not* append a newline (so it behaves
|
||||
differently than the CRT's puts() function)
|
||||
|
||||
sdtx_putr(str, len) - 'put range' output the first 'len' characters of
|
||||
a C string or until the zero character is encountered
|
||||
|
||||
sdtx_printf(fmt, ...) - output with printf-formatting, note that you
|
||||
can inject your own printf-compatible function
|
||||
by overriding the SOKOL_VSNPRINTF define before
|
||||
including the implementation
|
||||
|
||||
sdtx_vprintf(fmt, args) - same as sdtx_printf() but with the arguments
|
||||
provided in a va_list
|
||||
|
||||
- Note that the text will not yet be rendered, only recorded for rendering
|
||||
at a later time, the actual rendering happens when sdtx_draw() is called
|
||||
inside a sokol-gfx render pass.
|
||||
- This means also you can output text anywhere in the frame, it doesn't
|
||||
have to be inside a render pass.
|
||||
- Note that character codes <32 are reserved as control characters
|
||||
and won't render anything. Currently only the following control
|
||||
characters are implemented:
|
||||
|
||||
\r - carriage return (same as sdtx_pos_x(0))
|
||||
\n - carriage return + line feed (same as stdx_crlf())
|
||||
\t - a tab character
|
||||
|
||||
--- You can 'record' text into render layers, this allows to mix/interleave
|
||||
sokol-debugtext rendering with other rendering operations inside
|
||||
sokol-gfx render passes. To start recording text into a different render
|
||||
layer, call:
|
||||
|
||||
sdtx_layer(int layer_id)
|
||||
|
||||
...outside a sokol-gfx render pass.
|
||||
|
||||
--- finally, from within a sokol-gfx render pass, call:
|
||||
|
||||
sdtx_draw()
|
||||
|
||||
...for non-layered rendering, or to draw a specific layer:
|
||||
|
||||
sdtx_draw_layer(int layer_id)
|
||||
|
||||
NOTE that sdtx_draw() is equivalent to:
|
||||
|
||||
sdtx_draw_layer(0)
|
||||
|
||||
...so sdtx_draw() will *NOT* render all text layers, instead it will
|
||||
only render the 'default layer' 0.
|
||||
|
||||
--- at the end of a frame (defined by the call to sg_commit()), sokol-debugtext
|
||||
will rewind all contexts:
|
||||
|
||||
- the internal vertex index is set to 0
|
||||
- the internal command index is set to 0
|
||||
- the current layer id is set to 0
|
||||
- the current font is set to 0
|
||||
- the cursor position is reset
|
||||
|
||||
|
||||
RENDERING WITH MULTIPLE CONTEXTS
|
||||
================================
|
||||
Use multiple text contexts if you need to render debug text in different
|
||||
sokol-gfx render passes, or want to render text to different layers
|
||||
in the same render pass, each with its own set of parameters.
|
||||
|
||||
To create a new text context call:
|
||||
|
||||
sdtx_context ctx = sdtx_make_context(&(sdtx_context_desc_t){ ... });
|
||||
|
||||
The creation parameters in the sdtx_context_desc_t struct are the same
|
||||
as already described above in the sdtx_setup() function:
|
||||
|
||||
.char_buf_size -- max number of characters rendered in one frame, default: 4096
|
||||
.canvas_width -- the initial virtual canvas width, default: 640
|
||||
.canvas_height -- the initial virtual canvas height, default: 400
|
||||
.tab_width -- tab width in number of characters, default: 4
|
||||
.color_format -- color pixel format of target render pass
|
||||
.depth_format -- depth pixel format of target render pass
|
||||
.sample_count -- MSAA sample count of target render pass
|
||||
|
||||
To make a new context the active context, call:
|
||||
|
||||
sdtx_set_context(ctx)
|
||||
|
||||
...and after that call the text output functions as described above, and
|
||||
finally, inside a sokol-gfx render pass, call sdtx_draw() to actually
|
||||
render the text for this context.
|
||||
|
||||
A context keeps track of the following parameters:
|
||||
|
||||
- the active font
|
||||
- the virtual canvas size
|
||||
- the origin position
|
||||
- the current cursor position
|
||||
- the current tab width
|
||||
- the current color
|
||||
- and the current layer-id
|
||||
|
||||
You can get the currently active context with:
|
||||
|
||||
sdtx_get_context()
|
||||
|
||||
To make the default context current, call sdtx_set_context() with the
|
||||
special SDTX_DEFAULT_CONTEXT handle:
|
||||
|
||||
sdtx_set_context(SDTX_DEFAULT_CONTEXT)
|
||||
|
||||
Alternatively, use the function sdtx_default_context() to get the default
|
||||
context handle:
|
||||
|
||||
sdtx_set_context(sdtx_default_context());
|
||||
|
||||
To destroy a context, call:
|
||||
|
||||
sdtx_destroy_context(ctx)
|
||||
|
||||
If a context is set as active that no longer exists, all sokol-debugtext
|
||||
functions that require an active context will silently fail.
|
||||
|
||||
You can directly draw the recorded text in a specific context without
|
||||
setting the active context:
|
||||
|
||||
sdtx_context_draw(ctx)
|
||||
sdtx_context_draw_layer(ctx, layer_id)
|
||||
|
||||
USING YOUR OWN FONT DATA
|
||||
========================
|
||||
|
||||
Instead of the built-in fonts you can also plug your own font data
|
||||
into sokol-debugtext by providing one or several sdtx_font_desc_t
|
||||
structures in the sdtx_setup call.
|
||||
|
||||
For instance to use a built-in font at slot 0, and a user-font at
|
||||
font slot 1, the sdtx_setup() call might look like this:
|
||||
|
||||
sdtx_setup(&sdtx_desc_t){
|
||||
.fonts = {
|
||||
[0] = sdtx_font_kc853(),
|
||||
[1] = {
|
||||
.data = {
|
||||
.ptr = my_font_data,
|
||||
.size = sizeof(my_font_data)
|
||||
},
|
||||
.first_char = ...,
|
||||
.last_char = ...
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
Where 'my_font_data' is a byte array where every character is described
|
||||
by 8 bytes arranged like this:
|
||||
|
||||
bits
|
||||
7 6 5 4 3 2 1 0
|
||||
. . . X X . . . byte 0: 0x18
|
||||
. . X X X X . . byte 1: 0x3C
|
||||
. X X . . X X . byte 2: 0x66
|
||||
. X X . . X X . byte 3: 0x66
|
||||
. X X X X X X . byte 4: 0x7E
|
||||
. X X . . X X . byte 5: 0x66
|
||||
. X X . . X X . byte 6: 0x66
|
||||
. . . . . . . . byte 7: 0x00
|
||||
|
||||
A complete font consists of 256 characters, resulting in 2048 bytes for
|
||||
the font data array (but note that the character codes 0..31 will never
|
||||
be rendered).
|
||||
|
||||
If you provide such a complete font data array, you can drop the .first_char
|
||||
and .last_char initialization parameters since those default to 0 and 255,
|
||||
note that you can also use the SDTX_RANGE() helper macro to build the
|
||||
.data item:
|
||||
|
||||
sdtx_setup(&sdtx_desc_t){
|
||||
.fonts = {
|
||||
[0] = sdtx_font_kc853(),
|
||||
[1] = {
|
||||
.data = SDTX_RANGE(my_font_data)
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
If the font doesn't define all 256 character tiles, or you don't need an
|
||||
entire 256-character font and want to save a couple of bytes, use the
|
||||
.first_char and .last_char initialization parameters to define a sub-range.
|
||||
For instance if the font only contains the characters between the Space
|
||||
(ASCII code 32) and uppercase character 'Z' (ASCII code 90):
|
||||
|
||||
sdtx_setup(&sdtx_desc_t){
|
||||
.fonts = {
|
||||
[0] = sdtx_font_kc853(),
|
||||
[1] = {
|
||||
.data = SDTX_RANGE(my_font_data),
|
||||
.first_char = 32, // could also write ' '
|
||||
.last_char = 90 // could also write 'Z'
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
Character tiles that haven't been defined in the font will be rendered
|
||||
as a solid 8x8 quad.
|
||||
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
...
|
||||
sdtx_setup(&(sdtx_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"
|
||||
|
||||
sdtx_setup(&(sdtx_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. 'sdtx'
|
||||
uint32_t log_level, // 0=panic, 1=error, 2=warn, 3=info
|
||||
uint32_t log_item_id, // SDTX_LOGITEM_*
|
||||
const char* message_or_null, // a message string, may be nullptr in release mode
|
||||
uint32_t line_nr, // line number in sokol_debugtext.h
|
||||
const char* filename_or_null, // source filename, may be nullptr in release mode
|
||||
void* user_data)
|
||||
{
|
||||
...
|
||||
}
|
||||
|
||||
...and then setup sokol-debugtext like this:
|
||||
|
||||
sdtx_setup(&(sdtx_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) 2020 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:fmt"
|
||||
import "core:strings"
|
||||
printf :: proc(s: string, args: ..any) {
|
||||
fstr := fmt.tprintf(s, ..args)
|
||||
putr(strings.unsafe_string_to_cstring(fstr), len(fstr))
|
||||
}
|
||||
import "core:c"
|
||||
|
||||
_ :: c
|
||||
|
||||
SOKOL_DEBUG :: #config(SOKOL_DEBUG, ODIN_DEBUG)
|
||||
|
||||
DEBUG :: #config(SOKOL_DEBUGTEXT_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_debugtext_clib { "../sokol_dll_windows_x64_gl_debug.lib" } }
|
||||
else { foreign import sokol_debugtext_clib { "../sokol_dll_windows_x64_gl_release.lib" } }
|
||||
} else {
|
||||
when DEBUG { foreign import sokol_debugtext_clib { "../sokol_dll_windows_x64_d3d11_debug.lib" } }
|
||||
else { foreign import sokol_debugtext_clib { "../sokol_dll_windows_x64_d3d11_release.lib" } }
|
||||
}
|
||||
} else {
|
||||
when USE_GL {
|
||||
when DEBUG { foreign import sokol_debugtext_clib { "sokol_debugtext_windows_x64_gl_debug.lib" } }
|
||||
else { foreign import sokol_debugtext_clib { "sokol_debugtext_windows_x64_gl_release.lib" } }
|
||||
} else {
|
||||
when DEBUG { foreign import sokol_debugtext_clib { "sokol_debugtext_windows_x64_d3d11_debug.lib" } }
|
||||
else { foreign import sokol_debugtext_clib { "sokol_debugtext_windows_x64_d3d11_release.lib" } }
|
||||
}
|
||||
}
|
||||
} else when ODIN_OS == .Darwin {
|
||||
when USE_DLL {
|
||||
when USE_GL && ODIN_ARCH == .arm64 && DEBUG { foreign import sokol_debugtext_clib { "../dylib/sokol_dylib_macos_arm64_gl_debug.dylib" } }
|
||||
else when USE_GL && ODIN_ARCH == .arm64 && !DEBUG { foreign import sokol_debugtext_clib { "../dylib/sokol_dylib_macos_arm64_gl_release.dylib" } }
|
||||
else when USE_GL && ODIN_ARCH == .amd64 && DEBUG { foreign import sokol_debugtext_clib { "../dylib/sokol_dylib_macos_x64_gl_debug.dylib" } }
|
||||
else when USE_GL && ODIN_ARCH == .amd64 && !DEBUG { foreign import sokol_debugtext_clib { "../dylib/sokol_dylib_macos_x64_gl_release.dylib" } }
|
||||
else when !USE_GL && ODIN_ARCH == .arm64 && DEBUG { foreign import sokol_debugtext_clib { "../dylib/sokol_dylib_macos_arm64_metal_debug.dylib" } }
|
||||
else when !USE_GL && ODIN_ARCH == .arm64 && !DEBUG { foreign import sokol_debugtext_clib { "../dylib/sokol_dylib_macos_arm64_metal_release.dylib" } }
|
||||
else when !USE_GL && ODIN_ARCH == .amd64 && DEBUG { foreign import sokol_debugtext_clib { "../dylib/sokol_dylib_macos_x64_metal_debug.dylib" } }
|
||||
else when !USE_GL && ODIN_ARCH == .amd64 && !DEBUG { foreign import sokol_debugtext_clib { "../dylib/sokol_dylib_macos_x64_metal_release.dylib" } }
|
||||
} else {
|
||||
when USE_GL {
|
||||
when ODIN_ARCH == .arm64 {
|
||||
when DEBUG { foreign import sokol_debugtext_clib { "sokol_debugtext_macos_arm64_gl_debug.a" } }
|
||||
else { foreign import sokol_debugtext_clib { "sokol_debugtext_macos_arm64_gl_release.a" } }
|
||||
} else {
|
||||
when DEBUG { foreign import sokol_debugtext_clib { "sokol_debugtext_macos_x64_gl_debug.a" } }
|
||||
else { foreign import sokol_debugtext_clib { "sokol_debugtext_macos_x64_gl_release.a" } }
|
||||
}
|
||||
} else {
|
||||
when ODIN_ARCH == .arm64 {
|
||||
when DEBUG { foreign import sokol_debugtext_clib { "sokol_debugtext_macos_arm64_metal_debug.a" } }
|
||||
else { foreign import sokol_debugtext_clib { "sokol_debugtext_macos_arm64_metal_release.a" } }
|
||||
} else {
|
||||
when DEBUG { foreign import sokol_debugtext_clib { "sokol_debugtext_macos_x64_metal_debug.a" } }
|
||||
else { foreign import sokol_debugtext_clib { "sokol_debugtext_macos_x64_metal_release.a" } }
|
||||
}
|
||||
}
|
||||
}
|
||||
} else when ODIN_OS == .Linux {
|
||||
when USE_DLL {
|
||||
when DEBUG { foreign import sokol_debugtext_clib { "sokol_debugtext_linux_x64_gl_debug.so" } }
|
||||
else { foreign import sokol_debugtext_clib { "sokol_debugtext_linux_x64_gl_release.so" } }
|
||||
} else {
|
||||
when DEBUG { foreign import sokol_debugtext_clib { "sokol_debugtext_linux_x64_gl_debug.a" } }
|
||||
else { foreign import sokol_debugtext_clib { "sokol_debugtext_linux_x64_gl_release.a" } }
|
||||
}
|
||||
} else when ODIN_ARCH == .wasm32 || ODIN_ARCH == .wasm64p32 {
|
||||
// Feed sokol_debugtext_wasm_gl_debug.a or sokol_debugtext_wasm_gl_release.a into emscripten compiler.
|
||||
foreign import sokol_debugtext_clib { "env.o" }
|
||||
} else {
|
||||
#panic("This OS is currently not supported")
|
||||
}
|
||||
|
||||
@(default_calling_convention="c", link_prefix="sdtx_")
|
||||
foreign sokol_debugtext_clib {
|
||||
// initialization/shutdown
|
||||
setup :: proc(#by_ptr desc: Desc) ---
|
||||
shutdown :: proc() ---
|
||||
// builtin font data (use to populate sdtx_desc.font[])
|
||||
font_kc853 :: proc() -> Font_Desc ---
|
||||
font_kc854 :: proc() -> Font_Desc ---
|
||||
font_z1013 :: proc() -> Font_Desc ---
|
||||
font_cpc :: proc() -> Font_Desc ---
|
||||
font_c64 :: proc() -> Font_Desc ---
|
||||
font_oric :: proc() -> Font_Desc ---
|
||||
// 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 ---
|
||||
// drawing functions (call inside 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) ---
|
||||
// switch render layer
|
||||
layer :: proc(#any_int layer_id: c.int) ---
|
||||
// switch to a different font
|
||||
font :: proc(#any_int font_index: c.int) ---
|
||||
// set a new virtual canvas size in screen pixels
|
||||
canvas :: proc(w: f32, h: f32) ---
|
||||
// set a new origin in character grid coordinates
|
||||
origin :: proc(x: f32, y: f32) ---
|
||||
// cursor movement functions (relative to origin in character grid coordinates)
|
||||
home :: proc() ---
|
||||
pos :: proc(x: f32, y: f32) ---
|
||||
pos_x :: proc(x: f32) ---
|
||||
pos_y :: proc(y: f32) ---
|
||||
move :: proc(dx: f32, dy: f32) ---
|
||||
move_x :: proc(dx: f32) ---
|
||||
move_y :: proc(dy: f32) ---
|
||||
crlf :: proc() ---
|
||||
// set the current text color
|
||||
color3b :: proc(r: u8, g: u8, b: u8) ---
|
||||
color3f :: proc(r: f32, g: f32, b: f32) ---
|
||||
color4b :: proc(r: u8, g: u8, b: u8, a: u8) ---
|
||||
color4f :: proc(r: f32, g: f32, b: f32, a: f32) ---
|
||||
color1i :: proc(rgba: u32) ---
|
||||
// text rendering
|
||||
putc :: proc(c: u8) ---
|
||||
puts :: proc(str: cstring) ---
|
||||
putr :: proc(str: cstring, #any_int len: c.int) ---
|
||||
}
|
||||
|
||||
Log_Item :: enum i32 {
|
||||
OK,
|
||||
MALLOC_FAILED,
|
||||
ADD_COMMIT_LISTENER_FAILED,
|
||||
COMMAND_BUFFER_FULL,
|
||||
CONTEXT_POOL_EXHAUSTED,
|
||||
CANNOT_DESTROY_DEFAULT_CONTEXT,
|
||||
}
|
||||
|
||||
/*
|
||||
sdtx_logger_t
|
||||
|
||||
Used in sdtx_desc_t to provide a custom logging and error reporting
|
||||
callback to sokol-debugtext.
|
||||
*/
|
||||
Logger :: struct {
|
||||
func : proc "c" (a0: cstring, a1: u32, a2: u32, a3: cstring, a4: u32, a5: cstring, a6: rawptr),
|
||||
user_data : rawptr,
|
||||
}
|
||||
|
||||
// a rendering context handle
|
||||
Context :: struct {
|
||||
id : u32,
|
||||
}
|
||||
|
||||
/*
|
||||
sdtx_range is a pointer-size-pair struct used to pass memory
|
||||
blobs into sokol-debugtext. When initialized from a value type
|
||||
(array or struct), use the SDTX_RANGE() macro to build
|
||||
an sdtx_range struct.
|
||||
*/
|
||||
Range :: struct {
|
||||
ptr : rawptr,
|
||||
size : c.size_t,
|
||||
}
|
||||
|
||||
Font_Desc :: struct {
|
||||
data : Range,
|
||||
first_char : u8,
|
||||
last_char : u8,
|
||||
}
|
||||
|
||||
/*
|
||||
sdtx_context_desc_t
|
||||
|
||||
Describes the initialization parameters of a rendering context. Creating
|
||||
additional rendering contexts is useful if you want to render in
|
||||
different sokol-gfx rendering passes, or when rendering several layers
|
||||
of text.
|
||||
*/
|
||||
Context_Desc :: struct {
|
||||
max_commands : c.int,
|
||||
char_buf_size : c.int,
|
||||
canvas_width : f32,
|
||||
canvas_height : f32,
|
||||
tab_width : c.int,
|
||||
color_format : sg.Pixel_Format,
|
||||
depth_format : sg.Pixel_Format,
|
||||
sample_count : c.int,
|
||||
}
|
||||
|
||||
/*
|
||||
sdtx_allocator_t
|
||||
|
||||
Used in sdtx_desc_t to provide custom memory-alloc and -free functions
|
||||
to sokol_debugtext.h. If memory management should be overridden, both the
|
||||
alloc_fn and free_fn 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,
|
||||
}
|
||||
|
||||
/*
|
||||
sdtx_desc_t
|
||||
|
||||
Describes the sokol-debugtext API initialization parameters. Passed
|
||||
to the sdtx_setup() function.
|
||||
|
||||
NOTE: to populate the fonts item array with builtin fonts, use any
|
||||
of the following functions:
|
||||
|
||||
sdtx_font_kc853()
|
||||
sdtx_font_kc854()
|
||||
sdtx_font_z1013()
|
||||
sdtx_font_cpc()
|
||||
sdtx_font_c64()
|
||||
sdtx_font_oric()
|
||||
*/
|
||||
Desc :: struct {
|
||||
context_pool_size : c.int,
|
||||
printf_buf_size : c.int,
|
||||
fonts : [8]Font_Desc,
|
||||
ctx : Context_Desc,
|
||||
allocator : Allocator,
|
||||
logger : Logger,
|
||||
}
|
||||
|
4673
thirdparty/sokol/gfx/gfx.odin
vendored
Normal file
4673
thirdparty/sokol/gfx/gfx.odin
vendored
Normal file
File diff suppressed because it is too large
Load Diff
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,
|
||||
}
|
||||
|
164
thirdparty/sokol/glue/glue.odin
vendored
Normal file
164
thirdparty/sokol/glue/glue.odin
vendored
Normal file
@@ -0,0 +1,164 @@
|
||||
// machine generated, do not edit
|
||||
|
||||
package sokol_glue
|
||||
|
||||
/*
|
||||
|
||||
sokol_glue.h -- glue helper functions for sokol headers
|
||||
|
||||
Project URL: https://github.com/floooh/sokol
|
||||
|
||||
Do this:
|
||||
#define SOKOL_IMPL or
|
||||
#define SOKOL_GLUE_IMPL
|
||||
before you include this file in *one* C or C++ file to create the
|
||||
implementation.
|
||||
|
||||
...optionally provide the following macros to override defaults:
|
||||
|
||||
SOKOL_ASSERT(c) - your own assert macro (default: assert(c))
|
||||
SOKOL_GLUE_API_DECL - public function declaration prefix (default: extern)
|
||||
SOKOL_API_DECL - same as SOKOL_GLUE_API_DECL
|
||||
SOKOL_API_IMPL - public function implementation prefix (default: -)
|
||||
|
||||
If sokol_glue.h is compiled as a DLL, define the following before
|
||||
including the declaration or implementation:
|
||||
|
||||
SOKOL_DLL
|
||||
|
||||
On Windows, SOKOL_DLL will define SOKOL_GLUE_API_DECL as __declspec(dllexport)
|
||||
or __declspec(dllimport) as needed.
|
||||
|
||||
OVERVIEW
|
||||
========
|
||||
sokol_glue.h provides glue helper functions between sokol_gfx.h and sokol_app.h,
|
||||
so that sokol_gfx.h doesn't need to depend on sokol_app.h but can be
|
||||
used with different window system glue libraries.
|
||||
|
||||
PROVIDED FUNCTIONS
|
||||
==================
|
||||
|
||||
sg_environment sglue_environment(void)
|
||||
|
||||
Returns an sg_environment struct initialized by calling sokol_app.h
|
||||
functions. Use this in the sg_setup() call like this:
|
||||
|
||||
sg_setup(&(sg_desc){
|
||||
.environment = sglue_environment(),
|
||||
...
|
||||
});
|
||||
|
||||
sg_swapchain sglue_swapchain(void)
|
||||
|
||||
Returns an sg_swapchain struct initialized by calling sokol_app.h
|
||||
functions. Use this in sg_begin_pass() for a 'swapchain pass' like
|
||||
this:
|
||||
|
||||
sg_begin_pass(&(sg_pass){ .swapchain = sglue_swapchain(), ... });
|
||||
|
||||
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_GLUE_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_glue_clib { "../sokol_dll_windows_x64_gl_debug.lib" } }
|
||||
else { foreign import sokol_glue_clib { "../sokol_dll_windows_x64_gl_release.lib" } }
|
||||
} else {
|
||||
when DEBUG { foreign import sokol_glue_clib { "../sokol_dll_windows_x64_d3d11_debug.lib" } }
|
||||
else { foreign import sokol_glue_clib { "../sokol_dll_windows_x64_d3d11_release.lib" } }
|
||||
}
|
||||
} else {
|
||||
when USE_GL {
|
||||
when DEBUG { foreign import sokol_glue_clib { "sokol_glue_windows_x64_gl_debug.lib" } }
|
||||
else { foreign import sokol_glue_clib { "sokol_glue_windows_x64_gl_release.lib" } }
|
||||
} else {
|
||||
when DEBUG { foreign import sokol_glue_clib { "sokol_glue_windows_x64_d3d11_debug.lib" } }
|
||||
else { foreign import sokol_glue_clib { "sokol_glue_windows_x64_d3d11_release.lib" } }
|
||||
}
|
||||
}
|
||||
} else when ODIN_OS == .Darwin {
|
||||
when USE_DLL {
|
||||
when USE_GL && ODIN_ARCH == .arm64 && DEBUG { foreign import sokol_glue_clib { "../dylib/sokol_dylib_macos_arm64_gl_debug.dylib" } }
|
||||
else when USE_GL && ODIN_ARCH == .arm64 && !DEBUG { foreign import sokol_glue_clib { "../dylib/sokol_dylib_macos_arm64_gl_release.dylib" } }
|
||||
else when USE_GL && ODIN_ARCH == .amd64 && DEBUG { foreign import sokol_glue_clib { "../dylib/sokol_dylib_macos_x64_gl_debug.dylib" } }
|
||||
else when USE_GL && ODIN_ARCH == .amd64 && !DEBUG { foreign import sokol_glue_clib { "../dylib/sokol_dylib_macos_x64_gl_release.dylib" } }
|
||||
else when !USE_GL && ODIN_ARCH == .arm64 && DEBUG { foreign import sokol_glue_clib { "../dylib/sokol_dylib_macos_arm64_metal_debug.dylib" } }
|
||||
else when !USE_GL && ODIN_ARCH == .arm64 && !DEBUG { foreign import sokol_glue_clib { "../dylib/sokol_dylib_macos_arm64_metal_release.dylib" } }
|
||||
else when !USE_GL && ODIN_ARCH == .amd64 && DEBUG { foreign import sokol_glue_clib { "../dylib/sokol_dylib_macos_x64_metal_debug.dylib" } }
|
||||
else when !USE_GL && ODIN_ARCH == .amd64 && !DEBUG { foreign import sokol_glue_clib { "../dylib/sokol_dylib_macos_x64_metal_release.dylib" } }
|
||||
} else {
|
||||
when USE_GL {
|
||||
when ODIN_ARCH == .arm64 {
|
||||
when DEBUG { foreign import sokol_glue_clib { "sokol_glue_macos_arm64_gl_debug.a" } }
|
||||
else { foreign import sokol_glue_clib { "sokol_glue_macos_arm64_gl_release.a" } }
|
||||
} else {
|
||||
when DEBUG { foreign import sokol_glue_clib { "sokol_glue_macos_x64_gl_debug.a" } }
|
||||
else { foreign import sokol_glue_clib { "sokol_glue_macos_x64_gl_release.a" } }
|
||||
}
|
||||
} else {
|
||||
when ODIN_ARCH == .arm64 {
|
||||
when DEBUG { foreign import sokol_glue_clib { "sokol_glue_macos_arm64_metal_debug.a" } }
|
||||
else { foreign import sokol_glue_clib { "sokol_glue_macos_arm64_metal_release.a" } }
|
||||
} else {
|
||||
when DEBUG { foreign import sokol_glue_clib { "sokol_glue_macos_x64_metal_debug.a" } }
|
||||
else { foreign import sokol_glue_clib { "sokol_glue_macos_x64_metal_release.a" } }
|
||||
}
|
||||
}
|
||||
}
|
||||
} else when ODIN_OS == .Linux {
|
||||
when USE_DLL {
|
||||
when DEBUG { foreign import sokol_glue_clib { "sokol_glue_linux_x64_gl_debug.so" } }
|
||||
else { foreign import sokol_glue_clib { "sokol_glue_linux_x64_gl_release.so" } }
|
||||
} else {
|
||||
when DEBUG { foreign import sokol_glue_clib { "sokol_glue_linux_x64_gl_debug.a" } }
|
||||
else { foreign import sokol_glue_clib { "sokol_glue_linux_x64_gl_release.a" } }
|
||||
}
|
||||
} else when ODIN_ARCH == .wasm32 || ODIN_ARCH == .wasm64p32 {
|
||||
// Feed sokol_glue_wasm_gl_debug.a or sokol_glue_wasm_gl_release.a into emscripten compiler.
|
||||
foreign import sokol_glue_clib { "env.o" }
|
||||
} else {
|
||||
#panic("This OS is currently not supported")
|
||||
}
|
||||
|
||||
@(default_calling_convention="c", link_prefix="sglue_")
|
||||
foreign sokol_glue_clib {
|
||||
environment :: proc() -> sg.Environment ---
|
||||
swapchain :: proc() -> sg.Swapchain ---
|
||||
}
|
||||
|
38
thirdparty/sokol/helpers/allocator.odin
vendored
Normal file
38
thirdparty/sokol/helpers/allocator.odin
vendored
Normal file
@@ -0,0 +1,38 @@
|
||||
package sokol_helpers
|
||||
|
||||
// Use native odin allocators in sokol allocator interface
|
||||
|
||||
import sapp "../app"
|
||||
import sg "../gfx"
|
||||
import "base:runtime"
|
||||
import "core:c"
|
||||
|
||||
Allocator :: struct {
|
||||
alloc_fn: proc "c" (size: c.size_t, user_data: rawptr) -> rawptr,
|
||||
free_fn: proc "c" (ptr: rawptr, user_data: rawptr),
|
||||
user_data: rawptr,
|
||||
}
|
||||
|
||||
// context_ptr: a pointer to a context which persists during the lifetime of the program.
|
||||
// Note: you can transmute() this into a logger for any specific sokol library.
|
||||
allocator :: proc(context_ptr: ^runtime.Context) -> Allocator {
|
||||
return {
|
||||
alloc_fn = allocator_alloc_proc,
|
||||
free_fn = allocator_free_proc,
|
||||
user_data = cast(rawptr)context_ptr,
|
||||
}
|
||||
}
|
||||
|
||||
allocator_alloc_proc :: proc "c" (size: c.size_t, user_data: rawptr) -> rawptr {
|
||||
context = (cast(^runtime.Context)user_data)^
|
||||
bytes, err := runtime.mem_alloc(size = int(size))
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
return raw_data(bytes)
|
||||
}
|
||||
|
||||
allocator_free_proc :: proc "c" (ptr: rawptr, user_data: rawptr) {
|
||||
context = (cast(^runtime.Context)user_data)^
|
||||
runtime.mem_free(ptr)
|
||||
}
|
37
thirdparty/sokol/helpers/glue.odin
vendored
Normal file
37
thirdparty/sokol/helpers/glue.odin
vendored
Normal file
@@ -0,0 +1,37 @@
|
||||
package sokol_helpers
|
||||
|
||||
// Alternative native odin implementation of sokol_glue.h, in case you want to minimize C dependencies
|
||||
// (since sokol_glue is only a few lines of code)
|
||||
|
||||
import sapp "../app"
|
||||
import sg "../gfx"
|
||||
|
||||
glue_environment :: proc() -> (env: sg.Environment) {
|
||||
env.defaults.color_format = cast(sg.Pixel_Format)sapp.color_format()
|
||||
env.defaults.depth_format = cast(sg.Pixel_Format)sapp.depth_format()
|
||||
env.defaults.sample_count = sapp.sample_count()
|
||||
env.metal.device = sapp.metal_get_device()
|
||||
env.d3d11.device = sapp.d3d11_get_device()
|
||||
env.d3d11.device_context = sapp.d3d11_get_device_context()
|
||||
env.wgpu.device = sapp.wgpu_get_device()
|
||||
return env
|
||||
}
|
||||
|
||||
glue_swapchain :: proc() -> (swapchain: sg.Swapchain) {
|
||||
swapchain.width = sapp.width()
|
||||
swapchain.height = sapp.height()
|
||||
swapchain.sample_count = sapp.sample_count()
|
||||
swapchain.color_format = cast(sg.Pixel_Format)sapp.color_format()
|
||||
swapchain.depth_format = cast(sg.Pixel_Format)sapp.depth_format()
|
||||
swapchain.metal.current_drawable = sapp.metal_get_current_drawable()
|
||||
swapchain.metal.depth_stencil_texture = sapp.metal_get_depth_stencil_texture()
|
||||
swapchain.metal.msaa_color_texture = sapp.metal_get_msaa_color_texture()
|
||||
swapchain.d3d11.render_view = sapp.d3d11_get_render_view()
|
||||
swapchain.d3d11.resolve_view = sapp.d3d11_get_resolve_view()
|
||||
swapchain.d3d11.depth_stencil_view = sapp.d3d11_get_depth_stencil_view()
|
||||
swapchain.wgpu.render_view = sapp.wgpu_get_render_view()
|
||||
swapchain.wgpu.resolve_view = sapp.wgpu_get_resolve_view()
|
||||
swapchain.wgpu.depth_stencil_view = sapp.wgpu_get_depth_stencil_view()
|
||||
swapchain.gl.framebuffer = sapp.gl_get_framebuffer()
|
||||
return swapchain
|
||||
}
|
59
thirdparty/sokol/helpers/logger.odin
vendored
Normal file
59
thirdparty/sokol/helpers/logger.odin
vendored
Normal file
@@ -0,0 +1,59 @@
|
||||
package sokol_helpers
|
||||
|
||||
// Pass sokol logs into native odin logging system
|
||||
|
||||
import sapp "../app"
|
||||
import sg "../gfx"
|
||||
import "base:runtime"
|
||||
import "core:log"
|
||||
|
||||
Logger :: struct {
|
||||
func: proc "c" (
|
||||
tag: cstring,
|
||||
log_level: u32,
|
||||
log_item: u32,
|
||||
message: cstring,
|
||||
line_nr: u32,
|
||||
filename: cstring,
|
||||
user_data: rawptr,
|
||||
),
|
||||
user_data: rawptr,
|
||||
}
|
||||
|
||||
// context_ptr: a pointer to a context which persists during the lifetime of the program.
|
||||
// Note: you can transmute() this into a logger for any specific sokol library.
|
||||
logger :: proc "contextless" (context_ptr: ^runtime.Context) -> Logger {
|
||||
return {func = logger_proc, user_data = cast(rawptr)context_ptr}
|
||||
}
|
||||
|
||||
logger_proc :: proc "c" (
|
||||
tag: cstring,
|
||||
log_level: u32,
|
||||
log_item: u32,
|
||||
message: cstring,
|
||||
line_nr: u32,
|
||||
filename: cstring,
|
||||
user_data: rawptr,
|
||||
) {
|
||||
context = (cast(^runtime.Context)user_data)^
|
||||
|
||||
loc := runtime.Source_Code_Location {
|
||||
file_path = string(filename),
|
||||
line = i32(line_nr),
|
||||
}
|
||||
|
||||
level: log.Level
|
||||
switch log_level {
|
||||
case 0:
|
||||
log.panicf("Sokol Panic: (%i) %s: %s", log_item, tag, message, location = loc)
|
||||
|
||||
case 1:
|
||||
level = .Error
|
||||
case 2:
|
||||
level = .Warning
|
||||
case:
|
||||
level = .Info
|
||||
}
|
||||
|
||||
log.logf(level, "(%i) %s: %s", log_item, tag, message, location = loc)
|
||||
}
|
193
thirdparty/sokol/log/log.odin
vendored
Normal file
193
thirdparty/sokol/log/log.odin
vendored
Normal file
@@ -0,0 +1,193 @@
|
||||
// machine generated, do not edit
|
||||
|
||||
package sokol_log
|
||||
|
||||
/*
|
||||
|
||||
sokol_log.h -- common logging callback for sokol headers
|
||||
|
||||
Project URL: https://github.com/floooh/sokol
|
||||
|
||||
Example code: https://github.com/floooh/sokol-samples
|
||||
|
||||
Do this:
|
||||
#define SOKOL_IMPL or
|
||||
#define SOKOL_LOG_IMPL
|
||||
before you include this file in *one* C or C++ file to create the
|
||||
implementation.
|
||||
|
||||
Optionally provide the following defines when building the implementation:
|
||||
|
||||
SOKOL_ASSERT(c) - your own assert macro (default: assert(c))
|
||||
SOKOL_UNREACHABLE() - a guard macro for unreachable code (default: assert(false))
|
||||
SOKOL_LOG_API_DECL - public function declaration prefix (default: extern)
|
||||
SOKOL_API_DECL - same as SOKOL_GFX_API_DECL
|
||||
SOKOL_API_IMPL - public function implementation prefix (default: -)
|
||||
|
||||
Optionally define the following for verbose output:
|
||||
|
||||
SOKOL_DEBUG - by default this is defined if _DEBUG is defined
|
||||
|
||||
|
||||
OVERVIEW
|
||||
========
|
||||
sokol_log.h provides a default logging callback for other sokol headers.
|
||||
|
||||
To use the default log callback, just include sokol_log.h and provide
|
||||
a function pointer to the 'slog_func' function when setting up the
|
||||
sokol library:
|
||||
|
||||
For instance with sokol_audio.h:
|
||||
|
||||
#include "sokol_log.h"
|
||||
...
|
||||
saudio_setup(&(saudio_desc){ .logger.func = slog_func });
|
||||
|
||||
Logging output goes to stderr and/or a platform specific logging subsystem
|
||||
(which means that in some scenarios you might see logging messages duplicated):
|
||||
|
||||
- Windows: stderr + OutputDebugStringA()
|
||||
- macOS/iOS/Linux: stderr + syslog()
|
||||
- Emscripten: console.info()/warn()/error()
|
||||
- Android: __android_log_write()
|
||||
|
||||
On Windows with sokol_app.h also note the runtime config items to make
|
||||
stdout/stderr output visible on the console for WinMain() applications
|
||||
via sapp_desc.win32_console_attach or sapp_desc.win32_console_create,
|
||||
however when running in a debugger on Windows, the logging output should
|
||||
show up on the debug output UI panel.
|
||||
|
||||
In debug mode, a log message might look like this:
|
||||
|
||||
[sspine][error][id:12] /Users/floh/projects/sokol/util/sokol_spine.h:3472:0:
|
||||
SKELETON_DESC_NO_ATLAS: no atlas object provided in sspine_skeleton_desc.atlas
|
||||
|
||||
The source path and line number is formatted like compiler errors, in some IDEs (like VSCode)
|
||||
such error messages are clickable.
|
||||
|
||||
In release mode, logging is less verbose as to not bloat the executable with string data, but you still get
|
||||
enough information to identify the type and location of an error:
|
||||
|
||||
[sspine][error][id:12][line:3472]
|
||||
|
||||
RULES FOR WRITING YOUR OWN LOGGING FUNCTION
|
||||
===========================================
|
||||
- must be re-entrant because it might be called from different threads
|
||||
- must treat **all** provided string pointers as optional (can be null)
|
||||
- don't store the string pointers, copy the string data instead
|
||||
- must not return for log level panic
|
||||
|
||||
LICENSE
|
||||
=======
|
||||
zlib/libpng license
|
||||
|
||||
Copyright (c) 2023 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 "core:c"
|
||||
|
||||
_ :: c
|
||||
|
||||
SOKOL_DEBUG :: #config(SOKOL_DEBUG, ODIN_DEBUG)
|
||||
|
||||
DEBUG :: #config(SOKOL_LOG_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_log_clib { "../sokol_dll_windows_x64_gl_debug.lib" } }
|
||||
else { foreign import sokol_log_clib { "../sokol_dll_windows_x64_gl_release.lib" } }
|
||||
} else {
|
||||
when DEBUG { foreign import sokol_log_clib { "../sokol_dll_windows_x64_d3d11_debug.lib" } }
|
||||
else { foreign import sokol_log_clib { "../sokol_dll_windows_x64_d3d11_release.lib" } }
|
||||
}
|
||||
} else {
|
||||
when USE_GL {
|
||||
when DEBUG { foreign import sokol_log_clib { "sokol_log_windows_x64_gl_debug.lib" } }
|
||||
else { foreign import sokol_log_clib { "sokol_log_windows_x64_gl_release.lib" } }
|
||||
} else {
|
||||
when DEBUG { foreign import sokol_log_clib { "sokol_log_windows_x64_d3d11_debug.lib" } }
|
||||
else { foreign import sokol_log_clib { "sokol_log_windows_x64_d3d11_release.lib" } }
|
||||
}
|
||||
}
|
||||
} else when ODIN_OS == .Darwin {
|
||||
when USE_DLL {
|
||||
when USE_GL && ODIN_ARCH == .arm64 && DEBUG { foreign import sokol_log_clib { "../dylib/sokol_dylib_macos_arm64_gl_debug.dylib" } }
|
||||
else when USE_GL && ODIN_ARCH == .arm64 && !DEBUG { foreign import sokol_log_clib { "../dylib/sokol_dylib_macos_arm64_gl_release.dylib" } }
|
||||
else when USE_GL && ODIN_ARCH == .amd64 && DEBUG { foreign import sokol_log_clib { "../dylib/sokol_dylib_macos_x64_gl_debug.dylib" } }
|
||||
else when USE_GL && ODIN_ARCH == .amd64 && !DEBUG { foreign import sokol_log_clib { "../dylib/sokol_dylib_macos_x64_gl_release.dylib" } }
|
||||
else when !USE_GL && ODIN_ARCH == .arm64 && DEBUG { foreign import sokol_log_clib { "../dylib/sokol_dylib_macos_arm64_metal_debug.dylib" } }
|
||||
else when !USE_GL && ODIN_ARCH == .arm64 && !DEBUG { foreign import sokol_log_clib { "../dylib/sokol_dylib_macos_arm64_metal_release.dylib" } }
|
||||
else when !USE_GL && ODIN_ARCH == .amd64 && DEBUG { foreign import sokol_log_clib { "../dylib/sokol_dylib_macos_x64_metal_debug.dylib" } }
|
||||
else when !USE_GL && ODIN_ARCH == .amd64 && !DEBUG { foreign import sokol_log_clib { "../dylib/sokol_dylib_macos_x64_metal_release.dylib" } }
|
||||
} else {
|
||||
when USE_GL {
|
||||
when ODIN_ARCH == .arm64 {
|
||||
when DEBUG { foreign import sokol_log_clib { "sokol_log_macos_arm64_gl_debug.a" } }
|
||||
else { foreign import sokol_log_clib { "sokol_log_macos_arm64_gl_release.a" } }
|
||||
} else {
|
||||
when DEBUG { foreign import sokol_log_clib { "sokol_log_macos_x64_gl_debug.a" } }
|
||||
else { foreign import sokol_log_clib { "sokol_log_macos_x64_gl_release.a" } }
|
||||
}
|
||||
} else {
|
||||
when ODIN_ARCH == .arm64 {
|
||||
when DEBUG { foreign import sokol_log_clib { "sokol_log_macos_arm64_metal_debug.a" } }
|
||||
else { foreign import sokol_log_clib { "sokol_log_macos_arm64_metal_release.a" } }
|
||||
} else {
|
||||
when DEBUG { foreign import sokol_log_clib { "sokol_log_macos_x64_metal_debug.a" } }
|
||||
else { foreign import sokol_log_clib { "sokol_log_macos_x64_metal_release.a" } }
|
||||
}
|
||||
}
|
||||
}
|
||||
} else when ODIN_OS == .Linux {
|
||||
when USE_DLL {
|
||||
when DEBUG { foreign import sokol_log_clib { "sokol_log_linux_x64_gl_debug.so" } }
|
||||
else { foreign import sokol_log_clib { "sokol_log_linux_x64_gl_release.so" } }
|
||||
} else {
|
||||
when DEBUG { foreign import sokol_log_clib { "sokol_log_linux_x64_gl_debug.a" } }
|
||||
else { foreign import sokol_log_clib { "sokol_log_linux_x64_gl_release.a" } }
|
||||
}
|
||||
} else when ODIN_ARCH == .wasm32 || ODIN_ARCH == .wasm64p32 {
|
||||
// Feed sokol_log_wasm_gl_debug.a or sokol_log_wasm_gl_release.a into emscripten compiler.
|
||||
foreign import sokol_log_clib { "env.o" }
|
||||
} else {
|
||||
#panic("This OS is currently not supported")
|
||||
}
|
||||
|
||||
@(default_calling_convention="c", link_prefix="slog_")
|
||||
foreign sokol_log_clib {
|
||||
/*
|
||||
Plug this function into the 'logger.func' struct item when initializing any of the sokol
|
||||
headers. For instance for sokol_audio.h it would look like this:
|
||||
|
||||
saudio_setup(&(saudio_desc){
|
||||
.logger = {
|
||||
.func = slog_func
|
||||
}
|
||||
});
|
||||
*/
|
||||
func :: proc(tag: cstring, log_level: u32, log_item: u32, message: cstring, line_nr: u32, filename: cstring, user_data: rawptr) ---
|
||||
}
|
||||
|
581
thirdparty/sokol/shape/shape.odin
vendored
Normal file
581
thirdparty/sokol/shape/shape.odin
vendored
Normal file
@@ -0,0 +1,581 @@
|
||||
// machine generated, do not edit
|
||||
|
||||
package sokol_shape
|
||||
|
||||
/*
|
||||
|
||||
sokol_shape.h -- create simple primitive shapes for sokol_gfx.h
|
||||
|
||||
Project URL: https://github.com/floooh/sokol
|
||||
|
||||
Do this:
|
||||
#define SOKOL_IMPL or
|
||||
#define SOKOL_SHAPE_IMPL
|
||||
before you include this file in *one* C or C++ file to create the
|
||||
implementation.
|
||||
|
||||
Include the following headers before including sokol_shape.h:
|
||||
|
||||
sokol_gfx.h
|
||||
|
||||
...optionally provide the following macros to override defaults:
|
||||
|
||||
SOKOL_ASSERT(c) - your own assert macro (default: assert(c))
|
||||
SOKOL_SHAPE_API_DECL- public function declaration prefix (default: extern)
|
||||
SOKOL_API_DECL - same as SOKOL_SHAPE_API_DECL
|
||||
SOKOL_API_IMPL - public function implementation prefix (default: -)
|
||||
|
||||
If sokol_shape.h is compiled as a DLL, define the following before
|
||||
including the declaration or implementation:
|
||||
|
||||
SOKOL_DLL
|
||||
|
||||
On Windows, SOKOL_DLL will define SOKOL_SHAPE_API_DECL as __declspec(dllexport)
|
||||
or __declspec(dllimport) as needed.
|
||||
|
||||
FEATURE OVERVIEW
|
||||
================
|
||||
sokol_shape.h creates vertices and indices for simple shapes and
|
||||
builds structs which can be plugged into sokol-gfx resource
|
||||
creation functions:
|
||||
|
||||
The following shape types are supported:
|
||||
|
||||
- plane
|
||||
- cube
|
||||
- sphere (with poles, not geodesic)
|
||||
- cylinder
|
||||
- torus (donut)
|
||||
|
||||
Generated vertices look like this:
|
||||
|
||||
typedef struct sshape_vertex_t {
|
||||
float x, y, z;
|
||||
uint32_t normal; // packed normal as BYTE4N
|
||||
uint16_t u, v; // packed uv coords as USHORT2N
|
||||
uint32_t color; // packed color as UBYTE4N (r,g,b,a);
|
||||
} sshape_vertex_t;
|
||||
|
||||
Indices are generally 16-bits wide (SG_INDEXTYPE_UINT16) and the indices
|
||||
are written as triangle-lists (SG_PRIMITIVETYPE_TRIANGLES).
|
||||
|
||||
EXAMPLES:
|
||||
=========
|
||||
|
||||
Create multiple shapes into the same vertex- and index-buffer and
|
||||
render with separate draw calls:
|
||||
|
||||
https://github.com/floooh/sokol-samples/blob/master/sapp/shapes-sapp.c
|
||||
|
||||
Same as the above, but pre-transform shapes and merge them into a single
|
||||
shape that's rendered with a single draw call.
|
||||
|
||||
https://github.com/floooh/sokol-samples/blob/master/sapp/shapes-transform-sapp.c
|
||||
|
||||
STEP-BY-STEP:
|
||||
=============
|
||||
|
||||
Setup an sshape_buffer_t struct with pointers to memory buffers where
|
||||
generated vertices and indices will be written to:
|
||||
|
||||
```c
|
||||
sshape_vertex_t vertices[512];
|
||||
uint16_t indices[4096];
|
||||
|
||||
sshape_buffer_t buf = {
|
||||
.vertices = {
|
||||
.buffer = SSHAPE_RANGE(vertices),
|
||||
},
|
||||
.indices = {
|
||||
.buffer = SSHAPE_RANGE(indices),
|
||||
}
|
||||
};
|
||||
```
|
||||
|
||||
To find out how big those memory buffers must be (in case you want
|
||||
to allocate dynamically) call the following functions:
|
||||
|
||||
```c
|
||||
sshape_sizes_t sshape_plane_sizes(uint32_t tiles);
|
||||
sshape_sizes_t sshape_box_sizes(uint32_t tiles);
|
||||
sshape_sizes_t sshape_sphere_sizes(uint32_t slices, uint32_t stacks);
|
||||
sshape_sizes_t sshape_cylinder_sizes(uint32_t slices, uint32_t stacks);
|
||||
sshape_sizes_t sshape_torus_sizes(uint32_t sides, uint32_t rings);
|
||||
```
|
||||
|
||||
The returned sshape_sizes_t struct contains vertex- and index-counts
|
||||
as well as the equivalent buffer sizes in bytes. For instance:
|
||||
|
||||
```c
|
||||
sshape_sizes_t sizes = sshape_sphere_sizes(36, 12);
|
||||
uint32_t num_vertices = sizes.vertices.num;
|
||||
uint32_t num_indices = sizes.indices.num;
|
||||
uint32_t vertex_buffer_size = sizes.vertices.size;
|
||||
uint32_t index_buffer_size = sizes.indices.size;
|
||||
```
|
||||
|
||||
With the sshape_buffer_t struct that was setup earlier, call any
|
||||
of the shape-builder functions:
|
||||
|
||||
```c
|
||||
sshape_buffer_t sshape_build_plane(const sshape_buffer_t* buf, const sshape_plane_t* params);
|
||||
sshape_buffer_t sshape_build_box(const sshape_buffer_t* buf, const sshape_box_t* params);
|
||||
sshape_buffer_t sshape_build_sphere(const sshape_buffer_t* buf, const sshape_sphere_t* params);
|
||||
sshape_buffer_t sshape_build_cylinder(const sshape_buffer_t* buf, const sshape_cylinder_t* params);
|
||||
sshape_buffer_t sshape_build_torus(const sshape_buffer_t* buf, const sshape_torus_t* params);
|
||||
```
|
||||
|
||||
Note how the sshape_buffer_t struct is both an input value and the
|
||||
return value. This can be used to append multiple shapes into the
|
||||
same vertex- and index-buffers (more on this later).
|
||||
|
||||
The second argument is a struct which holds creation parameters.
|
||||
|
||||
For instance to build a sphere with radius 2, 36 "cake slices" and 12 stacks:
|
||||
|
||||
```c
|
||||
sshape_buffer_t buf = ...;
|
||||
buf = sshape_build_sphere(&buf, &(sshape_sphere_t){
|
||||
.radius = 2.0f,
|
||||
.slices = 36,
|
||||
.stacks = 12,
|
||||
});
|
||||
```
|
||||
|
||||
If the provided buffers are big enough to hold all generated vertices and
|
||||
indices, the "valid" field in the result will be true:
|
||||
|
||||
```c
|
||||
assert(buf.valid);
|
||||
```
|
||||
|
||||
The shape creation parameters have "useful defaults", refer to the
|
||||
actual C struct declarations below to look up those defaults.
|
||||
|
||||
You can also provide additional creation parameters, like a common vertex
|
||||
color, a debug-helper to randomize colors, tell the shape builder function
|
||||
to merge the new shape with the previous shape into the same draw-element-range,
|
||||
or a 4x4 transform matrix to move, rotate and scale the generated vertices:
|
||||
|
||||
```c
|
||||
sshape_buffer_t buf = ...;
|
||||
buf = sshape_build_sphere(&buf, &(sshape_sphere_t){
|
||||
.radius = 2.0f,
|
||||
.slices = 36,
|
||||
.stacks = 12,
|
||||
// merge with previous shape into a single element-range
|
||||
.merge = true,
|
||||
// set vertex color to red+opaque
|
||||
.color = sshape_color_4f(1.0f, 0.0f, 0.0f, 1.0f),
|
||||
// set position to y = 2.0
|
||||
.transform = {
|
||||
.m = {
|
||||
{ 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, 2.0f, 0.0f, 1.0f },
|
||||
}
|
||||
}
|
||||
});
|
||||
assert(buf.valid);
|
||||
```
|
||||
|
||||
The following helper functions can be used to build a packed
|
||||
color value or to convert from external matrix types:
|
||||
|
||||
```c
|
||||
uint32_t sshape_color_4f(float r, float g, float b, float a);
|
||||
uint32_t sshape_color_3f(float r, float g, float b);
|
||||
uint32_t sshape_color_4b(uint8_t r, uint8_t g, uint8_t b, uint8_t a);
|
||||
uint32_t sshape_color_3b(uint8_t r, uint8_t g, uint8_t b);
|
||||
sshape_mat4_t sshape_mat4(const float m[16]);
|
||||
sshape_mat4_t sshape_mat4_transpose(const float m[16]);
|
||||
```
|
||||
|
||||
After the shape builder function has been called, the following functions
|
||||
are used to extract the build result for plugging into sokol_gfx.h:
|
||||
|
||||
```c
|
||||
sshape_element_range_t sshape_element_range(const sshape_buffer_t* buf);
|
||||
sg_buffer_desc sshape_vertex_buffer_desc(const sshape_buffer_t* buf);
|
||||
sg_buffer_desc sshape_index_buffer_desc(const sshape_buffer_t* buf);
|
||||
sg_vertex_buffer_layout_state sshape_vertex_buffer_layout_state(void);
|
||||
sg_vertex_attr_state sshape_position_vertex_attr_state(void);
|
||||
sg_vertex_attr_state sshape_normal_vertex_attr_state(void);
|
||||
sg_vertex_attr_state sshape_texcoord_vertex_attr_state(void);
|
||||
sg_vertex_attr_state sshape_color_vertex_attr_state(void);
|
||||
```
|
||||
|
||||
The sshape_element_range_t struct contains the base-index and number of
|
||||
indices which can be plugged into the sg_draw() call:
|
||||
|
||||
```c
|
||||
sshape_element_range_t elms = sshape_element_range(&buf);
|
||||
...
|
||||
sg_draw(elms.base_element, elms.num_elements, 1);
|
||||
```
|
||||
|
||||
To create sokol-gfx vertex- and index-buffers from the generated
|
||||
shape data:
|
||||
|
||||
```c
|
||||
// create sokol-gfx vertex buffer
|
||||
sg_buffer_desc vbuf_desc = sshape_vertex_buffer_desc(&buf);
|
||||
sg_buffer vbuf = sg_make_buffer(&vbuf_desc);
|
||||
|
||||
// create sokol-gfx index buffer
|
||||
sg_buffer_desc ibuf_desc = sshape_index_buffer_desc(&buf);
|
||||
sg_buffer ibuf = sg_make_buffer(&ibuf_desc);
|
||||
```
|
||||
|
||||
The remaining functions are used to populate the vertex-layout item
|
||||
in sg_pipeline_desc, note that these functions don't depend on the
|
||||
created geometry, they always return the same result:
|
||||
|
||||
```c
|
||||
sg_pipeline pip = sg_make_pipeline(&(sg_pipeline_desc){
|
||||
.layout = {
|
||||
.buffers[0] = sshape_vertex_buffer_layout_state(),
|
||||
.attrs = {
|
||||
[0] = sshape_position_vertex_attr_state(),
|
||||
[1] = ssape_normal_vertex_attr_state(),
|
||||
[2] = sshape_texcoord_vertex_attr_state(),
|
||||
[3] = sshape_color_vertex_attr_state()
|
||||
}
|
||||
},
|
||||
...
|
||||
});
|
||||
```
|
||||
|
||||
Note that you don't have to use all generated vertex attributes in the
|
||||
pipeline's vertex layout, the sg_vertex_buffer_layout_state struct returned
|
||||
by sshape_vertex_buffer_layout_state() contains the correct vertex stride
|
||||
to skip vertex components.
|
||||
|
||||
WRITING MULTIPLE SHAPES INTO THE SAME BUFFER
|
||||
============================================
|
||||
You can merge multiple shapes into the same vertex- and
|
||||
index-buffers and either render them as a single shape, or
|
||||
in separate draw calls.
|
||||
|
||||
To build a single shape made of two cubes which can be rendered
|
||||
in a single draw-call:
|
||||
|
||||
```
|
||||
sshape_vertex_t vertices[128];
|
||||
uint16_t indices[16];
|
||||
|
||||
sshape_buffer_t buf = {
|
||||
.vertices.buffer = SSHAPE_RANGE(vertices),
|
||||
.indices.buffer = SSHAPE_RANGE(indices)
|
||||
};
|
||||
|
||||
// first cube at pos x=-2.0 (with default size of 1x1x1)
|
||||
buf = sshape_build_cube(&buf, &(sshape_box_t){
|
||||
.transform = {
|
||||
.m = {
|
||||
{ 1.0f, 0.0f, 0.0f, 0.0f },
|
||||
{ 0.0f, 1.0f, 0.0f, 0.0f },
|
||||
{ 0.0f, 0.0f, 1.0f, 0.0f },
|
||||
{-2.0f, 0.0f, 0.0f, 1.0f },
|
||||
}
|
||||
}
|
||||
});
|
||||
// ...and append another cube at pos pos=+1.0
|
||||
// NOTE the .merge = true, this tells the shape builder
|
||||
// function to not advance the current shape start offset
|
||||
buf = sshape_build_cube(&buf, &(sshape_box_t){
|
||||
.merge = true,
|
||||
.transform = {
|
||||
.m = {
|
||||
{ 1.0f, 0.0f, 0.0f, 0.0f },
|
||||
{ 0.0f, 1.0f, 0.0f, 0.0f },
|
||||
{ 0.0f, 0.0f, 1.0f, 0.0f },
|
||||
{-2.0f, 0.0f, 0.0f, 1.0f },
|
||||
}
|
||||
}
|
||||
});
|
||||
assert(buf.valid);
|
||||
|
||||
// skipping buffer- and pipeline-creation...
|
||||
|
||||
sshape_element_range_t elms = sshape_element_range(&buf);
|
||||
sg_draw(elms.base_element, elms.num_elements, 1);
|
||||
```
|
||||
|
||||
To render the two cubes in separate draw-calls, the element-ranges used
|
||||
in the sg_draw() calls must be captured right after calling the
|
||||
builder-functions:
|
||||
|
||||
```c
|
||||
sshape_vertex_t vertices[128];
|
||||
uint16_t indices[16];
|
||||
sshape_buffer_t buf = {
|
||||
.vertices.buffer = SSHAPE_RANGE(vertices),
|
||||
.indices.buffer = SSHAPE_RANGE(indices)
|
||||
};
|
||||
|
||||
// build a red cube...
|
||||
buf = sshape_build_cube(&buf, &(sshape_box_t){
|
||||
.color = sshape_color_3b(255, 0, 0)
|
||||
});
|
||||
sshape_element_range_t red_cube = sshape_element_range(&buf);
|
||||
|
||||
// append a green cube to the same vertex-/index-buffer:
|
||||
buf = sshape_build_cube(&bud, &sshape_box_t){
|
||||
.color = sshape_color_3b(0, 255, 0);
|
||||
});
|
||||
sshape_element_range_t green_cube = sshape_element_range(&buf);
|
||||
|
||||
// skipping buffer- and pipeline-creation...
|
||||
|
||||
sg_draw(red_cube.base_element, red_cube.num_elements, 1);
|
||||
sg_draw(green_cube.base_element, green_cube.num_elements, 1);
|
||||
```
|
||||
|
||||
...that's about all :)
|
||||
|
||||
LICENSE
|
||||
=======
|
||||
zlib/libpng license
|
||||
|
||||
Copyright (c) 2020 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_SHAPE_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_shape_clib { "../sokol_dll_windows_x64_gl_debug.lib" } }
|
||||
else { foreign import sokol_shape_clib { "../sokol_dll_windows_x64_gl_release.lib" } }
|
||||
} else {
|
||||
when DEBUG { foreign import sokol_shape_clib { "../sokol_dll_windows_x64_d3d11_debug.lib" } }
|
||||
else { foreign import sokol_shape_clib { "../sokol_dll_windows_x64_d3d11_release.lib" } }
|
||||
}
|
||||
} else {
|
||||
when USE_GL {
|
||||
when DEBUG { foreign import sokol_shape_clib { "sokol_shape_windows_x64_gl_debug.lib" } }
|
||||
else { foreign import sokol_shape_clib { "sokol_shape_windows_x64_gl_release.lib" } }
|
||||
} else {
|
||||
when DEBUG { foreign import sokol_shape_clib { "sokol_shape_windows_x64_d3d11_debug.lib" } }
|
||||
else { foreign import sokol_shape_clib { "sokol_shape_windows_x64_d3d11_release.lib" } }
|
||||
}
|
||||
}
|
||||
} else when ODIN_OS == .Darwin {
|
||||
when USE_DLL {
|
||||
when USE_GL && ODIN_ARCH == .arm64 && DEBUG { foreign import sokol_shape_clib { "../dylib/sokol_dylib_macos_arm64_gl_debug.dylib" } }
|
||||
else when USE_GL && ODIN_ARCH == .arm64 && !DEBUG { foreign import sokol_shape_clib { "../dylib/sokol_dylib_macos_arm64_gl_release.dylib" } }
|
||||
else when USE_GL && ODIN_ARCH == .amd64 && DEBUG { foreign import sokol_shape_clib { "../dylib/sokol_dylib_macos_x64_gl_debug.dylib" } }
|
||||
else when USE_GL && ODIN_ARCH == .amd64 && !DEBUG { foreign import sokol_shape_clib { "../dylib/sokol_dylib_macos_x64_gl_release.dylib" } }
|
||||
else when !USE_GL && ODIN_ARCH == .arm64 && DEBUG { foreign import sokol_shape_clib { "../dylib/sokol_dylib_macos_arm64_metal_debug.dylib" } }
|
||||
else when !USE_GL && ODIN_ARCH == .arm64 && !DEBUG { foreign import sokol_shape_clib { "../dylib/sokol_dylib_macos_arm64_metal_release.dylib" } }
|
||||
else when !USE_GL && ODIN_ARCH == .amd64 && DEBUG { foreign import sokol_shape_clib { "../dylib/sokol_dylib_macos_x64_metal_debug.dylib" } }
|
||||
else when !USE_GL && ODIN_ARCH == .amd64 && !DEBUG { foreign import sokol_shape_clib { "../dylib/sokol_dylib_macos_x64_metal_release.dylib" } }
|
||||
} else {
|
||||
when USE_GL {
|
||||
when ODIN_ARCH == .arm64 {
|
||||
when DEBUG { foreign import sokol_shape_clib { "sokol_shape_macos_arm64_gl_debug.a" } }
|
||||
else { foreign import sokol_shape_clib { "sokol_shape_macos_arm64_gl_release.a" } }
|
||||
} else {
|
||||
when DEBUG { foreign import sokol_shape_clib { "sokol_shape_macos_x64_gl_debug.a" } }
|
||||
else { foreign import sokol_shape_clib { "sokol_shape_macos_x64_gl_release.a" } }
|
||||
}
|
||||
} else {
|
||||
when ODIN_ARCH == .arm64 {
|
||||
when DEBUG { foreign import sokol_shape_clib { "sokol_shape_macos_arm64_metal_debug.a" } }
|
||||
else { foreign import sokol_shape_clib { "sokol_shape_macos_arm64_metal_release.a" } }
|
||||
} else {
|
||||
when DEBUG { foreign import sokol_shape_clib { "sokol_shape_macos_x64_metal_debug.a" } }
|
||||
else { foreign import sokol_shape_clib { "sokol_shape_macos_x64_metal_release.a" } }
|
||||
}
|
||||
}
|
||||
}
|
||||
} else when ODIN_OS == .Linux {
|
||||
when USE_DLL {
|
||||
when DEBUG { foreign import sokol_shape_clib { "sokol_shape_linux_x64_gl_debug.so" } }
|
||||
else { foreign import sokol_shape_clib { "sokol_shape_linux_x64_gl_release.so" } }
|
||||
} else {
|
||||
when DEBUG { foreign import sokol_shape_clib { "sokol_shape_linux_x64_gl_debug.a" } }
|
||||
else { foreign import sokol_shape_clib { "sokol_shape_linux_x64_gl_release.a" } }
|
||||
}
|
||||
} else when ODIN_ARCH == .wasm32 || ODIN_ARCH == .wasm64p32 {
|
||||
// Feed sokol_shape_wasm_gl_debug.a or sokol_shape_wasm_gl_release.a into emscripten compiler.
|
||||
foreign import sokol_shape_clib { "env.o" }
|
||||
} else {
|
||||
#panic("This OS is currently not supported")
|
||||
}
|
||||
|
||||
@(default_calling_convention="c", link_prefix="sshape_")
|
||||
foreign sokol_shape_clib {
|
||||
// shape builder functions
|
||||
build_plane :: proc(#by_ptr buf: Buffer, #by_ptr params: Plane) -> Buffer ---
|
||||
build_box :: proc(#by_ptr buf: Buffer, #by_ptr params: Box) -> Buffer ---
|
||||
build_sphere :: proc(#by_ptr buf: Buffer, #by_ptr params: Sphere) -> Buffer ---
|
||||
build_cylinder :: proc(#by_ptr buf: Buffer, #by_ptr params: Cylinder) -> Buffer ---
|
||||
build_torus :: proc(#by_ptr buf: Buffer, #by_ptr params: Torus) -> Buffer ---
|
||||
// query required vertex- and index-buffer sizes in bytes
|
||||
plane_sizes :: proc(tiles: u32) -> Sizes ---
|
||||
box_sizes :: proc(tiles: u32) -> Sizes ---
|
||||
sphere_sizes :: proc(slices: u32, stacks: u32) -> Sizes ---
|
||||
cylinder_sizes :: proc(slices: u32, stacks: u32) -> Sizes ---
|
||||
torus_sizes :: proc(sides: u32, rings: u32) -> Sizes ---
|
||||
// extract sokol-gfx desc structs and primitive ranges from build state
|
||||
element_range :: proc(#by_ptr buf: Buffer) -> Element_Range ---
|
||||
vertex_buffer_desc :: proc(#by_ptr buf: Buffer) -> sg.Buffer_Desc ---
|
||||
index_buffer_desc :: proc(#by_ptr buf: Buffer) -> sg.Buffer_Desc ---
|
||||
vertex_buffer_layout_state :: proc() -> sg.Vertex_Buffer_Layout_State ---
|
||||
position_vertex_attr_state :: proc() -> sg.Vertex_Attr_State ---
|
||||
normal_vertex_attr_state :: proc() -> sg.Vertex_Attr_State ---
|
||||
texcoord_vertex_attr_state :: proc() -> sg.Vertex_Attr_State ---
|
||||
color_vertex_attr_state :: proc() -> sg.Vertex_Attr_State ---
|
||||
// helper functions to build packed color value from floats or bytes
|
||||
color_4f :: proc(r: f32, g: f32, b: f32, a: f32) -> u32 ---
|
||||
color_3f :: proc(r: f32, g: f32, b: f32) -> u32 ---
|
||||
color_4b :: proc(r: u8, g: u8, b: u8, a: u8) -> u32 ---
|
||||
color_3b :: proc(r: u8, g: u8, b: u8) -> u32 ---
|
||||
// adapter function for filling matrix struct from generic float[16] array
|
||||
mat4 :: proc(m: ^f32) -> Mat4 ---
|
||||
mat4_transpose :: proc(m: ^f32) -> Mat4 ---
|
||||
}
|
||||
|
||||
/*
|
||||
sshape_range is a pointer-size-pair struct used to pass memory
|
||||
blobs into sokol-shape. When initialized from a value type
|
||||
(array or struct), use the SSHAPE_RANGE() macro to build
|
||||
an sshape_range struct.
|
||||
*/
|
||||
Range :: struct {
|
||||
ptr : rawptr,
|
||||
size : c.size_t,
|
||||
}
|
||||
|
||||
// a 4x4 matrix wrapper struct
|
||||
Mat4 :: struct {
|
||||
m : [4][4]f32,
|
||||
}
|
||||
|
||||
// vertex layout of the generated geometry
|
||||
Vertex :: struct {
|
||||
x : f32,
|
||||
y : f32,
|
||||
z : f32,
|
||||
normal : u32,
|
||||
u : u16,
|
||||
v : u16,
|
||||
color : u32,
|
||||
}
|
||||
|
||||
// a range of draw-elements (sg_draw(int base_element, int num_element, ...))
|
||||
Element_Range :: struct {
|
||||
base_element : c.int,
|
||||
num_elements : c.int,
|
||||
}
|
||||
|
||||
// number of elements and byte size of build actions
|
||||
Sizes_Item :: struct {
|
||||
num : u32,
|
||||
size : u32,
|
||||
}
|
||||
|
||||
Sizes :: struct {
|
||||
vertices : Sizes_Item,
|
||||
indices : Sizes_Item,
|
||||
}
|
||||
|
||||
// in/out struct to keep track of mesh-build state
|
||||
Buffer_Item :: struct {
|
||||
buffer : Range,
|
||||
data_size : c.size_t,
|
||||
shape_offset : c.size_t,
|
||||
}
|
||||
|
||||
Buffer :: struct {
|
||||
valid : bool,
|
||||
vertices : Buffer_Item,
|
||||
indices : Buffer_Item,
|
||||
}
|
||||
|
||||
// creation parameters for the different shape types
|
||||
Plane :: struct {
|
||||
width : f32,
|
||||
depth : f32,
|
||||
tiles : u16,
|
||||
color : u32,
|
||||
random_colors : bool,
|
||||
merge : bool,
|
||||
transform : Mat4,
|
||||
}
|
||||
|
||||
Box :: struct {
|
||||
width : f32,
|
||||
height : f32,
|
||||
depth : f32,
|
||||
tiles : u16,
|
||||
color : u32,
|
||||
random_colors : bool,
|
||||
merge : bool,
|
||||
transform : Mat4,
|
||||
}
|
||||
|
||||
Sphere :: struct {
|
||||
radius : f32,
|
||||
slices : u16,
|
||||
stacks : u16,
|
||||
color : u32,
|
||||
random_colors : bool,
|
||||
merge : bool,
|
||||
transform : Mat4,
|
||||
}
|
||||
|
||||
Cylinder :: struct {
|
||||
radius : f32,
|
||||
height : f32,
|
||||
slices : u16,
|
||||
stacks : u16,
|
||||
color : u32,
|
||||
random_colors : bool,
|
||||
merge : bool,
|
||||
transform : Mat4,
|
||||
}
|
||||
|
||||
Torus :: struct {
|
||||
radius : f32,
|
||||
ring_radius : f32,
|
||||
sides : u16,
|
||||
rings : u16,
|
||||
color : u32,
|
||||
random_colors : bool,
|
||||
merge : bool,
|
||||
transform : Mat4,
|
||||
}
|
||||
|
196
thirdparty/sokol/time/time.odin
vendored
Normal file
196
thirdparty/sokol/time/time.odin
vendored
Normal file
@@ -0,0 +1,196 @@
|
||||
// machine generated, do not edit
|
||||
|
||||
package sokol_time
|
||||
|
||||
/*
|
||||
|
||||
sokol_time.h -- simple cross-platform time measurement
|
||||
|
||||
Project URL: https://github.com/floooh/sokol
|
||||
|
||||
Do this:
|
||||
#define SOKOL_IMPL or
|
||||
#define SOKOL_TIME_IMPL
|
||||
before you include this file in *one* C or C++ file to create the
|
||||
implementation.
|
||||
|
||||
Optionally provide the following defines with your own implementations:
|
||||
SOKOL_ASSERT(c) - your own assert macro (default: assert(c))
|
||||
SOKOL_TIME_API_DECL - public function declaration prefix (default: extern)
|
||||
SOKOL_API_DECL - same as SOKOL_TIME_API_DECL
|
||||
SOKOL_API_IMPL - public function implementation prefix (default: -)
|
||||
|
||||
If sokol_time.h is compiled as a DLL, define the following before
|
||||
including the declaration or implementation:
|
||||
|
||||
SOKOL_DLL
|
||||
|
||||
On Windows, SOKOL_DLL will define SOKOL_TIME_API_DECL as __declspec(dllexport)
|
||||
or __declspec(dllimport) as needed.
|
||||
|
||||
void stm_setup();
|
||||
Call once before any other functions to initialize sokol_time
|
||||
(this calls for instance QueryPerformanceFrequency on Windows)
|
||||
|
||||
uint64_t stm_now();
|
||||
Get current point in time in unspecified 'ticks'. The value that
|
||||
is returned has no relation to the 'wall-clock' time and is
|
||||
not in a specific time unit, it is only useful to compute
|
||||
time differences.
|
||||
|
||||
uint64_t stm_diff(uint64_t new, uint64_t old);
|
||||
Computes the time difference between new and old. This will always
|
||||
return a positive, non-zero value.
|
||||
|
||||
uint64_t stm_since(uint64_t start);
|
||||
Takes the current time, and returns the elapsed time since start
|
||||
(this is a shortcut for "stm_diff(stm_now(), start)")
|
||||
|
||||
uint64_t stm_laptime(uint64_t* last_time);
|
||||
This is useful for measuring frame time and other recurring
|
||||
events. It takes the current time, returns the time difference
|
||||
to the value in last_time, and stores the current time in
|
||||
last_time for the next call. If the value in last_time is 0,
|
||||
the return value will be zero (this usually happens on the
|
||||
very first call).
|
||||
|
||||
uint64_t stm_round_to_common_refresh_rate(uint64_t duration)
|
||||
This oddly named function takes a measured frame time and
|
||||
returns the closest "nearby" common display refresh rate frame duration
|
||||
in ticks. If the input duration isn't close to any common display
|
||||
refresh rate, the input duration will be returned unchanged as a fallback.
|
||||
The main purpose of this function is to remove jitter/inaccuracies from
|
||||
measured frame times, and instead use the display refresh rate as
|
||||
frame duration.
|
||||
NOTE: for more robust frame timing, consider using the
|
||||
sokol_app.h function sapp_frame_duration()
|
||||
|
||||
Use the following functions to convert a duration in ticks into
|
||||
useful time units:
|
||||
|
||||
double stm_sec(uint64_t ticks);
|
||||
double stm_ms(uint64_t ticks);
|
||||
double stm_us(uint64_t ticks);
|
||||
double stm_ns(uint64_t ticks);
|
||||
Converts a tick value into seconds, milliseconds, microseconds
|
||||
or nanoseconds. Note that not all platforms will have nanosecond
|
||||
or even microsecond precision.
|
||||
|
||||
Uses the following time measurement functions under the hood:
|
||||
|
||||
Windows: QueryPerformanceFrequency() / QueryPerformanceCounter()
|
||||
MacOS/iOS: mach_absolute_time()
|
||||
emscripten: emscripten_get_now()
|
||||
Linux+others: clock_gettime(CLOCK_MONOTONIC)
|
||||
|
||||
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 "core:c"
|
||||
|
||||
_ :: c
|
||||
|
||||
SOKOL_DEBUG :: #config(SOKOL_DEBUG, ODIN_DEBUG)
|
||||
|
||||
DEBUG :: #config(SOKOL_TIME_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_time_clib { "../sokol_dll_windows_x64_gl_debug.lib" } }
|
||||
else { foreign import sokol_time_clib { "../sokol_dll_windows_x64_gl_release.lib" } }
|
||||
} else {
|
||||
when DEBUG { foreign import sokol_time_clib { "../sokol_dll_windows_x64_d3d11_debug.lib" } }
|
||||
else { foreign import sokol_time_clib { "../sokol_dll_windows_x64_d3d11_release.lib" } }
|
||||
}
|
||||
} else {
|
||||
when USE_GL {
|
||||
when DEBUG { foreign import sokol_time_clib { "sokol_time_windows_x64_gl_debug.lib" } }
|
||||
else { foreign import sokol_time_clib { "sokol_time_windows_x64_gl_release.lib" } }
|
||||
} else {
|
||||
when DEBUG { foreign import sokol_time_clib { "sokol_time_windows_x64_d3d11_debug.lib" } }
|
||||
else { foreign import sokol_time_clib { "sokol_time_windows_x64_d3d11_release.lib" } }
|
||||
}
|
||||
}
|
||||
} else when ODIN_OS == .Darwin {
|
||||
when USE_DLL {
|
||||
when USE_GL && ODIN_ARCH == .arm64 && DEBUG { foreign import sokol_time_clib { "../dylib/sokol_dylib_macos_arm64_gl_debug.dylib" } }
|
||||
else when USE_GL && ODIN_ARCH == .arm64 && !DEBUG { foreign import sokol_time_clib { "../dylib/sokol_dylib_macos_arm64_gl_release.dylib" } }
|
||||
else when USE_GL && ODIN_ARCH == .amd64 && DEBUG { foreign import sokol_time_clib { "../dylib/sokol_dylib_macos_x64_gl_debug.dylib" } }
|
||||
else when USE_GL && ODIN_ARCH == .amd64 && !DEBUG { foreign import sokol_time_clib { "../dylib/sokol_dylib_macos_x64_gl_release.dylib" } }
|
||||
else when !USE_GL && ODIN_ARCH == .arm64 && DEBUG { foreign import sokol_time_clib { "../dylib/sokol_dylib_macos_arm64_metal_debug.dylib" } }
|
||||
else when !USE_GL && ODIN_ARCH == .arm64 && !DEBUG { foreign import sokol_time_clib { "../dylib/sokol_dylib_macos_arm64_metal_release.dylib" } }
|
||||
else when !USE_GL && ODIN_ARCH == .amd64 && DEBUG { foreign import sokol_time_clib { "../dylib/sokol_dylib_macos_x64_metal_debug.dylib" } }
|
||||
else when !USE_GL && ODIN_ARCH == .amd64 && !DEBUG { foreign import sokol_time_clib { "../dylib/sokol_dylib_macos_x64_metal_release.dylib" } }
|
||||
} else {
|
||||
when USE_GL {
|
||||
when ODIN_ARCH == .arm64 {
|
||||
when DEBUG { foreign import sokol_time_clib { "sokol_time_macos_arm64_gl_debug.a" } }
|
||||
else { foreign import sokol_time_clib { "sokol_time_macos_arm64_gl_release.a" } }
|
||||
} else {
|
||||
when DEBUG { foreign import sokol_time_clib { "sokol_time_macos_x64_gl_debug.a" } }
|
||||
else { foreign import sokol_time_clib { "sokol_time_macos_x64_gl_release.a" } }
|
||||
}
|
||||
} else {
|
||||
when ODIN_ARCH == .arm64 {
|
||||
when DEBUG { foreign import sokol_time_clib { "sokol_time_macos_arm64_metal_debug.a" } }
|
||||
else { foreign import sokol_time_clib { "sokol_time_macos_arm64_metal_release.a" } }
|
||||
} else {
|
||||
when DEBUG { foreign import sokol_time_clib { "sokol_time_macos_x64_metal_debug.a" } }
|
||||
else { foreign import sokol_time_clib { "sokol_time_macos_x64_metal_release.a" } }
|
||||
}
|
||||
}
|
||||
}
|
||||
} else when ODIN_OS == .Linux {
|
||||
when USE_DLL {
|
||||
when DEBUG { foreign import sokol_time_clib { "sokol_time_linux_x64_gl_debug.so" } }
|
||||
else { foreign import sokol_time_clib { "sokol_time_linux_x64_gl_release.so" } }
|
||||
} else {
|
||||
when DEBUG { foreign import sokol_time_clib { "sokol_time_linux_x64_gl_debug.a" } }
|
||||
else { foreign import sokol_time_clib { "sokol_time_linux_x64_gl_release.a" } }
|
||||
}
|
||||
} else when ODIN_ARCH == .wasm32 || ODIN_ARCH == .wasm64p32 {
|
||||
// Feed sokol_time_wasm_gl_debug.a or sokol_time_wasm_gl_release.a into emscripten compiler.
|
||||
foreign import sokol_time_clib { "env.o" }
|
||||
} else {
|
||||
#panic("This OS is currently not supported")
|
||||
}
|
||||
|
||||
@(default_calling_convention="c", link_prefix="stm_")
|
||||
foreign sokol_time_clib {
|
||||
setup :: proc() ---
|
||||
now :: proc() -> u64 ---
|
||||
diff :: proc(new_ticks: u64, old_ticks: u64) -> u64 ---
|
||||
since :: proc(start_ticks: u64) -> u64 ---
|
||||
laptime :: proc(last_time: ^u64) -> u64 ---
|
||||
round_to_common_refresh_rate :: proc(frame_ticks: u64) -> u64 ---
|
||||
sec :: proc(ticks: u64) -> f64 ---
|
||||
ms :: proc(ticks: u64) -> f64 ---
|
||||
us :: proc(ticks: u64) -> f64 ---
|
||||
ns :: proc(ticks: u64) -> f64 ---
|
||||
}
|
||||
|
Reference in New Issue
Block a user