无法初始化 OpenGL

Posted

技术标签:

【中文标题】无法初始化 OpenGL【英文标题】:Can't initialize OpenGL 【发布时间】:2016-06-19 13:46:24 【问题描述】:

我在发挥自己的魅力时遇到了一些麻烦。当我初始化 glew 时,我收到一个错误:缺少 GL 版本。我也无法创建上下文:OpenGL 未初始化。 这是我的代码:

#include <GL\glew.h>
#include <GL\GLU.h>
#include <SDL2\SDL.h>
#include <SDL2\SDL_opengl.h>

#include <iostream>
#undef main

SDL_GLContext context;
SDL_Renderer * renderer;
SDL_Window * window;

int main(int argc, char *argv[]) 
    //init SDL
    if (SDL_Init(SDL_INIT_EVERYTHING) != 0) 
        fprintf(stderr, "\n> Unable to initialize SDL:  %s\n", SDL_GetError());
    

    window = SDL_CreateWindow("Cri Engine 3D", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, 800, 600, SDL_WINDOW_SHOWN);
    if (window == nullptr)
    
        printf("> Window could not be created! SDL Error: %s\n", SDL_GetError());
    

    SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3);
    SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 1);
    SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE);

    context = SDL_GL_CreateContext(window);
    SDL_GL_MakeCurrent(window, context);


    if (context == NULL) 
        printf("> OpenGL context could not be created! SDL Error: %s\n", SDL_GetError());
    

    //Glew
    glewExperimental = GL_TRUE;
    GLenum err = glewInit();
    if (GLEW_OK != err) 
        fprintf(stderr, "> Error: %s\n", glewGetErrorString(err));
    
    fprintf(stdout, "> Using GLEW %s\n", glewGetString(GLEW_VERSION));

    glViewport(0, 0, 800, 600);

    SDL_Quit();
    return 0;

这些是我使用的链接器设置(按此顺序):glew32.lib、glu32.lib、opengl32.lib、SDL2.lib、SDL2main.lib。

我确定这些库已正确包含。 PS:这是我的第一篇文章,如果我遗漏了一些信息,请告诉我!

【问题讨论】:

【参考方案1】:

您缺少 SDL_WINDOW_OPENGLSDL_CreateWindow() 标志。

另外,您必须删除#undef main。 否则,您需要自己进行一些低级初始化,而您不会这样做。

另一件事:您必须从核心配置文件 (SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_COMPATIBILITY);) 切换到兼容性配置文件,因为当您要求 GLEW 在 Windows 上初始化核心配置文件上下文时,它可能会崩溃。

此外,您的核心的许多部分都是多余的:

SDL_WINDOW_SHOWN - 默认已使用。 SDL_GL_MakeCurrent(window, context); - 只有一个上下文时不需要。 glViewport(0, 0, 800, 600); - 当您创建上下文时,它会自动为您设置正确的视口。 SDL_Quit(); - 当你的程序结束时,你不需要调用 anything。它什么也不做,只会让你的程序关闭得更慢。 (至少这是它在 Windows 上的工作方式。在 Linux 上,有时这是必要的,正如@keltar 所指出的那样。此外,它还可以防止像 valgring 这样的泄漏检测器就 SDL 内部结构对你大喊大叫。) #include &lt;SDL2\SDL_opengl.h&gt; - 它是 &lt;GL/gl.h&gt; 的替代品,您不需要,因为您已经拥有 &lt;GL\glew.h&gt;

【讨论】:

非常感谢,我试了很久才让它工作。在 SDL_CreateWindow() 中添加标志就可以了。我知道代码很乱(因为我已经搞砸了这么久)。 SDL_Quit 部分很有争议(例如 valgrind); SDL_opengl.h 是错误的,它永远不会被包含在内;不过,它可以替代gl.h 转念一想,没有DestroyWindow,所以如果没有SDL_Quit,如果窗口是全屏视频模式就不会恢复(至少在X11上),所以更糟。 【参考方案2】:

尝试将SDL_WINDOW_OPENGL 添加到窗口创建标志。

【讨论】:

以上是关于无法初始化 OpenGL的主要内容,如果未能解决你的问题,请参考以下文章

OpenGL 3.3 无法绘制任何东西

glew和glfw的opengl初始化问题

OpenGL 纹理无法正常工作

glGetString(GL_VERSION) 在 OpenGL 初始化时返回 NULL

OpenGL、GLSL 片段着色器无法读取 Sampler2D 纹理

OpenGL ES 无法使 LUMINANCE FBO 在 Android 中工作