OpenGL 三角形不会在 macOS 上渲染?

Posted

技术标签:

【中文标题】OpenGL 三角形不会在 macOS 上渲染?【英文标题】:OpenGL triangle won't render on macOS? 【发布时间】:2018-08-18 01:15:00 【问题描述】:

当我尝试使用 OpenGL 渲染三角形时出现空白屏幕。

我关注a tutorial,我的代码与教程的代码相同,但核心配置文件代码块除外。

我在 Mac 上运行它

#include <GL/glew.h>
#include <GLFW/glfw3.h>
#include <iostream>

static unsigned int CompileShader(unsigned int type, const std::string& source)
    unsigned int id = glCreateShader(type);
    const char* src = source.c_str();
    glShaderSource(id, 1, &src, nullptr);
    glCompileShader(id);

    int result;
    glGetShaderiv(id, GL_COMPILE_STATUS, &result);

    if(result == GL_FALSE)
        int length;
        glGetShaderiv(id, GL_INFO_LOG_LENGTH, &length);
        char* message = (char*) alloca(length*sizeof(char));
        glGetShaderInfoLog(id, length, &length, message);
        std::cout << "Failed to compile " << (type == GL_VERTEX_SHADER ? "vertex" : "fragment") << " shader" << std::endl;
        std::cout << message << std::endl;
    
    return id;

static unsigned int CreateShader(const std::string& vertexShader, const std::string& fragmentShader)
    unsigned int program = glCreateProgram();
    unsigned int vs = CompileShader(GL_VERTEX_SHADER, vertexShader);
    unsigned int fs = CompileShader(GL_FRAGMENT_SHADER, fragmentShader);

    glAttachShader(program, vs);
    glAttachShader(program, fs);
    glLinkProgram(program);
    glValidateProgram(program);

    glDeleteShader(vs);
    glDeleteShader(fs);

    return program;

int main(void)

    GLFWwindow* window;

    /* Initialize the library */
    if (!glfwInit())
        return -1;

    /* Core profile */
    glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);
    glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
    glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
    glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 2);

    /* Create a windowed mode window and its OpenGL context */
    window = glfwCreateWindow(640, 480, "Hello World", NULL, NULL);
    if (!window)
    
        glfwTerminate();
        return -1;
    

    /* Make the window's context current */
    glfwMakeContextCurrent(window);

    glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);

    if(glewInit() != GLEW_OK)
        std::cout <<"error!";


    std::cout << "Version: " << glGetString(GL_VERSION) << " :Version " << std::endl;

    float positions[6] = 
            -0.5f, -0.5f,
            0.0f, 0.5f,
            0.5f, -0.5f
    ;
    unsigned int buffer;
    glGenBuffers(1, &buffer);
    glBindBuffer(GL_ARRAY_BUFFER, buffer);
    glBufferData(GL_ARRAY_BUFFER, 6 * sizeof(float), positions, GL_STATIC_DRAW);
    glEnableVertexAttribArray(0);
    glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, sizeof(float) * 2, 0);

    std::string vertexShader =
        "#version 410 core\n"
        "\n"
        "layout(location = 0) in vec4 position;"
        "\n"
        "void main()\n"
        "   gl_Position = position;\n"
        "\n";

    std::string fragmentShader =
        "#version 410 core\n"
        "\n"
        "layout(location = 0) out vec4 color;"
        "\n"
        "void main()\n"
        "   color = vec4(1.0, 0.0, 0.0, 1.0);\n"
        "\n";
    unsigned int shader = CreateShader(vertexShader, fragmentShader);
    glUseProgram(shader);

    /* Loop until the user closes the window */
    while (!glfwWindowShouldClose(window))
    
        /* Render here */
        glClear(GL_COLOR_BUFFER_BIT);

        glDrawArrays(GL_TRIANGLES, 0, 3);

       /* glBegin(GL_TRIANGLES);
        glVertex2f(-0.5, -0.5);
        glVertex2f(0, 0.5);
        glVertex2f(0.5, -0.5);

        glEnd();
        */
        /* Swap front and back buffers */
        glfwSwapBuffers(window);

        /* Poll for and process events */
        glfwPollEvents();
    

    glfwTerminate();
    return 0;

【问题讨论】:

您可以考虑查看learnopengl.com/Getting-started/Hello-Triangle 以供参考。你用的是什么平台? 【参考方案1】:

几个问题:

您正在请求 GL 3.2 上下文,但使用的是 #version 410 着色器;您请求的 GL 上下文版本应该达到或超过您的目标着色器版本。将您请求的 GL 版本提升到 4.1,或者将您的 GLSL #version 退回到 150。 调用glfwWindowHint() 之后 glfwCreateWindow() 不会做任何有用的事情;它只会影响 next glfwCreateWindow() 调用。 顶点数组对象 (VAO) 在核心上下文中不是可选的:您需要一个绑定来绘制任何东西。在程序开始时生成一个并在整个过程中保持绑定是非常好的。 glValidateProgram() 本身通常并不像听起来那么有用(如果您实际上不检查 GL_VALIDATE_STATUS 则更是如此);如果您想验证您的程序是否已成功链接,请改为查询 GL_LINK_STATUS

大家一起:

#include <GL/glew.h>
#include <GLFW/glfw3.h>
#include <iostream>
#include <cstdarg>

struct Program

    static GLuint Load( const char* shader, ... )
    
        GLuint prog = glCreateProgram();
        va_list args;
        va_start( args, shader );
        while( shader )
        
            const GLenum type = va_arg( args, GLenum );
            AttachShader( prog, type, shader );
            shader = va_arg( args, const char* );
        
        va_end( args );
        glLinkProgram( prog );
        CheckStatus( prog );
        return prog;
    

private:
    static void CheckStatus( GLuint obj )
    
        GLint status = GL_FALSE;
        if( glIsShader(obj) ) glGetShaderiv( obj, GL_COMPILE_STATUS, &status );
        if( glIsProgram(obj) ) glGetProgramiv( obj, GL_LINK_STATUS, &status );
        if( status == GL_TRUE ) return;
        GLchar log[ 1 << 15 ] =  0 ;
        if( glIsShader(obj) ) glGetShaderInfoLog( obj, sizeof(log), NULL, log );
        if( glIsProgram(obj) ) glGetProgramInfoLog( obj, sizeof(log), NULL, log );
        std::cerr << log << std::endl;
        std::exit( EXIT_FAILURE );
    

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

int main()

    if( !glfwInit() )
        return -1;

    /* Core profile */
    glfwWindowHint( GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE );
    glfwWindowHint( GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE );
    glfwWindowHint( GLFW_CONTEXT_VERSION_MAJOR, 4 );
    glfwWindowHint( GLFW_CONTEXT_VERSION_MINOR, 1 );

    /* Create a windowed mode window and its OpenGL context */
    GLFWwindow* window = glfwCreateWindow( 640, 480, "Hello World", NULL, NULL );
    if( !window )
    
        glfwTerminate();
        return -1;
    

    /* Make the window's context current */
    glfwMakeContextCurrent( window );

    if( glewInit() != GLEW_OK )
        std::cout << "error!";

    std::cout << "Version: " << glGetString( GL_VERSION ) << " :Version " << std::endl;

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

    float positions[ 6 ] =
    
        -0.5f, -0.5f,
        0.0f,  0.5f,
        0.5f, -0.5f,
    ;
    unsigned int buffer;
    glGenBuffers( 1, &buffer );
    glBindBuffer( GL_ARRAY_BUFFER, buffer );
    glBufferData( GL_ARRAY_BUFFER, 6 * sizeof( float ), positions, GL_STATIC_DRAW );
    glEnableVertexAttribArray( 0 );
    glVertexAttribPointer( 0, 2, GL_FLOAT, GL_FALSE, sizeof( float ) * 2, 0 );

    std::string vertexShader =
        "#version 410 core\n"
        "layout(location = 0) in vec4 position;\n"
        "void main()\n"
        "   gl_Position = position;\n"
        "\n";

    std::string fragmentShader =
        "#version 410 core\n"
        "layout(location = 0) out vec4 color;\n"
        "void main()\n"
        "   color = vec4(1.0, 0.0, 0.0, 1.0);\n"
        "\n";
    unsigned int shader = Program::Load( vertexShader.c_str(), GL_VERTEX_SHADER, fragmentShader.c_str(), GL_FRAGMENT_SHADER, NULL );
    glUseProgram( shader );

    while( !glfwWindowShouldClose( window ) )
    
        glClear( GL_COLOR_BUFFER_BIT );

        glDrawArrays( GL_TRIANGLES, 0, 3 );

        glfwSwapBuffers( window );

        glfwPollEvents();
    

    glfwTerminate();
    return 0;

【讨论】:

以上是关于OpenGL 三角形不会在 macOS 上渲染?的主要内容,如果未能解决你的问题,请参考以下文章

[go + SDL + OpenGL + MacOS示例=在DrawArrays()之后我得到了INVALID_OPERATION

用 D 语言用 OpenGL 3 渲染一个简单的矩形

OpenGL三角形不渲染

OpenGL不使用纹理渲染

openGL 索引渲染问题

OpenGL 忽略四边形并将它们变成三角形