X-Git-Url: https://git.lizzy.rs/?a=blobdiff_plain;f=src%2Fclient%2Frenderingengine.cpp;h=8491dda04c6800a1af1fae50b904cd2703fea3b0;hb=a049e8267fabd101cb5c6528b3270214cb0647f0;hp=b18e91f6e35bc19b49086b8993fa17179bab45fa;hpb=b02effdab9b837bd2197ffe7f7f26e0e49fe8acd;p=dragonfireclient.git diff --git a/src/client/renderingengine.cpp b/src/client/renderingengine.cpp index b18e91f6e..8491dda04 100644 --- a/src/client/renderingengine.cpp +++ b/src/client/renderingengine.cpp @@ -19,7 +19,6 @@ with this program; if not, write to the Free Software Foundation, Inc., */ #include -#include #include "fontengine.h" #include "client.h" #include "clouds.h" @@ -35,6 +34,7 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "render/factory.h" #include "inputhandler.h" #include "gettext.h" +#include "../gui/guiSkin.h" #if !defined(_WIN32) && !defined(__APPLE__) && !defined(__ANDROID__) && \ !defined(SERVER) && !defined(__HAIKU__) @@ -46,12 +46,40 @@ with this program; if not, write to the Free Software Foundation, Inc., #include #endif -#ifdef __ANDROID__ +#ifdef _WIN32 +#include +#include +#endif + +#if ENABLE_GLES #include "filesys.h" #endif RenderingEngine *RenderingEngine::s_singleton = nullptr; + +static gui::GUISkin *createSkin(gui::IGUIEnvironment *environment, + gui::EGUI_SKIN_TYPE type, video::IVideoDriver *driver) +{ + gui::GUISkin *skin = new gui::GUISkin(type, driver); + + gui::IGUIFont *builtinfont = environment->getBuiltInFont(); + gui::IGUIFontBitmap *bitfont = nullptr; + if (builtinfont && builtinfont->getType() == gui::EGFT_BITMAP) + bitfont = (gui::IGUIFontBitmap*)builtinfont; + + gui::IGUISpriteBank *bank = 0; + skin->setFont(builtinfont); + + if (bitfont) + bank = bitfont->getSpriteBank(); + + skin->setSpriteBank(bank); + + return skin; +} + + RenderingEngine::RenderingEngine(IEventReceiver *receiver) { sanity_check(!s_singleton); @@ -63,7 +91,6 @@ RenderingEngine::RenderingEngine(IEventReceiver *receiver) // bpp, fsaa, vsync bool vsync = g_settings->getBool("vsync"); - u16 bits = g_settings->getU16("fullscreen_bpp"); u16 fsaa = g_settings->getU16("fsaa"); // stereo buffer required for pageflip stereo @@ -77,7 +104,7 @@ RenderingEngine::RenderingEngine(IEventReceiver *receiver) u32 i; for (i = 0; i != drivers.size(); i++) { if (!strcasecmp(driverstring.c_str(), - RenderingEngine::getVideoDriverName(drivers[i]))) { + RenderingEngine::getVideoDriverInfo(drivers[i]).name.c_str())) { driverType = drivers[i]; break; } @@ -89,39 +116,46 @@ RenderingEngine::RenderingEngine(IEventReceiver *receiver) } SIrrlichtCreationParameters params = SIrrlichtCreationParameters(); + if (g_logger.getTraceEnabled()) + params.LoggingLevel = irr::ELL_DEBUG; params.DriverType = driverType; params.WindowSize = core::dimension2d(screen_w, screen_h); - params.Bits = bits; params.AntiAlias = fsaa; params.Fullscreen = fullscreen; params.Stencilbuffer = false; params.Stereobuffer = stereo_buffer; params.Vsync = vsync; params.EventReceiver = receiver; - params.HighPrecisionFPU = g_settings->getBool("high_precision_fpu"); - params.ZBufferBits = 24; + params.HighPrecisionFPU = true; #ifdef __ANDROID__ - // clang-format off params.PrivateData = porting::app_global; - params.OGLES2ShaderPath = std::string(porting::path_user + DIR_DELIM + "media" + - DIR_DELIM + "Shaders" + DIR_DELIM).c_str(); - // clang-format on +#endif +#if ENABLE_GLES + // there is no standardized path for these on desktop + std::string rel_path = std::string("client") + DIR_DELIM + + "shaders" + DIR_DELIM + "Irrlicht"; + params.OGLES2ShaderPath = (porting::path_share + DIR_DELIM + rel_path + DIR_DELIM).c_str(); #endif m_device = createDeviceEx(params); driver = m_device->getVideoDriver(); s_singleton = this; + + auto skin = createSkin(m_device->getGUIEnvironment(), + gui::EGST_WINDOWS_METALLIC, driver); + m_device->getGUIEnvironment()->setSkin(skin); + skin->drop(); } RenderingEngine::~RenderingEngine() { core.reset(); - m_device->drop(); + m_device->closeDevice(); s_singleton = nullptr; } -v2u32 RenderingEngine::getWindowSize() const +v2u32 RenderingEngine::_getWindowSize() const { if (core) return core->getVirtualSize(); @@ -133,85 +167,35 @@ void RenderingEngine::setResizable(bool resize) m_device->setResizable(resize); } -bool RenderingEngine::print_video_modes() +void RenderingEngine::removeMesh(const scene::IMesh* mesh) { - IrrlichtDevice *nulldevice; - - bool vsync = g_settings->getBool("vsync"); - u16 fsaa = g_settings->getU16("fsaa"); - MyEventReceiver *receiver = new MyEventReceiver(); - - SIrrlichtCreationParameters params = SIrrlichtCreationParameters(); - params.DriverType = video::EDT_NULL; - params.WindowSize = core::dimension2d(640, 480); - params.Bits = 24; - params.AntiAlias = fsaa; - params.Fullscreen = false; - params.Stencilbuffer = false; - params.Vsync = vsync; - params.EventReceiver = receiver; - params.HighPrecisionFPU = g_settings->getBool("high_precision_fpu"); - - nulldevice = createDeviceEx(params); - - if (!nulldevice) { - delete receiver; - return false; - } - - std::cout << _("Available video modes (WxHxD):") << std::endl; - - video::IVideoModeList *videomode_list = nulldevice->getVideoModeList(); - - if (videomode_list != NULL) { - s32 videomode_count = videomode_list->getVideoModeCount(); - core::dimension2d videomode_res; - s32 videomode_depth; - for (s32 i = 0; i < videomode_count; ++i) { - videomode_res = videomode_list->getVideoModeResolution(i); - videomode_depth = videomode_list->getVideoModeDepth(i); - std::cout << videomode_res.Width << "x" << videomode_res.Height - << "x" << videomode_depth << std::endl; - } + m_device->getSceneManager()->getMeshCache()->removeMesh(mesh); +} - std::cout << _("Active video mode (WxHxD):") << std::endl; - videomode_res = videomode_list->getDesktopResolution(); - videomode_depth = videomode_list->getDesktopDepth(); - std::cout << videomode_res.Width << "x" << videomode_res.Height << "x" - << videomode_depth << std::endl; +void RenderingEngine::cleanupMeshCache() +{ + auto mesh_cache = m_device->getSceneManager()->getMeshCache(); + while (mesh_cache->getMeshCount() != 0) { + if (scene::IAnimatedMesh *mesh = mesh_cache->getMeshByIndex(0)) + mesh_cache->removeMesh(mesh); } - - nulldevice->drop(); - delete receiver; - - return videomode_list != NULL; } bool RenderingEngine::setupTopLevelWindow(const std::string &name) { // FIXME: It would make more sense for there to be a switch of some // sort here that would call the correct toplevel setup methods for - // the environment Minetest is running in but for now not deviating - // from the original pattern. - + // the environment Minetest is running in. + /* Setting Xorg properties for the top level window */ setupTopLevelXorgWindow(name); - /* Done with Xorg properties */ /* Setting general properties for the top level window */ verbosestream << "Client: Configuring general top level" << " window properties" << std::endl; - bool result = setWindowIcon(); - verbosestream << "Client: Finished configuring general top level" - << " window properties" - << std::endl; - /* Done with general properties */ - - // FIXME: setWindowIcon returns a bool result but it is unused. - // For now continue to return this result. return result; } @@ -223,11 +207,11 @@ void RenderingEngine::setupTopLevelXorgWindow(const std::string &name) Display *x11_dpl = reinterpret_cast(exposedData.OpenGLLinux.X11Display); if (x11_dpl == NULL) { warningstream << "Client: Could not find X11 Display in ExposedVideoData" - << std::endl; + << std::endl; return; } - verbosestream << "Client: Configuring Xorg specific top level" + verbosestream << "Client: Configuring X11-specific top level" << " window properties" << std::endl; @@ -244,45 +228,43 @@ void RenderingEngine::setupTopLevelXorgWindow(const std::string &name) // FIXME: In the future WMNormalHints should be set ... e.g see the // gtk/gdk code (gdk/x11/gdksurface-x11.c) for the setup_top_level - // method. But for now (as it would require some significant changes) - // leave the code as is. - + // method. But for now (as it would require some significant changes) + // leave the code as is. + // The following is borrowed from the above gdk source for setting top // level windows. The source indicates and the Xlib docs suggest that - // this will set the WM_CLIENT_MACHINE and WM_LOCAL_NAME. This will not - // set the WM_CLIENT_MACHINE to a Fully Qualified Domain Name (FQDN) which is + // this will set the WM_CLIENT_MACHINE and WM_LOCAL_NAME. This will not + // set the WM_CLIENT_MACHINE to a Fully Qualified Domain Name (FQDN) which is // required by the Extended Window Manager Hints (EWMH) spec when setting // the _NET_WM_PID (see further down) but running Minetest in an env // where the window manager is on another machine from Minetest (therefore // making the PID useless) is not expected to be a problem. Further // more, using gtk/gdk as the model it would seem that not using a FQDN is // not an issue for modern Xorg window managers. - + verbosestream << "Client: Setting Xorg window manager Properties" << std::endl; XSetWMProperties (x11_dpl, x11_win, NULL, NULL, NULL, 0, NULL, NULL, NULL); - // Set the _NET_WM_PID window property according to the EWMH spec. _NET_WM_PID - // (in conjunction with WM_CLIENT_MACHINE) can be used by window managers to - // force a shutdown of an application if it doesn't respond to the destroy - // window message. - + // Set the _NET_WM_PID window property according to the EWMH spec. _NET_WM_PID + // (in conjunction with WM_CLIENT_MACHINE) can be used by window managers to + // force a shutdown of an application if it doesn't respond to the destroy + // window message. + verbosestream << "Client: Setting Xorg _NET_WM_PID extened window manager property" << std::endl; Atom NET_WM_PID = XInternAtom(x11_dpl, "_NET_WM_PID", false); pid_t pid = getpid(); - infostream << "Client: PID is '" << static_cast(pid) << "'" - << std::endl; - XChangeProperty(x11_dpl, x11_win, NET_WM_PID, - XA_CARDINAL, 32, PropModeReplace, + XChangeProperty(x11_dpl, x11_win, NET_WM_PID, + XA_CARDINAL, 32, PropModeReplace, reinterpret_cast(&pid),1); // Set the WM_CLIENT_LEADER window property here. Minetest has only one - // window and that window will always be the leader. + // window and that window will always be the leader. verbosestream << "Client: Setting Xorg WM_CLIENT_LEADER property" << std::endl; @@ -292,13 +274,29 @@ void RenderingEngine::setupTopLevelXorgWindow(const std::string &name) XChangeProperty (x11_dpl, x11_win, WM_CLIENT_LEADER, XA_WINDOW, 32, PropModeReplace, reinterpret_cast(&x11_win), 1); - - verbosestream << "Client: Finished configuring Xorg specific top level" - << " window properties" - << std::endl; #endif } +#ifdef _WIN32 +static bool getWindowHandle(irr::video::IVideoDriver *driver, HWND &hWnd) +{ + const video::SExposedVideoData exposedData = driver->getExposedVideoData(); + + switch (driver->getDriverType()) { +#if ENABLE_GLES + case video::EDT_OGLES1: + case video::EDT_OGLES2: +#endif + case video::EDT_OPENGL: + hWnd = reinterpret_cast(exposedData.OpenGLWin32.HWnd); + break; + default: + return false; + } + + return true; +} +#endif bool RenderingEngine::setWindowIcon() { @@ -316,22 +314,9 @@ bool RenderingEngine::setWindowIcon() "-xorg-icon-128.png"); #endif #elif defined(_WIN32) - const video::SExposedVideoData exposedData = driver->getExposedVideoData(); HWND hWnd; // Window handle - - switch (driver->getDriverType()) { - case video::EDT_DIRECT3D8: - hWnd = reinterpret_cast(exposedData.D3D8.HWnd); - break; - case video::EDT_DIRECT3D9: - hWnd = reinterpret_cast(exposedData.D3D9.HWnd); - break; - case video::EDT_OPENGL: - hWnd = reinterpret_cast(exposedData.OpenGLWin32.HWnd); - break; - default: + if (!getWindowHandle(driver, hWnd)) return false; - } // Load the ICON from resource file const HICON hicon = LoadIcon(GetModuleHandle(NULL), @@ -442,11 +427,11 @@ bool RenderingEngine::setXorgWindowIconFromPath(const std::string &icon_file) Text will be removed when the screen is drawn the next time. Additionally, a progressbar can be drawn when percent is set between 0 and 100. */ -void RenderingEngine::_draw_load_screen(const std::wstring &text, +void RenderingEngine::draw_load_screen(const std::wstring &text, gui::IGUIEnvironment *guienv, ITextureSource *tsrc, float dtime, int percent, bool clouds) { - v2u32 screensize = RenderingEngine::get_instance()->getWindowSize(); + v2u32 screensize = getWindowSize(); v2s32 textsize(g_fontengine->getTextWidth(text), g_fontengine->getLineHeight()); v2s32 center(screensize.X / 2, screensize.Y / 2); @@ -514,7 +499,7 @@ void RenderingEngine::_draw_load_screen(const std::wstring &text, /* Draws the menu scene including (optional) cloud background. */ -void RenderingEngine::_draw_menu_scene(gui::IGUIEnvironment *guienv, +void RenderingEngine::draw_menu_scene(gui::IGUIEnvironment *guienv, float dtime, bool clouds) { bool cloud_menu_background = clouds && g_settings->getBool("menu_clouds"); @@ -531,89 +516,57 @@ void RenderingEngine::_draw_menu_scene(gui::IGUIEnvironment *guienv, get_video_driver()->endScene(); } -std::vector> RenderingEngine::getSupportedVideoModes() -{ - IrrlichtDevice *nulldevice = createDevice(video::EDT_NULL); - sanity_check(nulldevice); - - std::vector> mlist; - video::IVideoModeList *modelist = nulldevice->getVideoModeList(); - - s32 num_modes = modelist->getVideoModeCount(); - for (s32 i = 0; i != num_modes; i++) { - core::dimension2d mode_res = modelist->getVideoModeResolution(i); - u32 mode_depth = (u32)modelist->getVideoModeDepth(i); - mlist.emplace_back(mode_res.Width, mode_res.Height, mode_depth); - } - - nulldevice->drop(); - return mlist; -} - std::vector RenderingEngine::getSupportedVideoDrivers() { + // Only check these drivers. + // We do not support software and D3D in any capacity. + static const irr::video::E_DRIVER_TYPE glDrivers[4] = { + irr::video::EDT_NULL, + irr::video::EDT_OPENGL, + irr::video::EDT_OGLES1, + irr::video::EDT_OGLES2, + }; std::vector drivers; - for (int i = 0; i != irr::video::EDT_COUNT; i++) { - if (irr::IrrlichtDevice::isDriverSupported((irr::video::E_DRIVER_TYPE)i)) - drivers.push_back((irr::video::E_DRIVER_TYPE)i); + for (int i = 0; i < 4; i++) { + if (irr::IrrlichtDevice::isDriverSupported(glDrivers[i])) + drivers.push_back(glDrivers[i]); } return drivers; } -void RenderingEngine::_initialize(Client *client, Hud *hud) +void RenderingEngine::initialize(Client *client, Hud *hud) { const std::string &draw_mode = g_settings->get("3d_mode"); core.reset(createRenderingCore(draw_mode, m_device, client, hud)); core->initialize(); } -void RenderingEngine::_finalize() +void RenderingEngine::finalize() { core.reset(); } -void RenderingEngine::_draw_scene(video::SColor skycolor, bool show_hud, +void RenderingEngine::draw_scene(video::SColor skycolor, bool show_hud, bool show_minimap, bool draw_wield_tool, bool draw_crosshair) { core->draw(skycolor, show_hud, show_minimap, draw_wield_tool, draw_crosshair); } -const char *RenderingEngine::getVideoDriverName(irr::video::E_DRIVER_TYPE type) +const VideoDriverInfo &RenderingEngine::getVideoDriverInfo(irr::video::E_DRIVER_TYPE type) { - static const char *driver_ids[] = { - "null", - "software", - "burningsvideo", - "direct3d8", - "direct3d9", - "opengl", - "ogles1", - "ogles2", + static const std::unordered_map driver_info_map = { + {(int)video::EDT_NULL, {"null", "NULL Driver"}}, + {(int)video::EDT_OPENGL, {"opengl", "OpenGL"}}, + {(int)video::EDT_OGLES1, {"ogles1", "OpenGL ES1"}}, + {(int)video::EDT_OGLES2, {"ogles2", "OpenGL ES2"}}, }; - - return driver_ids[type]; -} - -const char *RenderingEngine::getVideoDriverFriendlyName(irr::video::E_DRIVER_TYPE type) -{ - static const char *driver_names[] = { - "NULL Driver", - "Software Renderer", - "Burning's Video", - "Direct3D 8", - "Direct3D 9", - "OpenGL", - "OpenGL ES1", - "OpenGL ES2", - }; - - return driver_names[type]; + return driver_info_map.at((int)type); } #ifndef __ANDROID__ -#ifdef XORG_USED +#if defined(XORG_USED) static float calcDisplayDensity() { @@ -648,12 +601,42 @@ float RenderingEngine::getDisplayDensity() return cached_display_density; } -#else // XORG_USED +#elif defined(_WIN32) + + +static float calcDisplayDensity(irr::video::IVideoDriver *driver) +{ + HWND hWnd; + if (getWindowHandle(driver, hWnd)) { + HDC hdc = GetDC(hWnd); + float dpi = GetDeviceCaps(hdc, LOGPIXELSX); + ReleaseDC(hWnd, hdc); + return dpi / 96.0f; + } + + /* return manually specified dpi */ + return g_settings->getFloat("screen_dpi") / 96.0f; +} + +float RenderingEngine::getDisplayDensity() +{ + static bool cached = false; + static float display_density; + if (!cached) { + display_density = calcDisplayDensity(get_video_driver()); + cached = true; + } + return display_density; +} + +#else + float RenderingEngine::getDisplayDensity() { return g_settings->getFloat("screen_dpi") / 96.0; } -#endif // XORG_USED + +#endif v2u32 RenderingEngine::getDisplaySize() {