mirror of
https://github.com/luanti-org/luanti.git
synced 2025-11-05 01:35:29 +01:00
Remove Irrlicht devices except SDL (#16580)
This commit is contained in:
@@ -434,7 +434,6 @@ window_maximized (Window maximized) bool false
|
|||||||
# Save window size automatically when modified.
|
# Save window size automatically when modified.
|
||||||
# If true, screen size is saved in screen_w and screen_h, and whether the window
|
# If true, screen size is saved in screen_w and screen_h, and whether the window
|
||||||
# is maximized is stored in window_maximized.
|
# is maximized is stored in window_maximized.
|
||||||
# (Autosaving window_maximized only works if compiled with SDL.)
|
|
||||||
#
|
#
|
||||||
# Requires: desktop
|
# Requires: desktop
|
||||||
autosave_screensize (Remember screen size) bool true
|
autosave_screensize (Remember screen size) bool true
|
||||||
|
|||||||
@@ -22,7 +22,6 @@ General options and their default values:
|
|||||||
MinSizeRel - Release build with -Os passed to compiler to make executable as small as possible
|
MinSizeRel - Release build with -Os passed to compiler to make executable as small as possible
|
||||||
PRECOMPILE_HEADERS=FALSE - Precompile some headers (experimental; requires CMake 3.16 or later)
|
PRECOMPILE_HEADERS=FALSE - Precompile some headers (experimental; requires CMake 3.16 or later)
|
||||||
PRECOMPILED_HEADERS_PATH= - Path to a file listing all headers to precompile (default points to src/precompiled_headers.txt)
|
PRECOMPILED_HEADERS_PATH= - Path to a file listing all headers to precompile (default points to src/precompiled_headers.txt)
|
||||||
USE_SDL2=TRUE - Build with SDL2; Enables IrrlichtMt device SDL2
|
|
||||||
USE_SDL2_STATIC=TRUE - Links with SDL2::SDL2-static instead of SDL2::SDL2
|
USE_SDL2_STATIC=TRUE - Links with SDL2::SDL2-static instead of SDL2::SDL2
|
||||||
ENABLE_CURL=ON - Build with cURL; Enables use of online mod repo, public serverlist and remote media fetching via http
|
ENABLE_CURL=ON - Build with cURL; Enables use of online mod repo, public serverlist and remote media fetching via http
|
||||||
ENABLE_CURSES=ON - Build with (n)curses; Enables a server side terminal (command line option: --terminal)
|
ENABLE_CURSES=ON - Build with (n)curses; Enables a server side terminal (command line option: --terminal)
|
||||||
@@ -48,9 +47,9 @@ General options and their default values:
|
|||||||
|
|
||||||
Library specific options:
|
Library specific options:
|
||||||
|
|
||||||
SDL2_DLL - Only if building with SDL2 on Windows; path to libSDL2.dll
|
SDL2_DLL - Only if building on Windows; path to libSDL2.dll
|
||||||
SDL2_INCLUDE_DIRS - Only if building with SDL2; directory where SDL.h is located
|
SDL2_INCLUDE_DIRS - directory where SDL.h is located
|
||||||
SDL2_LIBRARIES - Only if building with SDL2; path to libSDL2.a/libSDL2.so/libSDL2.lib
|
SDL2_LIBRARIES - path to libSDL2.a/libSDL2.so/libSDL2.lib
|
||||||
CURL_DLL - Only if building with cURL on Windows; path to libcurl.dll
|
CURL_DLL - Only if building with cURL on Windows; path to libcurl.dll
|
||||||
CURL_INCLUDE_DIR - Only if building with cURL; directory where curl.h is located
|
CURL_INCLUDE_DIR - Only if building with cURL; directory where curl.h is located
|
||||||
CURL_LIBRARY - Only if building with cURL; path to libcurl.a/libcurl.so/libcurl.lib
|
CURL_LIBRARY - Only if building with cURL; path to libcurl.a/libcurl.so/libcurl.lib
|
||||||
|
|||||||
@@ -2,8 +2,6 @@ cmake_minimum_required(VERSION 3.12)
|
|||||||
|
|
||||||
project(Irrlicht LANGUAGES CXX)
|
project(Irrlicht LANGUAGES CXX)
|
||||||
|
|
||||||
message(STATUS "*** Building IrrlichtMt ***")
|
|
||||||
|
|
||||||
set(CMAKE_CXX_STANDARD 17)
|
set(CMAKE_CXX_STANDARD 17)
|
||||||
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
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).
|
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.
|
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
|
* zlib, libPNG, libJPEG
|
||||||
* OpenGL
|
* OpenGL
|
||||||
* or on mobile: OpenGL ES (can be optionally enabled on desktop too)
|
* or on mobile: OpenGL ES (can be optionally enabled on desktop too)
|
||||||
* on Unix: X11
|
* SDL2
|
||||||
* SDL2 (see below)
|
|
||||||
|
|
||||||
Aside from standard search options (`ZLIB_INCLUDE_DIR`, `ZLIB_LIBRARY`, ...) the following options are available:
|
Aside from standard search options (`ZLIB_INCLUDE_DIR`, `ZLIB_LIBRARY`, ...) the following options are available:
|
||||||
* `ENABLE_OPENGL` - Enable OpenGL driver
|
* `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
|
* `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
|
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.
|
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
|
License
|
||||||
-------
|
-------
|
||||||
|
|
||||||
|
|||||||
@@ -7,23 +7,14 @@
|
|||||||
//! An enum for the different device types supported by the Irrlicht Engine.
|
//! An enum for the different device types supported by the Irrlicht Engine.
|
||||||
enum E_DEVICE_TYPE
|
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,
|
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,
|
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,
|
EIDT_OSX,
|
||||||
|
|
||||||
//! A device which uses Simple DirectMedia Layer
|
//! A device which uses Simple DirectMedia Layer
|
||||||
/** The SDL device works under all platforms supported by SDL but first must be compiled
|
/** The SDL device works under all platforms supported by SDL. */
|
||||||
in by setting the USE_SDL2 CMake option to ON */
|
|
||||||
EIDT_SDL,
|
EIDT_SDL,
|
||||||
|
|
||||||
//! This selection allows Irrlicht to choose the best device from the ones available.
|
//! 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. */
|
although it may not be able to render anything. */
|
||||||
EIDT_BEST,
|
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,
|
EIDT_ANDROID,
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -15,65 +15,7 @@ you are using the software or the null device.
|
|||||||
*/
|
*/
|
||||||
struct SExposedVideoData
|
struct SExposedVideoData
|
||||||
{
|
{
|
||||||
SExposedVideoData()
|
char dummy = 0;
|
||||||
{
|
|
||||||
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;
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // end namespace video
|
} // end namespace video
|
||||||
|
|||||||
@@ -35,16 +35,9 @@ bool CEGLManager::initialize(const SIrrlichtCreationParameters ¶ms, const SE
|
|||||||
return true;
|
return true;
|
||||||
|
|
||||||
// Window is depend on platform.
|
// Window is depend on platform.
|
||||||
#if defined(_IRR_COMPILE_WITH_WINDOWS_DEVICE_)
|
#if defined(_IRR_EMSCRIPTEN_PLATFORM_)
|
||||||
EglWindow = (NativeWindowType)Data.OpenGLWin32.HWnd;
|
|
||||||
Data.OpenGLWin32.HDc = GetDC((HWND)EglWindow);
|
|
||||||
EglDisplay = eglGetDisplay((NativeDisplayType)Data.OpenGLWin32.HDc);
|
|
||||||
#elif defined(_IRR_EMSCRIPTEN_PLATFORM_)
|
|
||||||
EglWindow = 0;
|
EglWindow = 0;
|
||||||
EglDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY);
|
EglDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY);
|
||||||
#elif defined(_IRR_COMPILE_WITH_X11_DEVICE_)
|
|
||||||
EglWindow = (NativeWindowType)Data.OpenGLLinux.X11Window;
|
|
||||||
EglDisplay = eglGetDisplay((NativeDisplayType)Data.OpenGLLinux.X11Display);
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// We must check if EGL display is valid.
|
// We must check if EGL display is valid.
|
||||||
@@ -80,13 +73,6 @@ void CEGLManager::terminate()
|
|||||||
EglDisplay = EGL_NO_DISPLAY;
|
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;
|
MajorVersion = 0;
|
||||||
MinorVersion = 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)
|
option(USE_SDL2_STATIC "Link with SDL2 static libraries" FALSE)
|
||||||
|
|
||||||
# Compiler flags
|
# Compiler flags
|
||||||
@@ -62,26 +58,18 @@ endif()
|
|||||||
|
|
||||||
if(WIN32)
|
if(WIN32)
|
||||||
add_compile_definitions(_IRR_WINDOWS_ _IRR_WINDOWS_API_)
|
add_compile_definitions(_IRR_WINDOWS_ _IRR_WINDOWS_API_)
|
||||||
set(DEVICE "WINDOWS")
|
|
||||||
elseif(APPLE)
|
elseif(APPLE)
|
||||||
add_compile_definitions(_IRR_OSX_PLATFORM_)
|
add_compile_definitions(_IRR_OSX_PLATFORM_)
|
||||||
set(DEVICE "OSX")
|
|
||||||
elseif(ANDROID)
|
elseif(ANDROID)
|
||||||
add_compile_definitions(_IRR_ANDROID_PLATFORM_)
|
add_compile_definitions(_IRR_ANDROID_PLATFORM_)
|
||||||
if(NOT USE_SDL2)
|
|
||||||
message(FATAL_ERROR "The Android build requires SDL2")
|
|
||||||
endif()
|
|
||||||
elseif(EMSCRIPTEN)
|
elseif(EMSCRIPTEN)
|
||||||
add_compile_definitions(_IRR_EMSCRIPTEN_PLATFORM_ _IRR_COMPILE_WITH_EGL_MANAGER_)
|
add_compile_definitions(_IRR_EMSCRIPTEN_PLATFORM_ _IRR_COMPILE_WITH_EGL_MANAGER_)
|
||||||
set(LINUX_PLATFORM TRUE)
|
set(LINUX_PLATFORM TRUE)
|
||||||
set(DEVICE "SDL")
|
|
||||||
elseif(SOLARIS)
|
elseif(SOLARIS)
|
||||||
add_compile_definitions(_IRR_SOLARIS_PLATFORM_ _IRR_POSIX_API_)
|
add_compile_definitions(_IRR_SOLARIS_PLATFORM_ _IRR_POSIX_API_)
|
||||||
set(DEVICE "X11")
|
|
||||||
else()
|
else()
|
||||||
add_compile_definitions(_IRR_POSIX_API_)
|
add_compile_definitions(_IRR_POSIX_API_)
|
||||||
set(LINUX_PLATFORM TRUE)
|
set(LINUX_PLATFORM TRUE)
|
||||||
set(DEVICE "X11")
|
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if(LINUX_PLATFORM)
|
if(LINUX_PLATFORM)
|
||||||
@@ -92,29 +80,7 @@ if(MSVC)
|
|||||||
add_compile_definitions(_CRT_SECURE_NO_WARNINGS)
|
add_compile_definitions(_CRT_SECURE_NO_WARNINGS)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if(USE_SDL2)
|
add_compile_definitions("_IRR_COMPILE_WITH_SDL_DEVICE_")
|
||||||
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()
|
|
||||||
|
|
||||||
# Joystick
|
# Joystick
|
||||||
|
|
||||||
@@ -122,14 +88,10 @@ if(NOT (BSD OR SOLARIS OR EMSCRIPTEN))
|
|||||||
add_compile_definitions(_IRR_COMPILE_WITH_JOYSTICK_EVENTS_)
|
add_compile_definitions(_IRR_COMPILE_WITH_JOYSTICK_EVENTS_)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
# OpenGL
|
# OpenGL (ES)
|
||||||
|
|
||||||
if(USE_SDL2)
|
if(NOT ANDROID)
|
||||||
if(NOT ANDROID)
|
set(DEFAULT_OPENGL3 TRUE)
|
||||||
set(DEFAULT_OPENGL3 TRUE)
|
|
||||||
endif()
|
|
||||||
else()
|
|
||||||
set(DEFAULT_OPENGL3 FALSE)
|
|
||||||
endif()
|
endif()
|
||||||
option(ENABLE_OPENGL3 "Enable OpenGL 3+" ${DEFAULT_OPENGL3})
|
option(ENABLE_OPENGL3 "Enable OpenGL 3+" ${DEFAULT_OPENGL3})
|
||||||
|
|
||||||
@@ -157,35 +119,13 @@ else()
|
|||||||
endif()
|
endif()
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if(ENABLE_OPENGL OR (ENABLE_OPENGL3 AND NOT USE_SDL2))
|
if(ENABLE_OPENGL)
|
||||||
if(ENABLE_OPENGL)
|
add_compile_definitions(_IRR_COMPILE_WITH_OPENGL_)
|
||||||
add_compile_definitions(_IRR_COMPILE_WITH_OPENGL_)
|
set(OPENGL_DIRECT_LINK TRUE) # driver relies on this
|
||||||
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()
|
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if(ENABLE_GLES2)
|
if(ENABLE_GLES2)
|
||||||
add_compile_definitions(_IRR_COMPILE_WITH_OGLES2_)
|
add_compile_definitions(_IRR_COMPILE_WITH_OGLES2_)
|
||||||
if(DEVICE MATCHES "^(WINDOWS|X11)$" OR EMSCRIPTEN)
|
|
||||||
add_compile_definitions(_IRR_COMPILE_WITH_EGL_MANAGER_)
|
|
||||||
endif()
|
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if(ENABLE_WEBGL1)
|
if(ENABLE_WEBGL1)
|
||||||
@@ -202,7 +142,6 @@ endif()
|
|||||||
|
|
||||||
# Configuration report
|
# Configuration report
|
||||||
|
|
||||||
message(STATUS "Device: ${DEVICE}")
|
|
||||||
message(STATUS "OpenGL: ${ENABLE_OPENGL}")
|
message(STATUS "OpenGL: ${ENABLE_OPENGL}")
|
||||||
message(STATUS "OpenGL 3: ${ENABLE_OPENGL3}")
|
message(STATUS "OpenGL 3: ${ENABLE_OPENGL3}")
|
||||||
if (ENABLE_GLES2)
|
if (ENABLE_GLES2)
|
||||||
@@ -227,7 +166,7 @@ if(ENABLE_OPENGL)
|
|||||||
find_package(OpenGL REQUIRED)
|
find_package(OpenGL REQUIRED)
|
||||||
endif()
|
endif()
|
||||||
set(USE_SDL2_SHARED FALSE)
|
set(USE_SDL2_SHARED FALSE)
|
||||||
if(USE_SDL2)
|
if(TRUE)
|
||||||
if(NOT USE_SDL2_STATIC)
|
if(NOT USE_SDL2_STATIC)
|
||||||
set(USE_SDL2_SHARED TRUE)
|
set(USE_SDL2_SHARED TRUE)
|
||||||
endif()
|
endif()
|
||||||
@@ -260,7 +199,7 @@ endif()
|
|||||||
|
|
||||||
# More special config
|
# 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,
|
# The legacy GL driver requires some symbols from GL 4.5 to compile,
|
||||||
# which SDL only provides since 2.26.0 (Nov 2022).
|
# which SDL only provides since 2.26.0 (Nov 2022).
|
||||||
# We have a fallback in case this isn't satisfied so test for it.
|
# We have a fallback in case this isn't satisfied so test for it.
|
||||||
@@ -278,19 +217,8 @@ endif()
|
|||||||
|
|
||||||
# Platform-specific libs
|
# Platform-specific libs
|
||||||
|
|
||||||
if(ANDROID)
|
if(APPLE)
|
||||||
enable_language(C)
|
|
||||||
elseif(APPLE)
|
|
||||||
find_library(COCOA_LIB Cocoa REQUIRED)
|
|
||||||
find_library(IOKIT_LIB IOKit REQUIRED)
|
|
||||||
|
|
||||||
add_compile_definitions(GL_SILENCE_DEPRECATION)
|
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()
|
endif()
|
||||||
|
|
||||||
set(link_includes
|
set(link_includes
|
||||||
@@ -300,13 +228,11 @@ set(link_includes
|
|||||||
"${ZLIB_INCLUDE_DIR}"
|
"${ZLIB_INCLUDE_DIR}"
|
||||||
"${JPEG_INCLUDE_DIR}"
|
"${JPEG_INCLUDE_DIR}"
|
||||||
"${PNG_INCLUDE_DIR}"
|
"${PNG_INCLUDE_DIR}"
|
||||||
"$<$<BOOL:${USE_SDL2}>:${SDL2_INCLUDE_DIRS}>"
|
"${SDL2_INCLUDE_DIRS}"
|
||||||
|
|
||||||
${OPENGL_INCLUDE_DIR}
|
${OPENGL_INCLUDE_DIR}
|
||||||
${OPENGLES2_INCLUDE_DIR}
|
${OPENGLES2_INCLUDE_DIR}
|
||||||
${EGL_INCLUDE_DIR}
|
${EGL_INCLUDE_DIR}
|
||||||
|
|
||||||
"$<$<BOOL:${USE_X11}>:${X11_INCLUDE_DIR}>"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
# Source files
|
# Source files
|
||||||
@@ -338,14 +264,10 @@ target_link_libraries(IRRMESHOBJ PUBLIC tiniergltf::tiniergltf)
|
|||||||
|
|
||||||
set(IRRDRVROBJ
|
set(IRRDRVROBJ
|
||||||
CNullDriver.h
|
CNullDriver.h
|
||||||
CGLXManager.h
|
|
||||||
CWGLManager.h
|
|
||||||
CEGLManager.h
|
CEGLManager.h
|
||||||
CSDLManager.h
|
CSDLManager.h
|
||||||
|
|
||||||
CNullDriver.cpp
|
CNullDriver.cpp
|
||||||
CGLXManager.cpp
|
|
||||||
CWGLManager.cpp
|
|
||||||
CEGLManager.cpp
|
CEGLManager.cpp
|
||||||
CSDLManager.cpp
|
CSDLManager.cpp
|
||||||
mt_opengl_loader.cpp
|
mt_opengl_loader.cpp
|
||||||
@@ -446,17 +368,13 @@ add_library(IRRIOOBJ OBJECT
|
|||||||
|
|
||||||
add_library(IRROTHEROBJ OBJECT
|
add_library(IRROTHEROBJ OBJECT
|
||||||
CIrrDeviceSDL.h
|
CIrrDeviceSDL.h
|
||||||
CIrrDeviceLinux.h
|
|
||||||
CIrrDeviceStub.h
|
CIrrDeviceStub.h
|
||||||
CIrrDeviceWin32.h
|
|
||||||
CLogger.h
|
CLogger.h
|
||||||
COSOperator.h
|
COSOperator.h
|
||||||
os.h
|
os.h
|
||||||
|
|
||||||
CIrrDeviceSDL.cpp
|
CIrrDeviceSDL.cpp
|
||||||
CIrrDeviceLinux.cpp
|
|
||||||
CIrrDeviceStub.cpp
|
CIrrDeviceStub.cpp
|
||||||
CIrrDeviceWin32.cpp
|
|
||||||
CLogger.cpp
|
CLogger.cpp
|
||||||
COSOperator.cpp
|
COSOperator.cpp
|
||||||
Irrlicht.cpp
|
Irrlicht.cpp
|
||||||
@@ -470,22 +388,6 @@ endif()
|
|||||||
if(APPLE)
|
if(APPLE)
|
||||||
# Build all IRROTHEROBJ sources as objc++, including the .cpp's
|
# Build all IRROTHEROBJ sources as objc++, including the .cpp's
|
||||||
set_target_properties(IRROTHEROBJ PROPERTIES COMPILE_OPTIONS "-xobjective-c++")
|
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()
|
endif()
|
||||||
|
|
||||||
add_library(IRRGUIOBJ OBJECT
|
add_library(IRRGUIOBJ OBJECT
|
||||||
@@ -591,12 +493,6 @@ target_link_libraries(IrrlichtMt PRIVATE
|
|||||||
|
|
||||||
# incl. transitive SDL2 dependencies for static linking
|
# incl. transitive SDL2 dependencies for static linking
|
||||||
"$<$<PLATFORM_ID:Android>:-landroid -llog -lGLESv2 -lGLESv1_CM -lOpenSLES>"
|
"$<$<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)
|
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_)
|
#if defined(_IRR_COMPILE_WITH_SDL_DEVICE_)
|
||||||
#include <SDL_clipboard.h>
|
#include <SDL_clipboard.h>
|
||||||
#include <SDL_version.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
|
#endif
|
||||||
|
|
||||||
#include "fast_atof.h"
|
#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
|
// constructor
|
||||||
COSOperator::COSOperator(const core::stringc &osVersion) :
|
COSOperator::COSOperator(const core::stringc &osVersion) :
|
||||||
OperatingSystem(osVersion)
|
OperatingSystem(osVersion)
|
||||||
@@ -64,43 +51,6 @@ void COSOperator::copyToClipboard(const c8 *text) const
|
|||||||
|
|
||||||
#if defined(_IRR_COMPILE_WITH_SDL_DEVICE_)
|
#if defined(_IRR_COMPILE_WITH_SDL_DEVICE_)
|
||||||
SDL_SetClipboardText(text);
|
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
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -114,10 +64,6 @@ void COSOperator::copyToPrimarySelection(const c8 *text) const
|
|||||||
#if SDL_VERSION_ATLEAST(2, 25, 0)
|
#if SDL_VERSION_ATLEAST(2, 25, 0)
|
||||||
SDL_SetPrimarySelectionText(text);
|
SDL_SetPrimarySelectionText(text);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#elif defined(_IRR_COMPILE_WITH_X11_DEVICE_)
|
|
||||||
if (IrrDeviceLinux)
|
|
||||||
IrrDeviceLinux->copyToPrimarySelection(text);
|
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -128,42 +74,6 @@ const c8 *COSOperator::getTextFromClipboard() const
|
|||||||
SDL_free(ClipboardSelectionText);
|
SDL_free(ClipboardSelectionText);
|
||||||
ClipboardSelectionText = SDL_GetClipboardText();
|
ClipboardSelectionText = SDL_GetClipboardText();
|
||||||
return ClipboardSelectionText;
|
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
|
#else
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
@@ -181,11 +91,6 @@ const c8 *COSOperator::getTextFromPrimarySelection() const
|
|||||||
#endif
|
#endif
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
#elif defined(_IRR_COMPILE_WITH_X11_DEVICE_)
|
|
||||||
if (IrrDeviceLinux)
|
|
||||||
return IrrDeviceLinux->getTextFromPrimarySelection();
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
@@ -238,7 +143,6 @@ bool COSOperator::getSystemMemory(u32 *Total, u32 *Avail) const
|
|||||||
*Avail = (u32)(physical_memory >> 10); // we don't know better
|
*Avail = (u32)(physical_memory >> 10); // we don't know better
|
||||||
return true;
|
return true;
|
||||||
#else
|
#else
|
||||||
// TODO: implement for others
|
|
||||||
return false;
|
return false;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,16 +6,11 @@
|
|||||||
|
|
||||||
#include "IOSOperator.h"
|
#include "IOSOperator.h"
|
||||||
|
|
||||||
class CIrrDeviceLinux;
|
|
||||||
|
|
||||||
//! The OSOperator provides OS-specific methods and information.
|
//! The OSOperator provides OS-specific methods and information.
|
||||||
class COSOperator : public IOSOperator
|
class COSOperator : public IOSOperator
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
// constructor
|
// constructor
|
||||||
#if defined(_IRR_COMPILE_WITH_X11_DEVICE_)
|
|
||||||
COSOperator(const core::stringc &osversion, CIrrDeviceLinux *device);
|
|
||||||
#endif
|
|
||||||
COSOperator(const core::stringc &osversion);
|
COSOperator(const core::stringc &osversion);
|
||||||
|
|
||||||
~COSOperator();
|
~COSOperator();
|
||||||
@@ -53,10 +48,6 @@ public:
|
|||||||
private:
|
private:
|
||||||
core::stringc OperatingSystem;
|
core::stringc OperatingSystem;
|
||||||
|
|
||||||
#if defined(_IRR_COMPILE_WITH_X11_DEVICE_)
|
|
||||||
CIrrDeviceLinux *IrrDeviceLinux;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef _IRR_WINDOWS_API_
|
#ifdef _IRR_WINDOWS_API_
|
||||||
mutable core::stringc ClipboardBuf;
|
mutable core::stringc ClipboardBuf;
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -44,10 +44,6 @@ bool COpenGLDriver::initDriver()
|
|||||||
|
|
||||||
genericDriverInit();
|
genericDriverInit();
|
||||||
|
|
||||||
#if defined(_IRR_COMPILE_WITH_WINDOWS_DEVICE_) || defined(_IRR_COMPILE_WITH_X11_DEVICE_)
|
|
||||||
extGlSwapInterval(Params.Vsync ? 1 : 0);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -89,22 +89,6 @@ COpenGLExtensionHandler::COpenGLExtensionHandler() :
|
|||||||
// DSA with EXT or functions to simulate it
|
// DSA with EXT or functions to simulate it
|
||||||
pGlTextureStorage2DEXT(0), pGlTexStorage2D(0), pGlTextureStorage3DEXT(0), pGlTexStorage3D(0), pGlTextureSubImage2DEXT(0), pGlGetTextureImageEXT(0),
|
pGlTextureStorage2DEXT(0), pGlTexStorage2D(0), pGlTextureStorage3DEXT(0), pGlTexStorage3D(0), pGlTextureSubImage2DEXT(0), pGlGetTextureImageEXT(0),
|
||||||
pGlNamedFramebufferTextureEXT(0), pGlFramebufferTexture(0), pGlGenerateTextureMipmapEXT(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)
|
for (u32 i = 0; i < IRR_OpenGL_Feature_Count; ++i)
|
||||||
FeatureAvailable[i] = false;
|
FeatureAvailable[i] = false;
|
||||||
@@ -360,20 +344,6 @@ void COpenGLExtensionHandler::initExtensions(video::IContextManager *cmgr, bool
|
|||||||
pGlActiveTexture = (PFNGLACTIVETEXTUREPROC)IRR_OGL_LOAD_EXTENSION("glActiveTexture");
|
pGlActiveTexture = (PFNGLACTIVETEXTUREPROC)IRR_OGL_LOAD_EXTENSION("glActiveTexture");
|
||||||
pGlGenerateTextureMipmapEXT = (PFNGLGENERATETEXTUREMIPMAPEXTPROC)IRR_OGL_LOAD_EXTENSION("glGenerateTextureMipmapEXT");
|
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;
|
GLint num = 0;
|
||||||
// set some properties
|
// set some properties
|
||||||
#if defined(GL_ARB_multitexture) || defined(GL_VERSION_1_3)
|
#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 extGlBindTextures(GLuint first, GLsizei count, const GLuint *textures, const GLenum *targets);
|
||||||
void extGlGenerateTextureMipmap(GLuint texture, GLenum target);
|
void extGlGenerateTextureMipmap(GLuint texture, GLenum target);
|
||||||
|
|
||||||
// generic vsync setting method for several extensions
|
|
||||||
void extGlSwapInterval(int interval);
|
|
||||||
|
|
||||||
// the global feature array
|
// the global feature array
|
||||||
bool FeatureAvailable[IRR_OpenGL_Feature_Count];
|
bool FeatureAvailable[IRR_OpenGL_Feature_Count];
|
||||||
|
|
||||||
@@ -1388,19 +1385,6 @@ protected:
|
|||||||
PFNGLNAMEDFRAMEBUFFERTEXTUREEXTPROC pGlNamedFramebufferTextureEXT;
|
PFNGLNAMEDFRAMEBUFFERTEXTUREEXTPROC pGlNamedFramebufferTextureEXT;
|
||||||
PFNGLFRAMEBUFFERTEXTUREPROC pGlFramebufferTexture;
|
PFNGLFRAMEBUFFERTEXTUREPROC pGlFramebufferTexture;
|
||||||
PFNGLGENERATETEXTUREMIPMAPEXTPROC pGlGenerateTextureMipmapEXT;
|
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)
|
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
|
#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 "matrix4.h"
|
||||||
#include "SMaterial.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_
|
#ifdef _IRR_COMPILE_WITH_SDL_DEVICE_
|
||||||
#include "CIrrDeviceSDL.h"
|
#include "CIrrDeviceSDL.h"
|
||||||
#endif
|
#endif
|
||||||
@@ -49,21 +37,6 @@ extern "C" IrrlichtDevice *createDeviceEx(const SIrrlichtCreationParameters &par
|
|||||||
|
|
||||||
IrrlichtDevice *dev = 0;
|
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_
|
#ifdef _IRR_COMPILE_WITH_SDL_DEVICE_
|
||||||
if (params.DeviceType == EIDT_SDL || (!dev && params.DeviceType == EIDT_BEST))
|
if (params.DeviceType == EIDT_SDL || (!dev && params.DeviceType == EIDT_BEST))
|
||||||
dev = new CIrrDeviceSDL(params);
|
dev = new CIrrDeviceSDL(params);
|
||||||
|
|||||||
@@ -2049,10 +2049,10 @@ void Game::updateCameraDirection(CameraOrientation *cam, float dtime)
|
|||||||
{
|
{
|
||||||
auto *cur_control = device->getCursorControl();
|
auto *cur_control = device->getCursorControl();
|
||||||
|
|
||||||
/* With CIrrDeviceSDL on Linux and Windows, enabling relative mouse mode
|
/* On Linux and Windows, enabling relative mouse mode somehow results
|
||||||
somehow results in simulated mouse events being generated from touch events,
|
in simulated mouse events being generated from touch events, even though
|
||||||
although SDL_HINT_MOUSE_TOUCH_EVENTS and SDL_HINT_TOUCH_MOUSE_EVENTS are set to 0.
|
SDL_HINT_MOUSE_TOUCH_EVENTS and SDL_HINT_TOUCH_MOUSE_EVENTS are set to 0.
|
||||||
Since Minetest has its own code to synthesize mouse events from touch events,
|
Since we have our own code to synthesize mouse events from touch events,
|
||||||
this results in duplicated input. To avoid that, we don't enable relative
|
this results in duplicated input. To avoid that, we don't enable relative
|
||||||
mouse mode if we're in touchscreen mode. */
|
mouse mode if we're in touchscreen mode. */
|
||||||
if (cur_control)
|
if (cur_control)
|
||||||
|
|||||||
@@ -143,8 +143,7 @@ bool MyEventReceiver::OnEvent(const SEvent &event)
|
|||||||
IrrlichtDevice *device = RenderingEngine::get_raw_device();
|
IrrlichtDevice *device = RenderingEngine::get_raw_device();
|
||||||
|
|
||||||
bool new_fullscreen = !device->isFullscreen();
|
bool new_fullscreen = !device->isFullscreen();
|
||||||
// Only update the setting if toggling succeeds - it always fails
|
// Only update the setting if toggling succeeds
|
||||||
// if Minetest was built without SDL.
|
|
||||||
if (device->setFullscreen(new_fullscreen)) {
|
if (device->setFullscreen(new_fullscreen)) {
|
||||||
g_settings->setBool("fullscreen", new_fullscreen);
|
g_settings->setBool("fullscreen", new_fullscreen);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -305,31 +305,24 @@ KeyPress::KeyPress(const std::string &name)
|
|||||||
|
|
||||||
KeyPress::KeyPress(const SEvent::SKeyInput &in)
|
KeyPress::KeyPress(const SEvent::SKeyInput &in)
|
||||||
{
|
{
|
||||||
if (USE_SDL2) {
|
if (in.SystemKeyCode)
|
||||||
if (in.SystemKeyCode)
|
scancode.emplace<u32>(in.SystemKeyCode);
|
||||||
scancode.emplace<u32>(in.SystemKeyCode);
|
else
|
||||||
else
|
scancode.emplace<EKEY_CODE>(in.Key);
|
||||||
scancode.emplace<EKEY_CODE>(in.Key);
|
|
||||||
} else {
|
|
||||||
loadFromKey(in.Key, in.Char);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string KeyPress::formatScancode() const
|
std::string KeyPress::formatScancode() const
|
||||||
{
|
{
|
||||||
if (USE_SDL2) {
|
if (auto pv = std::get_if<u32>(&scancode))
|
||||||
if (auto pv = std::get_if<u32>(&scancode))
|
return *pv == 0 ? "" : "SYSTEM_SCANCODE_" + std::to_string(*pv);
|
||||||
return *pv == 0 ? "" : "SYSTEM_SCANCODE_" + std::to_string(*pv);
|
|
||||||
}
|
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string KeyPress::sym() const
|
std::string KeyPress::sym() const
|
||||||
{
|
{
|
||||||
std::string name = lookup_scancode(scancode).Name;
|
std::string name = lookup_scancode(scancode).Name;
|
||||||
if (USE_SDL2 || name.empty())
|
if (auto newname = formatScancode(); !newname.empty())
|
||||||
if (auto newname = formatScancode(); !newname.empty())
|
return newname;
|
||||||
return newname;
|
|
||||||
return name;
|
return name;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -353,18 +346,14 @@ wchar_t KeyPress::getKeychar() const
|
|||||||
|
|
||||||
bool KeyPress::loadFromScancode(const std::string &name)
|
bool KeyPress::loadFromScancode(const std::string &name)
|
||||||
{
|
{
|
||||||
if (USE_SDL2) {
|
if (!str_starts_with(name, "SYSTEM_SCANCODE_"))
|
||||||
if (!str_starts_with(name, "SYSTEM_SCANCODE_"))
|
|
||||||
return false;
|
|
||||||
char *p;
|
|
||||||
const auto code = strtoul(name.c_str()+16, &p, 10);
|
|
||||||
if (p != name.c_str() + name.size())
|
|
||||||
return false;
|
|
||||||
scancode.emplace<u32>(code);
|
|
||||||
return true;
|
|
||||||
} else {
|
|
||||||
return false;
|
return false;
|
||||||
}
|
char *p;
|
||||||
|
const auto code = strtoul(name.c_str()+16, &p, 10);
|
||||||
|
if (p != name.c_str() + name.size())
|
||||||
|
return false;
|
||||||
|
scancode.emplace<u32>(code);
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::unordered_map<std::string, KeyPress> specialKeyCache;
|
std::unordered_map<std::string, KeyPress> specialKeyCache;
|
||||||
|
|||||||
@@ -41,5 +41,4 @@
|
|||||||
#cmakedefine01 CURSES_HAVE_NCURSESW_CURSES_H
|
#cmakedefine01 CURSES_HAVE_NCURSESW_CURSES_H
|
||||||
#cmakedefine01 BUILD_UNITTESTS
|
#cmakedefine01 BUILD_UNITTESTS
|
||||||
#cmakedefine01 BUILD_BENCHMARKS
|
#cmakedefine01 BUILD_BENCHMARKS
|
||||||
#cmakedefine01 USE_SDL2
|
|
||||||
#cmakedefine01 BUILD_WITH_TRACY
|
#cmakedefine01 BUILD_WITH_TRACY
|
||||||
|
|||||||
@@ -129,23 +129,14 @@ void set_default_settings()
|
|||||||
settings->setDefault("chat_weblink_color", "#8888FF");
|
settings->setDefault("chat_weblink_color", "#8888FF");
|
||||||
|
|
||||||
// Keymap
|
// Keymap
|
||||||
#if USE_SDL2
|
|
||||||
#define USEKEY2(name, value, _) settings->setDefault(name, value)
|
#define USEKEY2(name, value, _) settings->setDefault(name, value)
|
||||||
#else
|
|
||||||
#define USEKEY2(name, _, value) settings->setDefault(name, value)
|
|
||||||
#endif
|
|
||||||
USEKEY2("keymap_forward", "SYSTEM_SCANCODE_26", "KEY_KEY_W");
|
USEKEY2("keymap_forward", "SYSTEM_SCANCODE_26", "KEY_KEY_W");
|
||||||
settings->setDefault("keymap_autoforward", "");
|
settings->setDefault("keymap_autoforward", "");
|
||||||
USEKEY2("keymap_backward", "SYSTEM_SCANCODE_22", "KEY_KEY_S");
|
USEKEY2("keymap_backward", "SYSTEM_SCANCODE_22", "KEY_KEY_S");
|
||||||
USEKEY2("keymap_left", "SYSTEM_SCANCODE_4", "KEY_KEY_A");
|
USEKEY2("keymap_left", "SYSTEM_SCANCODE_4", "KEY_KEY_A");
|
||||||
USEKEY2("keymap_right", "SYSTEM_SCANCODE_7", "KEY_KEY_D");
|
USEKEY2("keymap_right", "SYSTEM_SCANCODE_7", "KEY_KEY_D");
|
||||||
USEKEY2("keymap_jump", "SYSTEM_SCANCODE_44", "KEY_SPACE");
|
USEKEY2("keymap_jump", "SYSTEM_SCANCODE_44", "KEY_SPACE");
|
||||||
#if !USE_SDL2 && defined(__MACH__) && defined(__APPLE__)
|
|
||||||
// Altered settings for CIrrDeviceOSX
|
|
||||||
settings->setDefault("keymap_sneak", "KEY_SHIFT");
|
|
||||||
#else
|
|
||||||
USEKEY2("keymap_sneak", "SYSTEM_SCANCODE_225", "KEY_LSHIFT");
|
USEKEY2("keymap_sneak", "SYSTEM_SCANCODE_225", "KEY_LSHIFT");
|
||||||
#endif
|
|
||||||
settings->setDefault("keymap_dig", "KEY_LBUTTON");
|
settings->setDefault("keymap_dig", "KEY_LBUTTON");
|
||||||
settings->setDefault("keymap_place", "KEY_RBUTTON");
|
settings->setDefault("keymap_place", "KEY_RBUTTON");
|
||||||
USEKEY2("keymap_drop", "SYSTEM_SCANCODE_20", "KEY_KEY_Q");
|
USEKEY2("keymap_drop", "SYSTEM_SCANCODE_20", "KEY_KEY_Q");
|
||||||
|
|||||||
Reference in New Issue
Block a user