From 140e990ab45e9ef6b8e3c405228eae72a5514f1c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Branimir=20Karad=C5=BEi=C4=87?= Date: Sun, 24 Aug 2014 17:41:41 -0700 Subject: [PATCH] Added RaspberryPi platform. --- examples/common/entry/entry_x11.cpp | 353 ++++++++++++++++++++++++++++ include/bgfxplatform.c99.h | 2 +- include/bgfxplatform.h | 2 +- makefile | 13 +- premake/bgfx.lua | 2 +- premake/premake4.lua | 9 + src/bgfx.cpp | 2 +- src/config.h | 2 + src/glcontext_egl.cpp | 27 ++- src/glcontext_glx.cpp | 4 +- src/renderer_gl.h | 2 +- 11 files changed, 407 insertions(+), 11 deletions(-) create mode 100644 examples/common/entry/entry_x11.cpp diff --git a/examples/common/entry/entry_x11.cpp b/examples/common/entry/entry_x11.cpp new file mode 100644 index 000000000..4383dc6a7 --- /dev/null +++ b/examples/common/entry/entry_x11.cpp @@ -0,0 +1,353 @@ +/* + * Copyright 2011-2014 Branimir Karadzic. All rights reserved. + * License: http://www.opensource.org/licenses/BSD-2-Clause + */ + +#include "entry_p.h" + +#if ENTRY_CONFIG_USE_NATIVE && (BX_PLATFORM_FREEBSD || BX_PLATFORM_LINUX || BX_PLATFORM_RPI) + +#define XK_MISCELLANY +#define XK_LATIN1 +#include +#include // will include X11 which #defines None... Don't mess with order of includes. + +#undef None +#include +#include +#include // memset + +namespace entry +{ + static uint8_t s_translateKey[512]; + + static void initTranslateKey(uint16_t _xk, Key::Enum _key) + { + _xk += 256; + BX_CHECK(_xk < BX_COUNTOF(s_translateKey), "Out of bounds %d.", _xk); + s_translateKey[_xk&0x1ff] = (uint8_t)_key; + } + + Key::Enum fromXk(uint16_t _xk) + { + _xk += 256; + return 512 > _xk ? (Key::Enum)s_translateKey[_xk] : Key::None; + } + + struct MainThreadEntry + { + int m_argc; + char** m_argv; + + static int32_t threadFunc(void* _userData); + }; + + struct Context + { + Context() + : m_modifiers(Modifier::None) + , m_exit(false) + { + memset(s_translateKey, 0, sizeof(s_translateKey) ); + initTranslateKey(XK_Escape, Key::Esc); + initTranslateKey(XK_Return, Key::Return); + initTranslateKey(XK_Tab, Key::Tab); + initTranslateKey(XK_BackSpace, Key::Backspace); + initTranslateKey(XK_space, Key::Space); + initTranslateKey(XK_Up, Key::Up); + initTranslateKey(XK_Down, Key::Down); + initTranslateKey(XK_Left, Key::Left); + initTranslateKey(XK_Right, Key::Right); + initTranslateKey(XK_Page_Up, Key::PageUp); + initTranslateKey(XK_Page_Down, Key::PageUp); + initTranslateKey(XK_Home, Key::Home); + initTranslateKey(XK_KP_End, Key::End); + initTranslateKey(XK_Print, Key::Print); + initTranslateKey(XK_equal, Key::Plus); + initTranslateKey(XK_minus, Key::Minus); + initTranslateKey(XK_F1, Key::F1); + initTranslateKey(XK_F2, Key::F2); + initTranslateKey(XK_F3, Key::F3); + initTranslateKey(XK_F4, Key::F4); + initTranslateKey(XK_F5, Key::F5); + initTranslateKey(XK_F6, Key::F6); + initTranslateKey(XK_F7, Key::F7); + initTranslateKey(XK_F8, Key::F8); + initTranslateKey(XK_F9, Key::F9); + initTranslateKey(XK_F10, Key::F10); + initTranslateKey(XK_F11, Key::F11); + initTranslateKey(XK_F12, Key::F12); + initTranslateKey(XK_KP_Insert, Key::NumPad0); + initTranslateKey(XK_KP_End, Key::NumPad1); + initTranslateKey(XK_KP_Down, Key::NumPad2); + initTranslateKey(XK_KP_Page_Down, Key::NumPad3); + initTranslateKey(XK_KP_Left, Key::NumPad4); + initTranslateKey(XK_KP_Begin, Key::NumPad5); + initTranslateKey(XK_KP_Right, Key::NumPad6); + initTranslateKey(XK_KP_Home, Key::NumPad7); + initTranslateKey(XK_KP_Up, Key::NumPad8); + initTranslateKey(XK_KP_Page_Up, Key::NumPad9); + initTranslateKey('0', Key::Key0); + initTranslateKey('1', Key::Key1); + initTranslateKey('2', Key::Key2); + initTranslateKey('3', Key::Key3); + initTranslateKey('4', Key::Key4); + initTranslateKey('5', Key::Key5); + initTranslateKey('6', Key::Key6); + initTranslateKey('7', Key::Key7); + initTranslateKey('8', Key::Key8); + initTranslateKey('9', Key::Key9); + initTranslateKey('a', Key::KeyA); + initTranslateKey('b', Key::KeyB); + initTranslateKey('c', Key::KeyC); + initTranslateKey('d', Key::KeyD); + initTranslateKey('e', Key::KeyE); + initTranslateKey('f', Key::KeyF); + initTranslateKey('g', Key::KeyG); + initTranslateKey('h', Key::KeyH); + initTranslateKey('i', Key::KeyI); + initTranslateKey('j', Key::KeyJ); + initTranslateKey('k', Key::KeyK); + initTranslateKey('l', Key::KeyL); + initTranslateKey('m', Key::KeyM); + initTranslateKey('n', Key::KeyN); + initTranslateKey('o', Key::KeyO); + initTranslateKey('p', Key::KeyP); + initTranslateKey('q', Key::KeyQ); + initTranslateKey('r', Key::KeyR); + initTranslateKey('s', Key::KeyS); + initTranslateKey('t', Key::KeyT); + initTranslateKey('u', Key::KeyU); + initTranslateKey('v', Key::KeyV); + initTranslateKey('w', Key::KeyW); + initTranslateKey('x', Key::KeyX); + initTranslateKey('y', Key::KeyY); + initTranslateKey('z', Key::KeyZ); + } + + int32_t run(int _argc, char** _argv) + { + XInitThreads(); + m_display = XOpenDisplay(0); + + int32_t screen = DefaultScreen(m_display); + int32_t depth = DefaultDepth(m_display, screen); + Visual* visual = DefaultVisual(m_display, screen); + Window root = RootWindow(m_display, screen); + + XSetWindowAttributes windowAttrs; + memset(&windowAttrs, 0, sizeof(windowAttrs) ); + windowAttrs.background_pixmap = 0; + windowAttrs.border_pixel = 0; + windowAttrs.event_mask = 0 + | ButtonPressMask + | ButtonReleaseMask + | ExposureMask + | KeyPressMask + | KeyReleaseMask + | PointerMotionMask + | ResizeRedirectMask + | StructureNotifyMask + ; + + m_window = XCreateWindow(m_display + , root + , 0, 0 + , ENTRY_DEFAULT_WIDTH, ENTRY_DEFAULT_HEIGHT, 0, depth + , InputOutput + , visual + , CWBorderPixel|CWEventMask + , &windowAttrs + ); + + const char *wmDeleteWindowName = "WM_DELETE_WINDOW"; + Atom wmDeleteWindow; + XInternAtoms(m_display, (char **)&wmDeleteWindowName, 1, False, &wmDeleteWindow); + XSetWMProtocols(m_display, m_window, &wmDeleteWindow, 1); + + XMapWindow(m_display, m_window); + XStoreName(m_display, m_window, "BGFX"); + + bgfx::x11SetDisplayWindow(m_display, m_window); + + MainThreadEntry mte; + mte.m_argc = _argc; + mte.m_argv = _argv; + + bx::Thread thread; + thread.init(mte.threadFunc, &mte); + + while (!m_exit) + { + if (XPending(m_display) ) + { + XEvent event; + XNextEvent(m_display, &event); + + switch (event.type) + { + case Expose: + break; + + case ConfigureNotify: + break; + + case ClientMessage: + if((Atom)event.xclient.data.l[0] == wmDeleteWindow) + { + m_eventQueue.postExitEvent(); + } + break; + + case ButtonPress: + case ButtonRelease: + { + const XButtonEvent& xbutton = event.xbutton; + MouseButton::Enum mb; + switch (xbutton.button) + { + case Button1: mb = MouseButton::Left; break; + case Button2: mb = MouseButton::Middle; break; + case Button3: mb = MouseButton::Right; break; + default: mb = MouseButton::None; break; + } + + if (MouseButton::None != mb) + { + m_eventQueue.postMouseEvent(xbutton.x + , xbutton.y + , 0 + , mb + , event.type == ButtonPress + ); + } + } + break; + + case MotionNotify: + { + const XMotionEvent& xmotion = event.xmotion; + m_eventQueue.postMouseEvent(xmotion.x + , xmotion.y + , 0 + ); + } + break; + + case KeyPress: + case KeyRelease: + { + XKeyEvent& xkey = event.xkey; + KeySym keysym = XLookupKeysym(&xkey, 0); + switch (keysym) + { + case XK_Meta_L: setModifier(Modifier::LeftMeta, KeyPress == event.type); break; + case XK_Meta_R: setModifier(Modifier::RightMeta, KeyPress == event.type); break; + case XK_Control_L: setModifier(Modifier::LeftCtrl, KeyPress == event.type); break; + case XK_Control_R: setModifier(Modifier::RightCtrl, KeyPress == event.type); break; + case XK_Shift_L: setModifier(Modifier::LeftShift, KeyPress == event.type); break; + case XK_Shift_R: setModifier(Modifier::RightShift, KeyPress == event.type); break; + case XK_Alt_L: setModifier(Modifier::LeftAlt, KeyPress == event.type); break; + case XK_Alt_R: setModifier(Modifier::RightAlt, KeyPress == event.type); break; + + default: + { + Key::Enum key = fromXk(keysym); + if (Key::None != key) + { + m_eventQueue.postKeyEvent(key, m_modifiers, KeyPress == event.type); + } + } + break; + } + } + break; + + case ResizeRequest: + { + const XResizeRequestEvent& xresize = event.xresizerequest; + XResizeWindow(m_display, m_window, xresize.width, xresize.height); + } + break; + } + } + } + + thread.shutdown(); + + XUnmapWindow(m_display, m_window); + XDestroyWindow(m_display, m_window); + + return EXIT_SUCCESS; + } + + void setModifier(Modifier::Enum _modifier, bool _set) + { + m_modifiers &= ~_modifier; + m_modifiers |= _set ? _modifier : 0; + } + + uint8_t m_modifiers; + Display* m_display; + Window m_window; + bool m_exit; + + EventQueue m_eventQueue; + }; + + static Context s_ctx; + + int32_t MainThreadEntry::threadFunc(void* _userData) + { + MainThreadEntry* self = (MainThreadEntry*)_userData; + int32_t result = main(self->m_argc, self->m_argv); + s_ctx.m_exit = true; + return result; + } + + const Event* poll() + { + return s_ctx.m_eventQueue.poll(); + } + + void release(const Event* _event) + { + s_ctx.m_eventQueue.release(_event); + } + + void setWindowSize(uint32_t _width, uint32_t _height) + { + XResizeRequestEvent ev; + ev.type = ResizeRequest; + ev.serial = 0; + ev.send_event = true; + ev.display = s_ctx.m_display; + ev.window = s_ctx.m_window; + ev.width = (int)_width; + ev.height = (int)_height; + XSendEvent(s_ctx.m_display, s_ctx.m_window, false, ResizeRedirectMask, (XEvent*)&ev); + } + + void setWindowTitle(const char* _title) + { + BX_UNUSED(_title); + } + + void toggleWindowFrame() + { + } + + void setMouseLock(bool _lock) + { + BX_UNUSED(_lock); + } + +} // namespace entry + +int main(int _argc, char** _argv) +{ + using namespace entry; + return s_ctx.run(_argc, _argv); +} + +#endif // ENTRY_CONFIG_USE_NATIVE && (BX_PLATFORM_FREEBSD || BX_PLATFORM_LINUX || BX_PLATFORM_RPI) diff --git a/include/bgfxplatform.c99.h b/include/bgfxplatform.c99.h index b4f758bcc..7ffeb2e80 100644 --- a/include/bgfxplatform.c99.h +++ b/include/bgfxplatform.c99.h @@ -46,7 +46,7 @@ BGFX_C_API void bgfx_android_set_window(ANativeWindow* _window); */ BGFX_C_API void bgfx_ios_set_eagl_layer(void* _layer); -#elif BX_PLATFORM_LINUX || BX_PLATFORM_FREEBSD +#elif BX_PLATFORM_FREEBSD || BX_PLATFORM_LINUX || BX_PLATFORM_RPI # include /** diff --git a/include/bgfxplatform.h b/include/bgfxplatform.h index e06967b09..4f94d4f99 100755 --- a/include/bgfxplatform.h +++ b/include/bgfxplatform.h @@ -50,7 +50,7 @@ namespace bgfx } // namespace bgfx -#elif BX_PLATFORM_LINUX || BX_PLATFORM_FREEBSD +#elif BX_PLATFORM_FREEBSD || BX_PLATFORM_LINUX || BX_PLATFORM_RPI # include namespace bgfx diff --git a/makefile b/makefile index a6b631805..fbe892dab 100644 --- a/makefile +++ b/makefile @@ -29,11 +29,12 @@ all: $(PREMAKE4) --file=premake/premake4.lua --gcc=android-mips gmake $(PREMAKE4) --file=premake/premake4.lua --gcc=android-x86 gmake $(PREMAKE4) --file=premake/premake4.lua --gcc=asmjs gmake + $(PREMAKE4) --file=premake/premake4.lua --gcc=ios-arm gmake + $(PREMAKE4) --file=premake/premake4.lua --gcc=ios-simulator gmake $(PREMAKE4) --file=premake/premake4.lua --gcc=nacl gmake $(PREMAKE4) --file=premake/premake4.lua --gcc=nacl-arm gmake $(PREMAKE4) --file=premake/premake4.lua --gcc=pnacl gmake - $(PREMAKE4) --file=premake/premake4.lua --gcc=ios-arm gmake - $(PREMAKE4) --file=premake/premake4.lua --gcc=ios-simulator gmake + $(PREMAKE4) --file=premake/premake4.lua --gcc=rpi gmake .build/projects/gmake-android-arm: $(PREMAKE4) --file=premake/premake4.lua --gcc=android-arm gmake @@ -165,6 +166,14 @@ ios-simulator-release: .build/projects/gmake-ios-simulator make -R -C .build/projects/gmake-ios-simulator config=release ios-simulator: ios-simulator-debug ios-simulator-release +.build/projects/gmake-rpi: + $(PREMAKE4) --file=premake/premake4.lua --gcc=rpi gmake +rpi-debug: .build/projects/gmake-rpi + make -R -C .build/projects/gmake-rpi config=debug +rpi-release: .build/projects/gmake-rpi + make -R -C .build/projects/gmake-rpi config=release +rpi: rpi-debug rpi-release + rebuild-shaders: make -R -C examples rebuild diff --git a/premake/bgfx.lua b/premake/bgfx.lua index e8bdec1e0..fb62856de 100644 --- a/premake/bgfx.lua +++ b/premake/bgfx.lua @@ -53,7 +53,7 @@ function bgfxProject(_name, _uuid, _kind, _defines) "Cocoa.framework", } - configuration { "vs* or linux or mingw or xcode4 or osx or ios*" } + configuration { "vs* or linux or mingw or xcode4 or osx or ios* or rpi" } includedirs { --nacl has GLES2 headers modified... BGFX_DIR .. "3rdparty/khronos", diff --git a/premake/premake4.lua b/premake/premake4.lua index 64384e03c..592936c69 100644 --- a/premake/premake4.lua +++ b/premake/premake4.lua @@ -124,6 +124,15 @@ function exampleProject(_name, _uuid) "pthread", } + configuration { "rpi" } + links { + "X11", + "GLESv2", + "EGL", + "bcm_host", + "pthread", + } + configuration { "osx" } files { BGFX_DIR .. "examples/common/**.mm", diff --git a/src/bgfx.cpp b/src/bgfx.cpp index f93e128ff..dddadf097 100644 --- a/src/bgfx.cpp +++ b/src/bgfx.cpp @@ -3319,7 +3319,7 @@ BGFX_C_API void bgfx_ios_set_eagl_layer(void* _layer) bgfx::iosSetEaglLayer(_layer); } -#elif BX_PLATFORM_LINUX || BX_PLATFORM_FREEBSD +#elif BX_PLATFORM_FREEBSD || BX_PLATFORM_LINUX || BX_PLATFORM_RPI BGFX_C_API void bgfx_x11_set_display_window(::Display* _display, ::Window _window) { bgfx::x11SetDisplayWindow(_display, _window); diff --git a/src/config.h b/src/config.h index 4510f7b80..a0a1c13a7 100644 --- a/src/config.h +++ b/src/config.h @@ -47,6 +47,7 @@ || BX_PLATFORM_ANDROID \ || BX_PLATFORM_IOS \ || BX_PLATFORM_QNX \ + || BX_PLATFORM_RPI \ ? 1 : 0) # endif // BGFX_CONFIG_RENDERER_OPENGLES @@ -121,6 +122,7 @@ || BX_PLATFORM_NACL \ || BX_PLATFORM_OSX \ || BX_PLATFORM_QNX \ + || BX_PLATFORM_RPI \ || BX_PLATFORM_WINDOWS \ || BX_PLATFORM_XBOX360 \ ? 1 : 0) ) diff --git a/src/glcontext_egl.cpp b/src/glcontext_egl.cpp index 5a084f796..b22612a1f 100644 --- a/src/glcontext_egl.cpp +++ b/src/glcontext_egl.cpp @@ -5,11 +5,15 @@ #include "bgfx_p.h" -#if (BGFX_CONFIG_RENDERER_OPENGLES|BGFX_CONFIG_RENDERER_OPENGL) +#if (BGFX_CONFIG_RENDERER_OPENGLES || BGFX_CONFIG_RENDERER_OPENGL) # include "renderer_gl.h" # if BGFX_USE_EGL +# if BX_PLATFORM_RPI +# include +# endif // BX_PLATFORM_RPI + #ifndef EGL_CONTEXT_MAJOR_VERSION_KHR # define EGL_CONTEXT_MAJOR_VERSION_KHR EGL_CONTEXT_CLIENT_VERSION #endif // EGL_CONTEXT_MAJOR_VERSION_KHR @@ -94,8 +98,23 @@ EGL_IMPORT # define GL_IMPORT(_optional, _proto, _func, _import) _proto _func = NULL # include "glimports.h" +# if BX_PLATFORM_RPI + static ::Display* s_display; + static ::Window s_window; + + void x11SetDisplayWindow(::Display* _display, ::Window _window) + { + s_display = _display; + s_window = _window; + } +# endif // BX_PLATFORM_RPI + void GlContext::create(uint32_t _width, uint32_t _height) { +# if BX_PLATFORM_RPI + bcm_host_init(); +# endif // BX_PLATFORM_RPI + m_eglLibrary = eglOpen(); BX_UNUSED(_width, _height); @@ -183,6 +202,10 @@ EGL_IMPORT m_context = NULL; eglClose(m_eglLibrary); + +# if BX_PLATFORM_RPI + bcm_host_deinit(); +# endif // BX_PLATFORM_RPI } void GlContext::resize(uint32_t /*_width*/, uint32_t /*_height*/, bool _vsync) @@ -227,4 +250,4 @@ EGL_IMPORT } // namespace bgfx # endif // BGFX_USE_EGL -#endif // (BGFX_CONFIG_RENDERER_OPENGLES|BGFX_CONFIG_RENDERER_OPENGL) +#endif // (BGFX_CONFIG_RENDERER_OPENGLES || BGFX_CONFIG_RENDERER_OPENGL) diff --git a/src/glcontext_glx.cpp b/src/glcontext_glx.cpp index 7e030cab3..4e32417b2 100644 --- a/src/glcontext_glx.cpp +++ b/src/glcontext_glx.cpp @@ -5,7 +5,7 @@ #include "bgfx_p.h" -#if (BX_PLATFORM_LINUX || BX_PLATFORM_FREEBSD) && (BGFX_CONFIG_RENDERER_OPENGLES || BGFX_CONFIG_RENDERER_OPENGL) +#if (BX_PLATFORM_FREEBSD || BX_PLATFORM_LINUX) && (BGFX_CONFIG_RENDERER_OPENGLES || BGFX_CONFIG_RENDERER_OPENGL) # include "renderer_gl.h" # define GLX_GLXEXT_PROTOTYPES # include @@ -233,4 +233,4 @@ namespace bgfx } // namespace bgfx -#endif // (BX_PLATFORM_LINUX || BX_PLATFORM_FREEBSD) && (BGFX_CONFIG_RENDERER_OPENGLES || BGFX_CONFIG_RENDERER_OPENGL) +#endif // (BX_PLATFORM_FREEBSD || BX_PLATFORM_LINUX) && (BGFX_CONFIG_RENDERER_OPENGLES || BGFX_CONFIG_RENDERER_OPENGL) diff --git a/src/renderer_gl.h b/src/renderer_gl.h index c62b26db8..9ba6f7c5d 100644 --- a/src/renderer_gl.h +++ b/src/renderer_gl.h @@ -6,7 +6,7 @@ #ifndef BGFX_RENDERER_GL_H_HEADER_GUARD #define BGFX_RENDERER_GL_H_HEADER_GUARD -#define BGFX_USE_EGL (BGFX_CONFIG_RENDERER_OPENGLES && (BX_PLATFORM_ANDROID || BX_PLATFORM_EMSCRIPTEN || BX_PLATFORM_QNX || BX_PLATFORM_WINDOWS) ) +#define BGFX_USE_EGL (BGFX_CONFIG_RENDERER_OPENGLES && (BX_PLATFORM_ANDROID || BX_PLATFORM_EMSCRIPTEN || BX_PLATFORM_QNX || BX_PLATFORM_RPI || BX_PLATFORM_WINDOWS) ) #define BGFX_USE_WGL (BGFX_CONFIG_RENDERER_OPENGL && BX_PLATFORM_WINDOWS) #define BGFX_USE_GL_DYNAMIC_LIB (BX_PLATFORM_LINUX || BX_PLATFORM_OSX || BX_PLATFORM_WINDOWS)