Compare commits

...

2 commits

Author SHA1 Message Date
John Alanbrook 011d1d99d5 Update sokol gfx 2024-05-09 21:15:19 -05:00
John Alanbrook d43d9d8fe3 Move buffer binding assignment to javascript 2024-05-09 20:37:11 -05:00
9 changed files with 859 additions and 239 deletions

View file

@ -544,6 +544,7 @@ int mat2type(int mat)
switch(mat) { switch(mat) {
case MAT_POS: case MAT_POS:
return SG_VERTEXFORMAT_FLOAT3; return SG_VERTEXFORMAT_FLOAT3;
case MAT_PPOS:
case MAT_WH: case MAT_WH:
case MAT_ST: case MAT_ST:
return SG_VERTEXFORMAT_FLOAT2; return SG_VERTEXFORMAT_FLOAT2;
@ -558,11 +559,26 @@ int mat2type(int mat)
case MAT_COLOR: case MAT_COLOR:
return SG_VERTEXFORMAT_UBYTE4N; return SG_VERTEXFORMAT_UBYTE4N;
case MAT_ANGLE: case MAT_ANGLE:
case MAT_SCALE:
return SG_VERTEXFORMAT_FLOAT; return SG_VERTEXFORMAT_FLOAT;
}; };
return 0; return 0;
} }
int mat2step(int mat)
{
switch(mat) {
case MAT_POS:
case MAT_UV:
case MAT_TAN:
case MAT_NORM:
case MAT_BONE:
case MAT_WEIGHT:
return SG_VERTEXSTEP_PER_VERTEX;
};
return SG_VERTEXSTEP_PER_INSTANCE;
}
sg_buffer mat2buffer(int mat, primitive *p) sg_buffer mat2buffer(int mat, primitive *p)
{ {
switch(mat) { switch(mat) {

View file

@ -18,6 +18,8 @@
#define MAT_ANGLE 7 #define MAT_ANGLE 7
#define MAT_WH 8 #define MAT_WH 8
#define MAT_ST 9 #define MAT_ST 9
#define MAT_PPOS 10
#define MAT_SCALE 11
typedef struct material { typedef struct material {
struct texture *diffuse; struct texture *diffuse;

View file

@ -17,9 +17,12 @@
#include "sokol/sokol_gfx.h" #include "sokol/sokol_gfx.h"
sg_shader vid_shader; void datastream_free(datastream *ds)
sg_pipeline vid_pipeline; {
sg_bindings vid_bind; sg_destroy_image(ds->img);
plm_destroy(ds->plm);
free(ds);
}
void soundstream_fillbuf(struct datastream *ds, soundbyte *buf, int frames) { void soundstream_fillbuf(struct datastream *ds, soundbyte *buf, int frames) {
for (int i = 0; i < frames*CHANNELS; i++) for (int i = 0; i < frames*CHANNELS; i++)
@ -27,17 +30,14 @@ void soundstream_fillbuf(struct datastream *ds, soundbyte *buf, int frames) {
} }
static void render_frame(plm_t *mpeg, plm_frame_t *frame, struct datastream *ds) { static void render_frame(plm_t *mpeg, plm_frame_t *frame, struct datastream *ds) {
return; if (ds->dirty) return;
uint8_t rgb[frame->height*frame->width*4]; uint8_t rgb[frame->height*frame->width*4];
memset(rgb,255,frame->height*frame->width*4);
plm_frame_to_rgba(frame, rgb, frame->width*4); plm_frame_to_rgba(frame, rgb, frame->width*4);
sg_image_data imgd; sg_image_data imgd = {0};
sg_range ir = { imgd.subimage[0][0] = SG_RANGE(rgb);
.ptr = rgb,
.size = frame->height*frame->width*4*sizeof(uint8_t)
};
imgd.subimage[0][0] = ir;
sg_update_image(ds->img, &imgd); sg_update_image(ds->img, &imgd);
ds->dirty = true;
} }
static void render_audio(plm_t *mpeg, plm_samples_t *samples, struct datastream *ds) { static void render_audio(plm_t *mpeg, plm_samples_t *samples, struct datastream *ds) {
@ -62,19 +62,24 @@ struct datastream *ds_openvideo(const char *path)
path, path,
plm_get_framerate(ds->plm), plm_get_framerate(ds->plm),
plm_get_samplerate(ds->plm), plm_get_samplerate(ds->plm),
plm_get_num_audio_streams(ds->plm), plm_get_num_audio_streams(ds->plm),
plm_get_duration(ds->plm)); plm_get_duration(ds->plm));
ds->img = sg_make_image(&(sg_image_desc){ ds->img = sg_make_image(&(sg_image_desc){
.width = plm_get_width(ds->plm), .width = plm_get_width(ds->plm),
.height = plm_get_height(ds->plm) .height = plm_get_height(ds->plm),
.usage = SG_USAGE_STREAM,
.type = SG_IMAGETYPE_2D,
.pixel_format = SG_PIXELFORMAT_RGBA8,
}); });
plm_set_video_decode_callback(ds->plm, render_frame, ds);
return ds;
ds->ring = ringnew(ds->ring, 8192); ds->ring = ringnew(ds->ring, 8192);
plugin_node(make_node(ds, soundstream_fillbuf, NULL), masterbus); plugin_node(make_node(ds, soundstream_fillbuf, NULL), masterbus);
plm_set_video_decode_callback(ds->plm, render_frame, ds);
plm_set_audio_decode_callback(ds->plm, render_audio, ds); plm_set_audio_decode_callback(ds->plm, render_audio, ds);
plm_set_loop(ds->plm, false); plm_set_loop(ds->plm, false);
@ -84,13 +89,12 @@ struct datastream *ds_openvideo(const char *path)
// Adjust the audio lead time according to the audio_spec buffer size // Adjust the audio lead time according to the audio_spec buffer size
plm_set_audio_lead_time(ds->plm, BUF_FRAMES / SAMPLERATE); plm_set_audio_lead_time(ds->plm, BUF_FRAMES / SAMPLERATE);
ds->playing = true;
return ds; return ds;
} }
void ds_advance(struct datastream *ds, double s) { void ds_advance(struct datastream *ds, double s) {
if (ds->playing) plm_decode(ds->plm, s); ds->dirty = false;
plm_decode(ds->plm, s);
} }
void ds_seek(struct datastream *ds, double time) { void ds_seek(struct datastream *ds, double time) {
@ -104,31 +108,6 @@ void ds_advanceframes(struct datastream *ds, int frames) {
} }
} }
void ds_pause(struct datastream *ds) {
ds->playing = false;
}
void ds_stop(struct datastream *ds) {
if (ds->plm != NULL) {
plm_destroy(ds->plm);
ds->plm = NULL;
}
ds->playing = false;
}
// TODO: Must be a better way
int ds_videodone(struct datastream *ds) {
return (ds->plm == NULL) || plm_get_time(ds->plm) >= plm_get_duration(ds->plm);
}
double ds_remainingtime(struct datastream *ds) {
if (ds->plm != NULL)
return plm_get_duration(ds->plm) - plm_get_time(ds->plm);
else
return 0.f;
}
double ds_length(struct datastream *ds) { double ds_length(struct datastream *ds) {
return plm_get_duration(ds->plm); return plm_get_duration(ds->plm);
} }

View file

@ -11,16 +11,22 @@ struct soundstream;
struct datastream { struct datastream {
plm_t *plm; plm_t *plm;
double last_time;
int playing;
sg_image img; sg_image img;
sg_image y;
sg_image cr;
sg_image cb;
int width; int width;
int height; int height;
int dirty;
soundbyte *ring; soundbyte *ring;
}; };
typedef struct datastream datastream;
struct texture; struct texture;
void datastream_free(datastream *ds);
struct datastream *ds_openvideo(const char *path); struct datastream *ds_openvideo(const char *path);
struct texture *ds_maketexture(struct datastream *); struct texture *ds_maketexture(struct datastream *);
void ds_advance(struct datastream *ds, double); void ds_advance(struct datastream *ds, double);

View file

@ -83,6 +83,7 @@ QJSCLASS(window)
QJSCLASS(constraint) QJSCLASS(constraint)
QJSCLASS(primitive) QJSCLASS(primitive)
QJSCLASS(sg_buffer) QJSCLASS(sg_buffer)
QJSCLASS(datastream)
static JSValue sound_proto; static JSValue sound_proto;
sound *js2sound(JSValue v) { return js2dsp_node(v)->data; } sound *js2sound(JSValue v) { return js2dsp_node(v)->data; }
@ -590,18 +591,23 @@ static const JSCFunctionListEntry js_warp_damp_funcs [] = {
CGETSET_ADD(warp_damp, damp) CGETSET_ADD(warp_damp, damp)
}; };
sg_bindings js2bind(JSValue mat, JSValue prim) sg_bindings js2bind(JSValue v)
{ {
sg_bindings bind = {0}; sg_bindings bind = {0};
for (int i = 0; i < js_arrlen(mat); i++) { JSValue attrib = js_getpropstr(v, "attrib");
bind.fs.images[i] = js2texture(js_getpropidx(mat, i))->id; for (int i = 0; i < js_arrlen(attrib); i++)
bind.vertex_buffers[i] = *js2sg_buffer(js_getpropidx(attrib,i));
JSValue index = js_getpropstr(v, "index");
if (!JS_IsUndefined(index))
bind.index_buffer = *js2sg_buffer(index);
JSValue imgs = js_getpropstr(v, "images");
for (int i = 0; i < js_arrlen(imgs); i++) {
bind.fs.images[i] = js2texture(js_getpropidx(imgs, i))->id;
bind.fs.samplers[i] = std_sampler; bind.fs.samplers[i] = std_sampler;
} }
bind.vertex_buffers[0] = *js2sg_buffer(js_getpropstr(prim, "pos"));
bind.index_buffer = *js2sg_buffer(js_getpropstr(prim, "index"));
bind.vertex_buffers[1] = *js2sg_buffer(js_getpropstr(prim, "uv"));
return bind; return bind;
} }
@ -624,7 +630,7 @@ JSC_GETSET(emitter, persist_var, number)
JSC_GETSET(emitter, warp_mask, bitmask) JSC_GETSET(emitter, warp_mask, bitmask)
JSC_CCALL(emitter_emit, emitter_emit(js2emitter(this), js2number(argv[0]), js2transform2d(argv[1]))) JSC_CCALL(emitter_emit, emitter_emit(js2emitter(this), js2number(argv[0]), js2transform2d(argv[1])))
JSC_CCALL(emitter_step, emitter_step(js2emitter(this), js2number(argv[0]), js2transform2d(argv[1]))) JSC_CCALL(emitter_step, emitter_step(js2emitter(this), js2number(argv[0]), js2transform2d(argv[1])))
JSC_CCALL(emitter_draw, emitter_draw(js2emitter(this), js2bind(argv[0], argv[1]))) JSC_CCALL(emitter_draw, emitter_draw(js2emitter(this), js2bind(argv[0])))
JSC_CCALL(render_flushtext, text_flush()) JSC_CCALL(render_flushtext, text_flush())
@ -664,11 +670,11 @@ JSC_CCALL(render_end_pass,
} }
p.id = js2number(argv[0]); p.id = js2number(argv[0]);
sg_apply_pipeline(p); sg_apply_pipeline(p);
sg_bindings bind = js2bind(argv[1], argv[2]); sg_bindings bind = js2bind(argv[1]);
bind.fs.images[0] = screencolor; bind.fs.images[0] = screencolor;
bind.fs.samplers[0] = std_sampler; bind.fs.samplers[0] = std_sampler;
sg_apply_bindings(&bind); sg_apply_bindings(&bind);
int c = js2number(js_getpropstr(argv[2], "count")); int c = js2number(js_getpropstr(argv[1], "count"));
sg_draw(0,c,1); sg_draw(0,c,1);
sg_end_pass(); sg_end_pass();
@ -730,8 +736,9 @@ sg_shader js2shader(JSValue v)
JSValue pairs = js_getpropstr(fs, "image_sampler_pairs"); JSValue pairs = js_getpropstr(fs, "image_sampler_pairs");
unin = js_arrlen(pairs); unin = js_arrlen(pairs);
for (int i = 0; i < unin; i++) { for (int i = 0; i < unin; i++) {
JSValue pair = js_getpropidx(pairs, i);
desc.fs.image_sampler_pairs[0].used = true; desc.fs.image_sampler_pairs[0].used = true;
desc.fs.image_sampler_pairs[0].image_slot = 0; desc.fs.image_sampler_pairs[0].image_slot = js2number(js_getpropstr(pair, "slot"));
desc.fs.image_sampler_pairs[0].sampler_slot = 0; desc.fs.image_sampler_pairs[0].sampler_slot = 0;
} }
@ -779,22 +786,31 @@ JSC_CCALL(render_pipeline,
) )
JSC_CCALL(render_setuniv, JSC_CCALL(render_setuniv,
float f = js2number(argv[2]); HMM_Vec4 f = {0};
f.x = js2number(argv[2]);
sg_apply_uniforms(js2number(argv[0]), js2number(argv[1]), SG_RANGE_REF(f)); sg_apply_uniforms(js2number(argv[0]), js2number(argv[1]), SG_RANGE_REF(f));
) )
JSC_CCALL(render_setuniv2, JSC_CCALL(render_setuniv2,
HMM_Vec2 v = js2vec2(argv[2]); HMM_Vec4 v;
v.xy = js2vec2(argv[2]);
sg_apply_uniforms(js2number(argv[0]), js2number(argv[1]), SG_RANGE_REF(v.e)); sg_apply_uniforms(js2number(argv[0]), js2number(argv[1]), SG_RANGE_REF(v.e));
) )
JSC_CCALL(render_setuniv3, JSC_CCALL(render_setuniv3,
HMM_Vec3 v = js2vec3(argv[2]); HMM_Vec4 f = {0};
sg_apply_uniforms(js2number(argv[0]), js2number(argv[1]), SG_RANGE_REF(v.e)); f.xyz = js2vec3(argv[2]);
sg_apply_uniforms(js2number(argv[0]), js2number(argv[1]), SG_RANGE_REF(f.e));
) )
JSC_CCALL(render_setuniv4, JSC_CCALL(render_setuniv4,
HMM_Vec4 v = js2vec4(argv[2]); HMM_Vec4 v = {0};
if (JS_IsArray(js, argv[2])) {
for (int i = 0; i < js_arrlen(argv[2]); i++)
v.e[i] = js2number(js_getpropidx(argv[2], i));
} else
v.x = js2number(argv[2]);
sg_apply_uniforms(js2number(argv[0]), js2number(argv[1]), SG_RANGE_REF(v.e)); sg_apply_uniforms(js2number(argv[0]), js2number(argv[1]), SG_RANGE_REF(v.e));
) )
@ -822,9 +838,9 @@ JSC_CCALL(render_setunim4,
); );
JSC_CCALL(render_spdraw, JSC_CCALL(render_spdraw,
sg_bindings bind = js2bind(argv[0], argv[1]); sg_bindings bind = js2bind(argv[0]);
sg_apply_bindings(&bind); sg_apply_bindings(&bind);
int p = js2number(js_getpropstr(argv[1], "count")); int p = js2number(js_getpropstr(argv[0], "count"));
sg_draw(0,p,1); sg_draw(0,p,1);
) )
@ -1549,6 +1565,27 @@ static const JSCFunctionListEntry js_dspsound_funcs[] = {
MIST_FUNC_DEF(dspsound, mod, 1) MIST_FUNC_DEF(dspsound, mod, 1)
}; };
JSC_CCALL(datastream_time, return number2js(plm_get_time(js2datastream(this)->plm)); )
JSC_CCALL(datastream_advance_frames, ds_advanceframes(js2datastream(this), js2number(argv[0])))
JSC_CCALL(datastream_seek, ds_seek(js2datastream(this), js2number(argv[0])))
JSC_CCALL(datastream_advance, ds_advance(js2datastream(this), js2number(argv[0])))
JSC_CCALL(datastream_duration, return number2js(ds_length(js2datastream(this))))
JSC_CCALL(datastream_framerate, return number2js(plm_get_framerate(js2datastream(this)->plm)))
static const JSCFunctionListEntry js_datastream_funcs[] = {
MIST_FUNC_DEF(datastream, time, 0),
MIST_FUNC_DEF(datastream, advance_frames, 1),
MIST_FUNC_DEF(datastream, seek, 1),
MIST_FUNC_DEF(datastream, advance, 1),
MIST_FUNC_DEF(datastream, duration, 0),
MIST_FUNC_DEF(datastream, framerate, 0),
};
JSC_CCALL(pshape_set_sensor, shape_set_sensor(js2ptr(argv[0]), js2boolean(argv[1]))) JSC_CCALL(pshape_set_sensor, shape_set_sensor(js2ptr(argv[0]), js2boolean(argv[1])))
JSC_CCALL(pshape_get_sensor, return boolean2js(shape_get_sensor(js2ptr(argv[0])))) JSC_CCALL(pshape_get_sensor, return boolean2js(shape_get_sensor(js2ptr(argv[0]))))
JSC_CCALL(pshape_set_enabled, shape_enabled(js2ptr(argv[0]), js2boolean(argv[1]))) JSC_CCALL(pshape_set_enabled, shape_enabled(js2ptr(argv[0]), js2boolean(argv[1])))
@ -1846,7 +1883,6 @@ JSC_CCALL(os_make_line_prim,
*idx = par_idx_buffer(m->triangle_indices, m->num_triangles*3); *idx = par_idx_buffer(m->triangle_indices, m->num_triangles*3);
js_setpropstr(prim, "index", sg_buffer2js(idx)); js_setpropstr(prim, "index", sg_buffer2js(idx));
printf("there are %d verts\n", m->num_vertices);
float uv[m->num_vertices*2]; float uv[m->num_vertices*2];
for (int i = 0; i < m->num_vertices; i++) { for (int i = 0; i < m->num_vertices; i++) {
uv[i*2] = m->annotations[i].u_along_curve; uv[i*2] = m->annotations[i].u_along_curve;
@ -1930,6 +1966,14 @@ JSC_CCALL(os_make_plane,
return parmesh2js(par_shapes_create_plane(js2number(argv[0]), js2number(argv[1]))); return parmesh2js(par_shapes_create_plane(js2number(argv[0]), js2number(argv[1])));
) )
JSC_SCALL(os_make_video,
datastream *ds = ds_openvideo(str);
ret = datastream2js(ds);
texture *t = malloc(sizeof(texture));
t->id = ds->img;
js_setpropstr(ret, "texture", texture2js(t));
)
static const JSCFunctionListEntry js_os_funcs[] = { static const JSCFunctionListEntry js_os_funcs[] = {
MIST_FUNC_DEF(os, cwd, 0), MIST_FUNC_DEF(os, cwd, 0),
MIST_FUNC_DEF(os, env, 1), MIST_FUNC_DEF(os, env, 1),
@ -1959,7 +2003,8 @@ static const JSCFunctionListEntry js_os_funcs[] = {
MIST_FUNC_DEF(os, make_klein_bottle, 2), MIST_FUNC_DEF(os, make_klein_bottle, 2),
MIST_FUNC_DEF(os, make_trefoil_knot, 3), MIST_FUNC_DEF(os, make_trefoil_knot, 3),
MIST_FUNC_DEF(os, make_hemisphere, 2), MIST_FUNC_DEF(os, make_hemisphere, 2),
MIST_FUNC_DEF(os, make_plane, 2) MIST_FUNC_DEF(os, make_plane, 2),
MIST_FUNC_DEF(os, make_video, 1),
}; };
#include "steam.h" #include "steam.h"
@ -1983,6 +2028,7 @@ void ffi_load() {
QJSCLASSPREP_FUNCS(constraint); QJSCLASSPREP_FUNCS(constraint);
QJSCLASSPREP_FUNCS(window); QJSCLASSPREP_FUNCS(window);
QJSCLASSPREP_FUNCS(model); QJSCLASSPREP_FUNCS(model);
QJSCLASSPREP_FUNCS(datastream);
QJSGLOBALCLASS(nota); QJSGLOBALCLASS(nota);
QJSGLOBALCLASS(input); QJSGLOBALCLASS(input);

View file

@ -185,7 +185,6 @@ HMM_Mat4 projection = {0.f};
HMM_Mat4 hudproj = {0.f}; HMM_Mat4 hudproj = {0.f};
HMM_Mat4 useproj = {0}; HMM_Mat4 useproj = {0};
void openglRender(struct window *window, transform2d *cam, float zoom) { void openglRender(struct window *window, transform2d *cam, float zoom) {
HMM_Vec2 usesize = mainwin.rendersize; HMM_Vec2 usesize = mainwin.rendersize;
if (mainwin.mode == MODE_FULL) if (mainwin.mode == MODE_FULL)

View file

@ -18,11 +18,12 @@
the backend selected for sokol_gfx.h if both are used in the same the backend selected for sokol_gfx.h if both are used in the same
project): project):
#define SOKOL_GLCORE33 #define SOKOL_GLCORE
#define SOKOL_GLES3 #define SOKOL_GLES3
#define SOKOL_D3D11 #define SOKOL_D3D11
#define SOKOL_METAL #define SOKOL_METAL
#define SOKOL_WGPU #define SOKOL_WGPU
#define SOKOL_NOAPI
Optionally provide the following defines with your own implementations: Optionally provide the following defines with your own implementations:
@ -47,7 +48,7 @@
On Windows, SOKOL_DLL will define SOKOL_APP_API_DECL as __declspec(dllexport) On Windows, SOKOL_DLL will define SOKOL_APP_API_DECL as __declspec(dllexport)
or __declspec(dllimport) as needed. or __declspec(dllimport) as needed.
On Linux, SOKOL_GLCORE33 can use either GLX or EGL. On Linux, SOKOL_GLCORE can use either GLX or EGL.
GLX is default, set SOKOL_FORCE_EGL to override. GLX is default, set SOKOL_FORCE_EGL to override.
For example code, see https://github.com/floooh/sokol-samples/tree/master/sapp For example code, see https://github.com/floooh/sokol-samples/tree/master/sapp
@ -87,7 +88,7 @@
- makes the rendered frame visible - makes the rendered frame visible
- provides keyboard-, mouse- and low-level touch-events - provides keyboard-, mouse- and low-level touch-events
- platforms: MacOS, iOS, HTML5, Win32, Linux/RaspberryPi, Android - platforms: MacOS, iOS, HTML5, Win32, Linux/RaspberryPi, Android
- 3D-APIs: Metal, D3D11, GL3.2, GLES3, WebGL, WebGL2 - 3D-APIs: Metal, D3D11, GL3.2, GLES3, WebGL, WebGL2, NOAPI
FEATURE/PLATFORM MATRIX FEATURE/PLATFORM MATRIX
======================= =======================
@ -97,6 +98,7 @@
gles3/webgl2 | --- | --- | YES(2)| YES | YES | YES gles3/webgl2 | --- | --- | YES(2)| YES | YES | YES
metal | --- | YES | --- | YES | --- | --- metal | --- | YES | --- | YES | --- | ---
d3d11 | YES | --- | --- | --- | --- | --- d3d11 | YES | --- | --- | --- | --- | ---
noapi | YES | TODO | TODO | --- | TODO | ---
KEY_DOWN | YES | YES | YES | SOME | TODO | YES KEY_DOWN | YES | YES | YES | SOME | TODO | YES
KEY_UP | YES | YES | YES | SOME | TODO | YES KEY_UP | YES | YES | YES | SOME | TODO | YES
CHAR | YES | YES | YES | YES | TODO | YES CHAR | YES | YES | YES | YES | TODO | YES
@ -313,10 +315,15 @@
objects and values required for rendering. If sokol_app.h objects and values required for rendering. If sokol_app.h
is not compiled with SOKOL_WGPU, these functions return null. is not compiled with SOKOL_WGPU, these functions return null.
const uint32_t sapp_gl_get_framebuffer(void) uint32_t sapp_gl_get_framebuffer(void)
This returns the 'default framebuffer' of the GL context. This returns the 'default framebuffer' of the GL context.
Typically this will be zero. Typically this will be zero.
int sapp_gl_get_major_version(void)
int sapp_gl_get_minor_version(void)
Returns the major and minor version of the GL context
(only for SOKOL_GLCORE, all other backends return zero here, including SOKOL_GLES3)
const void* sapp_android_get_native_activity(void); const void* sapp_android_get_native_activity(void);
On Android, get the native activity ANativeActivity pointer, otherwise On Android, get the native activity ANativeActivity pointer, otherwise
a null pointer. a null pointer.
@ -348,7 +355,7 @@
sapp_consume_event() from inside the event handler (NOTE that sapp_consume_event() from inside the event handler (NOTE that
this behaviour is currently only implemented for some HTML5 this behaviour is currently only implemented for some HTML5
events, support for other platforms and event types will events, support for other platforms and event types will
be added as needed, please open a github ticket and/or provide be added as needed, please open a GitHub ticket and/or provide
a PR if needed). a PR if needed).
NOTE: Do *not* call any 3D API rendering functions in the event NOTE: Do *not* call any 3D API rendering functions in the event
@ -1892,6 +1899,10 @@ SOKOL_APP_API_DECL const void* sapp_wgpu_get_depth_stencil_view(void);
/* GL: get framebuffer object */ /* GL: get framebuffer object */
SOKOL_APP_API_DECL uint32_t sapp_gl_get_framebuffer(void); SOKOL_APP_API_DECL uint32_t sapp_gl_get_framebuffer(void);
/* GL: get major version (only valid for desktop GL) */
SOKOL_APP_API_DECL int sapp_gl_get_major_version(void);
/* GL: get minor version (only valid for desktop GL) */
SOKOL_APP_API_DECL int sapp_gl_get_minor_version(void);
/* Android: get native activity handle */ /* Android: get native activity handle */
SOKOL_APP_API_DECL const void* sapp_android_get_native_activity(void); SOKOL_APP_API_DECL const void* sapp_android_get_native_activity(void);
@ -1959,8 +1970,8 @@ inline void sapp_run(const sapp_desc& desc) { return sapp_run(&desc); }
#if defined(TARGET_OS_IPHONE) && !TARGET_OS_IPHONE #if defined(TARGET_OS_IPHONE) && !TARGET_OS_IPHONE
/* MacOS */ /* MacOS */
#define _SAPP_MACOS (1) #define _SAPP_MACOS (1)
#if !defined(SOKOL_METAL) && !defined(SOKOL_GLCORE33) #if !defined(SOKOL_METAL) && !defined(SOKOL_GLCORE)
#error("sokol_app.h: unknown 3D API selected for MacOS, must be SOKOL_METAL or SOKOL_GLCORE33") #error("sokol_app.h: unknown 3D API selected for MacOS, must be SOKOL_METAL or SOKOL_GLCORE")
#endif #endif
#else #else
/* iOS or iOS Simulator */ /* iOS or iOS Simulator */
@ -1978,8 +1989,8 @@ inline void sapp_run(const sapp_desc& desc) { return sapp_run(&desc); }
#elif defined(_WIN32) #elif defined(_WIN32)
/* Windows (D3D11 or GL) */ /* Windows (D3D11 or GL) */
#define _SAPP_WIN32 (1) #define _SAPP_WIN32 (1)
#if !defined(SOKOL_D3D11) && !defined(SOKOL_GLCORE33) #if !defined(SOKOL_D3D11) && !defined(SOKOL_GLCORE) && !defined(SOKOL_NOAPI)
#error("sokol_app.h: unknown 3D API selected for Win32, must be SOKOL_D3D11 or SOKOL_GLCORE33") #error("sokol_app.h: unknown 3D API selected for Win32, must be SOKOL_D3D11, SOKOL_GLCORE or SOKOL_NOAPI")
#endif #endif
#elif defined(__ANDROID__) #elif defined(__ANDROID__)
/* Android */ /* Android */
@ -1993,7 +2004,7 @@ inline void sapp_run(const sapp_desc& desc) { return sapp_run(&desc); }
#elif defined(__linux__) || defined(__unix__) #elif defined(__linux__) || defined(__unix__)
/* Linux */ /* Linux */
#define _SAPP_LINUX (1) #define _SAPP_LINUX (1)
#if defined(SOKOL_GLCORE33) #if defined(SOKOL_GLCORE)
#if !defined(SOKOL_FORCE_EGL) #if !defined(SOKOL_FORCE_EGL)
#define _SAPP_GLX (1) #define _SAPP_GLX (1)
#endif #endif
@ -2003,13 +2014,13 @@ inline void sapp_run(const sapp_desc& desc) { return sapp_run(&desc); }
#include <GLES3/gl3.h> #include <GLES3/gl3.h>
#include <GLES3/gl3ext.h> #include <GLES3/gl3ext.h>
#else #else
#error("sokol_app.h: unknown 3D API selected for Linux, must be SOKOL_GLCORE33, SOKOL_GLES3") #error("sokol_app.h: unknown 3D API selected for Linux, must be SOKOL_GLCORE, SOKOL_GLES3")
#endif #endif
#else #else
#error "sokol_app.h: Unknown platform" #error "sokol_app.h: Unknown platform"
#endif #endif
#if defined(SOKOL_GLCORE33) || defined(SOKOL_GLES3) #if defined(SOKOL_GLCORE) || defined(SOKOL_GLES3)
#define _SAPP_ANY_GL (1) #define _SAPP_ANY_GL (1)
#endif #endif
@ -2399,11 +2410,11 @@ _SOKOL_PRIVATE double _sapp_timing_get_avg(_sapp_timing_t* t) {
#if defined(SOKOL_METAL) #if defined(SOKOL_METAL)
@interface _sapp_macos_view : MTKView @interface _sapp_macos_view : MTKView
@end @end
#elif defined(SOKOL_GLCORE33) #elif defined(SOKOL_GLCORE)
@interface _sapp_macos_view : NSOpenGLView @interface _sapp_macos_view : NSOpenGLView
- (void)timerFired:(id)sender; - (void)timerFired:(id)sender;
@end @end
#endif // SOKOL_GLCORE33 #endif // SOKOL_GLCORE
typedef struct { typedef struct {
uint32_t flags_changed_store; uint32_t flags_changed_store;
@ -2545,7 +2556,7 @@ typedef struct {
uint8_t raw_input_data[256]; uint8_t raw_input_data[256];
} _sapp_win32_t; } _sapp_win32_t;
#if defined(SOKOL_GLCORE33) #if defined(SOKOL_GLCORE)
#define WGL_NUMBER_PIXEL_FORMATS_ARB 0x2000 #define WGL_NUMBER_PIXEL_FORMATS_ARB 0x2000
#define WGL_SUPPORT_OPENGL_ARB 0x2010 #define WGL_SUPPORT_OPENGL_ARB 0x2010
#define WGL_DRAW_TO_WINDOW_ARB 0x2001 #define WGL_DRAW_TO_WINDOW_ARB 0x2001
@ -2605,7 +2616,7 @@ typedef struct {
HWND msg_hwnd; HWND msg_hwnd;
HDC msg_dc; HDC msg_dc;
} _sapp_wgl_t; } _sapp_wgl_t;
#endif // SOKOL_GLCORE33 #endif // SOKOL_GLCORE
#endif // _SAPP_WIN32 #endif // _SAPP_WIN32
@ -2876,7 +2887,7 @@ typedef struct {
_sapp_win32_t win32; _sapp_win32_t win32;
#if defined(SOKOL_D3D11) #if defined(SOKOL_D3D11)
_sapp_d3d11_t d3d11; _sapp_d3d11_t d3d11;
#elif defined(SOKOL_GLCORE33) #elif defined(SOKOL_GLCORE)
_sapp_wgl_t wgl; _sapp_wgl_t wgl;
#endif #endif
#elif defined(_SAPP_ANDROID) #elif defined(_SAPP_ANDROID)
@ -3085,8 +3096,13 @@ _SOKOL_PRIVATE sapp_desc _sapp_desc_defaults(const sapp_desc* desc) {
// (or expressed differently: zero is a valid value for gl_minor_version // (or expressed differently: zero is a valid value for gl_minor_version
// and can't be used to indicate 'default') // and can't be used to indicate 'default')
if (0 == res.gl_major_version) { if (0 == res.gl_major_version) {
res.gl_major_version = 3; #if defined(_SAPP_APPLE)
res.gl_minor_version = 2; res.gl_major_version = 4;
res.gl_minor_version = 1;
#else
res.gl_major_version = 4;
res.gl_minor_version = 3;
#endif
} }
res.html5_canvas_name = _sapp_def(res.html5_canvas_name, "canvas"); res.html5_canvas_name = _sapp_def(res.html5_canvas_name, "canvas");
res.clipboard_size = _sapp_def(res.clipboard_size, 8192); res.clipboard_size = _sapp_def(res.clipboard_size, 8192);
@ -3650,7 +3666,7 @@ _SOKOL_PRIVATE void _sapp_macos_update_dimensions(void) {
const int cur_fb_height = (int)roundf(fb_size.height); const int cur_fb_height = (int)roundf(fb_size.height);
const bool dim_changed = (_sapp.framebuffer_width != cur_fb_width) || const bool dim_changed = (_sapp.framebuffer_width != cur_fb_width) ||
(_sapp.framebuffer_height != cur_fb_height); (_sapp.framebuffer_height != cur_fb_height);
#elif defined(SOKOL_GLCORE33) #elif defined(SOKOL_GLCORE)
const int cur_fb_width = (int)roundf(bounds.size.width * _sapp.dpi_scale); const int cur_fb_width = (int)roundf(bounds.size.width * _sapp.dpi_scale);
const int cur_fb_height = (int)roundf(bounds.size.height * _sapp.dpi_scale); const int cur_fb_height = (int)roundf(bounds.size.height * _sapp.dpi_scale);
const bool dim_changed = (_sapp.framebuffer_width != cur_fb_width) || const bool dim_changed = (_sapp.framebuffer_width != cur_fb_width) ||
@ -3892,7 +3908,7 @@ _SOKOL_PRIVATE void _sapp_macos_frame(void) {
_sapp.macos.window.contentView = _sapp.macos.view; _sapp.macos.window.contentView = _sapp.macos.view;
[_sapp.macos.window makeFirstResponder:_sapp.macos.view]; [_sapp.macos.window makeFirstResponder:_sapp.macos.view];
_sapp.macos.view.layer.magnificationFilter = kCAFilterNearest; _sapp.macos.view.layer.magnificationFilter = kCAFilterNearest;
#elif defined(SOKOL_GLCORE33) #elif defined(SOKOL_GLCORE)
NSOpenGLPixelFormatAttribute attrs[32]; NSOpenGLPixelFormatAttribute attrs[32];
int i = 0; int i = 0;
attrs[i++] = NSOpenGLPFAAccelerated; attrs[i++] = NSOpenGLPFAAccelerated;
@ -4124,7 +4140,7 @@ _SOKOL_PRIVATE void _sapp_macos_frame(void) {
@end @end
@implementation _sapp_macos_view @implementation _sapp_macos_view
#if defined(SOKOL_GLCORE33) #if defined(SOKOL_GLCORE)
- (void)timerFired:(id)sender { - (void)timerFired:(id)sender {
_SOKOL_UNUSED(sender); _SOKOL_UNUSED(sender);
[self setNeedsDisplay:YES]; [self setNeedsDisplay:YES];
@ -4224,7 +4240,7 @@ _SOKOL_PRIVATE void _sapp_macos_poll_input_events(void) {
// helper function to make GL context active // helper function to make GL context active
static void _sapp_gl_make_current(void) { static void _sapp_gl_make_current(void) {
#if defined(SOKOL_GLCORE33) #if defined(SOKOL_GLCORE)
[[_sapp.macos.view openGLContext] makeCurrentContext]; [[_sapp.macos.view openGLContext] makeCurrentContext];
#endif #endif
} }
@ -5945,7 +5961,7 @@ int main(int argc, char* argv[]) {
// ██████ ███████ ██ ██ ███████ ███████ ██ ███████ ██ ██ ███████ // ██████ ███████ ██ ██ ███████ ███████ ██ ███████ ██ ██ ███████
// //
// >>gl helpers // >>gl helpers
#if defined(SOKOL_GLCORE33) #if defined(SOKOL_GLCORE)
typedef struct { typedef struct {
int red_bits; int red_bits;
int green_bits; int green_bits;
@ -6596,7 +6612,7 @@ _SOKOL_PRIVATE void _sapp_d3d11_present(bool do_not_wait) {
#endif /* SOKOL_D3D11 */ #endif /* SOKOL_D3D11 */
#if defined(SOKOL_GLCORE33) #if defined(SOKOL_GLCORE)
_SOKOL_PRIVATE void _sapp_wgl_init(void) { _SOKOL_PRIVATE void _sapp_wgl_init(void) {
_sapp.wgl.opengl32 = LoadLibraryA("opengl32.dll"); _sapp.wgl.opengl32 = LoadLibraryA("opengl32.dll");
if (!_sapp.wgl.opengl32) { if (!_sapp.wgl.opengl32) {
@ -6894,7 +6910,7 @@ _SOKOL_PRIVATE void _sapp_wgl_swap_buffers(void) {
/* FIXME: DwmIsCompositionEnabled? (see GLFW) */ /* FIXME: DwmIsCompositionEnabled? (see GLFW) */
SwapBuffers(_sapp.win32.dc); SwapBuffers(_sapp.win32.dc);
} }
#endif /* SOKOL_GLCORE33 */ #endif /* SOKOL_GLCORE */
_SOKOL_PRIVATE bool _sapp_win32_wide_to_utf8(const wchar_t* src, char* dst, int dst_num_bytes) { _SOKOL_PRIVATE bool _sapp_win32_wide_to_utf8(const wchar_t* src, char* dst, int dst_num_bytes) {
SOKOL_ASSERT(src && dst && (dst_num_bytes > 1)); SOKOL_ASSERT(src && dst && (dst_num_bytes > 1));
@ -7311,7 +7327,10 @@ _SOKOL_PRIVATE void _sapp_win32_timing_measure(void) {
// fallback if swap model isn't "flip-discard" or GetFrameStatistics failed for another reason // fallback if swap model isn't "flip-discard" or GetFrameStatistics failed for another reason
_sapp_timing_measure(&_sapp.timing); _sapp_timing_measure(&_sapp.timing);
#endif #endif
#if defined(SOKOL_GLCORE33) #if defined(SOKOL_GLCORE)
_sapp_timing_measure(&_sapp.timing);
#endif
#if defined(SOKOL_NOAPI)
_sapp_timing_measure(&_sapp.timing); _sapp_timing_measure(&_sapp.timing);
#endif #endif
} }
@ -7513,7 +7532,7 @@ _SOKOL_PRIVATE LRESULT CALLBACK _sapp_win32_wndproc(HWND hWnd, UINT uMsg, WPARAM
// present with DXGI_PRESENT_DO_NOT_WAIT // present with DXGI_PRESENT_DO_NOT_WAIT
_sapp_d3d11_present(true); _sapp_d3d11_present(true);
#endif #endif
#if defined(SOKOL_GLCORE33) #if defined(SOKOL_GLCORE)
_sapp_wgl_swap_buffers(); _sapp_wgl_swap_buffers();
#endif #endif
/* NOTE: resizing the swap-chain during resize leads to a substantial /* NOTE: resizing the swap-chain during resize leads to a substantial
@ -7926,7 +7945,7 @@ _SOKOL_PRIVATE void _sapp_win32_run(const sapp_desc* desc) {
_sapp_d3d11_create_device_and_swapchain(); _sapp_d3d11_create_device_and_swapchain();
_sapp_d3d11_create_default_render_target(); _sapp_d3d11_create_default_render_target();
#endif #endif
#if defined(SOKOL_GLCORE33) #if defined(SOKOL_GLCORE)
_sapp_wgl_init(); _sapp_wgl_init();
_sapp_wgl_load_extensions(); _sapp_wgl_load_extensions();
_sapp_wgl_create_context(); _sapp_wgl_create_context();
@ -7954,7 +7973,7 @@ _SOKOL_PRIVATE void _sapp_win32_run(const sapp_desc* desc) {
Sleep((DWORD)(16 * _sapp.swap_interval)); Sleep((DWORD)(16 * _sapp.swap_interval));
} }
#endif #endif
#if defined(SOKOL_GLCORE33) #if defined(SOKOL_GLCORE)
_sapp_wgl_swap_buffers(); _sapp_wgl_swap_buffers();
#endif #endif
/* check for window resized, this cannot happen in WM_SIZE as it explodes memory usage */ /* check for window resized, this cannot happen in WM_SIZE as it explodes memory usage */
@ -10947,7 +10966,7 @@ _SOKOL_PRIVATE void _sapp_x11_process_event(XEvent* event) {
#if !defined(_SAPP_GLX) #if !defined(_SAPP_GLX)
_SOKOL_PRIVATE void _sapp_egl_init(void) { _SOKOL_PRIVATE void _sapp_egl_init(void) {
#if defined(SOKOL_GLCORE33) #if defined(SOKOL_GLCORE)
if (!eglBindAPI(EGL_OPENGL_API)) { if (!eglBindAPI(EGL_OPENGL_API)) {
_SAPP_PANIC(LINUX_EGL_BIND_OPENGL_API_FAILED); _SAPP_PANIC(LINUX_EGL_BIND_OPENGL_API_FAILED);
} }
@ -10971,7 +10990,7 @@ _SOKOL_PRIVATE void _sapp_egl_init(void) {
EGLint alpha_size = _sapp.desc.alpha ? 8 : 0; EGLint alpha_size = _sapp.desc.alpha ? 8 : 0;
const EGLint config_attrs[] = { const EGLint config_attrs[] = {
EGL_SURFACE_TYPE, EGL_WINDOW_BIT, EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
#if defined(SOKOL_GLCORE33) #if defined(SOKOL_GLCORE)
EGL_RENDERABLE_TYPE, EGL_OPENGL_BIT, EGL_RENDERABLE_TYPE, EGL_OPENGL_BIT,
#elif defined(SOKOL_GLES3) #elif defined(SOKOL_GLES3)
EGL_RENDERABLE_TYPE, EGL_OPENGL_ES3_BIT, EGL_RENDERABLE_TYPE, EGL_OPENGL_ES3_BIT,
@ -11034,7 +11053,7 @@ _SOKOL_PRIVATE void _sapp_egl_init(void) {
} }
EGLint ctx_attrs[] = { EGLint ctx_attrs[] = {
#if defined(SOKOL_GLCORE33) #if defined(SOKOL_GLCORE)
EGL_CONTEXT_MAJOR_VERSION, _sapp.desc.gl_major_version, EGL_CONTEXT_MAJOR_VERSION, _sapp.desc.gl_major_version,
EGL_CONTEXT_MINOR_VERSION, _sapp.desc.gl_minor_version, EGL_CONTEXT_MINOR_VERSION, _sapp.desc.gl_minor_version,
EGL_CONTEXT_OPENGL_PROFILE_MASK, EGL_CONTEXT_OPENGL_CORE_PROFILE_BIT, EGL_CONTEXT_OPENGL_PROFILE_MASK, EGL_CONTEXT_OPENGL_CORE_PROFILE_BIT,
@ -11753,6 +11772,24 @@ SOKOL_API_IMPL uint32_t sapp_gl_get_framebuffer(void) {
#endif #endif
} }
SOKOL_API_IMPL int sapp_gl_get_major_version(void) {
SOKOL_ASSERT(_sapp.valid);
#if defined(SOKOL_GLCORE)
return _sapp.desc.gl_major_version;
#else
return 0;
#endif
}
SOKOL_API_IMPL int sapp_gl_get_minor_version(void) {
SOKOL_ASSERT(_sapp.valid);
#if defined(SOKOL_GLCORE)
return _sapp.desc.gl_minor_version;
#else
return 0;
#endif
}
SOKOL_API_IMPL const void* sapp_android_get_native_activity(void) { SOKOL_API_IMPL const void* sapp_android_get_native_activity(void) {
// NOTE: _sapp.valid is not asserted here because sapp_android_get_native_activity() // NOTE: _sapp.valid is not asserted here because sapp_android_get_native_activity()
// needs to be callable from within sokol_main() (see: https://github.com/floooh/sokol/issues/708) // needs to be callable from within sokol_main() (see: https://github.com/floooh/sokol/issues/708)

File diff suppressed because it is too large Load diff

View file

@ -43,7 +43,7 @@
functions. Use this in the sg_setup() call like this: functions. Use this in the sg_setup() call like this:
sg_setup(&(sg_desc){ sg_setup(&(sg_desc){
.environment = sglue_enviornment(), .environment = sglue_environment(),
... ...
}); });