让GLSL 1.5在Mac OS X上运行

The*_*mer 0 opengl macos shader objective-c

我正在尝试在我的程序中创建自己的顶点和片段着色器(这基本上是一个非常简单的程序,用VBO显示一个三角形).但是,当我尝试运行它时,我总是会看到一个没有任何显示的黑屏.我检查了编译日志,它返回没有错误.我还没有使用我自己的自定义着色器运行程序,这让我想知道我在这里做错了什么.我在OpenGL 3.2和GLSL 1.5上运行我的代码

以下是我正在尝试运行的代码


GLuint vbo;

GLfloat data[] = {0.0, 0.0, -5.0,
                  1.0, 0.0, -5.0,
                  1.0, 1.0, -5.0
};

const char *vertexShader = "\n\
#version 150\n\
\n\
layout (location=0) in vec4 position;\n\
void main()\n\
{\n\
gl_Position = position;\n\
}\n\
";

const char *fragmentShader = "\n\
#version 150\n\
\n\
out vec4 outColor;\n\
\n\
void main()\n\
{\n\
    outColor = vec4(1.0, 0.0, 0.0, 1.0);\n\
}";


- (void)drawRect:(NSRect)dirtyRect
{
    glClear(GL_COLOR_BUFFER_BIT);

    glMatrixMode(GL_MODELVIEW);

    glLoadIdentity();

    glUseProgram(programId);

    glBindBuffer(GL_ARRAY_BUFFER, vbo);
    glEnableVertexAttribArray(0);
    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0);

    glEnableClientState(GL_VERTEX_ARRAY);

    glVertexPointer(3, GL_FLOAT, 0, 0);

    glDrawArrays(GL_TRIANGLES, 0, sizeof(data));

    glFlush();


    glDisableClientState(GL_VERTEX_ARRAY);

}

-(void)reshape
{
    glViewport(0, 0, w, h);
    gluPerspective(45.0,                  //The camera angle
                   (double)w / (double)h, //The width-to-height ratio
                   1.0,                   //The near z clipping coordinate
                   200.0); 
}

-(void)prepareOpenGL
{
    glEnable(GL_DEPTH_TEST);  

    glGenBuffersARB(1, &vbo);
    glBindBufferARB(GL_ARRAY_BUFFER_ARB, vbo);
    glBufferDataARB(GL_ARRAY_BUFFER_ARB, sizeof(data), data, GL_STATIC_DRAW);

    glVertexAttribPointer(0, 3, GL_FLOAT, 0, 0, 0);


    vertexShaderId = glCreateShader(GL_VERTEX_SHADER);
    glShaderSource(vertexShaderId, 1, &vertexShader, NULL);

    glCompileShader(vertexShaderId);

    GLint completed;
    glGetShaderiv(vertexShaderId, GL_COMPILE_STATUS, &completed);

    if (!completed)
    {
        GLint length;
        GLchar *log;
        glGetShaderiv(vertexShaderId, GL_INFO_LOG_LENGTH, &length);

        log = (GLchar *)malloc(length);
        glGetShaderInfoLog(vertexShaderId, length, &length, log);
        fprintf(stderr, "Vertex compile log = '%s'\n", log);
    }



    fragmentShaderId = glCreateShader(GL_FRAGMENT_SHADER);
    glShaderSource(fragmentShaderId, 1, &fragmentShader, NULL);
    glCompileShader(fragmentShaderId);

    GLint complete;

    glGetShaderiv(fragmentShaderId, GL_COMPILE_STATUS, &complete);

    if (!complete)
    {
        GLint length;
        GLchar *log;
        glGetShaderiv(fragmentShaderId, GL_INFO_LOG_LENGTH, &length);

        log = (GLchar *)malloc(length);
        glGetShaderInfoLog(fragmentShaderId, length, &length, log);
        fprintf(stderr, "fragment compile log = '%s'\n", log);
    }

    programId = glCreateProgram();

    glAttachShader(programId, vertexShaderId);
    glAttachShader(programId, fragmentShaderId);

    glLinkProgram(programId);

    glUseProgram(programId);
}
Run Code Online (Sandbox Code Playgroud)

Nic*_*las 9

这里有几个问题.从上到下:


GLfloat data[] = {0.0, 0.0, -5.0,
                  1.0, 0.0, -5.0,
                  1.0, 1.0, -5.0
};
Run Code Online (Sandbox Code Playgroud)

此数据不可见,因为Z值超出了查看量[-1,1].尝试使用0.0代替.


#version 150\n\
\n\
layout (location=0) in vec4 position;
Run Code Online (Sandbox Code Playgroud)

layout(location=0) 在两种情况下,只适用于顶点着色器输入:

  1. 您使用的是GLSL 3.30或更高版本.你的着色器说#version 150.
  2. 您正在使用ARB_explicit_attrib_location扩展.在这种情况下,您需要#extension声明才能在着色器中激活它.另外,我知道一个事实,即OSX的GL 3.2支持并没有提供这个扩展.

所以你需要用老式的方式来做:用glBindAttribLocation.链接程序之前使用此功能.


glEnableClientState(GL_VERTEX_ARRAY);
glVertexPointer(3, GL_FLOAT, 0, 0);
Run Code Online (Sandbox Code Playgroud)

这不仅是不必要的,它还会对您尝试完成的操作产生主动破坏性,因为它会在您尝试渲染时导致生成OpenGL错误.

如果您使用的是通用属性,则不需要旧式属性.


glDrawArrays(GL_TRIANGLES, 0, sizeof(data));
Run Code Online (Sandbox Code Playgroud)

sizeof(data)是数组的大小(以字节单位)data.在大多数机器上,那将是36.你没有渲染36个顶点; 你渲染三个.所以这应该是:

glDrawArrays(GL_TRIANGLES, 0, 3);
Run Code Online (Sandbox Code Playgroud)
gluPerspective(45.0,                  //The camera angle
               (double)w / (double)h, //The width-to-height ratio
               1.0,                   //The near z clipping coordinate
               200.0); 
Run Code Online (Sandbox Code Playgroud)

这不是一个完全没有意义的问题.您使用着色器进行渲染,而您没有使用内置矩阵.这什么都不做.


glGenBuffersARB(1, &vbo);
glBindBufferARB(GL_ARRAY_BUFFER_ARB, vbo);
glBufferDataARB(GL_ARRAY_BUFFER_ARB, sizeof(data), data, GL_STATIC_DRAW);
Run Code Online (Sandbox Code Playgroud)

这也可能不是"问题",但也可能是.以"ARB"结尾的函数和枚举器代表OpenGL扩展.因此,您正在使用ARB_vertex_buffer_object扩展所公开的函数.

自GL 1.4以来,此扩展一直是核心.实际上,您甚至没有始终如一地使用扩展(这可能是出现问题的地方).您使用ARB扩展为您设置缓冲区的数据,但在渲染时使用核心功能.

只是抛弃ARB扩展的东西并使用核心功能.


    log = (GLchar *)malloc(length);
    glGetShaderInfoLog(vertexShaderId, length, &length, log);
    fprintf(stderr, "Vertex compile log = '%s'\n", log);
Run Code Online (Sandbox Code Playgroud)

这不会导致错误,但是......你的呼叫在free哪里?


glLinkProgram(programId);
glUseProgram(programId);
Run Code Online (Sandbox Code Playgroud)

编译着色器链接程序后,应始终 检查错误.


您的代码似乎是从各种来源复制粘贴在一起,形成某种科学怪人的程序.您的大部分问题源于不同的代码,这些代码与您计划使用它们的方式有所不同.你真的应该调查这些东西是如何运作的; 这样,你就不会遇到这些问题.

  • @theAmateurProgrammer:不,这是问题; 它只不是*唯一的*.看我的编辑. (2认同)