可靠地创建 OpenGL 上下文?

Reliably creating an OpenGL context?

总结:

在开发电脑上成功创建了OpenGL上下文,但是在尝试分发应用程序时,屏幕只显示黑色。分发OpenGL应用需要考虑哪些问题?

详情:

我正在使用 SDL2 创建 OpenGL 3.1 上下文。上下文必须至少为 3.1 才能工作。

我没有对问题进行彻底的测试,所以我没有使用的显卡等信息。但是,我对摘要中提出的一般性问题更感兴趣,即分发 OpenGL 应用程序时需要考虑的事项。

这是上下文创建代码。

    // CREATE SDL
    U32 flags;

    flags |= SDL_INIT_VIDEO;
    flags |= SDL_INIT_EVENTS;

    if(!SDL_WasInit(0)) // Make sure SDL is initialized.
        SDL_Init(0);

    CHECK(!SDL_InitSubSystem(flags));

    // SET OPENGL ATTRIBUTES
    SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, config.glVersionMajor);
    SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, config.glVersionMinor);
    if(config.glCoreProfile)
        SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE);
    else
        SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_COMPATIBILITY);
    //SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
    SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, config.glDepthBuffer);
    SDL_GL_SetSwapInterval(0);

    // CREATE WINDOW
    flags = SDL_WINDOW_OPENGL | SDL_WINDOW_SHOWN;
    if(config.fullscreen)
        flags = flags | SDL_WINDOW_FULLSCREEN_DESKTOP;
    else if(config.maximized)
        flags = flags | SDL_WINDOW_MAXIMIZED;
    if(config.resizable)
        flags = flags | SDL_WINDOW_RESIZABLE;
    mainWindow = SDL_CreateWindow(config.programName, SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED,
                                    config.windowWidth, config.windowHeight, flags);
    SDL_GetWindowSize(mainWindow, (int*)&windowWidth, (int*)&windowHeight);
    CHECK(mainWindow != NULL);

    // CREATE OPENGL CONTEXT
    mainContext = SDL_GL_CreateContext(mainWindow);
    CHECK(mainContext != NULL);

    // INIT GLEW
#ifdef _WIN32
    CHECK(GLEW_OK == glewInit());
#endif

    glEnable(GL_DEPTH_TEST);
    glViewport(0,0,windowWidth,windowHeight);

    glClearColor(0,0,0,1);
    //glEnable(GL_PRIMITIVE_RESTART);
    glEnable(GL_CULL_FACE);
    //glPrimitiveRestartIndex(0xFFFFFFFF);

    glEnable(GL_BLEND);
    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

    TTF_Init();
  1. 确保您知道您的应用程序依赖什么,并从平台要求它。根据我的经验,说 "Core profile" 意义不大。更好地查询您的应用程序需要的每个扩展,并在缺少某些内容时关闭应用程序(在用户眼中优雅而友善)。扩展并不是一切。还要检查所有缓冲区的最大大小。其中我有真实的生活经验。
  2. 永远不要依赖标准合规性。是的,标准说 GL_DEPTH 最初是禁用的。不,你永远不能相信 driver 符合该规则。是的,那是一个真实的场景。
  3. 运行 对各种硬件进行适当的测试。供应商以不同的方式实现 drivers。有些人可能认为负顶点索引非常好。有些人可能不会。还有真实的生活经历...
  4. 永远不要接受静默的 OpenGL 错误。 "Something went wrong and it is probably nothing to worry about. For this hardware. For this driver. For this version. For this OS. Maybe."
  5. 计算一下。 OpenGL 标准对浮点精度没有那么严格(在 OpenGL 中更严格)并且具有未定义行为的操作的行为,例如被零除或任何基于 NaN 的操作,永远不是您想要依赖的东西。
  6. 阅读标准。是的,这很痛苦,但相信我,它会得到回报。你当然不会感觉到它,因为你永远不会遇到你永远不会遇到的问题。

附带说明一下,没有人真正遵循这种做法。每个人都先编码,然后永远调试。