Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Question: nanovg with sokol_gfx? #633

Open
ib00 opened this issue Feb 20, 2022 · 14 comments
Open

Question: nanovg with sokol_gfx? #633

ib00 opened this issue Feb 20, 2022 · 14 comments

Comments

@ib00
Copy link

ib00 commented Feb 20, 2022

Has anybody attempted to write a nanovg renderer with sokol_gfx?

@RobLoach
Copy link

A Google Search didn't return any meaningful results, other than #29 . You could ask pplux.

@Sakari369
Copy link

Sakari369 commented Jul 13, 2022

Would be interested in the same thing, did you find out anything @ib00 ? How about @pplux, did you get nanovg working with sokol_gfx, perhaps you could share some sample code ? Thanks for any information :)

@ib00
Copy link
Author

ib00 commented Jul 13, 2022

Unfortunately not. The closest thing (for 2D drawing) is sokol_gp:
https://github.com/edubart/sokol_gp

@pplux
Copy link
Contributor

pplux commented Jul 13, 2022

Hi! at the time I was mixing sokol rendering with another gl-drawing library, in the end it worked. And maybe you can try that, nanovg supports render directly with gl so you just need to be careful to recover and save the proper gl state between the two libraries.

But depends very much on what you need, if you just need some basic 2D rendering... well, consider imgui to which sokol offers a proper full implementation on top of sokol_gfx, and you ca pretty much draw whatever you want with it:

ocornut/imgui#3606

@Sakari369
Copy link

Thanks @pplux and @ib00 for the tips.
Basically was looking into a quick way to render some mock lines and paths, but managed actually just with the Sokol_GL sgl_begin_lines() for now until doing a proper implementation.

@darkuranium
Copy link
Contributor

Hi. I made this a while ago, but never published it because it was never properly tested (plus I wanted to write a custom library). But I guess it'll be useful to others, too.

I still need to figure out the shader compiler to be able to distribute it for everything, but in principle, it works.

I don't have access to it today (not at home), but if someone reminds me in a few days, I can try to find the code.

@DagAgren
Copy link

DagAgren commented Nov 2, 2022

@darkuranium Very interested here.

@darkuranium
Copy link
Contributor

@DagAgren @ib00 Okay, so I wanted to clean this up and make a "proper" fork, but didn't get around to it due to a lack of time.

So here's just the nanovg_sokol.h file: https://gist.github.com/darkuranium/746a1cdbb73004d6567783650a4b557f

Caveats:

  • Currently only contains code for GLES2/WebGL, GLES3/WebGL2, and GLCORE33 (i.e. no D3D or similar). I've been wanting to use the Sokol shader compiler, but could never quite get it working.
  • It's based off of the official/unmaintained repository (because I made this a while ago).

If anyone would be interested in making a "proper" fork of NanoVG (as in: a hard fork, to clean some things up), let me know. There are a few things that bother me about it (e.g. the fact that it defines STB_IMAGE_IMPLEMENTATION itself, which conflicts with other uses of that library).


Note: I've been wanting to make an alternative to NanoVG (a completely new API [as in: no compatibility with NanoVG], to work around some NanoVG limitations), but there's a few obstacles I've yet to figure out. The main features I'd like to add on top of NanoVG are (in descending order of priority):

  • the ability to store computed path geometry into a buffer for reuse (this is the main thing that I need)
  • better anti-aliasing, especially of strokes (NanoVG struggles with thin strokes; somewhat high-priority)
  • the ability to properly render/anti-alias in perspective mode; in other words, proper support for perspective transform matrices instead of just 2x3 (rationale: to support the full set of CSS transforms, and for "pretty" rendering in 3D scenes)
  • better state management + batching, to reduce the number of draw calls (somewhat low-priority)
  • pixel-perfect bezier rasterization (fragment shader-based, instead of subdivision; low-priority)

The main obstacle at the moment is in figuring out how to do anti-aliasing for paths (there is a very promising paper on wavelet rasterization, but it might need compute shaders to implement on GPUs). Ideally, I would also like to avoid relying on the stencil buffer, because it's problematic for anti-aliasing and because for 2D uses, it means unnecessary extra memory for the depth buffer (and for 3D software, it means the depth buffer cannot be 32-bit, but must be 24+8 depth/stencil).
If I have to use a stencil buffer, I'm thinking some sort of SMAA or FXAA perhaps? Or simply the NanoVG approach of drawing lines around the path edges for AA (it's a shame that conservative rasterization isn't widely available, because it would be of great help here).

The reason I'm mentioning this is to query to see if anyone would be interested in contributing to such a project. The main issue is, as mentioned, anti-aliasing; and to some extent rasterization if I want to avoid stencil buffer approaches.
It would definitely use sokol_gfx for it, at least if at all possible (and if not, then I'd create an extension header for sokol, to add the needed functionality).

@ib00
Copy link
Author

ib00 commented Nov 20, 2022

Thanks for taking the time and making your implementation available.

There is a cool small library for 2D drawing different than nanovg:
https://github.com/edubart/sokol_gp

But, ultimately, something like this would be fantastic:
https://acegikmo.com/shapes/

@zeromake
Copy link

zeromake commented Oct 11, 2023

@darkuranium

nanovg_sokol.h file: https://gist.github.com/darkuranium/746a1cdbb73004d6567783650a4b557f

#define NANOVG_SG_PIPELINE_CACHE_SIZE 32

output:

sokol_gfx.h:15715:0: 
        PIPELINE_POOL_EXHAUSTED: pipeline pool exhausted

change NANOVG_SG_PIPELINE_CACHE_SIZE to 4 not error
or change sg_setup pipeline_pool_size

I try sokol shader compiler but draw is invalid, I'll try to see if it works fine in opengl

my nanovg_sokol.h
my example_sokol.c

on windows opengl dx11 all rendered normally
on macosx metal draw is invalid: on xcode gpu debug find vs_buffer always 0, nanovg metal not use vs_buffer but use MTLRenderCommandEncoder->setVertexBuffer(0), may vs buffer and uniform exist at the same time
use black apple osx is not work, but white apple osx work is ok……

@ib00
Copy link
Author

ib00 commented Mar 18, 2024

@zeromake Did you get this to work (in OpenGL)?

@zeromake
Copy link

zeromake commented Mar 19, 2024

@ib00
merge to master branch
my nanovg_sokol.h
my example_sokol.c

example

> git clone https://github.com/zeromake/nanovg.git && cd nanovg
> xmake f -c -vD -m debug --example=y --pkg='sokol' -y
> xmake b example.sokol
> xmake r example.sokol

@ib00
Copy link
Author

ib00 commented Mar 21, 2024

@zeromake Very cool! I have some trouble compiling on linux. Shaders don't get compiled (and output into .h files)
properly.

@zeromake
Copy link

@zeromake Very cool! I have some trouble compiling on linux. Shaders don't get compiled (and output into .h files) properly.

I missed sokol_shader target, now is fix

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

7 participants