Mercurial > projects > mde
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; + } +} +