Allows you to build a list of NanoVg rendering commands to be executued later/elsewhere/repeatably. One use case is to render from another thread.
Single header, only dependencies are nanovg, cstdint, std::string, std::vector
This also supports sdl_stb_font producer consumer frontend integration, use #define SDL_STB_PRODUCER_CONSUMER to enable.
Example - lock free submission of nanovg draw commands from a second thread.
// Thread 1 (update thread)
NanoVgCommandBuffer* buff = new NanoVgCommandBuffer; // you don't need to use heap, its just easier to pass between threads
buff->nvgBeginPath();
buff->nvgRect(100,100, 120,30);
buff->nvgFillColor(nvgRGBA(255,192,0,255));
buff->nvgFill();
mConcurrentQueue.enqueue(buff); // using moodycamel::BlockingConcurrentQueue to pass ownership between threads
buff = NULL;
// Thread 2 (render thread)
NanoVgCommandBuffer* buff = NULL;
mConcurrentQueue.dequeue(buff)
nvgBeginFrame(vg, windowW , windowH, (float)windowW / ( float)windowH);
if (buff) {
buff->dispatch(vg); // actually executes the commandsdelete buff; // if you're done with it, otherwise keep and reuse it
}
nvgEndFrame(vg);Buffers can be reused. NanoVgCommandBuffer doesn't need to see a nanovg context nor does it care about nanovg's internal state, it just stores commands to be executed when dispatch(vg) is called.
This is a single header library. To use:
#include"nanovg_command_buffer.hpp"and in one file:
#defineNANOVG_COMMAND_BUFFER_IMPL
#include"nanovg_command_buffer.hpp"classNanoVgCommandBuffer;
///////////////////////////////// Command Buffer Object Functionsvoidswap(NanoVgCommandBuffer& other); // swaps internal std::vectorsvoidclear();
voiddispatchSingle(NVGcontext* ctx, const NanoVgCommandBuffer::command & c); // Executes a single instructionvoiddispatch(NVGcontext* ctx); // Executes all instructions//////////////////////////////// Command Buffer Commands:// flow controlvoidpause(int pauseCode); // Sets a marker in the command buffer to pause rendering until dispatch() is called again. NanoVgCommandBuffer::pauseCode is set to `pauseCode`// nvg compositevoidnvgGlobalCompositeOperation(int op);
voidnvgGlobalCompositeBlendFunc(int sfactor, int dfactor);
voidnvgGlobalCompositeBlendFuncSeparate(int srcRGB, int dstRGB, int srcAlpha, int dstAlpha);
// nvg statevoidnvgSave();
voidnvgRestore();
voidnvgReset();
// nvg stylevoidnvgShapeAntiAlias(int enabled);
voidnvgStrokeColor(NVGcolor color);
voidnvgStrokePaint(NVGpaint paint);
voidnvgFillColor(NVGcolor color);
voidnvgFillPaint(NVGpaint paint);
voidnvgMiterLimit(float limit);
voidnvgStrokeWidth(float size);
voidnvgLineCap(int cap);
voidnvgLineJoin(int join);
voidnvgGlobalAlpha(float alpha);
// nvg transformvoidnvgResetTransform();
voidnvgTransform(float a, float b, float c, float d, float e, float f);
voidnvgTranslate(float x, float y);
voidnvgRotate(float angle);
voidnvgSkewX(float angle);
voidnvgSkewY(float angle);
voidnvgScale(float x, float y);
// nvg scissorvoidnvgScissor(float x, float y, float w, float h);
voidnvgIntersectScissor(float x, float y, float w, float h);
voidnvgResetScissor();
//nvg pathvoidnvgBeginPath();
voidnvgMoveTo(float x, float y);
voidnvgLineTo(float x, float y);
voidnvgBezierTo(float c1x, float c1y, float c2x, float c2y, float x, float y);
voidnvgQuadTo(float cx, float cy, float x, float y);
voidnvgArcTo(float cx, float cy, float x, float y, float radius);
voidnvgClosePath();
voidnvgPathWinding(int dir);
voidnvgArc(float cx, float cy, float r, float a0, float a1, int dir);
voidnvgRect(float x, float y, float w, float h);
voidnvgRoundedRect(float x, float y, float w, float h, float r);
voidnvgEllipse(float cx, float cy, float rx, float ry);
voidnvgCircle(float cx, float cy, float r);
voidnvgFill();
voidnvgStroke();
// nvg fontvoidnvgFontSize(float size);
voidnvgFontBlur(float blur);
voidnvgTextLetterSpacing(float spacing);
voidnvgTextLineHeight(float lineHeight);
voidnvgTextAlign(int align);
voidnvgFontFaceId(int font);
voidnvgText(float x, float y, constchar* string, constchar* end);
voidnvgTextBox(float x, float y, float breakRowWidth, constchar* string, constchar* end);- NVGpaint instances will be reusued if the same one is used sequentially.
- Text functions store a copy of the string to be drawn. You can safely discard a string after calling nvgText, etc
- nvgRoundedRectVarying - has too many args. I might add it if someone wants it
- nvgFontFace - use nvgFontFaceId instead
- Most functions that returns a value. This lib can only be used to set states, not query them
Public Domain