ImageTexture.cs 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132
  1. // SuperTux Editor
  2. // Copyright (C) 2006 Matthias Braun <matze@braunis.de>
  3. //
  4. // This program is free software: you can redistribute it and/or modify
  5. // it under the terms of the GNU General Public License as published by
  6. // the Free Software Foundation, either version 3 of the License, or
  7. // (at your option) any later version.
  8. //
  9. // This program is distributed in the hope that it will be useful,
  10. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. // GNU General Public License for more details.
  13. //
  14. // You should have received a copy of the GNU General Public License
  15. // along with this program. If not, see <http://www.gnu.org/licenses/>.
  16. using System;
  17. using OpenGl;
  18. using System.IO;
  19. namespace Drawing
  20. {
  21. public sealed class ImageTexture : Texture
  22. {
  23. public float ImageWidth;
  24. public float ImageHeight;
  25. public int refcount;
  26. /// <summary>
  27. /// Reference to the Gdk.Pixbuf containing the texture image. Needed for lazy loading textures
  28. /// </summary>
  29. private Gdk.Pixbuf pixbuf;
  30. public ImageTexture(Stream input)
  31. {
  32. Gdk.Pixbuf pixbuf = new Gdk.Pixbuf(input);
  33. uint width = (uint)pixbuf.Width;
  34. uint height = (uint)pixbuf.Height;
  35. // Round to next power-of-two isn't needed with newer OpenGL versions
  36. if (!GlHelper.HasExtension("GL_ARB_texture_non_power_of_two")) {
  37. width = NextPowerOfTwo((uint)width);
  38. height = NextPowerOfTwo((uint)height);
  39. }
  40. Gdk.Pixbuf target = new Gdk.Pixbuf(Gdk.Colorspace.Rgb, true, 8, (int)width, (int)height);
  41. pixbuf.CopyArea(0, 0, pixbuf.Width, pixbuf.Height, target, 0, 0);
  42. ImageWidth = (float) pixbuf.Width;
  43. ImageHeight = (float) pixbuf.Height;
  44. this.width = (uint)target.Width;
  45. this.height = (uint)target.Height;
  46. this.pixbuf = target;
  47. }
  48. protected override void Create()
  49. {
  50. // Not needed on newer OpenGL
  51. if (!GlHelper.HasExtension("GL_ARB_texture_non_power_of_two"))
  52. {
  53. if(!IsPowerOf2(width) || !IsPowerOf2(height))
  54. throw new Exception("Texture size must be power of 2");
  55. }
  56. GlUtil.Assert("before creating texture");
  57. CreateTexture();
  58. try {
  59. gl.BindTexture(gl.TEXTURE_2D, Handle);
  60. gl.TexImage2D(gl.TEXTURE_2D, 0, (int)gl.RGBA,
  61. (int) width, (int) height, 0, (pixbuf.HasAlpha ? gl.RGBA : gl.RGB),
  62. gl.UNSIGNED_BYTE, pixbuf.Pixels);
  63. GlUtil.Assert("creating texture (too big?)");
  64. SetTextureParams();
  65. this.pixbuf = null; //gc can take it now
  66. } catch(Exception) {
  67. uint[] handles = { Handle };
  68. gl.DeleteTextures(1, handles);
  69. throw;
  70. }
  71. }
  72. private static uint NextPowerOfTwo(uint val)
  73. {
  74. uint result = 1;
  75. while(result < val)
  76. result *= 2;
  77. return result;
  78. }
  79. public float UVRight
  80. {
  81. get
  82. {
  83. return ImageWidth / (float) Width;
  84. }
  85. }
  86. public float UVBottom
  87. {
  88. get
  89. {
  90. return ImageHeight / (float) Height;
  91. }
  92. }
  93. public void Ref()
  94. {
  95. refcount++;
  96. }
  97. public void UnRef()
  98. {
  99. refcount--;
  100. if(refcount == 0)
  101. Dispose();
  102. }
  103. }
  104. }
  105. /* EOF */