You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

OpenGL与SDL2调用glGenBuffers时触发段错误崩溃问题求助

问题排查与修复方案

嘿,我帮你定位到了代码里的几个关键错误,正是这些问题导致glGenBuffers触发段错误,下面一步步给你解释并提供修正后的代码:

核心错误点

  • GL上下文属性设置时机颠倒:SDL_GL_SetAttribute必须在创建SDL窗口和GL上下文之前调用。你现在是先创建窗口再设置OpenGL版本,这时候属性已经无法生效,导致创建的上下文可能不支持你需要的OpenGL 3.3版本,甚至初始化失败。
  • GLEW初始化过早:glewInit()需要在有效的GL上下文创建并激活之后执行。你在还没创建窗口和上下文时就调用了它,此时没有GL环境,GLEW无法正确加载GL函数指针,后续调用glGenBuffers这类函数本质是调用空指针,直接触发段错误。
  • glBufferData的大小参数错误:你传入的大小是6,但这里需要的是字节数,6个float的总字节数应该是6 * sizeof(float),否则会导致数据拷贝不完整。

修正后的完整代码

#define GLEW_STATIC
#include <iostream>
#include <SDL2/SDL.h>
#include <SDL2/SDL_image.h>
#include <GL/glew.h>
using namespace std;

SDL_Window* win;
SDL_Event event;
const Uint8* keystate = SDL_GetKeyboardState(NULL);
SDL_GLContext context;

int main(int argc, char* args[]) {
    // 1. 先初始化SDL
    SDL_Init(SDL_INIT_EVERYTHING);

    // 2. 设置OpenGL上下文属性(必须在创建窗口之前)
    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); // 可选,指定核心模式

    // 3. 创建带OpenGL支持的窗口
    win = SDL_CreateWindow("opengl", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 900, 800, SDL_WINDOW_OPENGL);
    if (!win) {
        cerr << "SDL窗口创建失败:" << SDL_GetError() << endl;
        return 1;
    }

    // 4. 创建并激活GL上下文
    context = SDL_GL_CreateContext(win);
    if (!context) {
        cerr << "GL上下文创建失败:" << SDL_GetError() << endl;
        SDL_DestroyWindow(win);
        return 1;
    }
    SDL_GL_MakeCurrent(win, context);

    // 5. 初始化GLEW(此时已有有效GL上下文)
    glewExperimental = GL_TRUE;
    GLenum glewErr = glewInit();
    if (glewErr != GLEW_OK) {
        cerr << "GLEW初始化失败:" << glewGetErrorString(glewErr) << endl;
        SDL_GL_DeleteContext(context);
        SDL_DestroyWindow(win);
        return 1;
    }

    // 后续OpenGL操作
    glClearColor(1.0f, 1.0f, 1.0f, 1.0f);

    float positions[6] = { -0.5f,-0.5f, 0.0f,0.5f, 0.5f,0.0f };
    GLuint buffer;
    glGenBuffers(1, &buffer); // 现在可以正常执行了
    glBindBuffer(GL_ARRAY_BUFFER, buffer);
    glBufferData(GL_ARRAY_BUFFER, 6 * sizeof(float), positions, GL_STATIC_DRAW);

    // 注意:还需要启用顶点属性指针才能绘制,否则glDrawArrays不会有效果
    glEnableVertexAttribArray(0);
    glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 2 * sizeof(float), (void*)0);

    while (true) {
        while (SDL_PollEvent(&event)) {
            if (event.type == SDL_QUIT) {
                // 资源清理
                glDeleteBuffers(1, &buffer);
                SDL_GL_DeleteContext(context);
                SDL_DestroyWindow(win);
                return 0;
            }
        }

        glClear(GL_COLOR_BUFFER_BIT);
        glDrawArrays(GL_TRIANGLES, 0, 3);
        SDL_GL_SwapWindow(win);
    }
}

额外说明

修正后的代码还添加了:

  • 错误检查(窗口、上下文、GLEW初始化的错误判断),方便排查后续问题
  • 顶点属性指针的启用和设置,否则你的三角形无法被正确绘制
  • 退出时的资源清理,避免内存泄漏

内容的提问来源于stack exchange,提问作者Mysz nocny

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.29 17:27:38