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