Cromon

RoundedRectangle.hlsl

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