【问题标题】:OpenGL: glGenVertexArrays() gives EXC_BAD_ACCESSOpenGL:glGenVertexArrays() 给出 EXC_BAD_ACCESS
【发布时间】:2022-01-28 00:42:20
【问题描述】:

当我使用 OpenGL 并运行我的代码来制作三角形时,函数 glGenVertexArrays() 会给我 EXE_BAD_ACCESS

Error

代码:

#include <iostream>
#include <glad/glad.h>
#include <GLFW/glfw3.h>
#include <cmath>

// Window specs
const int HEIGHT = 800;
const int WIDTH = 600;

// Shader source code
const char* vertexShaderSource = "#version 330 core\n"
"layout (location = 0) in vec3 aPos;\n"
"void main()\n"
"{\n"
"   gl_Position = vec4(aPos.x, aPos.y, aPos.z, 1.0);\n"
"}\0";
const char* fragmentShaderSource = "#version 330 core\n"
"out vec4 FragColor;\n"
"void main()\n"
"{\n"
"   FragColor = vec4(0.8f, 0.3f, 0.02f, 1.0f);\n"
"}\n\0";

int main(void)
{
    if (!glfwInit())
    {
        std::cout<<"GLFW failed to Initialize!"<<std::endl;
        return -1;
    }
    
    
    GLfloat vertices[] =
    {
        -0.5f, -0.5f * float(sqrt(3)) / 3, 0.0f,
        0.5f, -0.5f * float(sqrt(3)) / 3, 0.0f,
        0.0f, 0.5f * float(sqrt(3)) * 2 / 3, 0.0f
    };
    
    GLFWwindow* window = glfwCreateWindow(WIDTH, HEIGHT, "Open GL", NULL, NULL);
        
    glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
    glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
    glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
    glfwWindowHint(GLFW_RESIZABLE, GLFW_FALSE);

    glfwMakeContextCurrent(window);
    
    if(!window)
    {
        std::cout<<"Something went Wrong when Creating a Window!\nShutting down ..."<<std::endl;
        glfwTerminate();
        return -1;
    }
    //
    gladLoadGL();
    glViewport(0, 0, WIDTH, HEIGHT);
    
    GLuint vertexShader = glCreateShader(GL_VERTEX_SHADER);
    glShaderSource(vertexShader, 1, &vertexShaderSource, NULL);
    glCompileShader(vertexShader);
    
    GLuint fragmentShader  = glCreateShader(GL_FRAGMENT_SHADER);
    glShaderSource(fragmentShader, 1, &fragmentShaderSource, NULL);
    glCompileShader(fragmentShader);
    //
    GLuint shaderProgram = glCreateProgram();
    
    glAttachShader(shaderProgram, vertexShader);
    glAttachShader(shaderProgram, fragmentShader);
    
    glLinkProgram(shaderProgram);
    
    glDeleteShader(vertexShader);
    glDeleteShader(fragmentShader);
    
    GLuint VAO;
    GLuint VBO;
    
    glGenVertexArrays(1, &VAO);
    glGenBuffers(1, &VBO);
    
    glBindVertexArray(VAO);
    
    glBindBuffer(GL_ARRAY_BUFFER, VBO);
    glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
    
    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0);
    glEnableVertexAttribArray(0);
    
    glBindBuffer(GL_ARRAY_BUFFER, 0);
    glBindVertexArray(0);

    while(!glfwWindowShouldClose(window))
    {
        glClearColor(1.0f, 0.0f, 0.0f, 1.0f);
        glClear(GL_COLOR_BUFFER_BIT);
        
        glUseProgram(shaderProgram);
        glBindVertexArray(VAO);
        
        glDrawArrays(GL_TRIANGLES, 0, 3);
        glfwSwapBuffers(window);
        
        glfwPollEvents();
    }
    
    glDeleteVertexArrays(1, &VAO);
    glDeleteBuffers(1, &VBO);
    glDeleteProgram(shaderProgram);
    
    glfwDestroyWindow(window);
    glfwTerminate();
    return 0;
}

我曾经很高兴编写代码。有谁知道如何解决这个问题或我做错了什么。

使用 Xcode 13.2.1 重新创建它,然后使用 Opengl 4.1 和 GLFW 链接 Glad 并使其看起来像这样

File Layout

然后将代码粘贴到 main 中并运行。

【问题讨论】:

  • 你为什么打电话给glfwWindowHint() 之后 glfwCreateWindow()
  • “我在glfwCreateWindow() 之后使用glfwWindowHint(),因为当我在收到错误消息之前放置它时......” - !? glfwWindowHint 影响窗口(OpenGL 上下文)的创建方式。但是glfwCreateWindow之后就没有任何效果了
  • glGenVertexArrays 需要 OpenGL 3.0 或更高版本。因为在您创建窗口之后之后 之前您不会调用glfwWindowHint,所以您的上下文可能只是OpenGL 2.0 或2.1。因此出现了问题。
  • @NickDeveloper 你的硬件支持 OpenGL 3.3 吗?
  • 如果窗口创建失败,您需要使用glfwGetError检查错误。

标签: c++ xcode opengl glfw exc-bad-access


【解决方案1】:

一些事情:

  • glfwWindowHint() 仅影响 next glfwCreateWindow() 调用,因此请确保在创建窗口之前调用它们。默认提示设置通常会在 macOS 上为您提供无法处理 #version 330 core GLSL 代码的版本 2.1 兼容性上下文。
  • GLFW_CONTEXT_VERSION_MAJOR 被使用了两次;你也需要GLFW_CONTEXT_VERSION_MINOR
  • 对于核心上下文,macOS 需要将 GLFW_OPENGL_FORWARD_COMPAT 设置为 GLFW_TRUE
  • 检查着色器编译/链接错误。
  • 您的 GLAD 可能与您所定位的 GL 版本不同步;有关我使用的设置,请参阅 cmets 中的生成器链接。
  • GLFW 在glfwGetProcAddress() 中有一个完全可用的GLADloadproc;还不如从gladLoadGL()切换到gladLoadGLLoader()
  • 提供glfwSetErrorCallback() 可以让您从 GLFW 获得一些早期/即时错误报告。这就是我发现缺少的GLFW_CONTEXT_VERSION_MINOR 提示的方式。没有理由不使用它。

大家一起:

// g++ -Iinclude main.cpp src/glad.c `pkg-config --cflags --libs glfw3`

// Commandline:
//   --profile="compatibility" --api="gl=3.3" --generator="c" --spec="gl" --no-loader --extensions=""
// Online:
//   https://glad.dav1d.de/#profile=compatibility&language=c&specification=gl&api=gl%3D3.3
#include <glad/glad.h>

#include <GLFW/glfw3.h>
#include <iostream>
#include <cmath>

void CheckStatus( GLuint obj, bool isShader )
{
    GLint status = GL_FALSE, log[ 1 << 11 ] = { 0 };
    ( isShader ? glGetShaderiv : glGetProgramiv )( obj, isShader ? GL_COMPILE_STATUS : GL_LINK_STATUS, &status );
    if( status == GL_TRUE ) return;
    ( isShader ? glGetShaderInfoLog : glGetProgramInfoLog )( obj, sizeof( log ), NULL, (GLchar*)log );
    std::cerr << (GLchar*)log << "\n";
    std::exit( EXIT_FAILURE );
}

void AttachShader( GLuint program, GLenum type, const char* src )
{
    GLuint shader = glCreateShader( type );
    glShaderSource( shader, 1, &src, NULL );
    glCompileShader( shader );
    CheckStatus( shader, true );
    glAttachShader( program, shader );
    glDeleteShader( shader );
}

const char* const vert = 1 + R"GLSL(
#version 330 core
layout (location = 0) in vec3 aPos;
void main()
{
   gl_Position = vec4(aPos.x, aPos.y, aPos.z, 1.0);
};
)GLSL";

const char* const frag = 1 + R"GLSL(
#version 330 core
out vec4 FragColor;
void main()
{
   FragColor = vec4(0.8f, 0.3f, 0.02f, 1.0f);
}
)GLSL";

int main(void)
{
    glfwSetErrorCallback( []( int, const char* desc )
    {
        std::cerr << desc << "\n";
        std::exit( EXIT_FAILURE );
    } );
    if (!glfwInit())
    {
        std::cout<<"GLFW failed to Initialize!"<<std::endl;
        return -1;
    }

    GLfloat vertices[] =
    {
        -0.5f, -0.5f * float(sqrt(3)) / 3, 0.0f,
        0.5f, -0.5f * float(sqrt(3)) / 3, 0.0f,
        0.0f, 0.5f * float(sqrt(3)) * 2 / 3, 0.0f
    };

    glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
    glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
    glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
    glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GLFW_TRUE);
    glfwWindowHint(GLFW_RESIZABLE, GLFW_FALSE);
    GLFWwindow* window = glfwCreateWindow(800, 600, "Open GL", NULL, NULL);
    if(!window)
    {
        std::cout<<"Something went Wrong when Creating a Window!\nShutting down ..."<<std::endl;
        glfwTerminate();
        return -1;
    }

    glfwMakeContextCurrent(window);

    gladLoadGLLoader( (GLADloadproc)glfwGetProcAddress );

    glViewport(0, 0, 800, 600);

    GLuint prog = glCreateProgram();
    AttachShader( prog, GL_VERTEX_SHADER, vert );
    AttachShader( prog, GL_FRAGMENT_SHADER, frag );
    glLinkProgram( prog );
    CheckStatus( prog, false );
    glUseProgram( prog );

    GLuint VAO;
    GLuint VBO;

    glGenVertexArrays(1, &VAO);
    glGenBuffers(1, &VBO);

    glBindVertexArray(VAO);

    glBindBuffer(GL_ARRAY_BUFFER, VBO);
    glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);

    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0);
    glEnableVertexAttribArray(0);

    glBindBuffer(GL_ARRAY_BUFFER, 0);
    glBindVertexArray(0);

    while(!glfwWindowShouldClose(window))
    {
        glClearColor(1.0f, 0.0f, 0.0f, 1.0f);
        glClear(GL_COLOR_BUFFER_BIT);

        glUseProgram(prog);
        glBindVertexArray(VAO);

        glDrawArrays(GL_TRIANGLES, 0, 3);
        glfwSwapBuffers(window);

        glfwPollEvents();
    }

    glDeleteVertexArrays(1, &VAO);
    glDeleteBuffers(1, &VBO);
    glDeleteProgram(prog);

    glfwDestroyWindow(window);
    glfwTerminate();
    return 0;
}

【讨论】:

  • “macOS 的目标版本仅支持 OpenGL 3.2 及更高版本的前向兼容核心配置文件上下文”我放了 3.3 并使用了你的代码,但这就是我得到的
  • @NickDeveloper:很抱歉,忘记了 macOS needs GLFW_OPENGL_FORWARD_COMPAT 设置为 GLFW_TRUE 用于核心上下文。已更新。
  • 感谢您的回答,我从没想过会非常感谢。
【解决方案2】:

请注意,对于 MacOS 上的 3.3 核心配置文件,您可能还需要致电 glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE); 由 GM 在评论部分和 genpfault 发表

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-10-05
    • 1970-01-01
    • 2017-03-23
    • 1970-01-01
    • 1970-01-01
    • 2010-10-08
    相关资源
    最近更新 更多