mirror of
https://github.com/memononen/nanovg
synced 2026-09-26 16:19:07 +03:00
Merge pull request #312 from satoren/master
Improve nvgGlobalCompositeOperation with state
This commit is contained in:
commit
47ffd9d0b9
3 changed files with 60 additions and 22 deletions
|
|
@ -390,7 +390,7 @@ void nvgCancelFrame(NVGcontext* ctx)
|
|||
void nvgEndFrame(NVGcontext* ctx)
|
||||
{
|
||||
NVGstate* state = nvg__getState(ctx);
|
||||
ctx->params.renderFlush(ctx->params.userPtr, state->compositeOperation);
|
||||
ctx->params.renderFlush(ctx->params.userPtr);
|
||||
if (ctx->fontImageIdx != 0) {
|
||||
int fontImage = ctx->fontImages[ctx->fontImageIdx];
|
||||
int i, j, iw, ih;
|
||||
|
|
@ -2212,7 +2212,7 @@ void nvgFill(NVGcontext* ctx)
|
|||
fillPaint.innerColor.a *= state->alpha;
|
||||
fillPaint.outerColor.a *= state->alpha;
|
||||
|
||||
ctx->params.renderFill(ctx->params.userPtr, &fillPaint, &state->scissor, ctx->fringeWidth,
|
||||
ctx->params.renderFill(ctx->params.userPtr, &fillPaint, state->compositeOperation, &state->scissor, ctx->fringeWidth,
|
||||
ctx->cache->bounds, ctx->cache->paths, ctx->cache->npaths);
|
||||
|
||||
// Count triangles
|
||||
|
|
@ -2253,7 +2253,7 @@ void nvgStroke(NVGcontext* ctx)
|
|||
else
|
||||
nvg__expandStroke(ctx, strokeWidth*0.5f, state->lineCap, state->lineJoin, state->miterLimit);
|
||||
|
||||
ctx->params.renderStroke(ctx->params.userPtr, &strokePaint, &state->scissor, ctx->fringeWidth,
|
||||
ctx->params.renderStroke(ctx->params.userPtr, &strokePaint, state->compositeOperation, &state->scissor, ctx->fringeWidth,
|
||||
strokeWidth, ctx->cache->paths, ctx->cache->npaths);
|
||||
|
||||
// Count triangles
|
||||
|
|
@ -2401,7 +2401,7 @@ static void nvg__renderText(NVGcontext* ctx, NVGvertex* verts, int nverts)
|
|||
paint.innerColor.a *= state->alpha;
|
||||
paint.outerColor.a *= state->alpha;
|
||||
|
||||
ctx->params.renderTriangles(ctx->params.userPtr, &paint, &state->scissor, verts, nverts);
|
||||
ctx->params.renderTriangles(ctx->params.userPtr, &paint, state->compositeOperation, &state->scissor, verts, nverts);
|
||||
|
||||
ctx->drawCallCount++;
|
||||
ctx->textTriCount += nverts/3;
|
||||
|
|
|
|||
|
|
@ -652,10 +652,10 @@ 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, 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);
|
||||
void (*renderFlush)(void* uptr);
|
||||
void (*renderFill)(void* uptr, NVGpaint* paint, NVGcompositeOperationState compositeOperation, NVGscissor* scissor, float fringe, const float* bounds, const NVGpath* paths, int npaths);
|
||||
void (*renderStroke)(void* uptr, NVGpaint* paint, NVGcompositeOperationState compositeOperation, NVGscissor* scissor, float fringe, float strokeWidth, const NVGpath* paths, int npaths);
|
||||
void (*renderTriangles)(void* uptr, NVGpaint* paint, NVGcompositeOperationState compositeOperation, NVGscissor* scissor, const NVGvertex* verts, int nverts);
|
||||
void (*renderDelete)(void* uptr);
|
||||
};
|
||||
typedef struct NVGparams NVGparams;
|
||||
|
|
|
|||
|
|
@ -150,6 +150,15 @@ struct GLNVGtexture {
|
|||
};
|
||||
typedef struct GLNVGtexture GLNVGtexture;
|
||||
|
||||
struct GLNVGblend
|
||||
{
|
||||
GLenum srcRGB;
|
||||
GLenum dstRGB;
|
||||
GLenum srcAlpha;
|
||||
GLenum dstAlpha;
|
||||
};
|
||||
typedef struct GLNVGblend GLNVGblend;
|
||||
|
||||
enum GLNVGcallType {
|
||||
GLNVG_NONE = 0,
|
||||
GLNVG_FILL,
|
||||
|
|
@ -166,6 +175,7 @@ struct GLNVGcall {
|
|||
int triangleOffset;
|
||||
int triangleCount;
|
||||
int uniformOffset;
|
||||
GLNVGblend blendFunc;
|
||||
};
|
||||
typedef struct GLNVGcall GLNVGcall;
|
||||
|
||||
|
|
@ -256,6 +266,7 @@ struct GLNVGcontext {
|
|||
GLenum stencilFunc;
|
||||
GLint stencilFuncRef;
|
||||
GLuint stencilFuncMask;
|
||||
GLNVGblend blendFunc;
|
||||
#endif
|
||||
};
|
||||
typedef struct GLNVGcontext GLNVGcontext;
|
||||
|
|
@ -316,6 +327,21 @@ static void glnvg__stencilFunc(GLNVGcontext* gl, GLenum func, GLint ref, GLuint
|
|||
glStencilFunc(func, ref, mask);
|
||||
#endif
|
||||
}
|
||||
static void glnvg__blendFuncSeparate(GLNVGcontext* gl, const GLNVGblend* blend)
|
||||
{
|
||||
#if NANOVG_GL_USE_STATE_FILTER
|
||||
if ((gl->blendFunc.srcRGB != blend->srcRGB) ||
|
||||
(gl->blendFunc.dstRGB != blend->dstRGB) ||
|
||||
(gl->blendFunc.srcAlpha != blend->srcAlpha) ||
|
||||
(gl->blendFunc.dstAlpha != blend->dstAlpha)) {
|
||||
|
||||
gl->blendFunc = *blend;
|
||||
glBlendFuncSeparate(blend->srcRGB, blend->dstRGB, blend->srcAlpha,blend->dstAlpha);
|
||||
}
|
||||
#else
|
||||
glBlendFuncSeparate(blend->srcRGB, blend->dstRGB, blend->srcAlpha,blend->dstAlpha);
|
||||
#endif
|
||||
}
|
||||
|
||||
static GLNVGtexture* glnvg__allocTexture(GLNVGcontext* gl)
|
||||
{
|
||||
|
|
@ -1116,19 +1142,24 @@ static GLenum glnvg_convertBlendFuncFactor(int factor)
|
|||
return GL_INVALID_ENUM;
|
||||
}
|
||||
|
||||
static void glnvg__blendCompositeOperation(NVGcompositeOperationState op)
|
||||
static GLNVGblend glnvg__blendCompositeOperation(NVGcompositeOperationState op)
|
||||
{
|
||||
GLenum srcRGB = glnvg_convertBlendFuncFactor(op.srcRGB);
|
||||
GLenum dstRGB = glnvg_convertBlendFuncFactor(op.dstRGB);
|
||||
GLenum srcAlpha = glnvg_convertBlendFuncFactor(op.srcAlpha);
|
||||
GLenum dstAlpha = glnvg_convertBlendFuncFactor(op.dstAlpha);
|
||||
if (srcRGB == GL_INVALID_ENUM || dstRGB == GL_INVALID_ENUM || srcAlpha == GL_INVALID_ENUM || dstAlpha == GL_INVALID_ENUM)
|
||||
glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
|
||||
else
|
||||
glBlendFuncSeparate(srcRGB, dstRGB, srcAlpha, dstAlpha);
|
||||
GLNVGblend blend;
|
||||
blend.srcRGB = glnvg_convertBlendFuncFactor(op.srcRGB);
|
||||
blend.dstRGB = glnvg_convertBlendFuncFactor(op.dstRGB);
|
||||
blend.srcAlpha = glnvg_convertBlendFuncFactor(op.srcAlpha);
|
||||
blend.dstAlpha = glnvg_convertBlendFuncFactor(op.dstAlpha);
|
||||
if (blend.srcRGB == GL_INVALID_ENUM || blend.dstRGB == GL_INVALID_ENUM || blend.srcAlpha == GL_INVALID_ENUM || blend.dstAlpha == GL_INVALID_ENUM)
|
||||
{
|
||||
blend.srcRGB = GL_ONE;
|
||||
blend.dstRGB = GL_ONE_MINUS_SRC_ALPHA;
|
||||
blend.srcAlpha = GL_ONE;
|
||||
blend.dstAlpha = GL_ONE_MINUS_SRC_ALPHA;
|
||||
}
|
||||
return blend;
|
||||
}
|
||||
|
||||
static void glnvg__renderFlush(void* uptr, NVGcompositeOperationState compositeOperation)
|
||||
static void glnvg__renderFlush(void* uptr)
|
||||
{
|
||||
GLNVGcontext* gl = (GLNVGcontext*)uptr;
|
||||
int i;
|
||||
|
|
@ -1138,7 +1169,6 @@ static void glnvg__renderFlush(void* uptr, NVGcompositeOperationState compositeO
|
|||
// Setup require GL state.
|
||||
glUseProgram(gl->shader.prog);
|
||||
|
||||
glnvg__blendCompositeOperation(compositeOperation);
|
||||
glEnable(GL_CULL_FACE);
|
||||
glCullFace(GL_BACK);
|
||||
glFrontFace(GL_CCW);
|
||||
|
|
@ -1157,6 +1187,10 @@ static void glnvg__renderFlush(void* uptr, NVGcompositeOperationState compositeO
|
|||
gl->stencilFunc = GL_ALWAYS;
|
||||
gl->stencilFuncRef = 0;
|
||||
gl->stencilFuncMask = 0xffffffff;
|
||||
gl->blendFunc.srcRGB = GL_INVALID_ENUM;
|
||||
gl->blendFunc.srcAlpha = GL_INVALID_ENUM;
|
||||
gl->blendFunc.dstRGB = GL_INVALID_ENUM;
|
||||
gl->blendFunc.dstAlpha = GL_INVALID_ENUM;
|
||||
#endif
|
||||
|
||||
#if NANOVG_GL_USE_UNIFORMBUFFER
|
||||
|
|
@ -1186,6 +1220,7 @@ static void glnvg__renderFlush(void* uptr, NVGcompositeOperationState compositeO
|
|||
|
||||
for (i = 0; i < gl->ncalls; i++) {
|
||||
GLNVGcall* call = &gl->calls[i];
|
||||
glnvg__blendFuncSeparate(gl,&call->blendFunc);
|
||||
if (call->type == GLNVG_FILL)
|
||||
glnvg__fill(gl, call);
|
||||
else if (call->type == GLNVG_CONVEXFILL)
|
||||
|
|
@ -1301,7 +1336,7 @@ static void glnvg__vset(NVGvertex* vtx, float x, float y, float u, float v)
|
|||
vtx->v = v;
|
||||
}
|
||||
|
||||
static void glnvg__renderFill(void* uptr, NVGpaint* paint, NVGscissor* scissor, float fringe,
|
||||
static void glnvg__renderFill(void* uptr, NVGpaint* paint, NVGcompositeOperationState compositeOperation, NVGscissor* scissor, float fringe,
|
||||
const float* bounds, const NVGpath* paths, int npaths)
|
||||
{
|
||||
GLNVGcontext* gl = (GLNVGcontext*)uptr;
|
||||
|
|
@ -1317,6 +1352,7 @@ static void glnvg__renderFill(void* uptr, NVGpaint* paint, NVGscissor* scissor,
|
|||
if (call->pathOffset == -1) goto error;
|
||||
call->pathCount = npaths;
|
||||
call->image = paint->image;
|
||||
call->blendFunc = glnvg__blendCompositeOperation(compositeOperation);
|
||||
|
||||
if (npaths == 1 && paths[0].convex)
|
||||
call->type = GLNVG_CONVEXFILL;
|
||||
|
|
@ -1382,7 +1418,7 @@ error:
|
|||
if (gl->ncalls > 0) gl->ncalls--;
|
||||
}
|
||||
|
||||
static void glnvg__renderStroke(void* uptr, NVGpaint* paint, NVGscissor* scissor, float fringe,
|
||||
static void glnvg__renderStroke(void* uptr, NVGpaint* paint, NVGcompositeOperationState compositeOperation, NVGscissor* scissor, float fringe,
|
||||
float strokeWidth, const NVGpath* paths, int npaths)
|
||||
{
|
||||
GLNVGcontext* gl = (GLNVGcontext*)uptr;
|
||||
|
|
@ -1396,6 +1432,7 @@ static void glnvg__renderStroke(void* uptr, NVGpaint* paint, NVGscissor* scissor
|
|||
if (call->pathOffset == -1) goto error;
|
||||
call->pathCount = npaths;
|
||||
call->image = paint->image;
|
||||
call->blendFunc = glnvg__blendCompositeOperation(compositeOperation);
|
||||
|
||||
// Allocate vertices for all the paths.
|
||||
maxverts = glnvg__maxVertCount(paths, npaths);
|
||||
|
|
@ -1437,7 +1474,7 @@ error:
|
|||
if (gl->ncalls > 0) gl->ncalls--;
|
||||
}
|
||||
|
||||
static void glnvg__renderTriangles(void* uptr, NVGpaint* paint, NVGscissor* scissor,
|
||||
static void glnvg__renderTriangles(void* uptr, NVGpaint* paint, NVGcompositeOperationState compositeOperation, NVGscissor* scissor,
|
||||
const NVGvertex* verts, int nverts)
|
||||
{
|
||||
GLNVGcontext* gl = (GLNVGcontext*)uptr;
|
||||
|
|
@ -1448,6 +1485,7 @@ static void glnvg__renderTriangles(void* uptr, NVGpaint* paint, NVGscissor* scis
|
|||
|
||||
call->type = GLNVG_TRIANGLES;
|
||||
call->image = paint->image;
|
||||
call->blendFunc = glnvg__blendCompositeOperation(compositeOperation);
|
||||
|
||||
// Allocate vertices for all the paths.
|
||||
call->triangleOffset = glnvg__allocVerts(gl, nverts);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue