diff --git a/Source/Utilities/Graphics/AlphaTexture2D.cs b/Source/Utilities/Graphics/AlphaTexture2D.cs
index ac3686f7..637e4ec5 100644
--- a/Source/Utilities/Graphics/AlphaTexture2D.cs
+++ b/Source/Utilities/Graphics/AlphaTexture2D.cs
@@ -36,15 +36,10 @@ namespace OpenTK.Graphics
///
/// Encapsulates an OpenGL texture.
///
- class AlphaTexture2D : IGraphicsResource
+ class AlphaTexture2D : Texture2D
{
#region Fields
- GraphicsContext context;
- int id;
- int width, height;
- bool disposed;
-
#endregion
#region Constructors
@@ -53,174 +48,20 @@ namespace OpenTK.Graphics
/// Constructs a new Texture.
///
public AlphaTexture2D(int width, int height)
- {
- Width = width;
- Height = height;
- }
-
- #endregion
-
- #region IGraphicsResource Members
-
- GraphicsContext IGraphicsResource.Context { get { return context; } }
-
- int IGraphicsResource.Id
- {
- get
- {
- if (id == 0)
- {
- GraphicsContext.Assert();
- context = GraphicsContext.CurrentContext;
-
- id = GL.GenTexture();
- if (id == 0)
- throw new GraphicsResourceException(String.Format("Texture creation failed, (Error: {0})", GL.GetError()));
-
- // Ensure the texture is allocated.
- GL.BindTexture(TextureTarget.Texture2D, id);
- GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMinFilter, (int)All.Linear);
- GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMagFilter, (int)All.Linear);
- if (GL.SupportsExtension("Version12"))
- {
- GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapS, (int)All.ClampToEdge);
- GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapT, (int)All.ClampToEdge);
- }
- else
- {
- GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapS, (int)All.Clamp);
- GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapT, (int)All.Clamp);
- }
-
- GL.TexImage2D(TextureTarget.Texture2D, 0, PixelInternalFormat.Alpha, Width, Height, 0,
- OpenTK.Graphics.PixelFormat.Rgba, PixelType.UnsignedByte, IntPtr.Zero);
- }
-
- return id;
- }
- }
+ : base(width, height)
+ { }
#endregion
#region Public Members
- #region public int Width
-
- /// Gets the width of the texture.
- public int Width { get { return width; } private set { width = value; } }
-
#endregion
- #region public int Height
+ #region Protected Members
- /// Gets the height of the texture.
- public int Height { get { return height; } private set { height = value; } }
-
- #endregion
-
- #region WriteRegion
-
- public void WriteRegion(Rectangle source, Rectangle target, int mipLevel, Bitmap bitmap)
+ protected override PixelInternalFormat InternalFormat
{
- if (bitmap == null)
- throw new ArgumentNullException("data");
-
- GraphicsUnit unit = GraphicsUnit.Pixel;
-
- if (!bitmap.GetBounds(ref unit).Contains(source))
- throw new InvalidOperationException("The source Rectangle is larger than the Bitmap.");
-
- if (mipLevel < 0)
- throw new ArgumentOutOfRangeException("mipLevel");
-
- Bind();
-
- BitmapData data = bitmap.LockBits(source, ImageLockMode.ReadOnly, System.Drawing.Imaging.PixelFormat.Format32bppArgb);
-
- GL.PushClientAttrib(ClientAttribMask.ClientPixelStoreBit);
- try
- {
- GL.PixelStore(PixelStoreParameter.UnpackAlignment, 1);
- GL.PixelStore(PixelStoreParameter.UnpackRowLength, bitmap.Width);
- GL.TexSubImage2D(TextureTarget.Texture2D, mipLevel,
- target.Left, target.Top,
- target.Width, target.Height,
- OpenTK.Graphics.PixelFormat.Rgba,
- PixelType.UnsignedByte, data.Scan0);
- }
- finally
- {
- GL.PopClientAttrib();
- }
-
- bitmap.UnlockBits(data);
- }
-
- public void WriteRegion(TextureRegion2D region, int mipLevel)
- {
- if (mipLevel < 0)
- throw new ArgumentOutOfRangeException("miplevel");
-
- GL.TexSubImage2D(TextureTarget.Texture2D, mipLevel,
- region.Rectangle.X, region.Rectangle.Y,
- region.Rectangle.Width, region.Rectangle.Height,
- PixelFormat.Bgra, PixelType.UnsignedByte, region);
- }
-
- #endregion
-
- #region ReadRegion
-
- public TextureRegion2D ReadRegion(Rectangle rect, int mipLevel)
- {
- if (mipLevel < 0)
- throw new ArgumentOutOfRangeException("miplevel");
-
- TextureRegion2D region = new TextureRegion2D(rect);
-
- GL.GetTexImage(TextureTarget.Texture2D, mipLevel, PixelFormat.Bgra, PixelType.UnsignedByte, region.Data);
-
- return region;
- }
-
- #endregion
-
- #region Bind
-
- public void Bind()
- {
- GL.BindTexture(TextureTarget.Texture2D, (this as IGraphicsResource).Id);
- }
-
- #endregion
-
- #endregion
-
- #region IDisposable Members
-
- public void Dispose()
- {
- Dispose(true);
- GC.SuppressFinalize(this);
- }
-
- void Dispose(bool manual)
- {
- if (!disposed)
- {
- if (manual)
- {
- GL.DeleteTexture(id);
- }
- disposed = true;
- }
- }
-
- ~AlphaTexture2D()
- {
- GraphicsContext context = (this as IGraphicsResource).Context;
- if (context != null)
- (context as IGraphicsContextInternal).RegisterForDisposal(this);
+ get { return PixelInternalFormat.Alpha; }
}
#endregion
diff --git a/Source/Utilities/Graphics/Texture2D.cs b/Source/Utilities/Graphics/Texture2D.cs
new file mode 100644
index 00000000..6ab7cbc1
--- /dev/null
+++ b/Source/Utilities/Graphics/Texture2D.cs
@@ -0,0 +1,259 @@
+#region License
+//
+// The Open Toolkit Library License
+//
+// Copyright (c) 2006 - 2008 the Open Toolkit library, except where noted.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights to
+// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
+// the Software, and to permit persons to whom the Software is furnished to do
+// so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in all
+// copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+// OTHER DEALINGS IN THE SOFTWARE.
+//
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Text;
+using System.Drawing;
+using System.Drawing.Imaging;
+
+namespace OpenTK.Graphics
+{
+ abstract class Texture2D : IGraphicsResource
+ {
+ #region Fields
+
+ GraphicsContext context;
+ int id;
+ int width, height;
+ bool disposed;
+
+ TextureMagFilter mag_filter = TextureMagFilter.Linear;
+ TextureMinFilter min_filter = TextureMinFilter.Linear;
+
+ #endregion
+
+ #region Constructors
+
+ public Texture2D(int width, int height)
+ {
+ if (width <= 0)
+ throw new ArgumentOutOfRangeException("width");
+
+ if (height <= 0)
+ throw new ArgumentOutOfRangeException("height");
+
+ Width = width;
+ Height = height;
+ }
+
+ #endregion
+
+ #region Public Members
+
+ #region public int Width
+
+ /// Gets the width of the texture.
+ public int Width { get { return width; } private set { width = value; } }
+
+ #endregion
+
+ #region public int Height
+
+ /// Gets the height of the texture.
+ public int Height { get { return height; } private set { height = value; } }
+
+ #endregion
+
+ #region MagnificationFilter
+
+ public TextureMagFilter MagnificationFilter
+ {
+ get { return mag_filter; }
+ set { mag_filter = value; }
+ }
+
+ #endregion
+
+ #region MinificationFilter
+
+ public TextureMinFilter MinificationFilter
+ {
+ get { return min_filter; }
+ set { min_filter = value; }
+ }
+
+ #endregion
+
+ #region Bind
+
+ public void Bind()
+ {
+ GL.BindTexture(TextureTarget.Texture2D, (this as IGraphicsResource).Id);
+ }
+
+ #endregion
+
+ #region WriteRegion
+
+ public void WriteRegion(Rectangle source, Rectangle target, int mipLevel, Bitmap bitmap)
+ {
+ if (bitmap == null)
+ throw new ArgumentNullException("data");
+
+ GraphicsUnit unit = GraphicsUnit.Pixel;
+
+ if (!bitmap.GetBounds(ref unit).Contains(source))
+ throw new InvalidOperationException("The source Rectangle is larger than the Bitmap.");
+
+ if (mipLevel < 0)
+ throw new ArgumentOutOfRangeException("mipLevel");
+
+ Bind();
+
+ BitmapData data = null;
+
+ GL.PushClientAttrib(ClientAttribMask.ClientPixelStoreBit);
+ try
+ {
+ data = bitmap.LockBits(source, ImageLockMode.ReadOnly, System.Drawing.Imaging.PixelFormat.Format32bppArgb);
+ GL.PixelStore(PixelStoreParameter.UnpackAlignment, 1);
+ GL.PixelStore(PixelStoreParameter.UnpackRowLength, bitmap.Width);
+ GL.TexSubImage2D(TextureTarget.Texture2D, mipLevel,
+ target.Left, target.Top,
+ target.Width, target.Height,
+ OpenTK.Graphics.PixelFormat.Rgba,
+ PixelType.UnsignedByte, data.Scan0);
+ }
+ finally
+ {
+ GL.PopClientAttrib();
+ if (data != null)
+ bitmap.UnlockBits(data);
+ }
+ }
+
+ #endregion
+
+ #region ReadRegion
+
+ public TextureRegion2D ReadRegion(Rectangle rect, int mipLevel)
+ {
+ if (mipLevel < 0)
+ throw new ArgumentOutOfRangeException("miplevel");
+
+ TextureRegion2D region = new TextureRegion2D(rect);
+
+ GL.GetTexImage(TextureTarget.Texture2D, mipLevel, PixelFormat.Bgra, PixelType.UnsignedByte, region.Data);
+
+ return region;
+ }
+
+ #endregion
+
+ #endregion
+
+ #region Protected Members
+
+ #region InternalFormat
+
+ protected abstract PixelInternalFormat InternalFormat { get; }
+
+ #endregion
+
+ #endregion
+
+ #region IGraphicsResource Members
+
+ #region IGraphicsResource.Context
+
+ GraphicsContext IGraphicsResource.Context { get { return context; } }
+
+ #endregion
+
+ #region IGraphicsResource.Id
+
+ int IGraphicsResource.Id
+ {
+ get
+ {
+ if (id == 0)
+ {
+ GraphicsContext.Assert();
+ context = GraphicsContext.CurrentContext;
+
+ id = GL.GenTexture();
+ if (id == 0)
+ throw new GraphicsResourceException(String.Format("Texture creation failed, (Error: {0})", GL.GetError()));
+
+ // Ensure the texture is allocated.
+ GL.BindTexture(TextureTarget.Texture2D, id);
+ GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMinFilter, (int)All.Linear);
+ GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMagFilter, (int)All.Linear);
+ if (GL.SupportsExtension("Version12"))
+ {
+ GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapS, (int)All.ClampToEdge);
+ GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapT, (int)All.ClampToEdge);
+ }
+ else
+ {
+ GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapS, (int)All.Clamp);
+ GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapT, (int)All.Clamp);
+ }
+
+ GL.TexImage2D(TextureTarget.Texture2D, 0, InternalFormat, Width, Height, 0,
+ OpenTK.Graphics.PixelFormat.Rgba, PixelType.UnsignedByte, IntPtr.Zero);
+ }
+
+ return id;
+ }
+ }
+
+ #endregion
+
+ #endregion
+
+ #region IDisposable Members
+
+ public void Dispose()
+ {
+ Dispose(true);
+ GC.SuppressFinalize(this);
+ }
+
+ void Dispose(bool manual)
+ {
+ if (!disposed)
+ {
+ if (manual)
+ {
+ GL.DeleteTexture(id);
+ }
+ disposed = true;
+ }
+ }
+
+ ~Texture2D()
+ {
+ GraphicsContext context = (this as IGraphicsResource).Context;
+ if (context != null)
+ (context as IGraphicsContextInternal).RegisterForDisposal(this);
+ }
+
+ #endregion
+ }
+}