glewInit() 因“缺少 GL 版本”、SDL2 OpenGL 上下文、cygwin 编译器而失败

2024-01-04

下面的程序创建一个窗口,该窗口除了按 esc 关闭外不执行任何操作。当我用cygwin编译它时,没有错误。我使用的GLEW来自CYGWIN 端口 http://cygwinports.org/,SDL2 是版本 2.0.3,来自他们的website https://www.libsdl.org/download-2.0.php's SDL2-devel-2.0.3-mingw.tar.gz下载。我在编译的可执行文件的目录中有SDL2.dll。

链接:-lSDL2 -lSDL2main -lGLEW -lGLU -lGL -lSDL2 -lSDL2main -lGLEW -lGLU -lGL,两次以确保所有内容都链接起来。

还编译了:-std=c++11

在我的计算机上,打印出以下程序:

OpenGL Vendor: (null)
OpenGL Renderer: (null)
OpenGL Shading Language Version: (null)
OpenGL Extensions: (null)
Error initializing GLEW! Missing GL version

否则该程序似乎可以正常工作。主要问题是,如果我尝试打电话,例如glGenVertexArrays,程序将会崩溃STATUS_ACCESS_VIOLATION。 (参见崩溃代码here http://pastebin.com/cTEX9vqW。我认为这与 GLEW 的错误有关Missing GL version.

#include <cstdio>

#include <chrono>
#include <thread>

#include <SDL2/SDL.h>

#include <GL/glew.h>

#include <SDL2/SDL_opengl.h>

#include <GL/glu.h>

const int width = 1000;
const int height = 500;
bool Running = true;

#undef main
int main (int argc, char *argv[]) {
    FILE* cdebug = fopen("cdebug.txt", "w");

    if (SDL_Init(SDL_INIT_VIDEO) < 0) {
        fprintf(cdebug, "SDL could not initialize! SDL Error: %s\n", SDL_GetError()); fflush(cdebug);
    }

    #define setAttr(attr, value) \
        if (SDL_GL_SetAttribute(attr, value) < 0) { \
            fprintf(cdebug, "SDL failed to set %s to %s, SDL Error: %s\n", #attr, #value, SDL_GetError()); fflush(cdebug);\
        }
    setAttr(SDL_GL_CONTEXT_MAJOR_VERSION, 3);
    setAttr(SDL_GL_CONTEXT_MINOR_VERSION, 3);
    setAttr(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE);

    setAttr(SDL_GL_RED_SIZE, 8);
    setAttr(SDL_GL_GREEN_SIZE, 8);
    setAttr(SDL_GL_BLUE_SIZE, 8);
    setAttr(SDL_GL_DEPTH_SIZE, 24);
    setAttr(SDL_GL_DOUBLEBUFFER, 1);
    #undef setAttr
    /*
    SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3);
    SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 3);
    SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE);

    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_DEPTH_SIZE, 24);
    SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
    */
    SDL_Window *window = SDL_CreateWindow(
            "test",
            SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED,
            640, 480,
            SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE
    );
    if (window == NULL) {
        fprintf(cdebug, "Window could not be created! SDL Error: %s\n", SDL_GetError()); fflush(cdebug);
    }

    SDL_GLContext GLContext = SDL_GL_CreateContext(window);
    if (GLContext == NULL) {
        fprintf(cdebug, "OpenGL context could not be created! SDL Error: %s\n", SDL_GetError()); fflush(cdebug);
    }
    if (SDL_GL_MakeCurrent(window, GLContext) < 0) {
        fprintf(cdebug, "OpenGL context could not be made current! SDL Error: %s\n", SDL_GetError()); fflush(cdebug);
    }

    fprintf(cdebug, "OpenGL Vendor: %s\n", glGetString(GL_VENDOR));
    fprintf(cdebug, "OpenGL Renderer: %s\n", glGetString(GL_RENDERER));
    fprintf(cdebug, "OpenGL Shading Language Version: %s\n", glGetString(GL_SHADING_LANGUAGE_VERSION));
    fprintf(cdebug, "OpenGL Extensions: %s\n", glGetString(GL_EXTENSIONS));
    fflush(cdebug);

    glewExperimental = GL_TRUE;
    {
        GLenum glewError = glewInit();
        if (glewError != GLEW_OK) {
            fprintf(cdebug, "Error initializing GLEW! %s\n", glewGetErrorString(glewError)); fflush(cdebug);
        }
    }

    SDL_Event event;
    while (Running) {
        while (SDL_PollEvent(&event)) {
            switch (event.type) {
                case SDL_KEYUP: {
                    switch (event.key.keysym.scancode) {
                        case SDL_SCANCODE_ESCAPE:
                            Running = false;
                            break;
                    }
                    break;
                }

            }
        }

        glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
        glClear(GL_COLOR_BUFFER_BIT);

        SDL_GL_SwapWindow(window);
        std::this_thread::sleep_for(std::chrono::milliseconds(50));
    }

    SDL_GL_DeleteContext(GLContext);

    SDL_DestroyWindow(window);
    window = NULL;

    SDL_Quit();

    return 0;
}

您正在以不应该的方式混合 cygwin 和 mingw。

如果您使用 cygwin 的工具链并且-lGL等等,你链接到 cygwin 的 OpenGL - 这是notWindows 上的原生 OpenGL 库,但由 cygwin 的 X 服务器提供,实现 GLX 协议。

SDL 的 mingw 版本将使用本机 GL 库(opengl32.dll)在 Windows 上,使用 wgl API。因此,SDL 甚至可能为您创建一个上下文,但您的程序正在调用的 GL 函数属于完全不同的 GL 实现 - 您的程序从未为其创建 GL 上下文。

解决方案是坚持使用其中之一:完全使用 cygwin、SDL 的 cygwin 版本以及 cygwin X 服务器。然而,这不是我推荐的道路。我不知道这是否会给你带来一些硬件加速。

更有用的解决方案是在整个项目中不使用 cygwin,而是使用 mingw,并使用 mingw 版本的 GLEW。这将产生一个完全本机的 Windows 二进制文件,它将使用本机 OpenGL 库以及驱动程序提供的所有功能,并且不需要 cygwin 的 dll,尤其不需要 cygwin 的 X 服务器。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

glewInit() 因“缺少 GL 版本”、SDL2 OpenGL 上下文、cygwin 编译器而失败 的相关文章

随机推荐