提供变宽样式的接口,未实现
parent
a3d39b32e5
commit
b2e49dae17
|
@ -72,6 +72,7 @@
|
||||||
<PreprocessorDefinitions>FRAMELESSHELPER_WIDGETS_STATIC;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
<PreprocessorDefinitions>FRAMELESSHELPER_WIDGETS_STATIC;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
<WarningLevel>Level1</WarningLevel>
|
<WarningLevel>Level1</WarningLevel>
|
||||||
<FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
|
<FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
|
||||||
|
<TreatSpecificWarningsAsErrors>4715;</TreatSpecificWarningsAsErrors>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<Link>
|
<Link>
|
||||||
<AdditionalDependencies>opengl32.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
<AdditionalDependencies>opengl32.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||||
|
|
|
@ -557,7 +557,7 @@ int solve_quartic(vec4 coeffs, inout vec4 s)
|
||||||
|
|
||||||
return num;
|
return num;
|
||||||
}
|
}
|
||||||
float cubic_bezier_dis(vec2 uv, vec2 p0, vec2 p1, vec2 p2, vec2 p3, bool roundEnd)
|
float cubic_bezier_dis(vec2 uv, vec2 p0, vec2 p1, vec2 p2, vec2 p3, bool roundEnd, out float t)
|
||||||
{
|
{
|
||||||
|
|
||||||
// switch points when near to end point to minimize numerical error
|
// switch points when near to end point to minimize numerical error
|
||||||
|
@ -794,7 +794,13 @@ float cubic_bezier_dis(vec2 uv, vec2 p0, vec2 p1, vec2 p2, vec2 p3, bool roundEn
|
||||||
{
|
{
|
||||||
roots[i] = clamp(roots[i], 0., 1.);
|
roots[i] = clamp(roots[i], 0., 1.);
|
||||||
vec2 to_curve = uv - parametric_cub_bezier(roots[i], p0, p1, p2, p3);
|
vec2 to_curve = uv - parametric_cub_bezier(roots[i], p0, p1, p2, p3);
|
||||||
d0 = min(d0, dot(to_curve, to_curve));
|
float d = dot(to_curve, to_curve);
|
||||||
|
if (d < d0)
|
||||||
|
{
|
||||||
|
d0 = d;
|
||||||
|
t = roots[i];
|
||||||
|
}
|
||||||
|
// d0 = min(d0, dot(to_curve, to_curve));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -893,11 +899,11 @@ bool angleLargeThanPi(vec2 a, vec2 b)
|
||||||
|
|
||||||
/************************************************************************************/
|
/************************************************************************************/
|
||||||
|
|
||||||
void drawLine(in float d, uint styleIndex, out vec4 elementColor, out vec2 metallicRoughness)
|
void drawLine(in float d, uint styleHeadIndex, out vec4 elementColor, out vec2 metallicRoughness)
|
||||||
{
|
{
|
||||||
elementColor = vec4(1);
|
elementColor = vec4(1);
|
||||||
metallicRoughness = vec2(0.8);
|
metallicRoughness = vec2(0.8);
|
||||||
uint headUint = floatBitsToUint(style[styleIndex + 1]);
|
uint headUint = floatBitsToUint(style[styleHeadIndex]);
|
||||||
vec4 head = unpackUnorm4x8(headUint);
|
vec4 head = unpackUnorm4x8(headUint);
|
||||||
switch (int(head.a * 100) % 10)
|
switch (int(head.a * 100) % 10)
|
||||||
// switch (2)
|
// switch (2)
|
||||||
|
@ -905,7 +911,7 @@ void drawLine(in float d, uint styleIndex, out vec4 elementColor, out vec2 metal
|
||||||
/// Plain
|
/// Plain
|
||||||
case 0: {
|
case 0: {
|
||||||
metallicRoughness = head.rg;
|
metallicRoughness = head.rg;
|
||||||
elementColor = vec4(unpackUnorm4x8(floatBitsToUint(style[styleIndex + 2])).rgb, 1);
|
elementColor = vec4(unpackUnorm4x8(floatBitsToUint(style[styleHeadIndex + 1])).rgb, 1);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
/// RadialGradient
|
/// RadialGradient
|
||||||
|
@ -913,16 +919,16 @@ void drawLine(in float d, uint styleIndex, out vec4 elementColor, out vec2 metal
|
||||||
uint size = headUint % (1 << 15);
|
uint size = headUint % (1 << 15);
|
||||||
bool gradual = (headUint & (1 << 15)) != 0;
|
bool gradual = (headUint & (1 << 15)) != 0;
|
||||||
|
|
||||||
uint lastData = floatBitsToUint(style[styleIndex + 2 + 0 * 2]);
|
uint lastData = floatBitsToUint(style[styleHeadIndex + 1 + 0 * 2]);
|
||||||
float lastLevel = 0;
|
float lastLevel = 0;
|
||||||
vec2 lastMetallicRoughness = unpackUnorm4x8(lastData).rg;
|
vec2 lastMetallicRoughness = unpackUnorm4x8(lastData).rg;
|
||||||
vec4 lastColor = vec4(unpackUnorm4x8(floatBitsToUint(style[styleIndex + 3 + 0 * 2])).rgb, 1);
|
vec4 lastColor = vec4(unpackUnorm4x8(floatBitsToUint(style[styleHeadIndex + 2 + 0 * 2])).rgb, 1);
|
||||||
|
|
||||||
for (uint i = 0; i < size; i++)
|
for (uint i = 0; i < size; i++)
|
||||||
{
|
{
|
||||||
uint data = floatBitsToUint(style[styleIndex + 2 + i * 2]);
|
uint data = floatBitsToUint(style[styleHeadIndex + 1 + i * 2]);
|
||||||
float level = unpackUnorm2x16(data).y;
|
float level = unpackUnorm2x16(data).y;
|
||||||
vec4 currentColor = vec4(unpackUnorm4x8(floatBitsToUint(style[styleIndex + 3 + i * 2])).rgb, 1);
|
vec4 currentColor = vec4(unpackUnorm4x8(floatBitsToUint(style[styleHeadIndex + 2 + i * 2])).rgb, 1);
|
||||||
vec2 currentMetallicRoughness = unpackUnorm4x8(data).rg;
|
vec2 currentMetallicRoughness = unpackUnorm4x8(data).rg;
|
||||||
if (d <= level)
|
if (d <= level)
|
||||||
{
|
{
|
||||||
|
@ -969,21 +975,24 @@ void drawLine(in float d, uint styleIndex, out vec4 elementColor, out vec2 metal
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param styleIndex ÊäÈëstyleHeadµÄIndex£¬·µ»ØÏÂÒ»¸östyleµÄindex
|
||||||
|
*/
|
||||||
void nextStyleIndex(inout uint styleIndex)
|
void nextStyleIndex(inout uint styleIndex)
|
||||||
{
|
{
|
||||||
uint headUint = floatBitsToUint(style[styleIndex + 1]);
|
uint headUint = floatBitsToUint(style[styleIndex]);
|
||||||
vec4 head = unpackUnorm4x8(headUint);
|
vec4 head = unpackUnorm4x8(headUint);
|
||||||
switch (int(head.a * 100) % 10)
|
switch (int(head.a * 100) % 10)
|
||||||
{
|
{
|
||||||
/// Plain
|
/// Plain
|
||||||
case 0: {
|
case 0: {
|
||||||
styleIndex += 3;
|
styleIndex += 2;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
/// RadialGradient
|
/// RadialGradient
|
||||||
case 1: {
|
case 1: {
|
||||||
uint size = headUint % (1 << 15);
|
uint size = headUint % (1 << 15);
|
||||||
styleIndex += 2 + size * 2;
|
styleIndex += 1 + size * 2;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 2: {
|
case 2: {
|
||||||
|
@ -998,9 +1007,9 @@ bool shouldFillBeginCap(vec2 localUV, bool onVeryBegin, int endType, vec2 p0, ve
|
||||||
vec2 normal;
|
vec2 normal;
|
||||||
if (onVeryBegin)
|
if (onVeryBegin)
|
||||||
{
|
{
|
||||||
if (endType%2 == 0)
|
if (endType % 2 == 0)
|
||||||
return true;
|
return true;
|
||||||
else if (endType%2 == 1)
|
else if (endType % 2 == 1)
|
||||||
normal = normalize(mat2(0, 1, -1, 0) * (-tangentBegin));
|
normal = normalize(mat2(0, 1, -1, 0) * (-tangentBegin));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -1017,9 +1026,9 @@ bool shouldFillEndCap(vec2 localUV, bool onVeryEnd, int endType, vec2 p3, vec2 t
|
||||||
vec2 normal;
|
vec2 normal;
|
||||||
if (onVeryEnd)
|
if (onVeryEnd)
|
||||||
{
|
{
|
||||||
if ((endType/2)%2 == 0)
|
if ((endType / 2) % 2 == 0)
|
||||||
return true;
|
return true;
|
||||||
else if ((endType/2)%2 == 1)
|
else if ((endType / 2) % 2 == 1)
|
||||||
normal = normalize(mat2(0, 1, -1, 0) * tangentEnd);
|
normal = normalize(mat2(0, 1, -1, 0) * tangentEnd);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -1034,11 +1043,7 @@ bool shouldFillEndCap(vec2 localUV, bool onVeryEnd, int endType, vec2 p3, vec2 t
|
||||||
void main()
|
void main()
|
||||||
{
|
{
|
||||||
uvec2 pixelLocation = gl_GlobalInvocationID.xy;
|
uvec2 pixelLocation = gl_GlobalInvocationID.xy;
|
||||||
// imageStore(gBaseColor, ivec2(pixelLocation), vec4(vec2(pixelLocation)/vec2(imageSize(gBaseColor)), 1,1));
|
|
||||||
|
|
||||||
vec4 color = vec4(0);
|
vec4 color = vec4(0);
|
||||||
// if(isinf(path[0].x)) imageStore(gBaseColor, ivec2(pixelLocation),
|
|
||||||
// vec4(vec2(pixelLocation)/vec2(imageSize(gBaseColor)), 1,1)); return;
|
|
||||||
for (uint styleIndex = 0; styleIndex < styleSize;)
|
for (uint styleIndex = 0; styleIndex < styleSize;)
|
||||||
{
|
{
|
||||||
styleIndex += 6;
|
styleIndex += 6;
|
||||||
|
@ -1063,7 +1068,7 @@ void main()
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
mat4x2 p = mat4x2(p3Last, pTemp, path[++pathIndex], path[++pathIndex]);
|
mat4x2 p = mat4x2(p3Last, pTemp, path[++pathIndex], path[++pathIndex]);
|
||||||
|
++pathIndex;
|
||||||
num_its += cubic_bezier_int_test(localUV, p[0], p[1], p[2], p[3]);
|
num_its += cubic_bezier_int_test(localUV, p[0], p[1], p[2], p[3]);
|
||||||
p3Last = p[3];
|
p3Last = p[3];
|
||||||
p2Last = p[2];
|
p2Last = p[2];
|
||||||
|
@ -1075,22 +1080,23 @@ void main()
|
||||||
vec4 head = unpackUnorm4x8(floatBitsToUint(style[styleIndex]));
|
vec4 head = unpackUnorm4x8(floatBitsToUint(style[styleIndex]));
|
||||||
if (head.z == 0)
|
if (head.z == 0)
|
||||||
{
|
{
|
||||||
elementColor = vec4(unpackUnorm4x8(floatBitsToUint(style[styleIndex+1])).rgb, 1);
|
elementColor = vec4(unpackUnorm4x8(floatBitsToUint(style[styleIndex + 1])).rgb, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
styleIndex += 2;
|
styleIndex += 2;
|
||||||
}
|
}
|
||||||
else // Stroke
|
else // Stroke
|
||||||
{
|
{
|
||||||
|
uint widthMapSize = floatBitsToUint(style[styleIndex + 1]);
|
||||||
float minDistance = 1e38;
|
float minDistance = 1e38;
|
||||||
vec4 styleHead = unpackUnorm4x8(floatBitsToUint(style[styleIndex + 1]));
|
styleIndex += widthMapSize + 2;
|
||||||
|
vec4 styleHead = unpackUnorm4x8(floatBitsToUint(style[styleIndex]));
|
||||||
float lineType = floor(styleHead.b * 10);
|
float lineType = floor(styleHead.b * 10);
|
||||||
int endType = int(round(styleHead.b * 100)) % 10;
|
int endType = int(round(styleHead.b * 100)) % 10;
|
||||||
int debugBegin = 0;
|
int debugBegin = 0;
|
||||||
bool onVeryBegin = false;
|
bool onVeryBegin = false;
|
||||||
bool onVeryEnd = false;
|
bool onVeryEnd = false;
|
||||||
vec2 tangentEndLast;
|
vec2 tangentEndLast = vec2(0);
|
||||||
vec2 tangentFirstBegin;
|
vec2 tangentFirstBegin;
|
||||||
uint lastHitIndex = 0;
|
uint lastHitIndex = 0;
|
||||||
bool lastHitElement = false;
|
bool lastHitElement = false;
|
||||||
|
@ -1103,12 +1109,12 @@ void main()
|
||||||
pBegin = path[++pathIndex];
|
pBegin = path[++pathIndex];
|
||||||
p3Last = pBegin;
|
p3Last = pBegin;
|
||||||
p2Last = pBegin;
|
p2Last = pBegin;
|
||||||
if(endType == 4 /*StrokeEndType::kClosed*/)
|
if (endType == 4 /*StrokeEndType::kClosed*/)
|
||||||
{
|
{
|
||||||
//onVeryBegin = false;
|
// onVeryBegin = false;
|
||||||
vec2 lastP1 = path[pathSize-3];
|
vec2 lastP1 = path[pathSize - 4];
|
||||||
vec2 lastP2 = path[pathSize-2];
|
vec2 lastP2 = path[pathSize - 3];
|
||||||
vec2 lastP3 = path[pathSize-1];
|
vec2 lastP3 = path[pathSize - 2];
|
||||||
if (lastP3 != lastP2)
|
if (lastP3 != lastP2)
|
||||||
tangentEndLast = normalize(lastP3 - lastP2);
|
tangentEndLast = normalize(lastP3 - lastP2);
|
||||||
else
|
else
|
||||||
|
@ -1119,7 +1125,7 @@ void main()
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
mat4x2 p = mat4x2(p3Last, pTemp, path[++pathIndex], path[++pathIndex]);
|
mat4x2 p = mat4x2(p3Last, pTemp, path[++pathIndex], path[++pathIndex]);
|
||||||
|
vec2 lengthRate = path[++pathIndex];
|
||||||
vec2 tangentBeginNext;
|
vec2 tangentBeginNext;
|
||||||
if (pathIndex + 1 < pathSize)
|
if (pathIndex + 1 < pathSize)
|
||||||
{
|
{
|
||||||
|
@ -1140,31 +1146,35 @@ void main()
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if(endType == 4 /*StrokeEndType::kClosed*/)
|
if (endType == 4 /*StrokeEndType::kClosed*/)
|
||||||
{
|
{
|
||||||
//onVeryEnd = false;
|
// onVeryEnd = false;
|
||||||
tangentBeginNext = tangentFirstBegin;
|
tangentBeginNext = tangentFirstBegin;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
onVeryEnd = true;
|
onVeryEnd = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
vec2 tangentEnd;
|
||||||
|
if (p[3] != p[2])
|
||||||
|
tangentEnd = normalize(p[3] - p[2]);
|
||||||
|
else
|
||||||
|
tangentEnd = normalize(p[3] - p[1]);
|
||||||
|
|
||||||
float d = cubic_bezier_dis(localUV, p[0], p[1], p[2], p[3], true);
|
float t;
|
||||||
if (d <= strokeWidth)
|
float d = cubic_bezier_dis(localUV, p[0], p[1], p[2], p[3], true, t);
|
||||||
|
float localWidth = strokeWidth; // * mix(lengthRate.x, lengthRate.y, t);
|
||||||
|
if (d <= localWidth)
|
||||||
{
|
{
|
||||||
bool onBegin = distance(localUV, p[0]) <= strokeWidth;
|
bool onBegin = t<1e-5;
|
||||||
bool onEnd = distance(localUV, p[3]) <= strokeWidth;
|
bool onEnd = t>1-1e-5;
|
||||||
|
//bool onBegin = true;
|
||||||
|
//bool onEnd = true;
|
||||||
vec2 tangentBegin;
|
vec2 tangentBegin;
|
||||||
vec2 tangentEnd;
|
|
||||||
if (p[0] != p[1])
|
if (p[0] != p[1])
|
||||||
tangentBegin = normalize(p[0] - p[1]);
|
tangentBegin = normalize(p[0] - p[1]);
|
||||||
else
|
else
|
||||||
tangentBegin = normalize(p[0] - p[2]);
|
tangentBegin = normalize(p[0] - p[2]);
|
||||||
if (p[3] != p[2])
|
|
||||||
tangentEnd = normalize(p[3] - p[2]);
|
|
||||||
else
|
|
||||||
tangentEnd = normalize(p[3] - p[1]);
|
|
||||||
|
|
||||||
bool hit = d < minDistance;
|
bool hit = d < minDistance;
|
||||||
if (onBegin)
|
if (onBegin)
|
||||||
|
@ -1192,19 +1202,19 @@ void main()
|
||||||
hitElement = true;
|
hitElement = true;
|
||||||
// elementColor = vec4(1, 1, 0, 1);
|
// elementColor = vec4(1, 1, 0, 1);
|
||||||
vec2 metallicRoughness;
|
vec2 metallicRoughness;
|
||||||
drawLine(minDistance / strokeWidth, styleIndex, elementColor, metallicRoughness);
|
drawLine(minDistance / localWidth, styleIndex, elementColor, metallicRoughness);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
tangentEndLast = tangentEnd;
|
if (pathIndex == 5)
|
||||||
if(pathIndex == 4)
|
|
||||||
tangentFirstBegin = tangentBegin;
|
tangentFirstBegin = tangentBegin;
|
||||||
}
|
}
|
||||||
|
tangentEndLast = tangentEnd;
|
||||||
|
|
||||||
p3Last = p[3];
|
p3Last = p[3];
|
||||||
p2Last = p[2];
|
p2Last = p[2];
|
||||||
onVeryBegin = false;
|
onVeryBegin = false;
|
||||||
}
|
}
|
||||||
nextStyleIndex(styleIndex);
|
nextStyleIndex(styleIndex);
|
||||||
|
|
||||||
}
|
}
|
||||||
if (hitElement)
|
if (hitElement)
|
||||||
color = elementColor;
|
color = elementColor;
|
||||||
|
|
|
@ -959,11 +959,11 @@ bool angleLargeThanPi(vec2 a, vec2 b)
|
||||||
return a.x * b.y - b.x * a.y < 0;
|
return a.x * b.y - b.x * a.y < 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void drawLine(in float d, in uint styleIndex, out vec4 elementColor, out vec2 metallicRoughness)
|
void drawLine(in float d, uint styleHeadIndex, out vec4 elementColor, out vec2 metallicRoughness)
|
||||||
{
|
{
|
||||||
elementColor = vec4(1);
|
elementColor = vec4(1);
|
||||||
metallicRoughness = vec2(0.8);
|
metallicRoughness = vec2(0.8);
|
||||||
uint headUint = floatBitsToUint(elementData[styleIndex + 1]);
|
uint headUint = floatBitsToUint(elementData[styleHeadIndex]);
|
||||||
vec4 head = unpackUnorm4x8(headUint);
|
vec4 head = unpackUnorm4x8(headUint);
|
||||||
switch (int(head.a * 100) % 10)
|
switch (int(head.a * 100) % 10)
|
||||||
// switch (2)
|
// switch (2)
|
||||||
|
@ -971,7 +971,7 @@ void drawLine(in float d, in uint styleIndex, out vec4 elementColor, out vec2 me
|
||||||
/// Plain
|
/// Plain
|
||||||
case 0: {
|
case 0: {
|
||||||
metallicRoughness = head.rg;
|
metallicRoughness = head.rg;
|
||||||
elementColor = vec4(unpackUnorm4x8(floatBitsToUint(elementData[styleIndex + 2])).rgb, 1);
|
elementColor = vec4(unpackUnorm4x8(floatBitsToUint(elementData[styleHeadIndex + 1])).rgb, 1);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
/// RadialGradient
|
/// RadialGradient
|
||||||
|
@ -979,16 +979,16 @@ void drawLine(in float d, in uint styleIndex, out vec4 elementColor, out vec2 me
|
||||||
uint size = headUint % (1 << 15);
|
uint size = headUint % (1 << 15);
|
||||||
bool gradual = (headUint & (1 << 15)) != 0;
|
bool gradual = (headUint & (1 << 15)) != 0;
|
||||||
|
|
||||||
uint lastData = floatBitsToUint(elementData[styleIndex + 2 + 0 * 2]);
|
uint lastData = floatBitsToUint(elementData[styleHeadIndex + 1 + 0 * 2]);
|
||||||
float lastLevel = 0;
|
float lastLevel = 0;
|
||||||
vec2 lastMetallicRoughness = unpackUnorm4x8(lastData).rg;
|
vec2 lastMetallicRoughness = unpackUnorm4x8(lastData).rg;
|
||||||
vec4 lastColor = vec4(unpackUnorm4x8(floatBitsToUint(elementData[styleIndex + 3 + 0 * 2])).rgb, 1);
|
vec4 lastColor = vec4(unpackUnorm4x8(floatBitsToUint(elementData[styleHeadIndex + 2 + 0 * 2])).rgb, 1);
|
||||||
|
|
||||||
for (uint i = 0; i < size; i++)
|
for (uint i = 0; i < size; i++)
|
||||||
{
|
{
|
||||||
uint data = floatBitsToUint(elementData[styleIndex + 2 + i * 2]);
|
uint data = floatBitsToUint(elementData[styleHeadIndex + 1 + i * 2]);
|
||||||
float level = unpackUnorm2x16(data).y;
|
float level = unpackUnorm2x16(data).y;
|
||||||
vec4 currentColor = vec4(unpackUnorm4x8(floatBitsToUint(elementData[styleIndex + 3 + i * 2])).rgb, 1);
|
vec4 currentColor = vec4(unpackUnorm4x8(floatBitsToUint(elementData[styleHeadIndex + 2 + i * 2])).rgb, 1);
|
||||||
vec2 currentMetallicRoughness = unpackUnorm4x8(data).rg;
|
vec2 currentMetallicRoughness = unpackUnorm4x8(data).rg;
|
||||||
if (d <= level)
|
if (d <= level)
|
||||||
{
|
{
|
||||||
|
@ -1152,7 +1152,9 @@ bool strokeElement(vec2 localUV, uint contourIndex, uint linesOffset, uint point
|
||||||
|
|
||||||
float minDistance = 1e38;
|
float minDistance = 1e38;
|
||||||
uint lineCount = elementIndexs[contourIndex];
|
uint lineCount = elementIndexs[contourIndex];
|
||||||
vec4 styleHead = unpackUnorm4x8(floatBitsToUint(elementData[styleIndex + 1]));
|
uint widthMapSize = floatBitsToUint(elementData[styleIndex + 1]);
|
||||||
|
styleIndex += widthMapSize + 2;
|
||||||
|
vec4 styleHead = unpackUnorm4x8(floatBitsToUint(elementData[styleIndex]));
|
||||||
float lineType = floor(styleHead.b * 10);
|
float lineType = floor(styleHead.b * 10);
|
||||||
int endType = int(round(styleHead.b * 100)) % 10;
|
int endType = int(round(styleHead.b * 100)) % 10;
|
||||||
vec2 p3Last = vec2(1e38);
|
vec2 p3Last = vec2(1e38);
|
||||||
|
|
|
@ -413,6 +413,8 @@ int CubicBezierSignedDistance::solve_quadric(dvec2 coeffs, dvec2& roots) {
|
||||||
|
|
||||||
return 2;
|
return 2;
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CubicBezierSignedDistance::sort_roots3(dvec3& roots) {
|
void CubicBezierSignedDistance::sort_roots3(dvec3& roots) {
|
||||||
|
|
|
@ -77,8 +77,8 @@ bool Renderer::StrokeRadialGradient::operator==(const MaterialStroke& m) const
|
||||||
&& materialMap == static_cast<const StrokeRadialGradient&>(m).materialMap;
|
&& materialMap == static_cast<const StrokeRadialGradient&>(m).materialMap;
|
||||||
}
|
}
|
||||||
|
|
||||||
Renderer::MaterialStyleStroke::MaterialStyleStroke(float halfWidth, StrokeType strokeType, StrokeEndType endType, std::shared_ptr<MaterialStroke> materialStroke)
|
Renderer::MaterialStyleStroke::MaterialStyleStroke(float halfWidth, StrokeType strokeType, StrokeEndType endType, std::shared_ptr<MaterialStroke> materialStroke, std::map<float, float> widthMap)
|
||||||
: halfWidth(halfWidth), strokeType(strokeType), endType(endType), materialStroke(materialStroke)
|
: halfWidth(halfWidth), strokeType(strokeType), endType(endType), materialStroke(materialStroke), widthMap(widthMap)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -89,7 +89,9 @@ MaterialStyleType Renderer::MaterialStyleStroke::type() const
|
||||||
|
|
||||||
std::vector<GLfloat> Renderer::MaterialStyleStroke::encoded() const
|
std::vector<GLfloat> Renderer::MaterialStyleStroke::encoded() const
|
||||||
{
|
{
|
||||||
std::vector<GLfloat> v = { halfWidth };
|
std::vector<GLfloat> v = { halfWidth, glm::uintBitsToFloat(widthMap.size()) };
|
||||||
|
for(auto& [lengthRate, widthRate] : widthMap)
|
||||||
|
v.emplace_back(glm::uintBitsToFloat(glm::packUnorm2x16(glm::vec2(lengthRate, widthRate))));
|
||||||
auto encoded = materialStroke->encoded();
|
auto encoded = materialStroke->encoded();
|
||||||
glm::vec4 head = glm::unpackUnorm4x8(glm::floatBitsToUint(encoded[0]));
|
glm::vec4 head = glm::unpackUnorm4x8(glm::floatBitsToUint(encoded[0]));
|
||||||
head.b = (float)strokeType / 10. + (float)endType / 100.;
|
head.b = (float)strokeType / 10. + (float)endType / 100.;
|
||||||
|
|
|
@ -48,7 +48,7 @@ namespace Renderer
|
||||||
class MaterialStyleStroke : public MaterialStyle
|
class MaterialStyleStroke : public MaterialStyle
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
MaterialStyleStroke(float width, StrokeType strokeType, StrokeEndType endType, std::shared_ptr<MaterialStroke> materialStroke);
|
MaterialStyleStroke(float width, StrokeType strokeType, StrokeEndType endType, std::shared_ptr<MaterialStroke> materialStroke, std::map<float, float> widthMap = {});
|
||||||
virtual MaterialStyleType type() const override;
|
virtual MaterialStyleType type() const override;
|
||||||
virtual std::vector<GLfloat> encoded() const override;
|
virtual std::vector<GLfloat> encoded() const override;
|
||||||
virtual std::unique_ptr<MaterialStyle> clone() const override;
|
virtual std::unique_ptr<MaterialStyle> clone() const override;
|
||||||
|
@ -59,6 +59,7 @@ namespace Renderer
|
||||||
StrokeType strokeType;
|
StrokeType strokeType;
|
||||||
StrokeEndType endType;
|
StrokeEndType endType;
|
||||||
std::shared_ptr<MaterialStroke> materialStroke;
|
std::shared_ptr<MaterialStroke> materialStroke;
|
||||||
|
std::map<float, float> widthMap;
|
||||||
static const std::array<std::pair<QString, StrokeEndType>, 4> strokeEndTypeNames;
|
static const std::array<std::pair<QString, StrokeEndType>, 4> strokeEndTypeNames;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,6 +15,8 @@ using namespace Renderer;
|
||||||
|
|
||||||
std::vector<glm::vec2> generatePathBuffer(const QPainterPath& path)
|
std::vector<glm::vec2> generatePathBuffer(const QPainterPath& path)
|
||||||
{
|
{
|
||||||
|
float lastLength = 0;
|
||||||
|
glm::vec2 lastPoint;
|
||||||
std::vector<glm::vec2> pathBuffer;
|
std::vector<glm::vec2> pathBuffer;
|
||||||
for (int i = 0; i < path.elementCount(); i++)
|
for (int i = 0; i < path.elementCount(); i++)
|
||||||
{
|
{
|
||||||
|
@ -24,18 +26,24 @@ std::vector<glm::vec2> generatePathBuffer(const QPainterPath& path)
|
||||||
case QPainterPath::MoveToElement:
|
case QPainterPath::MoveToElement:
|
||||||
//qDebug() << "MoveToElement";
|
//qDebug() << "MoveToElement";
|
||||||
//qDebug() << element;
|
//qDebug() << element;
|
||||||
pathBuffer.push_back(glm::vec2(std::numeric_limits<float>::infinity()));
|
pathBuffer.emplace_back(std::numeric_limits<float>::infinity());
|
||||||
pathBuffer.push_back(glm::vec2(element.x, element.y));
|
pathBuffer.emplace_back(element.x, element.y);
|
||||||
|
lastLength = 0;
|
||||||
|
lastPoint = glm::vec2(element.x, element.y);
|
||||||
break;
|
break;
|
||||||
case QPainterPath::LineToElement:
|
case QPainterPath::LineToElement:
|
||||||
{
|
{
|
||||||
//qDebug() << "LineToElement";
|
//qDebug() << "LineToElement";
|
||||||
//qDebug() << element;
|
//qDebug() << element;
|
||||||
glm::vec2 end = glm::vec2(element.x, element.y);
|
glm::vec2 end = glm::vec2(element.x, element.y);
|
||||||
glm::vec2 mid = (pathBuffer.back() + end) / 2.f;
|
glm::vec2 mid = (lastPoint + end) / 2.f;
|
||||||
pathBuffer.push_back(mid);
|
pathBuffer.push_back(mid);
|
||||||
pathBuffer.push_back(mid);
|
pathBuffer.push_back(mid);
|
||||||
pathBuffer.push_back(end);
|
pathBuffer.push_back(end);
|
||||||
|
float length = (i + 1.) / path.elementCount();
|
||||||
|
pathBuffer.emplace_back(lastLength, length);
|
||||||
|
lastLength = length;
|
||||||
|
lastPoint = end;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case QPainterPath::CurveToElement:
|
case QPainterPath::CurveToElement:
|
||||||
|
@ -49,16 +57,20 @@ std::vector<glm::vec2> generatePathBuffer(const QPainterPath& path)
|
||||||
element = path.elementAt(++i);
|
element = path.elementAt(++i);
|
||||||
//qDebug() << element;
|
//qDebug() << element;
|
||||||
glm::vec2 p3 = glm::vec2(element.x, element.y);
|
glm::vec2 p3 = glm::vec2(element.x, element.y);
|
||||||
if (p3 != pathBuffer.back())
|
if (p3 != lastPoint)
|
||||||
{
|
{
|
||||||
pathBuffer.push_back(p1);
|
pathBuffer.push_back(p1);
|
||||||
pathBuffer.push_back(p2);
|
pathBuffer.push_back(p2);
|
||||||
pathBuffer.push_back(p3);
|
pathBuffer.push_back(p3);
|
||||||
|
float length = (i + 1.) / path.elementCount();
|
||||||
|
pathBuffer.emplace_back(lastLength, length);
|
||||||
|
lastLength = length;
|
||||||
|
lastPoint = p3;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case QPainterPath::CurveToDataElement:
|
case QPainterPath::CurveToDataElement:
|
||||||
pathBuffer.push_back(glm::vec2(element.x, element.y));
|
qCritical() << "Read QPainterPath Error";
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -206,9 +206,9 @@ namespace UnitTest
|
||||||
}
|
}
|
||||||
TEST_METHOD(TestBothSidesClosed)
|
TEST_METHOD(TestBothSidesClosed)
|
||||||
{
|
{
|
||||||
QPainterPath closedPath;
|
QPainterPath testPath;
|
||||||
SvgFileLoader().loadSvgFile("../../svg/4_L0.svg", closedPath);
|
SvgFileLoader().loadSvgFile("../../svg/4_L0.svg", testPath);
|
||||||
closedPath = QTransform::fromScale(5, 5).map(closedPath);
|
testPath = QTransform::fromScale(5, 5).map(testPath);
|
||||||
QApplication a(argc, argv);
|
QApplication a(argc, argv);
|
||||||
class StyleStrokeRadialGradient : public Renderer::ElementStyle
|
class StyleStrokeRadialGradient : public Renderer::ElementStyle
|
||||||
{
|
{
|
||||||
|
@ -220,11 +220,60 @@ namespace UnitTest
|
||||||
{1.00, Material{QColor(58,64,151)}}
|
{1.00, Material{QColor(58,64,151)}}
|
||||||
};
|
};
|
||||||
return { BaseStyle(std::make_shared<TransformStyle>(),
|
return { BaseStyle(std::make_shared<TransformStyle>(),
|
||||||
std::make_shared<MaterialStyleStroke>(20, StrokeType::kLeftSide, StrokeEndType::kClosed,
|
std::make_shared<MaterialStyleStroke>(10, StrokeType::kBothSides, StrokeEndType::kClosed,
|
||||||
std::make_shared<StrokeRadialGradient>(materialMap, false))) };
|
std::make_shared<StrokeRadialGradient>(materialMap, false))) };
|
||||||
}
|
}
|
||||||
} style;
|
} style;
|
||||||
TestGLWidget w(style, closedPath);
|
TestGLWidget w(style, testPath);
|
||||||
|
w.show();
|
||||||
|
a.exec();
|
||||||
|
}
|
||||||
|
TEST_METHOD(TestAcuteAngle)
|
||||||
|
{
|
||||||
|
QPainterPath testPath;
|
||||||
|
testPath.moveTo(50, 50);
|
||||||
|
testPath.lineTo(300, 300);
|
||||||
|
testPath.lineTo(300, 50);
|
||||||
|
QApplication a(argc, argv);
|
||||||
|
class StyleStrokeRadialGradient : public Renderer::ElementStyle
|
||||||
|
{
|
||||||
|
virtual std::vector<Renderer::BaseStyle> toBaseStyles() const override
|
||||||
|
{
|
||||||
|
std::map<float, Material> materialMap = {
|
||||||
|
{0.20, Material{QColor(255,255,255)}},
|
||||||
|
{0.60, Material{QColor(165,176,207)}},
|
||||||
|
{1.00, Material{QColor(58,64,151)}}
|
||||||
|
};
|
||||||
|
return { BaseStyle(std::make_shared<TransformStyle>(),
|
||||||
|
std::make_shared<MaterialStyleStroke>(20, StrokeType::kRightSide, StrokeEndType::kRound,
|
||||||
|
std::make_shared<StrokeRadialGradient>(materialMap, false))) };
|
||||||
|
}
|
||||||
|
} style;
|
||||||
|
TestGLWidget w(style, testPath);
|
||||||
|
w.show();
|
||||||
|
a.exec();
|
||||||
|
}
|
||||||
|
TEST_METHOD(TestBothSidesGradientWidth)
|
||||||
|
{
|
||||||
|
QPainterPath testPath;
|
||||||
|
testPath.moveTo(50, 50);
|
||||||
|
testPath.cubicTo(50, 200, 200, 300, 300, 300);
|
||||||
|
QApplication a(argc, argv);
|
||||||
|
class StyleStrokeRadialGradient : public Renderer::ElementStyle
|
||||||
|
{
|
||||||
|
virtual std::vector<Renderer::BaseStyle> toBaseStyles() const override
|
||||||
|
{
|
||||||
|
std::map<float, Material> materialMap = {
|
||||||
|
{0.20, Material{QColor(255,255,255)}},
|
||||||
|
{0.60, Material{QColor(165,176,207)}},
|
||||||
|
{1.00, Material{QColor(58,64,151)}}
|
||||||
|
};
|
||||||
|
return { BaseStyle(std::make_shared<TransformStyle>(),
|
||||||
|
std::make_shared<MaterialStyleStroke>(20, StrokeType::kLeftSide, StrokeEndType::kRound,
|
||||||
|
std::make_shared<StrokeRadialGradient>(materialMap, false))) };
|
||||||
|
}
|
||||||
|
} style;
|
||||||
|
TestGLWidget w(style, testPath);
|
||||||
w.show();
|
w.show();
|
||||||
a.exec();
|
a.exec();
|
||||||
}
|
}
|
||||||
|
|
|
@ -343,24 +343,6 @@
|
||||||
</QtMoc>
|
</QtMoc>
|
||||||
<ClInclude Include="qtmaterialtoggle_p.h" />
|
<ClInclude Include="qtmaterialtoggle_p.h" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
|
||||||
<CustomBuild Include="debug\moc_predefs.h.cbt">
|
|
||||||
<FileType>Document</FileType>
|
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
|
|
||||||
<AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(QTDIR)\mkspecs\features\data\dummy.cpp;%(AdditionalInputs)</AdditionalInputs>
|
|
||||||
<Command Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">cl -Bx"$(QTDIR)\bin\qmake.exe" -nologo -Zc:wchar_t -FS -Zc:rvalueCast -Zc:inline -Zc:strictStrings -Zc:throwingNew -Zc:referenceBinding -Zc:__cplusplus -Zi -MDd -W3 -w34100 -w34189 -w44996 -w44456 -w44457 -w44458 -wd4577 -wd4467 -E $(QTDIR)\mkspecs\features\data\dummy.cpp 2>NUL >debug\moc_predefs.h</Command>
|
|
||||||
<Message Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Generate moc_predefs.h</Message>
|
|
||||||
<Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">debug\moc_predefs.h;%(Outputs)</Outputs>
|
|
||||||
</CustomBuild>
|
|
||||||
<CustomBuild Include="release\moc_predefs.h.cbt">
|
|
||||||
<FileType>Document</FileType>
|
|
||||||
<AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(QTDIR)\mkspecs\features\data\dummy.cpp;%(AdditionalInputs)</AdditionalInputs>
|
|
||||||
<Command Condition="'$(Configuration)|$(Platform)'=='Release|x64'">cl -Bx"$(QTDIR)\bin\qmake.exe" -nologo -Zc:wchar_t -FS -Zc:rvalueCast -Zc:inline -Zc:strictStrings -Zc:throwingNew -Zc:referenceBinding -Zc:__cplusplus -O2 -MD -W3 -w34100 -w34189 -w44996 -w44456 -w44457 -w44458 -wd4577 -wd4467 -E $(QTDIR)\mkspecs\features\data\dummy.cpp 2>NUL >release\moc_predefs.h</Command>
|
|
||||||
<Message Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Generate moc_predefs.h</Message>
|
|
||||||
<Outputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">release\moc_predefs.h;%(Outputs)</Outputs>
|
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
|
|
||||||
</CustomBuild>
|
|
||||||
</ItemGroup>
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<None Include="..\fonts\Roboto\Roboto-Black.ttf" />
|
<None Include="..\fonts\Roboto\Roboto-Black.ttf" />
|
||||||
<None Include="..\fonts\Roboto\Roboto-Bold.ttf" />
|
<None Include="..\fonts\Roboto\Roboto-Bold.ttf" />
|
||||||
|
|
Loading…
Reference in New Issue