Exemplo n.º 1
0
 public override void BlitToMemory(BasicBox srcBox, PixelBox dst)
 {
     if (!this._buffer.Contains(srcBox))
     {
         throw new ArgumentException("Source box out of range.");
     }
     if (srcBox.Left == 0 && srcBox.Right == Width && srcBox.Top == 0 && srcBox.Bottom == Height && srcBox.Front == 0 &&
         srcBox.Back == Depth && dst.Width == Width && dst.Height == Height && dst.Depth == Depth &&
         GLPixelUtil.GetGLOriginFormat(dst.Format) != 0)
     {
         // The direct case: the user wants the entire texture in a format supported by GL
         // so we don't need an intermediate buffer
         download(dst);
     }
     else
     {
         // Use buffer for intermediate copy
         allocateBuffer();
         // Download entire buffer
         download(this._buffer);
         if (srcBox.Width != dst.Width || srcBox.Height != dst.Height || srcBox.Depth != dst.Depth)
         {
             //TODO Implement Image.Scale
             throw new Exception("Image scaling not yet implemented");
             // We need scaling
             //Image.Scale( _buffer.GetSubVolume( srcBox ), dst, ImageFilter.BiLinear );
         }
         else
         {
             // Just copy the bit that we need
             PixelConverter.BulkPixelConversion(this._buffer.GetSubVolume(srcBox), dst);
         }
         freeBuffer();
     }
 }
Exemplo n.º 2
0
        public override void CopyContentsToMemory(PixelBox dst, FrameBuffer buffer)
        {
            if ((dst.Left < 0) || (dst.Right > Width) ||
                (dst.Top < 0) || (dst.Bottom > Height) ||
                (dst.Front != 0) || (dst.Back != 1))
            {
                throw new Exception("Invalid box.");
            }
            if (buffer == RenderTarget.FrameBuffer.Auto)
            {
                buffer = IsFullScreen ? RenderTarget.FrameBuffer.Front : RenderTarget.FrameBuffer.Back;
            }

            int format = GLPixelUtil.GetGLOriginFormat(dst.Format);
            int type   = GLPixelUtil.GetGLOriginDataType(dst.Format);

            if ((format == Gl.GL_NONE) || (type == 0))
            {
                throw new Exception("Unsupported format.");
            }


            // Switch context if different from current one
            RenderSystem rsys = Root.Instance.RenderSystem;

            rsys.Viewport = this.GetViewport(0);

            // Must change the packing to ensure no overruns!
            Gl.glPixelStorei(Gl.GL_PACK_ALIGNMENT, 1);

            Gl.glReadBuffer((buffer == RenderTarget.FrameBuffer.Front) ? Gl.GL_FRONT : Gl.GL_BACK);
            Gl.glReadPixels(dst.Left, dst.Top, dst.Width, dst.Height, format, type, dst.Data);

            // restore default alignment
            Gl.glPixelStorei(Gl.GL_PACK_ALIGNMENT, 4);

            //vertical flip

            {
                int    rowSpan = dst.Width * PixelUtil.GetNumElemBytes(dst.Format);
                int    height  = dst.Height;
                byte[] tmpData = new byte[rowSpan * height];
                unsafe
                {
                    var dataPtr = dst.Data.ToBytePointer();
                    //int *srcRow = (uchar *)dst.data, *tmpRow = tmpData + (height - 1) * rowSpan;

                    for (int row = height - 1, tmpRow = 0; row >= 0; row--, tmpRow++)
                    {
                        for (int col = 0; col < rowSpan; col++)
                        {
                            tmpData[tmpRow * rowSpan + col] = dataPtr[row * rowSpan + col];
                        }
                    }
                }
                var tmpDataHandle = BufferBase.Wrap(tmpData);
                Memory.Copy(tmpDataHandle, dst.Data, rowSpan * height);
            }
        }
Exemplo n.º 3
0
        public GLRenderBuffer(int format, int width, int height, int fsaa)
            : base(width, height, 1, GLPixelUtil.GetClosestPixelFormat(format), BufferUsage.WriteOnly)
        {
            GLFormat = format;
            /// Generate renderbuffer
            Gl.glGenRenderbuffersEXT(1, out this._renderBufferId);
            /// Bind it to FBO
            Gl.glBindRenderbufferEXT(Gl.GL_RENDERBUFFER_EXT, this._renderBufferId);

            /// Allocate storage for depth buffer
            Gl.glRenderbufferStorageEXT(Gl.GL_RENDERBUFFER_EXT, format, width, height);
        }
Exemplo n.º 4
0
        protected override void download(PixelBox data)
        {
            if (data.Width != Width || data.Height != Height || data.Depth != Depth)
            {
                throw new ArgumentException("only download of entire buffer is supported by GL");
            }

            Gl.glBindTexture(this._target, this._textureId);
            if (PixelUtil.IsCompressed(data.Format))
            {
                if (data.Format != Format || !data.IsConsecutive)
                {
                    throw new ArgumentException("Compressed images must be consecutive, in the source format");
                }
                // Data must be consecutive and at beginning of buffer as PixelStorei not allowed
                // for compressed formate
                Gl.glGetCompressedTexImageARB(this._faceTarget, this._level, data.Data.Pin());
                data.Data.UnPin();
            }
            else
            {
                if (data.Width != data.RowPitch)
                {
                    Gl.glPixelStorei(Gl.GL_PACK_ROW_LENGTH, data.RowPitch);
                }
                if (data.Height * data.Width != data.SlicePitch)
                {
                    Gl.glPixelStorei(Gl.GL_PACK_IMAGE_HEIGHT, (data.SlicePitch / data.Width));
                }
                if (((data.Width * PixelUtil.GetNumElemBytes(data.Format)) & 3) != 0)
                {
                    // Standard alignment of 4 is not right
                    Gl.glPixelStorei(Gl.GL_PACK_ALIGNMENT, 1);
                }
                // We can only get the entire texture
                Gl.glGetTexImage(this._faceTarget, this._level, GLPixelUtil.GetGLOriginFormat(data.Format),
                                 GLPixelUtil.GetGLOriginDataType(data.Format), data.Data.Pin());
                data.Data.UnPin();
                // Restore defaults
                Gl.glPixelStorei(Gl.GL_PACK_ROW_LENGTH, 0);
                Gl.glPixelStorei(Gl.GL_PACK_IMAGE_HEIGHT, 0);
                Gl.glPixelStorei(Gl.GL_PACK_ALIGNMENT, 4);
            }
        }
Exemplo n.º 5
0
        public override void BlitFromMemory(PixelBox src, BasicBox dstBox)
        {
            PixelBox scaled;

            if (!this._buffer.Contains(dstBox))
            {
                throw new ArgumentException("Destination box out of range.");
            }

            if (src.Width != dstBox.Width || src.Height != dstBox.Height || src.Depth != dstBox.Depth)
            {
                // Scale to destination size. Use DevIL and not iluScale because ILU screws up for
                // floating point textures and cannot cope with 3D images.
                // This also does pixel format conversion if needed
                allocateBuffer();
                scaled = this._buffer.GetSubVolume(dstBox);

                Image.Scale(src, scaled, ImageFilter.Bilinear);
            }
            else if (GLPixelUtil.GetGLOriginFormat(src.Format) == 0)
            {
                // Extents match, but format is not accepted as valid source format for GL
                // do conversion in temporary buffer
                allocateBuffer();
                scaled = this._buffer.GetSubVolume(dstBox);
                PixelConverter.BulkPixelConversion(src, scaled);
            }
            else
            {
                // No scaling or conversion needed
                scaled = src;
                // Set extents for upload
                scaled.Left   = dstBox.Left;
                scaled.Right  = dstBox.Right;
                scaled.Top    = dstBox.Top;
                scaled.Bottom = dstBox.Bottom;
                scaled.Front  = dstBox.Front;
                scaled.Back   = dstBox.Back;
            }

            upload(scaled);
            freeBuffer();
        }
Exemplo n.º 6
0
        public GLTextureBuffer(string baseName, int target, int id, int face, int level, BufferUsage usage,
                               bool softwareMipmap, BaseGLSupport glSupport, bool writeGamma, int fsaa)
            : base(0, 0, 0, PixelFormat.Unknown, usage)
        {
            int value;

            this._glSupport = glSupport;

            this._target         = target;
            this._textureId      = id;
            this._face           = face;
            this._level          = level;
            this._softwareMipmap = softwareMipmap;

            Gl.glBindTexture(this._target, this._textureId);

            // Get face identifier
            this._faceTarget = this._target;
            if (this._target == Gl.GL_TEXTURE_CUBE_MAP)
            {
                this._faceTarget = Gl.GL_TEXTURE_CUBE_MAP_POSITIVE_X + this._face;
            }

            // Get width
            Gl.glGetTexLevelParameteriv(this._faceTarget, this._level, Gl.GL_TEXTURE_WIDTH, out value);
            width = value;

            // Get height
            if (this._target == Gl.GL_TEXTURE_1D)
            {
                value = 1; // Height always 1 for 1D textures
            }
            else
            {
                Gl.glGetTexLevelParameteriv(this._faceTarget, this._level, Gl.GL_TEXTURE_HEIGHT, out value);
            }
            height = value;

            // Get depth
            if (this._target != Gl.GL_TEXTURE_3D)
            {
                value = 1; // Depth always 1 for non-3D textures
            }
            else
            {
                Gl.glGetTexLevelParameteriv(this._faceTarget, this._level, Gl.GL_TEXTURE_DEPTH, out value);
            }
            depth = value;

            // Get format
            Gl.glGetTexLevelParameteriv(this._faceTarget, this._level, Gl.GL_TEXTURE_INTERNAL_FORMAT, out value);
            GLFormat = value;
            format   = GLPixelUtil.GetClosestPixelFormat(value);

            // Default
            rowPitch    = Width;
            slicePitch  = Height * Width;
            sizeInBytes = PixelUtil.GetMemorySize(Width, Height, Depth, Format);

            // Set up pixel box
            buffer = new PixelBox(Width, Height, Depth, Format);

            if (Width == 0 || Height == 0 || Depth == 0)
            {
                /// We are invalid, do not allocate a buffer
                return;
            }

            // Is this a render target?
            if (((TextureUsage)Usage & TextureUsage.RenderTarget) == TextureUsage.RenderTarget)
            {
                // Create render target for each slice
                this._sliceTRT.Capacity = Depth;
                for (int zoffset = 0; zoffset < Depth; ++zoffset)
                {
                    String name;
                    name = String.Format("{0}/{1}/{2}/{3}", baseName, face, this._level, zoffset);

                    GLSurfaceDesc renderTarget;
                    renderTarget.Buffer  = this;
                    renderTarget.ZOffset = zoffset;
                    RenderTexture trt = GLRTTManager.Instance.CreateRenderTexture(name, renderTarget, writeGamma, fsaa);
                    this._sliceTRT.Add(trt);
                    Root.Instance.RenderSystem.AttachRenderTarget(this._sliceTRT[zoffset]);
                }
            }
        }
Exemplo n.º 7
0
        protected override void upload(PixelBox box)
        {
            Gl.glBindTexture(this._target, this._textureId);
            if (PixelUtil.IsCompressed(box.Format))
            {
                if (box.Format != Format || !box.IsConsecutive)
                {
                    throw new ArgumentException("Compressed images must be consecutive, in the source format");
                }

                int format = GLPixelUtil.GetClosestGLInternalFormat(Format);
                // Data must be consecutive and at beginning of buffer as PixelStorei not allowed
                // for compressed formats
                switch (this._target)
                {
                case Gl.GL_TEXTURE_1D:
                    Gl.glCompressedTexSubImage1DARB(Gl.GL_TEXTURE_1D, this._level, box.Left, box.Width, format, box.ConsecutiveSize,
                                                    box.Data.Pin());
                    box.Data.UnPin();
                    break;

                case Gl.GL_TEXTURE_2D:
                case Gl.GL_TEXTURE_CUBE_MAP:
                    Gl.glCompressedTexSubImage2DARB(this._faceTarget, this._level, box.Left, box.Top, box.Width, box.Height, format,
                                                    box.ConsecutiveSize, box.Data.Pin());
                    box.Data.UnPin();
                    break;

                case Gl.GL_TEXTURE_3D:
                    Gl.glCompressedTexSubImage3DARB(Gl.GL_TEXTURE_3D, this._level, box.Left, box.Top, box.Front, box.Width,
                                                    box.Height,
                                                    box.Depth, format, box.ConsecutiveSize, box.Data.Pin());
                    box.Data.UnPin();
                    break;
                }
            }
            else if (this._softwareMipmap)
            {
                int internalFormat;
                Gl.glGetTexLevelParameteriv(this._target, this._level, Gl.GL_TEXTURE_INTERNAL_FORMAT, out internalFormat);
                if (box.Width != box.RowPitch)
                {
                    Gl.glPixelStorei(Gl.GL_UNPACK_ROW_LENGTH, box.RowPitch);
                }
                if (box.Height * box.Width != box.SlicePitch)
                {
                    Gl.glPixelStorei(Gl.GL_UNPACK_IMAGE_HEIGHT, (box.SlicePitch / box.Width));
                }
                Gl.glPixelStorei(Gl.GL_UNPACK_ALIGNMENT, 1);

                switch (this._target)
                {
                case Gl.GL_TEXTURE_1D:
                    Glu.gluBuild1DMipmaps(Gl.GL_TEXTURE_1D, internalFormat, box.Width, GLPixelUtil.GetGLOriginFormat(box.Format),
                                          GLPixelUtil.GetGLOriginDataType(box.Format), box.Data.Pin());
                    box.Data.UnPin();
                    break;

                case Gl.GL_TEXTURE_2D:
                case Gl.GL_TEXTURE_CUBE_MAP:
                    Glu.gluBuild2DMipmaps(this._faceTarget, internalFormat, box.Width, box.Height,
                                          GLPixelUtil.GetGLOriginFormat(box.Format), GLPixelUtil.GetGLOriginDataType(box.Format),
                                          box.Data.Pin());
                    box.Data.UnPin();
                    break;

                case Gl.GL_TEXTURE_3D:
                    /* Requires GLU 1.3 which is harder to come by than cards doing hardware mipmapping
                     *                              Most 3D textures don't need mipmaps?
                     *                      Gl.gluBuild3DMipmaps(
                     *                              Gl.GL_TEXTURE_3D, internalFormat,
                     *                              box.getWidth(), box.getHeight(), box.getDepth(),
                     *                              GLPixelUtil.getGLOriginFormat(box.format), GLPixelUtil.getGLOriginDataType(box.format),
                     *                              box.box);
                     */
                    Gl.glTexImage3D(Gl.GL_TEXTURE_3D, 0, internalFormat, box.Width, box.Height, box.Depth, 0,
                                    GLPixelUtil.GetGLOriginFormat(box.Format), GLPixelUtil.GetGLOriginDataType(box.Format),
                                    box.Data.Pin());
                    box.Data.UnPin();
                    break;
                }
            }
            else
            {
                if (box.Width != box.RowPitch)
                {
                    Gl.glPixelStorei(Gl.GL_UNPACK_ROW_LENGTH, box.RowPitch);
                }
                if (box.Height * box.Width != box.SlicePitch)
                {
                    Gl.glPixelStorei(Gl.GL_UNPACK_IMAGE_HEIGHT, (box.SlicePitch / box.Width));
                }
                if (((box.Width * PixelUtil.GetNumElemBytes(box.Format)) & 3) != 0)
                {
                    // Standard alignment of 4 is not right
                    Gl.glPixelStorei(Gl.GL_UNPACK_ALIGNMENT, 1);
                }
                switch (this._target)
                {
                case Gl.GL_TEXTURE_1D:
                    Gl.glTexSubImage1D(Gl.GL_TEXTURE_1D, this._level, box.Left, box.Width,
                                       GLPixelUtil.GetGLOriginFormat(box.Format),
                                       GLPixelUtil.GetGLOriginDataType(box.Format), box.Data.Pin());
                    box.Data.UnPin();
                    break;

                case Gl.GL_TEXTURE_2D:
                case Gl.GL_TEXTURE_CUBE_MAP:
                    Gl.glTexSubImage2D(this._faceTarget, this._level, box.Left, box.Top, box.Width, box.Height,
                                       GLPixelUtil.GetGLOriginFormat(box.Format), GLPixelUtil.GetGLOriginDataType(box.Format),
                                       box.Data.Pin());
                    box.Data.UnPin();
                    break;

                case Gl.GL_TEXTURE_3D:
                    Gl.glTexSubImage3D(Gl.GL_TEXTURE_3D, this._level, box.Left, box.Top, box.Front, box.Width, box.Height, box.Depth,
                                       GLPixelUtil.GetGLOriginFormat(box.Format), GLPixelUtil.GetGLOriginDataType(box.Format),
                                       box.Data.Pin());
                    box.Data.UnPin();
                    break;
                }
            }
            // Restore defaults
            Gl.glPixelStorei(Gl.GL_UNPACK_ROW_LENGTH, 0);
            Gl.glPixelStorei(Gl.GL_UNPACK_IMAGE_HEIGHT, 0);
            Gl.glPixelStorei(Gl.GL_UNPACK_ALIGNMENT, 4);
        }
Exemplo n.º 8
0
        /// <summary>
        /// Detect allowed FBO formats
        /// </summary>
        private void _detectFBOFormats()
        {
            // Try all formats, and report which ones work as target
            int fb, tid;
            int old_drawbuffer, old_readbuffer;
            int target = Gl.GL_TEXTURE_2D;

            Gl.glGetIntegerv(Gl.GL_DRAW_BUFFER, out old_drawbuffer);
            Gl.glGetIntegerv(Gl.GL_READ_BUFFER, out old_readbuffer);

            for (int x = 0; x < (int)PixelFormat.Count; ++x)
            {
                this._props[x].Valid = false;

                // Fetch GL format token
                int fmt = GLPixelUtil.GetGLInternalFormat((PixelFormat)x);
                if (fmt == Gl.GL_NONE && x != 0)
                {
                    continue;
                }

                // No test for compressed formats
                if (PixelUtil.IsCompressed((PixelFormat)x))
                {
                    continue;
                }

                // Buggy ATI cards *crash* on non-RGB(A) formats
                int[] depths = PixelUtil.GetBitDepths((PixelFormat)x);
                if (fmt != Gl.GL_NONE && this._atiMode && (depths[0] == 0 || depths[1] == 0 || depths[2] == 0))
                {
                    continue;
                }

                // Buggy NVidia Drivers fail on 32Bit FP formats on Windows.
                if (PixelUtil.IsFloatingPoint((PixelFormat)x) && PlatformManager.IsWindowsOS && !this._atiMode)
                {
                    continue;
                }

                // Create and attach framebuffer
                Gl.glGenFramebuffersEXT(1, out fb);
                Gl.glBindFramebufferEXT(Gl.GL_FRAMEBUFFER_EXT, fb);
                if (fmt != Gl.GL_NONE)
                {
                    // Create and attach texture
                    Gl.glGenTextures(1, out tid);
                    Gl.glBindTexture(target, tid);

                    // Set some default parameters so it won't fail on NVidia cards
                    Gl.glTexParameteri(target, Gl.GL_TEXTURE_MAX_LEVEL, 0);
                    Gl.glTexParameteri(target, Gl.GL_TEXTURE_MIN_FILTER, Gl.GL_NEAREST);
                    Gl.glTexParameteri(target, Gl.GL_TEXTURE_MAG_FILTER, Gl.GL_NEAREST);
                    Gl.glTexParameteri(target, Gl.GL_TEXTURE_WRAP_S, Gl.GL_CLAMP_TO_EDGE);
                    Gl.glTexParameteri(target, Gl.GL_TEXTURE_WRAP_T, Gl.GL_CLAMP_TO_EDGE);

                    Gl.glTexImage2D(target, 0, fmt, PROBE_SIZE, PROBE_SIZE, 0, Gl.GL_RGBA, Gl.GL_UNSIGNED_BYTE, IntPtr.Zero);
                    Gl.glFramebufferTexture2DEXT(Gl.GL_FRAMEBUFFER_EXT, Gl.GL_COLOR_ATTACHMENT0_EXT, target, tid, 0);
                }
                else
                {
                    // Draw to nowhere -- stencil/depth only
                    tid = 0;
                    Gl.glDrawBuffer(Gl.GL_NONE);
                    Gl.glReadBuffer(Gl.GL_NONE);
                }
                // Check status
                int status = Gl.glCheckFramebufferStatusEXT(Gl.GL_FRAMEBUFFER_EXT);

                // Ignore status in case of fmt==GL_NONE, because no implementation will accept
                // a buffer without *any* attachment. Buffers with only stencil and depth attachment
                // might still be supported, so we must continue probing.
                if (fmt == Gl.GL_NONE || status == Gl.GL_FRAMEBUFFER_COMPLETE_EXT)
                {
                    this._props[x].Valid = true;
                    var str = new StringBuilder();
                    str.AppendFormat("\tFBO {0} depth/stencil support: ", PixelUtil.GetFormatName((PixelFormat)x));

                    // For each depth/stencil formats
                    for (int depth = 0; depth < this._depthFormats.GetLength(0); ++depth)
                    {
                        if (this._depthFormats[depth] != GL_DEPTH24_STENCIL8_EXT)
                        {
                            // General depth/stencil combination

                            for (int stencil = 0; stencil < this._stencilFormats.GetLength(0); ++stencil)
                            {
                                //LogManager.Instance.Write( "Trying {0} D{1}S{2} ", PixelUtil.GetFormatName( (PixelFormat)x ), _depthBits[ depth ], _stencilBits[ stencil ] );

                                if (_tryFormat(this._depthFormats[depth], this._stencilFormats[stencil]))
                                {
                                    /// Add mode to allowed modes
                                    str.AppendFormat("D{0}S{1} ", this._depthBits[depth], this._stencilBits[stencil]);
                                    FormatProperties.Mode mode;
                                    mode.Depth   = depth;
                                    mode.Stencil = stencil;
                                    this._props[x].Modes.Add(mode);
                                }
                            }
                        }
                        else
                        {
                            // Packed depth/stencil format
#if false
                            // Only query packed depth/stencil formats for 32-bit
                            // non-floating point formats (ie not R32!)
                            // Linux nVidia driver segfaults if you query others
                            if (!PlatformManager.IsWindowsOS &&
                                (PixelUtil.GetNumElemBits((PixelFormat)x) != 32 ||
                                 PixelUtil.IsFloatingPoint((PixelFormat)x)))
                            {
                                continue;
                            }
#endif
                            if (_tryPackedFormat(this._depthFormats[depth]))
                            {
                                /// Add mode to allowed modes
                                str.AppendFormat("Packed-D{0}S8 ", this._depthBits[depth]);
                                FormatProperties.Mode mode;
                                mode.Depth   = depth;
                                mode.Stencil = 0; // unuse
                                this._props[x].Modes.Add(mode);
                            }
                        }
                    }

                    LogManager.Instance.Write(str.ToString());
                }
                // Delete texture and framebuffer
                Gl.glBindFramebufferEXT(Gl.GL_FRAMEBUFFER_EXT, 0);
                Gl.glDeleteFramebuffersEXT(1, ref fb);

                // Workaround for NVIDIA / Linux 169.21 driver problem
                // see http://www.ogre3d.org/phpBB2/viewtopic.php?t=38037&start=25
                Gl.glFinish();

                Gl.glDeleteTextures(1, ref tid);
            }

            // It seems a bug in nVidia driver: glBindFramebufferEXT should restore
            // draw and read buffers, but in some unclear circumstances it won't.
            Gl.glDrawBuffer(old_drawbuffer);
            Gl.glReadBuffer(old_readbuffer);

            string fmtstring = "";
            for (int x = 0; x < (int)PixelFormat.Count; ++x)
            {
                if (this._props[x].Valid)
                {
                    fmtstring += PixelUtil.GetFormatName((PixelFormat)x) + " ";
                }
            }
            LogManager.Instance.Write("[GL] : Valid FBO targets " + fmtstring);
        }
Exemplo n.º 9
0
        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;
        }