diff --git a/.cppcheck.supp b/.cppcheck.supp index 0fbb2a38f1..c3439e05fc 100644 --- a/.cppcheck.supp +++ b/.cppcheck.supp @@ -8,6 +8,10 @@ unknownMacro *:external/cxxopts/cxxopts.hpp *:external/dmon/dmon.h +// function returning a function +*:library/testing/TestSDKExternalWindowGLFW.cxx +*:library/testing/TestSDKExternalWindowQT.cxx + // specific checks knownConditionTrueFalse:library/testing/TestSDKImage.cxx knownConditionTrueFalse:library/testing/TestSDKImageDeprecated.cxx diff --git a/.github/actions/generic-ci/action.yml b/.github/actions/generic-ci/action.yml index 51bd08989e..512c9b4cc2 100644 --- a/.github/actions/generic-ci/action.yml +++ b/.github/actions/generic-ci/action.yml @@ -174,6 +174,7 @@ runs: -DF3D_PLUGIN_BUILD_USD=${{ inputs.optional_deps_label == 'optional-deps' && 'ON' || 'OFF' }} -DF3D_PLUGIN_BUILD_VDB=${{ matrix.vtk_version != 'v9.2.6' && (runner.os != 'Windows' || matrix.vtk_version != 'v9.3.1') && inputs.optional_deps_label == 'optional-deps' && 'ON' || 'OFF' }} -DF3D_STRICT_BUILD=ON + -DF3D_TESTING_ENABLE_ONSCREEN_TESTS=${{ inputs.egl_label == 'egl' && 'OFF' || 'ON' }} -DF3D_WINDOWS_GUI=ON ${{ runner.os == 'Windows' && '-Ax64 -DCMAKE_MSVC_RUNTIME_LIBRARY=MultiThreadedDLL' || null }} ${{ runner.os == 'macOS' && '-DCMAKE_OSX_DEPLOYMENT_TARGET=10.15' || null }} diff --git a/.github/actions/vtk-install-dep/action.yml b/.github/actions/vtk-install-dep/action.yml index 7707876a49..a47d6149af 100644 --- a/.github/actions/vtk-install-dep/action.yml +++ b/.github/actions/vtk-install-dep/action.yml @@ -86,7 +86,6 @@ runs: -DVTKOSPRAY_ENABLE_DENOISER=ON -DVTK_BUILD_TESTING=OFF -DVTK_DEBUG_LEAKS=ON - -DVTK_DEFAULT_RENDER_WINDOW_HEADLESS=${{ inputs.egl_label == 'egl' && 'ON' || 'OFF' }} -DVTK_ENABLE_LOGGING=OFF -DVTK_ENABLE_REMOTE_MODULES=OFF -DVTK_ENABLE_WRAPPING=OFF @@ -116,7 +115,6 @@ runs: -DVTK_MODULE_ENABLE_VTK_RenderingRayTracing=${{ inputs.raytracing_label == 'raytracing' && 'YES' || 'DEFAULT' }} -DVTK_MODULE_ENABLE_VTK_RenderingVolumeOpenGL2=YES -DVTK_MODULE_ENABLE_VTK_TestingCore=YES - -DVTK_OPENGL_HAS_EGL=${{ inputs.egl_label == 'egl' && 'ON' || 'OFF' }} -DVTK_SMP_IMPLEMENTATION_TYPE=TBB -DVTK_VERSIONED_INSTALL=OFF ${{ runner.os == 'macOS' && '-DCMAKE_OSX_DEPLOYMENT_TARGET=10.15' || null }} diff --git a/.github/actions/vtk_commit_sha b/.github/actions/vtk_commit_sha index 518ad1fd17..b06e36f176 100644 --- a/.github/actions/vtk_commit_sha +++ b/.github/actions/vtk_commit_sha @@ -1 +1 @@ -6a898fd91da30d3ff903416bf856f0d1cea82cdf +b300f41d8e0111e70f9c8844f587df8d8feeaec9 diff --git a/CMakeLists.txt b/CMakeLists.txt index 9544a84d9e..103709c2c6 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -62,6 +62,7 @@ option(F3D_USE_EXTERNAL_CXXOPTS "Use external cxxopts dependency" OFF) option(F3D_USE_EXTERNAL_NLOHMANN_JSON "Use external nlohmann_json dependency" OFF) option(F3D_USE_EXTERNAL_DMON "Use external dmon dependency" OFF) +find_package(OpenGL REQUIRED COMPONENTS OpenGL EGL GLX) if (F3D_USE_EXTERNAL_CXXOPTS) find_package(cxxopts REQUIRED) endif () @@ -99,14 +100,19 @@ find_package(VTK 9.0 REQUIRED RenderingVolumeOpenGL2 TestingCore jsoncpp - opengl OPTIONAL_COMPONENTS + opengl IOExodus IOOpenVDB RenderingExternal RenderingRayTracing) message(STATUS "VTK ${VTK_VERSION} found") +if(VTK_VERSION VERSION_LESS 9.3.20240914) + # Not optional before + find_package(VTK 9.0 REQUIRED COMPONENTS opengl) +endif() + # Shared options between application and library include(GNUInstallDirs) cmake_dependent_option(F3D_WINDOWS_GUI "Build a non-console Win32 application" ON "WIN32" OFF) @@ -184,6 +190,7 @@ list(APPEND f3d_link_options_public ${f3d_sanitizer_link_options}) option(BUILD_TESTING "Build the tests" OFF) cmake_dependent_option(F3D_TESTING_ENABLE_RENDERING_TESTS "Enable rendering tests" ON "BUILD_TESTING" OFF) cmake_dependent_option(F3D_TESTING_ENABLE_LONG_TIMEOUT_TESTS "Enable long timeout tests" OFF "BUILD_TESTING" OFF) +cmake_dependent_option(F3D_TESTING_ENABLE_ONSCREEN_TESTS "Enable test that require onscreen rendering" ON "F3D_TESTING_ENABLE_RENDERING_TESTS" OFF) if(BUILD_TESTING) enable_testing() endif() diff --git a/application/CMakeLists.txt b/application/CMakeLists.txt index be09595465..63a1c9da6f 100644 --- a/application/CMakeLists.txt +++ b/application/CMakeLists.txt @@ -106,9 +106,11 @@ if (F3D_MODULE_EXR) target_compile_definitions(f3d PRIVATE F3D_MODULE_EXR) endif () +if(VTK_VERSION VERSION_LESS 9.3.20240914) # Headless EGL build -if (VTK_OPENGL_HAS_EGL) - target_compile_definitions(f3d PRIVATE F3D_HEADLESS_BUILD) + if (VTK_OPENGL_HAS_EGL) + target_compile_definitions(f3d PRIVATE F3D_HEADLESS_BUILD) + endif () endif () # F3D_STRICT_BUILD diff --git a/application/testing/CMakeLists.txt b/application/testing/CMakeLists.txt index d4ab68045f..9493f3446e 100644 --- a/application/testing/CMakeLists.txt +++ b/application/testing/CMakeLists.txt @@ -369,6 +369,11 @@ f3d_test(NAME TestVerboseAnimationWrongAnimationTimeLow DATA BoxAnimated.gltf AR # Test exit hotkey f3d_test(NAME TestInteractionSimpleExit DATA cow.vtp REGEXP "Interactor has been stopped" INTERACTION NO_BASELINE) #Escape; +if(UNIX AND NOT APPLE AND VTK_VERSION VERSION_GREATER_EQUAL 9.3.20240914) + f3d_test(NAME TestInteractionSimpleExitHeadless DATA cow.vtp REGEXP "Interactor has been stopped" INTERACTION NO_BASELINE) #Escape; + set_tests_properties(f3d::TestInteractionSimpleExitHeadless PROPERTIES ENVIRONMENT "DISPLAY=") +endif() + # No alternative baseline supports in F3D if(F3D_MODULE_RAYTRACING) f3d_test(NAME TestInteractionCheatsheetRaytracing DATA cow.vtp INTERACTION) #H @@ -981,15 +986,17 @@ if(NOT F3D_MACOS_BUNDLE) endif() endif() +# TODO VTK_VERSION # Watch testing require onscreen rendering -if(NOT VTK_OPENGL_HAS_EGL) - if(UNIX) - set(_f3d_os_script_ext "sh") - set(_f3d_os_script_exec "") - elseif(WIN32) - set(_f3d_os_script_ext "ps1") - find_program(_f3d_os_script_exec NAMES pwsh powershell) - endif() +if(UNIX) + set(_f3d_os_script_ext "sh") + set(_f3d_os_script_exec "") +elseif(WIN32) + set(_f3d_os_script_ext "ps1") + find_program(_f3d_os_script_exec NAMES pwsh powershell) +endif() + +if(F3D_TESTING_ENABLE_ONSCREEN_TESTS) # Custom bash/pwsh test for testing watch option add_test (NAME f3d::TestWatch COMMAND ${_f3d_os_script_exec} ${CMAKE_CURRENT_SOURCE_DIR}/test_watch.${_f3d_os_script_ext} $ ${F3D_SOURCE_DIR}/testing/data ${CMAKE_BINARY_DIR}/Testing/Temporary) set_tests_properties(f3d::TestWatch PROPERTIES RUN_SERIAL TRUE) diff --git a/library/CMakeLists.txt b/library/CMakeLists.txt index e18be8807e..f33a19e84c 100644 --- a/library/CMakeLists.txt +++ b/library/CMakeLists.txt @@ -166,7 +166,7 @@ configure_file( # libf3d links with the static plugins. list(TRANSFORM F3D_STATIC_PLUGIN_TARGETS PREPEND "f3d-plugin-") -target_link_libraries(libf3d PRIVATE ${F3D_VTK_MODULES} ${F3D_STATIC_PLUGIN_TARGETS}) +target_link_libraries(libf3d PRIVATE ${F3D_VTK_MODULES} ${F3D_STATIC_PLUGIN_TARGETS} OpenGL::GLX OpenGL::EGL) target_compile_options(libf3d PUBLIC ${f3d_compile_options_public} PRIVATE ${f3d_compile_options_private}) target_link_options(libf3d PUBLIC ${f3d_link_options_public}) diff --git a/library/private/window_impl.h b/library/private/window_impl.h index 43da739a42..b93ccc4aa6 100644 --- a/library/private/window_impl.h +++ b/library/private/window_impl.h @@ -30,8 +30,11 @@ class window_impl : public window * Create the internal vtkRenderWindow using the offscreen param * and store option ref for later usage */ - window_impl(const options& options, Type type); + window_impl(const options& options, Type type, + F3DOpenGLLoaderFunction loader, void* openglContext = nullptr); + void initializeExternal( + f3d::window::F3DOpenGLLoaderFunction loader, void* openglContext = nullptr) override; /** * Default destructor */ diff --git a/library/public/engine.h b/library/public/engine.h index 9503e9bdb0..befc2d5f2f 100644 --- a/library/public/engine.h +++ b/library/public/engine.h @@ -11,6 +11,7 @@ #include #include #include +#include namespace f3d { @@ -56,7 +57,14 @@ class F3D_EXPORT engine * Throw a no_window_exception when using a Using window::Type::EXTERNAL without the right cmake * option. */ - explicit engine(window::Type windowType = window::Type::NATIVE); + engine(window::Type windowType = window::Type::NATIVE, window::F3DOpenGLLoaderFunction loader = {}, void* openglContext = nullptr); + + static std::shared_ptr createNative(); + static std::shared_ptr createNativeOffscreen(); + static std::shared_ptr createNone(); + static std::shared_ptr createExternal(window::F3DOpenGLLoaderFunction loader = {}, void* openglContext = nullptr); + static std::shared_ptr createExternalGLX(); + static std::shared_ptr createExternalEGL(); /** * Engine destructor, delete all object instances as well. @@ -214,6 +222,7 @@ class F3D_EXPORT engine engine(engine&& opt) = delete; engine& operator=(const engine& opt) = delete; engine& operator=(engine&& opt) = delete; + }; } diff --git a/library/public/window.h b/library/public/window.h index de4cbbf748..c2605b356f 100644 --- a/library/public/window.h +++ b/library/public/window.h @@ -41,6 +41,11 @@ class F3D_EXPORT window */ virtual Type getType() = 0; + typedef void (*F3DOpenGLAPIProc)(); + typedef F3DOpenGLAPIProc (*F3DOpenGLLoaderFunction)(void* userptr, const char* name); + virtual void initializeExternal( + F3DOpenGLLoaderFunction loader, void* openglContext = nullptr) = 0; + /** * Get the camera provided by the window. */ diff --git a/library/src/engine.cxx b/library/src/engine.cxx index da76189c82..ede5482119 100644 --- a/library/src/engine.cxx +++ b/library/src/engine.cxx @@ -21,6 +21,9 @@ #include +#include +#include + namespace f3d { class engine::internals @@ -33,7 +36,57 @@ class engine::internals }; //---------------------------------------------------------------------------- -engine::engine(window::Type windowType) +std::shared_ptr engine::createNative() +{ + return std::make_shared(window::Type::NATIVE); +} + +//---------------------------------------------------------------------------- +std::shared_ptr engine::createNativeOffscreen() +{ + return std::make_shared(window::Type::NATIVE_OFFSCREEN); +} + +//---------------------------------------------------------------------------- +std::shared_ptr engine::createNone() +{ + return std::make_shared(window::Type::NONE); +} + +//---------------------------------------------------------------------------- +std::shared_ptr engine::createExternal(window::F3DOpenGLLoaderFunction loader, void* openglContext) +{ + return std::make_shared(window::Type::EXTERNAL, loader, openglContext); +} + +//---------------------------------------------------------------------------- +std::shared_ptr engine::createExternalGLX() +{ + auto loadFunc = [](void*, const char* name) -> f3d::window::F3DOpenGLAPIProc { + if (name) + { + return glXGetProcAddress((const GLubyte*)name); + } + return nullptr; + }; + return std::make_shared(window::Type::EXTERNAL); +} + +//---------------------------------------------------------------------------- +std::shared_ptr engine::createExternalEGL() +{ + auto loadFunc = [](void*, const char* name) -> f3d::window::F3DOpenGLAPIProc { + if (name) + { + return eglGetProcAddress(name); + } + return nullptr; + }; + return std::make_shared(window::Type::EXTERNAL, loadFunc); +} + +//---------------------------------------------------------------------------- +engine::engine(window::Type windowType, window::F3DOpenGLLoaderFunction loader, void* openglContext) : Internals(new engine::internals) { // Ensure all lib initialization is done (once) @@ -58,7 +111,7 @@ engine::engine(window::Type windowType) this->Internals->Options = std::make_unique(); this->Internals->Window = - std::make_unique(*this->Internals->Options, windowType); + std::make_unique(*this->Internals->Options, windowType, loader, openglContext); this->Internals->Window->SetCachePath(cachePath); this->Internals->Loader = diff --git a/library/src/interactor_impl.cxx b/library/src/interactor_impl.cxx index 34a4fa6fb8..38d56fc323 100644 --- a/library/src/interactor_impl.cxx +++ b/library/src/interactor_impl.cxx @@ -502,7 +502,18 @@ class interactor_impl::internals void StopInteractor() { this->VTKInteractor->RemoveObservers(vtkCommand::TimerEvent); - this->VTKInteractor->ExitCallback(); + + vtkRenderWindow* renWin = this->Window.GetRenderWindow(); + bool usingNative = renWin->IsA("vtkWin32OpenGLRenderWindow") || + renWin->IsA("vtkCocoaRenderWindow") || renWin->IsA("vtkXOpenGLRenderWindow"); + if (usingNative) + { + this->VTKInteractor->ExitCallback(); + } + else + { + this->VTKInteractor->SetDone(true); + } } /** diff --git a/library/src/window_impl.cxx b/library/src/window_impl.cxx index 1f056db012..2bc41b96dc 100644 --- a/library/src/window_impl.cxx +++ b/library/src/window_impl.cxx @@ -14,6 +14,7 @@ #include #include #include +#include #include #include #include @@ -150,7 +151,7 @@ class window_impl::internals }; //---------------------------------------------------------------------------- -window_impl::window_impl(const options& options, Type type) +window_impl::window_impl(const options& options, Type type, F3DOpenGLLoaderFunction loader, void* openglContext) : Internals(std::make_unique(options)) { this->Internals->WindowType = type; @@ -161,7 +162,10 @@ window_impl::window_impl(const options& options, Type type) else if (type == Type::EXTERNAL) { #if F3D_MODULE_EXTERNAL_RENDERING - this->Internals->RenWin = vtkSmartPointer::New(); + vtkNew extWin; + extWin->AutomaticWindowPositionAndResizeOff(); + this->Internals->RenWin = extWin; + this->initializeExternal(loader, openglContext); #else throw engine::no_window_exception( "Window type is external but F3D_MODULE_EXTERNAL_RENDERING is not enabled"); @@ -194,6 +198,18 @@ window_impl::Type window_impl::getType() return this->Internals->WindowType; } +//---------------------------------------------------------------------------- +void window_impl::initializeExternal( + [[maybe_unused]] F3DOpenGLLoaderFunction loader, [[maybe_unused]] void* openglContext) +{ + // Option to add default initialization? TODO +#if VTK_VERSION_NUMBER >= VTK_VERSION_CHECK(9, 3, 20240914) + vtkOpenGLRenderWindow::SafeDownCast(this->Internals->RenWin) + ->SetOpenGLSymbolLoader(loader, openglContext); + vtkOpenGLRenderWindow::SafeDownCast(this->Internals->RenWin)->vtkOpenGLRenderWindow::OpenGLInit(); +#endif +} + //---------------------------------------------------------------------------- camera& window_impl::getCamera() { diff --git a/library/testing/CMakeLists.txt b/library/testing/CMakeLists.txt index 1e5470e916..e5c2ea1376 100644 --- a/library/testing/CMakeLists.txt +++ b/library/testing/CMakeLists.txt @@ -47,14 +47,16 @@ configure_file("${F3D_SOURCE_DIR}/testing/recordings/TestSDKInteractorDropFullSc "${CMAKE_BINARY_DIR}/TestSDKInteractorDropFullScene.log") # world.obj; S # External window tests -if(F3D_MODULE_EXTERNAL_RENDERING AND NOT VTK_OPENGL_HAS_EGL) - find_package(glfw3 QUIET) +# TODO better control of deps +if(F3D_MODULE_EXTERNAL_RENDERING AND F3D_TESTING_ENABLE_ONSCREEN_TESTS) + find_package(glfw3) if(glfw3_FOUND) list(APPEND libf3dSDKTests_list TestSDKExternalWindowGLFW.cxx + TestSDKExternalWindowGLX.cxx ) endif() - find_package(Qt5 QUIET COMPONENTS OpenGL) + find_package(Qt5 COMPONENTS OpenGL) if(Qt5_FOUND) list(APPEND libf3dSDKTests_list TestSDKExternalWindowQT.cxx @@ -123,7 +125,7 @@ target_link_libraries(libf3dSDKTests libf3d) if(glfw3_FOUND) # external window test using glfw - target_link_libraries(libf3dSDKTests glfw) + target_link_libraries(libf3dSDKTests glfw OpenGL::GLX X11) endif() if(Qt5_FOUND) diff --git a/library/testing/TestSDKExternalWindowGLFW.cxx b/library/testing/TestSDKExternalWindowGLFW.cxx index dafe686cde..bae1a4537b 100644 --- a/library/testing/TestSDKExternalWindowGLFW.cxx +++ b/library/testing/TestSDKExternalWindowGLFW.cxx @@ -10,10 +10,6 @@ int TestSDKExternalWindowGLFW(int argc, char* argv[]) { - // create engine and load file - f3d::engine eng(f3d::window::Type::EXTERNAL); - eng.getLoader().loadGeometry(std::string(argv[1]) + "/data/cow.vtp"); - // setup glfw window if (!glfwInit()) { @@ -35,9 +31,20 @@ int TestSDKExternalWindowGLFW(int argc, char* argv[]) std::cerr << "Can't create GLFW window." << std::endl; return EXIT_FAILURE; } - glfwMakeContextCurrent(window); - glfwSetWindowUserPointer(window, &eng); + + auto loadFunc = [](void*, const char* name) -> f3d::window::F3DOpenGLAPIProc { + if (name) + { + return glfwGetProcAddress(name); + } + return nullptr; + }; + auto eng = f3d::engine::createExternal(loadFunc); + eng->getWindow().setSize(300, 300); + + + glfwSetWindowUserPointer(window, eng.get()); // key callback glfwSetKeyCallback(window, [](GLFWwindow* window, int key, int scancode, int action, int mods) { @@ -47,9 +54,11 @@ int TestSDKExternalWindowGLFW(int argc, char* argv[]) } }); + eng->getLoader().loadGeometry(std::string(argv[1]) + "/data/cow.vtp"); + while (!glfwWindowShouldClose(window) && glfwGetTime() < 1.0) { - eng.getWindow().render(); + eng->getWindow().render(); glfwSwapBuffers(window); glfwPollEvents(); } @@ -57,7 +66,7 @@ int TestSDKExternalWindowGLFW(int argc, char* argv[]) // Ideally, we should not test the content of the window, but the GLFW framebuffer itself // There is currently no API in GLFW that allows to do that unfortunately if (!TestSDKHelpers::RenderTest( - eng.getWindow(), std::string(argv[1]) + "baselines/", argv[2], "TestSDKExternalWindowGLFW")) + eng->getWindow(), std::string(argv[1]) + "baselines/", argv[2], "TestSDKExternalWindowGLFW")) { return EXIT_FAILURE; } diff --git a/library/testing/TestSDKExternalWindowGLX.cxx b/library/testing/TestSDKExternalWindowGLX.cxx new file mode 100644 index 0000000000..18bb02e2d4 --- /dev/null +++ b/library/testing/TestSDKExternalWindowGLX.cxx @@ -0,0 +1,117 @@ +#include "engine.h" + +#include +#include +#include +#include + +#include +#include +#include + +#define GLX_CONTEXT_MAJOR_VERSION_ARB 0x2091 +#define GLX_CONTEXT_MINOR_VERSION_ARB 0x2092 +typedef GLXContext (*glXCreateContextAttribsARBProc)(Display*, GLXFBConfig, GLXContext, Bool, const int*); + +int TestSDKExternalWindowGLX(int argc, char* argv[]) +{ + Display *display = XOpenDisplay(0); + + glXCreateContextAttribsARBProc glXCreateContextAttribsARB = NULL; + + const char *extensions = glXQueryExtensionsString(display, DefaultScreen(display)); + std::cout << extensions << std::endl; + + static int visual_attribs[] = + { + GLX_RENDER_TYPE, GLX_RGBA_BIT, + GLX_DRAWABLE_TYPE, GLX_WINDOW_BIT, + GLX_DOUBLEBUFFER, true, + GLX_RED_SIZE, 1, + GLX_GREEN_SIZE, 1, + GLX_BLUE_SIZE, 1, + None + }; + + std::cout << "Getting framebuffer config" << std::endl; + int fbcount; + GLXFBConfig *fbc = glXChooseFBConfig(display, DefaultScreen(display), visual_attribs, &fbcount); + if (!fbc) + { + std::cout << "Failed to retrieve a framebuffer config" << std::endl; + return 1; + } + + std::cout << "Getting XVisualInfo" << std::endl; + XVisualInfo *vi = glXGetVisualFromFBConfig(display, fbc[0]); + + XSetWindowAttributes swa; + std::cout << "Creating colormap" << std::endl; + swa.colormap = XCreateColormap(display, RootWindow(display, vi->screen), vi->visual, AllocNone); + swa.border_pixel = 0; + swa.event_mask = StructureNotifyMask; + + std::cout << "Creating window" << std::endl; + Window win = XCreateWindow(display, RootWindow(display, vi->screen), 0, 0, 100, 100, 0, vi->depth, InputOutput, vi->visual, CWBorderPixel|CWColormap|CWEventMask, &swa); + if (!win) + { + std::cout << "Failed to create window." << std::endl; + return 1; + } + + std::cout << "Mapping window" << std::endl; + XMapWindow(display, win); + + // Create an oldstyle context first, to get the correct function pointer for glXCreateContextAttribsARB + GLXContext ctx_old = glXCreateContext(display, vi, 0, GL_TRUE); + glXCreateContextAttribsARB = (glXCreateContextAttribsARBProc)glXGetProcAddress((const GLubyte*)"glXCreateContextAttribsARB"); + glXMakeCurrent(display, 0, 0); + glXDestroyContext(display, ctx_old); + + if (glXCreateContextAttribsARB == NULL) + { + std::cout << "glXCreateContextAttribsARB entry point not found. Aborting." << std::endl; + return EXIT_FAILURE; + } + + static int context_attribs[] = + { + GLX_CONTEXT_MAJOR_VERSION_ARB, 3, + GLX_CONTEXT_MINOR_VERSION_ARB, 0, + None + }; + + std::cout << "Creating context" << std::endl; + GLXContext ctx = glXCreateContextAttribsARB(display, fbc[0], NULL, true, context_attribs); + if (!ctx) + { + std::cout << "Failed to create GL3 context." << std::endl; + return 1; + } + + std::cout << "Making context current" << std::endl; + glXMakeCurrent(display, win, ctx); + +/* glClearColor (0, 0.5, 1, 1); + glClear (GL_COLOR_BUFFER_BIT); + glXSwapBuffers (display, win); + + sleep(1); + + glClearColor (1, 0.5, 0, 1); + glClear (GL_COLOR_BUFFER_BIT); + glXSwapBuffers (display, win); + +*/ + // TODO this is not working yet + auto eng = f3d::engine::createExternalGLX(); + eng->getWindow().setSize(300, 300); + eng->getLoader().loadGeometry(std::string(argv[1]) + "/data/cow.vtp"); + + sleep(1); + + ctx = glXGetCurrentContext(); + glXMakeCurrent(display, 0, 0); + glXDestroyContext(display, ctx); + return EXIT_SUCCESS; +} diff --git a/library/testing/TestSDKExternalWindowQT.cxx b/library/testing/TestSDKExternalWindowQT.cxx index f32e9755e5..21b98f6124 100644 --- a/library/testing/TestSDKExternalWindowQT.cxx +++ b/library/testing/TestSDKExternalWindowQT.cxx @@ -13,14 +13,12 @@ class F3DWindow : public QOpenGLWindow { public: - F3DWindow(const std::string& filePath, std::string baselinePath, std::string outputPath) + F3DWindow(std::string filePath, std::string baselinePath, std::string outputPath) : QOpenGLWindow() - , mEngine(f3d::window::Type::EXTERNAL) + , mFilePath(std::move(filePath)) , mBaselinePath(std::move(baselinePath)) , mOutputPath(std::move(outputPath)) { - f3d::loader& load = mEngine.getLoader(); - load.loadGeometry(filePath); } protected: @@ -49,13 +47,36 @@ class F3DWindow : public QOpenGLWindow this->close(); } + void initializeGL() override + { + this->QOpenGLWindow::initializeGL(); + + auto loadFunc = [](void* userData, const char* name) -> f3d::window::F3DOpenGLAPIProc { + if (auto* context = reinterpret_cast(userData)) + { + if (auto* symbol = context->getProcAddress(name)) + { + return symbol; + } + } + return nullptr; + }; + + mEngine = f3d::engine::createExternal(loadFunc, this->context()); + f3d::loader& load = mEngine->getLoader(); + load.loadGeometry(this->mFilePath); + +// mEngine.getWindow().initializeExternal(loadFunc, this->context()); + } + void paintGL() override { - mEngine.getWindow().render(); + mEngine->getWindow().render(); } private: - f3d::engine mEngine; + std::shared_ptr mEngine; + std::string mFilePath; std::string mBaselinePath; std::string mOutputPath; }; diff --git a/testing/recordings/TestInteractionSimpleExitHeadless.log b/testing/recordings/TestInteractionSimpleExitHeadless.log new file mode 100644 index 0000000000..8ff79946e7 --- /dev/null +++ b/testing/recordings/TestInteractionSimpleExitHeadless.log @@ -0,0 +1,5 @@ +# StreamVersion 1.1 +ExposeEvent 0 599 0 0 0 0 +RenderEvent 0 599 0 0 0 0 +KeyReleaseEvent -710 286 0 13 1 Return +KeyPressEvent -710 286 0 27 1 Escape diff --git a/vtkext/private/module/vtk.module b/vtkext/private/module/vtk.module index 2373d44423..8186398b45 100644 --- a/vtkext/private/module/vtk.module +++ b/vtkext/private/module/vtk.module @@ -14,7 +14,6 @@ DEPENDS VTK::RenderingCore VTK::RenderingOpenGL2 VTK::RenderingVolumeOpenGL2 - VTK::opengl f3d::vtkext PRIVATE_DEPENDS VTK::CommonExecutionModel @@ -27,6 +26,7 @@ PRIVATE_DEPENDS VTK::RenderingCore VTK::RenderingVolumeOpenGL2 OPTIONAL_DEPENDS + VTK::opengl VTK::RenderingExternal VTK::RenderingRayTracing TEST_DEPENDS diff --git a/vtkext/private/module/vtkF3DCachedLUTTexture.cxx b/vtkext/private/module/vtkF3DCachedLUTTexture.cxx index 175bef25d4..bc3068bb80 100644 --- a/vtkext/private/module/vtkF3DCachedLUTTexture.cxx +++ b/vtkext/private/module/vtkF3DCachedLUTTexture.cxx @@ -1,13 +1,18 @@ #include "vtkF3DCachedLUTTexture.h" -#include "vtkImageData.h" -#include "vtkObjectFactory.h" -#include "vtkOpenGLRenderWindow.h" -#include "vtkRenderer.h" -#include "vtkTextureObject.h" -#include "vtkXMLImageDataReader.h" +#include +#include +#include +#include +#include +#include +#include +#if VTK_VERSION_NUMBER >= VTK_VERSION_CHECK(9, 3, 20240914) +#include +#else #include +#endif vtkStandardNewMacro(vtkF3DCachedLUTTexture); diff --git a/vtkext/private/module/vtkF3DCachedSpecularTexture.cxx b/vtkext/private/module/vtkF3DCachedSpecularTexture.cxx index 1ae5a32694..0c1cd1d597 100644 --- a/vtkext/private/module/vtkF3DCachedSpecularTexture.cxx +++ b/vtkext/private/module/vtkF3DCachedSpecularTexture.cxx @@ -1,14 +1,20 @@ #include "vtkF3DCachedSpecularTexture.h" -#include "vtkImageData.h" -#include "vtkMultiBlockDataSet.h" -#include "vtkObjectFactory.h" -#include "vtkOpenGLRenderWindow.h" -#include "vtkRenderer.h" -#include "vtkTextureObject.h" -#include "vtkXMLMultiBlockDataReader.h" - +#include +#include +#include +#include +#include +#include +#include +#include + +#if VTK_VERSION_NUMBER >= VTK_VERSION_CHECK(9, 3, 20240914) +#include +#else #include +#endif + vtkStandardNewMacro(vtkF3DCachedSpecularTexture); diff --git a/vtkext/private/module/vtkF3DPointSplatMapper.cxx b/vtkext/private/module/vtkF3DPointSplatMapper.cxx index 9b2c347aaf..52c47aa148 100644 --- a/vtkext/private/module/vtkF3DPointSplatMapper.cxx +++ b/vtkext/private/module/vtkF3DPointSplatMapper.cxx @@ -1,5 +1,8 @@ #include "vtkF3DPointSplatMapper.h" +#include "vtkF3DBitonicSort.h" +#include "vtkF3DComputeDepthCS.h" + #include #include #include @@ -14,10 +17,13 @@ #include #include #include -#include +#include -#include "vtkF3DBitonicSort.h" -#include "vtkF3DComputeDepthCS.h" +#if VTK_VERSION_NUMBER >= VTK_VERSION_CHECK(9, 3, 20240914) +#include +#else +#include +#endif //---------------------------------------------------------------------------- class vtkF3DSplatMapperHelper : public vtkOpenGLPointGaussianMapperHelper diff --git a/vtkext/private/module/vtkF3DRenderer.cxx b/vtkext/private/module/vtkF3DRenderer.cxx index 08ff8f39d7..7a459ac4c8 100644 --- a/vtkext/private/module/vtkF3DRenderer.cxx +++ b/vtkext/private/module/vtkF3DRenderer.cxx @@ -63,7 +63,11 @@ #include #endif +#if VTK_VERSION_NUMBER >= VTK_VERSION_CHECK(9, 3, 20240914) +#include +#else #include +#endif #include #include diff --git a/vtkext/public/module/vtkF3DBitonicSort.cxx b/vtkext/public/module/vtkF3DBitonicSort.cxx index cd08c78e5b..2b47729916 100644 --- a/vtkext/public/module/vtkF3DBitonicSort.cxx +++ b/vtkext/public/module/vtkF3DBitonicSort.cxx @@ -1,18 +1,24 @@ #include "vtkF3DBitonicSort.h" +#include "vtkF3DBitonicSortFunctions.h" +#include "vtkF3DBitonicSortGlobalDisperseCS.h" +#include "vtkF3DBitonicSortGlobalFlipCS.h" +#include "vtkF3DBitonicSortLocalDisperseCS.h" +#include "vtkF3DBitonicSortLocalSortCS.h" + #include #include #include #include #include #include -#include +#include -#include "vtkF3DBitonicSortFunctions.h" -#include "vtkF3DBitonicSortGlobalDisperseCS.h" -#include "vtkF3DBitonicSortGlobalFlipCS.h" -#include "vtkF3DBitonicSortLocalDisperseCS.h" -#include "vtkF3DBitonicSortLocalSortCS.h" +#if VTK_VERSION_NUMBER >= VTK_VERSION_CHECK(9, 3, 20240914) +#include +#else +#include +#endif #include