1
0
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:
sfan5
2025-10-30 13:39:44 +01:00
committed by GitHub
parent d4d3e10531
commit e924f425f2
31 changed files with 42 additions and 7972 deletions

View File

@@ -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

View File

@@ -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

View File

@@ -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)

View File

@@ -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
-------

View File

@@ -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,
};

View File

@@ -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

View File

@@ -35,16 +35,9 @@ bool CEGLManager::initialize(const SIrrlichtCreationParameters &params, 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;
}

View File

@@ -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 &params, 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 &params, 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

View File

@@ -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 &params, const SExposedVideoData &videodata, int screennr);
//! Destructor
~CGLXManager();
// Initialize
bool initialize(const SIrrlichtCreationParameters &params, 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

View File

@@ -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 &param);
//! 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_

View File

@@ -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 &params);
//! 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

View File

@@ -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 &params);
//! 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_

View File

@@ -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)

View File

@@ -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 &params, 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

View File

@@ -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 &params, 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

View File

@@ -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
}

View File

@@ -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

View File

@@ -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;
}

View File

@@ -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)

View File

@@ -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

View File

@@ -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 &params, 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

View File

@@ -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 &params, 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

View File

@@ -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);

View File

@@ -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)

View File

@@ -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);
}

View File

@@ -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;

View File

@@ -41,5 +41,4 @@
#cmakedefine01 CURSES_HAVE_NCURSESW_CURSES_H
#cmakedefine01 BUILD_UNITTESTS
#cmakedefine01 BUILD_BENCHMARKS
#cmakedefine01 USE_SDL2
#cmakedefine01 BUILD_WITH_TRACY

View File

@@ -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");