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; }