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

使用OpenGL(GLFW/GLEW)的C++代码出现Thread 1: EXC_BAD_ACCESS错误求助

问题分析与修复方案

你遇到的Thread 1: EXC_BAD_ACCESS (code=1, address=0x0)错误,核心原因是OpenGL上下文创建前就调用了OpenGL函数,再加上代码里几个关键逻辑错误,导致访问了空指针或无效GPU资源。下面一步步拆解问题并给出修复后的完整代码:

核心错误点

  • OpenGL函数调用顺序完全颠倒:所有OpenGL API(比如glGenVertexArrays、glUseProgram)必须在glfwMakeContextCurrent(window)之后调用——OpenGL需要一个活跃的上下文才能工作,否则这些函数的指针都是空的,调用就会触发内存访问错误。
  • 未初始化就使用renderingProgram:你直接调用glUseProgram(renderingProgram),但这个变量还没被赋值(全局变量默认是0,相当于尝试卸载一个不存在的程序)。
  • 片段着色器语法错误:片段着色器里不能使用gl_Position,这是顶点着色器的专属输出变量;片段着色器应该输出你定义的color变量。
  • glDrawArrays调用时机与参数错误:绘制操作应该放在渲染循环里,每次帧刷新时执行;同时参数应该是GL_POINTS(复数),不是GL_POINT。

修复后的完整代码

#include <GL/glew.h>
#include <GLFW/glfw3.h>
#define numVAOs 1

GLuint renderingProgram;
GLuint vao[numVAOs];

GLuint createShaderProgram() {
    // 顶点着色器:输出屏幕中心位置的点
    const char* vshaderSource = "#version 430 \n"
                                "void main(void) \n"
                                "{ gl_Position = vec4(0.0, 0.0, 0.0, 1.0); }";
    
    // 片段着色器:输出红色圆点(可自行修改颜色)
    const char* fshaderSource = "#version 430 \n"
                                "out vec4 color; \n"
                                "void main(void) \n"
                                "{ color = vec4(1.0, 0.0, 0.0, 1.0); }";

    GLuint vShader = glCreateShader(GL_VERTEX_SHADER);
    GLuint fShader = glCreateShader(GL_FRAGMENT_SHADER);

    glShaderSource(vShader, 1, &vshaderSource, NULL);
    glShaderSource(fShader, 1, &fshaderSource, NULL);

    glCompileShader(vShader);
    glCompileShader(fShader);

    // 新增:检查着色器编译错误(调试必备)
    GLint success;
    char infoLog[512];
    glGetShaderiv(vShader, GL_COMPILE_STATUS, &success);
    if(!success) {
        glGetShaderInfoLog(vShader, 512, NULL, infoLog);
        printf("Vertex shader compile error: %s\n", infoLog);
    }
    glGetShaderiv(fShader, GL_COMPILE_STATUS, &success);
    if(!success) {
        glGetShaderInfoLog(fShader, 512, NULL, infoLog);
        printf("Fragment shader compile error: %s\n", infoLog);
    }

    GLuint vfProgram = glCreateProgram();
    glAttachShader(vfProgram, vShader);
    glAttachShader(vfProgram, fShader);
    glLinkProgram(vfProgram);

    // 新增:检查程序链接错误(调试必备)
    glGetProgramiv(vfProgram, GL_LINK_STATUS, &success);
    if(!success) {
        glGetProgramInfoLog(vfProgram, 512, NULL, infoLog);
        printf("Program link error: %s\n", infoLog);
    }

    // 着色器已链接到程序,可删除临时对象
    glDeleteShader(vShader);
    glDeleteShader(fShader);

    return vfProgram;
}

int main() {
    // 初始化GLFW,先检查是否成功
    if (!glfwInit()) {
        printf("GLFW initialization failed!\n");
        return 1;
    }

    // 配置窗口与OpenGL上下文参数,版本与着色器的430匹配
    glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4);
    glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
    glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
    glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);
    glfwWindowHint(GLFW_RESIZABLE, GL_FALSE);

    // 创建窗口并检查是否成功
    GLFWwindow* window = glfwCreateWindow(1430, 800, "Davide", NULL, NULL);
    if (!window) {
        printf("Window creation failed!\n");
        glfwTerminate();
        return 1;
    }

    // 关键步骤:激活OpenGL上下文,所有OpenGL操作必须在这之后
    glfwMakeContextCurrent(window);

    // 初始化GLEW,加载OpenGL函数指针
    glewExperimental = GL_TRUE;
    if (glewInit() != GLEW_OK) {
        printf("GLEW initialization failed!\n");
        glfwTerminate();
        return 1;
    }

    // 创建着色器程序
    renderingProgram = createShaderProgram();

    // 创建并绑定VAO(核心模式必须使用VAO)
    glGenVertexArrays(numVAOs, vao);
    glBindVertexArray(vao[0]);

    // 新增:设置点的大小,让圆点更显眼
    glPointSize(10.0f);

    // 渲染循环
    while (!glfwWindowShouldClose(window)) {
        // 清除屏幕为黑色
        glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
        glClear(GL_COLOR_BUFFER_BIT);

        // 使用着色器程序并绘制中心圆点
        glUseProgram(renderingProgram);
        glDrawArrays(GL_POINTS, 0, 1);

        // 交换缓冲区并处理用户事件
        glfwSwapBuffers(window);
        glfwPollEvents();
    }

    // 清理资源
    glDeleteVertexArrays(numVAOs, vao);
    glDeleteProgram(renderingProgram);

    glfwTerminate();
    return 0;
}

额外说明

  • 我把GLFW的上下文版本改成了4.3,和你着色器里的#version 430完全匹配,避免版本不兼容问题。
  • 新增了着色器编译和程序链接的错误检查,方便你后续排查其他潜在问题。
  • 增加了glPointSize让中心圆点更显眼,你可以根据需要调整数值。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.12 05:09:17