/// <summary> /// Read pixels in specified rect and get the VertexIds they represent. /// </summary> /// <param name="target"></param> /// <returns></returns> private static unsafe List <Tuple <Point, uint> > ReadPixels(Rectangle target) { var result = new List <Tuple <Point, uint> >(); // get coded color. using (var codedColor = new UnmanagedArray <Pixel>(target.Width * target.Height)) { OpenGL.ReadPixels(target.X, target.Y, target.Width, target.Height, OpenGL.GL_RGBA, OpenGL.GL_UNSIGNED_BYTE, codedColor.Header); var array = (Pixel *)codedColor.Header.ToPointer(); int index = 0; var vertexIdList = new List <uint>(); for (int yOffset = target.Height - 1; yOffset >= 0; yOffset--) { for (int xOffset = 0; xOffset < target.Width; xOffset++) { Pixel pixel = array[index++]; // This is when (x, y) is not on background and some primitive is picked. if (!pixel.IsWhite()) { uint stageVertexId = pixel.ToStageVertexId(); if (!vertexIdList.Contains(stageVertexId)) { result.Add(new Tuple <Point, uint>( new Point(target.X + xOffset, target.Y + yOffset), stageVertexId)); vertexIdList.Add(stageVertexId); } } } } } return(result); }
/// <summary> /// Gets stage vertex id by color coded picking machanism. /// Note: left bottom is(0, 0). This is different from Winform's left top being (0, 0). /// </summary> /// <param name="x">target pixel position(Left Down is (0, 0)).</param> /// <param name="y">target pixel position(Left Down is (0, 0)).</param> /// <returns></returns> internal static unsafe uint ReadStageVertexId(int x, int y) { var array = new Pixel[1]; GCHandle pinned = GCHandle.Alloc(array, GCHandleType.Pinned); IntPtr header = Marshal.UnsafeAddrOfPinnedArrayElement(array, 0); // get coded color. GL.Instance.ReadPixels(x, y, 1, 1, GL.GL_RGBA, GL.GL_UNSIGNED_BYTE, header); pinned.Free(); Pixel pixel = array[0]; uint stageVertexId = pixel.IsWhite() ? uint.MaxValue : // This is when (x, y) is not on background and some primitive is picked. pixel.ToStageVertexId(); return(stageVertexId); }
/// <summary> /// Read pixels in specified rect and get the VertexIds they represent. /// </summary> /// <param name="target"></param> /// <returns></returns> private static unsafe List <Tuple <Point, uint> > ReadPixels(Rectangle target) { // get coded color. var codedColor = new Pixel[target.Width * target.Height]; { GCHandle pinned = GCHandle.Alloc(codedColor, GCHandleType.Pinned); IntPtr header = Marshal.UnsafeAddrOfPinnedArrayElement(codedColor, 0); OpenGL.ReadPixels(target.X, target.Y, target.Width, target.Height, OpenGL.GL_RGBA, OpenGL.GL_UNSIGNED_BYTE, header); pinned.Free(); } var result = new List <Tuple <Point, uint> >(); int index = 0; var vertexIdList = new List <uint>(); for (int yOffset = target.Height - 1; yOffset >= 0; yOffset--) { for (int xOffset = 0; xOffset < target.Width; xOffset++) { Pixel pixel = codedColor[index++]; // This is when (x, y) is not on background and some primitive is picked. if (!pixel.IsWhite()) { uint stageVertexId = pixel.ToStageVertexId(); if (!vertexIdList.Contains(stageVertexId)) { result.Add(new Tuple <Point, uint>( new Point(target.X + xOffset, target.Y + yOffset), stageVertexId)); vertexIdList.Add(stageVertexId); } } } } return(result); }