Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Wayland support #3142

Merged
merged 19 commits into from
Jun 26, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 7 additions & 2 deletions .github/workflows/ci-build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -107,8 +107,13 @@ jobs:
custombuild:
runs-on: ubuntu-20.04
steps:
- name: Install Dependencies
run: |
sudo apt update
sudo apt install -y libwayland-dev libwayland-egl1 pkg-config libegl-dev \
qtwayland5 qtbase5-private-dev
- uses: actions/checkout@v4
- name: Build
run: |
cmake -Bbuild -DOGRE_BUILD_DEPENDENCIES=OFF -DSWIG_EXECUTABLE=none -DOGRE_CONFIG_DOUBLE=ON -DOGRE_ASSERT_MODE=1 -DOGRE_PROFILING=ON .
cmake --build build -- -j 4
cmake -Bbuild -DOGRE_BUILD_DEPENDENCIES=OFF -DSWIG_EXECUTABLE=none -DOGRE_CONFIG_DOUBLE=ON -DOGRE_ASSERT_MODE=1 -DOGRE_PROFILING=ON -DOGRE_GLSUPPORT_USE_WAYLAND=ON .
cmake --build build -- -j 4
25 changes: 19 additions & 6 deletions BuildingOgre.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,25 +42,36 @@ For manually building the dependencies, please refer to the list below and get a
### Linux

On linux you additionally need the following system headers to build the GL, GL3+, GLES2 & Vulkan RenderSystems:

* Ubuntu

sudo apt-get install libgles2-mesa-dev libvulkan-dev glslang-dev libxrandr-dev
sudo apt-get install libgles2-mesa-dev libvulkan-dev glslang-dev

* **X11**: `sudo apt-get install libxrandr-dev`
* **Wayland**: `sudo apt-get install pkg-config libwayland-dev libwayland-egl1 libegl-dev`

* Fedora

sudo dnf install mesa-libGL-devel mesa-vulkan-devel glslang-devel
sudo dnf install mesa-libGL-devel mesa-libEGL-devel mesa-vulkan-devel glslang-devel

* **X11**: `sudo dnf install libXrandr-devel`
* **Wayland**: `sudo dnv install pkgconfig wayland-devel egl-wayland`

furthermore we recommend installing the following optional packages
Furthermore, we recommend installing the following optional packages

* Ubuntu

sudo apt-get install libsdl2-dev libxt-dev libxaw7-dev doxygen
sudo apt-get install libsdl2-dev doxygen

* **X11**: `sudo apt-get install libxt-dev libxaw7-dev`

* Fedora

sudo dnf install SDL2-devel libXt-devel libXaw-devel doxygen pugixml-devel
sudo dnf install SDL2-devel doxygen

* **X11**: `sudo dnf install libXt-devel libXaw-devel`

these will enable input handling in the SampleBrowser, the X11 ConfigDialog and allow building the documentation.
These will enable input handling in the SampleBrowser, the X11 ConfigDialog and allow building the documentation.

### Recommended dependencies

Expand All @@ -79,6 +90,7 @@ these will enable input handling in the SampleBrowser, the X11 ConfigDialog and
* Remotery: https://github.com/Celtoys/Remotery
* SWIG: http://www.swig.org/
* %Assimp: https://www.assimp.org/
* Wayland: https://wayland.freedesktop.org/

Running CMake
-------------
Expand Down Expand Up @@ -106,6 +118,7 @@ particular component/ plugin from being built
- `OGRE_ASSERT_MODE` allows you to to disable all runtime assertion exceptions or turn them into calls to `std::abort`.
- `OGRE_RESOURCEMANGER_STRICT` allows you to turn on resource lookup related quirks for pre ogre 1.10 compatibility.
- `OGRE_NODELESS_POSITIONING` allows to use Lights and Cameras without attaching them to nodes (only for legacy code).
- `OGRE_GLSUPPORT_USE_WAYLAND` will use Wayland window system instead of X11 on Linux for GL-based RenderSystems.

Once you are satisfied, hit
*Configure* again and then click on *Generate*. CMake will then create
Expand Down
13 changes: 12 additions & 1 deletion CMake/Dependencies.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -219,8 +219,19 @@ macro_log_feature(FREETYPE_FOUND "freetype" "Portable font engine" "http://www.f

# Find X11
if (UNIX AND NOT APPLE AND NOT ANDROID AND NOT EMSCRIPTEN)
find_package(X11 REQUIRED)
find_package(PkgConfig)
if (PKG_CONFIG_FOUND)
pkg_check_modules(waylands IMPORTED_TARGET wayland-client wayland-egl egl)
macro_log_feature(waylands_FOUND "Wayland" "Wayland window system" "https://wayland.freedesktop.org")
endif ()

if (NOT waylands_FOUND)
find_package(X11 REQUIRED)
else ()
find_package(X11)
endif ()
macro_log_feature(X11_FOUND "X11" "X Window system" "http://www.x.org")

endif ()


Expand Down
2 changes: 1 addition & 1 deletion CMake/Templates/OGREStatic.pc.in
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,6 @@ Name: OGRE (static lib)
Description: Object-Oriented Graphics Rendering Engine
Version: @OGRE_VERSION@
URL: http://www.ogre3d.org
Requires: freetype2, zziplib, x11, xt, xaw7, gl
Requires: freetype2, zziplib, gl, x11, xt, xaw7, wayland
Libs: -L${libdir} -L${plugindir} -lOgreMain@OGRE_LIB_SUFFIX@ @OGRE_ADDITIONAL_LIBS@
Cflags: -I${includedir} -I${includedir}/OGRE @OGRE_CFLAGS@
34 changes: 29 additions & 5 deletions Components/Bites/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ elseif(ANDROID)
endif()

cmake_dependent_option(OGRE_BITES_NATIVE_DIALOG "Provide a platform specific ConfigDialog implementation"
ON "NOT ANDROID;NOT EMSCRIPTEN;NOT APPLE_IOS;NOT WINDOWS_STORE;NOT WINDOWS_PHONE;NOT UNIX OR APPLE OR XAW_LIBRARY" OFF)
ON "NOT OGRE_GLSUPPORT_USE_WAYLAND;NOT ANDROID;NOT EMSCRIPTEN;NOT APPLE_IOS;NOT WINDOWS_STORE;NOT WINDOWS_PHONE;NOT UNIX OR APPLE OR XAW_LIBRARY" OFF)

if(NOT OGRE_BITES_NATIVE_DIALOG)
set_source_files_properties(src/OgreBitesConfigDialog.cpp PROPERTIES COMPILE_DEFINITIONS DISABLE_NATIVE_DIALOG)
Expand All @@ -134,14 +134,13 @@ elseif(APPLE)
set(RESOURCE_FILES "${CMAKE_CURRENT_SOURCE_DIR}/misc/ogrelogo.png")
source_group(Resources FILES ${RESOURCE_FILES})
set(DEPENDENCIES ${DEPENDENCIES} "-framework Cocoa")
elseif(UNIX AND XAW_LIBRARY)
elseif(UNIX AND XAW_LIBRARY AND NOT OGRE_GLSUPPORT_USE_WAYLAND)
list(APPEND SOURCES "${CMAKE_CURRENT_SOURCE_DIR}/src/OgreGLXConfigDialog.cpp")
list(APPEND DEPENDENCIES ${X11_Xt_LIB} ${XAW_LIBRARY})
install(FILES "${CMAKE_CURRENT_SOURCE_DIR}/misc/GLX_backdrop.png" DESTINATION "${OGRE_MEDIA_PATH}/../")
endif()

if(UNIX AND NOT APPLE)
# for WindowEventUtilities
if(UNIX AND NOT APPLE AND NOT OGRE_GLSUPPORT_USE_WAYLAND)
list(APPEND DEPENDENCIES ${X11_X11_LIB})
set(NATIVE_INCLUDES ${X11_Xlib_INCLUDE_PATH})
endif()
Expand Down Expand Up @@ -176,6 +175,10 @@ if(OGRE_STATIC AND APPLE AND OGRE_BUILD_PLUGIN_CG)
target_include_directories(OgreBites PUBLIC ${Cg_INCLUDE_DIRS})
endif()

if(OGRE_GLSUPPORT_USE_WAYLAND)
target_compile_definitions(OgreBites PRIVATE OGRE_WAYLAND)
endif()

if(SDL2_FOUND)
target_link_libraries(OgreBites PRIVATE SDL2::SDL2)
elseif(NOT EMSCRIPTEN)
Expand All @@ -187,6 +190,21 @@ generate_export_header(OgreBites
EXPORT_FILE_NAME ${PROJECT_BINARY_DIR}/include/OgreBitesPrerequisites.h)

if(Qt6_FOUND OR Qt5_FOUND)
set(_OgreBitesQt ON)
else()
set(_OgreBitesQt OFF)
endif()

if(OGRE_GLSUPPORT_USE_WAYLAND)
if(NOT TARGET Qt${QT_VERSION_MAJOR}::GuiPrivate)
set(_OgreBitesQt OFF)
else()
configure_file("${CMAKE_CURRENT_SOURCE_DIR}/include/OgreQtNativeinterface.h.in"
"${PROJECT_BINARY_DIR}/include_private/OgreQtNativeinterface.h" @ONLY)
endif()
endif()

if(_OgreBitesQt)
if(Qt6_FOUND)
qt6_wrap_cpp(MOC_SRC "${CMAKE_CURRENT_SOURCE_DIR}/include/OgreApplicationContextQt.h")
else()
Expand All @@ -196,10 +214,16 @@ if(Qt6_FOUND OR Qt5_FOUND)
add_library(OgreBitesQt ${OGRE_COMP_LIB_TYPE} ${MOC_SRC} "${CMAKE_CURRENT_SOURCE_DIR}/src/OgreApplicationContextQt.cpp")
set_target_properties(OgreBitesQt PROPERTIES VERSION ${OGRE_SOVERSION} SOVERSION ${OGRE_SOVERSION})
target_link_libraries(OgreBitesQt PUBLIC Qt${QT_VERSION_MAJOR}::Gui OgreBites)
if(OGRE_GLSUPPORT_USE_WAYLAND)
target_compile_definitions(OgreBitesQt PRIVATE OGRE_WAYLAND)
target_link_libraries(OgreBitesQt PRIVATE Qt${QT_VERSION_MAJOR}::GuiPrivate)
target_include_directories(OgreBitesQt PRIVATE
"$<BUILD_INTERFACE:${PROJECT_BINARY_DIR}/include_private>")
endif()
ogre_config_component(OgreBitesQt)
endif()

# install
# install
ogre_config_framework(OgreBites)
ogre_config_component(OgreBites)

Expand Down
2 changes: 2 additions & 0 deletions Components/Bites/include/OgreQtNativeinterface.h.in
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
#pragma once
#include <@QT_VERSION@/QtGui/qpa/qplatformnativeinterface.h>
27 changes: 26 additions & 1 deletion Components/Bites/src/OgreApplicationContextQt.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,10 @@
#include <QResizeEvent>
#include <QKeyEvent>

#ifdef OGRE_WAYLAND
#include "OgreQtNativeinterface.h"
#endif

namespace OgreBites
{
static Event convert(const QEvent* in)
Expand Down Expand Up @@ -129,8 +133,29 @@ namespace OgreBites
p.width = window->width();
p.height= window->height();

p.miscParams["externalWindowHandle"] = std::to_string(size_t(window->winId()));
if (QGuiApplication::platformName() != "wayland") {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Need to investigate whether other platform names may be relevant too.
https://github.com/qt/qtwayland/blob/dev/README

p.miscParams["externalWindowHandle"] = std::to_string(size_t(window->winId()));
}

if (QGuiApplication::platformName() == "wayland")
{
window->create(); // This must be called since window->winId() is not called.

#ifdef OGRE_WAYLAND

QPlatformNativeInterface *nativeInterface = QGuiApplication::platformNativeInterface();
if (!nativeInterface)
{
Ogre::LogManager::getSingleton().logMessage("[Qt] Native interface is nullptr!");
}

void* display = nativeInterface->nativeResourceForWindow("display", nullptr);
void* surface = nativeInterface->nativeResourceForWindow("surface", window);

p.miscParams["externalWlDisplay"] = Ogre::StringConverter::toString(size_t(display));
p.miscParams["externalWlSurface"] = Ogre::StringConverter::toString(size_t(surface));
#endif
}
if (!mWindows.empty())
{
// additional windows should reuse the context
Expand Down
12 changes: 11 additions & 1 deletion Components/Bites/src/OgreApplicationContextSDL.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,17 @@ NativeWindowPair ApplicationContextSDL::createWindow(const Ogre::String& name, O
p.miscParams["sdlwin"] = Ogre::StringConverter::toString(size_t(ret.native));

#if OGRE_PLATFORM == OGRE_PLATFORM_LINUX
p.miscParams["externalWindowHandle"] = Ogre::StringConverter::toString(size_t(wmInfo.info.x11.window));
if (wmInfo.subsystem == SDL_SYSWM_WAYLAND)
{
Ogre::LogManager::getSingleton().logMessage("[SDL] Creating Wayland window");
p.miscParams["externalWlDisplay"] = Ogre::StringConverter::toString(size_t(wmInfo.info.wl.display));
p.miscParams["externalWlSurface"] = Ogre::StringConverter::toString(size_t(wmInfo.info.wl.surface));
}
else if (wmInfo.subsystem == SDL_SYSWM_X11)
{
Ogre::LogManager::getSingleton().logMessage("[SDL] Creating X11 window");
p.miscParams["externalWindowHandle"] = Ogre::StringConverter::toString(size_t(wmInfo.info.x11.window));
}
#elif OGRE_PLATFORM == OGRE_PLATFORM_WIN32
p.miscParams["externalWindowHandle"] = Ogre::StringConverter::toString(size_t(wmInfo.info.win.window));
#elif OGRE_PLATFORM == OGRE_PLATFORM_APPLE
Expand Down
10 changes: 5 additions & 5 deletions Components/Bites/src/OgreWindowEventUtilities.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,8 @@ THE SOFTWARE.
# define NOMINMAX // required to stop windows.h messing up std::min
# endif
# include <windows.h>
#elif OGRE_PLATFORM == OGRE_PLATFORM_LINUX
#include <X11/Xlib.h>
#elif OGRE_PLATFORM == OGRE_PLATFORM_LINUX && !defined(OGRE_WAYLAND)
# include <X11/Xlib.h>
#endif

using namespace Ogre;
Expand All @@ -47,7 +47,7 @@ typedef std::multimap<RenderWindow*, WindowEventListener*> WindowEventListeners;
static WindowEventListeners _msListeners;
static RenderWindowList _msWindows;

#if OGRE_PLATFORM == OGRE_PLATFORM_LINUX
#if OGRE_PLATFORM == OGRE_PLATFORM_LINUX && !defined(OGRE_WAYLAND)
static void GLXProc( RenderWindow *win, const XEvent &event );
#endif

Expand Down Expand Up @@ -184,7 +184,7 @@ void WindowEventUtilities::messagePump()
TranslateMessage( &msg );
DispatchMessage( &msg );
}
#elif OGRE_PLATFORM == OGRE_PLATFORM_LINUX
#elif OGRE_PLATFORM == OGRE_PLATFORM_LINUX && !defined(OGRE_WAYLAND)
//GLX Message Pump
Display* xDisplay = 0; // same for all windows

Expand Down Expand Up @@ -240,7 +240,7 @@ void WindowEventUtilities::_removeRenderWindow(RenderWindow* window)
_msWindows.erase( i );
}

#if OGRE_PLATFORM == OGRE_PLATFORM_LINUX
#if OGRE_PLATFORM == OGRE_PLATFORM_LINUX && !defined(OGRE_WAYLAND)
//--------------------------------------------------------------------------------//
static void GLXProc( Ogre::RenderWindow *win, const XEvent &event )
{
Expand Down
2 changes: 2 additions & 0 deletions OgreMain/include/OgreRenderSystem.h
Original file line number Diff line number Diff line change
Expand Up @@ -385,6 +385,8 @@ namespace Ogre
| displayFrequency | Refresh rate in Hertz (e.g. 60, 75, 100) | Desktop vsync rate | Display frequency rate, for fullscreen mode | |
| externalWindowHandle | <ul><li>Win32: HWND as int<li>Linux: X11 Window as ulong<li>OSX: OgreGLView address as an integer. You can pass NSView or NSWindow too, but should perform OgreGLView callbacks into the Ogre manually<li>iOS: UIWindow address as an integer<li>Emscripten: canvas selector String ("#canvas")</ul> | 0 (none) | External window handle, for embedding the OGRE render in an existing window | |
| externalGLControl | true, false | false | Let the external window control OpenGL i.e. don't select a pixel format for the window, do not change v-sync and do not swap buffer. When set to true, the calling application is responsible of OpenGL initialization and buffer swapping. It should also create an OpenGL context for its own rendering, Ogre will create one for its use. Then the calling application must also enable Ogre OpenGL context before calling any Ogre function and restore its OpenGL context after these calls. | OpenGL |
| externalWlDisplay | wl_display address as an integer | 0 (none) | Wayland display connection | Linux |
| externalWlSurface | wl_surface address as an integer | 0 (none) | Wayland onscreen surface | Linux |
| currentGLContext | true, false | false | Use an externally created GL context. (Must be current) | OpenGL |
| minColourBufferSize | Positive integer (usually 16, 32) | 16 | Min total colour buffer size. See EGL_BUFFER_SIZE | OpenGL |
| windowProc | WNDPROC | DefWindowProc | function that processes window messages | Win 32 |
Expand Down
34 changes: 27 additions & 7 deletions RenderSystems/GLSupport/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@

if(EGL_FOUND)
cmake_dependent_option(OGRE_GLSUPPORT_USE_EGL "use EGL for GL Context Creation instead of GLX/ WGL" TRUE "NOT WIN32" FALSE)
cmake_dependent_option(OGRE_GLSUPPORT_USE_WAYLAND "use Wayland window manager" FALSE "UNIX;NOT APPLE;NOT EMSCRIPTEN;NOT ANDROID" FALSE)
endif()

if(ANDROID)
Expand Down Expand Up @@ -64,13 +65,26 @@ elseif (APPLE)
set(PLATFORM_LIBS "-framework AppKit" ${OPENGL_gl_LIBRARY})
elseif (UNIX)
if(OGRE_GLSUPPORT_USE_EGL)
file(GLOB PLATFORM_HEADERS "include/EGL/X11/*.h" "include/EGL/*.h")
file(GLOB PLATFORM_SOURCES "src/EGL/X11/*.cpp" "src/EGL/*.cpp" "src/X11/*.cpp")

set(NATIVE_INCLUDES
${CMAKE_CURRENT_SOURCE_DIR}/include/EGL
list(APPEND _EGL_HEADERS "include/EGL/*.h")
list(APPEND _EGL_SOURCES "src/EGL/*.cpp")
list(APPEND NATIVE_INCLUDES ${CMAKE_CURRENT_SOURCE_DIR}/include/EGL)
if(OGRE_GLSUPPORT_USE_WAYLAND)
list(APPEND _EGL_HEADERS "include/EGL/Wayland/*.h")
list(APPEND _EGL_SOURCES "src/EGL/Wayland/*.cpp")
list(APPEND NATIVE_INCLUDES
${CMAKE_CURRENT_SOURCE_DIR}/include/EGL/Wayland)
set(PLATFORM_LIBS ${EGL_LIBRARIES} PkgConfig::waylands)
else()
list(APPEND _EGL_HEADERS "include/EGL/X11/*.h")
list(APPEND _EGL_SOURCES "src/EGL/X11/*.cpp")
list(APPEND _EGL_SOURCES "src/X11/*.cpp")
list(APPEND NATIVE_INCLUDES
${CMAKE_CURRENT_SOURCE_DIR}/include/EGL/X11)
set(PLATFORM_LIBS ${X11_LIBRARIES} ${X11_Xrandr_LIB} ${EGL_LIBRARIES})
set(PLATFORM_LIBS ${X11_LIBRARIES} ${X11_Xrandr_LIB} ${EGL_LIBRARIES})
endif()

file(GLOB PLATFORM_HEADERS ${_EGL_HEADERS})
file(GLOB PLATFORM_SOURCES ${_EGL_SOURCES})
else()
file(GLOB PLATFORM_HEADERS "include/GLX/*.h")
file(GLOB PLATFORM_SOURCES "src/GLX/*.cpp" "src/X11/*.cpp")
Expand All @@ -85,7 +99,9 @@ elseif (UNIX)

set(PLATFORM_LIBS ${X11_LIBRARIES} ${X11_Xrandr_LIB} ${OPENGL_glx_LIBRARY})
endif()
list(APPEND NATIVE_INCLUDES "${CMAKE_CURRENT_SOURCE_DIR}/src/X11/")
if(NOT OGRE_GLSUPPORT_USE_WAYLAND)
list(APPEND NATIVE_INCLUDES "${CMAKE_CURRENT_SOURCE_DIR}/src/X11/")
endif()
endif ()

file(GLOB GLSUPPORT_HEADERS "${CMAKE_CURRENT_SOURCE_DIR}/include/*.h")
Expand Down Expand Up @@ -116,6 +132,10 @@ target_include_directories(OgreGLSupport PUBLIC
"$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include/GLSL>"
PRIVATE "$<BUILD_INTERFACE:${NATIVE_INCLUDES}>")

if(OGRE_GLSUPPORT_USE_WAYLAND)
target_compile_definitions(OgreGLSupport PRIVATE OGRE_WAYLAND)
endif()

set_property(TARGET OgreGLSupport PROPERTY POSITION_INDEPENDENT_CODE ON)
generate_export_header(OgreGLSupport
EXPORT_MACRO_NAME _OgreGLExport
Expand Down
11 changes: 11 additions & 0 deletions RenderSystems/GLSupport/include/EGL/OgreEGLSupport.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,17 @@ THE SOFTWARE.
#ifndef __EGLSupport_H__
#define __EGLSupport_H__

#ifndef OGRE_WAYLAND
// Tell EGL that we are using X11 (to select the appropriate definitions)
#define USE_X11
#else
// Tell EGL to not include X11 headers
#define EGL_NO_X11
// Tell EGL that we are using wayland
#ifndef WL_EGL_PLATFORM
#define WL_EGL_PLATFORM 1
#endif
#endif

#include "OgreGLNativeSupport.h"
#include <EGL/egl.h>
Expand Down
Loading