【问题标题】:Reliably creating an OpenGL context?可靠地创建 OpenGL 上下文?
【发布时间】:2016-03-26 21:14:41
【问题描述】:

总结:

在开发计算机上成功创建了 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();

【问题讨论】:

  • 你为什么只在 Windows 上glewInit
  • @Colonel 好吧,它似乎在 Mac 上也能正常工作
  • 你为什么要在拥有当前 GL 上下文之前尝试SDL_GL_SetSwapInterval()?或者甚至是一个窗口?
  • 在验证 mainWindow 不为 NULL 之前,您还尝试 SDL_GetWindowSize()
  • CHECK() 是否调用 SDL_GetError()

标签: c++ opengl sdl opengl-3


【解决方案1】:
  1. 确保您知道您的应用程序依赖于什么,并从平台要求它。在我的经验中,说“核心配置文件”意义不大。更好地查询您的应用程序需要的每个扩展,并在缺少某些内容时关闭应用程序(在用户眼中优雅而友善)。扩展并不是一切。检查所有缓冲区的最大大小。其中我有真实的生活经验。
  2. 永远不要依赖标准合规性。是的,标准说 GL_DEPTH 最初是禁用的。不,你永远不能依赖司机是否遵守该规则。是的,那是一个真实的生活场景。
  3. 在各种硬件上运行适当的测试。供应商实现驱动程序的方式不同。有些人可能认为负顶点索引非常好。有些可能不会。那里还有真实的生活体验......
  4. 永远不要接受无提示的 OpenGL 错误。 “出了点问题,可能没什么好担心的。对于这个硬件。对于这个驱动程序。对于这个版本。对于这个操作系统。也许。”
  5. 算一下。浮点精度在 OpenGL 标准中并不那么严格(在 OpenGL 中更严格),对于具有未定义行为的操作(例如除以零或任何基于 NaN 的操作)的行为绝不是您想要依赖的。
  6. 阅读标准。是的,这很痛苦,但相信我会付出代价的。你当然不会感觉到它,因为你永远不会遇到你永远不会遇到的问题。

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-06-24
    • 1970-01-01
    • 1970-01-01
    • 2020-08-29
    • 2013-08-10
    • 2015-12-21
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多