gpt4 book ai didi

c++ - CMake 子项目不能调用 OpenGL 函数,但父项目可以

转载 作者:太空宇宙 更新时间:2023-11-04 12:46:14 25 4
gpt4 key购买 nike

我有一个父 CMake 项目和一个子 CMake 项目,在父 cmake 项目中我可以调用任何 OpenGL 函数并且它工作得很好,但是在子项目中我不能直接调用任何 OpenGL 函数,只能通过父项目功能会起作用吗。

父项目:

cmake_minimum_required (VERSION 3.8)
project(LumiumEngine)

set(CMAKE_DEBUG_POSTFIX "-d")
set(LUMI_DIR "LumiumEngine")

# SDL2
find_package(SDL2 CONFIG REQUIRED)

add_library(${PROJECT_NAME} SHARED "${LUMI_DIR}/System/Window.hpp" "${LUMI_DIR}/System/Window.cpp")

# glad
set(GLAD_DIR "${CMAKE_HOME_DIRECTORY}/external/glad")
add_library("glad" "${GLAD_DIR}/src/glad.c")
target_include_directories("glad" PUBLIC "${GLAD_DIR}/include")

target_include_directories(${PROJECT_NAME} PUBLIC "${SDL2_INCLUDE_DIRS}" "${GLAD_DIR}/include")
target_link_libraries(${PROJECT_NAME} PUBLIC SDL2::SDL2 SDL2::SDL2main "glad" "${CMAKE_DL_LIBS}")

set_target_properties(${PROJECT_NAME} PROPERTIES
ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_HOME_DIRECTORY}/${PROJECT_NAME}/lib"
RUNTIME_OUTPUT_DIRECTORY "${CMAKE_HOME_DIRECTORY}/${PROJECT_NAME}/bin"
)

install(DIRECTORY bin
DESTINATION "${CMAKE_HOME_DIRECTORY}/Lumin"
FILES_MATCHING
PATTERN "*.dll"
PATTERN "*.ilk" EXCLUDE
PATTERN "*.pdb" EXCLUDE
)

子项目:

cmake_minimum_required (VERSION 3.8)
project(Lumin)

set(CMAKE_DEBUG_POSTFIX "-d")

# find OpenGL
find_package(OpenGL REQUIRED)
add_executable(${PROJECT_NAME} "main.cpp" "${CMAKE_HOME_DIRECTORY}/external/glad/src/glad.c")

target_link_libraries(${PROJECT_NAME} PUBLIC "${OPENGL_LIBRARIES}" LumiumEngine)

set_target_properties(${PROJECT_NAME} PROPERTIES
RUNTIME_OUTPUT_DIRECTORY "${CMAKE_HOME_DIRECTORY}/${PROJECT_NAME}/bin"
)

子项目依赖于父项目,(在父-父目录中,我只是将这两个项目添加为子目录和 add_dependency(Child Parent),应该加载正确的 .dll 和 .libs,从我的理解我在父项目中加载 SDL2, SDL2main, glad 然后加载 OpenGL + Parent 中的所有库,因为它们是用 PUBLIC 标签添加的

代码不是问题,因为我在 Visual Studio 中使用相同的代码创建了一个包含两个子项目的项目。有没有我想念的图书馆?编译 OpenGL Loader `glad' 也可能是一个问题。

我认为让我感到困惑的主要问题是,为什么在我的父项目中被抽象层隐藏的 OpenGL 函数工作正常,但是当我在我的子项目中调用 OpenGL 函数时,我得到一个“在 0x00010 处抛出的异常...”在 OpenGL 调用中。感谢您提供任何帮助或指导。

编辑:添加代码示例:

这是父项目 LumiumEngine 中我的 Window.cpp

#include "Window.hpp"
#include <glad/glad.h>

lumi::Window::Window()
{
m_shouldClose = true;
}

lumi::Window::~Window()
{
SDL_Quit();
}

bool lumi::Window::createWindow(std::string title, int xPos, int yPos, int width, int height, unsigned int flags)
{
// Set SDL as ready and init SDL
SDL_SetMainReady();
if (SDL_Init(SDL_INIT_VIDEO) != 0)
{
SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, "SDL Init Error", "Could not init SDL2", NULL);
SDL_Quit();
return false;
}

SDL_GL_LoadLibrary(NULL); // Default OpenGL is fine.

// Request an OpenGL 4.5 context (should be core)
SDL_GL_SetAttribute(SDL_GL_ACCELERATED_VISUAL, 1);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 4);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 5);
// Also request a depth buffer
SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24);

// create the window
m_pWindow = SDL_CreateWindow(title.c_str(), xPos, yPos, width, height, flags);
if (m_pWindow == nullptr)
{
SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, "SDL Window Error", "Could not create a window", NULL);
SDL_Quit();
return false;
}

// create the openGL context
m_glContext = SDL_GL_CreateContext(m_pWindow);
if (m_glContext == nullptr)
{
SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, "SDL Window Error", "Could not create an openGL context with version 4.5", NULL);
SDL_Quit();
return false;
}

printf("OpenGL loaded\n");
gladLoadGLLoader(SDL_GL_GetProcAddress);
printf("Vendor: %s\n", glGetString(GL_VENDOR));
printf("Renderer: %s\n", glGetString(GL_RENDERER));
printf("Version: %s\n", glGetString(GL_VERSION));

m_shouldClose = false;
glViewport(0, 0, width, height);
glClearColor(.2f, .4f, .6f, 1.0f);
return true;
}

bool lumi::Window::isOpen()
{
return !m_shouldClose;
}

子项目 main.cpp

#include <LumiumEngine/System/Window.hpp>
#include <glad/glad.h>

int main(int argc, char **argv)
{
lumi::Window window;
if (window.createWindow("Hello World", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 800, 600, SDL_WINDOW_SHOWN | SDL_WINDOW_OPENGL))
{
glClearColor(0.2f, 0.4f, 0.6f, 1.0f); // exception occurs here, as you can see it's after i create a valid OpenGL context
while (window.isOpen())
{
//window.display();
}
}
return 1;
}

请注意我是如何在我的 createWindow 函数中调用完全相同的 OpenGL 函数 glClearColor() 的,它运行得非常好。我可以通过调用 window.display 来验证它是否有效, window.display 调用 glClear(GL_COLOR_BUFFER_BIT);然后是 SDL_GL_SwapBuffers()

旁注:我尝试摆脱子项目并将父项目制作成可执行文件而不是库,它工作正常,但我真的希望能够将 LumiumEngine 制作成一个库,这样我就可以调用它来自 future 的多个项目。我现在完全被难住了。

最佳答案

哇哇!

因此出于某种原因,您必须在子项目中再次通过 glad 手动加载 OpenGL,即使它已经在父项目中被调用并且我们已经验证我们有一个有效的 OpenGL 上下文。解决这个问题的简单方法是添加一个:

gladLoadGLLoader(SDL_GL_GetProcAddress)

创建SDL窗口后调用:

#include <LumiumEngine/System/Window.hpp>
#include <glad/glad.h>

int main(int argc, char **argv)
{
lumi::Window window;
if (window.createWindow("Hello World", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 800, 600, SDL_WINDOW_SHOWN | SDL_WINDOW_OPENGL))
{
gladLoadGLLoader(SDL_GL_GetProcAddress);
glClearColor(0.2f, 0.4f, 0.6f, 1.0f); // THIS WORKS NOW!!
while (window.isOpen())
{
window.display();
}
}
return 1;
}

如此简单的解决方案让我非常头疼。

关于c++ - CMake 子项目不能调用 OpenGL 函数,但父项目可以,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51418062/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com