具有 0 个颜色位和 0 个深度位的 SDL2 OpenGL 4.2 上下文
SDL2 OpenGL 4.2 context with 0 color bits and 0 depth bits
我一直在尝试启动一个新的 SDL + GLEW + OpenGL 项目,但设置很困难(MinGW-w64-32 on Windows 8 64-bit with Intel i7-4700MQ CPU 和 NVidia GTX 745M GPU)。
如果我将用于上下文创建的 GL 属性设置为使用 OpenGL 4.2 版,颜色和深度位大小将设置为 0。但是,如果我请求 2.1 上下文(这也是默认设置),我可以获得请求的位深度(每种颜色 8 位,深度 24 位)。然而,在任何一种情况下,glClearColor 都没有效果(只是黑色背景)。
在这两种情况下,几个 glGetString
调用的结果是相同的 - 4.2 上下文,表明 SDL 的输出远不正确。
可以找到完整的代码 here,目前它主要是大型项目的样板文件。相关部分很可能是
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_GL_DEPTH_SIZE 必须是所有颜色通道的总和:
使用四个颜色通道:
SDL_GL_SetAttribute (SDL_GL_DEPTH_SIZE, 32);
如果您使用 3 个颜色通道,那么:
SDL_GL_SetAttribute (SDL_GL_DEPTH_SIZE, 24);
已经有一些问题,这可能是问题所在。
对不起我的英语。
I'm using SDL's built-in function SDL_GL_GetAttribute
which returns the values that SDL uses to create the context, not the actual context attributes (as I understand it).
这是不正确的,我查看了 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 (...)
的 return 值应该不为零。
如果您必须从 SDL_GL_GetAttribute (...)
中获得有意义的位深度值,那么这意味着您必须使用兼容性配置文件。 SDL2 不会从它选择的像素格式中提取此信息(像 GLFW 这样的更智能的框架会这样做),但它会天真地尝试从 GL 中查询它。
我一直在尝试启动一个新的 SDL + GLEW + OpenGL 项目,但设置很困难(MinGW-w64-32 on Windows 8 64-bit with Intel i7-4700MQ CPU 和 NVidia GTX 745M GPU)。
如果我将用于上下文创建的 GL 属性设置为使用 OpenGL 4.2 版,颜色和深度位大小将设置为 0。但是,如果我请求 2.1 上下文(这也是默认设置),我可以获得请求的位深度(每种颜色 8 位,深度 24 位)。然而,在任何一种情况下,glClearColor 都没有效果(只是黑色背景)。
在这两种情况下,几个 glGetString
调用的结果是相同的 - 4.2 上下文,表明 SDL 的输出远不正确。
可以找到完整的代码 here,目前它主要是大型项目的样板文件。相关部分很可能是
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_GL_DEPTH_SIZE 必须是所有颜色通道的总和:
使用四个颜色通道:
SDL_GL_SetAttribute (SDL_GL_DEPTH_SIZE, 32);
如果您使用 3 个颜色通道,那么:
SDL_GL_SetAttribute (SDL_GL_DEPTH_SIZE, 24);
已经有一些问题,这可能是问题所在。 对不起我的英语。
I'm using SDL's built-in function
SDL_GL_GetAttribute
which returns the values that SDL uses to create the context, not the actual context attributes (as I understand it).
这是不正确的,我查看了 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 (...)
的 return 值应该不为零。
如果您必须从 SDL_GL_GetAttribute (...)
中获得有意义的位深度值,那么这意味着您必须使用兼容性配置文件。 SDL2 不会从它选择的像素格式中提取此信息(像 GLFW 这样的更智能的框架会这样做),但它会天真地尝试从 GL 中查询它。