diff options
Diffstat (limited to 'src/gui/painting/qpaintengine_d3d.fx')
-rw-r--r-- | src/gui/painting/qpaintengine_d3d.fx | 608 |
1 files changed, 608 insertions, 0 deletions
diff --git a/src/gui/painting/qpaintengine_d3d.fx b/src/gui/painting/qpaintengine_d3d.fx new file mode 100644 index 0000000..1148b2a --- /dev/null +++ b/src/gui/painting/qpaintengine_d3d.fx @@ -0,0 +1,608 @@ +bool g_mCosmeticPen; +int4 g_mChannel; +float2 g_mMaskOffset; +int2 g_mMaskSize; +float4x4 g_mMaskProjection; +float4x4 g_mViewProjection; +float4x4 g_mTransformation; +texture g_mAAMask; +texture g_mTexture; +int g_mBrushMode; +float g_mFocalDist; + +#define M_PI 3.14159265358979323846 + +sampler PixmapSampler = sampler_state +{ + texture = <g_mTexture>; + MIPFILTER = NONE; + MINFILTER = LINEAR; + MAGFILTER = LINEAR; +}; + +sampler TextSampler = sampler_state +{ + texture = <g_mTexture>; + MIPFILTER = NONE; + MINFILTER = POINT; + MAGFILTER = POINT; +}; + +sampler AAMaskSampler = sampler_state +{ + texture = <g_mAAMask>; + AddressU = WRAP; + AddressV = WRAP; + AddressW = WRAP; + MIPFILTER = NONE; + MINFILTER = POINT; + MAGFILTER = POINT; +}; + +struct VS_FULL +{ + float4 Position : POSITION; + float4 Diffuse : COLOR0; + float4 TexCoords0 : TEXCOORD0; + float4 TexCoords1 : TEXCOORD1; +}; + +VS_FULL TrapezoidVS( float4 Position : POSITION, + float4 Diffuse : COLOR0, + float4 TexCoords0 : TEXCOORD0, + float4 TexCoords1 : TEXCOORD1) +{ + VS_FULL Output; + + float a = (TexCoords1.x * Position.x) + (TexCoords1.z * (1.0 - Position.x) ); // left or right a + float b = (TexCoords1.y * Position.x) + (TexCoords1.w * (1.0 - Position.x) ); // left or right b + float d = 1.0 - (Position.x * 2); + + Position.x = (a * Position.y + b) + ( sqrt( abs(a * a) ) * d ); + //Position.x += step(abs(a), 0) * d; + Position.x += (0.5 * d); + + Output.Position = mul(Position, g_mMaskProjection); + Output.Diffuse = Diffuse; + Output.TexCoords0 = TexCoords0; + Output.TexCoords1 = TexCoords1; + + return Output; +} + +struct PS_OUTPUT +{ + float4 Color : COLOR0; +}; + +PS_OUTPUT TrapezoidPS(VS_FULL In, float2 pixelPos : VPOS) +{ + PS_OUTPUT Out; + + float top = max(pixelPos.y - 0.5, In.TexCoords0.x); + float bottom = min(pixelPos.y + 0.5, In.TexCoords0.y); + + float area = bottom - top; + + float left = pixelPos.x - 0.5; + float right = pixelPos.x + 0.5; + + // use line equations to compute intersections of left/right edges with top/bottom of truncated pixel + // vecX: x = (left, top), y = (left, bottom), z = (right, top), w = (right, bottom) + float4 vecX = In.TexCoords1.xxzz * float2(top, bottom).xyxy + In.TexCoords1.yyww; + + float2 invA = In.TexCoords0.zw; + + // transform right line to left to be able to use same calculations for both + vecX.zw = 2 * pixelPos.x - vecX.zw; + + float2 topX = float2(vecX.x, vecX.z); + float2 bottomX = float2(vecX.y, vecX.w); + + // transform lines such that top intersection is to the right of bottom intersection + float2 topXTemp = max(topX, bottomX); + float2 bottomXTemp = min(topX, bottomX); + + // make sure line slope reflects mirrored lines + invA = lerp(invA, -invA, step(topX, bottomX)); + + float2 vecLeftRight = float2(left, right); + + // compute the intersections of the lines with the left and right edges of the pixel + // intersectY: x = (left_line, left), y = (left_line, right), z = (right_line, left), w = (right_line, right) + float4 intersectY = top + (vecLeftRight.xyxy - topXTemp.xxyy) * invA.xxyy; + + float2 temp = lerp(area - 0.5 * (right - bottomXTemp) * (bottom - intersectY.yw), // left < bottom < right < top + (0.5 * (topXTemp + bottomXTemp) - left) * area, // left < bottom < top < right + step(topXTemp, right)); + + float2 excluded = 0.5 * (intersectY.xz - top) * (topXTemp - left); // bottom < left < top < right + + excluded = lerp(0.5 * (intersectY.yw + intersectY.xz) - top, // bottom < left < right < top + excluded, step(topXTemp, right)); + + excluded = lerp(temp, // left < bottom < right (see calculation of temp) + excluded, step(bottomXTemp, left)); + + excluded = lerp(float2(area, area), // right < bottom < top + excluded, step(bottomXTemp, right)); + + excluded *= step(left, topXTemp); + + float result = (area - excluded.x - excluded.y) * step(top, bottom); + Out.Color.r = result * g_mChannel[0]; + Out.Color.g = result * g_mChannel[1]; + Out.Color.b = result * g_mChannel[2]; + Out.Color.a = result * g_mChannel[3]; + + return Out; +} + +VS_FULL ViewProjectionVS( float4 Position : POSITION, + float4 Diffuse : COLOR0, + float4 TexCoords0 : TEXCOORD0, + float4 TexCoords1 : TEXCOORD1) +{ + VS_FULL Output; + + Output.Position = mul(Position, g_mTransformation); + Output.Position = mul(Output.Position, g_mViewProjection); + Output.Diffuse = Diffuse; + Output.TexCoords0 = TexCoords0; + Output.TexCoords1 = TexCoords1; + + return Output; +} + +PS_OUTPUT DirectMaskPS(VS_FULL In, float2 pixelPos : VPOS) +{ + PS_OUTPUT Out; + Out.Color = In.Diffuse; + + float2 maskcoords = ( (pixelPos + g_mMaskOffset) - 0.5 ) / g_mMaskSize; + float2 clipcoords = (pixelPos - 0.5) / g_mMaskSize; + + float4 c = tex2D(AAMaskSampler, maskcoords.xy) * Out.Color.a; + Out.Color.a = c.r * g_mChannel[0]; + Out.Color.a += c.g * g_mChannel[1]; + Out.Color.a += c.b * g_mChannel[2]; + Out.Color.a += c.a * g_mChannel[3]; + + return Out; +} + +PS_OUTPUT MaskPS(VS_FULL In, float2 pixelPos : VPOS) +{ + PS_OUTPUT Out; + + if (g_mBrushMode == 1) { + float x = In.TexCoords0.x; + float y = In.TexCoords0.y; + x = x - int(x); + y = y - int(y); + Out.Color = tex2D(PixmapSampler, float2(x, y)); + Out.Color.a = Out.Color.a * In.Diffuse.a; + } else if (g_mBrushMode == 2) { + Out.Color = tex1D(PixmapSampler, In.TexCoords0.x); + } else if (g_mBrushMode == 3) { + float t = atan2(In.TexCoords0.y, -In.TexCoords0.x) / (2 * M_PI); + Out.Color = tex1D(PixmapSampler, t + 0.5); + } else if (g_mBrushMode == 4) { + float2 tc = float2(In.TexCoords0.x, abs(In.TexCoords0.y)); + float a = (tc.x - g_mFocalDist) / tc.y; + float b = g_mFocalDist; + + float A = 1 + (a * a); + float B = 2.0 * a * b; + float C = (b * b) - 1; + + float y = (-B + sqrt(B*B - 4.0*A*C)) / (2.0*A); + Out.Color = tex1D(PixmapSampler, (tc.y / y) ); + } else if (g_mBrushMode == 5) { + Out.Color = tex2D(PixmapSampler, In.TexCoords0.xy); + Out.Color = Out.Color * In.Diffuse; + } else { + Out.Color = In.Diffuse; + } + + float2 maskcoords = ( (pixelPos + g_mMaskOffset) - 0.5 ) / g_mMaskSize; + + float4 c = tex2D(AAMaskSampler, maskcoords.xy) * Out.Color.a; + Out.Color.a = c.r * g_mChannel[0]; + Out.Color.a += c.g * g_mChannel[1]; + Out.Color.a += c.b * g_mChannel[2]; + Out.Color.a += c.a * g_mChannel[3]; + + return Out; +} + +struct VS_NORMAL +{ + float4 Position : POSITION; + float4 Diffuse : COLOR0; + float4 TexCoords : TEXCOORD0; +}; + +VS_NORMAL MaskProjectionVS(VS_NORMAL In) +{ + VS_NORMAL Output; + + Output.Position = mul(In.Position, g_mMaskProjection); + Output.Diffuse = In.Diffuse; + Output.TexCoords = In.TexCoords; + + return Output; +} + +float4 DirectSimplePS(float4 Color : COLOR0) : COLOR0 +{ + return Color; +} + +float4 SimplePS(float4 Color : COLOR0, float4 TexCoords : TEXCOORD0) : COLOR0 +{ + if (g_mBrushMode == 1) { + float opacity = Color.a; + float x = TexCoords.x; + float y = TexCoords.y; + x = x - int(x); + y = y - int(y); + Color = tex2D(PixmapSampler, float2(x, y)); + Color.a = Color.a * opacity; + } else if (g_mBrushMode == 2) { + Color = tex1D(PixmapSampler, TexCoords.x); + } else if (g_mBrushMode == 3) { + float t = atan2(TexCoords.y, -TexCoords.x) / (2 * M_PI); + Color = tex1D(PixmapSampler, t + 0.5); + } else if (g_mBrushMode == 4) { + float2 tc = float2(TexCoords.x, abs(TexCoords.y)); + float a = (tc.x - g_mFocalDist) / tc.y; + float b = g_mFocalDist; + + float A = 1 + (a * a); + float B = 2.0 * a * b; + float C = (b * b) - 1; + + float y = (-B + sqrt(B*B - 4.0*A*C)) / (2.0*A); + Color = tex1D(PixmapSampler, (tc.y / y) ); + } else if (g_mBrushMode == 5) { + Color = tex2D(PixmapSampler, TexCoords.xy) * Color; + } + + return Color; +} + +float4 TextPS(float4 Color : COLOR0, float4 TexCoords : TEXCOORD0) : COLOR0 +{ + Color.a *= tex2D(TextSampler, TexCoords.xy).a; + return Color; +} + +float4 ClearTypePS(float4 Color : COLOR0, float4 TexCoords : TEXCOORD0) : COLOR0 +{ +// if (g_mUsePixmap) { +// float4 MaskColor = tex2D(PixmapSampler, TexCoords.xy); +// Color = float4(1.0, 0.0, 0.0, 1.0); +// Color.a = (1 - MaskColor.a) + MaskColor.a * Color.a; +// Color.r = (1.0 - MaskColor.r) + (MaskColor.r * Color.r); +// Color.g = (1.0 - MaskColor.g) + (MaskColor.g * Color.g); +// Color.b = (1.0 - MaskColor.b) + (MaskColor.b * Color.b); +// Color = MaskColor; + return tex2D(PixmapSampler, TexCoords.xy); +} + +VS_NORMAL NoTxAliasedVS(VS_NORMAL In) +{ + VS_NORMAL Output; + + Output.Position = mul(In.Position, g_mViewProjection); + Output.Diffuse = In.Diffuse; + Output.TexCoords = In.TexCoords; + + return Output; +} + +VS_NORMAL AliasedVS(VS_NORMAL In) +{ + VS_NORMAL Output; + + Output.Position = mul(In.Position, g_mTransformation); + Output.Position = mul(Output.Position, g_mViewProjection); + Output.Diffuse = In.Diffuse; + Output.TexCoords = In.TexCoords; + + return Output; +} + +VS_NORMAL AliasedLinesVS(VS_NORMAL In) +{ + VS_NORMAL Output; + + float4 start = float4(In.Position.x, In.Position.y, 0.5, In.Position.w); + float4 end = float4(In.TexCoords.z, In.TexCoords.w, 0.5, In.Position.w); + if (g_mCosmeticPen) { + start = mul(start, g_mTransformation); + end = mul(end, g_mTransformation); + } + + float2 line_vec = end - start; + float2 vec = normalize(line_vec); + float2 norm = float2(-vec.y, vec.x); + + float pen_width = In.Position.z; + norm = norm * pen_width * 0.5; + vec = vec * pen_width * 0.5; + + Output.Position.w = In.Position.w; + Output.Position.x = start.x + (vec.x * In.TexCoords.x); + Output.Position.x = Output.Position.x + (norm.x * In.TexCoords.y); + Output.Position.x = Output.Position.x + (line_vec.x * step(0, In.TexCoords.x)); + Output.Position.y = start.y + (vec.y * In.TexCoords.x); + Output.Position.y = Output.Position.y + (norm.y * In.TexCoords.y); + Output.Position.y = Output.Position.y + (line_vec.y * step(0, In.TexCoords.x)); + Output.Position.z = 0.5; + + if (!g_mCosmeticPen) { + Output.Position = mul(Output.Position, g_mTransformation); + } + Output.Position = mul(Output.Position, g_mViewProjection); + + Output.Diffuse = In.Diffuse; + Output.TexCoords = In.TexCoords; + + return Output; +} + + +technique Antialiased +{ + pass PASS_AA_CREATEMASK + { + StencilEnable = False; + ZWriteEnable = False; + ColorWriteEnable = 0x0f; + ZEnable = False; + + SrcBlend = One; + DestBlend = One; + + VertexShader = compile vs_3_0 TrapezoidVS(); + PixelShader = compile ps_3_0 TrapezoidPS(); + } + + pass PASS_AA_DRAW + { + StencilEnable = False; + ZFunc = Greater; + ZWriteEnable = False; + ZEnable = True; + ColorWriteEnable = 0x0f; + + VertexShader = compile vs_3_0 ViewProjectionVS(); + PixelShader = compile ps_3_0 MaskPS(); + } + + pass PASS_AA_DRAW_DIRECT + { + StencilEnable = False; + ZFunc = Greater; + ZEnable = True; + ZWriteEnable = False; + ColorWriteEnable = 0x0f; + + VertexShader = compile vs_3_0 ViewProjectionVS(); + PixelShader = compile ps_3_0 DirectMaskPS(); + } +} + +technique Aliased +{ + pass PASS_STENCIL_ODDEVEN + { + TwoSidedStencilMode = False; + StencilEnable = True; + StencilPass = Invert; + StencilFunc = Always; + ColorWriteEnable = 0; + + ZEnable = False; + ZWriteEnable = False; + + VertexShader = compile vs_1_1 NoTxAliasedVS(); + PixelShader = compile ps_2_0 DirectSimplePS(); + } + + pass PASS_STENCIL_WINDING + { + TwoSidedStencilMode = True; + StencilEnable = True; + StencilRef = 0; + StencilMask = 0xFFFFFFFF; + + CCW_StencilPass = Incr; + CCW_StencilFunc = Always; + + StencilPass = Decr; + StencilFunc = Always; + + ColorWriteEnable = 0; + + ZEnable = False; + ZWriteEnable = False; + + VertexShader = compile vs_1_1 NoTxAliasedVS(); + PixelShader = compile ps_2_0 DirectSimplePS(); + } + + pass PASS_STENCIL_DRAW + { + TwoSidedStencilMode = False; + StencilEnable = True; + StencilFunc = NotEqual; + StencilMask = 0xFFFFFFFF; + StencilRef = 0; + StencilPass = Zero; + StencilFail = Zero; + StencilZFail = Zero; + + ColorWriteEnable = 0x0f; + ZEnable = True; + ZWriteEnable = False; + ZFunc = Greater; + + VertexShader = compile vs_1_1 AliasedVS(); + PixelShader = compile ps_2_0 SimplePS(); + } + + pass PASS_STENCIL_DRAW_DIRECT + { + TwoSidedStencilMode = False; + StencilEnable = True; + StencilFunc = NotEqual; + StencilMask = 0xFFFFFFFF; + StencilRef = 0; + StencilPass = Zero; + StencilFail = Zero; + StencilZFail = Zero; + + ColorWriteEnable = 0x0f; + ZEnable = True; + ZWriteEnable = False; + ZFunc = Greater; + + VertexShader = compile vs_1_1 AliasedVS(); + PixelShader = compile ps_2_0 DirectSimplePS(); + } + + pass PASS_STENCIL_CLIP + { + TwoSidedStencilMode = False; + StencilEnable = True; + StencilFunc = NotEqual; + StencilMask = 0xFFFFFFFF; + StencilRef = 0; + StencilPass = Zero; + StencilFail = Zero; + StencilZFail = Zero; + + ColorWriteEnable = 0; + ZEnable = True; + ZWriteEnable = True; + ZFunc = Always; + + VertexShader = compile vs_1_1 NoTxAliasedVS(); + PixelShader = compile ps_2_0 DirectSimplePS(); + } + + pass PASS_STENCIL_NOSTENCILCHECK + { + StencilEnable = False; + + ZEnable = True; + ZWriteEnable = False; + ZFunc = Greater; + + ColorWriteEnable = 0x0f; + + SrcBlend = SrcAlpha; + DestBlend = InvSrcAlpha; + + VertexShader = compile vs_1_1 AliasedVS(); + PixelShader = compile ps_2_0 SimplePS(); + } + + pass PASS_STENCIL_NOSTENCILCHECK_DIRECT + { + StencilEnable = False; + + ZEnable = True; + ZWriteEnable = False; + ZFunc = Greater; + + ColorWriteEnable = 0x0f; + + SrcBlend = SrcAlpha; + DestBlend = InvSrcAlpha; + + VertexShader = compile vs_1_1 AliasedVS(); + PixelShader = compile ps_2_0 DirectSimplePS(); + } + + pass PASS_TEXT + { + StencilEnable = False; + + ZEnable = True; + ZWriteEnable = False; + ZFunc = Greater; + + ColorWriteEnable = 0x0f; + + SrcBlend = SrcAlpha; + DestBlend = InvSrcAlpha; + + VertexShader = compile vs_1_1 AliasedVS(); + PixelShader = compile ps_2_0 TextPS(); + } + + pass PASS_CLEARTYPE_TEXT + { + StencilEnable = False; + + ZEnable = True; + ZWriteEnable = False; + ZFunc = Greater; + + ColorWriteEnable = 0x0f; + +// SrcBlend = SrcAlpha; +// DestBlend = InvSrcAlpha; + +// SrcBlend = DestColor; +// DestBlend = Zero; + SrcBlend = BlendFactor; + DestBlend = InvSrcColor; + +// SrcBlend = Zero; +// DestBlend = SrcColor; + +// SrcBlend = One; +// DestBlend = Zero; + + VertexShader = compile vs_3_0 AliasedVS(); + PixelShader = compile ps_3_0 ClearTypePS(); + } + + pass PASS_ALIASED_LINES + { + TwoSidedStencilMode = False; + StencilEnable = True; + StencilPass = Invert; + StencilFunc = Always; + ColorWriteEnable = 0; + + ZEnable = False; + ZWriteEnable = False; + + VertexShader = compile vs_1_1 AliasedLinesVS(); + PixelShader = compile ps_2_0 DirectSimplePS(); + } + + pass PASS_ALIASED_LINES_DIRECT + { + StencilEnable = False; + + ZEnable = True; + ZWriteEnable = False; + ZFunc = Greater; + + ColorWriteEnable = 0x0f; + + SrcBlend = SrcAlpha; + DestBlend = InvSrcAlpha; + + VertexShader = compile vs_1_1 AliasedLinesVS(); + PixelShader = compile ps_2_0 DirectSimplePS(); + } +} + |