Beispiel #1
0
int SDLScreenDPI(int screen)
{
    int screens = max(1, SDL_GetNumVideoDisplays());
    float ddpi = 200;  // Reasonable default just in case screen 0 gives an error.
    #ifndef __EMSCRIPTEN__
    SDL_GetDisplayDPI(screen, &ddpi, nullptr, nullptr);
    #endif
    return screen >= screens
           ? 0  // Screen not present.
           : (int)(ddpi + 0.5f);
}
GHOST_TUns16
GHOST_WindowSDL::getDPIHint()
{
	int displayIndex = SDL_GetWindowDisplayIndex(m_sdl_win);
	if (displayIndex < 0) {
		return 96;
	}

	float ddpi;
	if (SDL_GetDisplayDPI(displayIndex, &ddpi, NULL, NULL) != 0) {
		return 96;
	}

	return (int)ddpi;
}
float RocketRenderingInterface::GetPixelsPerInch()
{
#if SDL_VERSION_ATLEAST(2, 0, 4)
	auto display = os_config_read_uint("Video", "Display", 0);
	float ddpi;
	if (SDL_GetDisplayDPI(display, &ddpi, nullptr, nullptr) != 0) {
		mprintf(("Failed to determine display DPI: %s\n", SDL_GetError()));
		return 96.f;
	}

	// Diagonal DPI should be accurate enough
	return ddpi;
#else
	// return a default value
	return 96.f;
#endif
}
Beispiel #4
0
    math::vector<float, 2> window::get_dpi() const
    {
        // On macOS we always get a 2x (or larger?) backbuffer on hi-DPI
        // systems, and this is then downsampled by the compositor, depending on
        // the display scale factor. 72 is the default DPI on macOS.

        // On Windows this is not the case; we get a 1x backbuffer on all
        // systems, and we'll have to render the graphics at the proper DPI,
        // which is the DPI of the screen that the window currently resides on.

#if defined(__APPLE__)
        return get_backbuffer_size() / get_size() * 72;
#elif defined (_WIN32)
        int display = SDL_GetWindowDisplayIndex(handle.get());
        assert(display != -1);

        float dpi_x, dpi_y;
        assert(SDL_GetDisplayDPI(display, nullptr, &dpi_x, &dpi_y) != -1);

        return { dpi_x, dpi_y };
#endif
    }
Beispiel #5
0
	value System::GetDisplay (int id) {
		
		if (!init) {
			
			id_bounds = val_id ("bounds");
			id_currentMode = val_id ("currentMode");
			id_dpi = val_id ("dpi");
			id_height = val_id ("height");
			id_name = val_id ("name");
			id_pixelFormat = val_id ("pixelFormat");
			id_refreshRate = val_id ("refreshRate");
			id_supportedModes = val_id ("supportedModes");
			id_width = val_id ("width");
			init = true;
			
		}
		
		int numDisplays = GetNumDisplays ();
		
		if (id < 0 || id >= numDisplays) {
			
			return alloc_null ();
			
		}
		
		value display = alloc_empty_object ();
		alloc_field (display, id_name, alloc_string (SDL_GetDisplayName (id)));
		
		SDL_Rect bounds = { 0, 0, 0, 0 };
		SDL_GetDisplayBounds (id, &bounds);
		alloc_field (display, id_bounds, Rectangle (bounds.x, bounds.y, bounds.w, bounds.h).Value ());
		
		float dpi = 72.0;
		#ifndef EMSCRIPTEN
		SDL_GetDisplayDPI (id, &dpi, NULL, NULL);
		#endif
		alloc_field (display, id_dpi, alloc_float (dpi));
		
		SDL_DisplayMode currentDisplayMode = { SDL_PIXELFORMAT_UNKNOWN, 0, 0, 0, 0 };
		SDL_DisplayMode displayMode = { SDL_PIXELFORMAT_UNKNOWN, 0, 0, 0, 0 };
		
		SDL_GetCurrentDisplayMode (id, &currentDisplayMode);
		
		int numDisplayModes = SDL_GetNumDisplayModes (id);
		value supportedModes = alloc_array (numDisplayModes);
		value mode;
		
		for (int i = 0; i < numDisplayModes; i++) {
			
			SDL_GetDisplayMode (id, i, &displayMode);
			
			if (displayMode.format == currentDisplayMode.format && displayMode.w == currentDisplayMode.w && displayMode.h == currentDisplayMode.h && displayMode.refresh_rate == currentDisplayMode.refresh_rate) {
				
				alloc_field (display, id_currentMode, alloc_int (i));
				
			}
			
			mode = alloc_empty_object ();
			alloc_field (mode, id_height, alloc_int (displayMode.h));
			
			switch (displayMode.format) {
				
				case SDL_PIXELFORMAT_ARGB8888:
					
					alloc_field (mode, id_pixelFormat, alloc_int (ARGB32));
					break;
				
				case SDL_PIXELFORMAT_BGRA8888:
				case SDL_PIXELFORMAT_BGRX8888:
					
					alloc_field (mode, id_pixelFormat, alloc_int (BGRA32));
					break;
				
				default:
					
					alloc_field (mode, id_pixelFormat, alloc_int (RGBA32));
				
			}
			
			alloc_field (mode, id_refreshRate, alloc_int (displayMode.refresh_rate));
			alloc_field (mode, id_width, alloc_int (displayMode.w));
			
			val_array_set_i (supportedModes, i, mode);
			
		}
		
		alloc_field (display, id_supportedModes, supportedModes);
		return display;
		
	}
int SDLHardwareRenderDevice::createContextInternal() {
	bool settings_changed = (fullscreen != settings->fullscreen ||
			                 hwsurface != settings->hwsurface ||
							 vsync != settings->vsync ||
							 texture_filter != settings->texture_filter ||
							 ignore_texture_filter != eset->resolutions.ignore_texture_filter);

	Uint32 w_flags = 0;
	Uint32 r_flags = 0;
	int window_w = settings->screen_w;
	int window_h = settings->screen_h;

	if (settings->fullscreen) {
		w_flags = w_flags | SDL_WINDOW_FULLSCREEN_DESKTOP;

		// make the window the same size as the desktop resolution
		SDL_DisplayMode desktop;
		if (SDL_GetDesktopDisplayMode(0, &desktop) == 0) {
			window_w = desktop.w;
			window_h = desktop.h;
		}
	}
	else if (fullscreen && is_initialized) {
		// if the game was previously in fullscreen, resize the window when returning to windowed mode
		window_w = eset->resolutions.min_screen_w;
		window_h = eset->resolutions.min_screen_h;
		w_flags = w_flags | SDL_WINDOW_SHOWN;
	}
	else {
		w_flags = w_flags | SDL_WINDOW_SHOWN;
	}

	w_flags = w_flags | SDL_WINDOW_RESIZABLE;

	if (settings->hwsurface) {
		r_flags = SDL_RENDERER_ACCELERATED | SDL_RENDERER_TARGETTEXTURE;
	}
	else {
		r_flags = SDL_RENDERER_SOFTWARE | SDL_RENDERER_TARGETTEXTURE;
		settings->vsync = false; // can't have software mode & vsync at the same time
	}
	if (settings->vsync) r_flags = r_flags | SDL_RENDERER_PRESENTVSYNC;

	if (settings_changed || !is_initialized) {
		destroyContext();

		window = SDL_CreateWindow(NULL, SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, window_w, window_h, w_flags);
		if (window) {
			renderer = SDL_CreateRenderer(window, -1, r_flags);
			if (renderer) {
				if (settings->texture_filter && !eset->resolutions.ignore_texture_filter)
					SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, "1");
				else
					SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, "0");

				windowResize();
			}

			SDL_SetWindowMinimumSize(window, eset->resolutions.min_screen_w, eset->resolutions.min_screen_h);
			// setting minimum size might move the window, so set position again
			SDL_SetWindowPosition(window, SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED);
		}

		if (window && renderer) {
			if (!is_initialized) {
				// save the system gamma levels if we just created the window
				SDL_GetWindowGammaRamp(window, gamma_r, gamma_g, gamma_b);
				Utils::logInfo("RenderDevice: Window size is %dx%d", settings->screen_w, settings->screen_h);
			}

			fullscreen = settings->fullscreen;
			hwsurface = settings->hwsurface;
			vsync = settings->vsync;
			texture_filter = settings->texture_filter;
			ignore_texture_filter = eset->resolutions.ignore_texture_filter;
			is_initialized = true;

			Utils::logInfo("RenderDevice: Fullscreen=%d, Hardware surfaces=%d, Vsync=%d, Texture Filter=%d", fullscreen, hwsurface, vsync, texture_filter);

#if SDL_VERSION_ATLEAST(2, 0, 4)
			SDL_GetDisplayDPI(0, &ddpi, 0, 0);
			Utils::logInfo("RenderDevice: Display DPI is %f", ddpi);
#else
			Utils::logError("RenderDevice: The SDL version used to compile Flare does not support SDL_GetDisplayDPI(). The virtual_dpi setting will be ignored.");
#endif
		}
	}

	if (is_initialized) {
		// update minimum window size if it has changed
		if (min_screen.x != eset->resolutions.min_screen_w || min_screen.y != eset->resolutions.min_screen_h) {
			min_screen.x = eset->resolutions.min_screen_w;
			min_screen.y = eset->resolutions.min_screen_h;
			SDL_SetWindowMinimumSize(window, eset->resolutions.min_screen_w, eset->resolutions.min_screen_h);
			SDL_SetWindowPosition(window, SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED);
		}

		windowResize();

		// update title bar text and icon
		updateTitleBar();

		// load persistent resources
		delete icons;
		icons = new IconManager();
		delete curs;
		curs = new CursorManager();

		if (settings->change_gamma)
			setGamma(settings->gamma);
		else {
			resetGamma();
			settings->change_gamma = false;
			settings->gamma = 1.0;
		}
	}

	return (is_initialized ? 0 : -1);
}
/* inits sdl and creates an opengl window */
static void initSDL(VideoMode *video) {
	if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO | SDL_INIT_JOYSTICK | SDL_INIT_GAMECONTROLLER) < 0) {
		LOGE("Failed to init SDL2: %s", SDL_GetError());
		exit(1);
	}

#ifdef _WIN32
	float ddpi;
	if (!SDL_GetDisplayDPI(0, &ddpi, nullptr, nullptr)) {
		const float WINDOWS_DEFAULT_DPI = 96.0f;
		video->pixel_scale = ddpi / WINDOWS_DEFAULT_DPI;
	}
#endif

	SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
	SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 16);
	//SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS, 1);
	//SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, 4);

#ifdef EMSCRIPTEN
	SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 2);
	SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 0);
	SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK,
						SDL_GL_CONTEXT_PROFILE_ES);
#else
	SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 2);
	SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 1);
	SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK,
						SDL_GL_CONTEXT_PROFILE_COMPATIBILITY);
#endif

	int window_flags =
		  SDL_WINDOW_SHOWN
		| SDL_WINDOW_RESIZABLE
		| SDL_WINDOW_OPENGL
		| SDL_WINDOW_ALLOW_HIGHDPI;
	if (video->fullscreen) window_flags |= SDL_WINDOW_FULLSCREEN_DESKTOP;

	sdl_window = SDL_CreateWindow(WINDOW_TITLE,
		SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED,
		video->pixel_scale * video->width, video->pixel_scale * video->height,
		window_flags);
	if (!sdl_window) {
		LOGE("Failed to create an OpenGL window: %s", SDL_GetError());
		exit(1);
	}

	sdl_gl_context = SDL_GL_CreateContext(sdl_window);
	if (!sdl_gl_context) {
		LOGE("Failed to create an OpenGL context: %s", SDL_GetError());
		exit(1);
	}

	int drawable_width, drawable_height;
	SDL_GL_GetDrawableSize(sdl_window, &drawable_width, &drawable_height);
	if (drawable_width != video->width) {
		LOGI("Created high DPI window. (%dx%d)", drawable_width, drawable_height);
		video->pixel_scale = (float)drawable_width / (float)video->width;
	} else {
		video->pixel_scale = 1.0f;
	}

	if (SDL_GL_SetSwapInterval(1) == -1) { // sync with monitor refresh rate
		LOGW("Could not enable VSync.");
	}

	#ifndef __APPLE__
	glewInit();
	#endif
}