public void InitWithBitmap(Bitmap imageSource, ALL11 filter, ALL11 wrap)
        {
            //TODO:  Android.Opengl.GLUtils.GetInternalFormat()
            try
            {
                _format = SurfaceFormat.Color;
                if (imageSource.HasAlpha)
                {
                    _format = SurfaceFormat.Color;
                }

                if (GraphicsDevice.OpenGLESVersion == OpenTK.Graphics.GLContextVersion.Gles2_0)
                {
                    _width  = imageSource.Width;
                    _height = imageSource.Height;

                    // There are rules for npot textures that we must abide by (wrap = ClampToEdge and filter = Nearest or Linear)
                    if (!MathHelper.IsPowerOfTwo(_width) || !MathHelper.IsPowerOfTwo(_height))
                    {
                        filter = ALL11.Linear;
                        wrap   = ALL11.ClampToEdge;
                    }
                }
                else
                {
                    //scale up bitmap to be power of 2 dimensions but dont exceed 1024x1024.
                    //Note: may not have to do this with OpenGL 2+
                    _width  = (int)Math.Pow(2, Math.Min(10, Math.Ceiling(Math.Log10(imageSource.Width) / Math.Log10(2))));
                    _height = (int)Math.Pow(2, Math.Min(10, Math.Ceiling(Math.Log10(imageSource.Height) / Math.Log10(2))));
                }

                _size.Width  = _width;
                _size.Height = _height;

                if (GraphicsDevice.OpenGLESVersion ==
                    OpenTK.Graphics.GLContextVersion.Gles2_0)
                {
                    GL20.GenTextures(1, ref _name);
                }
                else
                {
                    GL11.GenTextures(1, ref _name);
                }

                if (_name == 0)
                {
                    _originalBitmap = imageSource;
                    _originalFilter = filter;
                    _originalWrap   = wrap;
                    PrimaryThreadLoader.AddToList(this);
                    _textureCreated = false;
                }
                else
                {
                    _originalBitmap = null;
                    _textureCreated = true;

                    using (
                        Bitmap imagePadded = Bitmap.CreateBitmap(_width, _height,
                                                                 Bitmap.Config.Argb8888)
                        )
                    {
                        using (Canvas can = new Canvas(imagePadded))
                        {
                            can.DrawARGB(0, 0, 0, 0);

                            if (AndroidCompatibility.ScaleImageToPowerOf2)
                            {
                                can.DrawBitmap(imageSource, new Rect(0, 0, imageSource.Width, imageSource.Height), new Rect(0, 0, _width, _height), null);          //Scale to texture
                            }
                            else
                            {
                                can.DrawBitmap(imageSource, 0, 0, null);
                            }

                            if (GraphicsDevice.OpenGLESVersion ==
                                OpenTK.Graphics.GLContextVersion.Gles2_0)
                            {
                                GL20.BindTexture(ALL20.Texture2D, _name);
                                GL20.TexParameter(ALL20.Texture2D, ALL20.TextureMinFilter,
                                                  (int)filter);
                                GL20.TexParameter(ALL20.Texture2D, ALL20.TextureMagFilter,
                                                  (int)filter);
                                GL20.TexParameter(ALL20.Texture2D, ALL20.TextureWrapS, (int)wrap);
                                GL20.TexParameter(ALL20.Texture2D, ALL20.TextureWrapT, (int)wrap);
                                Android.Opengl.GLUtils.TexImage2D((int)ALL20.Texture2D, 0,
                                                                  imagePadded, 0);

                                // error checking
                                //int errAndroidGL = Android.Opengl.GLES20.GlGetError();
                                //ALL20 errGenericGL = GL20.GetError();
                                //if (errAndroidGL != Android.Opengl.GLES20.GlNoError || errGenericGL != ALL20.NoError)
                                //    Console.WriteLine(string.Format("OpenGL ES 2.0:\n\tAndroid error: {0,10:X}\n\tGeneric error: {1, 10:X}", errAndroidGL, errGenericGL));
                            }
                            else
                            {
                                GL11.BindTexture(ALL11.Texture2D, _name);
                                GL11.TexParameter(ALL11.Texture2D, ALL11.TextureMinFilter,
                                                  (int)filter);
                                GL11.TexParameter(ALL11.Texture2D, ALL11.TextureMagFilter,
                                                  (int)filter);
                                GL11.TexParameter(ALL11.Texture2D, ALL11.TextureWrapS, (int)wrap);
                                GL11.TexParameter(ALL11.Texture2D, ALL11.TextureWrapT, (int)wrap);
                                GL11.TexParameter(ALL11.Texture2D, ALL11.GenerateMipmap, 1);
                                Android.Opengl.GLUtils.TexImage2D((int)ALL11.Texture2D, 0,
                                                                  imagePadded, 0);
                            }
                        }
                    }
                }
            }
            finally
            {
                if (_originalBitmap != imageSource)
                {
                    // free bitmap
                    imageSource.Dispose();
                }
            }

            _maxS = _size.Width / (float)_width;
            _maxT = _size.Height / (float)_height;
        }
        public void InitWithData(IntPtr data, SurfaceFormat pixelFormat, int width, int height, Size size, ALL11 filter, ALL11 wrap)
        {
            if (GraphicsDevice.OpenGLESVersion == OpenTK.Graphics.GLContextVersion.Gles2_0)
            {
                if (!MathHelper.IsPowerOfTwo(width) || !MathHelper.IsPowerOfTwo(height))
                {
                    filter = ALL11.Linear;
                    wrap   = ALL11.ClampToEdge;
                }
                GL20.GenTextures(1, ref _name);
                GL20.BindTexture(ALL20.Texture2D, _name);
                GL20.TexParameter(ALL20.Texture2D, ALL20.TextureMinFilter, (int)filter);
                GL20.TexParameter(ALL20.Texture2D, ALL20.TextureMagFilter, (int)filter);
                GL20.TexParameter(ALL20.Texture2D, ALL20.TextureWrapS, (int)wrap);
                GL20.TexParameter(ALL20.Texture2D, ALL20.TextureWrapT, (int)wrap);

                switch (pixelFormat)
                {
                case SurfaceFormat.Color /*kTexture2DPixelFormat_RGBA8888*/:
                case SurfaceFormat.Dxt1:
                case SurfaceFormat.Dxt3:
                    //sz = 4;
                    GL20.TexImage2D(ALL20.Texture2D, 0, (int)ALL20.Rgba, (int)width, (int)height, 0, ALL20.Rgba, ALL20.UnsignedByte, data);
                    break;

                case SurfaceFormat.Bgra4444 /*kTexture2DPixelFormat_RGBA4444*/:
                    //sz = 2;
                    GL20.TexImage2D(ALL20.Texture2D, 0, (int)ALL20.Rgba, (int)width, (int)height, 0, ALL20.Rgba, ALL20.UnsignedShort4444, data);
                    break;

                case SurfaceFormat.Bgra5551 /*kTexture2DPixelFormat_RGB5A1*/:
                    //sz = 2;
                    GL20.TexImage2D(ALL20.Texture2D, 0, (int)ALL20.Rgba, (int)width, (int)height, 0, ALL20.Rgba, ALL20.UnsignedShort5551, data);
                    break;

                case SurfaceFormat.Alpha8 /*kTexture2DPixelFormat_A8*/:
                    //sz = 1;
                    GL20.TexImage2D(ALL20.Texture2D, 0, (int)ALL20.Alpha, (int)width, (int)height, 0, ALL20.Alpha, ALL20.UnsignedByte, data);
                    break;

                default:
                    throw new NotSupportedException("Texture format");
                }
            }
            else
            {
                GL11.GenTextures(1, ref _name);
                GL11.BindTexture(ALL11.Texture2D, _name);
                GL11.TexParameter(ALL11.Texture2D, ALL11.TextureMinFilter, (int)filter);
                GL11.TexParameter(ALL11.Texture2D, ALL11.TextureMagFilter, (int)filter);
                GL11.TexParameter(ALL11.Texture2D, ALL11.TextureWrapS, (int)ALL11.ClampToEdge);
                GL11.TexParameter(ALL11.Texture2D, ALL11.TextureWrapT, (int)ALL11.ClampToEdge);

                switch (pixelFormat)
                {
                case SurfaceFormat.Color /*kTexture2DPixelFormat_RGBA8888*/:
                case SurfaceFormat.Dxt1:
                case SurfaceFormat.Dxt3:
                    GL11.TexImage2D(ALL11.Texture2D, 0, (int)ALL11.Rgba, (int)width, (int)height, 0, ALL11.Rgba, ALL11.UnsignedByte, data);
                    break;

                case SurfaceFormat.Bgra4444 /*kTexture2DPixelFormat_RGBA4444*/:
                    GL11.TexImage2D(ALL11.Texture2D, 0, (int)ALL11.Rgba, (int)width, (int)height, 0, ALL11.Rgba, ALL11.UnsignedShort4444, data);
                    break;

                case SurfaceFormat.Bgra5551 /*kTexture2DPixelFormat_RGB5A1*/:
                    GL11.TexImage2D(ALL11.Texture2D, 0, (int)ALL11.Rgba, (int)width, (int)height, 0, ALL11.Rgba, ALL11.UnsignedShort5551, data);
                    break;

                case SurfaceFormat.Alpha8 /*kTexture2DPixelFormat_A8*/:
                    GL11.TexImage2D(ALL11.Texture2D, 0, (int)ALL11.Alpha, (int)width, (int)height, 0, ALL11.Alpha, ALL11.UnsignedByte, data);
                    break;

                default:
                    throw new NotSupportedException("Texture format");
                }
            }

            _size   = size;
            _width  = width;
            _height = height;
            _format = pixelFormat;
            _maxS   = size.Width / (float)_width;
            _maxT   = size.Height / (float)_height;
        }
Esempio n. 3
0
        protected override void createInternalResources()
        {
            //Conver to nearest power of two size if require
            this.width  = GLES2PixelUtil.OptionalPO2(Width);
            this.height = GLES2PixelUtil.OptionalPO2(Height);
            this.depth  = GLES2PixelUtil.OptionalPO2(Depth);

            //Adjust format if required
            format = TextureManager.Instance.GetNativeFormat(textureType, Format, usage);

            //Check requested number of mipmaps
            int maxMips = GLES2PixelUtil.GetMaxMipmaps(this.width, this.height, this.depth, format);

            if (PixelUtil.IsCompressed(format) && (mipmapCount == 0))
            {
                requestedMipmapCount = 0;
            }

            mipmapCount = requestedMipmapCount;
            if (mipmapCount > maxMips)
            {
                mipmapCount = maxMips;
            }

            //Generate texture name
            GL.GenTextures(1, ref this.textureID);
            GLES2Config.GlCheckError(this);

            //Set texture name
            GL.BindTexture(this.GLES2TextureTarget, this.textureID);
            GLES2Config.GlCheckError(this);

            //Set some misc default parameters, tehse can of course be changed later
            GL.TexParameter(this.GLES2TextureTarget, GLenum.TextureMinFilter, (int)GLenum.Nearest);
            GLES2Config.GlCheckError(this);

            GL.TexParameter(this.GLES2TextureTarget, GLenum.TextureMagFilter, (int)GLenum.Nearest);
            GLES2Config.GlCheckError(this);

            GL.TexParameter(this.GLES2TextureTarget, GLenum.TextureWrapS, (int)GLenum.ClampToEdge);
            GLES2Config.GlCheckError(this);

            GL.TexParameter(this.GLES2TextureTarget, GLenum.TextureWrapT, (int)GLenum.ClampToEdge);
            GLES2Config.GlCheckError(this);

            //If we can do automip generation and the user desires this, do so
            mipmapsHardwareGenerated = Root.Instance.RenderSystem.Capabilities.HasCapability(Capabilities.HardwareMipMaps) && !PixelUtil.IsCompressed(format);

            //Ogre FIXME: For some reason this is crashing on iOS 5
#if !MONOTOUCH && ANDROID
            if ((usage & TextureUsage.AutoMipMap) == TextureUsage.AutoMipMap && requestedMipmapCount > 0 && mipmapsHardwareGenerated && (textureType != Graphics.TextureType.CubeMap))
            {
                GL.GenerateMipmap(this.GLES2TextureTarget);
                GLES2Config.GlCheckError(this);
            }
#endif
            //Allocate internal buffer so that glTexSubImageXD can be used
            //INternal format
            GLenum glformat = GLES2PixelUtil.GetClosestGLInternalFormat(format, hwGamma);

            GLenum dataType = GLES2PixelUtil.GetGLOriginDataType(format);
            int    width    = Width;
            int    height   = Height;
            int    depth    = Depth;

            if (PixelUtil.IsCompressed(format))
            {
                //Compressed formats
                int size = PixelUtil.GetMemorySize(Width, Height, Depth, Format);

                // Provide temporary buffer filled with zeroes as glCompressedTexImageXD does not
                // accept a 0 pointer like normal glTexImageXD
                // Run through this process for every mipmap to pregenerate mipmap pyramid


                var tmpData = new IntPtr();

                for (int mip = 0; mip < mipmapCount; mip++)
                {
                    size = PixelUtil.GetMemorySize(width, height, depth, Format);

                    switch (textureType)
                    {
                    case TextureType.OneD:
                    case TextureType.TwoD:
                        GL.CompressedTexImage2D(GLenum.Texture2D, mip, glformat, width, height, 0, size, tmpData);
                        GLES2Config.GlCheckError(this);

                        break;

                    case TextureType.CubeMap:
                        for (int face = 0; face < 6; face++)
                        {
                            GL.CompressedTexImage2D((GLenum)((int)GLenum.TextureCubeMapPositiveX + face), mip, glformat, width, height, 0, size, tmpData);
                            GLES2Config.GlCheckError(this);
                        }
                        break;

                    case TextureType.ThreeD:
                        break;

                    default:
                        break;
                    }

                    if (width > 1)
                    {
                        width = width / 2;
                    }
                    if (height > 1)
                    {
                        height = height / 2;
                    }
                    if (depth > 1)
                    {
                        depth = depth / 2;
                    }
                }
                tmpData = IntPtr.Zero;
            }
            else
            {
                //Run through this process to pregenerate mipmap pyramid
                for (int mip = 0; mip < mipmapCount; mip++)
                {
                    //Normal formats
                    switch (textureType)
                    {
                    case TextureType.OneD:
                    case TextureType.TwoD:
                        GL.TexImage2D(GLenum.Texture2D, mip, (int)glformat, width, height, 0, glformat, dataType, new IntPtr());
                        GLES2Config.GlCheckError(this);

                        break;

                    case TextureType.CubeMap:
                        for (int face = 0; face < 6; face++)
                        {
                            GL.TexImage2D(GLenum.TextureCubeMapPositiveX + face, mip, (int)glformat, width, height, 0, glformat, dataType, new IntPtr());
                            GLES2Config.GlCheckError(this);
                        }
                        break;

                    case TextureType.ThreeD:
                    default:
                        break;
                    }
                    if (width > 1)
                    {
                        width /= 2;
                    }
                    if (height > 1)
                    {
                        height /= 2;
                    }
                }
            }

            this.CreateSurfaceList();

            //Get final internal format
            base.format = this.GetBuffer(0, 0).Format;
        }