floooh / sokol Goto Github PK
View Code? Open in Web Editor NEWminimal cross-platform standalone C headers
Home Page: https://floooh.github.io/sokol-html5
License: zlib License
minimal cross-platform standalone C headers
Home Page: https://floooh.github.io/sokol-html5
License: zlib License
I started a library thats similar to https://github.com/jimon/entrypoint
The point of it:
Other features I want to add but I'm not sure about them, or maybe add it after a 1.0:
So the way its used its pretty similar to your sokol samples, in fact these entry points there is what I started with.
Currently I'm implementing OSX and iOS, both supporting Metal & OpenGL (for OpenGL it looks like I still need something like glad)
So this is how your clear-metal looks now with sokol_entry, not much changed, in fact for OSX/iOS its mostly renaming...
//------------------------------------------------------------------------------
// clear-metal.c
//------------------------------------------------------------------------------
#include "sokol_gfx.h"
#include "sokol_entry/sokol_entry.h"
sg_pass_action pass_action;
void init(const sg_gfx_init_data *data) {
sg_desc desc = {
.mtl_device = data->mtl_device,
.mtl_renderpass_descriptor_cb = data->mtl_renderpass_descriptor_cb,
.mtl_drawable_cb = data->mtl_drawable_cb
};
sg_setup(&desc);
pass_action = (sg_pass_action) {
.colors[0] = { .action = SG_ACTION_CLEAR, .val = { 1.0f, 0.0f, 0.0f, 1.0f } }
};
}
static bool wasFullscreen;
void frame() {
sg_set_window_fullscreen(true);
if (sg_is_window_fullscreen()) {
wasFullscreen = true;
}
if (!sg_is_window_fullscreen() && wasFullscreen) {
sg_quite();
}
/* animate clear colors */
float g = pass_action.colors[0].val[1] + 0.01f;
if (g > 1.0f) g = 0.0f;
pass_action.colors[0].val[1] = g;
/* draw one frame */
sg_begin_default_pass(&pass_action, sg_get_window_width(), sg_get_window_width());
sg_end_pass();
sg_commit();
}
void shutdown() {
sg_shutdown();
}
void sg_main() {
sg_start(840, 480, 1, "Sokol Clear (Metal)", init, frame, shutdown);
}
So.. do you have interest in this? If not I will rename it to something else. Also any feedback is very welcome.
You can see my current WiP code here:
https://github.com/pjako/sokol/tree/entry/sokol_entry
Hi Andre,
do you plan to add event for window size/pos changes? I'm volunteering to write it for Win32, if you don't have it already in private.
...should be renamed.
The pass object should only have the minimally required information baked in (number of attachments, and their types - check Vulkan and D3D12 for exact requirements), and the actual render target image ids should be provided in the 'dynamic' sg_pass_action (probably would make sense to rename this struct then to something else).
Why are uniforms
in sg_shader_uniform_block_desc
set manually ?
Maybe the could be set automatically during the compilation of the shader with introspection ?
Thank you in advance.
OPTIONAL:
Hello,
A common way to implement the gaussian blur in OpenGL/GLSL is to setup ping-ponging framebuffers and apply horizontal and vertical blurs with fixed width kernel repeatedly (ref).
Attempting to implement such setup in sokol seems to be quite tricky. While it is possible to change the input texture by setting .fs_images[i] variable of sg_draw_state object, it seems to be impossible to change the output framebuffer, as it is only set when creating sg_pass object, and setting color attachements. As such I don't really see a way to setup buffer ping-ponging in sokol, other than a) injecting openGL or b) creating and destroying pass object on the fly.
My questions are then - have I missed anything and there is in fact a way to set up the ping-ponging framebuffer? Otherwise, given that buffer ping-ponging is relatively common operation, should it be possible to express that operation in sokol without injecting gl code.
Thanks!
...this would enable C99 designated initialisers (where non-mentioned fields are zeroed).
Hi,
First of all, thanks so much for the library!
I am currently learning how to use it by writing a simple mesh-viewer application, however I am running into trouble when submitting my vertex data. In my application I am keeping my vertex positions and vertex normals as separate buffers, however all examples showcase interleaved vertex data.
Is there a way to inform sokol about non-interleaved vertex data? (VVVNNN) vs (VNVNVN)
OpenGL pseudocode snipped to show what I am trying to achieve:
glBufferSubData( GL_ARRAY_BUFFER, 0, mesh->n_vertices*3*sizeof(float), &(mesh->positions[0]) );
glEnableVertexAttribArray( 0 );
glVertexAttribPointer( 0, 3, GL_FLOAT, GL_FALSE, 0, (void*)0);
glBufferSubData( GL_ARRAY_BUFFER, 3 * sizeof(float) * mesh->n_vertices, 3 * sizeof(float) * mesh->n_vertices, &(mesh->normals[0]) );
glEnableVertexAttribArray( 1 );
glVertexAttribPointer( 1, 3, GL_FLOAT, GL_FALSE, 0, (void*) ( 3 * sizeof(float) * mesh->n_vertices) );
when building with cpp cl compiler, I get error in sokol_app.h, line 2873:
1>error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
here's the place where it happens (function: _sapp_d3d11_destroy_device_and_swapchain):
_SOKOL_PRIVATE _sapp_d3d11_destroy_device_and_swapchain(void) {
_SAPP_SAFE_RELEASE(IDXGISwapChain, _sapp_dxgi_swap_chain);
_SAPP_SAFE_RELEASE(ID3D11DeviceContext, _sapp_d3d11_device_context);
_SAPP_SAFE_RELEASE(ID3D11Device, _sapp_d3d11_device);
}
I guess inserting void on the beginning of the declaration solved the problem
This should go into "v1.1".
...currently these are only reported as modifiers, and at least on some platforms, not also as key up/down events.
On RaspberryPi with an older GCC (4.9.1) there are a lot of errors because of "for (int...)". If this is the only problem, it's worth it to make sokol_gfx.h C89 clean.
I'm trying to build sokol_app in a cpp file, but I can't get it done without cl complaining ...
file: d3d11.h , line: 1128
error C2733: 'operator ==': second C linkage of overloaded function not allowed
this is fixed with defining D3D11_NO_HELPERS before including sokol_app.h
But these errors :
error C3861: 'ID3D11DeviceContext_Release': identifier not found
error C3861: 'ID3D11Device_Release': identifier not found
error C3861: 'IDXGISwapChain_GetBuffer': identifier not found
error C3861: 'ID3D11Device_CreateRenderTargetView': identifier not found
error C3861: 'ID3D11Device_CreateTexture2D': identifier not found
error C3861: 'ID3D11Device_CreateDepthStencilView': identifier not found
error C3861: 'ID3D11Texture2D_Release': identifier not found
error C3861: 'ID3D11RenderTargetView_Release': identifier not found
error C3861: 'ID3D11Texture2D_Release': identifier not found
error C3861: 'ID3D11DepthStencilView_Release': identifier not found
error C3861: 'IDXGISwapChain_ResizeBuffers': identifier not found
error C3861: 'IDXGISwapChain_Present': identifier not found
still exist, and I can't get rid of them because the code is disabled in __cplusplus. By inspecting dxgi.h, I defined CINTERFACE and the code is enabled again, but this error shows up:
sokol_app.h(2881): error C2664: 'HRESULT (IDXGISwapChain *,UINT,const IID &,void **)': cannot convert argument 3 from 'const IID *' to 'const IID &'
So I had to add another __cplusplus case for this issue to fix:
#ifdef __cplusplus
hr = IDXGISwapChain_GetBuffer(_sapp_dxgi_swap_chain, 0, IID_ID3D11Texture2D, (void**)&_sapp_d3d11_rt);
#else
hr = IDXGISwapChain_GetBuffer(_sapp_dxgi_swap_chain, 0, &IID_ID3D11Texture2D, (void**)&_sapp_d3d11_rt);
#endif
PS. there is also a minor performance warning in msvc that is raised and not really important but I though I'd let you know:
warning C4800: 'const char *const ': forcing value to bool 'true' or 'false' (performance warning)
in SOKOL_VALIDATE , sokol_gfx.h (8092)
I'm running into trouble when creating and destroying buffers (or pipelines) every frame with the Metal backend.
Here's a test case made by moving the vertex buffer creation from init
to frame
in the triangle-metal.c
sample and destroying it after using it. After a few seconds it fires an assert:
Assertion failed: (_sg_mtl_free_queue_top > 0), function _sg_mtl_add_resource, file sokol/_sokol_gfx_metal.impl.h, line 379.
One possible error could be with the logic in _sg_mtl_garbage_collect
, since it is called after every frame via sg_commit
but seems to never process any of the resources in the release queue. Specifically, on line 413 it checks if frame index of the oldest resource is less than the current frame + inflight frames + 1, which should always be true if the frame index only increases and inflight frames is positive.
It's easy to forget calling the sg_init_* functions to initialize structs. Solution: add a magic cookie field that's set in the sg_init functions, and check for the correct magic value when the struct is inspected.
Add optional buffer offsets to sg_draw_state, this would allow to pack several things into the same buffer.
sg_draw_state ds = {
.pipeline = pip;
.vertex_buffers = {
[0] = vbuf,
[1] = vbuf,
},
.vertex_buffer_offsets = {
[0] = 128,
[1] = 2048,
},
.index_buffer = ibuf,
.index_buffer_offset = 256,
// ...
};
In GL, the offset would be applied during glVertexAttribPointer() calls, in D3D11 in IASetVertexBuffers() and IASetIndexBuffer(), and in Metal in [setVertexBuffer:offset:atIndex] and for indices in [drawIndexedPrimitives:...]
Oh, but it's still illlegal to put vertices and indices into the same buffer (because of WebGL), but this is already checked in _sg_validate_draw_state().
Hi,
Is there any reason for one update per frame restriction?
I'm implementing a sprite batch using sokol_gfx. A common pattern for this (such as in FNA) is to instantiate a fixed-size array which stores all the vertices and indices of the sprites, and if the user provides more sprites, the sprites are drawn, and the buffers reused for more sprites in the same frame.
Sticking to one buffer update per frame would force me to have a large upper bound on number of sprites which wastes memory, or using heap allocated memory, which is bad for cache.
Removing SOKOL_ASSERT(buf->upd_frame_index != _sg.frame_index);
from sg_update_buffer
simply works for me. So I'm curious to know what your reasons for this are.
EDIT: This is the code if you're interested in how I'm using sokol_gfx
: https://github.com/sherjilozair/sokol2d/blob/master/sokol2d.h#L347
In the function _sg_create_context the line
SOKOL_ASSERT(0 == ctx->vao);
fails to compile when compiling with #define SOKOL_GLES2.
This is not surprising since we have
typedef struct {
_sg_slot slot;
#if !defined(SOKOL_GLES2)
GLuint vao;
#endif
GLuint default_framebuffer;
} _sg_context;
Should be an easy fix. Just a side question; this makes me feel that SOKOL_GLES3 is more tested. Are there maybe more issues related to vao for GLES2? Things seems to work and afaict the sokol-samples are compiled for GLES2...?
Would be nice to have a nuklear example (instead or over imgui), since nuklear and sokol are C while imgui is C++.
As far as I can see by the implementation, sokol_gfx can not support multiple windows/contexts. Maybe it is just a matter of storing the _sg_backend object and restoring it with a reset_state_cache call between contexts.
Not sure if this is really a Sokol problem but referencing
KhronosGroup/SPIRV-Cross#169
it does not seem to be a problem with Oryol?
So the problem is currently, if a msl defines the out struct of the vertex shader with a [point_size]
struct main0_out {
float gl_PointSize [[point_size]]; // This by default is always in the compiled shader
};
Sokol/Metal complains: Compiler failed to build request
Vertex shader writes point size but inputPrimitiveTopology is MTLPrimitiveTopologyClassTriangle
Could this something specific to the Metal API Validation being enabled?
Currently fixed the problem in the spirv-cross compiler with "opts.point_size_compat = true" but thats not good solution.
Sokol doesn't play terribly nice with C++ compilers. Rather than forcing C++ consumers to fiddle with the header files, it would be nice to wrap the entire library in extern "C"
guards:
#ifdef __cplusplus
extern "C" {
#endif
// ...
#ifdef __cplusplus
}
#endif
Note that stb_* libraries do exactly this: https://github.com/nothings/stb/blob/master/stb_image.h#L323
Hey, I'm just trying to adjust the oryol shader compiler to Sokol.
Stumbled over this problem:
spirvCross names the main function for vs/fs this way: "main0"
In metal sokol_gfx the main method for binary vs/fs shader is set to: "_main"
Nice API!
I would like to set up soko with one shader setup and render multiple models(verts/index date) with the same format.
I've probably missed something really obvious, but I can't see a way to do this?
I see SG_MAX_SHADERSTAGE_BUFFERS is set to 4 and streaming data via sg_update_buffer is also limited to "... only one update allowed per frame and resource object, and data must be written from the start (but the data size can be smaller than the resource size)."
Any help would be great :)
Cheers
Mike.
I know, OpenGL is deprecated on mac, but maybe it would be nice to have it until it is removed completely?
when the .h file is referenced from multiple .c files, compilation performance suffers (on low-end devices: ARM, lowend x86/x64, ...) as well as IDE performance. Splitting it to .c and .h files would reduce that enormously.
PROS:
If you still have to do that, you can include one intermediate header file that include both .c and .h files
Note: Nuklear started by having a header only file, then ended up doing the split
...also needs a test
Hi, thanks for creating sokol, I find very refreshing working with it!
Question:
do you have somewhere a snippet of code or an example on how I can access/visualize the depth buffer?
I naively tried to attach the depth_image to a color attachment but it doesn't seem to work for me.
For example, in the offscreen-glow.c
sample, if I modify the default draw state like this (around line 242):
sg_draw_state default_ds = {
.pipeline = default_pip,
.vertex_buffers[0] = vbuf,
.index_buffer = ibuf,
.fs_images[0] = depth_img // was: "color_img"
};
I see no difference in the generated output image.
Similarly, using the mrt-glfw.c
sample, if I change the debug view in the main loop to also draw the depth, like this (around line345):
sg_draw(0, 4, 1);
for (int i = 0; i < 3; i++) {
sg_apply_viewport(i*100, 0, 100, 100, false);
dbg_ds.fs_images[0] = offscreen_pass_desc.color_attachments[i].image;
sg_apply_draw_state(&dbg_ds);
sg_draw(0, 4, 1);
}
for (int i = 3; i < 4; i++) {
sg_apply_viewport(i*100, 0, 100, 100, false);
dbg_ds.fs_images[0] = offscreen_pass_desc.depth_stencil_attachment.image;
sg_apply_draw_state(&dbg_ds);
sg_draw(0, 4, 1);
}
sg_end_pass();
what I get is a duplication of the last color attachment that has been bound (see the following screenshot).
Probably I'm trying to "map" my OpenGL mindset to Sokol, and doing something wrong.
Any suggestion on the right way to use the depth buffer in a shader?
thanks!
...
sg_apply_draw_state() must check:
sg_image_desc should have a max_anisotropy sampler state member to configure anisotropic filtering.
also needs a test, maybe port the native texture demo over from Oryol?
The GL backend variations are currently "leaking" into each other, e.g. the GLES2 backend is using functionality that isn't actually available in GLES2.
Hi dude,
Any plan on having multithreading, command buffers support?
Something similar to:
https://developer.apple.com/documentation/metal/mtlparallelrendercommandencoder
https://developer.apple.com/videos/play/wwdc2018/607/
I'm working on CommandBuffers support into my engine (https://github.com/amerkoleci/alimer), just was thinking to ask for your thoughts?
Thanks,
Cleanup the 'item id 0 is reserved' stuff:
Instead of a generic sg_id there should be sg_buffer_id, sg_image_id, etc...
Hi
I'm on ubuntu with installed package glew 1.13.
I got assertion on the first _SG_GL_CHECK_ERROR();
in _sg_create_context function. because there was a pending GL error (GL_INVALID_ENUM)
It seems that the problem is with version 1.13 of glew documented here
So I had to reset the errors after glewInit. Is it ok if sokol_gfx clears errors on setup and throw a warning or something, in case if previous errors are raised by glew or similiar lib ?
When running the sapp dear imgui sample with xcode/metal the app crashes. The strange thing is that it worked a day ago with no problem...
2018-05-30 15:32:49.223915+0200 imgui-sapp[1812:27662] [DYMTLInitPlatform] platform initialization successful
2018-05-30 15:32:49.461297+0200 imgui-sapp[1812:27593] Metal GPU Frame Capture Enabled
2018-05-30 15:32:49.461684+0200 imgui-sapp[1812:27593] Metal API Validation Enabled
2018-05-30 15:32:49.739457+0200 imgui-sapp[1812:27684] MessageTracer: Falling back to default whitelist
2018-05-30 15:32:50.341674+0200 imgui-sapp[1812:27593] -[MTLTextureDescriptorInternal validateWithDevice:], line 832: error 'MTLTextureDescriptor has sampleCount set but is using a type that does not allow sampleCount.'
-[MTLTextureDescriptorInternal validateWithDevice:]:832: failed assertion `MTLTextureDescriptor has sampleCount set but is using a type that does not allow sampleCount.'
Problems in the current implementation:
Lines 375 to 392 in 2070f2b
Hi Andre,
I use sokol since few weeks and (for now) I think the only missing feature is the export of image to CPU side.
I don't known if this request is compatible with Metal and GLES API but I think it's Ok for DX11 and OpenGL.
And maybe you don't want to add new feature to your lib?
Anyway, thanks for this awesome little and simple lib.
Every frame I'm rendering I mix sokol with other opengl related libraries, not a good Idea I know, but sokol is supposed to handle that with sg_reset_state_cache, doesn't it?
the order is:
If I clear openglErrors between 4 and 5, it works... but something is not right.
(Thanks for an awesome library, btw ๐ )
PD: The proper way is to implement a nanovg backend on top of soko_gfx, I know! Just need time.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.