diff mde/gl/texture.d @ 55:f3d8c0441408

Implemented gl.texture (without testing) & fixed log options adjusted previously. Implemented gl.texture module to load textures from file (untested). Fixed log level/option setting in Init.
author Diggory Hardy <diggory.hardy@gmail.com>
date Tue, 10 Jun 2008 17:35:13 +0100
parents
children 960206198cbd
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mde/gl/texture.d	Tue Jun 10 17:35:13 2008 +0100
@@ -0,0 +1,113 @@
+/* LICENSE BLOCK
+Part of mde: a Modular D game-oriented Engine
+Copyright © 2007-2008 Diggory Hardy
+
+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 2 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/>. */
+
+/** Simple module for loading images.
+*/
+module mde.resource.image;
+
+import mde.resource.exception;
+
+import tango.std.stringz;
+
+import derelict.sdl.sdl;
+import derelict.sdl.image;
+import derelict.opengl.gl;
+
+/// The usual texture....
+alias Texture!(GL_TEXTURE_2D) Texture2D;
+
+/** Represents a texture. */
+class Texture(TARGET)
+{
+    static assert (TARGET == GL_TEXTURE_1D ||
+            TARGET == GL_TEXTURE_2D ||
+            TARGET == GL_TEXTURE_3D ||
+                    TARGET == GL_TEXTURE_CUBE_MAP);
+    
+    /** Create a new Texture.
+     *
+     * The Texture is not associated with an OpenGL texture name until load is called.
+     *
+     * Params:
+     *  components = The number of components per pixel, 3 (RGB) or 4 (RGBA), or 0 in which case
+     *  	components is derived from the image loaded.
+     */
+    this (ubyte components) {
+        components_ = components;
+    }
+    /// Free the texture ID.
+    ~this () {
+        glDeleteTextures(1, &texID);
+    }
+    
+    /// Bind as current opengl texture.
+    void bind () {
+        assert (texID != 0, "No texture loaded yet!");
+        glBindTexture (TARGET, texID);
+    }
+    
+    /// Load from a file
+    void load (char[] file) {
+        static assert (TARGET == GL_TEXTURE_2D);	// no other support
+        
+        assert (texID == 0, "Texture already loaded.");
+        glGenTextures (1, &texID);
+        bind;
+        
+        SDL_Surface* image;
+        image = IMG_Load (toStringz(file));
+        if (image is null)
+            throw new ImageException ("Unable to load "~file);
+        // SDL_Surfaces sometimes need locking... really just for spec compliance:
+        assert (!SDL_MUSTLOCK(image), "Didn't expect to have to lock a surface loaded from a file; no locks used!");
+        
+        GLenum format;
+        if (image.format.BytesPerPixel == 3)
+            format = GL_RGB;
+        else if (image.format.BytesPerPixel == 4)
+            format = GL_RGBA;
+        else
+            throw new ImageException ("Only 8-bit-per-channel RGB/RGBA images are supported");
+        
+        // Assume format is RGB(A); i.e. don't bother checking what
+        // image.format.[RGBA]mask/shift/loss are.
+        
+        if (components_ == 0)
+            components_ = image.format.BytesPerPixel;
+        
+        if (image.pitch != image.w)
+            throw new ImageException ("pitch != width; this is unsupported");
+        
+        glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
+        glPixelStorei (GL_UNPACK_ROW_LENGTH, 0);
+        glTexImage2D(TARGET, 0, components_,
+                     w, h, 0,
+                     format, GL_UNSIGNED_BYTE, image.pixels);
+        
+        SDL_FreeSurface (image);
+    }
+    
+    int width () {	return w;	}
+    int height () {	return h;	}
+    /// 3 for RGB, 4 for RGBA, 0 if no image loaded and format will be derived from the image.
+    ubyte components () {	return components_;	}
+    
+    private {
+        int w, h;		// size
+        ubyte components_ = 0;	// 3 for RGB, 4 for RGBA
+        uint texID = 0;
+    }
+}
+