* This is the reference documentation for handling matrices to use as transformation in drawing operations.
* Matrix computations in vkvg are taken from the cairo library.
* @{ */
-#define VKVG_IDENTITY_MATRIX {1,0,0,1,0,0}/*!< The identity matrix*/
+#define VKVG_IDENTITY_MATRIX (vkvg_matrix_t){1,0,0,1,0,0}/*!< The identity matrix*/
/**
* @brief vkvg matrix structure
*
*/
vkvg_public
void vkvg_clip_preserve (VkvgContext ctx);
+vkvg_public
+void vkvg_set_opacity (VkvgContext ctx, float opacity);
+vkvg_public
+float vkvg_get_opacity (VkvgContext ctx);
/**
* @brief Set current source for drawing to the solid color defined by the supplied 32bit integer.
* @param ctx a valid vkvg @ref context
*/
vkvg_public
vkvg_pattern_type_t vkvg_pattern_get_type (VkvgPattern pat);
+vkvg_public
+void vkvg_pattern_set_matrix (VkvgPattern pat, const vkvg_matrix_t* matrix);
+vkvg_public
+void vkvg_pattern_get_matrix (VkvgPattern pat, vkvg_matrix_t* matrix);
+
/** @}*/
/********* EXPERIMENTAL **************/
layout (location = 0) in vec3 inFontUV; //if it is a text drawing, inFontUV.z hold fontMap layer
layout (location = 1) in vec4 inSrc; //source bounds or color depending on pattern type
layout (location = 2) in flat int inPatType; //pattern type
-layout (location = 3) in mat3x2 inMat;
+layout (location = 3) in flat float inOpacity;
+layout (location = 4) in mat3x2 inMat;
layout (location = 0) out vec4 outFragColor;
if (inFontUV.z >= 0.0)
c *= texture(fontMap, inFontUV).r;
+ c.a *= inOpacity;
outFragColor = c;
}
layout (location = 0) out vec3 outUV;
layout (location = 1) out vec4 outSrc;
layout (location = 2) out flat int outPatType;
-layout (location = 3) out mat3x2 outMat;
-
+layout (location = 3) out flat float outOpacity;
+layout (location = 4) out mat3x2 outMat;
/*out gl_PerVertex
{
vec4 gl_Position;
};*/
layout(push_constant) uniform PushConsts {
- vec4 source;
- vec2 size;
- int srcType;
- int fullScreenQuad;
- mat3x2 mat;
- mat3x2 matInv;
+ vec4 source;
+ vec2 size;
+ int fullScreenQuad_srcType;
+ float opacity;
+ mat3x2 mat;
+ mat3x2 matInv;
} pc;
+#define FULLSCREEN_BIT 0x10000000
+#define SRCTYPE_MASK 0x000000FF
#define SOLID 0
#define SURFACE 1
#define LINEAR 2
void main()
{
- outPatType = pc.srcType;
+ outPatType = pc.fullScreenQuad_srcType & SRCTYPE_MASK;
outMat = pc.matInv;
- outSrc = pc.srcType == SOLID ? inColor : pc.source;
+ outSrc = outPatType == SOLID ? inColor : pc.source;
+ outOpacity = pc.opacity;
- if (pc.fullScreenQuad != 0) {
+ if ((pc.fullScreenQuad_srcType & FULLSCREEN_BIT)==FULLSCREEN_BIT) {
gl_Position = vec4(inPos, 0.0f, 1.0f);
outUV = vec3(0,0,-1);
return;
ctx->bounds = (VkRect2D) {{0,0},{ctx->pSurf->width,ctx->pSurf->height}};
ctx->pushConsts = (push_constants) {
- {.height=1},
+ {.a = 1},
{(float)ctx->pSurf->width,(float)ctx->pSurf->height},
VKVG_PATTERN_TYPE_SOLID,
- 0,
+ 1.0f,
VKVG_IDENTITY_MATRIX,
VKVG_IDENTITY_MATRIX
};
free(ctx);
}
+void vkvg_set_opacity (VkvgContext ctx, float opacity) {
+ if (ctx->status)
+ return;
+
+ if (EQUF(ctx->pushConsts.opacity, opacity))
+ return;
+
+ _emit_draw_cmd_undrawn_vertices (ctx);
+ ctx->pushConsts.opacity = opacity;
+ ctx->pushCstDirty = true;
+}
+float vkvg_get_opacity (VkvgContext ctx) {
+ return ctx->pushConsts.opacity;
+}
vkvg_status_t vkvg_status (VkvgContext ctx) {
return ctx->status;
}
//compute dyn distanceTolerance depending on current transform
float dx = 1, dy = 1;
- vkvg_matrix_transform_distance (&ctx->pushConsts.mat, &dx, &dy);
- float distanceTolerance = 0.02f / fmaxf(dx,dy);
+ vkvg_matrix_transform_point (&ctx->pushConsts.mat, &dx, &dy);
+ float distanceTolerance = fabs(0.02f / fmaxf(dx,dy));
_recursive_bezier (ctx, distanceTolerance, cp.x, cp.y, x1, y1, x2, y2, x3, y3, 0);
/*cp.x = x3;
void vkvg_set_source_surface(VkvgContext ctx, VkvgSurface surf, float x, float y){
if (ctx->status)
return;
- _update_cur_pattern (ctx, vkvg_pattern_create_for_surface(surf));
ctx->pushConsts.source.x = x;
ctx->pushConsts.source.y = y;
+ _update_cur_pattern (ctx, vkvg_pattern_create_for_surface(surf));
ctx->pushCstDirty = true;
}
void vkvg_set_source (VkvgContext ctx, VkvgPattern pat){
ctx->pathes[ctx->pathPtr] = 0;
ctx->segmentPtr = 0;
+ ctx->subpathCount++;
}
//clear path datas in context
void _clear_path (VkvgContext ctx){
ctx->pathes [ctx->pathPtr] = 0;
ctx->pointCount = 0;
ctx->segmentPtr = 0;
+ ctx->subpathCount = 0;
}
void _remove_last_point (VkvgContext ctx){
ctx->pathes[ctx->pathPtr]--;
float _get_arc_step (VkvgContext ctx, float radius) {
float dx = radius, dy = radius;
vkvg_matrix_transform_distance (&ctx->pushConsts.mat, &dx, &dy);
- float r = fmaxf(dx,dy);
+ float r = fabsf(fmaxf(dx,dy));
if (r < 3.0f)
return asinf (1.0f / r) * 0.25f;
return asinf (1.0f / r) * 1.5f * sqrtf(r);
_update_descriptor_set (ctx, ctx->source, ctx->dsSrc);
- vec4 srcRect = {{0},{0},{(float)surf->width},{(float)surf->height}};
- ctx->pushConsts.source = srcRect;
+ if (pat->hasMatrix) {
+
+ }
+
+ ctx->pushConsts.source.width = (float)surf->width;
+ ctx->pushConsts.source.height = (float)surf->height;
break;
}
case VKVG_PATTERN_TYPE_LINEAR:
ctx->status = VKVG_STATUS_PATTERN_INVALID_GRADIENT;
return;
}
+ vkvg_matrix_t mat;
+ if (pat->hasMatrix) {
+ vkvg_pattern_get_matrix (pat, &mat);
+ if (vkvg_matrix_invert (&mat) != VKVG_STATUS_SUCCESS)
+ mat = VKVG_IDENTITY_MATRIX;
+ }
+ if (pat->hasMatrix)
+ vkvg_matrix_transform_point (&mat, &grad.cp[0].x, &grad.cp[0].y);
+ vkvg_matrix_transform_point (&ctx->pushConsts.mat, &grad.cp[0].x, &grad.cp[0].y);
if (pat->type == VKVG_PATTERN_TYPE_LINEAR) {
- vkvg_matrix_transform_point (&ctx->pushConsts.mat, &grad.cp[0].x, &grad.cp[0].y);
+ if (pat->hasMatrix)
+ vkvg_matrix_transform_point (&mat, &grad.cp[0].z, &grad.cp[0].w);
vkvg_matrix_transform_point (&ctx->pushConsts.mat, &grad.cp[0].z, &grad.cp[0].w);
} else {
- //centers
- vkvg_matrix_transform_point (&ctx->pushConsts.mat, &grad.cp[0].x, &grad.cp[0].y);
+ if (pat->hasMatrix)
+ vkvg_matrix_transform_point (&mat, &grad.cp[1].x, &grad.cp[1].y);
vkvg_matrix_transform_point (&ctx->pushConsts.mat, &grad.cp[1].x, &grad.cp[1].y);
+
//radii
+ if (pat->hasMatrix) {
+ vkvg_matrix_transform_distance (&mat, &grad.cp[0].z, &grad.cp[0].w);
+ vkvg_matrix_transform_distance (&mat, &grad.cp[1].z, &grad.cp[0].w);
+ }
vkvg_matrix_transform_distance (&ctx->pushConsts.mat, &grad.cp[0].z, &grad.cp[0].w);
vkvg_matrix_transform_distance (&ctx->pushConsts.mat, &grad.cp[1].z, &grad.cp[0].w);
}
vkvg_buffer_flush(&ctx->uboGrad);
break;
}
- ctx->pushConsts.patternType = newPatternType;
+ ctx->pushConsts.fsq_patternType = (ctx->pushConsts.fsq_patternType & FULLSCREEN_BIT) + newPatternType;
ctx->pushCstDirty = true;
if (lastPat)
vkvg_pattern_destroy (lastPat);
while (ptrPath < ctx->pathPtr){
uint32_t pathPointCount = ctx->pathes[ptrPath] & PATH_ELT_MASK;
- for (uint32_t i = firstPtIdx; i < firstPtIdx + pathPointCount - 1; i++){
+ for (uint32_t i = firstPtIdx; i < firstPtIdx + pathPointCount; i++){
vec2 p = ctx->points[i];
if (transformed)
vkvg_matrix_transform_point (&ctx->pushConsts.mat, &p.x, &p.y);
*y1 = yMin;
*y2 = yMax;
}
-static const uint32_t one = 1;
-static const uint32_t zero = 0;
+
void _draw_full_screen_quad (VkvgContext ctx, bool useScissor) {
#if defined(DEBUG) && defined (VKVG_DBG_UTILS)
vkh_cmd_label_start(ctx->cmd, "_draw_full_screen_quad", DBG_LAB_COLOR_FSQ);
_add_vertexf (ctx, -1, 3);
ctx->curVertOffset = ctx->vertCount;
+ ctx->pushConsts.fsq_patternType |= FULLSCREEN_BIT;
CmdPushConstants(ctx->cmd, ctx->pSurf->dev->pipelineLayout,
- VK_SHADER_STAGE_VERTEX_BIT, 28, 4,&one);
+ VK_SHADER_STAGE_VERTEX_BIT, 24, 4,&ctx->pushConsts.fsq_patternType);
CmdDraw (ctx->cmd,3,1,firstVertIdx,0);
+ ctx->pushConsts.fsq_patternType &= ~FULLSCREEN_BIT;
CmdPushConstants(ctx->cmd, ctx->pSurf->dev->pipelineLayout,
- VK_SHADER_STAGE_VERTEX_BIT, 28, 4,&zero);
+ VK_SHADER_STAGE_VERTEX_BIT, 24, 4,&ctx->pushConsts.fsq_patternType);
if (us)
CmdSetScissor(ctx->cmd, 0, 1, &ctx->bounds);
#define VKVG_VK_INDEX_TYPE VK_INDEX_TYPE_UINT32
#endif
-
+#define FULLSCREEN_BIT 0x10000000
+#define SRCTYPE_MASK 0x000000FF
#define CreateRgba(r, g, b, a) ((a << 24) | (r << 16) | (g << 8) | b)
#ifdef VKVG_PREMULT_ALPHA
typedef struct {
vec4 source;
vec2 size;
- uint32_t patternType;
- uint32_t fullScreenQuad;
+ uint32_t fsq_patternType;
+ float opacity;
vkvg_matrix_t mat;
vkvg_matrix_t matInv;
}push_constants;
uint32_t sizePathes;
uint32_t segmentPtr; //current segment count in current path having curves
+ uint32_t subpathCount; //store count of subpath, not straight forward to retrieve from segmented path array
float lineWidth;
uint32_t dashCount; //value count in dash array, 0 if dash not set.
*a = c.a;
return VKVG_STATUS_SUCCESS;
}
+void vkvg_pattern_set_matrix (VkvgPattern pat, const vkvg_matrix_t* matrix) {
+ pat->matrix = *matrix;
+ pat->hasMatrix = true;
+}
+void vkvg_pattern_get_matrix (VkvgPattern pat, vkvg_matrix_t* matrix) {
+ if (pat->hasMatrix)
+ *matrix = pat->matrix;
+ else
+ *matrix = VKVG_IDENTITY_MATRIX;
+}
void vkvg_pattern_destroy(VkvgPattern pat)
{
vkvg_pattern_type_t type;
vkvg_extend_t extend;
vkvg_filter_t filter;
+ vkvg_matrix_t matrix;
+ bool hasMatrix;
void* data;
uint32_t references;
}vkvg_pattern_t;
vec4 srcRect = {.x=0,.y=0,.width=(float)surf->width,.height=(float)surf->height};
ctx->pushConsts.source = srcRect;
- ctx->pushConsts.patternType = VKVG_PATTERN_TYPE_SURFACE;
+ ctx->pushConsts.fsq_patternType = (ctx->pushConsts.fsq_patternType & FULLSCREEN_BIT) + VKVG_PATTERN_TYPE_SURFACE;
//_update_push_constants (ctx);
_update_descriptor_set (ctx, tmpImg, ctx->dsSrc);