1 module unecht.gl.texture;
2 
3 import derelict.freeimage.freeimage;
4 import derelict.opengl3.gl3;
5 
6 final class GLTexture
7 {
8 	GLuint tex;
9 
10 	bool pointFiltering=false;
11 
12 	void create(string _file, bool _fromMemory=true)
13 	{
14 		if(!_fromMemory)
15 		{
16 			import std.string;
17 			auto fn = toStringz(_file);
18 
19 			FIBITMAP* bitmap = FreeImage_Load(FreeImage_GetFileType(fn, 0), fn);
20 			scope(exit) FreeImage_Unload(bitmap);
21 			createRaw(bitmap);
22 		}
23 		else
24 		{
25 			FIMEMORY* stream;
26 			stream = FreeImage_OpenMemory(cast(ubyte*)_file.ptr, _file.length);
27 			assert(stream);
28 			scope(exit) FreeImage_CloseMemory(stream);
29 
30 			auto ftype = FreeImage_GetFileTypeFromMemory(stream, cast(int)_file.length);
31 
32 			FIBITMAP* bitmap = FreeImage_LoadFromMemory(ftype, stream);
33 			scope(exit) FreeImage_Unload(bitmap);
34 
35 			createRaw(bitmap);
36 		}
37 	}
38 
39     void destroy()
40     {
41         glDeleteTextures(1,&tex);
42         tex = 0;
43     }
44 
45 	private void createRaw(FIBITMAP* _image)
46 	{
47 		//TODO: check if bits are not 32 first
48 		FIBITMAP* pImage = FreeImage_ConvertTo32Bits(_image);
49 		scope(exit) FreeImage_Unload(pImage);
50 		auto nWidth = FreeImage_GetWidth(pImage);
51 		auto nHeight = FreeImage_GetHeight(pImage);
52 		
53 		glGenTextures(1, &tex);
54 		
55 		glBindTexture(GL_TEXTURE_2D, tex);
56 		
57 		glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, nWidth, nHeight,
58 			0, GL_BGRA, GL_UNSIGNED_BYTE, cast(void*)FreeImage_GetBits(pImage));
59 	}
60 
61 	void bind()
62 	{
63 		glBindTexture(GL_TEXTURE_2D, tex);
64 		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, pointFiltering?GL_NEAREST:GL_LINEAR);
65 		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, pointFiltering?GL_NEAREST:GL_LINEAR);
66         //TODO: parameterize
67         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
68         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
69 	}
70 
71 	void unbind()
72 	{
73 		glBindTexture(GL_TEXTURE_2D, 0);
74 	}
75 }