Reputation: 183
At the moment I am making a simple 3D space using glfw and glad. My approach for project management is to separate it into smaller projects, like:
ExternalGraphicsLibs has glfw, glad and glm dirs which source is directly from github (I have only made a single cmakelists file to make it .dll from this project). Renderer and Scene both use glad functionality (they do not see GLFW functionality) and Window only sees GLFW (no GLAD visibility).
The problem I am facing is that both Renderer and Scene need glad initialized, and if I initialize glad only in renderer, the scene does not see it so I need to reinitialize it there too. In my opinion, it is not the best approach, because both libs will have 2 different function pointers to glad which basically will do the same thing.
Do you guys know any solution to this problem? How to solve this problem, or just leave it this where every dll that uses glad would have it's own initialization?
My cmake for ExternalGraphicalLibs:
cmake_minimum_required(VERSION 3.24.0)
project(ExternalGraphicsLibs)
set(CMAKE_BUILD_PARALLEL_LEVEL)
set(CMAKE_CXX_STANDARD 23)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
# Find and configure OpenGL
find_package(OpenGL REQUIRED)
# GLFW options
set(GLFW_BUILD_DOCS OFF CACHE BOOL "Disable GLFW docs" FORCE)
set(GLFW_BUILD_TESTS OFF CACHE BOOL "Disable GLFW tests" FORCE)
set(GLFW_BUILD_EXAMPLES OFF CACHE BOOL "Disable GLFW examples" FORCE)
set(GLFW_INSTALL OFF CACHE BOOL "Disable GLFW install" FORCE)
# Add GLFW source code
add_subdirectory(glfw)
# Add GLAD source code
add_library(${PROJECT_NAME}
STATIC
${CMAKE_CURRENT_SOURCE_DIR}/glad/src/gl.c
)
target_include_directories(${PROJECT_NAME}
PUBLIC
glfw/include
glad/include
glm/
${OPENGL_INCLUDE_DIRS}
)
target_link_libraries(${PROJECT_NAME}
PUBLIC
glfw
${OPENGL_LIBRARIES}
)
Upvotes: 1
Views: 69
Reputation: 183
Big thanks to @Botje, I have managed to make GLAD a SHARED lib (.dll) with this cmake:
cmake_minimum_required(VERSION 3.24.0)
project(ExternalGraphicsLibs)
set(CMAKE_BUILD_PARALLEL_LEVEL)
set(CMAKE_CXX_STANDARD 23)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
# Find and configure OpenGL
find_package(OpenGL REQUIRED)
# GLFW options
set(GLFW_BUILD_DOCS OFF CACHE BOOL "Disable GLFW docs" FORCE)
set(GLFW_BUILD_TESTS OFF CACHE BOOL "Disable GLFW tests" FORCE)
set(GLFW_BUILD_EXAMPLES OFF CACHE BOOL "Disable GLFW examples" FORCE)
set(GLFW_INSTALL OFF CACHE BOOL "Disable GLFW install" FORCE)
# Add GLFW source code
add_subdirectory(glfw)
# Add GLAD source code
add_library(${PROJECT_NAME}
SHARED
${CMAKE_CURRENT_SOURCE_DIR}/glad/src/gl.c
)
# Define GLM_DLL_EXPORT for exporting symbols
target_compile_definitions(${PROJECT_NAME}
PRIVATE
GLAD_API_CALL_EXPORT_BUILD
PUBLIC
GLAD_API_CALL_EXPORT
)
target_include_directories(${PROJECT_NAME}
PUBLIC
glfw/include
glad/include
glm/
${OPENGL_INCLUDE_DIRS}
)
target_link_libraries(${PROJECT_NAME}
PUBLIC
glfw
${OPENGL_LIBRARIES}
)
P.S. note that ExternalGraphicsLibs subproject has GLFW and GLM directories in the same path as GLAD.
Upvotes: 1
Reputation: 30860
By making your ExternalGraphicsLibs STATIC, every library that links to it effectively has its own copy of GLAD. Make it SHARED instead, so the GLAD state can be shared by all of its customers.
It also looks like gladLoadGL
is not designed to be called multiple times. You should wrap it in a simple function that prevents multiple calls. Or you could use std::call_once
, which also handles any concurrent calls for you:
// As part of a second file in externalGraphicsLibs
std::once_flag loadGL_once;
int loadGL() {
return std::call_once(loadGL_once, [](){ return gladLoadGL(glfwGetProcAddress); });
}
Upvotes: 2