private ReadPixels ( int x, int y, int width, int height, uint format, uint type, IntPtr pixels ) : void | ||
x | int | |
y | int | |
width | int | |
height | int | |
format | uint | |
type | uint | |
pixels | IntPtr | |
return | void |
/// <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); }
private static unsafe bool PickedSomething(Rectangle rect, Rectangle rectangle) { if (rect.Width <= 0 || rect.Height <= 0) { return(false); } bool result = false; using (var codedColor = new UnmanagedArray <byte>(rect.Width * rect.Height)) { OpenGL.ReadPixels(rect.X, rectangle.Height - rect.Y - 1, rect.Width, rect.Height, OpenGL.GL_DEPTH_COMPONENT, OpenGL.GL_UNSIGNED_BYTE, codedColor.Header); var array = (byte *)codedColor.Header.ToPointer(); for (int i = 0; i < codedColor.Length; i++) { if (array[i] < byte.MaxValue) { result = true; break; } } } return(result); }
/// <summary> /// <para>Read pixels in specified rect and get the VertexIds they represent.</para> /// </summary> /// <param name="rect"></param> /// <param name="canvasHeight"></param> /// <returns></returns> public static unsafe List <Tuple <Point, uint> > ReadPixels( Rectangle rect, int canvasHeight) { var result = new List <Tuple <Point, uint> >(); if (rect.Width <= 0 || rect.Height <= 0) { return(result); } // get coded color. using (var codedColor = new UnmanagedArray <Pixel>(rect.Width * rect.Height)) { OpenGL.ReadPixels(rect.X, canvasHeight - rect.Y - 1, rect.Width, rect.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 = rect.Height - 1; yOffset >= 0; yOffset--) { for (int xOffset = 0; xOffset < rect.Width; xOffset++) { Pixel pixel = array[index++]; if (! // This is when (x, y) is on background and no primitive is picked. (pixel.r == byte.MaxValue && pixel.g == byte.MaxValue && pixel.b == byte.MaxValue && pixel.a == byte.MaxValue)) { /* // This is how is vertexID coded into color in vertex shader. * int objectID = gl_VertexID; * codedColor = vec4( * float(objectID & 0xFF), * float((objectID >> 8) & 0xFF), * float((objectID >> 16) & 0xFF), * float((objectID >> 24) & 0xFF)); */ // get vertexID from coded color. // the vertexID is the last vertex that constructs the primitive. // see http://www.cnblogs.com/bitzhuwei/p/modern-opengl-picking-primitive-in-VBO-2.html uint shiftedR = (uint)pixel.r; uint shiftedG = (uint)pixel.g << 8; uint shiftedB = (uint)pixel.b << 16; uint shiftedA = (uint)pixel.a << 24; var vertexId = shiftedR + shiftedG + shiftedB + shiftedA; if (!vertexIdList.Contains(vertexId)) { result.Add(new Tuple <Point, uint>( new Point(rect.X + xOffset, rect.Y + yOffset), vertexId)); vertexIdList.Add(vertexId); } } } } } return(result); }
/// <summary> /// Screen shot of OpenGL canvas. /// </summary> /// <param name="x">左下角坐标为(0, 0)</param> /// <param name="y">左下角坐标为(0, 0)</param> /// <param name="width">宽度</param> /// <param name="height">高度</param> public static Bitmap ScreenShot(int x, int y, int width, int height) { var format = System.Drawing.Imaging.PixelFormat.Format32bppArgb; var bitmap = new Bitmap(width, height, format); var bitmapRect = new Rectangle(0, 0, bitmap.Width, bitmap.Height); var lockMode = System.Drawing.Imaging.ImageLockMode.WriteOnly; System.Drawing.Imaging.BitmapData bmpData = bitmap.LockBits(bitmapRect, lockMode, format); OpenGL.ReadPixels(x, y, width, height, OpenGL.GL_BGRA, OpenGL.GL_UNSIGNED_BYTE, bmpData.Scan0); bitmap.UnlockBits(bmpData); bitmap.RotateFlip(RotateFlipType.Rotate180FlipX); return(bitmap); }
/// <summary> /// /// </summary> /// <param name="deviceContext"></param> public override void Blit(IntPtr deviceContext) { if (this.DeviceContextHandle != IntPtr.Zero) { // Set the read buffer. OpenGL.ReadBuffer(OpenGL.GL_COLOR_ATTACHMENT0); // Read the pixels into the DIB section. OpenGL.ReadPixels(0, 0, this.Width, this.Height, OpenGL.GL_BGRA, OpenGL.GL_UNSIGNED_BYTE, this.dibSection.Bits); // Blit the DC (containing the DIB section) to the target DC. Win32.BitBlt(deviceContext, 0, 0, this.Width, this.Height, this.dibSection.MemoryDeviceContext, 0, 0, Win32.SRCCOPY); } }
/// <summary> /// 把OpenGL渲染的内容保存到图片文件。 /// </summary> /// <param name="x">左下角坐标为(0, 0)</param> /// <param name="y">左下角坐标为(0, 0)</param> /// <param name="width">宽度</param> /// <param name="height">高度</param> /// <param name="filename"></param> public static void Save2Picture(int x, int y, int width, int height, string filename) { var format = System.Drawing.Imaging.PixelFormat.Format32bppArgb; using (var bitmap = new Bitmap(width, height, format)) { var bitmapRect = new Rectangle(0, 0, bitmap.Width, bitmap.Height); var lockMode = System.Drawing.Imaging.ImageLockMode.WriteOnly; System.Drawing.Imaging.BitmapData bmpData = bitmap.LockBits(bitmapRect, lockMode, format); OpenGL.ReadPixels(x, y, width, height, OpenGL.GL_BGRA, OpenGL.GL_UNSIGNED_BYTE, bmpData.Scan0); bitmap.UnlockBits(bmpData); bitmap.RotateFlip(RotateFlipType.Rotate180FlipX); bitmap.Save(filename); } }
/// <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. OpenGL.ReadPixels(x, y, 1, 1, OpenGL.GL_RGBA, OpenGL.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); }
public static unsafe uint ReadPixel( int x, int y, int canvasHeight) { uint stageVertexId = uint.MaxValue; // get coded color. using (var codedColor = new UnmanagedArray <byte>(4)) { OpenGL.ReadPixels(x, canvasHeight - y - 1, 1, 1, OpenGL.GL_RGBA, OpenGL.GL_UNSIGNED_BYTE, codedColor.Header); var array = (Pixel *)codedColor.Header.ToPointer(); Pixel pixel = array[0]; if (! // This is when (x, y) is on background and no primitive is picked. (pixel.r == byte.MaxValue && pixel.g == byte.MaxValue && pixel.b == byte.MaxValue && pixel.a == byte.MaxValue)) { /* // This is how is vertexID coded into color in vertex shader. * int objectID = gl_VertexID; * codedColor = vec4( * float(objectID & 0xFF), * float((objectID >> 8) & 0xFF), * float((objectID >> 16) & 0xFF), * float((objectID >> 24) & 0xFF)); */ // get vertexID from coded color. // the vertexID is the last vertex that constructs the primitive. // see http://www.cnblogs.com/bitzhuwei/p/modern-opengl-picking-primitive-in-VBO-2.html uint shiftedR = (uint)pixel.r; uint shiftedG = (uint)pixel.g << 8; uint shiftedB = (uint)pixel.b << 16; uint shiftedA = (uint)pixel.a << 24; stageVertexId = shiftedR + shiftedG + shiftedB + shiftedA; } } return(stageVertexId); }