changeset 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 c81342b54ef2
children f9f5e04f20b2
files codeDoc/jobs.txt data/conf/options.mtt mde/exception.d mde/gl/draw.d mde/gl/tex2d.d mde/gl/texture.d mde/scheduler/Init.d mde/sdl.d
diffstat 8 files changed, 147 insertions(+), 33 deletions(-) [+]
line wrap: on
line diff
--- a/codeDoc/jobs.txt	Thu Jun 05 18:05:22 2008 +0100
+++ b/codeDoc/jobs.txt	Tue Jun 10 17:35:13 2008 +0100
@@ -8,8 +8,7 @@
 
 To do (importance 0-5: 0 pointless, 1 no obvious impact now, 2 todo sometime, 3 useful, 4 important, 5 urgent):
 Also see todo.txt and FIXME/NOTE comment marks.
-5   mergetag crashes with no ending > on a tag and doesn't add header data when comments are included!
-4   LCD filtering / fonts from Options. Get yMax for font not all glyphs on line?
+4   Fonts from Options. Get yMax for font not all glyphs on line?
 4   Not guaranteed to catch up-click ending callback! Appears not to be a problem...
 4   OutOfMemoryException is not currently checked for − it should be at least in critical places (use high-level catching of all errors?).
 3   on-event draw support (mde.events and GUI need to tell mde.mde)
@@ -52,3 +51,5 @@
 
 
 Done (for git log message):
+Implemented gl.texture module to load textures from file (untested).
+Fixed log level/option setting in Init.
\ No newline at end of file
--- a/data/conf/options.mtt	Thu Jun 05 18:05:22 2008 +0100
+++ b/data/conf/options.mtt	Tue Jun 10 17:35:13 2008 +0100
@@ -3,8 +3,7 @@
 <bool|useThreads=false>
 <bool|exitImmediately=false>
 <char[]|L10n="en-GB">
-<int|logLevel=1>
-<int|logOptions=0x1003>
+<int|logOptions=0x3001>
 <double|pollInterval=0.01>
 
 {font}
--- a/mde/exception.d	Thu Jun 05 18:05:22 2008 +0100
+++ b/mde/exception.d	Tue Jun 10 17:35:13 2008 +0100
@@ -66,6 +66,17 @@
     }
 }
 
+/// Thrown when an image fails to load or cannot be loaded to a texture (unsupported format?).
+class ImageException : mdeException {
+    char[] getSymbol () {
+        return super.getSymbol ~ ".gl.texture";
+    }
+    this (char[] msg) {
+        super (msg);
+    }
+}
+
+
 debug (mdeUnitTest) {
     import tango.util.log.Log : Log, Logger;
 
--- a/mde/gl/draw.d	Thu Jun 05 18:05:22 2008 +0100
+++ b/mde/gl/draw.d	Tue Jun 10 17:35:13 2008 +0100
@@ -41,9 +41,10 @@
     debug FontStyle.drawTexture;
     
     GLenum err = glGetError();
-    if (err != GL_NO_ERROR) {
+    while (err != GL_NO_ERROR) {
         char[128] tmp;
         logger.error (logger.format (tmp, "GL error: {}", err));
+        err = glGetError();
     }
     
     glFinish();		// Use Finish rather than Flush to make sure gl is ready to swap buffers
--- a/mde/gl/tex2d.d	Thu Jun 05 18:05:22 2008 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,20 +0,0 @@
-/* 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/>. */
-
-/// Experiment for texturing
-module mde.gl.tex2d;
-
-import derelict.opengl.gl;
-
--- /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;
+    }
+}
+
--- a/mde/scheduler/Init.d	Thu Jun 05 18:05:22 2008 +0100
+++ b/mde/scheduler/Init.d	Tue Jun 10 17:35:13 2008 +0100
@@ -50,6 +50,7 @@
 // Derelict imports
 import derelict.opengl.gl;
 import derelict.sdl.sdl;
+import derelict.sdl.image;
 import derelict.freetype.ft;
 import derelict.util.exception;
 
@@ -160,9 +161,9 @@
         Logger root;
 	try {
             enum LOG {
-                LEVEL	= 0x10,		// mask for log level
-                CONSOLE	= 0x1001,	// log to console?
-                ROLLFILE= 0x1002	// use Rolling/Switching File Appender?
+                LEVEL	= 0xF,		// mask for log level
+                CONSOLE	= 0x1000,	// log to console?
+                ROLLFILE= 0x2000	// use Rolling/Switching File Appender?
             }
             
 	    // Where logging is done to is determined at compile-time, currently just via static ifs.
@@ -170,7 +171,7 @@
 	    root.clearAppenders;	// we may no longer want to log to the console
 	    
             // Now re-set the logging level, using the value from the config file:
-            Log.getRootLogger.setLevel (cast(Log.Level) (miscOpts.logOptions & LOG.LEVEL), true);
+            root.setLevel (cast(Log.Level) (miscOpts.logOptions & LOG.LEVEL), true);
             
             // Log to a file (first appender so root seperator messages don't show on console):
             if (miscOpts.logOptions & LOG.ROLLFILE) {
@@ -207,6 +208,7 @@
         * Also means that init functions aren't run if a library fails to load. */
         try {
             DerelictSDL.load();
+            DerelictSDLImage.load();
             DerelictGL.load();
             DerelictFT.load();
         } catch (DerelictException de) {
--- a/mde/sdl.d	Thu Jun 05 18:05:22 2008 +0100
+++ b/mde/sdl.d	Tue Jun 10 17:35:13 2008 +0100
@@ -122,15 +122,22 @@
     /* Now (must be done after GL context is created) we can try to load later version.
      * The initial loading provides opengl 1.1 features.
      *
+     * 1.4 is now used for glBlendColor (coloured text).
+     *
      * Currently the latest version used is 1.3; adjust this as necessary. However, before using
      * features from any OpenGL version > 1.1 a check must be made on what was loaded by calling
      * DerelictGL.availableVersion(). Note that availableVersion() could be used instead to load
      * the highest supported version but this way we know what we're getting.
      */
-    try {
-        DerelictGL.loadVersions(GLVersion.Version13);
+    if (DerelictGL.availableVersion < GLVersion.Version13) {
+        logger.fatal ("Required at least OpenGL 1.3");
+        setInitFailure;
+        return;
+    }
+    /+try {
+        DerelictGL.loadVersions(GLVersion.Version14);
     } catch (SharedLibProcLoadException e) {
-        logger.warn ("Loading OpenGL version 1.3 failed:");
+        logger.warn ("Loading OpenGL version 1.4 failed:");
         logger.warn (e.msg);
         
         //NOTE: might be worth guaranteeing a minimal version to save later checks?
@@ -138,7 +145,7 @@
         setInitFailure ();
         return;
         +/
-    }
+    }+/
     
     // OpenGL stuff:
     glSetup();