123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132 |
- // SuperTux Editor
- // Copyright (C) 2006 Matthias Braun <matze@braunis.de>
- //
- // This program is free software: you can redistribute it and/or modify
- // it under the terms of the GNU General Public License as published by
- // the Free Software Foundation, either version 3 of the License, or
- // (at your option) any later version.
- //
- // This program is distributed in the hope that it will be useful,
- // but WITHOUT ANY WARRANTY; without even the implied warranty of
- // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- // GNU General Public License for more details.
- //
- // You should have received a copy of the GNU General Public License
- // along with this program. If not, see <http://www.gnu.org/licenses/>.
- using System;
- using OpenGl;
- using System.IO;
- namespace Drawing
- {
- public sealed class ImageTexture : Texture
- {
- public float ImageWidth;
- public float ImageHeight;
- public int refcount;
- /// <summary>
- /// Reference to the Gdk.Pixbuf containing the texture image. Needed for lazy loading textures
- /// </summary>
- private Gdk.Pixbuf pixbuf;
- public ImageTexture(Stream input)
- {
- Gdk.Pixbuf pixbuf = new Gdk.Pixbuf(input);
- uint width = (uint)pixbuf.Width;
- uint height = (uint)pixbuf.Height;
- // Round to next power-of-two isn't needed with newer OpenGL versions
- if (!GlHelper.HasExtension("GL_ARB_texture_non_power_of_two")) {
- width = NextPowerOfTwo((uint)width);
- height = NextPowerOfTwo((uint)height);
- }
- Gdk.Pixbuf target = new Gdk.Pixbuf(Gdk.Colorspace.Rgb, true, 8, (int)width, (int)height);
- pixbuf.CopyArea(0, 0, pixbuf.Width, pixbuf.Height, target, 0, 0);
- ImageWidth = (float) pixbuf.Width;
- ImageHeight = (float) pixbuf.Height;
- this.width = (uint)target.Width;
- this.height = (uint)target.Height;
- this.pixbuf = target;
- }
- protected override void Create()
- {
- // Not needed on newer OpenGL
- if (!GlHelper.HasExtension("GL_ARB_texture_non_power_of_two"))
- {
- if(!IsPowerOf2(width) || !IsPowerOf2(height))
- throw new Exception("Texture size must be power of 2");
- }
- GlUtil.Assert("before creating texture");
- CreateTexture();
- try {
- gl.BindTexture(gl.TEXTURE_2D, Handle);
- gl.TexImage2D(gl.TEXTURE_2D, 0, (int)gl.RGBA,
- (int) width, (int) height, 0, (pixbuf.HasAlpha ? gl.RGBA : gl.RGB),
- gl.UNSIGNED_BYTE, pixbuf.Pixels);
- GlUtil.Assert("creating texture (too big?)");
- SetTextureParams();
- this.pixbuf = null; //gc can take it now
- } catch(Exception) {
- uint[] handles = { Handle };
- gl.DeleteTextures(1, handles);
- throw;
- }
- }
- private static uint NextPowerOfTwo(uint val)
- {
- uint result = 1;
- while(result < val)
- result *= 2;
- return result;
- }
- public float UVRight
- {
- get
- {
- return ImageWidth / (float) Width;
- }
- }
- public float UVBottom
- {
- get
- {
- return ImageHeight / (float) Height;
- }
- }
- public void Ref()
- {
- refcount++;
- }
- public void UnRef()
- {
- refcount--;
- if(refcount == 0)
- Dispose();
- }
- }
- }
- /* EOF */
|