Example #1
0
        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);
            }
        }
Example #2
0
        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();
            }
        }