protected override void createInternalResources() { // Convert to nearest power-of-two size if required Width = GLPixelUtil.OptionalPO2(Width); Height = GLPixelUtil.OptionalPO2(Height); Depth = GLPixelUtil.OptionalPO2(Depth); // Adjust format if required this.format = TextureManager.Instance.GetNativeFormat(TextureType, Format, Usage); // Check requested number of mipmaps int maxMips = GLPixelUtil.GetMaxMipmaps(Width, Height, Depth, Format); MipmapCount = requestedMipmapCount; if (MipmapCount > maxMips) { MipmapCount = maxMips; } // Generate texture name Gl.glGenTextures(1, out this._glTextureID); // Set texture type Gl.glBindTexture(GLTextureType, this._glTextureID); // This needs to be set otherwise the texture doesn't get rendered Gl.glTexParameteri(GLTextureType, Gl.GL_TEXTURE_MAX_LEVEL, MipmapCount); // Set some misc default parameters so NVidia won't complain, these can of course be changed later Gl.glTexParameteri(GLTextureType, Gl.GL_TEXTURE_MIN_FILTER, Gl.GL_NEAREST); Gl.glTexParameteri(GLTextureType, Gl.GL_TEXTURE_MAG_FILTER, Gl.GL_NEAREST); Gl.glTexParameteri(GLTextureType, Gl.GL_TEXTURE_WRAP_S, Gl.GL_CLAMP_TO_EDGE); Gl.glTexParameteri(GLTextureType, Gl.GL_TEXTURE_WRAP_T, Gl.GL_CLAMP_TO_EDGE); // If we can do automip generation and the user desires this, do so mipmapsHardwareGenerated = Root.Instance.RenderSystem.Capabilities.HasCapability(Capabilities.HardwareMipMaps); if (((Usage & TextureUsage.AutoMipMap) == TextureUsage.AutoMipMap) && requestedMipmapCount != 0 && MipmapsHardwareGenerated) { Gl.glTexParameteri(GLTextureType, Gl.GL_GENERATE_MIPMAP, Gl.GL_TRUE); } // Allocate internal buffer so that glTexSubImageXD can be used // Internal format int format = GLPixelUtil.GetClosestGLInternalFormat(Format); int width = Width; int height = Height; int depth = Depth; { // Run through this process to pregenerate mipmap pyramid for (int mip = 0; mip <= MipmapCount; mip++) { // Normal formats switch (TextureType) { case TextureType.OneD: Gl.glTexImage1D(Gl.GL_TEXTURE_1D, mip, format, width, 0, Gl.GL_RGBA, Gl.GL_UNSIGNED_BYTE, IntPtr.Zero); break; case TextureType.TwoD: Gl.glTexImage2D(Gl.GL_TEXTURE_2D, mip, format, width, height, 0, Gl.GL_RGBA, Gl.GL_UNSIGNED_BYTE, IntPtr.Zero); break; case TextureType.ThreeD: Gl.glTexImage3D(Gl.GL_TEXTURE_3D, mip, format, width, height, depth, 0, Gl.GL_RGBA, Gl.GL_UNSIGNED_BYTE, IntPtr.Zero); break; case TextureType.CubeMap: for (int face = 0; face < 6; face++) { Gl.glTexImage2D(Gl.GL_TEXTURE_CUBE_MAP_POSITIVE_X + face, mip, format, width, height, 0, Gl.GL_RGBA, Gl.GL_UNSIGNED_BYTE, IntPtr.Zero); } break; } ; if (width > 1) { width = width / 2; } if (height > 1) { height = height / 2; } if (depth > 1) { depth = depth / 2; } } } _createSurfaceList(); // Get final internal format this.format = GetBuffer(0, 0).Format; }