Logo Search packages:      
Sourcecode: f-spot version File versions  Download package

Texture.cs

/* 
 * Texture.cs
 *
 * Copyright 2007 Novell Inc.
 *
 * Author
 *   Larry Ewing <lewing@novell.com>
 *
 * See COPYING for license information.
 *
 */

using System;
using Gtk;
using Tao.OpenGl;
using Cairo;
using System.Runtime.InteropServices;
using FSpot.Widgets;

namespace FSpot {
      // FIXME this class is a hack to have get_data functionality
      // on cairo 1.0.x
      public sealed class MemorySurface : ImageSurface {
            [DllImport ("libfspot")]
            static extern IntPtr f_image_surface_create (Cairo.Format format, int width, int height);
            
            [DllImport ("libfspot")]
            static extern IntPtr f_image_surface_get_data (IntPtr surface);

            [DllImport ("libfspot")]
            static extern Cairo.Format f_image_surface_get_format (IntPtr surface);

            public MemorySurface (Cairo.Format format, int width, int height)
                  : this (f_image_surface_create (format, width, height))
            {
            }

            public MemorySurface (IntPtr handle) : base (handle, true)
            {
                  if (Pixels == IntPtr.Zero)
                        throw new ApplicationException ("Missing image data");
            }

            public IntPtr Pixels {
                  get {
                        return f_image_surface_get_data (Handle);
                  }
            }

            public Cairo.Format Format {
                  get {
                        return f_image_surface_get_format (Handle);
                  }
            }
      }

      public class TextureException : System.Exception {
            public TextureException (string msg) : base (msg)
            {
            }
      }

      public sealed class Texture : IDisposable {
            int texture_id;
            int width;
            int height;
            
            public int Width {
                  get { return width; }
            }

            public int Height {
                  get { return height; }
            }
            
            public int Id {
                  get { return texture_id; }
            }

            public MemorySurface CreateMatchingSurface ()
            {
                  return new MemorySurface (Format.Argb32, width, height);
            }
            
            public Texture (MemorySurface surface) 
                  : this (surface.Width, surface.Height)
            {
                  CopyFromSurface (surface);
            }

            public Texture (Gdk.Pixbuf pixbuf) 
                  : this (pixbuf.Width, pixbuf.Height)
            {
                  MemorySurface surface = CairoUtils.CreateSurface (pixbuf);
                  CopyFromSurface (surface);
                  surface.Destroy ();
            }

            private Texture (int width, int height)
            {
                  this.width = width;
                  this.height = height;
                  
                  Gl.glGenTextures (1, out texture_id);
                  //System.Console.WriteLine ("generated texture.{0} ({1}, {2})", texture_id, width, height); 
            }

            public void Bind ()
            {
                  /*
                  Console.WriteLine ("binding texture {0} is it a texture {1}", 
                                 texture_id, 
                                 Gl.glIsTexture (texture_id));
                  */
                  Gl.glEnable (Gl.GL_TEXTURE_RECTANGLE_ARB);
                  Gl.glBindTexture (Gl.GL_TEXTURE_RECTANGLE_ARB, texture_id);
            }

            public int CopyFromSurface (MemorySurface surface)
            {
                  Bind ();

                  int max_size;
                  Gl.glGetIntegerv (Gl.GL_MAX_RECTANGLE_TEXTURE_SIZE_ARB, out max_size);
                  float scale = (float)Math.Min (1.0, max_size / (double) Math.Max (width, height));
                  System.Console.WriteLine ("max texture size {0} scaling to {1}", max_size, scale);
                  
                  if (surface.Pixels == IntPtr.Zero)
                        throw new TextureException ("Surface has no data");

                  if (surface.Format != Format.Rgb24 && surface.Format != Format.Argb32)
                        throw new TextureException ("Unsupported format type");

                  IntPtr pixels = surface.Pixels;
                  IntPtr tmp = IntPtr.Zero;
                  if (scale != 1.0) {
                        int swidth = (int)(width * scale);
                        int sheight = (int) (height * scale);
                        tmp = Marshal.AllocHGlobal (swidth * sheight * 4);
                        System.Console.WriteLine ("scaling image {0} x {1}", swidth, sheight);

                        Glu.gluScaleImage (Gl.GL_BGRA,
                                      width,
                                      height,
                                      Gl.GL_UNSIGNED_BYTE,
                                      pixels,
                                      swidth,
                                      sheight,
                                      Gl.GL_UNSIGNED_BYTE,
                                      tmp);
                        pixels = tmp;
                        width = swidth;
                        height = sheight;
                  }
                  
                  Gl.glTexImage2D (Gl.GL_TEXTURE_RECTANGLE_ARB,
                               0,
                               Gl.GL_RGBA,
                               width,
                               height,
                               0,
                               Gl.GL_BGRA,
                               Gl.GL_UNSIGNED_BYTE,
                               pixels);
                  

                  if (tmp != IntPtr.Zero)
                        Marshal.FreeHGlobal (tmp);

                  if (Gl.glGetError () != Gl.GL_NO_ERROR)
                        System.Console.WriteLine ("unable to allocate texture");
                  //    throw new TextureException ("Unable to allocate texture resources");

                  return texture_id;
            }

            protected void Close ()
            {
                  System.Console.WriteLine ("Disposing {0} IsTexture {1}", texture_id, Gl.glIsTexture (texture_id));
                  int [] ids = new int [] { texture_id };
                  Gl.glDeleteTextures (1, ids);
                  System.Console.WriteLine ("Done Disposing {0}", ids [0]);
            }

            public void Dispose ()
            {
                  Close ();
                  GC.SuppressFinalize (this);
            }
            /*
            ~Texture ()
            {
                  Close ();
            }
            */

      }
}

Generated by  Doxygen 1.6.0   Back to index