コード例 #1
0
ファイル: RC.ReadPixels.cs プロジェクト: xinfushe/SoftGL
        private unsafe void ReadPixels(int x, int y, int width, int height, ReadPixelsFormat format, ReadPixelsType type, IntPtr data, IAttachable attachment)
        {
            byte[] dataStore = attachment.DataStore;
            //int srcBitSize = InternalFormatHelper.BitSize(attachment.Format);
            //int srcElementByteLength = (srcBitSize % 8 == 0) ? srcBitSize / 8 : srcBitSize / 8 + 1; // TODO: any better solution?
            int srcWidth = attachment.Width, srcHeight = attachment.Height;
            //int dstBitSize = InternalFormatHelper.BitSize((uint)format);
            //int dstElementByteLength = (dstBitSize % 8 == 0) ? dstBitSize / 8 : dstBitSize / 8 + 1; // TODO: any better solution?
            var array = (byte *)data.ToPointer();

            if (format == ReadPixelsFormat.BGRA && attachment.Format == GL.GL_RGBA)
            {
                var indexes = new int[4] {
                    2, 1, 0, 3
                };
                for (int i = 0; i < width; i++)
                {
                    for (int j = 0; j < height; j++)
                    {
                        for (int t = 0; t < 4; t++)
                        {
                            int dstT = (j * width + i) * 4 + t;
                            int srcT = ((j + y) * srcWidth + (i + x)) * 4 + indexes[t];
                            array[dstT] = dataStore[srcT];
                        }
                    }
                }
            }
            else if (format == ReadPixelsFormat.BGRA && attachment.Format == GL.GL_BGRA)
            {
                for (int i = 0; i < width; i++)
                {
                    for (int j = 0; j < height; j++)
                    {
                        for (int t = 0; t < 4; t++)
                        {
                            int dstT = (j * width + i) * 4 + t;
                            int srcT = ((j + y) * srcWidth + (i + x)) * 4 + t;
                            array[dstT] = dataStore[srcT];
                        }
                    }
                }
            }
            else // TODO; deal with all possibilities.
            {
                throw new NotImplementedException();
            }
        }
コード例 #2
0
ファイル: RC.ReadPixels.cs プロジェクト: xinfushe/SoftGL
        private unsafe void ReadPixels(int x, int y, int width, int height, ReadPixelsFormat format, ReadPixelsType type, IntPtr data)
        {
            Framebuffer framebuffer = this.currentFramebuffer;

            if (framebuffer == null)
            {
                throw new Exception("This should not happen!");
            }

            if (!Enum.IsDefined(typeof(ReadPixelsFormat), format))
            {
                SetLastError(ErrorCode.InvalidEnum); return;
            }
            if (!Enum.IsDefined(typeof(ReadPixelsType), type))
            {
                SetLastError(ErrorCode.InvalidEnum); return;
            }
            if (width < 0 || height < 0)
            {
                SetLastError(ErrorCode.InvalidValue); return;
            }
            if (format == ReadPixelsFormat.StencilIndex && framebuffer.StencilbufferAttachment == null)
            {
                SetLastError(ErrorCode.InvalidOperation); return;
            }
            if (format == ReadPixelsFormat.DepthComponent && framebuffer.DepthbufferAttachment == null)
            {
                SetLastError(ErrorCode.InvalidOperation); return;
            }
            if (format == ReadPixelsFormat.DepthStencil && (framebuffer.DepthbufferAttachment == null || framebuffer.StencilbufferAttachment == null))
            {
                SetLastError(ErrorCode.InvalidOperation); return;
            }
            if (format == ReadPixelsFormat.DepthStencil &&
                (type != ReadPixelsType.UnsignedInt248 && type != ReadPixelsType.Float32UnsignedInt248Rev))
            {
                SetLastError(ErrorCode.InvalidEnum); return;
            }
            if (format != ReadPixelsFormat.RGB &&
                (type == ReadPixelsType.UnsignedByte332 || type == ReadPixelsType.UnsignedByte233Rev || type == ReadPixelsType.UnsignedShort565 || type == ReadPixelsType.UnsignedShort565Rev))
            {
                SetLastError(ErrorCode.InvalidOperation); return;
            }
            if ((format != ReadPixelsFormat.RGBA && format != ReadPixelsFormat.BGRA) &&
                (type == ReadPixelsType.UnsignedShort4444 || type == ReadPixelsType.UnsignedShort4444Rev || type == ReadPixelsType.UnsignedShort5551 || type == ReadPixelsType.UnsignedShort1555Rev || type == ReadPixelsType.UnsignedInt8888 || type == ReadPixelsType.UnsignedInt8888Rev || type == ReadPixelsType.UnsignedInt1010102 || type == ReadPixelsType.UnsignedInt2101010Rev))
            {
                SetLastError(ErrorCode.InvalidOperation); return;
            }
            // TODO: GL_INVALID_OPERATION is generated if a non-zero buffer object name is bound to the GL_PIXEL_PACK_BUFFER target and the buffer object's data store is currently mapped.
            // TODO: GL_INVALID_OPERATION is generated if a non-zero buffer object name is bound to the GL_PIXEL_PACK_BUFFER target and the data would be packed to the buffer object such that the memory writes required would exceed the data store size.
            // TODO: GL_INVALID_OPERATION is generated if a non-zero buffer object name is bound to the GL_PIXEL_PACK_BUFFER target and data​ is not evenly divisible into the number of bytes needed to store in memory a datum indicated by type.
            // TODO: GL_INVALID_OPERATION is generated if GL_READ_FRAMEBUFFER_BINDING is non-zero, the read framebuffer is complete, and the value of GL_SAMPLE_BUFFERS for the read framebuffer is greater than zero.

            IAttachable attachment = null;

            if (format == ReadPixelsFormat.DepthComponent)
            {
                attachment = framebuffer.DepthbufferAttachment;
            }
            else if (format == ReadPixelsFormat.StencilIndex)
            {
                attachment = framebuffer.StencilbufferAttachment;
            }
            else if (format == ReadPixelsFormat.DepthStencil)
            {
                attachment = framebuffer.DepthbufferAttachment;
            }
            else
            {
                IList <uint> drawBuffers = framebuffer.DrawBuffers;
                if (drawBuffers.Count > 0)
                {
                    uint index = drawBuffers[0].ToIndex();
                    attachment = framebuffer.ColorbufferAttachments[index];
                }
            }
            // copy data from attachment to "data".
            if (attachment != null)
            {
                ReadPixels(x, y, width, height, format, type, data, attachment);
            }
        }
コード例 #3
0
        /// <summary>
        /// Reads pixels from this <see cref="FramebufferObject"/>.
        /// </summary>
        /// <typeparam name="T">A struct with the same format as a pixel to read.</typeparam>
        /// <param name="data">The span to which the data will be written.</param>
        /// <param name="x">The X coordinate of the first pixel to read.</param>
        /// <param name="y">The (invertex) Y coordinate of the first pixel to read.</param>
        /// <param name="width">The width of the rectangle of pixels to read.</param>
        /// <param name="height">The height of the rectangle of pixels to read.</param>
        /// <param name="pixelFormat">The format the pixel data will be read as.</param>
        /// <param name="pixelType">The format the pixel data is stored as.</param>
        public unsafe void ReadPixels <T>(Span <T> data, int x, int y, uint width, uint height, ReadPixelsFormat pixelFormat = ReadPixelsFormat.Rgba, PixelType pixelType = PixelType.UnsignedByte) where T : unmanaged
        {
            if (data.Length < (width - x) * (height - y))
            {
                throw new ArgumentException(nameof(data) + " must be able to hold the requested pixel data", nameof(data));

                fixed(void *ptr = data)
                ReadPixelsPtr(ptr, x, y, width, height, pixelFormat, pixelType);
        }
コード例 #4
0
        /// <summary>
        /// Reads pixels from this <see cref="FramebufferObject"/>.
        /// </summary>
        /// <param name="ptr">The pointer to which the pixel data will be written.</param>
        /// <param name="x">The X coordinate of the first pixel to read.</param>
        /// <param name="y">The (invertex) Y coordinate of the first pixel to read.</param>
        /// <param name="width">The width of the rectangle of pixels to read.</param>
        /// <param name="height">The height of the rectangle of pixels to read.</param>
        /// <param name="pixelFormat">The format the pixel data will be read as.</param>
        /// <param name="pixelType">The format the pixel data is stored as.</param>
        public unsafe void ReadPixelsPtr(void *ptr, int x, int y, uint width, uint height, ReadPixelsFormat pixelFormat = ReadPixelsFormat.Rgba, PixelType pixelType = PixelType.UnsignedByte)
        {
            if (x < 0)
            {
                throw new ArgumentException(nameof(x) + " must be greater than or equal to 0", nameof(x));
            }

            if (y < 0)
            {
                throw new ArgumentException(nameof(y) + " must be greater than or equal to 0", nameof(y));
            }

            if (width <= 0 || width > Width)
            {
                throw new ArgumentOutOfRangeException(nameof(width), width, nameof(width) + " must be in the range (0, " + nameof(Width) + "]");
            }

            if (height <= 0 || height > Height)
            {
                throw new ArgumentOutOfRangeException(nameof(height), height, nameof(height) + " must be in the range (0, " + nameof(Height) + "]");
            }

            if (x + width > Width || y + height > Height)
            {
                throw new ArgumentException("Tried to read outside the " + nameof(FramebufferObject) + "'s image");
            }

            if (pixelFormat == ReadPixelsFormat.DepthStencil && pixelType != (PixelType)GLEnum.UnsignedInt248)
            {
                throw new ArgumentException("When reading depth-stencil, " + nameof(pixelType) + " must be UnsignedInt248", nameof(pixelType));
            }

            GraphicsDevice.ReadFramebuffer = this;
            GL.ReadPixels(x, y, width, height, (PixelFormat)pixelFormat, pixelType, ptr);
        }