// The renderer plugin's entry points, which SceneWindow.dll's createDLLRenderer looks up by name (exported // undecorated by plugin.def). For now the renderer is the pass-through: IMVU's Direct3D engine, wrapped. #include #include #include "log.hpp" #include "passthrough_engine.hpp" #include "renderer_process.hpp" #include "t5de/imvu/render_engine.hpp" namespace { using namespace t5de; // IMVU's Direct3D 9 engine, made by SceneWindow.dll (already loaded: it's what loads this plugin). Direct3D // rather than IMVU's OpenGL engine, which needs a real graphics driver: Direct3D also works on Windows' basic // display driver (virtual machines), and it's what most players use. imvu::SharedPtr create_imvu_engine(imvu::SharedPtr window) { HMODULE scene_window = GetModuleHandleW(L"SceneWindow.dll"); auto create = scene_window == nullptr ? nullptr : reinterpret_cast(GetProcAddress(scene_window, imvu::createRendererName)); if (create == nullptr) { log::info("SceneWindow.dll's createRenderer not found"); return {}; } return create(std::move(window), imvu::RendererType::Direct3D); } } // namespace extern "C" int __cdecl isRenderEngineSupported() { return 1; } // Returns a C++ object from a C-linkage function: fine here, the caller is C++ built for the same ABI. #pragma warning(suppress : 4190) extern "C" imvu::SharedPtr __cdecl createRenderEngine(imvu::SharedPtr window) { try { log::info("createRenderEngine: window {}", static_cast(window.get())); HWND hwnd = window ? window->getPlatformWindow() : nullptr; auto inner = create_imvu_engine(std::move(window)); if (!inner) { return {}; } auto renderer = hwnd != nullptr ? RendererProcess::start(hwnd) : nullptr; return imvu::SharedPtr( std::make_unique(std::move(inner), std::move(renderer))); } catch (const std::exception& e) { // Exceptions mustn't cross into IMVU's code (a different C++ runtime). log::info("createRenderEngine failed: {}", e.what()); return {}; } catch (...) { log::info("createRenderEngine failed"); return {}; } }