macOS 上无法解释的 OpenGl 着色器行为

Inesplicable OpenGl shader behaviour on macOSX

我创建了顶点数组,我创建了着色器,编译并 link 它们,但是当我使用 drawarrays 时没有任何反应。

屏幕上没有绘制几何图形,而我应该看到一个红色三角形。
命令行没有错误,一点问题都没有,但三角形不会出现。

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

using namespace std;

static GLuint compileShader(const string& source,GLuint type);
static int createShader(const string& vertexShader, const string& fragment);

int main(void){

    // I INITIALISE GLFW TO HAVE THE LATEST VERSION OF THE SHADER VERSION
    glfwInit();
    glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
    glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
    glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);
    glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);


    //I CREATE THE WINDOW
    GLFWwindow* window = glfwCreateWindow(800,600,"Dio suino",NULL,NULL);
    glfwMakeContextCurrent(window);
    glewExperimental= GL_TRUE;

    //I INITIALISE GLEW
    if(glewInit()!=GLEW_OK){
        fprintf(stderr,"ERROR");
        exit(1);
    }

    //I SPECIFY THE VERTEX DATA
    float bufferData[6]={
        0.5,-0.5,
        -0.5,-0.5,
        0.0,0.5
    };

    GLuint bufferId;

    // I CREATE THE BUFFER, BIND IT AND SPECIFY ALL THE INFO NEEDED
    glGenBuffers(1,&bufferId);

    glBindBuffer(GL_ARRAY_BUFFER,bufferId);
    glBufferData(GL_ARRAY_BUFFER,6*sizeof(float),bufferData,GL_STATIC_DRAW);
    glVertexAttribPointer(0,2,GL_FLOAT,GL_FALSE,2*sizeof(float),0);
    glEnableVertexAttribArray(0);


    // I CREATE THE VERTEX AND FRAGMENT SHADERS
    string vs,fs;

    vs = 
    "#version 330 core \n"
    "in vec4 position;\n"
    "\n"
    "void main()\n"
    "{\n"
    "    gl_Position = position;\n"
    "}\n";

    fs =
    "#version 330 core \n"
    "out vec4 color;\n"
    "\n"
    "void main()\n"
    "{\n"
    "    color = vec4(1.0,0.0,0.0,1.0);\n"
    "}\n";

    //I USE THE PROGRAM
    int shaderProgram = createShader(vs,fs);
    glUseProgram(shaderProgram);
    glBindBuffer(GL_ARRAY_BUFFER,0);


    // WINDOW LOOP: CLEAR COLOR, SWAP BUFFER ECC
    while(!glfwWindowShouldClose(window)){


        glClearColor(0,60,80,0);
        glClear(GL_COLOR_BUFFER_BIT);

        glDrawArrays(GL_TRIANGLES,0,3); 

        glfwSwapBuffers(window);

        glfwPollEvents();


    }

    cout<< glGetString(GL_VERSION)<<endl;

    return 0;
}

//CREATES THE SHADER PROGRAM WITH ALL THE SHADERS LINKED
static int createShader(const string& vertexShader, const string& fragment)
{
    GLuint program = glCreateProgram();
    GLuint vs = compileShader(vertexShader,GL_VERTEX_SHADER);
    GLuint fs = compileShader(fragment,GL_FRAGMENT_SHADER);

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

    glDeleteShader(vs);
    glDeleteShader(fs);

    return program;
}

//COMPILES THE SHADER
static GLuint compileShader(const string& source,GLuint type)
{
    GLuint id = glCreateShader(type);
    const char* src = source.c_str();
    glShaderSource(id,1,&src,nullptr);
    glCompileShader(id);

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

    if(debug == GL_FALSE){

        int length;
        glGetShaderiv(id,GL_INFO_LOG_LENGTH,&length);
        char message[length];
        glGetShaderInfoLog(id,length,&length,message);
        fprintf(stderr,"Something went wrong in the shader of type %i: %s",type,message);
        glDeleteShader(id);
    }

    return id;
}

现在这些是我包含的库。
生成文件:

CC = clang++
MAIN = main.cpp
LIB = -lglew -lglfw 
FWORK = -framework OpenGl
NAME = -o dio -std=c++11

all:
    ${CC} ${MAIN} ${LIB} ${FWORK} ${NAME}

我做错了什么?

当您使用核心配置文件时OpenGL Context, then you have to create an named Vertex Array Object,因为默认的 VAO (0) 无效。 VAO 规定了顶点数组的规范。

如果您的硬件和驱动程序支持(可能不支持 macOSX),您可以切换到兼容性配置文件上下文来解决问题:

https://www.khronos.org/opengl/wiki/Vertex_Specification#Vertex_Array_Object:

glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);

glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_COMPAT_PROFILE);

但是,我建议在指定通用顶点数组数据之前创建一个顶点数组对象。当调用 glVertexAttribPointer and glEnableVertexAttribArray 时,必须绑定 VAO,因为这条指令改变了 VAO 的状态向量:

GLuint bufferId;
glGenBuffers(1,&bufferId);
glBindBuffer(GL_ARRAY_BUFFER,bufferId);
glBufferData(GL_ARRAY_BUFFER,6*sizeof(float),bufferData,GL_STATIC_DRAW);

GLuint vao;
glGenVertexArrays( 1, &vao );
glBindVertexArray( vao );
glVertexAttribPointer(0,2,GL_FLOAT,GL_FALSE,2*sizeof(float),0);
glEnableVertexAttribArray(0);