Beispiel #1
0
        /// <summary>
        /// Create texture from pixel array
        /// </summary>
        public void LoadImage(Color4[] pixels, int width, int height)
        {
            IsStubTexture = false;

            reloader = new TexturePixelArrayReloader(pixels, width, height);

            MemoryUsed  = 4 * width * height;
            ImageSize   = new Size(width, height);
            SurfaceSize = ImageSize;
            uvRect      = new Rectangle(0, 0, 1, 1);

            Window.Current.InvokeOnRendering(() => {
                var pinnedArray = GCHandle.Alloc(pixels, GCHandleType.Pinned);
                var pointer     = pinnedArray.AddrOfPinnedObject();

                PrepareOpenGLTexture();
                GL.ActiveTexture(TextureUnit.Texture0);
                GL.BindTexture(TextureTarget.Texture2D, handle);
                GL.TexImage2D(TextureTarget.Texture2D, 0, PixelInternalFormat.Rgba, width, height, 0, PixelFormat.Rgba, PixelType.UnsignedByte, pointer);
                PlatformRenderer.MarkTextureSlotAsDirty(0);
                PlatformRenderer.CheckErrors();

                pinnedArray.Free();
            });
        }
Beispiel #2
0
        private void ReadCompressedImage(ref Action glCommands, BinaryReader reader, int level, int width, int height, int linearSize, UInt32 pfFourCC)
        {
            var pif = (PixelInternalFormat)All.CompressedRgbS3tcDxt1Ext;

            switch ((DDSFourCC)pfFourCC)
            {
            case DDSFourCC.DXT1:
                pif = (PixelInternalFormat)All.CompressedRgbS3tcDxt1Ext;
                break;

            case DDSFourCC.DXT3:
                pif = (PixelInternalFormat)All.CompressedRgbaS3tcDxt3Ext;
                break;

            case DDSFourCC.DXT5:
                pif = (PixelInternalFormat)All.CompressedRgbaS3tcDxt5Ext;
                break;

            default:
                throw new InvalidDataException("Unsupported texture format");
            }
            var buffer = ReadTextureData(reader, linearSize);

            glCommands += () => {
                PlatformRenderer.PushTexture(handle, 0);
                GL.CompressedTexImage2D(TextureTarget.Texture2D, level, pif, width, height, 0, buffer.Length, buffer);
                PlatformRenderer.PopTexture(0);
                PlatformRenderer.CheckErrors();
            };
        }
Beispiel #3
0
 private unsafe void SyncIntVector2(int location, ShaderParam <IntVector2> param)
 {
     fixed(IntVector2 *dataPtr = param.Data)
     {
         GL.Uniform2(location, param.Count, (int *)dataPtr);
         PlatformRenderer.CheckErrors();
     }
 }
Beispiel #4
0
 private unsafe void SyncInt(int location, ShaderParam <int> param)
 {
     fixed(int *dataPtr = param.Data)
     {
         GL.Uniform1(location, param.Count, dataPtr);
         PlatformRenderer.CheckErrors();
     }
 }
Beispiel #5
0
 private unsafe void SyncFloatMatrix4x4(int location, ShaderParam <Matrix44> param)
 {
     fixed(Matrix44 *dataPtr = param.Data)
     {
         GL.UniformMatrix4(location, param.Count, false, (float *)dataPtr);
         PlatformRenderer.CheckErrors();
     }
 }
Beispiel #6
0
 private unsafe void SyncFloatVector4(int location, ShaderParam <Vector4> param)
 {
     fixed(Vector4 *dataPtr = param.Data)
     {
         GL.Uniform4(location, param.Count, (float *)dataPtr);
         PlatformRenderer.CheckErrors();
     }
 }
Beispiel #7
0
        public void SetData <T>(T[] data, int elementCount) where T : struct
        {
            CreateIfRequired();
            var elementSize = Toolbox.SizeOf <T>();
            var usageHint   = Dynamic ? BufferUsageHint.DynamicDraw : BufferUsageHint.StaticDraw;

            GL.BindBuffer(target, handle);
            PlatformRenderer.CheckErrors();
            GL.BufferData(target, new IntPtr(elementSize * elementCount), data, usageHint);
            PlatformRenderer.CheckErrors();
        }
Beispiel #8
0
 /// <summary>
 /// Load subtexture from pixel array
 /// Warning: this method doesn't support automatic texture reload after restoring graphics context
 /// </summary>
 public void LoadSubImage(Color4[] pixels, int x, int y, int width, int height)
 {
     Application.InvokeOnMainThread(() => {
         PrepareOpenGLTexture();
         PlatformRenderer.PushTexture(handle, 0);
         GL.TexSubImage2D(TextureTarget.Texture2D, 0, x, y, width, height,
                          PixelFormat.Rgba, PixelType.UnsignedByte, pixels);
         PlatformRenderer.CheckErrors();
         PlatformRenderer.PopTexture(0);
     });
 }
Beispiel #9
0
        private void CreateTexture()
        {
            if (IsDisposed)
            {
                throw new ObjectDisposedException(GetType().Name);
            }
            var t = new uint[1];

            GL.GenFramebuffers(1, t);
            framebuffer = t[0];
            GL.GenTextures(1, t);
            handle = t[0];
            GL.ActiveTexture(TextureUnit.Texture0);
            GL.BindTexture(TextureTarget.Texture2D, handle);
            GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMinFilter, textureParams.MinFilter.ToInt());
            GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMagFilter, textureParams.MagFilter.ToInt());
            GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapS, textureParams.WrapModeU.ToInt());
            GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapT, textureParams.WrapModeV.ToInt());
            int bpp;

            if (Format == RenderTextureFormat.RGBA8)
            {
                GL.TexImage2D(TextureTarget.Texture2D, 0, PixelInternalFormat.Rgba, size.Width, size.Height, 0, PixelFormat.Rgba, PixelType.UnsignedByte, (IntPtr)null);
                bpp = 4;
            }
            else
            {
                GL.TexImage2D(TextureTarget.Texture2D, 0, PixelInternalFormat.Rgb, size.Width, size.Height, 0, PixelFormat.Rgb, PixelType.UnsignedShort565, (IntPtr)null);
                bpp = 2;
            }
            MemoryUsed = SurfaceSize.Width * SurfaceSize.Height * bpp;
            uint oldFramebuffer = PlatformRenderer.CurrentFramebuffer;

            PlatformRenderer.BindFramebuffer(framebuffer);
            PlatformRenderer.CheckErrors();
            GL.FramebufferTexture2D(
                FramebufferTarget.Framebuffer,
                FramebufferSlot.ColorAttachment0,
                TextureTarget.Texture2D,
                handle,
                level: 0);
            if ((int)GL.CheckFramebufferStatus(FramebufferTarget.Framebuffer) != (int)FramebufferErrorCode.FramebufferComplete)
            {
                throw new Exception("Failed to create render texture. Framebuffer is incomplete.");
            }
            AttachRenderBuffer(FramebufferSlot.DepthAttachment, RenderbufferInternalFormat.DepthComponent16, out depthBuffer);
            Renderer.Clear(Color4.Black);
            PlatformRenderer.MarkTextureSlotAsDirty(0);
            PlatformRenderer.BindFramebuffer(oldFramebuffer);
            PlatformRenderer.CheckErrors();
        }
Beispiel #10
0
 private void CreateIfRequired()
 {
     if (IsDisposed)
     {
         throw new ObjectDisposedException(GetType().Name);
     }
     if (handle == 0)
     {
         var handles = new uint[1];
         GL.GenBuffers(1, handles);
         PlatformRenderer.CheckErrors();
         handle = handles[0];
     }
 }
Beispiel #11
0
        private void CreateTexture()
        {
            if (!Application.CurrentThread.IsMain())
            {
                throw new Lime.Exception("Attempt to create a RenderTexture not from the main thread");
            }
            var t = new uint[1];

            GL.GenFramebuffers(1, t);
            framebuffer = t[0];
            GL.GenTextures(1, t);
            handle = t[0];
            PlatformRenderer.PushTexture(handle, 0);
            GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMinFilter, textureParams.MinFilter.ToInt());
            GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMagFilter, textureParams.MagFilter.ToInt());
            GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapS, textureParams.WrapModeU.ToInt());
            GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapT, textureParams.WrapModeV.ToInt());
            int bpp;

            if (Format == RenderTextureFormat.RGBA8)
            {
                GL.TexImage2D(TextureTarget.Texture2D, 0, PixelInternalFormat.Rgba, size.Width, size.Height, 0, PixelFormat.Rgba, PixelType.UnsignedByte, (IntPtr)null);
                bpp = 4;
            }
            else
            {
                GL.TexImage2D(TextureTarget.Texture2D, 0, PixelInternalFormat.Rgb, size.Width, size.Height, 0, PixelFormat.Rgb, PixelType.UnsignedShort565, (IntPtr)null);
                bpp = 2;
            }
            MemoryUsed = SurfaceSize.Width * SurfaceSize.Height * bpp;
            uint oldFramebuffer = PlatformRenderer.CurrentFramebuffer;

            PlatformRenderer.BindFramebuffer(framebuffer);
            PlatformRenderer.CheckErrors();
            GL.FramebufferTexture2D(
                FramebufferTarget.Framebuffer,
                FramebufferSlot.ColorAttachment0,
                TextureTarget.Texture2D,
                handle,
                level: 0);
            if ((int)GL.CheckFramebufferStatus(FramebufferTarget.Framebuffer) != (int)FramebufferErrorCode.FramebufferComplete)
            {
                throw new Exception("Failed to create render texture. Framebuffer is incomplete.");
            }
            AttachRenderBuffer(FramebufferSlot.DepthAttachment, RenderbufferInternalFormat.DepthComponent16, out depthBuffer);
            Renderer.Clear(0, 0, 0, 0);
            PlatformRenderer.PopTexture(0);
            PlatformRenderer.BindFramebuffer(oldFramebuffer);
            PlatformRenderer.CheckErrors();
        }
Beispiel #12
0
        /// <summary>
        /// Load subtexture from pixel array
        /// Warning: this method doesn't support automatic texture reload after restoring graphics context
        /// </summary>
        public void LoadSubImage(Color4[] pixels, int x, int y, int width, int height)
        {
            IsStubTexture = false;

            Window.Current.InvokeOnRendering(() => {
                PrepareOpenGLTexture();
                GL.ActiveTexture(TextureUnit.Texture0);
                GL.BindTexture(TextureTarget.Texture2D, handle);
                GL.TexSubImage2D(TextureTarget.Texture2D, 0, x, y, width, height,
                                 PixelFormat.Rgba, PixelType.UnsignedByte, pixels);
                PlatformRenderer.CheckErrors();
                PlatformRenderer.MarkTextureSlotAsDirty(0);
            });
        }
Beispiel #13
0
 private void Reload()
 {
     Window.Current.InvokeOnRendering(() => {
         if (reloader != null)
         {
             reloader.Reload(this);
         }
         else
         {
             PrepareOpenGLTexture();
             PlatformRenderer.CheckErrors();
         }
     });
 }
Beispiel #14
0
        private void Link()
        {
            GL.LinkProgram(handle);
            var result = new int[1];

            GL.GetProgram(handle, ProgramParameter.LinkStatus, result);
            if (result[0] == 0)
            {
                var infoLog = GetLinkLog();
                Logger.Write("Shader program link log:\n{0}", infoLog);
                throw new Lime.Exception(infoLog.ToString());
            }
            PlatformRenderer.CheckErrors();
        }
Beispiel #15
0
 private void Reload()
 {
     Application.InvokeOnMainThread(() => {
         if (reloader != null)
         {
             reloader.Reload(this);
         }
         else
         {
             PrepareOpenGLTexture();
             PlatformRenderer.CheckErrors();
         }
     });
 }
Beispiel #16
0
        private void ReadRGBAImage(ref Action glCommands, BinaryReader reader, int level, int width, int height, int pitch)
        {
            if (pitch != width * 4)
            {
                throw new InvalidDataException("Error reading RGBA texture. Must be 32 bit rgba");
            }
            var buffer = ReadTextureData(reader, pitch * height);

            glCommands += () => {
                PlatformRenderer.PushTexture(handle, 0);
                GL.TexImage2D(TextureTarget.Texture2D, level, PixelInternalFormat.Rgba, width, height, 0,
                              PixelFormat.Rgba, PixelType.UnsignedByte, buffer);
                PlatformRenderer.PopTexture(0);
                PlatformRenderer.CheckErrors();
            };
        }
Beispiel #17
0
        public void LoadImage(IntPtr pixels, int width, int height)
        {
            if (!Application.CurrentThread.IsMain())
            {
                throw new InvalidOperationException();
            }
            PrepareOpenGLTexture();
            PlatformRenderer.PushTexture(handle, 0);
            GL.TexImage2D(TextureTarget.Texture2D, 0, PixelInternalFormat.Rgba, width, height, 0, PixelFormat.Rgba, PixelType.UnsignedByte, pixels);
            MemoryUsed = 4 * width * height;
            PlatformRenderer.PopTexture(0);
            PlatformRenderer.CheckErrors();

            ImageSize   = new Size(width, height);
            SurfaceSize = ImageSize;
            uvRect      = new Rectangle(0, 0, 1, 1);
        }
Beispiel #18
0
 private void PrepareOpenGLTexture()
 {
     // Generate a new texture.
     if (handle == 0)
     {
         var t = new int[1];
         GL.GenTextures(1, t);
         handle = (uint)t[0];
     }
     PlatformRenderer.PushTexture(handle, 0);
     GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMinFilter, textureParams.MinFilter.ToInt());
     GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMagFilter, textureParams.MagFilter.ToInt());
     GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapS, textureParams.WrapModeU.ToInt());
     GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapT, textureParams.WrapModeV.ToInt());
     PlatformRenderer.PopTexture(0);
     PlatformRenderer.CheckErrors();
 }
Beispiel #19
0
 private void PrepareOpenGLTexture()
 {
     // Generate a new texture.
     if (handle == 0)
     {
         var t = new int[1];
         GL.GenTextures(1, t);
         handle = (uint)t[0];
     }
     GL.ActiveTexture(TextureUnit.Texture0);
     GL.BindTexture(TextureTarget.Texture2D, handle);
     GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMinFilter, textureParams.MinFilter.ToInt());
     GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMagFilter, textureParams.MagFilter.ToInt());
     GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapS, textureParams.WrapModeU.ToInt());
     GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapT, textureParams.WrapModeV.ToInt());
     PlatformRenderer.MarkTextureSlotAsDirty(0);
     PlatformRenderer.CheckErrors();
 }
Beispiel #20
0
        public void Discard()
        {
            if (handle != 0)
            {
                var handleCopy = handle;
                Window.Current.InvokeOnRendering(() => {
#if !MAC
                    if (OpenTK.Graphics.GraphicsContext.CurrentContext == null)
                    {
                        return;
                    }
#endif
                    GL.DeleteBuffers(1, new uint[] { handleCopy });
                    PlatformRenderer.CheckErrors();
                });
                handle = 0;
            }
        }
Beispiel #21
0
 private void Create()
 {
     handle = GL.CreateProgram();
     foreach (var shader in shaders)
     {
         GL.AttachShader(handle, shader.GetHandle());
     }
     foreach (var i in attribLocations)
     {
         GL.BindAttribLocation(handle, i.Index, i.Name);
     }
     Link();
     uniforms     = ReflectUniforms().OrderBy(i => i.SortingKey).ToArray();
     paramsToSync = new ShaderParam[uniforms.Length];
     boundParams  = new BoundShaderParam[uniforms.Length];
     GL.UseProgram(handle);
     PlatformRenderer.CheckErrors();
     foreach (var i in samplers)
     {
         GL.Uniform1(GL.GetUniformLocation(handle, i.Name), i.Stage);
         PlatformRenderer.CheckErrors();
     }
 }
Beispiel #22
0
 public void Discard()
 {
     MemoryUsed = 0;
     if (framebuffer != 0)
     {
         var h = framebuffer;
         Window.Current.InvokeOnRendering(() => {
             GL.DeleteFramebuffers(1, new uint[] { h });
             PlatformRenderer.CheckErrors();
         });
         framebuffer = 0;
     }
     if (handle != 0)
     {
         var h = handle;
         Window.Current.InvokeOnRendering(() => {
             GL.DeleteTextures(1, new uint[] { h });
             PlatformRenderer.CheckErrors();
         });
         handle = 0;
     }
     DeleteRenderBuffer(ref depthBuffer);
 }
Beispiel #23
0
 public void Discard()
 {
     MemoryUsed = 0;
     if (framebuffer != 0)
     {
         var h = framebuffer;
         Application.InvokeOnMainThread(() => {
             GL.DeleteFramebuffers(1, new uint[] { h });
             PlatformRenderer.CheckErrors();
         });
         framebuffer = 0;
     }
     if (handle != 0)
     {
         var h = handle;
         Application.InvokeOnMainThread(() => {
             GL.DeleteTextures(1, new uint[] { h });
             PlatformRenderer.CheckErrors();
             PlatformRenderer.InvalidateTexture(h);
         });
         handle = 0;
     }
     DeleteRenderBuffer(ref depthBuffer);
 }
Beispiel #24
0
        private void InitWithPVRTexture(BinaryReader reader)
        {
            var version = reader.ReadUInt32();

            if (version != PVRMagic)
            {
                throw new Exception("Invalid PVR header");
            }
            reader.ReadUInt32();             // flags
            var pixelFormat = (PVRFormat)reader.ReadUInt64();

            reader.ReadUInt32();             // color space
            reader.ReadUInt32();             // channel type
            var height = reader.ReadInt32();
            var width  = reader.ReadInt32();

            reader.ReadUInt32();             // depth
            reader.ReadUInt32();             // num surfaces
            reader.ReadUInt32();             // num faces
            var numMipmaps   = reader.ReadInt32();
            var metaDataSize = reader.ReadInt32();

            if (metaDataSize > 0)
            {
                reader.ReadChars(metaDataSize);
            }
            SurfaceSize = ImageSize = new Size(width, height);
            Action glCommands = PrepareOpenGLTexture;

            MemoryUsed = 0;
            for (int i = 0; i < numMipmaps; i++)
            {
                if (i > 0 && (width < 8 || height < 8))
                {
                    continue;
                }
                // Cloning variables to prevent wrong capturing
                int mipLevel = i;
                int width2   = width;
                int height2  = height;
                switch (pixelFormat)
                {
#if iOS
                case PVRFormat.PVRTC_4_RGBA: {
                    var buffer = ReadTextureData(reader, width * height * 4 / 8);
                    glCommands += () => {
                        PlatformRenderer.PushTexture(handle, 0);
                        GL.CompressedTexImage2D(All.Texture2D, mipLevel, All.CompressedRgbaPvrtc4Bppv1Img, width2, height2, 0, buffer.Length, buffer);
                        PlatformRenderer.PopTexture(0);
                        PlatformRenderer.CheckErrors();
                    };
                    break;
                }

                case PVRFormat.PVRTC_2_RGBA: {
                    if (i > 0 && height < 16)
                    {
                        continue;
                    }
                    var buffer = ReadTextureData(reader, width * height * 2 / 8);
                    glCommands += () => {
                        PlatformRenderer.PushTexture(handle, 0);
                        GL.CompressedTexImage2D(All.Texture2D, mipLevel, All.CompressedRgbaPvrtc2Bppv1Img, width2, height2, 0, buffer.Length, buffer);
                        PlatformRenderer.PopTexture(0);
                        PlatformRenderer.CheckErrors();
                    };
                    break;
                }
#elif ANDROID
                case PVRFormat.ETC1: {
                    var buffer = ReadTextureData(reader, width * height * 4 / 8);
                    glCommands += () => {
                        PlatformRenderer.PushTexture(handle, 0);
                        GL.CompressedTexImage2D(All.Texture2D, mipLevel, All.Etc1Rgb8Oes, width2, height2, 0, buffer.Length, buffer);
                        PlatformRenderer.PopTexture(0);
                        PlatformRenderer.CheckErrors();
                    };
                    break;
                }
#endif
                case PVRFormat.RGBA4444: {
                    var buffer = ReadTextureData(reader, width * height * 2);
                    glCommands += () => {
                        PlatformRenderer.PushTexture(handle, 0);
                        GL.TexImage2D(TextureTarget.Texture2D, mipLevel, PixelInternalFormat.Rgba, width2, height2, 0, PixelFormat.Rgba, PixelType.UnsignedShort4444, buffer);
                        PlatformRenderer.PopTexture(0);
                        PlatformRenderer.CheckErrors();
                    };
                    break;
                }

                case PVRFormat.RGB565: {
                    var buffer = ReadTextureData(reader, width * height * 2);
                    glCommands += () => {
                        PlatformRenderer.PushTexture(handle, 0);
                        GL.TexImage2D(TextureTarget.Texture2D, mipLevel, PixelInternalFormat.Rgb, width2, height2, 0, PixelFormat.Rgb, PixelType.UnsignedShort565, buffer);
                        PlatformRenderer.PopTexture(0);
                        PlatformRenderer.CheckErrors();
                    };
                    break;
                }

                case PVRFormat.RGBA8888: {
                    var buffer = ReadTextureData(reader, width * height * 4);
                    glCommands += () => {
                        PlatformRenderer.PushTexture(handle, 0);
                        GL.TexImage2D(TextureTarget.Texture2D, mipLevel, PixelInternalFormat.Rgba, width2, height2, 0, PixelFormat.Rgba, PixelType.UnsignedByte, buffer);
                        PlatformRenderer.PopTexture(0);
                        PlatformRenderer.CheckErrors();
                    };
                    break;
                }

                default:
                    throw new NotImplementedException();
                }
                width  /= 2;
                height /= 2;
            }
            Application.InvokeOnMainThread(glCommands);
        }
Beispiel #25
0
        private void InitWithKTXTexture(BinaryReader reader)
        {
            var identifier = reader.ReadBytes(12);

            if (identifier[1] != 'K' || identifier[2] != 'T' || identifier[3] != 'X')
            {
                throw new InvalidDataException("Invalid KTX header");
            }
            var endiannes = reader.ReadUInt32();

            if (endiannes != 0x04030201)
            {
                throw new InvalidDataException("Unsupported endiannes");
            }
            var glType                = reader.ReadInt32();
            var glTypeSize            = reader.ReadInt32();
            var glFormat              = reader.ReadInt32();
            var glInternalFormat      = reader.ReadInt32();
            var glBaseInternalFormat  = reader.ReadInt32();
            var pixelWidth            = reader.ReadInt32();
            var pixelHeight           = reader.ReadInt32();
            var pixelDepth            = reader.ReadInt32();
            var numberOfArrayElements = reader.ReadInt32();
            var numberOfFaces         = reader.ReadInt32();
            var numberOfMipmapLevels  = reader.ReadInt32();
            var bytesOfKeyValueData   = reader.ReadInt32();

            reader.ReadBytes(bytesOfKeyValueData);
            if (numberOfArrayElements != 0)
            {
                throw new InvalidDataException("Array textures are not supported");
            }
            if (numberOfFaces != 1)
            {
                throw new InvalidDataException("Cubemap textures are not supported");
            }
            if (pixelDepth != 0)
            {
                throw new InvalidDataException("3D Textures are not supported");
            }
            if ((pixelWidth & 3) != 0 || (pixelHeight & 3) != 0)
            {
                throw new InvalidDataException("Texture dimensions should multiple of 4");
            }
            SurfaceSize = ImageSize = new Size(pixelWidth, pixelHeight);
            Action glCommands = PrepareOpenGLTexture;

            PrepareOpenGLTexture();
            for (int i = 0; i < Math.Max(1, numberOfMipmapLevels); i++)
            {
                var dataLength = reader.ReadInt32();
                MemoryUsed = 0;
                if (i > 0 && (pixelWidth < 8 || pixelHeight < 8))
                {
                    continue;
                }
                // Copy variables because they will be captured.
                int mipLevel = i;
                int width    = pixelWidth;
                int height   = pixelHeight;
                if (glFormat == 0)
                {
                    var data = ReadTextureData(reader, dataLength);
                    glCommands += () => {
                        if (!etc2Checked)
                        {
                            etc2Checked = true;
                            if (PlatformRenderer.GetGLESMajorVersion() >= 3)
                            {
                                etc2Supported = true;
                            }
                            else
                            {
                                var ext = GL.GetString(StringName.Extensions);
                                etc2Supported = ext?.Contains("ETC2_RGBA8") ?? false;
                            }
                            Debug.Write(etc2Supported ? "ETC2 textures supported." : "ETC2 textures not supported.");
                        }
                        PlatformRenderer.PushTexture(handle, 0);
                        const int etc1Rgb8Oes = 36196;
                        if (etc2Supported || (Application.Platform == PlatformId.Android && glInternalFormat == etc1Rgb8Oes))
                        {
                            GL.CompressedTexImage2D(
                                TextureTarget.Texture2D, mipLevel, (PixelInternalFormat)glInternalFormat,
                                width, height, 0, dataLength, data);
                        }
                        else
                        {
                            var rgba8Data = Marshal.AllocHGlobal(width * height * 4);
                            Etc2Decoder.Decode(data, rgba8Data, width, height, glInternalFormat);
                            GL.TexImage2D(TextureTarget.Texture2D, mipLevel, PixelInternalFormat.Rgba, width, height, 0, PixelFormat.Rgba, PixelType.UnsignedByte, rgba8Data);
                            Marshal.FreeHGlobal(rgba8Data);
                        }
                        PlatformRenderer.PopTexture(0);
                        PlatformRenderer.CheckErrors();
                    };
                }
                else
                {
                    var data = ReadTextureData(reader, dataLength);
                    glCommands += () => {
                        PlatformRenderer.PushTexture(handle, 0);
                        GL.TexImage2D(
                            TextureTarget.Texture2D, mipLevel, (PixelInternalFormat)glInternalFormat,
                            width, height, 0, (PixelFormat)glFormat, (PixelType)glType, data);
                        PlatformRenderer.PopTexture(0);
                        PlatformRenderer.CheckErrors();
                    };
                }
                pixelWidth  /= 2;
                pixelHeight /= 2;
            }
            Application.InvokeOnMainThread(glCommands);
        }
Beispiel #26
0
 private void BindSampler(string name, int stage)
 {
     Use();
     GL.Uniform1(GL.GetUniformLocation(handle, name), stage);
     PlatformRenderer.CheckErrors();
 }