mirror of
				https://github.com/luanti-org/luanti.git
				synced 2025-11-04 01:05:48 +01:00 
			
		
		
		
	Remove Irrlicht devices except SDL (#16580)
This commit is contained in:
		@@ -2,8 +2,6 @@ cmake_minimum_required(VERSION 3.12)
 | 
			
		||||
 | 
			
		||||
project(Irrlicht LANGUAGES CXX)
 | 
			
		||||
 | 
			
		||||
message(STATUS "*** Building IrrlichtMt ***")
 | 
			
		||||
 | 
			
		||||
set(CMAKE_CXX_STANDARD 17)
 | 
			
		||||
set(CMAKE_CXX_STANDARD_REQUIRED ON)
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -1,5 +1,5 @@
 | 
			
		||||
IrrlichtMt version 1.9
 | 
			
		||||
======================
 | 
			
		||||
IrrlichtMt
 | 
			
		||||
==========
 | 
			
		||||
 | 
			
		||||
IrrlichtMt is the 3D engine of [Luanti](https://github.com/luanti-org).
 | 
			
		||||
It is based on the [Irrlicht Engine](https://irrlicht.sourceforge.io/) but is now developed independently.
 | 
			
		||||
@@ -14,16 +14,14 @@ The following libraries are required to be installed:
 | 
			
		||||
* zlib, libPNG, libJPEG
 | 
			
		||||
* OpenGL
 | 
			
		||||
  * or on mobile: OpenGL ES (can be optionally enabled on desktop too)
 | 
			
		||||
* on Unix: X11
 | 
			
		||||
* SDL2 (see below)
 | 
			
		||||
* SDL2
 | 
			
		||||
 | 
			
		||||
Aside from standard search options (`ZLIB_INCLUDE_DIR`, `ZLIB_LIBRARY`, ...) the following options are available:
 | 
			
		||||
* `ENABLE_OPENGL` - Enable OpenGL driver
 | 
			
		||||
* `ENABLE_OPENGL3` (default: `OFF`) - Enable OpenGL 3+ driver
 | 
			
		||||
* `ENABLE_OPENGL3` - Enable OpenGL 3+ driver
 | 
			
		||||
* `ENABLE_GLES2` - Enable OpenGL ES 2+ driver
 | 
			
		||||
* `USE_SDL2` (default: platform-dependent, usually `ON`) - Use SDL2 instead of older native device code
 | 
			
		||||
 | 
			
		||||
However, IrrlichtMt cannot be built or installed separately.
 | 
			
		||||
**However, IrrlichtMt cannot be built or installed separately.**
 | 
			
		||||
 | 
			
		||||
Platforms
 | 
			
		||||
---------
 | 
			
		||||
@@ -36,27 +34,6 @@ We aim to support these platforms:
 | 
			
		||||
 | 
			
		||||
This doesn't mean other platforms don't work or won't be supported, if you find something that doesn't work contributions are welcome.
 | 
			
		||||
 | 
			
		||||
Compatibility matrix
 | 
			
		||||
--------------------
 | 
			
		||||
 | 
			
		||||
Driver (rows) vs Device (columns)
 | 
			
		||||
 | 
			
		||||
|                           | SDL [1]  | Linux [2]      | OSX [3]          | Win32 [4]       |
 | 
			
		||||
|---------------------------|----------|----------------|------------------|-----------------|
 | 
			
		||||
| OpenGL 1.2 (to 2.1)       | Works    | Works (GLX)    | Works (NSOpenGL) | Works (WGL)     |
 | 
			
		||||
| OpenGL 3.2+               | Works    | Testing (GLX)  | Not implemented  | Testing (WGL)   |
 | 
			
		||||
| OpenGL ES 2.x             | Works    | Untested (EGL) | Not implemented  | Untested (EGL)  |
 | 
			
		||||
| WebGL 1                   | Untested | Untested (EGL) | Not implemented  | Not implemented |
 | 
			
		||||
| Null (no graphics output) | Works    | Works          | Works            | Works           |
 | 
			
		||||
 | 
			
		||||
Notes:
 | 
			
		||||
 | 
			
		||||
* [1] `CIrrDeviceSDL`: supports Android, Linux, macOS, Windows
 | 
			
		||||
* [2] `CIrrDeviceLinux`: supports Linux
 | 
			
		||||
* [3] `CIrrDeviceOSX`: supports macOS
 | 
			
		||||
* [4] `CIrrDeviceWin32`: supports Windows
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
License
 | 
			
		||||
-------
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -7,23 +7,14 @@
 | 
			
		||||
//! An enum for the different device types supported by the Irrlicht Engine.
 | 
			
		||||
enum E_DEVICE_TYPE
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
	//! A device native to Microsoft Windows
 | 
			
		||||
	/** This device uses the Win32 API and works in all versions of Windows. */
 | 
			
		||||
	EIDT_WIN32,
 | 
			
		||||
 | 
			
		||||
	//! A device native to Unix style operating systems.
 | 
			
		||||
	/** This device uses the X11 windowing system and works in Linux, Solaris, FreeBSD, OSX and
 | 
			
		||||
	other operating systems which support X11. */
 | 
			
		||||
	EIDT_X11,
 | 
			
		||||
 | 
			
		||||
	//! A device native to Mac OSX
 | 
			
		||||
	/** This device uses Apple's Cocoa API and works in Mac OSX 10.2 and above. */
 | 
			
		||||
	EIDT_OSX,
 | 
			
		||||
 | 
			
		||||
	//! A device which uses Simple DirectMedia Layer
 | 
			
		||||
	/** The SDL device works under all platforms supported by SDL but first must be compiled
 | 
			
		||||
	in by setting the USE_SDL2 CMake option to ON */
 | 
			
		||||
	/** The SDL device works under all platforms supported by SDL. */
 | 
			
		||||
	EIDT_SDL,
 | 
			
		||||
 | 
			
		||||
	//! This selection allows Irrlicht to choose the best device from the ones available.
 | 
			
		||||
@@ -33,9 +24,5 @@ enum E_DEVICE_TYPE
 | 
			
		||||
	although it may not be able to render anything. */
 | 
			
		||||
	EIDT_BEST,
 | 
			
		||||
 | 
			
		||||
	//! A device for Android platforms
 | 
			
		||||
	/** Best used with embedded devices and mobile systems.
 | 
			
		||||
	Does not need X11 or other graphical subsystems.
 | 
			
		||||
	May support hw-acceleration via OpenGL-ES */
 | 
			
		||||
	EIDT_ANDROID,
 | 
			
		||||
};
 | 
			
		||||
 
 | 
			
		||||
@@ -15,65 +15,7 @@ you are using the software or the null device.
 | 
			
		||||
*/
 | 
			
		||||
struct SExposedVideoData
 | 
			
		||||
{
 | 
			
		||||
	SExposedVideoData()
 | 
			
		||||
	{
 | 
			
		||||
		OpenGLWin32.HDc = 0;
 | 
			
		||||
		OpenGLWin32.HRc = 0;
 | 
			
		||||
		OpenGLWin32.HWnd = 0;
 | 
			
		||||
	}
 | 
			
		||||
	explicit SExposedVideoData(void *Window)
 | 
			
		||||
	{
 | 
			
		||||
		OpenGLWin32.HDc = 0;
 | 
			
		||||
		OpenGLWin32.HRc = 0;
 | 
			
		||||
		OpenGLWin32.HWnd = Window;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	struct SOpenGLWin32
 | 
			
		||||
	{
 | 
			
		||||
		//! Private GDI Device Context.
 | 
			
		||||
		/** Get if for example with: HDC h = reinterpret_cast<HDC>(exposedData.OpenGLWin32.HDc) */
 | 
			
		||||
		void *HDc;
 | 
			
		||||
 | 
			
		||||
		//! Permanent Rendering Context.
 | 
			
		||||
		/** Get if for example with: HGLRC h = reinterpret_cast<HGLRC>(exposedData.OpenGLWin32.HRc) */
 | 
			
		||||
		void *HRc;
 | 
			
		||||
 | 
			
		||||
		//! Window handle.
 | 
			
		||||
		/** Get with for example with: HWND h = reinterpret_cast<HWND>(exposedData.OpenGLWin32.HWnd) */
 | 
			
		||||
		void *HWnd;
 | 
			
		||||
	};
 | 
			
		||||
 | 
			
		||||
	struct SOpenGLLinux
 | 
			
		||||
	{
 | 
			
		||||
		// XWindow handles
 | 
			
		||||
		void *X11Display;
 | 
			
		||||
		void *X11Context;
 | 
			
		||||
		unsigned long X11Window;
 | 
			
		||||
		unsigned long GLXWindow;
 | 
			
		||||
	};
 | 
			
		||||
 | 
			
		||||
	struct SOpenGLOSX
 | 
			
		||||
	{
 | 
			
		||||
		//! The NSOpenGLContext object.
 | 
			
		||||
		void *Context;
 | 
			
		||||
 | 
			
		||||
		//! The NSWindow object.
 | 
			
		||||
		void *Window;
 | 
			
		||||
	};
 | 
			
		||||
 | 
			
		||||
	struct SOGLESAndroid
 | 
			
		||||
	{
 | 
			
		||||
		//! The ANativeWindow object.
 | 
			
		||||
		void *Window;
 | 
			
		||||
	};
 | 
			
		||||
 | 
			
		||||
	union
 | 
			
		||||
	{
 | 
			
		||||
		SOpenGLWin32 OpenGLWin32;
 | 
			
		||||
		SOpenGLLinux OpenGLLinux;
 | 
			
		||||
		SOpenGLOSX OpenGLOSX;
 | 
			
		||||
		SOGLESAndroid OGLESAndroid;
 | 
			
		||||
	};
 | 
			
		||||
	char dummy = 0;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
} // end namespace video
 | 
			
		||||
 
 | 
			
		||||
@@ -35,16 +35,9 @@ bool CEGLManager::initialize(const SIrrlichtCreationParameters ¶ms, const SE
 | 
			
		||||
		return true;
 | 
			
		||||
 | 
			
		||||
		// Window is depend on platform.
 | 
			
		||||
#if defined(_IRR_COMPILE_WITH_WINDOWS_DEVICE_)
 | 
			
		||||
	EglWindow = (NativeWindowType)Data.OpenGLWin32.HWnd;
 | 
			
		||||
	Data.OpenGLWin32.HDc = GetDC((HWND)EglWindow);
 | 
			
		||||
	EglDisplay = eglGetDisplay((NativeDisplayType)Data.OpenGLWin32.HDc);
 | 
			
		||||
#elif defined(_IRR_EMSCRIPTEN_PLATFORM_)
 | 
			
		||||
#if defined(_IRR_EMSCRIPTEN_PLATFORM_)
 | 
			
		||||
	EglWindow = 0;
 | 
			
		||||
	EglDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY);
 | 
			
		||||
#elif defined(_IRR_COMPILE_WITH_X11_DEVICE_)
 | 
			
		||||
	EglWindow = (NativeWindowType)Data.OpenGLLinux.X11Window;
 | 
			
		||||
	EglDisplay = eglGetDisplay((NativeDisplayType)Data.OpenGLLinux.X11Display);
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
	// We must check if EGL display is valid.
 | 
			
		||||
@@ -80,13 +73,6 @@ void CEGLManager::terminate()
 | 
			
		||||
		EglDisplay = EGL_NO_DISPLAY;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
#if defined(_IRR_COMPILE_WITH_WINDOWS_DEVICE_)
 | 
			
		||||
	if (Data.OpenGLWin32.HDc) {
 | 
			
		||||
		ReleaseDC((HWND)EglWindow, (HDC)Data.OpenGLWin32.HDc);
 | 
			
		||||
		Data.OpenGLWin32.HDc = 0;
 | 
			
		||||
	}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
	MajorVersion = 0;
 | 
			
		||||
	MinorVersion = 0;
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -1,394 +0,0 @@
 | 
			
		||||
// Copyright (C) 2013 Christian Stehno
 | 
			
		||||
// This file is part of the "Irrlicht Engine".
 | 
			
		||||
// For conditions of distribution and use, see copyright notice in Irrlicht.h
 | 
			
		||||
 | 
			
		||||
#include "CGLXManager.h"
 | 
			
		||||
 | 
			
		||||
#ifdef _IRR_COMPILE_WITH_GLX_MANAGER_
 | 
			
		||||
 | 
			
		||||
#include "os.h"
 | 
			
		||||
 | 
			
		||||
#define GL_GLEXT_LEGACY 1
 | 
			
		||||
#define GLX_GLXEXT_LEGACY 1
 | 
			
		||||
#include <GL/gl.h>
 | 
			
		||||
#include <GL/glx.h>
 | 
			
		||||
#include <GL/glext.h>
 | 
			
		||||
#include <GL/glxext.h>
 | 
			
		||||
 | 
			
		||||
namespace video
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
CGLXManager::CGLXManager(const SIrrlichtCreationParameters ¶ms, const SExposedVideoData &videodata, int screennr) :
 | 
			
		||||
		Params(params), PrimaryContext(videodata), VisualInfo(0), glxFBConfig(0), GlxWin(0)
 | 
			
		||||
{
 | 
			
		||||
	CurrentContext.OpenGLLinux.X11Display = PrimaryContext.OpenGLLinux.X11Display;
 | 
			
		||||
 | 
			
		||||
	int major, minor;
 | 
			
		||||
	Display *display = (Display *)PrimaryContext.OpenGLLinux.X11Display;
 | 
			
		||||
	const bool isAvailableGLX = glXQueryExtension(display, &major, &minor);
 | 
			
		||||
 | 
			
		||||
	if (isAvailableGLX && glXQueryVersion(display, &major, &minor)) {
 | 
			
		||||
#if defined(GLX_VERSION_1_3)
 | 
			
		||||
		typedef GLXFBConfig *(*PFNGLXCHOOSEFBCONFIGPROC)(Display *dpy, int screen, const int *attrib_list, int *nelements);
 | 
			
		||||
 | 
			
		||||
		PFNGLXCHOOSEFBCONFIGPROC glxChooseFBConfig = (PFNGLXCHOOSEFBCONFIGPROC)glXGetProcAddress(reinterpret_cast<const GLubyte *>("glXChooseFBConfig"));
 | 
			
		||||
		if (major == 1 && minor > 2 && glxChooseFBConfig) {
 | 
			
		||||
			os::Printer::log("GLX >= 1.3", ELL_DEBUG);
 | 
			
		||||
			// attribute array for the draw buffer
 | 
			
		||||
			int visualAttrBuffer[] = {
 | 
			
		||||
					GLX_RENDER_TYPE,
 | 
			
		||||
					GLX_RGBA_BIT,
 | 
			
		||||
					GLX_RED_SIZE,
 | 
			
		||||
					4,
 | 
			
		||||
					GLX_GREEN_SIZE,
 | 
			
		||||
					4,
 | 
			
		||||
					GLX_BLUE_SIZE,
 | 
			
		||||
					4,
 | 
			
		||||
					GLX_ALPHA_SIZE,
 | 
			
		||||
					Params.WithAlphaChannel ? 1 : 0,
 | 
			
		||||
					GLX_DEPTH_SIZE,
 | 
			
		||||
					Params.ZBufferBits, // 10,11
 | 
			
		||||
					GLX_DOUBLEBUFFER,
 | 
			
		||||
					Params.Doublebuffer ? True : False,
 | 
			
		||||
					GLX_STENCIL_SIZE,
 | 
			
		||||
					Params.Stencilbuffer ? 1 : 0,
 | 
			
		||||
#if defined(GLX_VERSION_1_4) && defined(GLX_SAMPLE_BUFFERS) // we need to check the extension string!
 | 
			
		||||
					GLX_SAMPLE_BUFFERS,
 | 
			
		||||
					1,
 | 
			
		||||
					GLX_SAMPLES,
 | 
			
		||||
					Params.AntiAlias, // 18,19
 | 
			
		||||
#elif defined(GLX_ARB_multisample)
 | 
			
		||||
					GLX_SAMPLE_BUFFERS_ARB,
 | 
			
		||||
					1,
 | 
			
		||||
					GLX_SAMPLES_ARB,
 | 
			
		||||
					Params.AntiAlias, // 18,19
 | 
			
		||||
#elif defined(GLX_SGIS_multisample)
 | 
			
		||||
					GLX_SAMPLE_BUFFERS_SGIS,
 | 
			
		||||
					1,
 | 
			
		||||
					GLX_SAMPLES_SGIS,
 | 
			
		||||
					Params.AntiAlias, // 18,19
 | 
			
		||||
#endif
 | 
			
		||||
					GLX_STEREO,
 | 
			
		||||
					Params.Stereobuffer ? True : False,
 | 
			
		||||
					None,
 | 
			
		||||
				};
 | 
			
		||||
 | 
			
		||||
			GLXFBConfig *configList = 0;
 | 
			
		||||
			int nitems = 0;
 | 
			
		||||
			if (Params.AntiAlias < 2) {
 | 
			
		||||
				visualAttrBuffer[17] = 0;
 | 
			
		||||
				visualAttrBuffer[19] = 0;
 | 
			
		||||
			}
 | 
			
		||||
			// first round with unchanged values
 | 
			
		||||
			{
 | 
			
		||||
				configList = glxChooseFBConfig(display, screennr, visualAttrBuffer, &nitems);
 | 
			
		||||
				if (!configList && Params.AntiAlias) {
 | 
			
		||||
					while (!configList && (visualAttrBuffer[19] > 1)) {
 | 
			
		||||
						visualAttrBuffer[19] -= 1;
 | 
			
		||||
						configList = glxChooseFBConfig(display, screennr, visualAttrBuffer, &nitems);
 | 
			
		||||
					}
 | 
			
		||||
					if (!configList) {
 | 
			
		||||
						visualAttrBuffer[17] = 0;
 | 
			
		||||
						visualAttrBuffer[19] = 0;
 | 
			
		||||
						configList = glxChooseFBConfig(display, screennr, visualAttrBuffer, &nitems);
 | 
			
		||||
						if (configList) {
 | 
			
		||||
							os::Printer::log("No FSAA available.", ELL_WARNING);
 | 
			
		||||
							Params.AntiAlias = 0;
 | 
			
		||||
						} else {
 | 
			
		||||
							// reenable multisampling
 | 
			
		||||
							visualAttrBuffer[17] = 1;
 | 
			
		||||
							visualAttrBuffer[19] = Params.AntiAlias;
 | 
			
		||||
						}
 | 
			
		||||
					}
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
			// Next try with flipped stencil buffer value
 | 
			
		||||
			// If the first round was with stencil flag it's now without
 | 
			
		||||
			// Other way round also makes sense because some configs
 | 
			
		||||
			// only have depth buffer combined with stencil buffer
 | 
			
		||||
			if (!configList) {
 | 
			
		||||
				if (Params.Stencilbuffer)
 | 
			
		||||
					os::Printer::log("No stencilbuffer available, disabling stencil shadows.", ELL_WARNING);
 | 
			
		||||
				Params.Stencilbuffer = !Params.Stencilbuffer;
 | 
			
		||||
				visualAttrBuffer[15] = Params.Stencilbuffer ? 1 : 0;
 | 
			
		||||
 | 
			
		||||
				configList = glxChooseFBConfig(display, screennr, visualAttrBuffer, &nitems);
 | 
			
		||||
				if (!configList && Params.AntiAlias) {
 | 
			
		||||
					while (!configList && (visualAttrBuffer[19] > 1)) {
 | 
			
		||||
						visualAttrBuffer[19] -= 1;
 | 
			
		||||
						configList = glxChooseFBConfig(display, screennr, visualAttrBuffer, &nitems);
 | 
			
		||||
					}
 | 
			
		||||
					if (!configList) {
 | 
			
		||||
						visualAttrBuffer[17] = 0;
 | 
			
		||||
						visualAttrBuffer[19] = 0;
 | 
			
		||||
						configList = glxChooseFBConfig(display, screennr, visualAttrBuffer, &nitems);
 | 
			
		||||
						if (configList) {
 | 
			
		||||
							os::Printer::log("No FSAA available.", ELL_WARNING);
 | 
			
		||||
							Params.AntiAlias = 0;
 | 
			
		||||
						} else {
 | 
			
		||||
							// reenable multisampling
 | 
			
		||||
							visualAttrBuffer[17] = 1;
 | 
			
		||||
							visualAttrBuffer[19] = Params.AntiAlias;
 | 
			
		||||
						}
 | 
			
		||||
					}
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
			// Next try without double buffer
 | 
			
		||||
			if (!configList && Params.Doublebuffer) {
 | 
			
		||||
				os::Printer::log("No doublebuffering available.", ELL_WARNING);
 | 
			
		||||
				Params.Doublebuffer = false;
 | 
			
		||||
				visualAttrBuffer[13] = GLX_DONT_CARE;
 | 
			
		||||
				Params.Stencilbuffer = false;
 | 
			
		||||
				visualAttrBuffer[15] = 0;
 | 
			
		||||
				configList = glxChooseFBConfig(display, screennr, visualAttrBuffer, &nitems);
 | 
			
		||||
				if (!configList && Params.AntiAlias) {
 | 
			
		||||
					while (!configList && (visualAttrBuffer[19] > 1)) {
 | 
			
		||||
						visualAttrBuffer[19] -= 1;
 | 
			
		||||
						configList = glxChooseFBConfig(display, screennr, visualAttrBuffer, &nitems);
 | 
			
		||||
					}
 | 
			
		||||
					if (!configList) {
 | 
			
		||||
						visualAttrBuffer[17] = 0;
 | 
			
		||||
						visualAttrBuffer[19] = 0;
 | 
			
		||||
						configList = glxChooseFBConfig(display, screennr, visualAttrBuffer, &nitems);
 | 
			
		||||
						if (configList) {
 | 
			
		||||
							os::Printer::log("No FSAA available.", ELL_WARNING);
 | 
			
		||||
							Params.AntiAlias = 0;
 | 
			
		||||
						} else {
 | 
			
		||||
							// reenable multisampling
 | 
			
		||||
							visualAttrBuffer[17] = 1;
 | 
			
		||||
							visualAttrBuffer[19] = Params.AntiAlias;
 | 
			
		||||
						}
 | 
			
		||||
					}
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
			if (configList) {
 | 
			
		||||
				glxFBConfig = configList[0];
 | 
			
		||||
				XFree(configList);
 | 
			
		||||
				typedef XVisualInfo *(*PFNGLXGETVISUALFROMFBCONFIGPROC)(Display *dpy, GLXFBConfig config);
 | 
			
		||||
				PFNGLXGETVISUALFROMFBCONFIGPROC glxGetVisualFromFBConfig = (PFNGLXGETVISUALFROMFBCONFIGPROC)glXGetProcAddress(reinterpret_cast<const GLubyte *>("glXGetVisualFromFBConfig"));
 | 
			
		||||
				if (glxGetVisualFromFBConfig)
 | 
			
		||||
					VisualInfo = glxGetVisualFromFBConfig(display, (GLXFBConfig)glxFBConfig);
 | 
			
		||||
			}
 | 
			
		||||
		} else
 | 
			
		||||
#endif
 | 
			
		||||
		{
 | 
			
		||||
			// attribute array for the draw buffer
 | 
			
		||||
			int visualAttrBuffer[] = {
 | 
			
		||||
					GLX_RGBA, GLX_USE_GL,
 | 
			
		||||
					GLX_RED_SIZE, 4,
 | 
			
		||||
					GLX_GREEN_SIZE, 4,
 | 
			
		||||
					GLX_BLUE_SIZE, 4,
 | 
			
		||||
					GLX_ALPHA_SIZE, Params.WithAlphaChannel ? 1 : 0,
 | 
			
		||||
					GLX_DEPTH_SIZE, Params.ZBufferBits,
 | 
			
		||||
					GLX_STENCIL_SIZE, Params.Stencilbuffer ? 1 : 0, // 12,13
 | 
			
		||||
					// The following attributes have no flags, but are
 | 
			
		||||
					// either present or not. As a no-op we use
 | 
			
		||||
					// GLX_USE_GL, which is silently ignored by glXChooseVisual
 | 
			
		||||
					Params.Doublebuffer ? GLX_DOUBLEBUFFER : GLX_USE_GL, // 14
 | 
			
		||||
					Params.Stereobuffer ? GLX_STEREO : GLX_USE_GL,       // 15
 | 
			
		||||
					None,
 | 
			
		||||
				};
 | 
			
		||||
 | 
			
		||||
			VisualInfo = glXChooseVisual(display, screennr, visualAttrBuffer);
 | 
			
		||||
			if (!VisualInfo) {
 | 
			
		||||
				if (Params.Stencilbuffer)
 | 
			
		||||
					os::Printer::log("No stencilbuffer available, disabling.", ELL_WARNING);
 | 
			
		||||
				Params.Stencilbuffer = !Params.Stencilbuffer;
 | 
			
		||||
				visualAttrBuffer[13] = Params.Stencilbuffer ? 1 : 0;
 | 
			
		||||
 | 
			
		||||
				VisualInfo = glXChooseVisual(display, screennr, visualAttrBuffer);
 | 
			
		||||
				if (!VisualInfo && Params.Doublebuffer) {
 | 
			
		||||
					os::Printer::log("No doublebuffering available.", ELL_WARNING);
 | 
			
		||||
					Params.Doublebuffer = false;
 | 
			
		||||
					visualAttrBuffer[14] = GLX_USE_GL;
 | 
			
		||||
					VisualInfo = glXChooseVisual(display, screennr, visualAttrBuffer);
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	} else
 | 
			
		||||
		os::Printer::log("No GLX support available. OpenGL driver will not work.", ELL_WARNING);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
CGLXManager::~CGLXManager()
 | 
			
		||||
{
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool CGLXManager::initialize(const SIrrlichtCreationParameters ¶ms, const SExposedVideoData &videodata)
 | 
			
		||||
{
 | 
			
		||||
	// store params
 | 
			
		||||
	Params = params;
 | 
			
		||||
 | 
			
		||||
	// set display
 | 
			
		||||
	CurrentContext.OpenGLLinux.X11Display = videodata.OpenGLLinux.X11Display;
 | 
			
		||||
 | 
			
		||||
	// now get new window
 | 
			
		||||
	CurrentContext.OpenGLLinux.X11Window = videodata.OpenGLLinux.X11Window;
 | 
			
		||||
	if (!PrimaryContext.OpenGLLinux.X11Window) {
 | 
			
		||||
		PrimaryContext.OpenGLLinux.X11Window = CurrentContext.OpenGLLinux.X11Window;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return true;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void CGLXManager::terminate()
 | 
			
		||||
{
 | 
			
		||||
	memset((void *)&CurrentContext, 0, sizeof(CurrentContext));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool CGLXManager::generateSurface()
 | 
			
		||||
{
 | 
			
		||||
	if (glxFBConfig) {
 | 
			
		||||
		GlxWin = glXCreateWindow((Display *)CurrentContext.OpenGLLinux.X11Display, (GLXFBConfig)glxFBConfig, CurrentContext.OpenGLLinux.X11Window, NULL);
 | 
			
		||||
		if (!GlxWin) {
 | 
			
		||||
			os::Printer::log("Could not create GLX window.", ELL_WARNING);
 | 
			
		||||
			return false;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		CurrentContext.OpenGLLinux.GLXWindow = GlxWin;
 | 
			
		||||
	} else {
 | 
			
		||||
		CurrentContext.OpenGLLinux.GLXWindow = CurrentContext.OpenGLLinux.X11Window;
 | 
			
		||||
	}
 | 
			
		||||
	return true;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void CGLXManager::destroySurface()
 | 
			
		||||
{
 | 
			
		||||
	if (GlxWin)
 | 
			
		||||
		glXDestroyWindow((Display *)CurrentContext.OpenGLLinux.X11Display, GlxWin);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#if defined(GLX_ARB_create_context)
 | 
			
		||||
static int IrrIgnoreError(Display *display, XErrorEvent *event)
 | 
			
		||||
{
 | 
			
		||||
	char msg[256];
 | 
			
		||||
	XGetErrorText(display, event->error_code, msg, 256);
 | 
			
		||||
	os::Printer::log("Ignoring an X error", msg, ELL_DEBUG);
 | 
			
		||||
	return 0;
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
bool CGLXManager::generateContext()
 | 
			
		||||
{
 | 
			
		||||
	GLXContext context = 0;
 | 
			
		||||
 | 
			
		||||
	if (glxFBConfig) {
 | 
			
		||||
		if (GlxWin) {
 | 
			
		||||
#if defined(GLX_ARB_create_context)
 | 
			
		||||
 | 
			
		||||
			PFNGLXCREATECONTEXTATTRIBSARBPROC glxCreateContextAttribsARB = (PFNGLXCREATECONTEXTATTRIBSARBPROC)glXGetProcAddress(reinterpret_cast<const GLubyte *>("glXCreateContextAttribsARB"));
 | 
			
		||||
 | 
			
		||||
			if (glxCreateContextAttribsARB) {
 | 
			
		||||
				os::Printer::log("GLX with GLX_ARB_create_context", ELL_DEBUG);
 | 
			
		||||
				int contextAttrBuffer[] = {
 | 
			
		||||
						GLX_CONTEXT_MAJOR_VERSION_ARB, 3,
 | 
			
		||||
						GLX_CONTEXT_MINOR_VERSION_ARB, 0,
 | 
			
		||||
						// GLX_CONTEXT_PROFILE_MASK_ARB, GLX_CONTEXT_CORE_PROFILE_BIT_ARB,
 | 
			
		||||
						None};
 | 
			
		||||
				XErrorHandler old = XSetErrorHandler(IrrIgnoreError);
 | 
			
		||||
				context = glxCreateContextAttribsARB((Display *)CurrentContext.OpenGLLinux.X11Display, (GLXFBConfig)glxFBConfig, NULL, True, contextAttrBuffer);
 | 
			
		||||
				XSetErrorHandler(old);
 | 
			
		||||
				// transparently fall back to legacy call
 | 
			
		||||
			}
 | 
			
		||||
			if (!context)
 | 
			
		||||
#endif
 | 
			
		||||
			{
 | 
			
		||||
				// create glx context
 | 
			
		||||
				context = glXCreateNewContext((Display *)CurrentContext.OpenGLLinux.X11Display, (GLXFBConfig)glxFBConfig, GLX_RGBA_TYPE, NULL, True);
 | 
			
		||||
				if (!context) {
 | 
			
		||||
					os::Printer::log("Could not create GLX rendering context.", ELL_WARNING);
 | 
			
		||||
					return false;
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
		} else {
 | 
			
		||||
			os::Printer::log("GLX window was not properly created.", ELL_WARNING);
 | 
			
		||||
			return false;
 | 
			
		||||
		}
 | 
			
		||||
	} else {
 | 
			
		||||
		context = glXCreateContext((Display *)CurrentContext.OpenGLLinux.X11Display, VisualInfo, NULL, True);
 | 
			
		||||
		if (!context) {
 | 
			
		||||
			os::Printer::log("Could not create GLX rendering context.", ELL_WARNING);
 | 
			
		||||
			return false;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	CurrentContext.OpenGLLinux.X11Context = context;
 | 
			
		||||
	return true;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const SExposedVideoData &CGLXManager::getContext() const
 | 
			
		||||
{
 | 
			
		||||
	return CurrentContext;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool CGLXManager::activateContext(const SExposedVideoData &videoData, bool restorePrimaryOnZero)
 | 
			
		||||
{
 | 
			
		||||
	// TODO: handle restorePrimaryOnZero
 | 
			
		||||
 | 
			
		||||
	if (videoData.OpenGLLinux.X11Window) {
 | 
			
		||||
		if (videoData.OpenGLLinux.X11Display && videoData.OpenGLLinux.X11Context) {
 | 
			
		||||
			if (!glXMakeCurrent((Display *)videoData.OpenGLLinux.X11Display, videoData.OpenGLLinux.GLXWindow, (GLXContext)videoData.OpenGLLinux.X11Context)) {
 | 
			
		||||
				os::Printer::log("Context activation failed.");
 | 
			
		||||
				return false;
 | 
			
		||||
			} else {
 | 
			
		||||
				CurrentContext.OpenGLLinux.GLXWindow = videoData.OpenGLLinux.GLXWindow;
 | 
			
		||||
				CurrentContext.OpenGLLinux.X11Window = videoData.OpenGLLinux.X11Window;
 | 
			
		||||
				CurrentContext.OpenGLLinux.X11Display = videoData.OpenGLLinux.X11Display;
 | 
			
		||||
			}
 | 
			
		||||
		} else {
 | 
			
		||||
			// in case we only got a window ID, try with the existing values for display and context
 | 
			
		||||
			if (!glXMakeCurrent((Display *)PrimaryContext.OpenGLLinux.X11Display, videoData.OpenGLLinux.GLXWindow, (GLXContext)PrimaryContext.OpenGLLinux.X11Context)) {
 | 
			
		||||
				os::Printer::log("Context activation failed.");
 | 
			
		||||
				return false;
 | 
			
		||||
			} else {
 | 
			
		||||
				CurrentContext.OpenGLLinux.GLXWindow = videoData.OpenGLLinux.GLXWindow;
 | 
			
		||||
				CurrentContext.OpenGLLinux.X11Window = videoData.OpenGLLinux.X11Window;
 | 
			
		||||
				CurrentContext.OpenGLLinux.X11Display = PrimaryContext.OpenGLLinux.X11Display;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	} else if (!restorePrimaryOnZero && !videoData.OpenGLLinux.X11Window && !videoData.OpenGLLinux.X11Display) {
 | 
			
		||||
		if (!glXMakeCurrent((Display *)PrimaryContext.OpenGLLinux.X11Display, None, NULL)) {
 | 
			
		||||
			os::Printer::log("Render Context reset failed.");
 | 
			
		||||
			return false;
 | 
			
		||||
		}
 | 
			
		||||
		CurrentContext.OpenGLLinux.X11Window = 0;
 | 
			
		||||
		CurrentContext.OpenGLLinux.X11Display = 0;
 | 
			
		||||
	}
 | 
			
		||||
	// set back to main context
 | 
			
		||||
	else if (CurrentContext.OpenGLLinux.X11Display != PrimaryContext.OpenGLLinux.X11Display) {
 | 
			
		||||
		if (!glXMakeCurrent((Display *)PrimaryContext.OpenGLLinux.X11Display, PrimaryContext.OpenGLLinux.X11Window, (GLXContext)PrimaryContext.OpenGLLinux.X11Context)) {
 | 
			
		||||
			os::Printer::log("Context activation failed.");
 | 
			
		||||
			return false;
 | 
			
		||||
		} else {
 | 
			
		||||
			CurrentContext = PrimaryContext;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	return true;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void CGLXManager::destroyContext()
 | 
			
		||||
{
 | 
			
		||||
	if (CurrentContext.OpenGLLinux.X11Context) {
 | 
			
		||||
		if (GlxWin) {
 | 
			
		||||
			if (!glXMakeContextCurrent((Display *)CurrentContext.OpenGLLinux.X11Display, None, None, NULL))
 | 
			
		||||
				os::Printer::log("Could not release glx context.", ELL_WARNING);
 | 
			
		||||
		} else {
 | 
			
		||||
			if (!glXMakeCurrent((Display *)CurrentContext.OpenGLLinux.X11Display, None, NULL))
 | 
			
		||||
				os::Printer::log("Could not release glx context.", ELL_WARNING);
 | 
			
		||||
		}
 | 
			
		||||
		glXDestroyContext((Display *)CurrentContext.OpenGLLinux.X11Display, (GLXContext)CurrentContext.OpenGLLinux.X11Context);
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void *CGLXManager::getProcAddress(const std::string &procName)
 | 
			
		||||
{
 | 
			
		||||
	return (void *)glXGetProcAddressARB(reinterpret_cast<const GLubyte *>(procName.c_str()));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool CGLXManager::swapBuffers()
 | 
			
		||||
{
 | 
			
		||||
	glXSwapBuffers((Display *)CurrentContext.OpenGLLinux.X11Display, CurrentContext.OpenGLLinux.GLXWindow);
 | 
			
		||||
	return true;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
@@ -1,73 +0,0 @@
 | 
			
		||||
// Copyright (C) 2013 Christian Stehno
 | 
			
		||||
// This file is part of the "Irrlicht Engine".
 | 
			
		||||
// For conditions of distribution and use, see copyright notice in Irrlicht.h
 | 
			
		||||
 | 
			
		||||
#pragma once
 | 
			
		||||
 | 
			
		||||
#ifdef _IRR_COMPILE_WITH_GLX_MANAGER_
 | 
			
		||||
 | 
			
		||||
#include "SIrrCreationParameters.h"
 | 
			
		||||
#include "SExposedVideoData.h"
 | 
			
		||||
#include "IContextManager.h"
 | 
			
		||||
#include "SColor.h"
 | 
			
		||||
#include <X11/Xlib.h>
 | 
			
		||||
#include <X11/Xutil.h>
 | 
			
		||||
 | 
			
		||||
// we can't include glx.h here, because gl.h has incompatible types with ogl es headers and it
 | 
			
		||||
// cause redefinition errors, thats why we use ugly trick with void* types and casts.
 | 
			
		||||
 | 
			
		||||
namespace video
 | 
			
		||||
{
 | 
			
		||||
// GLX manager.
 | 
			
		||||
class CGLXManager : public IContextManager
 | 
			
		||||
{
 | 
			
		||||
public:
 | 
			
		||||
	//! Constructor.
 | 
			
		||||
	CGLXManager(const SIrrlichtCreationParameters ¶ms, const SExposedVideoData &videodata, int screennr);
 | 
			
		||||
 | 
			
		||||
	//! Destructor
 | 
			
		||||
	~CGLXManager();
 | 
			
		||||
 | 
			
		||||
	// Initialize
 | 
			
		||||
	bool initialize(const SIrrlichtCreationParameters ¶ms, const SExposedVideoData &data) override;
 | 
			
		||||
 | 
			
		||||
	// Terminate
 | 
			
		||||
	void terminate() override;
 | 
			
		||||
 | 
			
		||||
	// Create surface.
 | 
			
		||||
	bool generateSurface() override;
 | 
			
		||||
 | 
			
		||||
	// Destroy surface.
 | 
			
		||||
	void destroySurface() override;
 | 
			
		||||
 | 
			
		||||
	// Create context.
 | 
			
		||||
	bool generateContext() override;
 | 
			
		||||
 | 
			
		||||
	// Destroy context.
 | 
			
		||||
	void destroyContext() override;
 | 
			
		||||
 | 
			
		||||
	//! Get current context
 | 
			
		||||
	const SExposedVideoData &getContext() const override;
 | 
			
		||||
 | 
			
		||||
	//! Change render context, disable old and activate new defined by videoData
 | 
			
		||||
	bool activateContext(const SExposedVideoData &videoData, bool restorePrimaryOnZero) override;
 | 
			
		||||
 | 
			
		||||
	// Get procedure address.
 | 
			
		||||
	void *getProcAddress(const std::string &procName) override;
 | 
			
		||||
 | 
			
		||||
	// Swap buffers.
 | 
			
		||||
	bool swapBuffers() override;
 | 
			
		||||
 | 
			
		||||
	XVisualInfo *getVisual() const { return VisualInfo; } // return XVisualInfo
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
	SIrrlichtCreationParameters Params;
 | 
			
		||||
	SExposedVideoData PrimaryContext;
 | 
			
		||||
	SExposedVideoData CurrentContext;
 | 
			
		||||
	XVisualInfo *VisualInfo;
 | 
			
		||||
	void *glxFBConfig; // GLXFBConfig
 | 
			
		||||
	XID GlxWin;        // GLXWindow
 | 
			
		||||
};
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							@@ -1,471 +0,0 @@
 | 
			
		||||
// Copyright (C) 2002-2012 Nikolaus Gebhardt
 | 
			
		||||
// This file is part of the "Irrlicht Engine".
 | 
			
		||||
// For conditions of distribution and use, see copyright notice in irrlicht.h
 | 
			
		||||
 | 
			
		||||
#pragma once
 | 
			
		||||
 | 
			
		||||
#ifdef _IRR_COMPILE_WITH_X11_DEVICE_
 | 
			
		||||
 | 
			
		||||
#include "CIrrDeviceStub.h"
 | 
			
		||||
#include "IrrlichtDevice.h"
 | 
			
		||||
#include "ICursorControl.h"
 | 
			
		||||
#include "os.h"
 | 
			
		||||
namespace video
 | 
			
		||||
{
 | 
			
		||||
	class ITexture;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#ifdef _IRR_COMPILE_WITH_X11_
 | 
			
		||||
 | 
			
		||||
#include <X11/Xlib.h>
 | 
			
		||||
#include <X11/Xutil.h>
 | 
			
		||||
#include <X11/cursorfont.h>
 | 
			
		||||
#include <X11/keysym.h>
 | 
			
		||||
 | 
			
		||||
#ifdef _IRR_LINUX_X11_XINPUT2_
 | 
			
		||||
#include <X11/extensions/XInput2.h>
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#else
 | 
			
		||||
#define KeySym s32
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
class CIrrDeviceLinux : public CIrrDeviceStub
 | 
			
		||||
{
 | 
			
		||||
public:
 | 
			
		||||
	//! constructor
 | 
			
		||||
	CIrrDeviceLinux(const SIrrlichtCreationParameters ¶m);
 | 
			
		||||
 | 
			
		||||
	//! destructor
 | 
			
		||||
	virtual ~CIrrDeviceLinux();
 | 
			
		||||
 | 
			
		||||
	//! runs the device. Returns false if device wants to be deleted
 | 
			
		||||
	bool run() override;
 | 
			
		||||
 | 
			
		||||
	//! Cause the device to temporarily pause execution and let other processes to run
 | 
			
		||||
	// This should bring down processor usage without major performance loss for Irrlicht
 | 
			
		||||
	void yield() override;
 | 
			
		||||
 | 
			
		||||
	//! Pause execution and let other processes to run for a specified amount of time.
 | 
			
		||||
	void sleep(u32 timeMs, bool pauseTimer) override;
 | 
			
		||||
 | 
			
		||||
	//! sets the caption of the window
 | 
			
		||||
	void setWindowCaption(const wchar_t *text) override;
 | 
			
		||||
 | 
			
		||||
	//! Sets the window icon.
 | 
			
		||||
	bool setWindowIcon(const video::IImage *img) override;
 | 
			
		||||
 | 
			
		||||
	//! returns if window is active. if not, nothing need to be drawn
 | 
			
		||||
	bool isWindowActive() const override;
 | 
			
		||||
 | 
			
		||||
	//! returns if window has focus.
 | 
			
		||||
	bool isWindowFocused() const override;
 | 
			
		||||
 | 
			
		||||
	//! returns if window is minimized.
 | 
			
		||||
	bool isWindowMinimized() const override;
 | 
			
		||||
 | 
			
		||||
	//! returns last state from maximizeWindow() and restoreWindow()
 | 
			
		||||
	bool isWindowMaximized() const override;
 | 
			
		||||
 | 
			
		||||
	//! Checks if the Irrlicht device supports touch events.
 | 
			
		||||
	bool supportsTouchEvents() const override;
 | 
			
		||||
 | 
			
		||||
	//! returns color format of the window.
 | 
			
		||||
	video::ECOLOR_FORMAT getColorFormat() const override;
 | 
			
		||||
 | 
			
		||||
	//! notifies the device that it should close itself
 | 
			
		||||
	void closeDevice() override;
 | 
			
		||||
 | 
			
		||||
	//! Sets if the window should be resizable in windowed mode.
 | 
			
		||||
	void setResizable(bool resize = false) override;
 | 
			
		||||
 | 
			
		||||
	//! Resize the render window.
 | 
			
		||||
	void setWindowSize(const core::dimension2d<u32> &size) override;
 | 
			
		||||
 | 
			
		||||
	//! Minimizes the window.
 | 
			
		||||
	void minimizeWindow() override;
 | 
			
		||||
 | 
			
		||||
	//! Maximizes the window.
 | 
			
		||||
	void maximizeWindow() override;
 | 
			
		||||
 | 
			
		||||
	//! Restores the window size.
 | 
			
		||||
	void restoreWindow() override;
 | 
			
		||||
 | 
			
		||||
	//! Get the position of this window on screen
 | 
			
		||||
	core::position2di getWindowPosition() override;
 | 
			
		||||
 | 
			
		||||
	//! Activate any joysticks, and generate events for them.
 | 
			
		||||
	bool activateJoysticks(core::array<SJoystickInfo> &joystickInfo) override;
 | 
			
		||||
 | 
			
		||||
	//! gets text from the clipboard
 | 
			
		||||
	//! \return Returns 0 if no string is in there, otherwise utf-8 text.
 | 
			
		||||
	virtual const c8 *getTextFromClipboard() const;
 | 
			
		||||
 | 
			
		||||
	//! gets text from the primary selection
 | 
			
		||||
	//! \return Returns 0 if no string is in there, otherwise utf-8 text.
 | 
			
		||||
	virtual const c8 *getTextFromPrimarySelection() const;
 | 
			
		||||
 | 
			
		||||
	//! copies text to the clipboard
 | 
			
		||||
	//! This sets the clipboard selection and _not_ the primary selection.
 | 
			
		||||
	//! @param text The text in utf-8
 | 
			
		||||
	virtual void copyToClipboard(const c8 *text) const;
 | 
			
		||||
 | 
			
		||||
	//! copies text to the primary selection
 | 
			
		||||
	//! This sets the primary selection which you have on X on the middle mouse button.
 | 
			
		||||
	//! @param text The text in utf-8
 | 
			
		||||
	virtual void copyToPrimarySelection(const c8 *text) const;
 | 
			
		||||
 | 
			
		||||
	//! Remove all messages pending in the system message loop
 | 
			
		||||
	void clearSystemMessages() override;
 | 
			
		||||
 | 
			
		||||
	//! Get the device type
 | 
			
		||||
	E_DEVICE_TYPE getType() const override
 | 
			
		||||
	{
 | 
			
		||||
		return EIDT_X11;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	//! Get the display density in dots per inch.
 | 
			
		||||
	float getDisplayDensity() const override;
 | 
			
		||||
 | 
			
		||||
#ifdef _IRR_COMPILE_WITH_X11_
 | 
			
		||||
	// convert an Irrlicht texture to a X11 cursor
 | 
			
		||||
	Cursor TextureToCursor(video::ITexture *tex, const core::rect<s32> &sourceRect, const core::position2d<s32> &hotspot);
 | 
			
		||||
	Cursor TextureToMonochromeCursor(video::ITexture *tex, const core::rect<s32> &sourceRect, const core::position2d<s32> &hotspot);
 | 
			
		||||
#ifdef _IRR_LINUX_XCURSOR_
 | 
			
		||||
	Cursor TextureToARGBCursor(video::ITexture *tex, const core::rect<s32> &sourceRect, const core::position2d<s32> &hotspot);
 | 
			
		||||
#endif
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
	//! create the driver
 | 
			
		||||
	void createDriver();
 | 
			
		||||
 | 
			
		||||
	bool createWindow();
 | 
			
		||||
 | 
			
		||||
	void createKeyMap();
 | 
			
		||||
 | 
			
		||||
	void pollJoysticks();
 | 
			
		||||
 | 
			
		||||
	void initXAtoms();
 | 
			
		||||
 | 
			
		||||
	void initXInput2();
 | 
			
		||||
 | 
			
		||||
	bool switchToFullscreen();
 | 
			
		||||
 | 
			
		||||
	void setupTopLevelXorgWindow();
 | 
			
		||||
 | 
			
		||||
#ifdef _IRR_COMPILE_WITH_X11_
 | 
			
		||||
	bool createInputContext();
 | 
			
		||||
	void destroyInputContext();
 | 
			
		||||
	EKEY_CODE getKeyCode(XEvent &event);
 | 
			
		||||
 | 
			
		||||
	const c8 *getTextFromSelection(Atom selection, core::stringc &text_buffer) const;
 | 
			
		||||
	bool becomeSelectionOwner(Atom selection) const;
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
	//! Implementation of the linux cursor control
 | 
			
		||||
	class CCursorControl : public gui::ICursorControl
 | 
			
		||||
	{
 | 
			
		||||
	public:
 | 
			
		||||
		CCursorControl(CIrrDeviceLinux *dev, bool null);
 | 
			
		||||
 | 
			
		||||
		~CCursorControl();
 | 
			
		||||
 | 
			
		||||
		//! Changes the visible state of the mouse cursor.
 | 
			
		||||
		void setVisible(bool visible) override
 | 
			
		||||
		{
 | 
			
		||||
			if (visible == IsVisible)
 | 
			
		||||
				return;
 | 
			
		||||
			IsVisible = visible;
 | 
			
		||||
#ifdef _IRR_COMPILE_WITH_X11_
 | 
			
		||||
			if (!Null) {
 | 
			
		||||
				if (!IsVisible)
 | 
			
		||||
					XDefineCursor(Device->XDisplay, Device->XWindow, InvisCursor);
 | 
			
		||||
				else
 | 
			
		||||
					XUndefineCursor(Device->XDisplay, Device->XWindow);
 | 
			
		||||
			}
 | 
			
		||||
#endif
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		//! Returns if the cursor is currently visible.
 | 
			
		||||
		bool isVisible() const override
 | 
			
		||||
		{
 | 
			
		||||
			return IsVisible;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		//! Sets the new position of the cursor.
 | 
			
		||||
		void setPosition(const core::position2d<f32> &pos) override
 | 
			
		||||
		{
 | 
			
		||||
			setPosition(pos.X, pos.Y);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		//! Sets the new position of the cursor.
 | 
			
		||||
		void setPosition(f32 x, f32 y) override
 | 
			
		||||
		{
 | 
			
		||||
			setPosition((s32)(x * Device->Width), (s32)(y * Device->Height));
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		//! Sets the new position of the cursor.
 | 
			
		||||
		void setPosition(const core::position2d<s32> &pos) override
 | 
			
		||||
		{
 | 
			
		||||
			setPosition(pos.X, pos.Y);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		//! Sets the new position of the cursor.
 | 
			
		||||
		void setPosition(s32 x, s32 y) override
 | 
			
		||||
		{
 | 
			
		||||
#ifdef _IRR_COMPILE_WITH_X11_
 | 
			
		||||
 | 
			
		||||
			if (!Null) {
 | 
			
		||||
				if (UseReferenceRect) {
 | 
			
		||||
// NOTE: XIWarpPointer works when X11 has set a coordinate transformation matrix for the mouse unlike XWarpPointer
 | 
			
		||||
// which runs into a bug mentioned here: https://gitlab.freedesktop.org/xorg/xserver/-/issues/600
 | 
			
		||||
// So also workaround for Irrlicht bug #450
 | 
			
		||||
#ifdef _IRR_LINUX_X11_XINPUT2_
 | 
			
		||||
					if (DeviceId != 0) {
 | 
			
		||||
						XIWarpPointer(Device->XDisplay,
 | 
			
		||||
								DeviceId,
 | 
			
		||||
								None,
 | 
			
		||||
								Device->XWindow, 0, 0,
 | 
			
		||||
								Device->Width,
 | 
			
		||||
								Device->Height,
 | 
			
		||||
								ReferenceRect.UpperLeftCorner.X + x,
 | 
			
		||||
								ReferenceRect.UpperLeftCorner.Y + y);
 | 
			
		||||
					} else
 | 
			
		||||
#endif
 | 
			
		||||
					{
 | 
			
		||||
						XWarpPointer(Device->XDisplay,
 | 
			
		||||
								None,
 | 
			
		||||
								Device->XWindow, 0, 0,
 | 
			
		||||
								Device->Width,
 | 
			
		||||
								Device->Height,
 | 
			
		||||
								ReferenceRect.UpperLeftCorner.X + x,
 | 
			
		||||
								ReferenceRect.UpperLeftCorner.Y + y);
 | 
			
		||||
					}
 | 
			
		||||
				} else {
 | 
			
		||||
#ifdef _IRR_LINUX_X11_XINPUT2_
 | 
			
		||||
					if (DeviceId != 0) {
 | 
			
		||||
						XIWarpPointer(Device->XDisplay,
 | 
			
		||||
								DeviceId,
 | 
			
		||||
								None,
 | 
			
		||||
								Device->XWindow, 0, 0,
 | 
			
		||||
								Device->Width,
 | 
			
		||||
								Device->Height, x, y);
 | 
			
		||||
					} else
 | 
			
		||||
#endif
 | 
			
		||||
					{
 | 
			
		||||
						XWarpPointer(Device->XDisplay,
 | 
			
		||||
								None,
 | 
			
		||||
								Device->XWindow, 0, 0,
 | 
			
		||||
								Device->Width,
 | 
			
		||||
								Device->Height, x, y);
 | 
			
		||||
					}
 | 
			
		||||
				}
 | 
			
		||||
				XFlush(Device->XDisplay);
 | 
			
		||||
			}
 | 
			
		||||
#endif
 | 
			
		||||
			CursorPos.X = x;
 | 
			
		||||
			CursorPos.Y = y;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		//! Returns the current position of the mouse cursor.
 | 
			
		||||
		const core::position2d<s32> &getPosition(bool updateCursor) override
 | 
			
		||||
		{
 | 
			
		||||
			if (updateCursor)
 | 
			
		||||
				updateCursorPos();
 | 
			
		||||
			return CursorPos;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		//! Returns the current position of the mouse cursor.
 | 
			
		||||
		core::position2d<f32> getRelativePosition(bool updateCursor) override
 | 
			
		||||
		{
 | 
			
		||||
			if (updateCursor)
 | 
			
		||||
				updateCursorPos();
 | 
			
		||||
 | 
			
		||||
			if (!UseReferenceRect) {
 | 
			
		||||
				return core::position2d<f32>(CursorPos.X / (f32)Device->Width,
 | 
			
		||||
						CursorPos.Y / (f32)Device->Height);
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			return core::position2d<f32>(CursorPos.X / (f32)ReferenceRect.getWidth(),
 | 
			
		||||
					CursorPos.Y / (f32)ReferenceRect.getHeight());
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		void setReferenceRect(core::rect<s32> *rect = 0) override
 | 
			
		||||
		{
 | 
			
		||||
			if (rect) {
 | 
			
		||||
				ReferenceRect = *rect;
 | 
			
		||||
				UseReferenceRect = true;
 | 
			
		||||
 | 
			
		||||
				// prevent division through zero and uneven sizes
 | 
			
		||||
 | 
			
		||||
				if (!ReferenceRect.getHeight() || ReferenceRect.getHeight() % 2)
 | 
			
		||||
					ReferenceRect.LowerRightCorner.Y += 1;
 | 
			
		||||
 | 
			
		||||
				if (!ReferenceRect.getWidth() || ReferenceRect.getWidth() % 2)
 | 
			
		||||
					ReferenceRect.LowerRightCorner.X += 1;
 | 
			
		||||
			} else
 | 
			
		||||
				UseReferenceRect = false;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		//! Sets the active cursor icon
 | 
			
		||||
		void setActiveIcon(gui::ECURSOR_ICON iconId) override;
 | 
			
		||||
 | 
			
		||||
		//! Gets the currently active icon
 | 
			
		||||
		gui::ECURSOR_ICON getActiveIcon() const override
 | 
			
		||||
		{
 | 
			
		||||
			return ActiveIcon;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		//! Add a custom sprite as cursor icon.
 | 
			
		||||
		gui::ECURSOR_ICON addIcon(const gui::SCursorSprite &icon) override;
 | 
			
		||||
 | 
			
		||||
		//! replace the given cursor icon.
 | 
			
		||||
		void changeIcon(gui::ECURSOR_ICON iconId, const gui::SCursorSprite &icon) override;
 | 
			
		||||
 | 
			
		||||
		//! Return a system-specific size which is supported for cursors. Larger icons will fail, smaller icons might work.
 | 
			
		||||
		core::dimension2di getSupportedIconSize() const override;
 | 
			
		||||
 | 
			
		||||
#ifdef _IRR_COMPILE_WITH_X11_
 | 
			
		||||
		//! Set platform specific behavior flags.
 | 
			
		||||
		void setPlatformBehavior(gui::ECURSOR_PLATFORM_BEHAVIOR behavior) override { PlatformBehavior = behavior; }
 | 
			
		||||
 | 
			
		||||
		//! Return platform specific behavior.
 | 
			
		||||
		gui::ECURSOR_PLATFORM_BEHAVIOR getPlatformBehavior() const override { return PlatformBehavior; }
 | 
			
		||||
 | 
			
		||||
		void update();
 | 
			
		||||
		void clearCursors();
 | 
			
		||||
#endif
 | 
			
		||||
	private:
 | 
			
		||||
		void updateCursorPos()
 | 
			
		||||
		{
 | 
			
		||||
#ifdef _IRR_COMPILE_WITH_X11_
 | 
			
		||||
			if (Null)
 | 
			
		||||
				return;
 | 
			
		||||
 | 
			
		||||
			if (PlatformBehavior & gui::ECPB_X11_CACHE_UPDATES && !os::Timer::isStopped()) {
 | 
			
		||||
				u32 now = os::Timer::getTime();
 | 
			
		||||
				if (now <= LastQuery)
 | 
			
		||||
					return;
 | 
			
		||||
				LastQuery = now;
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			Window tmp;
 | 
			
		||||
			int itmp1, itmp2;
 | 
			
		||||
			unsigned int maskreturn;
 | 
			
		||||
			XQueryPointer(Device->XDisplay, Device->XWindow,
 | 
			
		||||
					&tmp, &tmp,
 | 
			
		||||
					&itmp1, &itmp2,
 | 
			
		||||
					&CursorPos.X, &CursorPos.Y, &maskreturn);
 | 
			
		||||
#endif
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		CIrrDeviceLinux *Device;
 | 
			
		||||
		core::position2d<s32> CursorPos;
 | 
			
		||||
		core::rect<s32> ReferenceRect;
 | 
			
		||||
#ifdef _IRR_COMPILE_WITH_X11_
 | 
			
		||||
		gui::ECURSOR_PLATFORM_BEHAVIOR PlatformBehavior;
 | 
			
		||||
		u32 LastQuery;
 | 
			
		||||
		Cursor InvisCursor;
 | 
			
		||||
 | 
			
		||||
#ifdef _IRR_LINUX_X11_XINPUT2_
 | 
			
		||||
		int DeviceId;
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
		struct CursorFrameX11
 | 
			
		||||
		{
 | 
			
		||||
			CursorFrameX11() :
 | 
			
		||||
					IconHW(0) {}
 | 
			
		||||
			CursorFrameX11(Cursor icon) :
 | 
			
		||||
					IconHW(icon) {}
 | 
			
		||||
 | 
			
		||||
			Cursor IconHW; // hardware cursor
 | 
			
		||||
		};
 | 
			
		||||
 | 
			
		||||
		struct CursorX11
 | 
			
		||||
		{
 | 
			
		||||
			CursorX11() {}
 | 
			
		||||
			explicit CursorX11(Cursor iconHw, u32 frameTime = 0) :
 | 
			
		||||
					FrameTime(frameTime)
 | 
			
		||||
			{
 | 
			
		||||
				Frames.push_back(CursorFrameX11(iconHw));
 | 
			
		||||
			}
 | 
			
		||||
			core::array<CursorFrameX11> Frames;
 | 
			
		||||
			u32 FrameTime;
 | 
			
		||||
		};
 | 
			
		||||
 | 
			
		||||
		core::array<CursorX11> Cursors;
 | 
			
		||||
 | 
			
		||||
		void initCursors();
 | 
			
		||||
#endif
 | 
			
		||||
		bool IsVisible;
 | 
			
		||||
		bool Null;
 | 
			
		||||
		bool UseReferenceRect;
 | 
			
		||||
		gui::ECURSOR_ICON ActiveIcon;
 | 
			
		||||
		u32 ActiveIconStartTime;
 | 
			
		||||
	};
 | 
			
		||||
 | 
			
		||||
	friend class CCursorControl;
 | 
			
		||||
 | 
			
		||||
#ifdef _IRR_COMPILE_WITH_X11_
 | 
			
		||||
	friend class COpenGLDriver;
 | 
			
		||||
 | 
			
		||||
	Display *XDisplay;
 | 
			
		||||
	XVisualInfo *VisualInfo;
 | 
			
		||||
	int Screennr;
 | 
			
		||||
	Window XWindow;
 | 
			
		||||
	XSetWindowAttributes WndAttributes;
 | 
			
		||||
	XSizeHints *StdHints;
 | 
			
		||||
	XIM XInputMethod;
 | 
			
		||||
	XIC XInputContext;
 | 
			
		||||
	bool HasNetWM;
 | 
			
		||||
	// text is utf-8
 | 
			
		||||
	mutable core::stringc Clipboard;
 | 
			
		||||
	mutable core::stringc PrimarySelection;
 | 
			
		||||
#endif
 | 
			
		||||
#if defined(_IRR_LINUX_X11_XINPUT2_)
 | 
			
		||||
	int currentTouchedCount;
 | 
			
		||||
#endif
 | 
			
		||||
	u32 Width, Height;
 | 
			
		||||
	bool WindowHasFocus;
 | 
			
		||||
	bool WindowMinimized;
 | 
			
		||||
	bool WindowMaximized;
 | 
			
		||||
	bool ExternalWindow;
 | 
			
		||||
	int AutorepeatSupport;
 | 
			
		||||
 | 
			
		||||
	struct SKeyMap
 | 
			
		||||
	{
 | 
			
		||||
		SKeyMap() {}
 | 
			
		||||
		SKeyMap(s32 x11, s32 win32) :
 | 
			
		||||
				X11Key(x11), Win32Key(win32)
 | 
			
		||||
		{
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		KeySym X11Key;
 | 
			
		||||
		s32 Win32Key;
 | 
			
		||||
 | 
			
		||||
		bool operator<(const SKeyMap &o) const
 | 
			
		||||
		{
 | 
			
		||||
			return X11Key < o.X11Key;
 | 
			
		||||
		}
 | 
			
		||||
	};
 | 
			
		||||
 | 
			
		||||
	core::array<SKeyMap> KeyMap;
 | 
			
		||||
 | 
			
		||||
#if defined(_IRR_COMPILE_WITH_JOYSTICK_EVENTS_)
 | 
			
		||||
	struct JoystickInfo
 | 
			
		||||
	{
 | 
			
		||||
		int fd;
 | 
			
		||||
		int axes;
 | 
			
		||||
		int buttons;
 | 
			
		||||
 | 
			
		||||
		SEvent persistentData;
 | 
			
		||||
 | 
			
		||||
		JoystickInfo() :
 | 
			
		||||
				fd(-1), axes(0), buttons(0) {}
 | 
			
		||||
	};
 | 
			
		||||
	core::array<JoystickInfo> ActiveJoysticks;
 | 
			
		||||
#endif
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#endif // _IRR_COMPILE_WITH_X11_DEVICE_
 | 
			
		||||
@@ -1,231 +0,0 @@
 | 
			
		||||
// Copyright (C) 2005-2006 Etienne Petitjean
 | 
			
		||||
// Copyright (C) 2007-2012 Christian Stehno
 | 
			
		||||
// This file is part of the "Irrlicht Engine".
 | 
			
		||||
// For conditions of distribution and use, see copyright notice in Irrlicht.h
 | 
			
		||||
 | 
			
		||||
#pragma once
 | 
			
		||||
 | 
			
		||||
#ifdef _IRR_COMPILE_WITH_OSX_DEVICE_
 | 
			
		||||
 | 
			
		||||
#include "CIrrDeviceStub.h"
 | 
			
		||||
#include "IrrlichtDevice.h"
 | 
			
		||||
#include "IGUIEnvironment.h"
 | 
			
		||||
#include "ICursorControl.h"
 | 
			
		||||
 | 
			
		||||
#import <AppKit/NSWindow.h>
 | 
			
		||||
#import <AppKit/NSBitmapImageRep.h>
 | 
			
		||||
 | 
			
		||||
#include <map>
 | 
			
		||||
 | 
			
		||||
class CIrrDeviceMacOSX;
 | 
			
		||||
 | 
			
		||||
@interface CIrrDelegateOSX : NSObject <NSApplicationDelegate, NSWindowDelegate>
 | 
			
		||||
 | 
			
		||||
- (id)initWithDevice:(CIrrDeviceMacOSX *)device;
 | 
			
		||||
- (void)terminate:(id)sender;
 | 
			
		||||
- (BOOL)isQuit;
 | 
			
		||||
 | 
			
		||||
@end
 | 
			
		||||
 | 
			
		||||
class CIrrDeviceMacOSX : public CIrrDeviceStub
 | 
			
		||||
{
 | 
			
		||||
public:
 | 
			
		||||
	//! constructor
 | 
			
		||||
	CIrrDeviceMacOSX(const SIrrlichtCreationParameters ¶ms);
 | 
			
		||||
 | 
			
		||||
	//! destructor
 | 
			
		||||
	virtual ~CIrrDeviceMacOSX();
 | 
			
		||||
 | 
			
		||||
	//! runs the device. Returns false if device wants to be deleted
 | 
			
		||||
	bool run() override;
 | 
			
		||||
 | 
			
		||||
	//! Cause the device to temporarily pause execution and let other processes to run
 | 
			
		||||
	// This should bring down processor usage without major performance loss for Irrlicht
 | 
			
		||||
	void yield() override;
 | 
			
		||||
 | 
			
		||||
	//! Pause execution and let other processes to run for a specified amount of time.
 | 
			
		||||
	void sleep(u32 timeMs, bool pauseTimer) override;
 | 
			
		||||
 | 
			
		||||
	//! sets the caption of the window
 | 
			
		||||
	void setWindowCaption(const wchar_t *text) override;
 | 
			
		||||
 | 
			
		||||
	//! returns if window is active. if not, nothing need to be drawn
 | 
			
		||||
	bool isWindowActive() const override;
 | 
			
		||||
 | 
			
		||||
	//! Checks if the Irrlicht window has focus
 | 
			
		||||
	bool isWindowFocused() const override;
 | 
			
		||||
 | 
			
		||||
	//! Checks if the Irrlicht window is minimized
 | 
			
		||||
	bool isWindowMinimized() const override;
 | 
			
		||||
 | 
			
		||||
	//! notifies the device that it should close itself
 | 
			
		||||
	void closeDevice() override;
 | 
			
		||||
 | 
			
		||||
	//! Sets if the window should be resizable in windowed mode.
 | 
			
		||||
	void setResizable(bool resize) override;
 | 
			
		||||
 | 
			
		||||
	//! Returns true if the window is resizable, false if not
 | 
			
		||||
	virtual bool isResizable() const;
 | 
			
		||||
 | 
			
		||||
	//! Minimizes the window if possible
 | 
			
		||||
	void minimizeWindow() override;
 | 
			
		||||
 | 
			
		||||
	//! Maximizes the window if possible.
 | 
			
		||||
	void maximizeWindow() override;
 | 
			
		||||
 | 
			
		||||
	//! Restore the window to normal size if possible.
 | 
			
		||||
	void restoreWindow() override;
 | 
			
		||||
 | 
			
		||||
	//! Get the position of this window on screen
 | 
			
		||||
	core::position2di getWindowPosition() override;
 | 
			
		||||
 | 
			
		||||
	//! Activate any joysticks, and generate events for them.
 | 
			
		||||
	bool activateJoysticks(core::array<SJoystickInfo> &joystickInfo) override;
 | 
			
		||||
 | 
			
		||||
	//! Get the device type
 | 
			
		||||
	E_DEVICE_TYPE getType() const override
 | 
			
		||||
	{
 | 
			
		||||
		return EIDT_OSX;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	void setMouseLocation(int x, int y);
 | 
			
		||||
	void setResize(int width, int height);
 | 
			
		||||
	void setCursorVisible(bool visible);
 | 
			
		||||
	void setWindow(NSWindow *window);
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
	//! create the driver
 | 
			
		||||
	void createDriver();
 | 
			
		||||
 | 
			
		||||
	//! Implementation of the macos x cursor control
 | 
			
		||||
	class CCursorControl : public gui::ICursorControl
 | 
			
		||||
	{
 | 
			
		||||
	public:
 | 
			
		||||
		CCursorControl(const core::dimension2d<u32> &wsize, CIrrDeviceMacOSX *device) :
 | 
			
		||||
				WindowSize(wsize), InvWindowSize(0.0f, 0.0f), Device(device), IsVisible(true), UseReferenceRect(false)
 | 
			
		||||
		{
 | 
			
		||||
			CursorPos.X = CursorPos.Y = 0;
 | 
			
		||||
			if (WindowSize.Width != 0)
 | 
			
		||||
				InvWindowSize.Width = 1.0f / WindowSize.Width;
 | 
			
		||||
			if (WindowSize.Height != 0)
 | 
			
		||||
				InvWindowSize.Height = 1.0f / WindowSize.Height;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		//! Changes the visible state of the mouse cursor.
 | 
			
		||||
		void setVisible(bool visible) override
 | 
			
		||||
		{
 | 
			
		||||
			IsVisible = visible;
 | 
			
		||||
			Device->setCursorVisible(visible);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		//! Returns if the cursor is currently visible.
 | 
			
		||||
		bool isVisible() const override
 | 
			
		||||
		{
 | 
			
		||||
			return IsVisible;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		//! Sets the new position of the cursor.
 | 
			
		||||
		void setPosition(const core::position2d<f32> &pos) override
 | 
			
		||||
		{
 | 
			
		||||
			setPosition(pos.X, pos.Y);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		//! Sets the new position of the cursor.
 | 
			
		||||
		void setPosition(f32 x, f32 y) override
 | 
			
		||||
		{
 | 
			
		||||
			setPosition((s32)(x * WindowSize.Width), (s32)(y * WindowSize.Height));
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		//! Sets the new position of the cursor.
 | 
			
		||||
		void setPosition(const core::position2d<s32> &pos) override
 | 
			
		||||
		{
 | 
			
		||||
			if (CursorPos.X != pos.X || CursorPos.Y != pos.Y)
 | 
			
		||||
				setPosition(pos.X, pos.Y);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		//! Sets the new position of the cursor.
 | 
			
		||||
		void setPosition(s32 x, s32 y) override
 | 
			
		||||
		{
 | 
			
		||||
			if (UseReferenceRect) {
 | 
			
		||||
				Device->setMouseLocation(ReferenceRect.UpperLeftCorner.X + x, ReferenceRect.UpperLeftCorner.Y + y);
 | 
			
		||||
			} else {
 | 
			
		||||
				Device->setMouseLocation(x, y);
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		//! Returns the current position of the mouse cursor.
 | 
			
		||||
		const core::position2d<s32> &getPosition(bool updateCursor) override
 | 
			
		||||
		{
 | 
			
		||||
			return CursorPos;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		//! Returns the current position of the mouse cursor.
 | 
			
		||||
		core::position2d<f32> getRelativePosition(bool updateCursor) override
 | 
			
		||||
		{
 | 
			
		||||
			if (!UseReferenceRect) {
 | 
			
		||||
				return core::position2d<f32>(CursorPos.X * InvWindowSize.Width,
 | 
			
		||||
						CursorPos.Y * InvWindowSize.Height);
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			return core::position2d<f32>(CursorPos.X / (f32)ReferenceRect.getWidth(),
 | 
			
		||||
					CursorPos.Y / (f32)ReferenceRect.getHeight());
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		//! Sets an absolute reference rect for calculating the cursor position.
 | 
			
		||||
		void setReferenceRect(core::rect<s32> *rect = 0) override
 | 
			
		||||
		{
 | 
			
		||||
			if (rect) {
 | 
			
		||||
				ReferenceRect = *rect;
 | 
			
		||||
				UseReferenceRect = true;
 | 
			
		||||
 | 
			
		||||
				// prevent division through zero and uneven sizes
 | 
			
		||||
 | 
			
		||||
				if (!ReferenceRect.getHeight() || ReferenceRect.getHeight() % 2)
 | 
			
		||||
					ReferenceRect.LowerRightCorner.Y += 1;
 | 
			
		||||
 | 
			
		||||
				if (!ReferenceRect.getWidth() || ReferenceRect.getWidth() % 2)
 | 
			
		||||
					ReferenceRect.LowerRightCorner.X += 1;
 | 
			
		||||
			} else
 | 
			
		||||
				UseReferenceRect = false;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		//! Updates the internal cursor position
 | 
			
		||||
		void updateInternalCursorPosition(int x, int y)
 | 
			
		||||
		{
 | 
			
		||||
			CursorPos.X = x;
 | 
			
		||||
			CursorPos.Y = y;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
	private:
 | 
			
		||||
		core::position2d<s32> CursorPos;
 | 
			
		||||
		core::dimension2d<s32> WindowSize;
 | 
			
		||||
		core::dimension2d<float> InvWindowSize;
 | 
			
		||||
		core::rect<s32> ReferenceRect;
 | 
			
		||||
		CIrrDeviceMacOSX *Device;
 | 
			
		||||
		bool IsVisible;
 | 
			
		||||
		bool UseReferenceRect;
 | 
			
		||||
	};
 | 
			
		||||
 | 
			
		||||
	bool createWindow();
 | 
			
		||||
	void initKeycodes();
 | 
			
		||||
	void storeMouseLocation();
 | 
			
		||||
	void postMouseEvent(void *event, SEvent &ievent);
 | 
			
		||||
	void postKeyEvent(void *event, SEvent &ievent, bool pressed);
 | 
			
		||||
	void pollJoysticks();
 | 
			
		||||
 | 
			
		||||
	NSWindow *Window;
 | 
			
		||||
	CGDirectDisplayID Display;
 | 
			
		||||
	std::map<int, int> KeyCodes;
 | 
			
		||||
	int DeviceWidth;
 | 
			
		||||
	int DeviceHeight;
 | 
			
		||||
	int ScreenWidth;
 | 
			
		||||
	int ScreenHeight;
 | 
			
		||||
	u32 MouseButtonStates;
 | 
			
		||||
	bool IsFullscreen;
 | 
			
		||||
	bool IsActive;
 | 
			
		||||
	bool IsShiftDown;
 | 
			
		||||
	bool IsControlDown;
 | 
			
		||||
	bool IsResizable;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#endif // _IRR_COMPILE_WITH_OSX_DEVICE_
 | 
			
		||||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							@@ -1,402 +0,0 @@
 | 
			
		||||
// Copyright (C) 2002-2012 Nikolaus Gebhardt
 | 
			
		||||
// This file is part of the "Irrlicht Engine".
 | 
			
		||||
// For conditions of distribution and use, see copyright notice in irrlicht.h
 | 
			
		||||
 | 
			
		||||
#pragma once
 | 
			
		||||
 | 
			
		||||
#ifdef _IRR_COMPILE_WITH_WINDOWS_DEVICE_
 | 
			
		||||
 | 
			
		||||
#include "CIrrDeviceStub.h"
 | 
			
		||||
#include "IrrlichtDevice.h"
 | 
			
		||||
#include "ITexture.h"
 | 
			
		||||
 | 
			
		||||
#define WIN32_LEAN_AND_MEAN
 | 
			
		||||
#include <windows.h>
 | 
			
		||||
#include <mmsystem.h> // For JOYCAPS
 | 
			
		||||
#include <windowsx.h>
 | 
			
		||||
#if !defined(GET_X_LPARAM)
 | 
			
		||||
#define GET_X_LPARAM(lp) ((int)(short)LOWORD(lp))
 | 
			
		||||
#define GET_Y_LPARAM(lp) ((int)(short)HIWORD(lp))
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
struct SJoystickWin32Control;
 | 
			
		||||
 | 
			
		||||
class CIrrDeviceWin32 : public CIrrDeviceStub
 | 
			
		||||
{
 | 
			
		||||
	friend struct SJoystickWin32Control;
 | 
			
		||||
 | 
			
		||||
public:
 | 
			
		||||
	//! constructor
 | 
			
		||||
	CIrrDeviceWin32(const SIrrlichtCreationParameters ¶ms);
 | 
			
		||||
 | 
			
		||||
	//! destructor
 | 
			
		||||
	virtual ~CIrrDeviceWin32();
 | 
			
		||||
 | 
			
		||||
	//! runs the device. Returns false if device wants to be deleted
 | 
			
		||||
	bool run() override;
 | 
			
		||||
 | 
			
		||||
	//! Cause the device to temporarily pause execution and let other processes to run
 | 
			
		||||
	// This should bring down processor usage without major performance loss for Irrlicht
 | 
			
		||||
	void yield() override;
 | 
			
		||||
 | 
			
		||||
	//! Pause execution and let other processes to run for a specified amount of time.
 | 
			
		||||
	void sleep(u32 timeMs, bool pauseTimer) override;
 | 
			
		||||
 | 
			
		||||
	//! sets the caption of the window
 | 
			
		||||
	void setWindowCaption(const wchar_t *text) override;
 | 
			
		||||
 | 
			
		||||
	//! Sets the window icon.
 | 
			
		||||
	bool setWindowIcon(const video::IImage *img) override;
 | 
			
		||||
 | 
			
		||||
	//! returns if window is active. if not, nothing need to be drawn
 | 
			
		||||
	bool isWindowActive() const override;
 | 
			
		||||
 | 
			
		||||
	//! returns if window has focus
 | 
			
		||||
	bool isWindowFocused() const override;
 | 
			
		||||
 | 
			
		||||
	//! returns if window is minimized
 | 
			
		||||
	bool isWindowMinimized() const override;
 | 
			
		||||
 | 
			
		||||
	//! returns last state from maximizeWindow() and restoreWindow()
 | 
			
		||||
	bool isWindowMaximized() const override;
 | 
			
		||||
 | 
			
		||||
	//! notifies the device that it should close itself
 | 
			
		||||
	void closeDevice() override;
 | 
			
		||||
 | 
			
		||||
	//! Notifies the device, that it has been resized
 | 
			
		||||
	/** Must be publis as it is called from free function (event handler) */
 | 
			
		||||
	void OnResized();
 | 
			
		||||
 | 
			
		||||
	//! Sets if the window should be resizable in windowed mode.
 | 
			
		||||
	void setResizable(bool resize = false) override;
 | 
			
		||||
 | 
			
		||||
	//! Resize the render window.
 | 
			
		||||
	void setWindowSize(const core::dimension2d<u32> &size) override;
 | 
			
		||||
 | 
			
		||||
	//! Minimizes the window.
 | 
			
		||||
	void minimizeWindow() override;
 | 
			
		||||
 | 
			
		||||
	//! Maximizes the window.
 | 
			
		||||
	void maximizeWindow() override;
 | 
			
		||||
 | 
			
		||||
	//! Restores the window size.
 | 
			
		||||
	void restoreWindow() override;
 | 
			
		||||
 | 
			
		||||
	//! Get the position of the window on screen
 | 
			
		||||
	core::position2di getWindowPosition() override;
 | 
			
		||||
 | 
			
		||||
	//! Activate any joysticks, and generate events for them.
 | 
			
		||||
	bool activateJoysticks(core::array<SJoystickInfo> &joystickInfo) override;
 | 
			
		||||
 | 
			
		||||
	//! Remove all messages pending in the system message loop
 | 
			
		||||
	void clearSystemMessages() override;
 | 
			
		||||
 | 
			
		||||
	//! Get the device type
 | 
			
		||||
	E_DEVICE_TYPE getType() const override
 | 
			
		||||
	{
 | 
			
		||||
		return EIDT_WIN32;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	//! Get the display density in dots per inch.
 | 
			
		||||
	float getDisplayDensity() const override;
 | 
			
		||||
 | 
			
		||||
	//! Compares to the last call of this function to return double and triple clicks.
 | 
			
		||||
	//! \return Returns only 1,2 or 3. A 4th click will start with 1 again.
 | 
			
		||||
	u32 checkSuccessiveClicks(s32 mouseX, s32 mouseY, EMOUSE_INPUT_EVENT inputEvent) override
 | 
			
		||||
	{
 | 
			
		||||
		// we just have to make it public
 | 
			
		||||
		return CIrrDeviceStub::checkSuccessiveClicks(mouseX, mouseY, inputEvent);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	//! Switch to fullscreen
 | 
			
		||||
	bool switchToFullScreen();
 | 
			
		||||
 | 
			
		||||
	// convert an Irrlicht texture to a windows cursor
 | 
			
		||||
	HCURSOR TextureToCursor(HWND hwnd, video::ITexture *tex, const core::rect<s32> &sourceRect, const core::position2d<s32> &hotspot);
 | 
			
		||||
 | 
			
		||||
	//! Implementation of the win32 cursor control
 | 
			
		||||
	class CCursorControl : public gui::ICursorControl
 | 
			
		||||
	{
 | 
			
		||||
	public:
 | 
			
		||||
		CCursorControl(CIrrDeviceWin32 *device, const core::dimension2d<u32> &wsize, HWND hwnd, bool fullscreen);
 | 
			
		||||
		~CCursorControl();
 | 
			
		||||
 | 
			
		||||
		//! Changes the visible state of the mouse cursor.
 | 
			
		||||
		void setVisible(bool visible) override
 | 
			
		||||
		{
 | 
			
		||||
			CURSORINFO info;
 | 
			
		||||
			info.cbSize = sizeof(CURSORINFO);
 | 
			
		||||
			BOOL gotCursorInfo = GetCursorInfo(&info);
 | 
			
		||||
			while (gotCursorInfo) {
 | 
			
		||||
#ifdef CURSOR_SUPPRESSED
 | 
			
		||||
				// Since Windows 8 the cursor can be suppressed by a touch interface
 | 
			
		||||
				if (visible && info.flags == CURSOR_SUPPRESSED) {
 | 
			
		||||
					break;
 | 
			
		||||
				}
 | 
			
		||||
#endif
 | 
			
		||||
				if ((visible && info.flags == CURSOR_SHOWING) || // visible
 | 
			
		||||
						(!visible && info.flags == 0))           // hidden
 | 
			
		||||
				{
 | 
			
		||||
					break;
 | 
			
		||||
				}
 | 
			
		||||
				// this only increases an internal
 | 
			
		||||
				// display counter in windows, so it
 | 
			
		||||
				// might have to be called some more
 | 
			
		||||
				const int showResult = ShowCursor(visible);
 | 
			
		||||
				// if result has correct sign we can
 | 
			
		||||
				// stop here as well
 | 
			
		||||
				if ((!visible && showResult < 0) ||
 | 
			
		||||
						(visible && showResult >= 0))
 | 
			
		||||
					break;
 | 
			
		||||
				// yes, it really must be set each time
 | 
			
		||||
				info.cbSize = sizeof(CURSORINFO);
 | 
			
		||||
				gotCursorInfo = GetCursorInfo(&info);
 | 
			
		||||
 | 
			
		||||
#ifdef CURSOR_SUPPRESSED
 | 
			
		||||
				// Not sure if a cursor which we tried to hide still can be suppressed.
 | 
			
		||||
				// I have no touch-display for testing this and MSDN doesn't describe it.
 | 
			
		||||
				// But adding this check shouldn't hurt and might prevent an endless loop.
 | 
			
		||||
				if (!visible && info.flags == CURSOR_SUPPRESSED) {
 | 
			
		||||
					break;
 | 
			
		||||
				}
 | 
			
		||||
#endif
 | 
			
		||||
			}
 | 
			
		||||
			IsVisible = visible;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		//! Returns if the cursor is currently visible.
 | 
			
		||||
		bool isVisible() const override
 | 
			
		||||
		{
 | 
			
		||||
			return IsVisible;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		//! Sets the new position of the cursor.
 | 
			
		||||
		void setPosition(const core::position2d<f32> &pos) override
 | 
			
		||||
		{
 | 
			
		||||
			setPosition(pos.X, pos.Y);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		//! Sets the new position of the cursor.
 | 
			
		||||
		void setPosition(f32 x, f32 y) override
 | 
			
		||||
		{
 | 
			
		||||
			if (!UseReferenceRect)
 | 
			
		||||
				setPosition(core::round32(x * WindowSize.Width), core::round32(y * WindowSize.Height));
 | 
			
		||||
			else
 | 
			
		||||
				setPosition(core::round32(x * ReferenceRect.getWidth()), core::round32(y * ReferenceRect.getHeight()));
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		//! Sets the new position of the cursor.
 | 
			
		||||
		void setPosition(const core::position2d<s32> &pos) override
 | 
			
		||||
		{
 | 
			
		||||
			setPosition(pos.X, pos.Y);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		//! Sets the new position of the cursor.
 | 
			
		||||
		void setPosition(s32 x, s32 y) override
 | 
			
		||||
		{
 | 
			
		||||
			if (UseReferenceRect) {
 | 
			
		||||
				SetCursorPos(ReferenceRect.UpperLeftCorner.X + x,
 | 
			
		||||
						ReferenceRect.UpperLeftCorner.Y + y);
 | 
			
		||||
			} else {
 | 
			
		||||
				RECT rect;
 | 
			
		||||
				if (GetWindowRect(HWnd, &rect))
 | 
			
		||||
					SetCursorPos(x + rect.left + BorderX, y + rect.top + BorderY);
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			CursorPos.X = x;
 | 
			
		||||
			CursorPos.Y = y;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		//! Returns the current position of the mouse cursor.
 | 
			
		||||
		const core::position2d<s32> &getPosition(bool updateCursor) override
 | 
			
		||||
		{
 | 
			
		||||
			if (updateCursor)
 | 
			
		||||
				updateInternalCursorPosition();
 | 
			
		||||
			return CursorPos;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		//! Returns the current position of the mouse cursor.
 | 
			
		||||
		core::position2d<f32> getRelativePosition(bool updateCursor) override
 | 
			
		||||
		{
 | 
			
		||||
			if (updateCursor)
 | 
			
		||||
				updateInternalCursorPosition();
 | 
			
		||||
 | 
			
		||||
			if (!UseReferenceRect) {
 | 
			
		||||
				return core::position2d<f32>(CursorPos.X * InvWindowSize.Width,
 | 
			
		||||
						CursorPos.Y * InvWindowSize.Height);
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			return core::position2d<f32>(CursorPos.X / (f32)ReferenceRect.getWidth(),
 | 
			
		||||
					CursorPos.Y / (f32)ReferenceRect.getHeight());
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		//! Sets an absolute reference rect for calculating the cursor position.
 | 
			
		||||
		void setReferenceRect(core::rect<s32> *rect = 0) override
 | 
			
		||||
		{
 | 
			
		||||
			if (rect) {
 | 
			
		||||
				ReferenceRect = *rect;
 | 
			
		||||
				UseReferenceRect = true;
 | 
			
		||||
 | 
			
		||||
				// prevent division through zero and uneven sizes
 | 
			
		||||
 | 
			
		||||
				if (!ReferenceRect.getHeight() || ReferenceRect.getHeight() % 2)
 | 
			
		||||
					ReferenceRect.LowerRightCorner.Y += 1;
 | 
			
		||||
 | 
			
		||||
				if (!ReferenceRect.getWidth() || ReferenceRect.getWidth() % 2)
 | 
			
		||||
					ReferenceRect.LowerRightCorner.X += 1;
 | 
			
		||||
			} else
 | 
			
		||||
				UseReferenceRect = false;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		/** Used to notify the cursor that the window was resized. */
 | 
			
		||||
		void OnResize(const core::dimension2d<u32> &size)
 | 
			
		||||
		{
 | 
			
		||||
			WindowSize = size;
 | 
			
		||||
			if (size.Width != 0)
 | 
			
		||||
				InvWindowSize.Width = 1.0f / size.Width;
 | 
			
		||||
			else
 | 
			
		||||
				InvWindowSize.Width = 0.f;
 | 
			
		||||
 | 
			
		||||
			if (size.Height != 0)
 | 
			
		||||
				InvWindowSize.Height = 1.0f / size.Height;
 | 
			
		||||
			else
 | 
			
		||||
				InvWindowSize.Height = 0.f;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		/** Used to notify the cursor that the window resizable settings changed. */
 | 
			
		||||
		void updateBorderSize(bool fullscreen, bool resizable)
 | 
			
		||||
		{
 | 
			
		||||
			if (!fullscreen) {
 | 
			
		||||
				s32 paddingBorder = 0;
 | 
			
		||||
#ifdef SM_CXPADDEDBORDER
 | 
			
		||||
				paddingBorder = GetSystemMetrics(SM_CXPADDEDBORDER);
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
				if (resizable) {
 | 
			
		||||
					BorderX = GetSystemMetrics(SM_CXSIZEFRAME) + paddingBorder;
 | 
			
		||||
					BorderY = GetSystemMetrics(SM_CYCAPTION) + GetSystemMetrics(SM_CYSIZEFRAME) + paddingBorder;
 | 
			
		||||
				} else {
 | 
			
		||||
					BorderX = GetSystemMetrics(SM_CXDLGFRAME) + paddingBorder;
 | 
			
		||||
					BorderY = GetSystemMetrics(SM_CYCAPTION) + GetSystemMetrics(SM_CYDLGFRAME) + paddingBorder;
 | 
			
		||||
				}
 | 
			
		||||
			} else {
 | 
			
		||||
				BorderX = BorderY = 0;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		//! Sets the active cursor icon
 | 
			
		||||
		void setActiveIcon(gui::ECURSOR_ICON iconId) override;
 | 
			
		||||
 | 
			
		||||
		//! Gets the currently active icon
 | 
			
		||||
		gui::ECURSOR_ICON getActiveIcon() const override
 | 
			
		||||
		{
 | 
			
		||||
			return ActiveIcon;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		//! Add a custom sprite as cursor icon.
 | 
			
		||||
		gui::ECURSOR_ICON addIcon(const gui::SCursorSprite &icon) override;
 | 
			
		||||
 | 
			
		||||
		//! replace the given cursor icon.
 | 
			
		||||
		void changeIcon(gui::ECURSOR_ICON iconId, const gui::SCursorSprite &icon) override;
 | 
			
		||||
 | 
			
		||||
		//! Return a system-specific size which is supported for cursors. Larger icons will fail, smaller icons might work.
 | 
			
		||||
		core::dimension2di getSupportedIconSize() const override;
 | 
			
		||||
 | 
			
		||||
		void update();
 | 
			
		||||
 | 
			
		||||
	private:
 | 
			
		||||
		//! Updates the internal cursor position
 | 
			
		||||
		void updateInternalCursorPosition()
 | 
			
		||||
		{
 | 
			
		||||
			POINT p;
 | 
			
		||||
			if (!GetCursorPos(&p)) {
 | 
			
		||||
				DWORD xy = GetMessagePos();
 | 
			
		||||
				p.x = GET_X_LPARAM(xy);
 | 
			
		||||
				p.y = GET_Y_LPARAM(xy);
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			if (UseReferenceRect) {
 | 
			
		||||
				CursorPos.X = p.x - ReferenceRect.UpperLeftCorner.X;
 | 
			
		||||
				CursorPos.Y = p.y - ReferenceRect.UpperLeftCorner.Y;
 | 
			
		||||
			} else {
 | 
			
		||||
				RECT rect;
 | 
			
		||||
				if (GetWindowRect(HWnd, &rect)) {
 | 
			
		||||
					CursorPos.X = p.x - rect.left - BorderX;
 | 
			
		||||
					CursorPos.Y = p.y - rect.top - BorderY;
 | 
			
		||||
				} else {
 | 
			
		||||
					// window seems not to be existent, so set cursor to
 | 
			
		||||
					// a negative value
 | 
			
		||||
					CursorPos.X = -1;
 | 
			
		||||
					CursorPos.Y = -1;
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		CIrrDeviceWin32 *Device;
 | 
			
		||||
		core::position2d<s32> CursorPos;
 | 
			
		||||
		core::dimension2d<u32> WindowSize;
 | 
			
		||||
		core::dimension2d<f32> InvWindowSize;
 | 
			
		||||
		HWND HWnd;
 | 
			
		||||
 | 
			
		||||
		s32 BorderX, BorderY;
 | 
			
		||||
		core::rect<s32> ReferenceRect;
 | 
			
		||||
		bool UseReferenceRect;
 | 
			
		||||
		bool IsVisible;
 | 
			
		||||
 | 
			
		||||
		struct CursorFrameW32
 | 
			
		||||
		{
 | 
			
		||||
			CursorFrameW32() :
 | 
			
		||||
					IconHW(0) {}
 | 
			
		||||
			CursorFrameW32(HCURSOR icon) :
 | 
			
		||||
					IconHW(icon) {}
 | 
			
		||||
 | 
			
		||||
			HCURSOR IconHW; // hardware cursor
 | 
			
		||||
		};
 | 
			
		||||
 | 
			
		||||
		struct CursorW32
 | 
			
		||||
		{
 | 
			
		||||
			CursorW32() {}
 | 
			
		||||
			explicit CursorW32(HCURSOR iconHw, u32 frameTime = 0) :
 | 
			
		||||
					FrameTime(frameTime)
 | 
			
		||||
			{
 | 
			
		||||
				Frames.push_back(CursorFrameW32(iconHw));
 | 
			
		||||
			}
 | 
			
		||||
			core::array<CursorFrameW32> Frames;
 | 
			
		||||
			u32 FrameTime;
 | 
			
		||||
		};
 | 
			
		||||
 | 
			
		||||
		core::array<CursorW32> Cursors;
 | 
			
		||||
		gui::ECURSOR_ICON ActiveIcon;
 | 
			
		||||
		u32 ActiveIconStartTime;
 | 
			
		||||
 | 
			
		||||
		void initCursors();
 | 
			
		||||
	};
 | 
			
		||||
 | 
			
		||||
	//! returns the win32 cursor control
 | 
			
		||||
	CCursorControl *getWin32CursorControl();
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
	//! create the driver
 | 
			
		||||
	void createDriver();
 | 
			
		||||
 | 
			
		||||
	//! Process system events
 | 
			
		||||
	void handleSystemMessages();
 | 
			
		||||
 | 
			
		||||
	void getWindowsVersion(core::stringc &version);
 | 
			
		||||
 | 
			
		||||
	void resizeIfNecessary();
 | 
			
		||||
 | 
			
		||||
	DWORD getWindowStyle(bool fullscreen, bool resizable) const;
 | 
			
		||||
 | 
			
		||||
	HWND HWnd;
 | 
			
		||||
 | 
			
		||||
	bool Resized;
 | 
			
		||||
	bool ExternalWindow;
 | 
			
		||||
	CCursorControl *Win32CursorControl;
 | 
			
		||||
 | 
			
		||||
	SJoystickWin32Control *JoyControl;
 | 
			
		||||
 | 
			
		||||
	bool WindowMaximized;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#endif // _IRR_COMPILE_WITH_WINDOWS_DEVICE_
 | 
			
		||||
@@ -1,7 +1,3 @@
 | 
			
		||||
set(DEFAULT_SDL2 ON)
 | 
			
		||||
 | 
			
		||||
option(USE_SDL2 "Use the SDL2 backend" ${DEFAULT_SDL2})
 | 
			
		||||
 | 
			
		||||
option(USE_SDL2_STATIC "Link with SDL2 static libraries" FALSE)
 | 
			
		||||
 | 
			
		||||
# Compiler flags
 | 
			
		||||
@@ -62,26 +58,18 @@ endif()
 | 
			
		||||
 | 
			
		||||
if(WIN32)
 | 
			
		||||
	add_compile_definitions(_IRR_WINDOWS_ _IRR_WINDOWS_API_)
 | 
			
		||||
	set(DEVICE "WINDOWS")
 | 
			
		||||
elseif(APPLE)
 | 
			
		||||
	add_compile_definitions(_IRR_OSX_PLATFORM_)
 | 
			
		||||
	set(DEVICE "OSX")
 | 
			
		||||
elseif(ANDROID)
 | 
			
		||||
	add_compile_definitions(_IRR_ANDROID_PLATFORM_)
 | 
			
		||||
	if(NOT USE_SDL2)
 | 
			
		||||
		message(FATAL_ERROR "The Android build requires SDL2")
 | 
			
		||||
	endif()
 | 
			
		||||
elseif(EMSCRIPTEN)
 | 
			
		||||
	add_compile_definitions(_IRR_EMSCRIPTEN_PLATFORM_ _IRR_COMPILE_WITH_EGL_MANAGER_)
 | 
			
		||||
	set(LINUX_PLATFORM TRUE)
 | 
			
		||||
	set(DEVICE "SDL")
 | 
			
		||||
elseif(SOLARIS)
 | 
			
		||||
	add_compile_definitions(_IRR_SOLARIS_PLATFORM_ _IRR_POSIX_API_)
 | 
			
		||||
	set(DEVICE "X11")
 | 
			
		||||
else()
 | 
			
		||||
	add_compile_definitions(_IRR_POSIX_API_)
 | 
			
		||||
	set(LINUX_PLATFORM TRUE)
 | 
			
		||||
	set(DEVICE "X11")
 | 
			
		||||
endif()
 | 
			
		||||
 | 
			
		||||
if(LINUX_PLATFORM)
 | 
			
		||||
@@ -92,29 +80,7 @@ if(MSVC)
 | 
			
		||||
	add_compile_definitions(_CRT_SECURE_NO_WARNINGS)
 | 
			
		||||
endif()
 | 
			
		||||
 | 
			
		||||
if(USE_SDL2)
 | 
			
		||||
	set(DEVICE "SDL")
 | 
			
		||||
elseif(DEVICE STREQUAL "SDL")
 | 
			
		||||
	message(FATAL_ERROR "SDL was used but not enabled?!")
 | 
			
		||||
endif()
 | 
			
		||||
 | 
			
		||||
add_compile_definitions("_IRR_COMPILE_WITH_${DEVICE}_DEVICE_")
 | 
			
		||||
 | 
			
		||||
# X11
 | 
			
		||||
 | 
			
		||||
if(DEVICE STREQUAL "X11")
 | 
			
		||||
	option(USE_X11 "Use X11" TRUE)
 | 
			
		||||
else()
 | 
			
		||||
	set(USE_X11 FALSE)
 | 
			
		||||
endif()
 | 
			
		||||
 | 
			
		||||
if(LINUX_PLATFORM AND USE_X11)
 | 
			
		||||
	option(USE_XINPUT2 "Use XInput2" TRUE)
 | 
			
		||||
	option(USE_XCURSOR "Use XCursor" FALSE)
 | 
			
		||||
else()
 | 
			
		||||
	set(USE_XINPUT2 FALSE)
 | 
			
		||||
	set(USE_XCURSOR FALSE)
 | 
			
		||||
endif()
 | 
			
		||||
add_compile_definitions("_IRR_COMPILE_WITH_SDL_DEVICE_")
 | 
			
		||||
 | 
			
		||||
# Joystick
 | 
			
		||||
 | 
			
		||||
@@ -122,14 +88,10 @@ if(NOT (BSD OR SOLARIS OR EMSCRIPTEN))
 | 
			
		||||
	add_compile_definitions(_IRR_COMPILE_WITH_JOYSTICK_EVENTS_)
 | 
			
		||||
endif()
 | 
			
		||||
 | 
			
		||||
# OpenGL
 | 
			
		||||
# OpenGL (ES)
 | 
			
		||||
 | 
			
		||||
if(USE_SDL2)
 | 
			
		||||
	if(NOT ANDROID)
 | 
			
		||||
		set(DEFAULT_OPENGL3 TRUE)
 | 
			
		||||
	endif()
 | 
			
		||||
else()
 | 
			
		||||
	set(DEFAULT_OPENGL3 FALSE)
 | 
			
		||||
if(NOT ANDROID)
 | 
			
		||||
	set(DEFAULT_OPENGL3 TRUE)
 | 
			
		||||
endif()
 | 
			
		||||
option(ENABLE_OPENGL3 "Enable OpenGL 3+" ${DEFAULT_OPENGL3})
 | 
			
		||||
 | 
			
		||||
@@ -157,35 +119,13 @@ else()
 | 
			
		||||
	endif()
 | 
			
		||||
endif()
 | 
			
		||||
 | 
			
		||||
if(ENABLE_OPENGL OR (ENABLE_OPENGL3 AND NOT USE_SDL2))
 | 
			
		||||
	if(ENABLE_OPENGL)
 | 
			
		||||
		add_compile_definitions(_IRR_COMPILE_WITH_OPENGL_)
 | 
			
		||||
		set(OPENGL_DIRECT_LINK TRUE) # driver relies on this
 | 
			
		||||
	endif()
 | 
			
		||||
	if(DEVICE STREQUAL "WINDOWS")
 | 
			
		||||
		add_compile_definitions(_IRR_COMPILE_WITH_WGL_MANAGER_)
 | 
			
		||||
	elseif(DEVICE STREQUAL "X11")
 | 
			
		||||
		add_compile_definitions(_IRR_COMPILE_WITH_GLX_MANAGER_)
 | 
			
		||||
	elseif(DEVICE STREQUAL "OSX")
 | 
			
		||||
		add_compile_definitions(_IRR_COMPILE_WITH_NSOGL_MANAGER_)
 | 
			
		||||
	endif()
 | 
			
		||||
endif()
 | 
			
		||||
 | 
			
		||||
if(ENABLE_OPENGL3)
 | 
			
		||||
	if(DEVICE STREQUAL "WINDOWS")
 | 
			
		||||
		# supported
 | 
			
		||||
	elseif(DEVICE STREQUAL "X11")
 | 
			
		||||
		# supported
 | 
			
		||||
	elseif (NOT USE_SDL2)
 | 
			
		||||
		message(FATAL_ERROR "OpenGL 3 driver requires SDL2")
 | 
			
		||||
	endif()
 | 
			
		||||
if(ENABLE_OPENGL)
 | 
			
		||||
	add_compile_definitions(_IRR_COMPILE_WITH_OPENGL_)
 | 
			
		||||
	set(OPENGL_DIRECT_LINK TRUE) # driver relies on this
 | 
			
		||||
endif()
 | 
			
		||||
 | 
			
		||||
if(ENABLE_GLES2)
 | 
			
		||||
	add_compile_definitions(_IRR_COMPILE_WITH_OGLES2_)
 | 
			
		||||
	if(DEVICE MATCHES "^(WINDOWS|X11)$" OR EMSCRIPTEN)
 | 
			
		||||
		add_compile_definitions(_IRR_COMPILE_WITH_EGL_MANAGER_)
 | 
			
		||||
	endif()
 | 
			
		||||
endif()
 | 
			
		||||
 | 
			
		||||
if(ENABLE_WEBGL1)
 | 
			
		||||
@@ -202,7 +142,6 @@ endif()
 | 
			
		||||
 | 
			
		||||
# Configuration report
 | 
			
		||||
 | 
			
		||||
message(STATUS "Device: ${DEVICE}")
 | 
			
		||||
message(STATUS "OpenGL: ${ENABLE_OPENGL}")
 | 
			
		||||
message(STATUS "OpenGL 3: ${ENABLE_OPENGL3}")
 | 
			
		||||
if (ENABLE_GLES2)
 | 
			
		||||
@@ -227,7 +166,7 @@ if(ENABLE_OPENGL)
 | 
			
		||||
	find_package(OpenGL REQUIRED)
 | 
			
		||||
endif()
 | 
			
		||||
set(USE_SDL2_SHARED FALSE)
 | 
			
		||||
if(USE_SDL2)
 | 
			
		||||
if(TRUE)
 | 
			
		||||
	if(NOT USE_SDL2_STATIC)
 | 
			
		||||
		set(USE_SDL2_SHARED TRUE)
 | 
			
		||||
	endif()
 | 
			
		||||
@@ -260,7 +199,7 @@ endif()
 | 
			
		||||
 | 
			
		||||
# More special config
 | 
			
		||||
 | 
			
		||||
if(ENABLE_OPENGL AND DEVICE STREQUAL "SDL")
 | 
			
		||||
if(ENABLE_OPENGL)
 | 
			
		||||
	# The legacy GL driver requires some symbols from GL 4.5 to compile,
 | 
			
		||||
	# which SDL only provides since 2.26.0 (Nov 2022).
 | 
			
		||||
	# We have a fallback in case this isn't satisfied so test for it.
 | 
			
		||||
@@ -278,19 +217,8 @@ endif()
 | 
			
		||||
 | 
			
		||||
# Platform-specific libs
 | 
			
		||||
 | 
			
		||||
if(ANDROID)
 | 
			
		||||
	enable_language(C)
 | 
			
		||||
elseif(APPLE)
 | 
			
		||||
	find_library(COCOA_LIB Cocoa REQUIRED)
 | 
			
		||||
	find_library(IOKIT_LIB IOKit REQUIRED)
 | 
			
		||||
 | 
			
		||||
if(APPLE)
 | 
			
		||||
	add_compile_definitions(GL_SILENCE_DEPRECATION)
 | 
			
		||||
elseif(NOT USE_SDL2)
 | 
			
		||||
	# Unix probably
 | 
			
		||||
	find_package(X11 REQUIRED)
 | 
			
		||||
	if(USE_XINPUT2 AND NOT X11_Xi_FOUND)
 | 
			
		||||
		message(FATAL_ERROR "XInput not found")
 | 
			
		||||
	endif()
 | 
			
		||||
endif()
 | 
			
		||||
 | 
			
		||||
set(link_includes
 | 
			
		||||
@@ -300,13 +228,11 @@ set(link_includes
 | 
			
		||||
	"${ZLIB_INCLUDE_DIR}"
 | 
			
		||||
	"${JPEG_INCLUDE_DIR}"
 | 
			
		||||
	"${PNG_INCLUDE_DIR}"
 | 
			
		||||
	"$<$<BOOL:${USE_SDL2}>:${SDL2_INCLUDE_DIRS}>"
 | 
			
		||||
	"${SDL2_INCLUDE_DIRS}"
 | 
			
		||||
 | 
			
		||||
	${OPENGL_INCLUDE_DIR}
 | 
			
		||||
	${OPENGLES2_INCLUDE_DIR}
 | 
			
		||||
	${EGL_INCLUDE_DIR}
 | 
			
		||||
 | 
			
		||||
	"$<$<BOOL:${USE_X11}>:${X11_INCLUDE_DIR}>"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
# Source files
 | 
			
		||||
@@ -338,14 +264,10 @@ target_link_libraries(IRRMESHOBJ PUBLIC tiniergltf::tiniergltf)
 | 
			
		||||
 | 
			
		||||
set(IRRDRVROBJ
 | 
			
		||||
	CNullDriver.h
 | 
			
		||||
	CGLXManager.h
 | 
			
		||||
	CWGLManager.h
 | 
			
		||||
	CEGLManager.h
 | 
			
		||||
	CSDLManager.h
 | 
			
		||||
 | 
			
		||||
	CNullDriver.cpp
 | 
			
		||||
	CGLXManager.cpp
 | 
			
		||||
	CWGLManager.cpp
 | 
			
		||||
	CEGLManager.cpp
 | 
			
		||||
	CSDLManager.cpp
 | 
			
		||||
	mt_opengl_loader.cpp
 | 
			
		||||
@@ -446,17 +368,13 @@ add_library(IRRIOOBJ OBJECT
 | 
			
		||||
 | 
			
		||||
add_library(IRROTHEROBJ OBJECT
 | 
			
		||||
	CIrrDeviceSDL.h
 | 
			
		||||
	CIrrDeviceLinux.h
 | 
			
		||||
	CIrrDeviceStub.h
 | 
			
		||||
	CIrrDeviceWin32.h
 | 
			
		||||
	CLogger.h
 | 
			
		||||
	COSOperator.h
 | 
			
		||||
	os.h
 | 
			
		||||
 | 
			
		||||
	CIrrDeviceSDL.cpp
 | 
			
		||||
	CIrrDeviceLinux.cpp
 | 
			
		||||
	CIrrDeviceStub.cpp
 | 
			
		||||
	CIrrDeviceWin32.cpp
 | 
			
		||||
	CLogger.cpp
 | 
			
		||||
	COSOperator.cpp
 | 
			
		||||
	Irrlicht.cpp
 | 
			
		||||
@@ -470,22 +388,6 @@ endif()
 | 
			
		||||
if(APPLE)
 | 
			
		||||
	# Build all IRROTHEROBJ sources as objc++, including the .cpp's
 | 
			
		||||
	set_target_properties(IRROTHEROBJ PROPERTIES COMPILE_OPTIONS "-xobjective-c++")
 | 
			
		||||
	target_sources(IRROTHEROBJ PRIVATE
 | 
			
		||||
		CIrrDeviceOSX.mm
 | 
			
		||||
		CNSOGLManager.mm
 | 
			
		||||
	)
 | 
			
		||||
endif()
 | 
			
		||||
 | 
			
		||||
if(USE_X11)
 | 
			
		||||
	target_compile_definitions(IRROTHEROBJ PRIVATE _IRR_COMPILE_WITH_X11_)
 | 
			
		||||
endif()
 | 
			
		||||
 | 
			
		||||
if(USE_XINPUT2)
 | 
			
		||||
	target_compile_definitions(IRROTHEROBJ PRIVATE _IRR_LINUX_X11_XINPUT2_)
 | 
			
		||||
endif()
 | 
			
		||||
 | 
			
		||||
if(USE_XCURSOR)
 | 
			
		||||
	target_compile_definitions(IRROTHEROBJ PRIVATE _IRR_LINUX_XCURSOR_)
 | 
			
		||||
endif()
 | 
			
		||||
 | 
			
		||||
add_library(IRRGUIOBJ OBJECT
 | 
			
		||||
@@ -591,12 +493,6 @@ target_link_libraries(IrrlichtMt PRIVATE
 | 
			
		||||
 | 
			
		||||
	# incl. transitive SDL2 dependencies for static linking
 | 
			
		||||
	"$<$<PLATFORM_ID:Android>:-landroid -llog -lGLESv2 -lGLESv1_CM -lOpenSLES>"
 | 
			
		||||
	${COCOA_LIB}
 | 
			
		||||
	${IOKIT_LIB}
 | 
			
		||||
	"$<$<PLATFORM_ID:Windows>:gdi32>"
 | 
			
		||||
	"$<$<PLATFORM_ID:Windows>:winmm>"
 | 
			
		||||
	"$<$<BOOL:${USE_X11}>:${X11_X11_LIB}>"
 | 
			
		||||
	"$<$<BOOL:${USE_X11}>:${X11_Xi_LIB}>"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
if(WIN32)
 | 
			
		||||
 
 | 
			
		||||
@@ -1,67 +0,0 @@
 | 
			
		||||
// Copyright (C) 2014 Patryk Nadrowski
 | 
			
		||||
// This file is part of the "Irrlicht Engine".
 | 
			
		||||
// For conditions of distribution and use, see copyright notice in Irrlicht.h
 | 
			
		||||
 | 
			
		||||
#pragma once
 | 
			
		||||
 | 
			
		||||
#ifdef _IRR_COMPILE_WITH_NSOGL_MANAGER_
 | 
			
		||||
 | 
			
		||||
#include "SIrrCreationParameters.h"
 | 
			
		||||
#include "SExposedVideoData.h"
 | 
			
		||||
#include "IContextManager.h"
 | 
			
		||||
#include "SColor.h"
 | 
			
		||||
 | 
			
		||||
#import <AppKit/NSOpenGL.h>
 | 
			
		||||
 | 
			
		||||
namespace video
 | 
			
		||||
{
 | 
			
		||||
// NSOpenGL manager.
 | 
			
		||||
class CNSOGLManager : public IContextManager
 | 
			
		||||
{
 | 
			
		||||
public:
 | 
			
		||||
	//! Constructor.
 | 
			
		||||
	CNSOGLManager();
 | 
			
		||||
 | 
			
		||||
	//! Destructor
 | 
			
		||||
	~CNSOGLManager();
 | 
			
		||||
 | 
			
		||||
	// Initialize
 | 
			
		||||
	bool initialize(const SIrrlichtCreationParameters ¶ms, const SExposedVideoData &data) override;
 | 
			
		||||
 | 
			
		||||
	// Terminate
 | 
			
		||||
	void terminate() override;
 | 
			
		||||
 | 
			
		||||
	// Create surface.
 | 
			
		||||
	bool generateSurface() override;
 | 
			
		||||
 | 
			
		||||
	// Destroy surface.
 | 
			
		||||
	void destroySurface() override;
 | 
			
		||||
 | 
			
		||||
	// Create context.
 | 
			
		||||
	bool generateContext() override;
 | 
			
		||||
 | 
			
		||||
	// Destroy EGL context.
 | 
			
		||||
	void destroyContext() override;
 | 
			
		||||
 | 
			
		||||
	//! Get current context
 | 
			
		||||
	const SExposedVideoData &getContext() const;
 | 
			
		||||
 | 
			
		||||
	//! Change render context, disable old and activate new defined by videoData
 | 
			
		||||
	bool activateContext(const SExposedVideoData &videoData, bool restorePrimaryOnZero) override;
 | 
			
		||||
 | 
			
		||||
	// Get procedure address.
 | 
			
		||||
	void *getProcAddress(const std::string &procName) override;
 | 
			
		||||
 | 
			
		||||
	// Swap buffers.
 | 
			
		||||
	bool swapBuffers() override;
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
	SIrrlichtCreationParameters Params;
 | 
			
		||||
	SExposedVideoData PrimaryContext;
 | 
			
		||||
	SExposedVideoData CurrentContext;
 | 
			
		||||
 | 
			
		||||
	NSOpenGLPixelFormat *PixelFormat;
 | 
			
		||||
};
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
@@ -1,227 +0,0 @@
 | 
			
		||||
// Copyright (C) 2014 Patryk Nadrowski
 | 
			
		||||
// This file is part of the "Irrlicht Engine".
 | 
			
		||||
// For conditions of distribution and use, see copyright notice in Irrlicht.h
 | 
			
		||||
 | 
			
		||||
#include "CNSOGLManager.h"
 | 
			
		||||
 | 
			
		||||
#ifdef _IRR_COMPILE_WITH_NSOGL_MANAGER_
 | 
			
		||||
 | 
			
		||||
#include <mach-o/dyld.h>
 | 
			
		||||
#include "os.h"
 | 
			
		||||
 | 
			
		||||
namespace video
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
CNSOGLManager::CNSOGLManager() :
 | 
			
		||||
		PrimaryContext(SExposedVideoData(0)), PixelFormat(nil)
 | 
			
		||||
{}
 | 
			
		||||
 | 
			
		||||
CNSOGLManager::~CNSOGLManager()
 | 
			
		||||
{
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool CNSOGLManager::initialize(const SIrrlichtCreationParameters ¶ms, const SExposedVideoData &videodata)
 | 
			
		||||
{
 | 
			
		||||
	Params = params;
 | 
			
		||||
 | 
			
		||||
	return true;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void CNSOGLManager::terminate()
 | 
			
		||||
{
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool CNSOGLManager::generateSurface()
 | 
			
		||||
{
 | 
			
		||||
	if (Params.DriverType == video::EDT_OPENGL) {
 | 
			
		||||
		int alphaSize = Params.WithAlphaChannel ? 4 : 0;
 | 
			
		||||
		int depthSize = Params.ZBufferBits;
 | 
			
		||||
 | 
			
		||||
		if (Params.WithAlphaChannel && Params.Bits == 32)
 | 
			
		||||
			alphaSize = 8;
 | 
			
		||||
 | 
			
		||||
		NSOpenGLPixelFormatAttribute Attribs[] = {
 | 
			
		||||
				NSOpenGLPFANoRecovery,
 | 
			
		||||
				NSOpenGLPFAAccelerated,
 | 
			
		||||
				NSOpenGLPFADoubleBuffer,
 | 
			
		||||
				NSOpenGLPFADepthSize, static_cast<NSOpenGLPixelFormatAttribute>(depthSize),
 | 
			
		||||
				NSOpenGLPFAColorSize, Params.Bits,
 | 
			
		||||
				NSOpenGLPFAAlphaSize, static_cast<NSOpenGLPixelFormatAttribute>(alphaSize),
 | 
			
		||||
				NSOpenGLPFASampleBuffers, 1,
 | 
			
		||||
				NSOpenGLPFASamples, Params.AntiAlias,
 | 
			
		||||
				NSOpenGLPFAStencilSize, static_cast<NSOpenGLPixelFormatAttribute>(Params.Stencilbuffer ? 1 : 0),
 | 
			
		||||
				// NSOpenGLPFAFullScreen,
 | 
			
		||||
				0,
 | 
			
		||||
			};
 | 
			
		||||
 | 
			
		||||
		u32 Steps = 6;
 | 
			
		||||
 | 
			
		||||
		// Choose the best pixel format.
 | 
			
		||||
		do {
 | 
			
		||||
			switch (Steps) {
 | 
			
		||||
			case 6: // decrease step.
 | 
			
		||||
				--Steps;
 | 
			
		||||
				break;
 | 
			
		||||
			case 5: // samples
 | 
			
		||||
				if (Attribs[12] > 2)
 | 
			
		||||
					--Attribs[12];
 | 
			
		||||
				else {
 | 
			
		||||
					Attribs[10] = 0;
 | 
			
		||||
					Attribs[12] = 0;
 | 
			
		||||
					--Steps;
 | 
			
		||||
				}
 | 
			
		||||
				break;
 | 
			
		||||
			case 4: // alpha
 | 
			
		||||
				if (Attribs[8]) {
 | 
			
		||||
					Attribs[8] = 0;
 | 
			
		||||
 | 
			
		||||
					if (Params.AntiAlias) {
 | 
			
		||||
						Attribs[10] = 1;
 | 
			
		||||
						Attribs[12] = Params.AntiAlias;
 | 
			
		||||
						Steps = 5;
 | 
			
		||||
					}
 | 
			
		||||
				} else
 | 
			
		||||
					--Steps;
 | 
			
		||||
				break;
 | 
			
		||||
			case 3: // stencil
 | 
			
		||||
				if (Attribs[14]) {
 | 
			
		||||
					Attribs[14] = 0;
 | 
			
		||||
 | 
			
		||||
					if (Params.AntiAlias) {
 | 
			
		||||
						Attribs[10] = 1;
 | 
			
		||||
						Attribs[12] = Params.AntiAlias;
 | 
			
		||||
						Steps = 5;
 | 
			
		||||
					}
 | 
			
		||||
				} else
 | 
			
		||||
					--Steps;
 | 
			
		||||
				break;
 | 
			
		||||
			case 2: // depth size
 | 
			
		||||
				if (Attribs[4] > 16) {
 | 
			
		||||
					Attribs[4] = Attribs[4] - 8;
 | 
			
		||||
				} else
 | 
			
		||||
					--Steps;
 | 
			
		||||
				break;
 | 
			
		||||
			case 1: // buffer size
 | 
			
		||||
				if (Attribs[6] > 16) {
 | 
			
		||||
					Attribs[6] = Attribs[6] - 8;
 | 
			
		||||
				} else
 | 
			
		||||
					--Steps;
 | 
			
		||||
				break;
 | 
			
		||||
			default:
 | 
			
		||||
				os::Printer::log("Could not get pixel format.");
 | 
			
		||||
				return false;
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			PixelFormat = [[NSOpenGLPixelFormat alloc] initWithAttributes:Attribs];
 | 
			
		||||
		} while (PixelFormat == nil);
 | 
			
		||||
 | 
			
		||||
		if (Params.AntiAlias && !Attribs[10])
 | 
			
		||||
			os::Printer::log("No multisampling.");
 | 
			
		||||
 | 
			
		||||
		if (Params.WithAlphaChannel && !Attribs[8])
 | 
			
		||||
			os::Printer::log("No alpha.");
 | 
			
		||||
 | 
			
		||||
		if (Params.Stencilbuffer && !Attribs[14])
 | 
			
		||||
			os::Printer::log("No stencil buffer.");
 | 
			
		||||
 | 
			
		||||
		if (Params.ZBufferBits > Attribs[4])
 | 
			
		||||
			os::Printer::log("No full depth buffer.");
 | 
			
		||||
 | 
			
		||||
		if (Params.Bits > Attribs[6])
 | 
			
		||||
			os::Printer::log("No full color buffer.");
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return true;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void CNSOGLManager::destroySurface()
 | 
			
		||||
{
 | 
			
		||||
	[PixelFormat release];
 | 
			
		||||
	PixelFormat = nil;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool CNSOGLManager::generateContext()
 | 
			
		||||
{
 | 
			
		||||
	NSOpenGLContext *Context = [[NSOpenGLContext alloc] initWithFormat:PixelFormat shareContext:nil];
 | 
			
		||||
 | 
			
		||||
	GLint Vsync = Params.Vsync ? 1 : 0;
 | 
			
		||||
	[Context setValues:&Vsync forParameter:NSOpenGLCPSwapInterval];
 | 
			
		||||
 | 
			
		||||
	if (Context == nil) {
 | 
			
		||||
		os::Printer::log("Could not create OpenGL context.", ELL_ERROR);
 | 
			
		||||
		return false;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// set exposed data
 | 
			
		||||
	CurrentContext.OpenGLOSX.Context = Context;
 | 
			
		||||
 | 
			
		||||
	if (!PrimaryContext.OpenGLOSX.Context)
 | 
			
		||||
		PrimaryContext.OpenGLOSX.Context = CurrentContext.OpenGLOSX.Context;
 | 
			
		||||
 | 
			
		||||
	return true;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const SExposedVideoData &CNSOGLManager::getContext() const
 | 
			
		||||
{
 | 
			
		||||
	return CurrentContext;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool CNSOGLManager::activateContext(const SExposedVideoData &videoData, bool restorePrimaryOnZero)
 | 
			
		||||
{
 | 
			
		||||
	// TODO: handle restorePrimaryOnZero
 | 
			
		||||
	if (videoData.OpenGLOSX.Context) {
 | 
			
		||||
		if ((NSOpenGLContext *)videoData.OpenGLOSX.Context != [NSOpenGLContext currentContext]) {
 | 
			
		||||
			[(NSOpenGLContext *)videoData.OpenGLOSX.Context makeCurrentContext];
 | 
			
		||||
 | 
			
		||||
			CurrentContext = videoData;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	// set back to main context
 | 
			
		||||
	else {
 | 
			
		||||
		if ((NSOpenGLContext *)PrimaryContext.OpenGLOSX.Context != [NSOpenGLContext currentContext]) {
 | 
			
		||||
			[(NSOpenGLContext *)PrimaryContext.OpenGLOSX.Context makeCurrentContext];
 | 
			
		||||
 | 
			
		||||
			CurrentContext = PrimaryContext;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return true;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void CNSOGLManager::destroyContext()
 | 
			
		||||
{
 | 
			
		||||
	if (CurrentContext.OpenGLOSX.Context) {
 | 
			
		||||
		if (PrimaryContext.OpenGLOSX.Context == CurrentContext.OpenGLOSX.Context)
 | 
			
		||||
			PrimaryContext.OpenGLOSX.Context = nil;
 | 
			
		||||
 | 
			
		||||
		[(NSOpenGLContext *)CurrentContext.OpenGLOSX.Context makeCurrentContext];
 | 
			
		||||
		[(NSOpenGLContext *)CurrentContext.OpenGLOSX.Context clearDrawable];
 | 
			
		||||
		[(NSOpenGLContext *)CurrentContext.OpenGLOSX.Context release];
 | 
			
		||||
		[NSOpenGLContext clearCurrentContext];
 | 
			
		||||
 | 
			
		||||
		CurrentContext.OpenGLOSX.Context = nil;
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// It appears that there is no separate GL proc address getter on OSX.
 | 
			
		||||
// https://developer.apple.com/library/archive/documentation/GraphicsImaging/Conceptual/OpenGL-MacProgGuide/opengl_entrypts/opengl_entrypts.html
 | 
			
		||||
void *CNSOGLManager::getProcAddress(const std::string &procName)
 | 
			
		||||
{
 | 
			
		||||
	NSSymbol symbol = NULL;
 | 
			
		||||
	// Allocate a buffer for the name, an underscore prefix, and a cstring terminator.
 | 
			
		||||
	std::string mangledName = "_" + procName;
 | 
			
		||||
	if (NSIsSymbolNameDefined(mangledName.c_str()))
 | 
			
		||||
		symbol = NSLookupAndBindSymbol(mangledName.c_str());
 | 
			
		||||
	return symbol ? NSAddressOfSymbol(symbol) : NULL;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool CNSOGLManager::swapBuffers()
 | 
			
		||||
{
 | 
			
		||||
	[(NSOpenGLContext *)CurrentContext.OpenGLOSX.Context flushBuffer];
 | 
			
		||||
 | 
			
		||||
	return true;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
@@ -20,23 +20,10 @@
 | 
			
		||||
#if defined(_IRR_COMPILE_WITH_SDL_DEVICE_)
 | 
			
		||||
#include <SDL_clipboard.h>
 | 
			
		||||
#include <SDL_version.h>
 | 
			
		||||
#elif defined(_IRR_COMPILE_WITH_X11_DEVICE_)
 | 
			
		||||
#include "CIrrDeviceLinux.h"
 | 
			
		||||
#endif
 | 
			
		||||
#if defined(_IRR_COMPILE_WITH_OSX_DEVICE_)
 | 
			
		||||
#import <Cocoa/Cocoa.h>
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#include "fast_atof.h"
 | 
			
		||||
 | 
			
		||||
#if defined(_IRR_COMPILE_WITH_X11_DEVICE_)
 | 
			
		||||
// constructor  linux
 | 
			
		||||
COSOperator::COSOperator(const core::stringc &osVersion, CIrrDeviceLinux *device) :
 | 
			
		||||
		OperatingSystem(osVersion), IrrDeviceLinux(device)
 | 
			
		||||
{
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
// constructor
 | 
			
		||||
COSOperator::COSOperator(const core::stringc &osVersion) :
 | 
			
		||||
		OperatingSystem(osVersion)
 | 
			
		||||
@@ -64,43 +51,6 @@ void COSOperator::copyToClipboard(const c8 *text) const
 | 
			
		||||
 | 
			
		||||
#if defined(_IRR_COMPILE_WITH_SDL_DEVICE_)
 | 
			
		||||
	SDL_SetClipboardText(text);
 | 
			
		||||
 | 
			
		||||
#elif defined(_IRR_WINDOWS_API_)
 | 
			
		||||
	if (!OpenClipboard(NULL) || text == 0)
 | 
			
		||||
		return;
 | 
			
		||||
 | 
			
		||||
	EmptyClipboard();
 | 
			
		||||
 | 
			
		||||
	core::stringw tempbuffer;
 | 
			
		||||
	core::utf8ToWString(tempbuffer, text);
 | 
			
		||||
	const u32 size = (tempbuffer.size() + 1) * sizeof(wchar_t);
 | 
			
		||||
 | 
			
		||||
	HGLOBAL clipbuffer;
 | 
			
		||||
	void *buffer;
 | 
			
		||||
 | 
			
		||||
	clipbuffer = GlobalAlloc(GMEM_MOVEABLE, size);
 | 
			
		||||
	buffer = GlobalLock(clipbuffer);
 | 
			
		||||
 | 
			
		||||
	memcpy(buffer, tempbuffer.c_str(), size);
 | 
			
		||||
 | 
			
		||||
	GlobalUnlock(clipbuffer);
 | 
			
		||||
	SetClipboardData(CF_UNICODETEXT, clipbuffer);
 | 
			
		||||
	CloseClipboard();
 | 
			
		||||
 | 
			
		||||
#elif defined(_IRR_COMPILE_WITH_OSX_DEVICE_)
 | 
			
		||||
	NSString *str = nil;
 | 
			
		||||
	NSPasteboard *board = nil;
 | 
			
		||||
 | 
			
		||||
	if ((text != NULL) && (strlen(text) > 0)) {
 | 
			
		||||
		str = [NSString stringWithCString:text encoding:NSUTF8StringEncoding];
 | 
			
		||||
		board = [NSPasteboard generalPasteboard];
 | 
			
		||||
		[board declareTypes:[NSArray arrayWithObject:NSPasteboardTypeString] owner:NSApp];
 | 
			
		||||
		[board setString:str forType:NSPasteboardTypeString];
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
#elif defined(_IRR_COMPILE_WITH_X11_DEVICE_)
 | 
			
		||||
	if (IrrDeviceLinux)
 | 
			
		||||
		IrrDeviceLinux->copyToClipboard(text);
 | 
			
		||||
#endif
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -114,10 +64,6 @@ void COSOperator::copyToPrimarySelection(const c8 *text) const
 | 
			
		||||
#if SDL_VERSION_ATLEAST(2, 25, 0)
 | 
			
		||||
	SDL_SetPrimarySelectionText(text);
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#elif defined(_IRR_COMPILE_WITH_X11_DEVICE_)
 | 
			
		||||
	if (IrrDeviceLinux)
 | 
			
		||||
		IrrDeviceLinux->copyToPrimarySelection(text);
 | 
			
		||||
#endif
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -128,42 +74,6 @@ const c8 *COSOperator::getTextFromClipboard() const
 | 
			
		||||
	SDL_free(ClipboardSelectionText);
 | 
			
		||||
	ClipboardSelectionText = SDL_GetClipboardText();
 | 
			
		||||
	return ClipboardSelectionText;
 | 
			
		||||
 | 
			
		||||
#elif defined(_IRR_WINDOWS_API_)
 | 
			
		||||
	if (!OpenClipboard(NULL))
 | 
			
		||||
		return 0;
 | 
			
		||||
 | 
			
		||||
	HANDLE hData = GetClipboardData(CF_UNICODETEXT);
 | 
			
		||||
	if (hData == NULL) // Probably not in Unicode text format
 | 
			
		||||
		return 0;
 | 
			
		||||
 | 
			
		||||
	wchar_t *buffer = (wchar_t *)GlobalLock(hData);
 | 
			
		||||
 | 
			
		||||
	core::wStringToUTF8(ClipboardBuf, buffer);
 | 
			
		||||
 | 
			
		||||
	GlobalUnlock(hData);
 | 
			
		||||
	CloseClipboard();
 | 
			
		||||
 | 
			
		||||
	return ClipboardBuf.c_str();
 | 
			
		||||
 | 
			
		||||
#elif defined(_IRR_COMPILE_WITH_OSX_DEVICE_)
 | 
			
		||||
	NSString *str = nil;
 | 
			
		||||
	NSPasteboard *board = nil;
 | 
			
		||||
	char *result = 0;
 | 
			
		||||
 | 
			
		||||
	board = [NSPasteboard generalPasteboard];
 | 
			
		||||
	str = [board stringForType:NSPasteboardTypeString];
 | 
			
		||||
 | 
			
		||||
	if (str != nil)
 | 
			
		||||
		result = (char *)[str cStringUsingEncoding:NSUTF8StringEncoding];
 | 
			
		||||
 | 
			
		||||
	return (result);
 | 
			
		||||
 | 
			
		||||
#elif defined(_IRR_COMPILE_WITH_X11_DEVICE_)
 | 
			
		||||
	if (IrrDeviceLinux)
 | 
			
		||||
		return IrrDeviceLinux->getTextFromClipboard();
 | 
			
		||||
	return 0;
 | 
			
		||||
 | 
			
		||||
#else
 | 
			
		||||
 | 
			
		||||
	return 0;
 | 
			
		||||
@@ -181,11 +91,6 @@ const c8 *COSOperator::getTextFromPrimarySelection() const
 | 
			
		||||
#endif
 | 
			
		||||
	return 0;
 | 
			
		||||
 | 
			
		||||
#elif defined(_IRR_COMPILE_WITH_X11_DEVICE_)
 | 
			
		||||
	if (IrrDeviceLinux)
 | 
			
		||||
		return IrrDeviceLinux->getTextFromPrimarySelection();
 | 
			
		||||
	return 0;
 | 
			
		||||
 | 
			
		||||
#else
 | 
			
		||||
 | 
			
		||||
	return 0;
 | 
			
		||||
@@ -238,7 +143,6 @@ bool COSOperator::getSystemMemory(u32 *Total, u32 *Avail) const
 | 
			
		||||
		*Avail = (u32)(physical_memory >> 10); // we don't know better
 | 
			
		||||
	return true;
 | 
			
		||||
#else
 | 
			
		||||
	// TODO: implement for others
 | 
			
		||||
	return false;
 | 
			
		||||
#endif
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -6,16 +6,11 @@
 | 
			
		||||
 | 
			
		||||
#include "IOSOperator.h"
 | 
			
		||||
 | 
			
		||||
class CIrrDeviceLinux;
 | 
			
		||||
 | 
			
		||||
//! The OSOperator provides OS-specific methods and information.
 | 
			
		||||
class COSOperator : public IOSOperator
 | 
			
		||||
{
 | 
			
		||||
public:
 | 
			
		||||
	// constructor
 | 
			
		||||
#if defined(_IRR_COMPILE_WITH_X11_DEVICE_)
 | 
			
		||||
	COSOperator(const core::stringc &osversion, CIrrDeviceLinux *device);
 | 
			
		||||
#endif
 | 
			
		||||
	COSOperator(const core::stringc &osversion);
 | 
			
		||||
 | 
			
		||||
	~COSOperator();
 | 
			
		||||
@@ -53,10 +48,6 @@ public:
 | 
			
		||||
private:
 | 
			
		||||
	core::stringc OperatingSystem;
 | 
			
		||||
 | 
			
		||||
#if defined(_IRR_COMPILE_WITH_X11_DEVICE_)
 | 
			
		||||
	CIrrDeviceLinux *IrrDeviceLinux;
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef _IRR_WINDOWS_API_
 | 
			
		||||
	mutable core::stringc ClipboardBuf;
 | 
			
		||||
#endif
 | 
			
		||||
 
 | 
			
		||||
@@ -44,10 +44,6 @@ bool COpenGLDriver::initDriver()
 | 
			
		||||
 | 
			
		||||
	genericDriverInit();
 | 
			
		||||
 | 
			
		||||
#if defined(_IRR_COMPILE_WITH_WINDOWS_DEVICE_) || defined(_IRR_COMPILE_WITH_X11_DEVICE_)
 | 
			
		||||
	extGlSwapInterval(Params.Vsync ? 1 : 0);
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
	return true;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -89,22 +89,6 @@ COpenGLExtensionHandler::COpenGLExtensionHandler() :
 | 
			
		||||
		// DSA with EXT or functions to simulate it
 | 
			
		||||
		pGlTextureStorage2DEXT(0), pGlTexStorage2D(0), pGlTextureStorage3DEXT(0), pGlTexStorage3D(0), pGlTextureSubImage2DEXT(0), pGlGetTextureImageEXT(0),
 | 
			
		||||
		pGlNamedFramebufferTextureEXT(0), pGlFramebufferTexture(0), pGlGenerateTextureMipmapEXT(0)
 | 
			
		||||
#if defined(GLX_SGI_swap_control)
 | 
			
		||||
		,
 | 
			
		||||
		pGlxSwapIntervalSGI(0)
 | 
			
		||||
#endif
 | 
			
		||||
#if defined(GLX_EXT_swap_control)
 | 
			
		||||
		,
 | 
			
		||||
		pGlxSwapIntervalEXT(0)
 | 
			
		||||
#endif
 | 
			
		||||
#if defined(WGL_EXT_swap_control)
 | 
			
		||||
		,
 | 
			
		||||
		pWglSwapIntervalEXT(0)
 | 
			
		||||
#endif
 | 
			
		||||
#if defined(GLX_MESA_swap_control)
 | 
			
		||||
		,
 | 
			
		||||
		pGlxSwapIntervalMESA(0)
 | 
			
		||||
#endif
 | 
			
		||||
{
 | 
			
		||||
	for (u32 i = 0; i < IRR_OpenGL_Feature_Count; ++i)
 | 
			
		||||
		FeatureAvailable[i] = false;
 | 
			
		||||
@@ -360,20 +344,6 @@ void COpenGLExtensionHandler::initExtensions(video::IContextManager *cmgr, bool
 | 
			
		||||
	pGlActiveTexture = (PFNGLACTIVETEXTUREPROC)IRR_OGL_LOAD_EXTENSION("glActiveTexture");
 | 
			
		||||
	pGlGenerateTextureMipmapEXT = (PFNGLGENERATETEXTUREMIPMAPEXTPROC)IRR_OGL_LOAD_EXTENSION("glGenerateTextureMipmapEXT");
 | 
			
		||||
 | 
			
		||||
// get vsync extension
 | 
			
		||||
#if defined(WGL_EXT_swap_control) && !defined(_IRR_COMPILE_WITH_SDL_DEVICE_)
 | 
			
		||||
	pWglSwapIntervalEXT = (PFNWGLSWAPINTERVALEXTPROC)IRR_OGL_LOAD_EXTENSION("wglSwapIntervalEXT");
 | 
			
		||||
#endif
 | 
			
		||||
#if defined(GLX_SGI_swap_control) && !defined(_IRR_COMPILE_WITH_SDL_DEVICE_)
 | 
			
		||||
	pGlxSwapIntervalSGI = (PFNGLXSWAPINTERVALSGIPROC)IRR_OGL_LOAD_EXTENSION("glXSwapIntervalSGI");
 | 
			
		||||
#endif
 | 
			
		||||
#if defined(GLX_EXT_swap_control) && !defined(_IRR_COMPILE_WITH_SDL_DEVICE_)
 | 
			
		||||
	pGlxSwapIntervalEXT = (PFNGLXSWAPINTERVALEXTPROC)IRR_OGL_LOAD_EXTENSION("glXSwapIntervalEXT");
 | 
			
		||||
#endif
 | 
			
		||||
#if defined(GLX_MESA_swap_control) && !defined(_IRR_COMPILE_WITH_SDL_DEVICE_)
 | 
			
		||||
	pGlxSwapIntervalMESA = (PFNGLXSWAPINTERVALMESAPROC)IRR_OGL_LOAD_EXTENSION("glXSwapIntervalMESA");
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
	GLint num = 0;
 | 
			
		||||
	// set some properties
 | 
			
		||||
#if defined(GL_ARB_multitexture) || defined(GL_VERSION_1_3)
 | 
			
		||||
 
 | 
			
		||||
@@ -1207,9 +1207,6 @@ public:
 | 
			
		||||
	void extGlBindTextures(GLuint first, GLsizei count, const GLuint *textures, const GLenum *targets);
 | 
			
		||||
	void extGlGenerateTextureMipmap(GLuint texture, GLenum target);
 | 
			
		||||
 | 
			
		||||
	// generic vsync setting method for several extensions
 | 
			
		||||
	void extGlSwapInterval(int interval);
 | 
			
		||||
 | 
			
		||||
	// the global feature array
 | 
			
		||||
	bool FeatureAvailable[IRR_OpenGL_Feature_Count];
 | 
			
		||||
 | 
			
		||||
@@ -1388,19 +1385,6 @@ protected:
 | 
			
		||||
	PFNGLNAMEDFRAMEBUFFERTEXTUREEXTPROC pGlNamedFramebufferTextureEXT;
 | 
			
		||||
	PFNGLFRAMEBUFFERTEXTUREPROC pGlFramebufferTexture;
 | 
			
		||||
	PFNGLGENERATETEXTUREMIPMAPEXTPROC pGlGenerateTextureMipmapEXT;
 | 
			
		||||
 | 
			
		||||
#if defined(WGL_EXT_swap_control)
 | 
			
		||||
	PFNWGLSWAPINTERVALEXTPROC pWglSwapIntervalEXT;
 | 
			
		||||
#endif
 | 
			
		||||
#if defined(GLX_SGI_swap_control)
 | 
			
		||||
	PFNGLXSWAPINTERVALSGIPROC pGlxSwapIntervalSGI;
 | 
			
		||||
#endif
 | 
			
		||||
#if defined(GLX_EXT_swap_control)
 | 
			
		||||
	PFNGLXSWAPINTERVALEXTPROC pGlxSwapIntervalEXT;
 | 
			
		||||
#endif
 | 
			
		||||
#if defined(GLX_MESA_swap_control)
 | 
			
		||||
	PFNGLXSWAPINTERVALMESAPROC pGlxSwapIntervalMESA;
 | 
			
		||||
#endif
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
inline void COpenGLExtensionHandler::irrGlActiveTexture(GLenum texture)
 | 
			
		||||
@@ -2581,32 +2565,6 @@ inline void COpenGLExtensionHandler::extGlGenerateTextureMipmap(GLuint texture,
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
inline void COpenGLExtensionHandler::extGlSwapInterval(int interval)
 | 
			
		||||
{
 | 
			
		||||
	// we have wglext, so try to use that
 | 
			
		||||
#if defined(_IRR_WINDOWS_API_) && defined(_IRR_COMPILE_WITH_WINDOWS_DEVICE_)
 | 
			
		||||
#ifdef WGL_EXT_swap_control
 | 
			
		||||
	if (pWglSwapIntervalEXT)
 | 
			
		||||
		pWglSwapIntervalEXT(interval);
 | 
			
		||||
#endif
 | 
			
		||||
#endif
 | 
			
		||||
#ifdef _IRR_COMPILE_WITH_X11_DEVICE_
 | 
			
		||||
#if defined(GLX_MESA_swap_control)
 | 
			
		||||
	if (pGlxSwapIntervalMESA)
 | 
			
		||||
		pGlxSwapIntervalMESA(interval);
 | 
			
		||||
#elif defined(GLX_EXT_swap_control)
 | 
			
		||||
	Display *dpy = glXGetCurrentDisplay();
 | 
			
		||||
	GLXDrawable drawable = glXGetCurrentDrawable();
 | 
			
		||||
	if (pGlxSwapIntervalEXT)
 | 
			
		||||
		pGlxSwapIntervalEXT(dpy, drawable, interval);
 | 
			
		||||
#elif defined(GLX_SGI_swap_control)
 | 
			
		||||
	// does not work with interval==0
 | 
			
		||||
	if (interval && pGlxSwapIntervalSGI)
 | 
			
		||||
		pGlxSwapIntervalSGI(interval);
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
#endif
 | 
			
		||||
}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 
 | 
			
		||||
@@ -1,436 +0,0 @@
 | 
			
		||||
// Copyright (C) 2013 Christian Stehno
 | 
			
		||||
// This file is part of the "Irrlicht Engine".
 | 
			
		||||
// For conditions of distribution and use, see copyright notice in Irrlicht.h
 | 
			
		||||
 | 
			
		||||
#include "CWGLManager.h"
 | 
			
		||||
 | 
			
		||||
#ifdef _IRR_COMPILE_WITH_WGL_MANAGER_
 | 
			
		||||
 | 
			
		||||
#include "os.h"
 | 
			
		||||
 | 
			
		||||
#include <GL/gl.h>
 | 
			
		||||
#include <GL/wglext.h>
 | 
			
		||||
 | 
			
		||||
namespace video
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
CWGLManager::CWGLManager() :
 | 
			
		||||
		PrimaryContext(SExposedVideoData(0)), PixelFormat(0), libHandle(NULL)
 | 
			
		||||
{
 | 
			
		||||
	memset(FunctionPointers, 0, sizeof(FunctionPointers));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
CWGLManager::~CWGLManager()
 | 
			
		||||
{
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool CWGLManager::initialize(const SIrrlichtCreationParameters ¶ms, const SExposedVideoData &videodata)
 | 
			
		||||
{
 | 
			
		||||
	// store params, videoData is set later as it would be overwritten else
 | 
			
		||||
	Params = params;
 | 
			
		||||
 | 
			
		||||
	// Create a window to test antialiasing support
 | 
			
		||||
	const fschar_t *ClassName = __TEXT("CWGLManager");
 | 
			
		||||
	HINSTANCE lhInstance = GetModuleHandle(0);
 | 
			
		||||
 | 
			
		||||
	// Register Class
 | 
			
		||||
	WNDCLASSEX wcex;
 | 
			
		||||
	wcex.cbSize = sizeof(WNDCLASSEX);
 | 
			
		||||
	wcex.style = CS_HREDRAW | CS_VREDRAW;
 | 
			
		||||
	wcex.lpfnWndProc = (WNDPROC)DefWindowProc;
 | 
			
		||||
	wcex.cbClsExtra = 0;
 | 
			
		||||
	wcex.cbWndExtra = 0;
 | 
			
		||||
	wcex.hInstance = lhInstance;
 | 
			
		||||
	wcex.hIcon = 0;
 | 
			
		||||
	wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
 | 
			
		||||
	wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
 | 
			
		||||
	wcex.lpszMenuName = 0;
 | 
			
		||||
	wcex.lpszClassName = ClassName;
 | 
			
		||||
	wcex.hIconSm = 0;
 | 
			
		||||
	RegisterClassEx(&wcex);
 | 
			
		||||
 | 
			
		||||
	RECT clientSize;
 | 
			
		||||
	clientSize.top = 0;
 | 
			
		||||
	clientSize.left = 0;
 | 
			
		||||
	clientSize.right = Params.WindowSize.Width;
 | 
			
		||||
	clientSize.bottom = Params.WindowSize.Height;
 | 
			
		||||
 | 
			
		||||
	DWORD style = WS_POPUP;
 | 
			
		||||
	if (!Params.Fullscreen)
 | 
			
		||||
		style = WS_SYSMENU | WS_BORDER | WS_CAPTION | WS_CLIPCHILDREN | WS_CLIPSIBLINGS;
 | 
			
		||||
 | 
			
		||||
	AdjustWindowRect(&clientSize, style, FALSE);
 | 
			
		||||
 | 
			
		||||
	const s32 realWidth = clientSize.right - clientSize.left;
 | 
			
		||||
	const s32 realHeight = clientSize.bottom - clientSize.top;
 | 
			
		||||
 | 
			
		||||
	const s32 windowLeft = (GetSystemMetrics(SM_CXSCREEN) - realWidth) / 2;
 | 
			
		||||
	const s32 windowTop = (GetSystemMetrics(SM_CYSCREEN) - realHeight) / 2;
 | 
			
		||||
 | 
			
		||||
	HWND temporary_wnd = CreateWindow(ClassName, __TEXT(""), style, windowLeft,
 | 
			
		||||
			windowTop, realWidth, realHeight, NULL, NULL, lhInstance, NULL);
 | 
			
		||||
 | 
			
		||||
	if (!temporary_wnd) {
 | 
			
		||||
		os::Printer::log("Cannot create a temporary window.", ELL_ERROR);
 | 
			
		||||
		UnregisterClass(ClassName, lhInstance);
 | 
			
		||||
		return false;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	HDC HDc = GetDC(temporary_wnd);
 | 
			
		||||
 | 
			
		||||
	// Set up pixel format descriptor with desired parameters
 | 
			
		||||
	PIXELFORMATDESCRIPTOR tmp_pfd = {
 | 
			
		||||
			sizeof(PIXELFORMATDESCRIPTOR),                         // Size Of This Pixel Format Descriptor
 | 
			
		||||
			1,                                                     // Version Number
 | 
			
		||||
			(DWORD)(PFD_DRAW_TO_WINDOW |                           // Format Must Support Window
 | 
			
		||||
					PFD_SUPPORT_OPENGL |                           // Format Must Support OpenGL
 | 
			
		||||
					(Params.Doublebuffer ? PFD_DOUBLEBUFFER : 0) | // Must Support Double Buffering
 | 
			
		||||
					(Params.Stereobuffer ? PFD_STEREO : 0)),       // Must Support Stereo Buffer
 | 
			
		||||
			PFD_TYPE_RGBA,                                         // Request An RGBA Format
 | 
			
		||||
			Params.Bits,                                           // Select Our Color Depth
 | 
			
		||||
			0, 0, 0, 0, 0, 0,                                      // Color Bits Ignored
 | 
			
		||||
			0,                                                     // No Alpha Buffer
 | 
			
		||||
			0,                                                     // Shift Bit Ignored
 | 
			
		||||
			0,                                                     // No Accumulation Buffer
 | 
			
		||||
			0, 0, 0, 0,                                            // Accumulation Bits Ignored
 | 
			
		||||
			Params.ZBufferBits,                                    // Z-Buffer (Depth Buffer)
 | 
			
		||||
			BYTE(Params.Stencilbuffer ? 1 : 0),                    // Stencil Buffer Depth
 | 
			
		||||
			0,                                                     // No Auxiliary Buffer
 | 
			
		||||
			PFD_MAIN_PLANE,                                        // Main Drawing Layer
 | 
			
		||||
			0,                                                     // Reserved
 | 
			
		||||
			0, 0, 0                                                // Layer Masks Ignored
 | 
			
		||||
	};
 | 
			
		||||
	pfd = tmp_pfd;
 | 
			
		||||
 | 
			
		||||
	for (u32 i = 0; i < 6; ++i) {
 | 
			
		||||
		if (i == 1) {
 | 
			
		||||
			if (Params.Stencilbuffer) {
 | 
			
		||||
				os::Printer::log("Cannot create a GL device with stencil buffer, disabling stencil shadows.", ELL_WARNING);
 | 
			
		||||
				Params.Stencilbuffer = false;
 | 
			
		||||
				pfd.cStencilBits = 0;
 | 
			
		||||
			} else
 | 
			
		||||
				continue;
 | 
			
		||||
		} else if (i == 2) {
 | 
			
		||||
			pfd.cDepthBits = 24;
 | 
			
		||||
		} else if (i == 3) {
 | 
			
		||||
			if (Params.Bits != 16)
 | 
			
		||||
				pfd.cDepthBits = 16;
 | 
			
		||||
			else
 | 
			
		||||
				continue;
 | 
			
		||||
		} else if (i == 4) {
 | 
			
		||||
			// try single buffer
 | 
			
		||||
			if (Params.Doublebuffer)
 | 
			
		||||
				pfd.dwFlags &= ~PFD_DOUBLEBUFFER;
 | 
			
		||||
			else
 | 
			
		||||
				continue;
 | 
			
		||||
		} else if (i == 5) {
 | 
			
		||||
			os::Printer::log("Cannot create a GL device context", "No suitable format for temporary window.", ELL_ERROR);
 | 
			
		||||
			ReleaseDC(temporary_wnd, HDc);
 | 
			
		||||
			DestroyWindow(temporary_wnd);
 | 
			
		||||
			UnregisterClass(ClassName, lhInstance);
 | 
			
		||||
			return false;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		// choose pixelformat
 | 
			
		||||
		PixelFormat = ChoosePixelFormat(HDc, &pfd);
 | 
			
		||||
		if (PixelFormat)
 | 
			
		||||
			break;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	SetPixelFormat(HDc, PixelFormat, &pfd);
 | 
			
		||||
	os::Printer::log("Create temporary GL rendering context", ELL_DEBUG);
 | 
			
		||||
	HGLRC hrc = wglCreateContext(HDc);
 | 
			
		||||
	if (!hrc) {
 | 
			
		||||
		os::Printer::log("Cannot create a temporary GL rendering context.", ELL_ERROR);
 | 
			
		||||
		ReleaseDC(temporary_wnd, HDc);
 | 
			
		||||
		DestroyWindow(temporary_wnd);
 | 
			
		||||
		UnregisterClass(ClassName, lhInstance);
 | 
			
		||||
		return false;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	CurrentContext.OpenGLWin32.HDc = HDc;
 | 
			
		||||
	CurrentContext.OpenGLWin32.HRc = hrc;
 | 
			
		||||
	CurrentContext.OpenGLWin32.HWnd = temporary_wnd;
 | 
			
		||||
 | 
			
		||||
	if (!activateContext(CurrentContext, false)) {
 | 
			
		||||
		os::Printer::log("Cannot activate a temporary GL rendering context.", ELL_ERROR);
 | 
			
		||||
		wglDeleteContext(hrc);
 | 
			
		||||
		ReleaseDC(temporary_wnd, HDc);
 | 
			
		||||
		DestroyWindow(temporary_wnd);
 | 
			
		||||
		UnregisterClass(ClassName, lhInstance);
 | 
			
		||||
		return false;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	core::stringc wglExtensions;
 | 
			
		||||
#ifdef WGL_ARB_extensions_string
 | 
			
		||||
	PFNWGLGETEXTENSIONSSTRINGARBPROC irrGetExtensionsString = (PFNWGLGETEXTENSIONSSTRINGARBPROC)wglGetProcAddress("wglGetExtensionsStringARB");
 | 
			
		||||
	if (irrGetExtensionsString)
 | 
			
		||||
		wglExtensions = irrGetExtensionsString(HDc);
 | 
			
		||||
#elif defined(WGL_EXT_extensions_string)
 | 
			
		||||
	PFNWGLGETEXTENSIONSSTRINGEXTPROC irrGetExtensionsString = (PFNWGLGETEXTENSIONSSTRINGEXTPROC)wglGetProcAddress("wglGetExtensionsStringEXT");
 | 
			
		||||
	if (irrGetExtensionsString)
 | 
			
		||||
		wglExtensions = irrGetExtensionsString(HDc);
 | 
			
		||||
#endif
 | 
			
		||||
	const bool pixel_format_supported = (wglExtensions.find("WGL_ARB_pixel_format") != -1);
 | 
			
		||||
	const bool multi_sample_supported = ((wglExtensions.find("WGL_ARB_multisample") != -1) ||
 | 
			
		||||
										 (wglExtensions.find("WGL_EXT_multisample") != -1) || (wglExtensions.find("WGL_3DFX_multisample") != -1));
 | 
			
		||||
	if (params.DriverDebug)
 | 
			
		||||
		os::Printer::log("WGL_extensions", wglExtensions);
 | 
			
		||||
 | 
			
		||||
	// Without a GL context we can't call wglGetProcAddress so store this for later
 | 
			
		||||
	FunctionPointers[0] = (void *)wglGetProcAddress("wglCreateContextAttribsARB");
 | 
			
		||||
 | 
			
		||||
#ifdef WGL_ARB_pixel_format
 | 
			
		||||
	PFNWGLCHOOSEPIXELFORMATARBPROC wglChoosePixelFormat_ARB = (PFNWGLCHOOSEPIXELFORMATARBPROC)wglGetProcAddress("wglChoosePixelFormatARB");
 | 
			
		||||
	if (pixel_format_supported && wglChoosePixelFormat_ARB) {
 | 
			
		||||
		// This value determines the number of samples used for antialiasing
 | 
			
		||||
		// My experience is that 8 does not show a big
 | 
			
		||||
		// improvement over 4, but 4 shows a big improvement
 | 
			
		||||
		// over 2.
 | 
			
		||||
 | 
			
		||||
		if (Params.AntiAlias > 32)
 | 
			
		||||
			Params.AntiAlias = 32;
 | 
			
		||||
 | 
			
		||||
		f32 fAttributes[] = {0.0, 0.0};
 | 
			
		||||
		s32 iAttributes[] = {
 | 
			
		||||
				WGL_DRAW_TO_WINDOW_ARB, 1,
 | 
			
		||||
				WGL_SUPPORT_OPENGL_ARB, 1,
 | 
			
		||||
				WGL_ACCELERATION_ARB, WGL_FULL_ACCELERATION_ARB,
 | 
			
		||||
				WGL_COLOR_BITS_ARB, (Params.Bits == 32) ? 24 : 15,
 | 
			
		||||
				WGL_ALPHA_BITS_ARB, (Params.Bits == 32) ? 8 : 1,
 | 
			
		||||
				WGL_DEPTH_BITS_ARB, Params.ZBufferBits, // 10,11
 | 
			
		||||
				WGL_STENCIL_BITS_ARB, Params.Stencilbuffer ? 1 : 0,
 | 
			
		||||
				WGL_DOUBLE_BUFFER_ARB, Params.Doublebuffer ? 1 : 0,
 | 
			
		||||
				WGL_STEREO_ARB, Params.Stereobuffer ? 1 : 0,
 | 
			
		||||
				WGL_PIXEL_TYPE_ARB, WGL_TYPE_RGBA_ARB,
 | 
			
		||||
#ifdef WGL_ARB_multisample
 | 
			
		||||
				WGL_SAMPLES_ARB, Params.AntiAlias, // 20,21
 | 
			
		||||
				WGL_SAMPLE_BUFFERS_ARB, (Params.AntiAlias > 0) ? 1 : 0,
 | 
			
		||||
#elif defined(WGL_EXT_multisample)
 | 
			
		||||
				WGL_SAMPLES_EXT, AntiAlias, // 20,21
 | 
			
		||||
				WGL_SAMPLE_BUFFERS_EXT, (Params.AntiAlias > 0) ? 1 : 0,
 | 
			
		||||
#elif defined(WGL_3DFX_multisample)
 | 
			
		||||
				WGL_SAMPLES_3DFX, AntiAlias, // 20,21
 | 
			
		||||
				WGL_SAMPLE_BUFFERS_3DFX, (Params.AntiAlias > 0) ? 1 : 0,
 | 
			
		||||
#endif
 | 
			
		||||
				//			WGL_DEPTH_FLOAT_EXT, 1,
 | 
			
		||||
				0, 0, 0, 0,
 | 
			
		||||
			};
 | 
			
		||||
		int iAttrSize = sizeof(iAttributes) / sizeof(int);
 | 
			
		||||
		if (!multi_sample_supported) {
 | 
			
		||||
			memmove(&iAttributes[20], &iAttributes[24], sizeof(int) * (iAttrSize - 24));
 | 
			
		||||
			iAttrSize -= 4;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		s32 rv = 0;
 | 
			
		||||
		// Try to get an acceptable pixel format
 | 
			
		||||
		do {
 | 
			
		||||
			int pixelFormat = 0;
 | 
			
		||||
			UINT numFormats = 0;
 | 
			
		||||
			const BOOL valid = wglChoosePixelFormat_ARB(HDc, iAttributes, fAttributes, 1, &pixelFormat, &numFormats);
 | 
			
		||||
 | 
			
		||||
			if (valid && numFormats)
 | 
			
		||||
				rv = pixelFormat;
 | 
			
		||||
			else
 | 
			
		||||
				iAttributes[21] -= 1;
 | 
			
		||||
		} while (rv == 0 && iAttributes[21] > 1);
 | 
			
		||||
		if (rv) {
 | 
			
		||||
			PixelFormat = rv;
 | 
			
		||||
			Params.AntiAlias = iAttributes[21];
 | 
			
		||||
		}
 | 
			
		||||
	} else
 | 
			
		||||
#endif
 | 
			
		||||
		Params.AntiAlias = 0;
 | 
			
		||||
 | 
			
		||||
	// this only terminates the temporary HRc
 | 
			
		||||
	destroyContext();
 | 
			
		||||
	destroySurface();
 | 
			
		||||
	terminate();
 | 
			
		||||
	DestroyWindow(temporary_wnd);
 | 
			
		||||
	UnregisterClass(ClassName, lhInstance);
 | 
			
		||||
 | 
			
		||||
	// now get new window
 | 
			
		||||
	CurrentContext.OpenGLWin32.HWnd = videodata.OpenGLWin32.HWnd;
 | 
			
		||||
	// get hdc
 | 
			
		||||
	if (!(CurrentContext.OpenGLWin32.HDc = GetDC((HWND)videodata.OpenGLWin32.HWnd))) {
 | 
			
		||||
		os::Printer::log("Cannot create a GL device context.", ELL_ERROR);
 | 
			
		||||
		return false;
 | 
			
		||||
	}
 | 
			
		||||
	if (!PrimaryContext.OpenGLWin32.HWnd) {
 | 
			
		||||
		PrimaryContext.OpenGLWin32.HWnd = CurrentContext.OpenGLWin32.HWnd;
 | 
			
		||||
		PrimaryContext.OpenGLWin32.HDc = CurrentContext.OpenGLWin32.HDc;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return true;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void CWGLManager::terminate()
 | 
			
		||||
{
 | 
			
		||||
	if (CurrentContext.OpenGLWin32.HDc)
 | 
			
		||||
		ReleaseDC((HWND)CurrentContext.OpenGLWin32.HWnd, (HDC)CurrentContext.OpenGLWin32.HDc);
 | 
			
		||||
	if (PrimaryContext.OpenGLWin32.HDc && PrimaryContext.OpenGLWin32.HDc == CurrentContext.OpenGLWin32.HDc)
 | 
			
		||||
		memset(&PrimaryContext, 0, sizeof(PrimaryContext));
 | 
			
		||||
	memset(&CurrentContext, 0, sizeof(CurrentContext));
 | 
			
		||||
	if (libHandle)
 | 
			
		||||
		FreeLibrary(libHandle);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool CWGLManager::generateSurface()
 | 
			
		||||
{
 | 
			
		||||
	HDC HDc = (HDC)CurrentContext.OpenGLWin32.HDc;
 | 
			
		||||
	// search for pixel format the simple way
 | 
			
		||||
	if (PixelFormat == 0 || (!SetPixelFormat(HDc, PixelFormat, &pfd))) {
 | 
			
		||||
		for (u32 i = 0; i < 5; ++i) {
 | 
			
		||||
			if (i == 1) {
 | 
			
		||||
				if (Params.Stencilbuffer) {
 | 
			
		||||
					os::Printer::log("Cannot create a GL device with stencil buffer, disabling stencil shadows.", ELL_WARNING);
 | 
			
		||||
					Params.Stencilbuffer = false;
 | 
			
		||||
					pfd.cStencilBits = 0;
 | 
			
		||||
				} else
 | 
			
		||||
					continue;
 | 
			
		||||
			} else if (i == 2) {
 | 
			
		||||
				pfd.cDepthBits = 24;
 | 
			
		||||
			}
 | 
			
		||||
			if (i == 3) {
 | 
			
		||||
				if (Params.Bits != 16)
 | 
			
		||||
					pfd.cDepthBits = 16;
 | 
			
		||||
				else
 | 
			
		||||
					continue;
 | 
			
		||||
			} else if (i == 4) {
 | 
			
		||||
				os::Printer::log("Cannot create a GL device context", "No suitable format.", ELL_ERROR);
 | 
			
		||||
				return false;
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			// choose pixelformat
 | 
			
		||||
			PixelFormat = ChoosePixelFormat(HDc, &pfd);
 | 
			
		||||
			if (PixelFormat)
 | 
			
		||||
				break;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		// set pixel format
 | 
			
		||||
		if (!SetPixelFormat(HDc, PixelFormat, &pfd)) {
 | 
			
		||||
			os::Printer::log("Cannot set the pixel format.", ELL_ERROR);
 | 
			
		||||
			return false;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (pfd.cAlphaBits != 0) {
 | 
			
		||||
		if (pfd.cRedBits == 8)
 | 
			
		||||
			ColorFormat = ECF_A8R8G8B8;
 | 
			
		||||
		else
 | 
			
		||||
			ColorFormat = ECF_A1R5G5B5;
 | 
			
		||||
	} else {
 | 
			
		||||
		if (pfd.cRedBits == 8)
 | 
			
		||||
			ColorFormat = ECF_R8G8B8;
 | 
			
		||||
		else
 | 
			
		||||
			ColorFormat = ECF_R5G6B5;
 | 
			
		||||
	}
 | 
			
		||||
	os::Printer::log("Pixel Format", core::stringc(PixelFormat).c_str(), ELL_DEBUG);
 | 
			
		||||
	return true;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void CWGLManager::destroySurface()
 | 
			
		||||
{
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool CWGLManager::generateContext()
 | 
			
		||||
{
 | 
			
		||||
	HDC HDc = (HDC)CurrentContext.OpenGLWin32.HDc;
 | 
			
		||||
	HGLRC hrc;
 | 
			
		||||
	// create rendering context
 | 
			
		||||
#ifdef WGL_ARB_create_context
 | 
			
		||||
	PFNWGLCREATECONTEXTATTRIBSARBPROC wglCreateContextAttribs_ARB = (PFNWGLCREATECONTEXTATTRIBSARBPROC)FunctionPointers[0];
 | 
			
		||||
	if (wglCreateContextAttribs_ARB) {
 | 
			
		||||
		// with 3.0 all available profiles should be usable, higher versions impose restrictions
 | 
			
		||||
		// we need at least 1.1
 | 
			
		||||
		const int iAttribs[] = {
 | 
			
		||||
				WGL_CONTEXT_MAJOR_VERSION_ARB, 1,
 | 
			
		||||
				WGL_CONTEXT_MINOR_VERSION_ARB, 1,
 | 
			
		||||
				//			WGL_CONTEXT_FLAGS_ARB, WGL_CONTEXT_DEBUG_BIT_ARB,	// enable to get a debug context (depends on driver if that does anything)
 | 
			
		||||
				0,
 | 
			
		||||
			};
 | 
			
		||||
		hrc = wglCreateContextAttribs_ARB(HDc, 0, iAttribs);
 | 
			
		||||
	} else
 | 
			
		||||
#endif
 | 
			
		||||
		hrc = wglCreateContext(HDc);
 | 
			
		||||
	os::Printer::log("Irrlicht context");
 | 
			
		||||
 | 
			
		||||
	if (!hrc) {
 | 
			
		||||
		os::Printer::log("Cannot create a GL rendering context.", ELL_ERROR);
 | 
			
		||||
		return false;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// set exposed data
 | 
			
		||||
	CurrentContext.OpenGLWin32.HRc = hrc;
 | 
			
		||||
	if (!PrimaryContext.OpenGLWin32.HRc)
 | 
			
		||||
		PrimaryContext.OpenGLWin32.HRc = CurrentContext.OpenGLWin32.HRc;
 | 
			
		||||
 | 
			
		||||
	return true;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const SExposedVideoData &CWGLManager::getContext() const
 | 
			
		||||
{
 | 
			
		||||
	return CurrentContext;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool CWGLManager::activateContext(const SExposedVideoData &videoData, bool restorePrimaryOnZero)
 | 
			
		||||
{
 | 
			
		||||
	if (videoData.OpenGLWin32.HWnd && videoData.OpenGLWin32.HDc && videoData.OpenGLWin32.HRc) {
 | 
			
		||||
		if (!wglMakeCurrent((HDC)videoData.OpenGLWin32.HDc, (HGLRC)videoData.OpenGLWin32.HRc)) {
 | 
			
		||||
			os::Printer::log("Render Context switch failed.");
 | 
			
		||||
			return false;
 | 
			
		||||
		}
 | 
			
		||||
		CurrentContext = videoData;
 | 
			
		||||
	} else if (!restorePrimaryOnZero && !videoData.OpenGLWin32.HDc && !videoData.OpenGLWin32.HRc) {
 | 
			
		||||
		if (!wglMakeCurrent((HDC)0, (HGLRC)0)) {
 | 
			
		||||
			os::Printer::log("Render Context reset failed.");
 | 
			
		||||
			return false;
 | 
			
		||||
		}
 | 
			
		||||
		CurrentContext = videoData;
 | 
			
		||||
	}
 | 
			
		||||
	// set back to main context
 | 
			
		||||
	else if (!videoData.OpenGLWin32.HWnd && CurrentContext.OpenGLWin32.HDc != PrimaryContext.OpenGLWin32.HDc) {
 | 
			
		||||
		if (!wglMakeCurrent((HDC)PrimaryContext.OpenGLWin32.HDc, (HGLRC)PrimaryContext.OpenGLWin32.HRc)) {
 | 
			
		||||
			os::Printer::log("Render Context switch (back to main) failed.");
 | 
			
		||||
			return false;
 | 
			
		||||
		}
 | 
			
		||||
		CurrentContext = PrimaryContext;
 | 
			
		||||
	}
 | 
			
		||||
	return true;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void CWGLManager::destroyContext()
 | 
			
		||||
{
 | 
			
		||||
	if (CurrentContext.OpenGLWin32.HRc) {
 | 
			
		||||
		if (!wglMakeCurrent((HDC)CurrentContext.OpenGLWin32.HDc, 0))
 | 
			
		||||
			os::Printer::log("Release of render context failed.", ELL_WARNING);
 | 
			
		||||
 | 
			
		||||
		if (!wglDeleteContext((HGLRC)CurrentContext.OpenGLWin32.HRc))
 | 
			
		||||
			os::Printer::log("Deletion of render context failed.", ELL_WARNING);
 | 
			
		||||
		if (PrimaryContext.OpenGLWin32.HRc == CurrentContext.OpenGLWin32.HRc)
 | 
			
		||||
			PrimaryContext.OpenGLWin32.HRc = 0;
 | 
			
		||||
		CurrentContext.OpenGLWin32.HRc = 0;
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void *CWGLManager::getProcAddress(const std::string &procName)
 | 
			
		||||
{
 | 
			
		||||
	void *proc = NULL;
 | 
			
		||||
	proc = (void *)wglGetProcAddress(procName.c_str());
 | 
			
		||||
	if (!proc) { // Fallback
 | 
			
		||||
		if (!libHandle)
 | 
			
		||||
			libHandle = LoadLibraryA("opengl32.dll");
 | 
			
		||||
		if (libHandle)
 | 
			
		||||
			proc = (void *)GetProcAddress(libHandle, procName.c_str());
 | 
			
		||||
	}
 | 
			
		||||
	return proc;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool CWGLManager::swapBuffers()
 | 
			
		||||
{
 | 
			
		||||
	return SwapBuffers((HDC)CurrentContext.OpenGLWin32.HDc) == TRUE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
@@ -1,73 +0,0 @@
 | 
			
		||||
// Copyright (C) 2013 Christian Stehno
 | 
			
		||||
// This file is part of the "Irrlicht Engine".
 | 
			
		||||
// For conditions of distribution and use, see copyright notice in Irrlicht.h
 | 
			
		||||
 | 
			
		||||
#pragma once
 | 
			
		||||
 | 
			
		||||
#ifdef _IRR_COMPILE_WITH_WGL_MANAGER_
 | 
			
		||||
 | 
			
		||||
#include "SIrrCreationParameters.h"
 | 
			
		||||
#include "SExposedVideoData.h"
 | 
			
		||||
#include "IContextManager.h"
 | 
			
		||||
#include "SColor.h"
 | 
			
		||||
 | 
			
		||||
#define WIN32_LEAN_AND_MEAN
 | 
			
		||||
#include <windows.h>
 | 
			
		||||
#include <libloaderapi.h>
 | 
			
		||||
 | 
			
		||||
namespace video
 | 
			
		||||
{
 | 
			
		||||
// WGL manager.
 | 
			
		||||
class CWGLManager : public IContextManager
 | 
			
		||||
{
 | 
			
		||||
public:
 | 
			
		||||
	//! Constructor.
 | 
			
		||||
	CWGLManager();
 | 
			
		||||
 | 
			
		||||
	//! Destructor
 | 
			
		||||
	~CWGLManager();
 | 
			
		||||
 | 
			
		||||
	// Initialize
 | 
			
		||||
	bool initialize(const SIrrlichtCreationParameters ¶ms, const SExposedVideoData &data) override;
 | 
			
		||||
 | 
			
		||||
	// Terminate
 | 
			
		||||
	void terminate() override;
 | 
			
		||||
 | 
			
		||||
	// Create surface.
 | 
			
		||||
	bool generateSurface() override;
 | 
			
		||||
 | 
			
		||||
	// Destroy surface.
 | 
			
		||||
	void destroySurface() override;
 | 
			
		||||
 | 
			
		||||
	// Create context.
 | 
			
		||||
	bool generateContext() override;
 | 
			
		||||
 | 
			
		||||
	// Destroy EGL context.
 | 
			
		||||
	void destroyContext() override;
 | 
			
		||||
 | 
			
		||||
	//! Get current context
 | 
			
		||||
	const SExposedVideoData &getContext() const override;
 | 
			
		||||
 | 
			
		||||
	//! Change render context, disable old and activate new defined by videoData
 | 
			
		||||
	bool activateContext(const SExposedVideoData &videoData, bool restorePrimaryOnZero) override;
 | 
			
		||||
 | 
			
		||||
	// Get procedure address.
 | 
			
		||||
	void *getProcAddress(const std::string &procName) override;
 | 
			
		||||
 | 
			
		||||
	// Swap buffers.
 | 
			
		||||
	bool swapBuffers() override;
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
	SIrrlichtCreationParameters Params;
 | 
			
		||||
	SExposedVideoData PrimaryContext;
 | 
			
		||||
	SExposedVideoData CurrentContext;
 | 
			
		||||
	s32 PixelFormat;
 | 
			
		||||
	PIXELFORMATDESCRIPTOR pfd;
 | 
			
		||||
	ECOLOR_FORMAT ColorFormat;
 | 
			
		||||
	void *FunctionPointers[1];
 | 
			
		||||
 | 
			
		||||
	HMODULE libHandle;
 | 
			
		||||
};
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
@@ -8,18 +8,6 @@ static const char *const copyright = "Irrlicht Engine (c) 2002-2017 Nikolaus Geb
 | 
			
		||||
#include "matrix4.h"
 | 
			
		||||
#include "SMaterial.h"
 | 
			
		||||
 | 
			
		||||
#ifdef _IRR_COMPILE_WITH_WINDOWS_DEVICE_
 | 
			
		||||
#include "CIrrDeviceWin32.h"
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef _IRR_COMPILE_WITH_X11_DEVICE_
 | 
			
		||||
#include "CIrrDeviceLinux.h"
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef _IRR_COMPILE_WITH_OSX_DEVICE_
 | 
			
		||||
#include "CIrrDeviceOSX.h"
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef _IRR_COMPILE_WITH_SDL_DEVICE_
 | 
			
		||||
#include "CIrrDeviceSDL.h"
 | 
			
		||||
#endif
 | 
			
		||||
@@ -49,21 +37,6 @@ extern "C" IrrlichtDevice *createDeviceEx(const SIrrlichtCreationParameters &par
 | 
			
		||||
 | 
			
		||||
	IrrlichtDevice *dev = 0;
 | 
			
		||||
 | 
			
		||||
#ifdef _IRR_COMPILE_WITH_WINDOWS_DEVICE_
 | 
			
		||||
	if (params.DeviceType == EIDT_WIN32 || (!dev && params.DeviceType == EIDT_BEST))
 | 
			
		||||
		dev = new CIrrDeviceWin32(params);
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef _IRR_COMPILE_WITH_OSX_DEVICE_
 | 
			
		||||
	if (params.DeviceType == EIDT_OSX || (!dev && params.DeviceType == EIDT_BEST))
 | 
			
		||||
		dev = new CIrrDeviceMacOSX(params);
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef _IRR_COMPILE_WITH_X11_DEVICE_
 | 
			
		||||
	if (params.DeviceType == EIDT_X11 || (!dev && params.DeviceType == EIDT_BEST))
 | 
			
		||||
		dev = new CIrrDeviceLinux(params);
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef _IRR_COMPILE_WITH_SDL_DEVICE_
 | 
			
		||||
	if (params.DeviceType == EIDT_SDL || (!dev && params.DeviceType == EIDT_BEST))
 | 
			
		||||
		dev = new CIrrDeviceSDL(params);
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user