1 module polyplex;
2 import derelict.sdl2.sdl;
3 import derelict.sdl2.image;
4 import derelict.sdl2.mixer;
5 import derelict.sdl2.ttf;
6 import derelict.vulkan.vulkan;
7 import derelict.opengl;
8 import derelict.openal;
9 import polyplex.utils.logging;
10 import std.stdio;
11 import std.conv;
12 static import std.file;
13 static import std.process;
14 
15 public import polyplex.core;
16 public import polyplex.math;
17 public import polyplex.utils.logging;
18 
19 
20 public static GraphicsBackend ChosenBackend = GraphicsBackend.NoneChosen;
21 private static bool core_init = false;
22 private static bool vk_init = false;
23 private static bool gl_init = false;
24 
25 
26 public enum GraphicsBackend {
27 	Vulkan,
28 	OpenGL,
29 	NoneChosen
30 }
31 
32 private string get_arch() {
33 	version(X86) return "i386";
34 	version(X86_64) return "amd64";
35 	version(ARM) return "arm";
36 	version(AArch64) return "arm64";
37 }
38 
39 private string get_system_lib(string libname, bool s = true) {
40 	string lstr = "libs/"~get_arch()~"/lib"~libname~".so";
41 
42 	string plt = "linux/bsd";
43 	version(Windows) {
44 		lstr = "libs/"~get_arch()~"/"~libname~".dll";
45 		plt = "win32";
46 	}
47 	
48 	version(FreeBSD) {
49 		lstr = "libs/"~get_arch()~"/lib"~libname~"-freebsd.so";
50 		plt = "linux/bsd";
51 	}
52 	
53 	version(OpenBSD) {
54 		lstr = "libs/"~get_arch()~"/lib"~libname~"-openbsd.so";
55 		plt = "linux/bsd";
56 	}
57 
58 	version(OSX) {
59 		lstr = "libs/"~get_arch()~"/lib"~libname~".dylib";
60 		plt = "darwin/osx";
61 	}
62 	Logger.Info("Binding library {0}: [{1} on {2}] from {3}", libname, plt, get_arch(), lstr);
63 	return lstr;
64 }
65 
66 private string trimexe(string input) {
67 	string i = input;
68 	version(Windows) {
69 		while (i[i.length-1] != '\\') {
70 			i.length--;
71 		}
72 		return i;
73 	}
74 	else {
75 		while (i[i.length-1] != '/') {
76 			i.length--;
77 		}
78 		return i;
79 	}
80 }
81 
82 /*
83 	InitLibraries loads the Derelict libraries for Vulkan, SDL and OpenGL
84 */
85 public void InitLibraries() {
86 	if (!core_init) {
87 		if (std.file.exists("libs/")) {
88 			// Load bundled libraries.
89 			Logger.Info("Binding to runtime libraries...");
90 			string path_sep = ":";
91 			string sys_sep = "/";
92 			version(Windows) {
93 				path_sep = ";";
94 				sys_sep = "\\";
95 			}
96 			string path = std.process.environment["PATH"];
97 			string path_begin = std.file.thisExePath();
98 			path_begin = trimexe(path_begin);
99 			std.process.environment["PATH"] = path_begin ~ "libs" ~ sys_sep ~ get_arch() ~ path_sep ~ path;
100 			Logger.Debug("Updated PATH to {0}", std.process.environment["PATH"]);
101 			DerelictSDL2.load(get_system_lib("SDL2"));
102 		} else {
103 			// Load system libraries
104 			Logger.Info("Binding to system libraries....");
105 			DerelictSDL2.load();
106 		}
107 		DerelictAL.load();
108 		SDL_version linked;
109 		SDL_version compiled;
110 		SDL_GetVersion(&linked);
111 		SDL_VERSION(&compiled);
112 		Logger.Log("SDL (compiled against): {0}.{1}.{2}", to!string(compiled.major), to!string(compiled.minor), to!string(compiled.patch), LogType.Info);
113 		Logger.Log("SDL (linked): {0}.{1}.{2}", to!string(linked.major), to!string(linked.minor), to!string(linked.patch), LogType.Info);
114 		core_init = true;
115 	}
116 	if (ChosenBackend == GraphicsBackend.NoneChosen) return;
117 
118 	if (ChosenBackend == GraphicsBackend.Vulkan) {
119 		if (gl_init) DerelictGL3.unload();
120 		gl_init = false;
121 
122 
123 		//Load vulkan... twice...
124 		DerelictVulkan.load();
125 		SDL_Vulkan_LoadLibrary(null);
126 		SDL_VideoInit(null);
127 
128 		vk_init = true;
129 		Logger.Info("Intialized Vulkan... ");
130 
131 		return;
132 	}
133 	else {
134 		if (vk_init) {
135 			DerelictVulkan.unload();
136 			SDL_Vulkan_UnloadLibrary();
137 		}
138 		vk_init = false;
139 		
140 		DerelictGL3.load();
141 		gl_init = true;
142 		Logger.Info("Initialized OpenGL...");
143 	}
144 }