Cromon

RoundedRectangle.hlsl

Oct 16th, 2012
142
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 5.03 KB | None | 0 0
  1.  
  2. matrix orthoProjMatrix;
  3. float4 elemSize;
  4. float4 strokeWidth;
  5. float4 rectParams;
  6.  
  7. texture brushTexture;
  8.  
  9. sampler brushSampler = sampler_state
  10. {
  11.     Texture = <brushTexture>;
  12.     AddressU = CLAMP;
  13.     AddressV = CLAMP;
  14.     AddressW = CLAMP;
  15.     BorderColor = float4(0, 0, 0, 0);
  16.     MipFilter = LINEAR;
  17.     MinFilter = LINEAR;
  18.     MagFilter = LINEAR;
  19. };
  20.  
  21. struct VertexShaderInput
  22. {
  23.     float3 position : POSITION0;
  24.     float4 color : COLOR0;
  25.     float2 texCoord : TEXCOORD0;
  26. };
  27.  
  28. struct PixelShaderInput
  29. {
  30.     float4 position : POSITION0;
  31.     float2 texCoord : TEXCOORD0;
  32.     float4 color : TEXCOORD1;
  33. };
  34.  
  35. void VertexMain(in VertexShaderInput vsInput, out PixelShaderInput output)
  36. {
  37.     output = (PixelShaderInput)0;
  38.  
  39.     output.position = mul(float4(vsInput.position, 1), orthoProjMatrix);
  40.     output.texCoord = vsInput.texCoord;
  41.     output.color = vsInput.color;
  42. }
  43.  
  44. float getEllipseRadius(float x, float y)
  45. {
  46.     float phi = atan2(y, x);
  47.     float a2 = rectParams.x * rectParams.x;
  48.     float b2 = rectParams.y * rectParams.y;
  49.     float ab = rectParams.x * rectParams.y;
  50.     float sin2 = sin(phi) * sin(phi);
  51.     float cos2 = cos(phi) * cos(phi);
  52.  
  53.     return (ab) / sqrt(a2 * sin2 + b2 * cos2);
  54. }
  55.  
  56. float4 sinusInterpolate(float4 src, float4 dest, float pct)
  57. {
  58.     float sinval = sin(pct * 3.1415926 / 2.0f);
  59.     return sinval * src + (1 - sinval) * dest;
  60. }
  61.  
  62. // Returns:
  63. // 0 -> top left
  64. // 1 -> bottom left
  65. // 2 -> top right
  66. // 3 -> bottom right
  67. // -2 -> "anti alias area"
  68. // -1 -> inside the solid area
  69. int getBorderQuad(float2 pos)
  70. {
  71.     if(pos.x <= rectParams.x + 2 && pos.y <= rectParams.y + 2)
  72.         return 0;
  73.     else if(pos.x <= rectParams.x + 2 && (elemSize.y - pos.y) <= rectParams.y + 2)
  74.         return 1;
  75.     else if((elemSize.x - pos.x) <= rectParams.x + 2 && pos.y <= rectParams.y + 2)
  76.         return 2;
  77.     else if((elemSize.x - pos.x) <= rectParams.x + 2 && (elemSize.y - pos.y) <= rectParams.y + 2)
  78.         return 3;
  79.  
  80.     if(pos.x <= 2 || pos.y <= 2 || (elemSize.x - pos.x) <= 2 || (elemSize.y - pos.y) <= 2)
  81.         return -2;
  82.  
  83.     return -1;
  84. }
  85.  
  86. float4 getColorFill(float4 color, float2 pos, bool fill, float2 texCoord)
  87. {
  88.     int quad = getBorderQuad(pos);
  89.    
  90.     if(quad == -2)
  91.     {
  92.         float pct = 0.0f;
  93.         if(pos.x <= 2)
  94.             pct = (2 - pos.x) / 2.0f;
  95.         else if(pos.x >= (elemSize.x - 2))
  96.             pct = (pos.x - elemSize.x + 2) / 2.0f;
  97.         else if(pos.y <= 2)
  98.             pct = (2 - pos.y) / 2.0f;
  99.         else if(pos.y >= (elemSize.y - 2))
  100.             pct = (pos.y - elemSize.y + 2) / 2.0f;
  101.  
  102.         return sinusInterpolate(color, float4(color.rgb, 0), 1 - pct);
  103.     }
  104.  
  105.     if(quad == -1)
  106.     {
  107.         if(fill)
  108.             return color;
  109.  
  110.         float strokex = strokeWidth.x;
  111.         float strokey = strokeWidth.y;
  112.  
  113.         float cy = 2 / elemSize.y;
  114.  
  115.         if((pos.x - 2) <= strokex)
  116.             return color;
  117.         if((texCoord.y - cy) <= strokey)
  118.             return color;
  119.         if((elemSize.x - 2 - pos.x) <= strokex)
  120.             return color;
  121.         if((1 - cy - texCoord.y) <= strokey)
  122.             return color;
  123.  
  124.         float pct = 0.0f;
  125.         if(pos.x <= 4)
  126.             pct = (2 - pos.x + 2) / 2.0f;
  127.         else if(pos.y <= 4)
  128.             pct = (2 - pos.y + 2) / 2.0f;
  129.         else if((elemSize.x - pos.x) <= 4)
  130.             pct = (elemSize.x - 2 - pos.x) / 2.0f;
  131.         else if((elemSize.y - pos.y) <= 4)
  132.             pct = (elemSize.y - 2 - pos.y) / 2.0f;
  133.         else
  134.             return float4(color.rgb, 0);
  135.  
  136.         return sinusInterpolate(color, float4(color.rgb, 0), 1 - pct);
  137.     }
  138.  
  139.     float2 midPoint;
  140.     if(quad == 0)
  141.         midPoint = float2(rectParams.x + 2, rectParams.y + 2);
  142.     else if(quad == 1)
  143.         midPoint = float2(rectParams.x + 2, elemSize.y - rectParams.y - 2);
  144.     else if(quad == 2)
  145.         midPoint = float2(elemSize.x - rectParams.x - 2, rectParams.y + 2);
  146.     else if(quad == 3)
  147.         midPoint = float2(elemSize.x - rectParams.x - 2, elemSize.y - rectParams.y - 2);
  148.  
  149.     float x = pos.x - midPoint.x;
  150.     float y = pos.y - midPoint.y;
  151.  
  152.     float radius = getEllipseRadius(x, y);
  153.     float radiusCoord = sqrt(x * x + y * y);
  154.     if(fill)
  155.     {
  156.         if(radiusCoord <= radius)
  157.             color = color;
  158.         else
  159.         {
  160.             float diff = radiusCoord - radius;
  161.             if(diff > 2)
  162.                 color = float4(color.rgb, 0);
  163.             else
  164.                 color = sinusInterpolate(color, float4(color.rgb, 0), 1.0f - diff / 2.0f);
  165.         }
  166.  
  167.         return color;
  168.     }
  169.     else
  170.     {
  171.         if(radiusCoord <= radius)
  172.         {
  173.             if((radius - radiusCoord) <= strokeWidth.x)
  174.                 color = color;
  175.             else
  176.             {
  177.                 float diff = (radius - radiusCoord) - strokeWidth.x;
  178.                 if(diff > 2)
  179.                     color = float4(color.rgb, 0);
  180.                 else
  181.                     color = sinusInterpolate(color, float4(color.rgb, 0), 1.0f - diff / 2.0f);
  182.             }
  183.         }
  184.         else
  185.         {
  186.             float diff = radiusCoord - radius;
  187.             if(diff > 2)
  188.                 color = float4(color.rgb, 0);
  189.             else
  190.                 color = sinusInterpolate(color, float4(color.rgb, 0), 1.0f - diff / 2.0f);
  191.         }
  192.  
  193.         return color;
  194.     }
  195. }
  196.  
  197. void PixelMainFill(in PixelShaderInput input, out float4 color : COLOR0)
  198. {
  199.     color = getColorFill(tex2D(brushSampler, input.texCoord), float2(elemSize.x * input.texCoord.x, elemSize.y * input.texCoord.y), true, input.texCoord);
  200. }
  201.  
  202. void PixelMainDraw(in PixelShaderInput input, out float4 color : COLOR0)
  203. {
  204.     color = getColorFill(tex2D(brushSampler, input.texCoord), float2(elemSize.x * input.texCoord.x, elemSize.y * input.texCoord.y), false, input.texCoord);
  205. }
Advertisement
Add Comment
Please, Sign In to add comment