1 module unecht.core.assets.texture; 2 3 import unecht.core.component; 4 import unecht.core.object; 5 import unecht.core.serialization.serializer; 6 import unecht.core.defaultInspector; 7 8 import derelict.opengl3.gl3; 9 10 /// 11 enum UETextureFiltering 12 { 13 linear, 14 point, 15 } 16 17 /// 18 enum UETextureRepeat 19 { 20 clamp, 21 repeat 22 } 23 24 /// 25 abstract class UETexture : UEObject 26 { 27 mixin(UERegisterObject!()); 28 29 /// 30 @property int width() const { return _width; } 31 /// 32 @property int height() const { return _height; } 33 34 /// 35 @property UETextureFiltering filter() const { return _filtering; } 36 /// 37 @property UETextureRepeat repeat() const { return _repeat; } 38 /// 39 @property void filter(UETextureFiltering v) { _filtering = v; } 40 /// 41 @property void repeat(UETextureRepeat v) { _repeat = v; } 42 /// 43 @property bool isValid() const { return _glTex != 0; } 44 /// 45 @property void* driverHandle() const { return cast(void*)_glTex; } 46 47 void bind() 48 { 49 glBindTexture(GL_TEXTURE_2D, _glTex); 50 51 setFilter(); 52 53 auto glClamp = GL_CLAMP_TO_EDGE; 54 if(_repeat == UETextureRepeat.repeat) 55 glClamp = GL_REPEAT; 56 57 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); 58 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); 59 } 60 61 void unbind() 62 { 63 glBindTexture(GL_TEXTURE_2D, 0); 64 } 65 66 protected void setFilter() 67 { 68 auto glFiltering = GL_NEAREST; 69 if(_filtering == UETextureFiltering.linear) 70 glFiltering = GL_LINEAR; 71 72 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, glFiltering); 73 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, glFiltering); 74 } 75 76 protected: 77 @Serialize 78 UETextureFiltering _filtering; 79 @Serialize 80 UETextureRepeat _repeat; 81 82 int _width; 83 int _height; 84 85 GLuint _glTex; 86 } 87 88 /// 89 final class UETexture2D : UETexture 90 { 91 import derelict.freeimage.freeimage; 92 93 mixin(UERegisterObject!()); 94 95 /// 96 public void loadFromFile(string path) 97 { 98 import std..string:toStringz; 99 import std.file:exists; 100 101 assert(exists(path)); 102 103 auto fn = toStringz(path); 104 105 FIBITMAP* bitmap = FreeImage_Load(FreeImage_GetFileType(fn, 0), fn); 106 scope(exit) FreeImage_Unload(bitmap); 107 108 createRaw(bitmap); 109 } 110 111 /// 112 public void loadFromMemFile(ubyte[] mem) 113 { 114 auto memHandle = FreeImage_OpenMemory(mem.ptr, mem.length); 115 assert(memHandle); 116 scope(exit) FreeImage_CloseMemory(memHandle); 117 118 auto format = FreeImage_GetFileTypeFromMemory(memHandle, cast(int)mem.length); 119 import unecht.core.logger; 120 import std.conv; 121 log.logf("loadFromMemFile: %s",to!string(format)); 122 123 FIBITMAP* bitmap = FreeImage_LoadFromMemory(format, memHandle); 124 assert(bitmap); 125 scope(exit) FreeImage_Unload(bitmap); 126 127 createRaw(bitmap); 128 } 129 130 private void createRaw(FIBITMAP* _image) 131 { 132 //TODO: check if bits are not 32 first 133 FIBITMAP* pImage = FreeImage_ConvertTo32Bits(_image); 134 scope(exit) FreeImage_Unload(pImage); 135 136 _width = FreeImage_GetWidth(_image); 137 _height = FreeImage_GetHeight(_image); 138 139 assert(pImage !is null); 140 assert(FreeImage_GetBPP(pImage) == 32); 141 142 glGenTextures(1, &_glTex); 143 144 glBindTexture(GL_TEXTURE_2D, _glTex); 145 146 setFilter(); 147 148 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, _width, _height, 149 0, GL_BGRA, GL_UNSIGNED_BYTE, cast(void*)FreeImage_GetBits(pImage)); 150 } 151 } 152 /+ 153 /// 154 final class UETextureCubemap : UETexture 155 { 156 mixin(UERegisterObject!()); 157 158 this(int size) 159 { 160 super(size,size); 161 } 162 163 private: 164 @Serialize 165 UETexture2D[6] faces; 166 } 167 +/