Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- matrix orthoProjMatrix;
- float4 elemSize;
- float4 strokeWidth;
- float4 rectParams;
- texture brushTexture;
- sampler brushSampler = sampler_state
- {
- Texture = <brushTexture>;
- AddressU = CLAMP;
- AddressV = CLAMP;
- AddressW = CLAMP;
- BorderColor = float4(0, 0, 0, 0);
- MipFilter = LINEAR;
- MinFilter = LINEAR;
- MagFilter = LINEAR;
- };
- struct VertexShaderInput
- {
- float3 position : POSITION0;
- float4 color : COLOR0;
- float2 texCoord : TEXCOORD0;
- };
- struct PixelShaderInput
- {
- float4 position : POSITION0;
- float2 texCoord : TEXCOORD0;
- float4 color : TEXCOORD1;
- };
- void VertexMain(in VertexShaderInput vsInput, out PixelShaderInput output)
- {
- output = (PixelShaderInput)0;
- output.position = mul(float4(vsInput.position, 1), orthoProjMatrix);
- output.texCoord = vsInput.texCoord;
- output.color = vsInput.color;
- }
- float getEllipseRadius(float x, float y)
- {
- float phi = atan2(y, x);
- float a2 = rectParams.x * rectParams.x;
- float b2 = rectParams.y * rectParams.y;
- float ab = rectParams.x * rectParams.y;
- float sin2 = sin(phi) * sin(phi);
- float cos2 = cos(phi) * cos(phi);
- return (ab) / sqrt(a2 * sin2 + b2 * cos2);
- }
- float4 sinusInterpolate(float4 src, float4 dest, float pct)
- {
- float sinval = sin(pct * 3.1415926 / 2.0f);
- return sinval * src + (1 - sinval) * dest;
- }
- // Returns:
- // 0 -> top left
- // 1 -> bottom left
- // 2 -> top right
- // 3 -> bottom right
- // -2 -> "anti alias area"
- // -1 -> inside the solid area
- int getBorderQuad(float2 pos)
- {
- if(pos.x <= rectParams.x + 2 && pos.y <= rectParams.y + 2)
- return 0;
- else if(pos.x <= rectParams.x + 2 && (elemSize.y - pos.y) <= rectParams.y + 2)
- return 1;
- else if((elemSize.x - pos.x) <= rectParams.x + 2 && pos.y <= rectParams.y + 2)
- return 2;
- else if((elemSize.x - pos.x) <= rectParams.x + 2 && (elemSize.y - pos.y) <= rectParams.y + 2)
- return 3;
- if(pos.x <= 2 || pos.y <= 2 || (elemSize.x - pos.x) <= 2 || (elemSize.y - pos.y) <= 2)
- return -2;
- return -1;
- }
- float4 getColorFill(float4 color, float2 pos, bool fill, float2 texCoord)
- {
- int quad = getBorderQuad(pos);
- if(quad == -2)
- {
- float pct = 0.0f;
- if(pos.x <= 2)
- pct = (2 - pos.x) / 2.0f;
- else if(pos.x >= (elemSize.x - 2))
- pct = (pos.x - elemSize.x + 2) / 2.0f;
- else if(pos.y <= 2)
- pct = (2 - pos.y) / 2.0f;
- else if(pos.y >= (elemSize.y - 2))
- pct = (pos.y - elemSize.y + 2) / 2.0f;
- return sinusInterpolate(color, float4(color.rgb, 0), 1 - pct);
- }
- if(quad == -1)
- {
- if(fill)
- return color;
- float strokex = strokeWidth.x;
- float strokey = strokeWidth.y;
- float cy = 2 / elemSize.y;
- if((pos.x - 2) <= strokex)
- return color;
- if((texCoord.y - cy) <= strokey)
- return color;
- if((elemSize.x - 2 - pos.x) <= strokex)
- return color;
- if((1 - cy - texCoord.y) <= strokey)
- return color;
- float pct = 0.0f;
- if(pos.x <= 4)
- pct = (2 - pos.x + 2) / 2.0f;
- else if(pos.y <= 4)
- pct = (2 - pos.y + 2) / 2.0f;
- else if((elemSize.x - pos.x) <= 4)
- pct = (elemSize.x - 2 - pos.x) / 2.0f;
- else if((elemSize.y - pos.y) <= 4)
- pct = (elemSize.y - 2 - pos.y) / 2.0f;
- else
- return float4(color.rgb, 0);
- return sinusInterpolate(color, float4(color.rgb, 0), 1 - pct);
- }
- float2 midPoint;
- if(quad == 0)
- midPoint = float2(rectParams.x + 2, rectParams.y + 2);
- else if(quad == 1)
- midPoint = float2(rectParams.x + 2, elemSize.y - rectParams.y - 2);
- else if(quad == 2)
- midPoint = float2(elemSize.x - rectParams.x - 2, rectParams.y + 2);
- else if(quad == 3)
- midPoint = float2(elemSize.x - rectParams.x - 2, elemSize.y - rectParams.y - 2);
- float x = pos.x - midPoint.x;
- float y = pos.y - midPoint.y;
- float radius = getEllipseRadius(x, y);
- float radiusCoord = sqrt(x * x + y * y);
- if(fill)
- {
- if(radiusCoord <= radius)
- color = color;
- else
- {
- float diff = radiusCoord - radius;
- if(diff > 2)
- color = float4(color.rgb, 0);
- else
- color = sinusInterpolate(color, float4(color.rgb, 0), 1.0f - diff / 2.0f);
- }
- return color;
- }
- else
- {
- if(radiusCoord <= radius)
- {
- if((radius - radiusCoord) <= strokeWidth.x)
- color = color;
- else
- {
- float diff = (radius - radiusCoord) - strokeWidth.x;
- if(diff > 2)
- color = float4(color.rgb, 0);
- else
- color = sinusInterpolate(color, float4(color.rgb, 0), 1.0f - diff / 2.0f);
- }
- }
- else
- {
- float diff = radiusCoord - radius;
- if(diff > 2)
- color = float4(color.rgb, 0);
- else
- color = sinusInterpolate(color, float4(color.rgb, 0), 1.0f - diff / 2.0f);
- }
- return color;
- }
- }
- void PixelMainFill(in PixelShaderInput input, out float4 color : COLOR0)
- {
- color = getColorFill(tex2D(brushSampler, input.texCoord), float2(elemSize.x * input.texCoord.x, elemSize.y * input.texCoord.y), true, input.texCoord);
- }
- void PixelMainDraw(in PixelShaderInput input, out float4 color : COLOR0)
- {
- color = getColorFill(tex2D(brushSampler, input.texCoord), float2(elemSize.x * input.texCoord.x, elemSize.y * input.texCoord.y), false, input.texCoord);
- }
Advertisement
Add Comment
Please, Sign In to add comment