SDL2 OpenGL 4.2上下文,具有0个颜色位和0个深度位

SDL2 OpenGL 4.2 context with 0 color bits and 0 depth bits

本文关键字:0个 颜色 深度 具有 OpenGL 上下文 SDL2      更新时间:2023-10-16

我一直在尝试启动一个新的SDL+GLEW+OpenGL项目,但设置很困难(在Windows 8 64位上使用Intel i7-4700MQ CPU和NVidia GTX 745M GPU的MinGW-w64-32)。

如果我将用于上下文创建的GL属性设置为使用OpenGL 4.2版,则颜色和深度位大小将设置为0。然而,如果我请求2.1上下文(这也是默认的),我可以获得所请求的比特深度(每种颜色8个比特,深度24个比特)。然而,在任何一种情况下,glClearColor都没有效果(只有黑色背景)。

在这两种情况下,几个glGetString调用的结果是相同的——一个4.2上下文,这表明SDL的输出远非正确。

整个代码可以在这里找到,目前它主要是一个更大项目的样板。相关部分很可能是

if(SDL_Init(SDL_INIT_EVERYTHING) != 0) {
    std::cerr << "Error initializing SDL.n";
    exit(1);
}
SDL_GL_SetAttribute(SDL_GL_ACCELERATED_VISUAL, 1);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 2);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 1);
//SDL_GL_SetAttribute(SDL_GL_CONTEXT_FLAGS, SDL_GL_CONTEXT_FORWARD_COMPATIBLE_FLAG);
SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 8);
SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 8);
SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 8);
SDL_GL_SetAttribute(SDL_GL_ALPHA_SIZE, 8);
SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24);
SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
SDL_Window* window = SDL_CreateWindow("RenderSystem", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 640, 480, SDL_WINDOW_OPENGL|SDL_WINDOW_RESIZABLE);
if(!window) {
    std::cerr << "Window creation failed.n";
    SDL_Quit();
    exit(2);
}
SDL_GLContext context = SDL_GL_CreateContext(window);
if(!context) {
    std::cerr << "OpenGL Context creation failed.n";
    SDL_DestroyWindow(window);
    SDL_Quit();
    exit(3);
}
SDL_GL_MakeCurrent(window, context);

glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
SDL_Event evt;
bool run = true;
while(run) {
    SDL_PollEvent(&evt);
    switch(evt.type) {
        case SDL_KEYDOWN:
            if(evt.key.keysym.sym == SDLK_ESCAPE) {
                run = false;
            }
            break;
        case SDL_QUIT:
            run = false;
            break;
    }
    SDL_GL_SwapWindow(window);
}

我使用SDL的内置函数SDL_GL_GetAttribute,它返回SDL用于创建上下文的值,而不是实际的上下文属性(据我所知)。

这是不正确的,我看了SDL_GL_GetAttribute (...)的SDL实现(参见src/video/SDL_video.c),它做了我所描述的。无法查询核心配置文件上下文中的值,因为它们不是为默认帧缓冲区定义的。

以下是问题的来源:

int
SDL_GL_GetAttribute(SDL_GLattr attr, int *value)
{
  // ...
  switch (attr) {
  case SDL_GL_RED_SIZE:
    attrib = GL_RED_BITS;
    break;
  case SDL_GL_BLUE_SIZE:
    attrib = GL_BLUE_BITS;
    break;
  case SDL_GL_GREEN_SIZE:
    attrib = GL_GREEN_BITS;
    break;
  case SDL_GL_ALPHA_SIZE:
    attrib = GL_ALPHA_BITS;
    break;
  }
  // ...
  glGetIntegervFunc(attrib, (GLint *) value);
  error = glGetErrorFunc();
}

该代码实际上在核心配置文件上生成了一个GL_INVALID_ENUM错误,因此SDL_GL_GetAttribute (...)的返回值应该为非零。

如果您必须从SDL_GL_GetAttribute (...)中获得位深度的有意义的值,那么这意味着您必须使用兼容性配置文件。SDL2不会从它选择的像素格式中提取这些信息(像GLFW这样的智能框架会这样做),但它天真地试图从GL中查询这些信息。

如果不是内存故障,SDL_GL_DEPTH_SIZE必须是所有颜色通道的总和:

使用四种颜色通道:

SDL_GL_SetAttribute (SDL_GL_DEPTH_SIZE, 32);

如果你使用3个颜色通道,那么:

SDL_GL_SetAttribute (SDL_GL_DEPTH_SIZE, 24);

它已经出现了一些问题,这可能就是问题所在。对不起我的英语。