void SDLWindow::updateSize(bool reinit) {
	
	const SDL_VideoInfo * vid = SDL_GetVideoInfo();
	
	DisplayMode oldMode(size_, depth_);
	
	size_ = Vec2i(vid->current_w, vid->current_h);
	depth_ = vid->vfmt->BitsPerPixel;
	
	// Finally, set the viewport for the newly created device
	arx_assert(renderer != NULL);
	
#if ARX_PLATFORM == ARX_PLATFORM_WIN32
	// use reinit as-is
#elif ARX_PLATFORM == ARX_PLATFORM_LINUX || ARX_PLATFORM == ARX_PLATFORM_BSD
	reinit = false; // Never needed under linux & bsd
#else
	reinit = true; // By default, always reinit to avoid issues on untested platforms
#endif
	
	if(reinit && !reinterpret_cast<OpenGLRenderer *>(renderer)->isInitialized()) {
		reinterpret_cast<OpenGLRenderer *>(renderer)->reinit();
		renderer->SetViewport(Rect(size_.x, size_.y));
		onRendererInit();
	} else {
		renderer->SetViewport(Rect(size_.x, size_.y));
	}
	
	if(size_ != oldMode.resolution) {
		onResize(size_.x, size_.y);
	}
}
bool SDLWindow::initialize(const std::string & title, Vec2i size, bool fullscreen,
                           unsigned depth) {
	
	arx_assert(!displayModes.empty());
	
	SDL_SetEventFilter(eventFilter);
	
	SDL_EventState(SDL_ACTIVEEVENT, SDL_ENABLE);
	SDL_EventState(SDL_QUIT, SDL_ENABLE);
	SDL_EventState(SDL_SYSWMEVENT, SDL_IGNORE);
	SDL_EventState(SDL_VIDEORESIZE, SDL_ENABLE);
	SDL_EventState(SDL_VIDEOEXPOSE, SDL_ENABLE);
	SDL_EventState(SDL_USEREVENT, SDL_IGNORE);
	
	SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
	SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 16);

	SDL_GL_SetAttribute(SDL_GL_SWAP_CONTROL, config.video.vsync ? 1 : 0);
	
	size_ = Vec2i_ZERO;
	depth_ = 0;
	
	for(int msaa = config.video.antialiasing ? 8 : 1; msaa >= 0; msaa--) {
		
		if(msaa > 1) {
			SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS, 1);
			SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, msaa);
		} else if(msaa > 0) {
			SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS, 0);
			SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, 0);
		} else {
			LogError << "Failed to initialize SDL Window: " << SDL_GetError();
			return false;
		}
		
		if(setMode(DisplayMode(size, fullscreen ? depth : 0), fullscreen)) {
			break;
		}
	}
	
	isFullscreen_ = fullscreen;
	
	SDL_WM_SetCaption(title.c_str(), title.c_str());
	title_ = title;
	
	SDL_ShowCursor(SDL_DISABLE);
	
	onCreate();
	
	renderer = new OpenGLRenderer;
	renderer->Initialize();
	
	updateSize(false);
	
	onShow(true);
	onFocus(true);
	
	onRendererInit();
	
	return true;
}
void OpenGLRenderer::reinit() {
	
	arx_assert(!isInitialized());
	
	m_hasTextureNPOT = GLEW_ARB_texture_non_power_of_two || GLEW_VERSION_2_0;
	if(!m_hasTextureNPOT) {
		LogWarning << "Missing OpenGL extension ARB_texture_non_power_of_two.";
	} else if(!GLEW_VERSION_3_0) {
		GLint max = 0;
		glGetIntegerv(GL_MAX_TEXTURE_SIZE, &max);
		if(max < 8192) {
			LogWarning << "Old hardware detected, ignoring OpenGL extension ARB_texture_non_power_of_two.";
			m_hasTextureNPOT = false;
		}
	}
	
	useVertexArrays = true;
	
	if(!GLEW_ARB_draw_elements_base_vertex) {
		LogWarning << "Missing OpenGL extension ARB_draw_elements_base_vertex!";
	}
	
	useVBOs = useVertexArrays;
	if(useVBOs && !GLEW_ARB_map_buffer_range) {
		LogWarning << "Missing OpenGL extension ARB_map_buffer_range, VBO performance will suffer.";
	}

	resetStateCache();
	
	SetRenderState(ZBias, true);
	
	glEnable(GL_DEPTH_TEST);
	SetRenderState(DepthTest, false);
	
	glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
	glPixelStorei(GL_PACK_ALIGNMENT, 1);
	
	// number of conventional fixed-function texture units
	GLint texunits = 0;
	glGetIntegerv(GL_MAX_TEXTURE_UNITS, &texunits);
	m_TextureStages.resize(texunits, NULL);
	for(size_t i = 0; i < m_TextureStages.size(); ++i) {
		m_TextureStages[i] = new GLTextureStage(this, i);
	}
	
	SetRenderState(ColorKey, true);
	
	// Clear screen
	Clear(ColorBuffer | DepthBuffer);
	
	currentTransform = GL_UnsetTransform;
	switchVertexArray(GL_NoArray, 0, 0);
	
	if(useVertexArrays && useVBOs) {
		if(!GLEW_ARB_shader_objects) {
			LogWarning << "Missing OpenGL extension ARB_shader_objects.";
		} else if(!GLEW_ARB_vertex_program) {
			LogWarning << "Missing OpenGL extension ARB_vertex_program.";
		} else {
			shader = loadVertexShader(vertexShaderSource);
		}
		if(!shader) {
			LogWarning << "Missing vertex shader, cannot use vertex arrays for pre-transformed vertices.";
		}
	}
	
	if(GLEW_EXT_texture_filter_anisotropic) {
		glGetFloatv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &maximumAnisotropy);
	}
	
	onRendererInit();
	
}