加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

c – 使用OpenGL核心配置文件时为什么会崩溃?

发布时间:2020-12-16 09:49:43 所属栏目:百科 来源:网络整理
导读:当我尝试运行这个简单的OpenGL测试程序时,我遇到了分段错误.只有在使用核心配置文件标志创建上下文时才会发生这种情况.如果我使用兼容性配置文件标志,程序运行没有问题. 编辑:我检查了函数glGenVertexArrays的指针,它返回NULL.如果glfwCreateWindow没有返回
当我尝试运行这个简单的OpenGL测试程序时,我遇到了分段错误.只有在使用核心配置文件标志创建上下文时才会发生这种情况.如果我使用兼容性配置文件标志,程序运行没有问题.

编辑:我检查了函数glGenVertexArrays的指针,它返回NULL.如果glfwCreateWindow没有返回NULL,并且glGetString(GL_VERSION)确认上下文是版本4.3而glewInit返回GLEW_OK那么为什么glGenVertexArrays == NULL?

我的操作系统是64位Windows 7,而我的GPU是带有331.82 WHQL驱动程序的Nvidia GTX 760.

码:

#include <GL/glew.h>
#include <GLFW/glfw3.h>
#include <stdlib.h>
#include <stdio.h>

#define GLSL(src) "#version 430 coren" #src

void key_callback(GLFWwindow* window,int key,int scancode,int action,int mods)
{
    if(key == GLFW_KEY_ESCAPE && action == GLFW_PRESS)
        glfwSetWindowShouldClose(window,GL_TRUE);
}

GLuint create_program(const char* vertex_source,const char* fragment_source)
{
    GLuint vs = glCreateShader(GL_VERTEX_SHADER);
    glShaderSource(vs,1,&vertex_source,NULL);
    glCompileShader(vs);
    unsigned int fs = glCreateShader(GL_FRAGMENT_SHADER);
    glShaderSource(fs,&fragment_source,NULL);
    glCompileShader(fs);

    GLuint shader_program = glCreateProgram();
    glAttachShader(shader_program,fs);
    glAttachShader(shader_program,vs);
    glLinkProgram(shader_program);

    return shader_program;
}

const char* vertex_shader = GLSL(
    layout(location = 0) in vec3 vertex_position;

    void main()
    {
        gl_Position = vec4(vertex_position,1.0);
    }
);

const char* fragment_shader = GLSL(
    out vec4 frag_color;

    void main()
    {
        frag_color = vec4(1.0,0.0,1.0);
    }
);

int main(int argc,char* argv[])
{
    if(!glfwInit())
        exit(EXIT_FAILURE);

    glfwWindowHint(GLFW_RESIZABLE,GL_FALSE);
    glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR,4);
    glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR,3);
    //if we set GLFW_OPENGL_PROFILE to GLFW_OPENGL_CORE_PROFILE 
    //instead of GLFW_OPENGL_COMPAT_PROFILE the program will 
    //segfault at line 98,call to glGenVertexArrays
    glfwWindowHint(GLFW_OPENGL_PROFILE,GLFW_OPENGL_CORE_PROFILE);

    GLFWwindow* window = glfwCreateWindow(512,512,"OpenGL",NULL,NULL);

    if(!window)
    {
        glfwTerminate();
        exit(EXIT_FAILURE);
    }

    glfwSetKeyCallback(window,key_callback);
    glfwMakeContextCurrent(window);

    GLenum glewError = glewInit();

    if(glewError != GLEW_OK)
    {
        glfwTerminate();
        exit(EXIT_FAILURE);
    }

    printf("OpenGL Version: %snn",glGetString(GL_VERSION));

    float position[] = 
    {
        1.0f,1.0f,0.0f,-1.0f,0.0f
    };

    unsigned short indices[] = 
    {
        1,2,3,2
    };

    GLuint vao = 0;
    glGenVertexArrays(1,&vao);
    glBindVertexArray(vao);

    GLuint index_buffer = 0;
    GLuint vertex_buffer = 0;

    glGenBuffers(1,&index_buffer);
    glGenBuffers(1,&vertex_buffer);

    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,index_buffer);
    glBufferData(GL_ELEMENT_ARRAY_BUFFER,sizeof(indices),&indices,GL_STATIC_DRAW);

    glBindBuffer(GL_ARRAY_BUFFER,vertex_buffer);
    glBufferData(GL_ARRAY_BUFFER,sizeof(position),&position,GL_STATIC_DRAW);
    glVertexAttribPointer(0,GL_FLOAT,GL_FALSE,0);
    glEnableVertexAttribArray(0);

    GLuint shader_program = create_program(vertex_shader,fragment_shader);
    glUseProgram(shader_program);

    while(!glfwWindowShouldClose(window))
    {
        glClear(GL_COLOR_BUFFER_BIT);
        glDrawElements(GL_TRIANGLES,6,GL_UNSIGNED_SHORT,NULL);
        glfwSwapBuffers(window);
        glfwPollEvents();
    }

    glfwDestroyWindow(window);
    glfwTerminate();
    exit(EXIT_SUCCESS);
}

解决方法

实际上,在调用glewInit()之后,你实际上是从OpenGL获得了一个无效的枚举[1280].

glewExperimental = GL_TRUE;

之前调用glewInit()之前.

glewExperimental = GL_TRUE;

GLenum glewError = glewInit();

if (glewError != GLEW_OK)
{
    glfwTerminate();
    exit(EXIT_FAILURE);
}

为什么?好吧它与GLEW如何加载扩展,函数等有关.默认情况下,GLEW会将某些函数等设置为不受支持,从而绕过你需要设置的glewExperimental = GL_TRUE;否则它会产生一个像你一样的错误.

Experimental Drivers

GLEW obtains information on the supported extensions from the graphics driver. Experimental or pre-release drivers,however,might not report every available extension through the standard mechanism,in which case GLEW will report it unsupported. To circumvent this situation,the glewExperimental global switch can be turned on by setting it to GL_TRUE before calling glewInit(),which ensures that all extensions with valid entry points will be exposed.

Source

额外

永远记住要检查OpenGL错误,它们通常会告诉您错误和/或帮助您找到问题.

GLenum error = glGetError();

if (error != GL_NO_ERROR)
{
    std::cout << "OpenGL Error: " << error << std::endl;
}

您可以阅读有关不同错误here的信息.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读