1 /* 2 ******************************************************************************************* 3 * Dgame (a D game framework) - Copyright (c) Randy Schütt 4 * 5 * This software is provided 'as-is', without any express or implied warranty. 6 * In no event will the authors be held liable for any damages arising from 7 * the use of this software. 8 * 9 * Permission is granted to anyone to use this software for any purpose, 10 * including commercial applications, and to alter it and redistribute it 11 * freely, subject to the following restrictions: 12 * 13 * 1. The origin of this software must not be misrepresented; you must not claim 14 * that you wrote the original software. If you use this software in a product, 15 * an acknowledgment in the product documentation would be appreciated but is 16 * not required. 17 * 18 * 2. Altered source versions must be plainly marked as such, and must not be 19 * misrepresented as being the original software. 20 * 21 * 3. This notice may not be removed or altered from any source distribution. 22 ******************************************************************************************* 23 */ 24 module Dgame.Window.Internal.Init; 25 26 private: 27 28 import derelict.sdl2.sdl; 29 import derelict.opengl3.gl; 30 import derelict.sdl2.ttf; 31 import derelict.sdl2.image; 32 import derelict.sdl2.mixer; 33 34 import Dgame.Window.GLContextSettings; 35 import Dgame.Internal.Error; 36 37 shared static this() { 38 DerelictSDL2.load(); 39 DerelictSDL2Image.load(); 40 DerelictSDL2ttf.load(); 41 DerelictSDL2Mixer.load(); 42 DerelictGL.load(); 43 } 44 45 shared static ~this() { 46 if (SDL_WasInit(SDL_INIT_JOYSTICK) != 0) 47 SDL_QuitSubSystem(SDL_INIT_JOYSTICK); 48 if (SDL_WasInit(SDL_INIT_GAMECONTROLLER) != 0) 49 SDL_QuitSubSystem(SDL_INIT_GAMECONTROLLER); 50 51 // quit SDL_image 52 IMG_Quit(); 53 // quit SDL_ttf 54 TTF_Quit(); 55 // quit SDL_mixer 56 Mix_ReserveChannels(0); 57 Mix_CloseAudio(); 58 Mix_Quit(); 59 // quit SDL 60 SDL_Quit(); 61 62 DerelictSDL2Image.unload(); 63 DerelictSDL2ttf.unload(); 64 DerelictSDL2Mixer.unload(); 65 DerelictSDL2.unload(); 66 DerelictGL.unload(); 67 } 68 69 bool _isGLInited = false; 70 bool _isSDLInited = false; 71 72 package(Dgame): 73 74 void _initSDL() { 75 if (_isSDLInited) 76 return; 77 78 debug { 79 SDL_version sdlver = void; 80 SDL_GetVersion(&sdlver); 81 82 print_fmt("SDL version: %d.%d.%d\n", sdlver.major, sdlver.minor, sdlver.patch); 83 } 84 85 scope(exit) _isSDLInited = true; 86 87 // Initialize SDL2 88 int result = SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO); 89 assert_fmt(result == 0, "Error: SDL could not be initialized: %s\n", SDL_GetError()); 90 91 if (SDL_InitSubSystem(SDL_INIT_JOYSTICK) != 0) 92 print_fmt("Warning: No Joystick support\n"); 93 if (SDL_InitSubSystem(SDL_INIT_GAMECONTROLLER) != 0) 94 print_fmt("Warning: No GameController support\n"); 95 96 // Initialize SDL_image 97 result = IMG_Init(IMG_INIT_JPG | IMG_INIT_PNG); 98 assert_fmt(result != 0, "Error: Failed to init the required jpg and png support: %s\n", IMG_GetError()); 99 100 if ((result & IMG_INIT_JPG) == 0) 101 print_fmt("Warning: No jpg support: %s\n", IMG_GetError()); 102 else if ((result & IMG_INIT_PNG) == 0) 103 print_fmt("Warning: No png support: %s\n", IMG_GetError()); 104 105 // Initialize SDL_ttf 106 result = TTF_Init(); 107 assert_fmt(result == 0, "Error: SDL_TTF could not be initialized: %s\n", Mix_GetError()); 108 109 // Initialize SDL_mixer 110 result = Mix_Init(MIX_INIT_OGG | MIX_INIT_MP3); 111 assert_fmt(result != 0, "Error: Failed to init the required ogg and mp3 support: %s\n", Mix_GetError()); 112 113 if ((result & MIX_INIT_OGG) == 0) 114 print_fmt("Warning: No ogg support: %s\n", Mix_GetError()); 115 else if ((result & MIX_INIT_MP3) == 0) 116 print_fmt("Warning: No mp3 support: %s\n", Mix_GetError()); 117 118 result = Mix_OpenAudio(22050, MIX_DEFAULT_FORMAT, MIX_DEFAULT_CHANNELS, 4096); 119 assert_fmt(result == 0, "Warning: Could not open Mix_OpenAudio: %s\n", Mix_GetError()); 120 121 SDL_ClearError(); // Ignore XAudio2 error: http://redmine.audacious-media-player.org/issues/346 122 123 immutable int channels = Mix_AllocateChannels(256); 124 if (channels < 256) 125 print_fmt("Warning: Could not reserve 256 channels, only %d. %s\n", channels, Mix_GetError()); 126 } 127 128 @nogc 129 void _initGLAttr(const GLContextSettings gl) { 130 ubyte majorVersion, minorVersion; 131 132 if (gl.vers == GLContextSettings.Version.Default) { 133 version (OSX) { 134 majorVersion = 2; 135 minorVersion = 1; 136 } 137 } else { 138 majorVersion = gl.vers / 10; 139 minorVersion = gl.vers % 10; 140 } 141 142 if (majorVersion != 0) { 143 int result = SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, majorVersion); 144 assert_fmt(result == 0, "Error by initializing OpenGL: %s\n", SDL_GetError()); 145 146 result = SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, minorVersion); 147 assert_fmt(result == 0, "Error by initializing OpenGL: %s\n", SDL_GetError()); 148 149 debug print_fmt("OpenGL Context created in OpenGL version %d.%d\n", majorVersion, minorVersion); 150 } 151 152 final switch (gl.profile) { 153 case GLContextSettings.Profile.Default: 154 break; 155 case GLContextSettings.Profile.Core: 156 SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE); 157 SDL_GL_SetAttribute(SDL_GL_CONTEXT_FLAGS, SDL_GL_CONTEXT_FORWARD_COMPATIBLE_FLAG); 158 break; 159 case GLContextSettings.Profile.Compatibility: 160 SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_COMPATIBILITY); 161 break; 162 case GLContextSettings.Profile.ES: 163 SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_ES); 164 break; 165 } 166 167 if (gl.antiAlias > 0) { 168 debug print_fmt("Set %d as anti alias level\n", gl.antiAlias); 169 170 int result = SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS, 1); 171 if (result != 0) 172 print_fmt("Could not enable Anti-Alias: %s\n", SDL_GetError()); 173 174 result = SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, gl.antiAlias); 175 if (result != 0) 176 print_fmt("Could not enable Anti-Alias Level %d: %s\n", gl.antiAlias, SDL_GetError()); 177 } 178 179 int result = SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1); 180 assert_fmt(result == 0, "Error by initializing OpenGL: %s\n", SDL_GetError()); 181 182 result = SDL_GL_SetAttribute(SDL_GL_ACCELERATED_VISUAL, 1); 183 assert_fmt(result == 0, "Error by initializing OpenGL: %s\n", SDL_GetError()); 184 } 185 186 void _initGL() { 187 if (_isGLInited) 188 return; 189 190 scope(exit) _isGLInited = true; 191 192 immutable GLVersion glver = DerelictGL.reload(); 193 const char* glverstr = glGetString(GL_VERSION); 194 debug print_fmt("Derelict loaded GL version: %d (%d), available GL version: %s\n", DerelictGL.loadedVersion, glver, glverstr); 195 196 version (OSX) 197 enum GLVersion NEEDED_GL_VERSION = GLVersion.GL21; 198 else 199 enum GLVersion NEEDED_GL_VERSION = GLVersion.GL30; 200 201 assert_fmt(glver >= NEEDED_GL_VERSION, "Your OpenGL version (%d) is too low. Need at least OpenGL 3.0.", glver); 202 203 glDisable(GL_DITHER); 204 glDisable(GL_LIGHTING); 205 glDisable(GL_DEPTH_TEST); 206 glDisable(GL_ALPHA_TEST); 207 208 glEnable(GL_TEXTURE_2D); 209 210 glEnable(GL_BLEND); 211 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); 212 213 glEnable(GL_CULL_FACE); 214 glCullFace(GL_FRONT); 215 216 glEnable(GL_MULTISAMPLE); 217 218 //glShadeModel(GL_SMOOTH); 219 //glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); 220 221 glEnableClientState(GL_VERTEX_ARRAY); 222 glEnableClientState(GL_COLOR_ARRAY); 223 glEnableClientState(GL_TEXTURE_COORD_ARRAY); 224 }