1 module polyplex.core.content.gl.textures; 2 import polyplex.core.content.textures; 3 import derelict.opengl; 4 import derelict.opengl.gl; 5 import polyplex.utils.logging; 6 import polyplex.core.render; 7 import polyplex.core.render.gl.shader; 8 import polyplex.core.color; 9 import std.stdio; 10 11 12 public class GlTexture2D : Texture2D { 13 private GLuint id; 14 15 private static int MAX_TEX_UNITS = -1; 16 17 this(TextureImg img) { 18 super(img); 19 } 20 21 this(Color[][] colors) { 22 super(colors); 23 } 24 25 ~this() { 26 glDeleteTextures(1, &id); 27 } 28 29 /** 30 Binds the texture. 31 */ 32 public override void Bind(int attach_pos = 0, Shader s = null) { 33 if (s is null) { 34 glBindTexture(GL_TEXTURE_2D, id); 35 return; 36 } 37 if (!s.HasUniform("ppTexture")) throw new Exception("Texture2D requires ppTexture sampler2d uniform to attach to!"); 38 int tpos = GL_TEXTURE0+attach_pos; 39 40 if (tpos > MAX_TEX_UNITS) tpos = MAX_TEX_UNITS; 41 if (tpos < GL_TEXTURE0) tpos = GL_TEXTURE0; 42 glActiveTexture(tpos); 43 glBindTexture(GL_TEXTURE_2D, id); 44 } 45 46 /** 47 Unbinds the texture. 48 */ 49 public override void Unbind() { 50 glBindTexture(GL_TEXTURE_2D, 0); 51 } 52 53 protected override void rebuffer() { 54 int mode = GL_RGBA; 55 56 // Delete the current version of the texture in memory, if any. 57 if (id != 0) glDeleteTextures(1, &id); 58 59 // Reallow GL_RGB again in the future? 60 /*if (img.Surface.format.BytesPerPixel == 3) { 61 mode = GL_RGB; 62 }*/ 63 64 // Generate a new texture over the old one, if any. Else just generate a new one and assign id. 65 glGenTextures(1, &id); 66 Bind(); 67 glTexImage2D(GL_TEXTURE_2D, 0, mode, image.Width, image.Height, 0, mode, GL_UNSIGNED_BYTE, image.Pixels.ptr); 68 Unbind(); 69 70 // Set max texture units. 71 if (MAX_TEX_UNITS == -1) { 72 glGetIntegerv(GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS, &MAX_TEX_UNITS); 73 Logger.Info("Set max texture units to: {0}", MAX_TEX_UNITS); 74 } 75 } 76 }