1 module evael.graphics.TextureArray; 2 3 import std.typecons : Flag, Yes, No; 4 5 import evael.graphics.GL; 6 7 import evael.system.Asset; 8 9 import evael.graphics.GraphicsDevice; 10 import evael.graphics.Texture; 11 12 /** 13 * TextureArray. 14 */ 15 class TextureArray 16 { 17 /// Texture array ID 18 private uint m_id; 19 20 /** 21 * TextureArray constructor. 22 */ 23 @nogc @safe 24 public this(in uint id) pure nothrow 25 { 26 this.m_id = id; 27 } 28 29 /** 30 * TextureArray destructor. 31 */ 32 @nogc 33 public void dispose() const nothrow 34 { 35 gl.DeleteBuffers(1, &this.m_id); 36 } 37 38 /** 39 * Builds a texture array from multiple textures. 40 * Params: 41 * textures : textures to load 42 * size : textures width and height 43 * flipTexture : flip each texture ? 44 */ 45 public static TextureArray build(in string[] textures, in int size = 512, in Flag!"flipTextures" flipTextures = Yes.flipTextures) 46 { 47 uint id; 48 gl.GenTextures(1, &id); 49 50 gl.ActiveTexture(GL_TEXTURE2); 51 gl.BindTexture(GL_TEXTURE_2D_ARRAY, id); 52 53 gl.TexImage3D(GL_TEXTURE_2D_ARRAY, 54 0, // mipmap level 55 GL_RGBA8, // gpu texel format 56 size, // width 57 size, // height 58 textures.length, // depth 59 0, // border 60 GL_BGRA, // cpu pixel format 61 GL_UNSIGNED_BYTE, // cpu pixel coord type 62 null); // pixel data 63 64 foreach (i, texture; textures) 65 { 66 auto bytes = Texture.loadBytes(texture); 67 gl.TexSubImage3D(GL_TEXTURE_2D_ARRAY, 0, 0, 0, i, size, size, 1, GL_BGRA, GL_UNSIGNED_BYTE, bytes.ptr); 68 } 69 70 auto minificationFilter = GL_LINEAR; 71 auto magnificationFilter = GL_LINEAR; 72 73 // Anisotropic filter 74 float fLargest; 75 gl.GetFloatv(0x84FF, &fLargest); 76 gl.TexParameterf(GL_TEXTURE_2D_ARRAY, 0x84FE, fLargest); 77 78 // Specify our minification and magnification filters 79 gl.TexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER, minificationFilter); 80 gl.TexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER, magnificationFilter); 81 82 // If we're using MipMaps, then we'll generate them here. 83 // Note: The glGenerateMipmap call requires OpenGL 3.0 as a minimum. 84 if (minificationFilter == GL_LINEAR_MIPMAP_LINEAR || 85 minificationFilter == GL_LINEAR_MIPMAP_NEAREST || 86 minificationFilter == GL_NEAREST_MIPMAP_LINEAR || 87 minificationFilter == GL_NEAREST_MIPMAP_NEAREST) 88 { 89 gl.GenerateMipmap(GL_TEXTURE_2D_ARRAY); 90 } 91 92 gl.BindTexture(GL_TEXTURE_2D_ARRAY, 0); 93 gl.ActiveTexture(GL_TEXTURE20); 94 95 return new TextureArray(id); 96 } 97 98 /** 99 * Properties 100 */ 101 @nogc @safe 102 @property pure nothrow 103 { 104 public uint id() const 105 { 106 return this.m_id; 107 } 108 } 109 } 110