Beispiel #1
0
        internal int GetPitch(int width)
        {
            Debug.Assert(width > 0, "The width is negative!");

            int pitch;

            switch (_format)
            {
            case SurfaceFormat.Dxt1:
            case SurfaceFormat.Dxt1SRgb:
            case SurfaceFormat.Dxt1a:
            case SurfaceFormat.RgbPvrtc2Bpp:
            case SurfaceFormat.RgbaPvrtc2Bpp:
            case SurfaceFormat.RgbEtc1:
            case SurfaceFormat.Dxt3:
            case SurfaceFormat.Dxt3SRgb:
            case SurfaceFormat.Dxt5:
            case SurfaceFormat.Dxt5SRgb:
            case SurfaceFormat.RgbPvrtc4Bpp:
            case SurfaceFormat.RgbaPvrtc4Bpp:
                pitch = ((width + 3) / 4) * _format.GetSize();
                break;

            default:
                pitch = width * _format.GetSize();
                break;
            }
            ;

            return(pitch);
        }
        private static int GetBitmapSize(SurfaceFormat format, int width, int height)
        {
            // It is recommended that the dwPitchOrLinearSize field is ignored and we calculate it ourselves
            // https://msdn.microsoft.com/en-us/library/bb943991.aspx

            int pitch;
            int rows;

            switch (format)
            {
            case SurfaceFormat.Rgba32:
            case SurfaceFormat.Bgra4444:
            case SurfaceFormat.Bgra5551:
            case SurfaceFormat.Bgr565:
            case SurfaceFormat.Vector4:
                pitch = width * format.GetSize();
                rows  = height;
                break;

            case SurfaceFormat.Dxt1:
            case SurfaceFormat.Dxt3:
            case SurfaceFormat.Dxt5:
                pitch = (width + 3) / 4 * format.GetSize();
                rows  = (height + 3) / 4;
                break;

            default:
                throw new ContentLoadException("Unsupported SurfaceFormat " + format);
            }

            return(pitch * rows);
        }
Beispiel #3
0
        public TextureCube(int size, bool mipMap, SurfaceFormat format)
        {
            ID     = GL.GenTexture();
            Size   = size;
            Format = format;
            Format.GetGLFormat(out glInternalFormat, out glFormat, out glType);
            LevelCount = mipMap ? CalculateMipLevels(size, size) : 1;

            //Bind the new TextureCube
            BindTo(4);
            //enable filtering
            GL.TexParameteri(GL.GL_TEXTURE_CUBE_MAP, GL.GL_TEXTURE_MIN_FILTER, GL.GL_LINEAR);
            GL.TexParameteri(GL.GL_TEXTURE_CUBE_MAP, GL.GL_TEXTURE_MAG_FILTER, GL.GL_LINEAR);
            //initialise
            if (glFormat == GL.GL_NUM_COMPRESSED_TEXTURE_FORMATS)
            {
                int imageSize = 0;
                if (GLExtensions.S3TC)
                {
                    switch (Format)
                    {
                    case SurfaceFormat.Dxt1:
                    case SurfaceFormat.Dxt3:
                    case SurfaceFormat.Dxt5:
                        imageSize = ((size + 3) / 4) * ((size + 3) / 4) * format.GetSize();
                        break;

                    default:
                        throw new NotSupportedException();
                    }
                }

                for (int i = 0; i < 6; i++)
                {
                    var target = ((CubeMapFace)i).ToGL();
                    if (GLExtensions.S3TC)
                    {
                        GL.CompressedTexImage2D(target, 0, glInternalFormat,
                                                size, size, 0,
                                                imageSize, IntPtr.Zero);
                    }
                    else
                    {
                        GL.TexImage2D(target, 0,
                                      GL.GL_RGBA,
                                      size, size, 0,
                                      GL.GL_BGRA, GL.GL_UNSIGNED_BYTE, IntPtr.Zero);
                    }
                }
            }
            else
            {
                for (int i = 0; i < 6; i++)
                {
                    var target = ((CubeMapFace)i).ToGL();
                    GL.TexImage2D(target, 0, glInternalFormat,
                                  size, size, 0, glFormat, glType, IntPtr.Zero);
                }
            }
        }
Beispiel #4
0
        private void PlatformConstruct(int width, int height, bool mipmap, SurfaceFormat format, SurfaceType type, bool shared)
        {
            this.glTarget = TextureTarget.Texture2D;
            format.GetGLFormat(GraphicsDevice, out glInternalFormat, out glFormat, out glType);
            Threading.BlockOnUIThread(() =>
            {
                GenerateGLTextureIfRequired();
                int w     = width;
                int h     = height;
                int level = 0;
                while (true)
                {
                    if (glFormat == (PixelFormat)GLPixelFormat.CompressedTextureFormats)
                    {
                        int imageSize = 0;
                        // PVRTC has explicit calculations for imageSize
                        // https://www.khronos.org/registry/OpenGL/extensions/IMG/IMG_texture_compression_pvrtc.txt
                        if (format == SurfaceFormat.RgbPvrtc2Bpp || format == SurfaceFormat.RgbaPvrtc2Bpp)
                        {
                            imageSize = (Math.Max(w, 16) * Math.Max(h, 8) * 2 + 7) / 8;
                        }
                        else if (format == SurfaceFormat.RgbPvrtc4Bpp || format == SurfaceFormat.RgbaPvrtc4Bpp)
                        {
                            imageSize = (Math.Max(w, 8) * Math.Max(h, 8) * 4 + 7) / 8;
                        }
                        else
                        {
                            int blockSize = format.GetSize();
                            int blockWidth, blockHeight;
                            format.GetBlockSize(out blockWidth, out blockHeight);
                            int wBlocks = (w + (blockWidth - 1)) / blockWidth;
                            int hBlocks = (h + (blockHeight - 1)) / blockHeight;
                            imageSize   = wBlocks * hBlocks * blockSize;
                        }
                        GL.CompressedTexImage2D(TextureTarget.Texture2D, level, glInternalFormat, w, h, 0, imageSize, IntPtr.Zero);
                        GraphicsExtensions.CheckGLError();
                    }
                    else
                    {
                        GL.TexImage2D(TextureTarget.Texture2D, level, glInternalFormat, w, h, 0, glFormat, glType, IntPtr.Zero);
                        GraphicsExtensions.CheckGLError();
                    }

                    if ((w == 1 && h == 1) || !mipmap)
                    {
                        break;
                    }
                    if (w > 1)
                    {
                        w = w / 2;
                    }
                    if (h > 1)
                    {
                        h = h / 2;
                    }
                    ++level;
                }
            });
        }
        public override byte[] GetPixelData()
        {
            var formatSize = _format.GetSize();
            var dataSize   = Width * Height * formatSize;
            var outputData = new byte[dataSize];

            for (var x = 0; x < Height; x++)
            {
                var dataHandle = GCHandle.Alloc(_pixelData[x], GCHandleType.Pinned);
                var dataPtr    = (IntPtr)(dataHandle.AddrOfPinnedObject().ToInt64());

                Marshal.Copy(dataPtr, outputData, (formatSize * x * Width), (Width * formatSize));

                dataHandle.Free();
            }

            return(outputData);
        }
        private void PlatformConstruct(int width, int height, bool mipmap, SurfaceFormat format, SurfaceType type, bool shared)
        {
            this.glTarget = gl.TEXTURE_2D;
            format.GetGLFormat(GraphicsDevice, out glInternalFormat, out glFormat, out glType);

            GenerateGLTextureIfRequired();
            int w     = width;
            int h     = height;
            int level = 0;

            while (true)
            {
                if (glFormat == gl.COMPRESSED_TEXTURE_FORMATS)
                {
                    int imageSize = 0;
                    // PVRTC has explicit calculations for imageSize
                    // https://www.khronos.org/registry/OpenGL/extensions/IMG/IMG_texture_compression_pvrtc.txt
                    if (format == SurfaceFormat.RgbPvrtc2Bpp || format == SurfaceFormat.RgbaPvrtc2Bpp)
                    {
                        imageSize = (Math.Max(w, 16) * Math.Max(h, 8) * 2 + 7) / 8;
                    }
                    else if (format == SurfaceFormat.RgbPvrtc4Bpp || format == SurfaceFormat.RgbaPvrtc4Bpp)
                    {
                        imageSize = (Math.Max(w, 8) * Math.Max(h, 8) * 4 + 7) / 8;
                    }
                    else
                    {
                        int blockSize = format.GetSize();
                        int blockWidth, blockHeight;
                        format.GetBlockSize(out blockWidth, out blockHeight);
                        int wBlocks = (w + (blockWidth - 1)) / blockWidth;
                        int hBlocks = (h + (blockHeight - 1)) / blockHeight;
                        imageSize = wBlocks * hBlocks * blockSize;
                    }
                }

                gl.texImage2D(gl.TEXTURE_2D, level, glInternalFormat, glFormat, glType, (new ImageData(w, h).As <ImageBitmap>()));
                GraphicsExtensions.CheckGLError();

                if ((w == 1 && h == 1) || !mipmap)
                {
                    break;
                }
                if (w > 1)
                {
                    w = w / 2;
                }
                if (h > 1)
                {
                    h = h / 2;
                }
                ++level;
            }
        }
        public PixelBitmapContent(int width, int height)
        {
            if (!TryGetFormat(out _format))
            {
                throw new InvalidOperationException($"Color format \"{typeof(TPixel)}\" is not supported");
            }

            Height     = height;
            Width      = width;
            _pixelData = new byte[Width * Height * _format.GetSize()];
        }
Beispiel #8
0
        public Texture2D(int width, int height, bool hasMipMaps, SurfaceFormat format) : this(true)
        {
            Width  = width;
            Height = height;
            Format = format;
            Format.GetGLFormat(out glInternalFormat, out glFormat, out glType);
            LevelCount    = hasMipMaps ? CalculateMipLevels(width, height) : 1;
            currentLevels = hasMipMaps ? (LevelCount - 1) : 0;
            //Bind the new TextureD
            GLBind.Trash();
            GLBind.BindTexture(4, GL.GL_TEXTURE_2D, ID);
            //initialise the texture data
            var imageSize = 0;
            Dxt1 = format == SurfaceFormat.Dxt1;
            if (glFormat == GL.GL_NUM_COMPRESSED_TEXTURE_FORMATS)
            {
                if (GLExtensions.S3TC)
                {
                    switch (Format)
                    {
                    case SurfaceFormat.Dxt1:
                    case SurfaceFormat.Dxt3:
                    case SurfaceFormat.Dxt5:
                        imageSize = ((Width + 3) / 4) * ((Height + 3) / 4) * format.GetSize();
                        break;

                    default:
                        throw new NotSupportedException();
                    }
                    GL.CompressedTexImage2D(GL.GL_TEXTURE_2D, 0, glInternalFormat,
                                            Width, Height, 0,
                                            imageSize, IntPtr.Zero);
                }
                else
                {
                    GL.TexImage2D(GL.GL_TEXTURE_2D, 0,
                                  GL.GL_RGBA,
                                  Width, Height, 0,
                                  GL.GL_BGRA, GL.GL_UNSIGNED_BYTE, IntPtr.Zero);
                }
            }
            else
            {
                GL.TexImage2D(GL.GL_TEXTURE_2D, 0,
                              glInternalFormat,
                              Width, Height, 0,
                              glFormat, glType, IntPtr.Zero);
            }
            //enable filtering
            GL.TexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_MIN_FILTER, GL.GL_LINEAR);
            GL.TexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_MAG_FILTER, GL.GL_LINEAR);
        }
Beispiel #9
0
        private void PlatformConstruct(GraphicsDevice graphicsDevice, int size, bool mipMap, SurfaceFormat format, bool renderTarget)
        {
            this.glTarget = TextureTarget.TextureCubeMap;

            Threading.BlockOnUIThread(() =>
            {
                GL.GenTextures(1, out this.glTexture);
                GraphicsExtensions.CheckGLError();
                GL.BindTexture(TextureTarget.TextureCubeMap, this.glTexture);
                GraphicsExtensions.CheckGLError();
                GL.TexParameter(TextureTarget.TextureCubeMap, TextureParameterName.TextureMinFilter,
                                mipMap ? (int)TextureMinFilter.LinearMipmapLinear : (int)TextureMinFilter.Linear);
                GraphicsExtensions.CheckGLError();
                GL.TexParameter(TextureTarget.TextureCubeMap, TextureParameterName.TextureMagFilter,
                                (int)TextureMagFilter.Linear);
                GraphicsExtensions.CheckGLError();
                GL.TexParameter(TextureTarget.TextureCubeMap, TextureParameterName.TextureWrapS,
                                (int)TextureWrapMode.ClampToEdge);
                GraphicsExtensions.CheckGLError();
                GL.TexParameter(TextureTarget.TextureCubeMap, TextureParameterName.TextureWrapT,
                                (int)TextureWrapMode.ClampToEdge);
                GraphicsExtensions.CheckGLError();


                format.GetGLFormat(GraphicsDevice, out glInternalFormat, out glFormat, out glType);

                for (var i = 0; i < 6; i++)
                {
                    var target = GetGLCubeFace((CubeMapFace)i);

                    if (glFormat == (PixelFormat)GLPixelFormat.CompressedTextureFormats)
                    {
                        var imageSize = 0;
                        switch (format)
                        {
                        case SurfaceFormat.RgbPvrtc2Bpp:
                        case SurfaceFormat.RgbaPvrtc2Bpp:
                            imageSize = (Math.Max(size, 16) * Math.Max(size, 8) * 2 + 7) / 8;
                            break;

                        case SurfaceFormat.RgbPvrtc4Bpp:
                        case SurfaceFormat.RgbaPvrtc4Bpp:
                            imageSize = (Math.Max(size, 8) * Math.Max(size, 8) * 4 + 7) / 8;
                            break;

                        case SurfaceFormat.Dxt1:
                        case SurfaceFormat.Dxt1a:
                        case SurfaceFormat.Dxt1SRgb:
                        case SurfaceFormat.Dxt3:
                        case SurfaceFormat.Dxt3SRgb:
                        case SurfaceFormat.Dxt5:
                        case SurfaceFormat.Dxt5SRgb:
                        case SurfaceFormat.RgbEtc1:
                        case SurfaceFormat.RgbaAtcExplicitAlpha:
                        case SurfaceFormat.RgbaAtcInterpolatedAlpha:
                            imageSize = (size + 3) / 4 * ((size + 3) / 4) * format.GetSize();
                            break;

                        default:
                            throw new NotSupportedException();
                        }
                        GL.CompressedTexImage2D(target, 0, glInternalFormat, size, size, 0, imageSize, IntPtr.Zero);
                        GraphicsExtensions.CheckGLError();
                    }
                    else
                    {
                        GL.TexImage2D(target, 0, glInternalFormat, size, size, 0, glFormat, glType, IntPtr.Zero);
                        GraphicsExtensions.CheckGLError();
                    }
                }

                if (mipMap)
                {
#if IOS || ANDROID
                    GL.GenerateMipmap(TextureTarget.TextureCubeMap);
#else
                    GraphicsDevice.FramebufferHelper.Get().GenerateMipmap((int)glTarget);
                    // This updates the mipmaps after a change in the base texture
                    GL.TexParameter(TextureTarget.TextureCubeMap, TextureParameterName.GenerateMipmap, (int)Bool.True);
#endif
                    GraphicsExtensions.CheckGLError();
                }
            });
        }
Beispiel #10
0
        private void PlatformConstruct(GraphicsDevice graphicsDevice, int size, bool mipMap, SurfaceFormat format, bool renderTarget)
        {
            this.glTarget = gl.TEXTURE_CUBE_MAP;

            this.glTexture = gl.createTexture();
            GraphicsExtensions.CheckGLError();
            gl.bindTexture(gl.TEXTURE_CUBE_MAP, this.glTexture);
            GraphicsExtensions.CheckGLError();
            gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_MIN_FILTER, mipMap ? gl.LINEAR_MIPMAP_LINEAR : gl.LINEAR);
            GraphicsExtensions.CheckGLError();
            gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
            GraphicsExtensions.CheckGLError();
            gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
            GraphicsExtensions.CheckGLError();
            gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
            GraphicsExtensions.CheckGLError();


            format.GetGLFormat(GraphicsDevice, out glInternalFormat, out glFormat, out glType);

            for (var i = 0; i < 6; i++)
            {
                var target = GetGLCubeFace((CubeMapFace)i);

                if (glFormat == gl.COMPRESSED_TEXTURE_FORMATS)
                {
                    var imageSize = 0;
                    switch (format)
                    {
                    case SurfaceFormat.RgbPvrtc2Bpp:
                    case SurfaceFormat.RgbaPvrtc2Bpp:
                        imageSize = (Math.Max(size, 16) * Math.Max(size, 8) * 2 + 7) / 8;
                        break;

                    case SurfaceFormat.RgbPvrtc4Bpp:
                    case SurfaceFormat.RgbaPvrtc4Bpp:
                        imageSize = (Math.Max(size, 8) * Math.Max(size, 8) * 4 + 7) / 8;
                        break;

                    case SurfaceFormat.Dxt1:
                    case SurfaceFormat.Dxt1a:
                    case SurfaceFormat.Dxt1SRgb:
                    case SurfaceFormat.Dxt3:
                    case SurfaceFormat.Dxt3SRgb:
                    case SurfaceFormat.Dxt5:
                    case SurfaceFormat.Dxt5SRgb:
                    case SurfaceFormat.RgbEtc1:
                    case SurfaceFormat.RgbaAtcExplicitAlpha:
                    case SurfaceFormat.RgbaAtcInterpolatedAlpha:
                        imageSize = (size + 3) / 4 * ((size + 3) / 4) * format.GetSize();
                        break;

                    default:
                        throw new NotSupportedException();
                    }
                    gl.compressedTexImage2D(target, 0, glInternalFormat, size, size, 0, new Int8Array(0));
                    GraphicsExtensions.CheckGLError();
                }
                else
                {
                    gl.texImage2D(target, 0, glInternalFormat, size, size, 0, glFormat, glType, new Int8Array(0).As <ArrayBufferView>());
                    GraphicsExtensions.CheckGLError();
                }
            }

            if (mipMap)
            {
                gl.generateMipmap(gl.TEXTURE_CUBE_MAP);
                GraphicsExtensions.CheckGLError();
            }
        }
Beispiel #11
0
        private void PlatformConstruct(
            int width, int height, bool mipmap, SurfaceFormat format, SurfaceType type, bool shared)
        {
            _glTarget = TextureTarget.Texture2D;
            format.GetGLFormat(GraphicsDevice, out _glInternalFormat, out _glFormat, out _glType);

            GenerateGLTextureIfRequired();
            int level = 0;

            while (true)
            {
                if (_glFormat == GLPixelFormat.CompressedTextureFormats)
                {
                    // PVRTC has explicit calculations for imageSize
                    // https://www.khronos.org/registry/OpenGL/extensions/IMG/IMG_texture_compression_pvrtc.txt

                    int imageSize;
                    switch (format)
                    {
                    case SurfaceFormat.RgbPvrtc2Bpp:
                    case SurfaceFormat.RgbaPvrtc2Bpp:
                        imageSize = (Math.Max(width, 16) * Math.Max(height, 8) * 2 + 7) / 8;
                        break;

                    case SurfaceFormat.RgbPvrtc4Bpp:
                    case SurfaceFormat.RgbaPvrtc4Bpp:
                        imageSize = (Math.Max(width, 8) * Math.Max(height, 8) * 4 + 7) / 8;
                        break;

                    default:
                    {
                        format.GetBlockSize(out int blockWidth, out int blockHeight);
                        int wBlocks = (width + (blockWidth - 1)) / blockWidth;
                        int hBlocks = (height + (blockHeight - 1)) / blockHeight;
                        imageSize = wBlocks * hBlocks * format.GetSize();
                        break;
                    }
                    }

                    GL.CompressedTexImage2D(
                        TextureTarget.Texture2D, level, _glInternalFormat, width, height, 0, imageSize, IntPtr.Zero);
                    GL.CheckError();
                }
                else
                {
                    GL.TexImage2D(
                        TextureTarget.Texture2D, level, _glInternalFormat, width, height, 0, _glFormat, _glType, IntPtr.Zero);
                    GL.CheckError();
                }

                if ((width == 1 && height == 1) || !mipmap)
                {
                    break;
                }

                if (width > 1)
                {
                    width /= 2;
                }
                if (height > 1)
                {
                    height /= 2;
                }
                level++;
            }
        }