Updates nanovg to support global composite operation. (#877)
This commit updates bgfx's NanoVG codebase to adapt the latest NanoVG commit since I've implemented blending support for the original NanoVG and there is no need of `nvgState()` anymore.
This commit is contained in:
parent
9f7386e53a
commit
1804ba77c1
@ -110,6 +110,7 @@ enum NVGpointFlags
|
||||
};
|
||||
|
||||
struct NVGstate {
|
||||
NVGcompositeOperationState compositeOperation;
|
||||
NVGpaint fill;
|
||||
NVGpaint stroke;
|
||||
float strokeWidth;
|
||||
@ -247,6 +248,79 @@ static void nvg__setDevicePixelRatio(NVGcontext* ctx, float ratio)
|
||||
ctx->devicePxRatio = ratio;
|
||||
}
|
||||
|
||||
static NVGcompositeOperationState nvg__compositeOperationState(int op)
|
||||
{
|
||||
int sfactor, dfactor;
|
||||
|
||||
if (op == NVG_SOURCE_OVER)
|
||||
{
|
||||
sfactor = NVG_ONE;
|
||||
dfactor = NVG_ONE_MINUS_SRC_ALPHA;
|
||||
}
|
||||
else if (op == NVG_SOURCE_IN)
|
||||
{
|
||||
sfactor = NVG_DST_ALPHA;
|
||||
dfactor = NVG_ZERO;
|
||||
}
|
||||
else if (op == NVG_SOURCE_OUT)
|
||||
{
|
||||
sfactor = NVG_ONE_MINUS_DST_ALPHA;
|
||||
dfactor = NVG_ZERO;
|
||||
}
|
||||
else if (op == NVG_ATOP)
|
||||
{
|
||||
sfactor = NVG_DST_ALPHA;
|
||||
dfactor = NVG_ONE_MINUS_SRC_ALPHA;
|
||||
}
|
||||
else if (op == NVG_DESTINATION_OVER)
|
||||
{
|
||||
sfactor = NVG_ONE_MINUS_DST_ALPHA;
|
||||
dfactor = NVG_ONE;
|
||||
}
|
||||
else if (op == NVG_DESTINATION_IN)
|
||||
{
|
||||
sfactor = NVG_ZERO;
|
||||
dfactor = NVG_SRC_ALPHA;
|
||||
}
|
||||
else if (op == NVG_DESTINATION_OUT)
|
||||
{
|
||||
sfactor = NVG_ZERO;
|
||||
dfactor = NVG_ONE_MINUS_SRC_ALPHA;
|
||||
}
|
||||
else if (op == NVG_DESTINATION_ATOP)
|
||||
{
|
||||
sfactor = NVG_ONE_MINUS_DST_ALPHA;
|
||||
dfactor = NVG_SRC_ALPHA;
|
||||
}
|
||||
else if (op == NVG_LIGHTER)
|
||||
{
|
||||
sfactor = NVG_ONE;
|
||||
dfactor = NVG_ONE;
|
||||
}
|
||||
else if (op == NVG_COPY)
|
||||
{
|
||||
sfactor = NVG_ONE;
|
||||
dfactor = NVG_ZERO;
|
||||
}
|
||||
else if (op == NVG_XOR)
|
||||
{
|
||||
sfactor = NVG_ONE_MINUS_DST_ALPHA;
|
||||
dfactor = NVG_ONE_MINUS_SRC_ALPHA;
|
||||
}
|
||||
|
||||
NVGcompositeOperationState state;
|
||||
state.srcRGB = sfactor;
|
||||
state.dstRGB = dfactor;
|
||||
state.srcAlpha = sfactor;
|
||||
state.dstAlpha = dfactor;
|
||||
return state;
|
||||
}
|
||||
|
||||
static NVGstate* nvg__getState(NVGcontext* ctx)
|
||||
{
|
||||
return &ctx->states[ctx->nstates-1];
|
||||
}
|
||||
|
||||
NVGcontext* nvgCreateInternal(NVGparams* params)
|
||||
{
|
||||
FONSparams fontParams;
|
||||
@ -354,7 +428,8 @@ void nvgCancelFrame(NVGcontext* ctx)
|
||||
|
||||
void nvgEndFrame(NVGcontext* ctx)
|
||||
{
|
||||
ctx->params.renderFlush(ctx->params.userPtr);
|
||||
NVGstate* state = nvg__getState(ctx);
|
||||
ctx->params.renderFlush(ctx->params.userPtr, state->compositeOperation);
|
||||
if (ctx->fontImageIdx != 0) {
|
||||
int fontImage = ctx->fontImages[ctx->fontImageIdx];
|
||||
int i, j, iw, ih;
|
||||
@ -430,7 +505,7 @@ NVGcolor nvgLerpRGBA(NVGcolor c0, NVGcolor c1, float u)
|
||||
{
|
||||
int i;
|
||||
float oneminu;
|
||||
NVGcolor cint;
|
||||
NVGcolor cint = {0};
|
||||
|
||||
u = nvg__clampf(u, 0.0f, 1.0f);
|
||||
oneminu = 1.0f - u;
|
||||
@ -477,12 +552,6 @@ NVGcolor nvgHSLA(float h, float s, float l, unsigned char a)
|
||||
return col;
|
||||
}
|
||||
|
||||
|
||||
static NVGstate* nvg__getState(NVGcontext* ctx)
|
||||
{
|
||||
return &ctx->states[ctx->nstates-1];
|
||||
}
|
||||
|
||||
void nvgTransformIdentity(float* t)
|
||||
{
|
||||
t[0] = 1.0f; t[1] = 0.0f;
|
||||
@ -615,6 +684,7 @@ void nvgReset(NVGcontext* ctx)
|
||||
|
||||
nvg__setPaintColor(&state->fill, nvgRGBA(255,255,255,255));
|
||||
nvg__setPaintColor(&state->stroke, nvgRGBA(0,0,0,255));
|
||||
state->compositeOperation = nvg__compositeOperationState(NVG_SOURCE_OVER);
|
||||
state->strokeWidth = 1.0f;
|
||||
state->miterLimit = 10.0f;
|
||||
state->lineCap = NVG_BUTT;
|
||||
@ -983,6 +1053,30 @@ void nvgResetScissor(NVGcontext* ctx)
|
||||
state->scissor.extent[1] = -1.0f;
|
||||
}
|
||||
|
||||
// Global composite operation.
|
||||
void nvgGlobalCompositeOperation(NVGcontext* ctx, int op)
|
||||
{
|
||||
NVGstate* state = nvg__getState(ctx);
|
||||
state->compositeOperation = nvg__compositeOperationState(op);
|
||||
}
|
||||
|
||||
void nvgGlobalCompositeBlendFunc(NVGcontext* ctx, int sfactor, int dfactor)
|
||||
{
|
||||
nvgGlobalCompositeBlendFuncSeparate(ctx, sfactor, dfactor, sfactor, dfactor);
|
||||
}
|
||||
|
||||
void nvgGlobalCompositeBlendFuncSeparate(NVGcontext* ctx, int srcRGB, int dstRGB, int srcAlpha, int dstAlpha)
|
||||
{
|
||||
NVGcompositeOperationState op;
|
||||
op.srcRGB = srcRGB;
|
||||
op.dstRGB = dstRGB;
|
||||
op.srcAlpha = srcAlpha;
|
||||
op.dstAlpha = dstAlpha;
|
||||
|
||||
NVGstate* state = nvg__getState(ctx);
|
||||
state->compositeOperation = op;
|
||||
}
|
||||
|
||||
static int nvg__ptEquals(float x1, float y1, float x2, float y2, float tol)
|
||||
{
|
||||
float dx = x2 - x1;
|
||||
|
@ -81,10 +81,46 @@ enum NVGalign {
|
||||
// Vertical align
|
||||
NVG_ALIGN_TOP = 1<<3, // Align text vertically to top.
|
||||
NVG_ALIGN_MIDDLE = 1<<4, // Align text vertically to middle.
|
||||
NVG_ALIGN_BOTTOM = 1<<5, // Align text vertically to bottom.
|
||||
NVG_ALIGN_BASELINE = 1<<6, // Default, align text vertically to baseline.
|
||||
NVG_ALIGN_BOTTOM = 1<<5, // Align text vertically to bottom.
|
||||
NVG_ALIGN_BASELINE = 1<<6, // Default, align text vertically to baseline.
|
||||
};
|
||||
|
||||
enum NVGblendFactor {
|
||||
NVG_ZERO = 1<<0,
|
||||
NVG_ONE = 1<<1,
|
||||
NVG_SRC_COLOR = 1<<2,
|
||||
NVG_ONE_MINUS_SRC_COLOR = 1<<3,
|
||||
NVG_DST_COLOR = 1<<4,
|
||||
NVG_ONE_MINUS_DST_COLOR = 1<<5,
|
||||
NVG_SRC_ALPHA = 1<<6,
|
||||
NVG_ONE_MINUS_SRC_ALPHA = 1<<7,
|
||||
NVG_DST_ALPHA = 1<<8,
|
||||
NVG_ONE_MINUS_DST_ALPHA = 1<<9,
|
||||
NVG_SRC_ALPHA_SATURATE = 1<<10,
|
||||
};
|
||||
|
||||
enum NVGcompositeOperation {
|
||||
NVG_SOURCE_OVER,
|
||||
NVG_SOURCE_IN,
|
||||
NVG_SOURCE_OUT,
|
||||
NVG_ATOP,
|
||||
NVG_DESTINATION_OVER,
|
||||
NVG_DESTINATION_IN,
|
||||
NVG_DESTINATION_OUT,
|
||||
NVG_DESTINATION_ATOP,
|
||||
NVG_LIGHTER,
|
||||
NVG_COPY,
|
||||
NVG_XOR,
|
||||
};
|
||||
|
||||
struct NVGcompositeOperationState {
|
||||
int srcRGB;
|
||||
int dstRGB;
|
||||
int srcAlpha;
|
||||
int dstAlpha;
|
||||
};
|
||||
typedef struct NVGcompositeOperationState NVGcompositeOperationState;
|
||||
|
||||
struct NVGglyphPosition {
|
||||
const char* str; // Position of the glyph in the input string.
|
||||
float x; // The x-coordinate of the logical glyph position.
|
||||
@ -125,6 +161,22 @@ void nvgCancelFrame(NVGcontext* ctx);
|
||||
// Ends drawing flushing remaining render state.
|
||||
void nvgEndFrame(NVGcontext* ctx);
|
||||
|
||||
//
|
||||
// Composite operation
|
||||
//
|
||||
// The composite operations in NanoVG are modeled after HTML Canvas API, and
|
||||
// the blend func is based on OpenGL (see corresponding manuals for more info).
|
||||
// The colors in the blending state have premultiplied alpha.
|
||||
|
||||
// Sets the composite operation. The op parameter should be one of NVGcompositeOperation.
|
||||
void nvgGlobalCompositeOperation(NVGcontext* ctx, int op);
|
||||
|
||||
// Sets the composite operation with custom pixel arithmetic. The parameters should be one of NVGblendFactor.
|
||||
void nvgGlobalCompositeBlendFunc(NVGcontext* ctx, int sfactor, int dfactor);
|
||||
|
||||
// Sets the composite operation with custom pixel arithmetic for RGB and alpha components separately. The parameters should be one of NVGblendFactor.
|
||||
void nvgGlobalCompositeBlendFuncSeparate(NVGcontext* ctx, int srcRGB, int dstRGB, int srcAlpha, int dstAlpha);
|
||||
|
||||
//
|
||||
// Color utils
|
||||
//
|
||||
@ -185,7 +237,7 @@ void nvgReset(NVGcontext* ctx);
|
||||
// Solid color is simply defined as a color value, different kinds of paints can be created
|
||||
// using nvgLinearGradient(), nvgBoxGradient(), nvgRadialGradient() and nvgImagePattern().
|
||||
//
|
||||
// Current render style can be saved and restored using nvgSave() and nvgRestore().
|
||||
// Current render style can be saved and restored using nvgSave() and nvgRestore().
|
||||
|
||||
// Sets current stroke style to a solid color.
|
||||
void nvgStrokeColor(NVGcontext* ctx, NVGcolor color);
|
||||
@ -215,7 +267,7 @@ void nvgLineCap(NVGcontext* ctx, int cap);
|
||||
void nvgLineJoin(NVGcontext* ctx, int join);
|
||||
|
||||
// Sets the transparency applied to all rendered shapes.
|
||||
// Alreade transparent paths will get proportionally more transparent as well.
|
||||
// Already transparent paths will get proportionally more transparent as well.
|
||||
void nvgGlobalAlpha(NVGcontext* ctx, float alpha);
|
||||
|
||||
//
|
||||
@ -233,7 +285,7 @@ void nvgGlobalAlpha(NVGcontext* ctx, float alpha);
|
||||
// Apart from nvgResetTransform(), each transformation function first creates
|
||||
// specific transformation matrix and pre-multiplies the current transformation by it.
|
||||
//
|
||||
// Current coordinate system (transformation) can be saved and restored using nvgSave() and nvgRestore().
|
||||
// Current coordinate system (transformation) can be saved and restored using nvgSave() and nvgRestore().
|
||||
|
||||
// Resets current transform to a identity matrix.
|
||||
void nvgResetTransform(NVGcontext* ctx);
|
||||
@ -347,7 +399,7 @@ NVGpaint nvgLinearGradient(NVGcontext* ctx, float sx, float sy, float ex, float
|
||||
NVGcolor icol, NVGcolor ocol);
|
||||
|
||||
// Creates and returns a box gradient. Box gradient is a feathered rounded rectangle, it is useful for rendering
|
||||
// drop shadows or hilights for boxes. Parameters (x,y) define the top-left corner of the rectangle,
|
||||
// drop shadows or highlights for boxes. Parameters (x,y) define the top-left corner of the rectangle,
|
||||
// (w,h) define the size of the rectangle, r defines the corner radius, and f feather. Feather defines how blurry
|
||||
// the border of the rectangle is. Parameter icol specifies the inner color and ocol the outer color of the gradient.
|
||||
// The gradient is transformed by the current transform when it is passed to nvgFillPaint() or nvgStrokePaint().
|
||||
@ -369,8 +421,8 @@ NVGpaint nvgImagePattern(NVGcontext* ctx, float ox, float oy, float ex, float ey
|
||||
//
|
||||
// Scissoring
|
||||
//
|
||||
// Scissoring allows you to clip the rendering into a rectangle. This is useful for varius
|
||||
// user interface cases like rendering a text edit or a timeline.
|
||||
// Scissoring allows you to clip the rendering into a rectangle. This is useful for various
|
||||
// user interface cases like rendering a text edit or a timeline.
|
||||
|
||||
// Sets the current scissor rectangle.
|
||||
// The scissor rectangle is transformed by the current transform.
|
||||
@ -425,7 +477,7 @@ void nvgArcTo(NVGcontext* ctx, float x1, float y1, float x2, float y2, float rad
|
||||
// Closes current sub-path with a line segment.
|
||||
void nvgClosePath(NVGcontext* ctx);
|
||||
|
||||
// Sets the current sub-path winding, see NVGwinding and NVGsolidity.
|
||||
// Sets the current sub-path winding, see NVGwinding and NVGsolidity.
|
||||
void nvgPathWinding(NVGcontext* ctx, int dir);
|
||||
|
||||
// Creates new circle arc shaped sub-path. The arc center is at cx,cy, the arc radius is r,
|
||||
@ -442,7 +494,7 @@ void nvgRoundedRect(NVGcontext* ctx, float x, float y, float w, float h, float r
|
||||
// Creates new ellipse shaped sub-path.
|
||||
void nvgEllipse(NVGcontext* ctx, float cx, float cy, float rx, float ry);
|
||||
|
||||
// Creates new circle shaped sub-path.
|
||||
// Creates new circle shaped sub-path.
|
||||
void nvgCircle(NVGcontext* ctx, float cx, float cy, float r);
|
||||
|
||||
// Fills the current path with current fill style.
|
||||
@ -489,7 +541,7 @@ void nvgStroke(NVGcontext* ctx);
|
||||
// Returns handle to the font.
|
||||
int nvgCreateFont(NVGcontext* ctx, const char* name, const char* filename);
|
||||
|
||||
// Creates image by loading it from the specified memory chunk.
|
||||
// Creates font by loading it from the specified memory chunk.
|
||||
// Returns handle to the font.
|
||||
int nvgCreateFontMem(NVGcontext* ctx, const char* name, unsigned char* data, int ndata, int freeData);
|
||||
|
||||
@ -505,7 +557,7 @@ void nvgFontBlur(NVGcontext* ctx, float blur);
|
||||
// Sets the letter spacing of current text style.
|
||||
void nvgTextLetterSpacing(NVGcontext* ctx, float spacing);
|
||||
|
||||
// Sets the proportional line height of current text style. The line height is specified as multiple of font size.
|
||||
// Sets the proportional line height of current text style. The line height is specified as multiple of font size.
|
||||
void nvgTextLineHeight(NVGcontext* ctx, float lineHeight);
|
||||
|
||||
// Sets the text align of current text style, see NVGalign for options.
|
||||
@ -592,7 +644,7 @@ struct NVGparams {
|
||||
int (*renderGetTextureSize)(void* uptr, int image, int* w, int* h);
|
||||
void (*renderViewport)(void* uptr, int width, int height, float devicePixelRatio);
|
||||
void (*renderCancel)(void* uptr);
|
||||
void (*renderFlush)(void* uptr);
|
||||
void (*renderFlush)(void* uptr, NVGcompositeOperationState compositeOperation);
|
||||
void (*renderFill)(void* uptr, NVGpaint* paint, NVGscissor* scissor, float fringe, const float* bounds, const NVGpath* paths, int npaths);
|
||||
void (*renderStroke)(void* uptr, NVGpaint* paint, NVGscissor* scissor, float fringe, float strokeWidth, const NVGpath* paths, int npaths);
|
||||
void (*renderTriangles)(void* uptr, NVGpaint* paint, NVGscissor* scissor, const NVGvertex* verts, int nverts);
|
||||
|
@ -537,7 +537,6 @@ namespace
|
||||
static void nvgRenderViewport(void* _userPtr, int width, int height, float devicePixelRatio)
|
||||
{
|
||||
struct GLNVGcontext* gl = (struct GLNVGcontext*)_userPtr;
|
||||
gl->state = 0;
|
||||
gl->view[0] = (float)width;
|
||||
gl->view[1] = (float)height;
|
||||
bgfx::setViewRect(gl->m_viewId, 0, 0, width * devicePixelRatio, height * devicePixelRatio);
|
||||
@ -694,7 +693,42 @@ namespace
|
||||
}
|
||||
}
|
||||
|
||||
static void nvgRenderFlush(void* _userPtr)
|
||||
static uint64_t glnvg_convertBlendFuncFactor(int factor)
|
||||
{
|
||||
if (factor == NVG_ZERO)
|
||||
return BGFX_STATE_BLEND_ZERO;
|
||||
if (factor == NVG_ONE)
|
||||
return BGFX_STATE_BLEND_ONE;
|
||||
if (factor == NVG_SRC_COLOR)
|
||||
return BGFX_STATE_BLEND_SRC_COLOR;
|
||||
if (factor == NVG_ONE_MINUS_SRC_COLOR)
|
||||
return BGFX_STATE_BLEND_INV_SRC_COLOR;
|
||||
if (factor == NVG_DST_COLOR)
|
||||
return BGFX_STATE_BLEND_DST_COLOR;
|
||||
if (factor == NVG_ONE_MINUS_DST_COLOR)
|
||||
return BGFX_STATE_BLEND_INV_DST_COLOR;
|
||||
if (factor == NVG_SRC_ALPHA)
|
||||
return BGFX_STATE_BLEND_SRC_ALPHA;
|
||||
if (factor == NVG_ONE_MINUS_SRC_ALPHA)
|
||||
return BGFX_STATE_BLEND_INV_SRC_ALPHA;
|
||||
if (factor == NVG_DST_ALPHA)
|
||||
return BGFX_STATE_BLEND_DST_ALPHA;
|
||||
if (factor == NVG_ONE_MINUS_DST_ALPHA)
|
||||
return BGFX_STATE_BLEND_INV_DST_ALPHA;
|
||||
if (factor == NVG_SRC_ALPHA_SATURATE)
|
||||
return BGFX_STATE_BLEND_SRC_ALPHA_SAT;
|
||||
}
|
||||
|
||||
static uint64_t glnvg__blendCompositeOperation(NVGcompositeOperationState op)
|
||||
{
|
||||
return BGFX_STATE_BLEND_FUNC_SEPARATE(
|
||||
glnvg_convertBlendFuncFactor(op.srcRGB),
|
||||
glnvg_convertBlendFuncFactor(op.dstRGB),
|
||||
glnvg_convertBlendFuncFactor(op.srcAlpha),
|
||||
glnvg_convertBlendFuncFactor(op.dstAlpha));
|
||||
}
|
||||
|
||||
static void nvgRenderFlush(void* _userPtr, NVGcompositeOperationState compositeOperation)
|
||||
{
|
||||
struct GLNVGcontext* gl = (struct GLNVGcontext*)_userPtr;
|
||||
|
||||
@ -712,12 +746,7 @@ namespace
|
||||
|
||||
memcpy(gl->tvb.data, gl->verts, gl->nverts * sizeof(struct NVGvertex) );
|
||||
|
||||
if (0 == gl->state)
|
||||
{
|
||||
gl->state = BGFX_STATE_BLEND_FUNC(BGFX_STATE_BLEND_ONE, BGFX_STATE_BLEND_INV_SRC_ALPHA);
|
||||
}
|
||||
|
||||
gl->state |= 0
|
||||
gl->state = glnvg__blendCompositeOperation(compositeOperation)
|
||||
| BGFX_STATE_RGB_WRITE
|
||||
| BGFX_STATE_ALPHA_WRITE
|
||||
;
|
||||
@ -1078,13 +1107,6 @@ void nvgDelete(struct NVGcontext* ctx)
|
||||
nvgDeleteInternal(ctx);
|
||||
}
|
||||
|
||||
void nvgState(struct NVGcontext* ctx, uint64_t state)
|
||||
{
|
||||
struct NVGparams* params = nvgInternalParams(ctx);
|
||||
struct GLNVGcontext* gl = (struct GLNVGcontext*)params->userPtr;
|
||||
gl->state = state;
|
||||
}
|
||||
|
||||
uint8_t nvgViewId(struct NVGcontext* ctx)
|
||||
{
|
||||
struct NVGparams* params = nvgInternalParams(ctx);
|
||||
@ -1144,9 +1166,9 @@ void nvgluBindFramebuffer(NVGLUframebuffer* framebuffer) {
|
||||
void nvgluDeleteFramebuffer(NVGLUframebuffer* framebuffer) {
|
||||
if (framebuffer == NULL)
|
||||
return;
|
||||
if (framebuffer->image >= 0)
|
||||
nvgDeleteImage(framebuffer->ctx, framebuffer->image);
|
||||
if (bgfx::isValid(framebuffer->handle))
|
||||
bgfx::destroyFrameBuffer(framebuffer->handle);
|
||||
if (framebuffer->image > 0)
|
||||
nvgDeleteImage(framebuffer->ctx, framebuffer->image);
|
||||
delete framebuffer;
|
||||
}
|
||||
|
@ -23,7 +23,6 @@ typedef struct NVGLUframebuffer NVGLUframebuffer;
|
||||
NVGcontext* nvgCreate(int edgeaa, unsigned char _viewId, bx::AllocatorI* _allocator);
|
||||
NVGcontext* nvgCreate(int edgeaa, unsigned char _viewId);
|
||||
void nvgDelete(struct NVGcontext* ctx);
|
||||
void nvgState(struct NVGcontext* ctx, uint64_t state);
|
||||
uint8_t nvgViewId(struct NVGcontext* ctx);
|
||||
void nvgViewId(struct NVGcontext* ctx, unsigned char _viewId);
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user