2 using System.Collections.Generic;
5 using System.Threading.Tasks;
6 using Tizen.NUI.BaseComponents;
7 using System.Runtime.InteropServices;
9 namespace Tizen.NUI.Samples
11 public class ClippedImage
13 public static float QUAD_GEOMETRY = 1.0f;
14 public static float CIRCLE_GEOMETRY = 0.0f;
15 static float[] circleArray;
16 static float[] quadArray;
18 static Geometry geometry = null;
20 private static readonly string VERTEX_SHADER =
21 "attribute vec2 aPositionCircle;\n" +
22 "attribute vec2 aPositionQuad;\n" +
23 "uniform float uDelta;\n" +
24 "uniform mat4 uMvpMatrix;\n" +
25 "uniform vec3 uSize;\n" +
29 " vec4 vertexPosition = vec4(mix(aPositionCircle, aPositionQuad, uDelta), 0.0, 1.0);\n" +
30 " vertexPosition.xyz *= uSize;\n" +
31 " gl_Position = uMvpMatrix * vertexPosition;\n" +
34 private static readonly string FRAGMENT_SHADER =
35 "precision mediump float;\n" +
38 " gl_FragColor = vec4(0.0, 0.0, 0.0, 0.0);\n" +
41 public static View Create(string imagePath )
43 // Create a view which whose geometry will be morphed between a circle and a quad
44 View clippedImage = new View();
45 clippedImage.ClippingMode = ClippingModeType.ClipChildren;
47 // Create the required renderer and add to the clipped image view
48 Shader shader = CreateShader();
50 Renderer renderer = new Renderer(geometry, shader);
51 renderer.BlendMode = 2;
52 clippedImage.AddRenderer(renderer);
54 // Register the property on the clipped image view which will allow animations between a circle and a quad
55 int propertyIndex = clippedImage.RegisterProperty("uDelta", new PropertyValue(0.0f));
57 // Add the actual image to the control
58 View image = new ImageView(imagePath);
59 image.WidthResizePolicy = ResizePolicyType.FillToParent;
60 image.HeightResizePolicy = ResizePolicyType.FillToParent;
61 image.ParentOrigin = ParentOrigin.Center;
62 image.PivotPoint = PivotPoint.Center;
63 image.PositionUsesPivotPoint = true;
64 clippedImage.Add(image);
69 private static Shader CreateShader()
71 Shader shader = new Shader(VERTEX_SHADER, FRAGMENT_SHADER);
76 private static void CreateGeometry()
80 geometry = new Geometry();
82 const int vertexCount = 34;
84 circleArray = new float[vertexCount * 2];
85 quadArray = new float[vertexCount * 2];
87 // Create the circle geometry
89 // Radius is bound to actor's dimensions so this should not be increased.
90 // If a bigger circle is required then the actor size should be increased.
91 const float radius = 0.5f;
92 Vector2 center = new Vector2(0.0f, 0.0f);
94 // Create a buffer for vertex data
95 Vector2[] circleBuffer = new Vector2[vertexCount];
98 // Center vertex for triangle fan
99 circleBuffer[idx++] = center;
101 // Outer vertices of the circle
102 const int outerVertexCount = vertexCount - 1;
104 for (int i = 0; i < outerVertexCount; ++i)
106 float percent = (i / (float)(outerVertexCount - 1));
107 float rad = percent * 2.0f * (float)Math.PI;
110 Vector2 tmpvec = new Vector2(0, 0);
111 tmpvec.X = (float)(center.X + radius * Math.Cos(rad));
112 tmpvec.Y = (float)(center.Y + radius * Math.Sin(rad));
114 circleBuffer[idx++] = tmpvec;
117 for(int i = 0; i < idx; i++)
119 circleArray[i * 2] = circleBuffer[i].X;
120 circleArray[i * 2 + 1] = circleBuffer[i].Y;
123 PropertyMap circleVertexFormat = new PropertyMap();
124 circleVertexFormat.Add("aPositionCircle", new PropertyValue((int)PropertyType.Vector2));
125 PropertyBuffer circleVertices = new PropertyBuffer(circleVertexFormat);
129 float* pc = (float*)Marshal.UnsafeAddrOfPinnedArrayElement(circleArray, 0);
130 IntPtr pA = new IntPtr(pc);
131 circleVertices.SetData(pA, vertexCount);
135 // Create the Quad Geometry
136 Vector2[] quadBuffer = new Vector2[vertexCount];
138 quadBuffer[idx++] = new Vector2(center.X, center.Y);
140 const int vertsPerSide = (vertexCount - 2) / 4;
141 Vector2 outer = new Vector2(0.5f, 0.0f);
142 quadBuffer[idx++] = new Vector2(outer.X, outer.Y);
143 float incrementPerBuffer = 1.0f / (float)(vertsPerSide);
145 for (int i = 0; i < vertsPerSide && outer.Y < 0.5f; ++i)
147 outer.Y += incrementPerBuffer;
148 quadBuffer[idx++] = new Vector2(outer.X, outer.Y);
151 for (int i = 0; i < vertsPerSide && outer.X > -0.5f; ++i)
153 outer.X -= incrementPerBuffer;
154 quadBuffer[idx++] = new Vector2(outer.X, outer.Y);
157 for (int i = 0; i < vertsPerSide && outer.Y > -0.5f; ++i)
159 outer.Y -= incrementPerBuffer;
160 quadBuffer[idx++] = new Vector2(outer.X, outer.Y);
163 for (int i = 0; i < vertsPerSide && outer.X < 0.5f; ++i)
165 outer.X += incrementPerBuffer;
166 quadBuffer[idx++] = new Vector2(outer.X, outer.Y);
169 for (int i = 0; i < vertsPerSide && outer.Y < 0.0f; ++i)
171 outer.Y += incrementPerBuffer;
172 quadBuffer[idx++] = new Vector2(outer.X, outer.Y);
175 for(int i = 0; i < idx; i++)
177 quadArray[i * 2] = quadBuffer[i].X;
178 quadArray[i * 2 + 1] = quadBuffer[i].Y;
181 PropertyMap vertexFormat = new PropertyMap();
182 vertexFormat.Add("aPositionQuad", new PropertyValue((int)PropertyType.Vector2));
183 PropertyBuffer quadVertices2 = new PropertyBuffer(vertexFormat);
186 float* pc = (float*)Marshal.UnsafeAddrOfPinnedArrayElement(quadArray, 0);
187 IntPtr pA = new IntPtr(pc);
188 quadVertices2.SetData(pA, vertexCount);
190 //int length2 = Marshal.SizeOf(quadBuffer[0]);
191 //IntPtr p2 = Marshal.AllocHGlobal(length2 * vertexCount);
192 //quadVertices2.SetData(p2, vertexCount);
194 // Create the geometry object itself
195 geometry.AddVertexBuffer(circleVertices);
196 geometry.AddVertexBuffer(quadVertices2);
197 geometry.SetType(Geometry.Type.TRIANGLE_FAN);