2012-08-11 134 views
2

我想在Mac上创建一个GLSL示例。我试图为每个顶点设置一个颜色属性。但是,当程序运行时,我只会看到一个紫色屏幕(紫色来自glClearColor)。我发布了相关的代码片段。GLSL示例不能在mac上工作

-(void)drawRect:(NSRect)dirtyRect 
{  
    // get program ID for shader program 
    GLuint programID = [self loadShaders]; 

    // get new dimensions 
    NSSize dim = [self frame].size; 

    // clear the background with color 
    glClearColor(0.4f, 0.1f, 0.7f, 1.0f); 
    glDepthRange(1.0, -1.0); 
    glViewport(0, 0, dim.width, dim.height); 
    glClear(GL_COLOR_BUFFER_BIT); 

    // generate a buffer for our triangle 
    glGenBuffers(2, vertexBuffer); 

    glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer[0]); 
    glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW); 
    glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer[1]); 
    glBufferData(GL_ARRAY_BUFFER, sizeof(colors), colors, GL_STATIC_DRAW); 

    glUseProgram(programID); 

    glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer[0]); 
    glEnableVertexAttribArray(0); 
    glVertexAttribPointer(VERTEX_POS_INDEX, VERTEX_POS_SIZE, GL_FLOAT, GL_FALSE, VERTEX_POS_SIZE*sizeof(vertices), vertices); 

    glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer[1]); 
    glEnableVertexAttribArray(1); 
    glVertexAttribPointer(VERTEX_COLOR_INDEX, VERTEX_COLOR_SIZE, GL_FLOAT, GL_FALSE, VERTEX_POS_SIZE*sizeof(colors), colors); 

    glDrawArrays(GL_TRIANGLES, 0, 3); 

    glDisableVertexAttribArray(0); 
    glDisableVertexAttribArray(1); 
    glUseProgram(0); 

    // flush buffer 
    glFlush(); 
    [[self openGLContext] flushBuffer]; 
} 

然后加载阴影代码:

-(GLuint)loadShaders 
{ 
    printf("GLSL version %s\n", glGetString(GL_SHADING_LANGUAGE_VERSION)); 
    printf("GL Version: %s", glGetString(GL_VERSION)); 

    // Create the shaders 
    GLuint vertexShaderID = glCreateShader(GL_VERTEX_SHADER); 
    GLuint fragmentShaderID = glCreateShader(GL_FRAGMENT_SHADER); 

    // get handle for app bundle 
    NSBundle *appBundle = [NSBundle mainBundle]; 

    // get the path for the vertex shader file 
    NSString *vertexFilePath = [appBundle pathForResource:vertexShaderFile ofType:nil]; 
    // get the path for the fragment shader file 
    NSString *fragmentFilePath = [appBundle pathForResource:fragmentShaderFile ofType:nil]; 

    // get the contents of the vertex shader file into a string 
    NSString *vertexFileContents = [NSString stringWithContentsOfFile:vertexFilePath encoding:NSUTF8StringEncoding error:NULL]; 
    NSLog(@"%@", vertexFileContents); 
    // get the contents of the fragment shader file into a string 
    NSString *fragmentFileContents = [NSString stringWithContentsOfFile:fragmentFilePath encoding:NSUTF8StringEncoding error:NULL]; 
    NSLog(@"%@", fragmentFileContents); 

    GLint Result = GL_FALSE; 
    int infoLogLength; 

    // get a pointer the vertex shader program source, compile shader program 
    const char *vertexSourcePointer = [vertexFileContents UTF8String]; 
    glShaderSource(vertexShaderID, 1, &vertexSourcePointer, NULL); 
    glCompileShader(vertexShaderID); 
    // check the vertex shader 
    glGetShaderiv(vertexShaderID, GL_COMPILE_STATUS, &Result); 
    glGetShaderiv(vertexShaderID, GL_INFO_LOG_LENGTH, &infoLogLength); 
    char vertexShaderErrorMessage[infoLogLength]; 
    glGetShaderInfoLog(vertexShaderID, infoLogLength, NULL, vertexShaderErrorMessage); 
    // print error message 
    NSLog(@"%@", [NSString stringWithUTF8String:vertexShaderErrorMessage]); 

    // get a pointer to the fragment shader program source, compile shader program 
    const char *fragmentSourcePointer = [fragmentFileContents UTF8String]; 
    glShaderSource(fragmentShaderID, 1, &fragmentSourcePointer, NULL); 
    glCompileShader(fragmentShaderID); 
    // check the fragment shader 
    glGetShaderiv(fragmentShaderID, GL_COMPILE_STATUS, &Result); 
    glGetShaderiv(fragmentShaderID, GL_INFO_LOG_LENGTH, &infoLogLength); 
    char fragmentShaderErrorMessage[infoLogLength]; 
    glGetShaderInfoLog(fragmentShaderID, infoLogLength, NULL, fragmentShaderErrorMessage); 
    // print error message 
    NSLog(@"%@", [NSString stringWithUTF8String:fragmentShaderErrorMessage]); 

    // link the program 
    NSLog(@"Linking program..."); 
    GLuint programID = glCreateProgram(); 
    glAttachShader(programID, vertexShaderID); 
    glAttachShader(programID, fragmentShaderID); 

    glBindAttribLocation(programID, 0, "position"); 
    glBindAttribLocation(programID, 1, "inColor"); 

    glLinkProgram(programID); 

    // check the program 
    glGetProgramiv(programID, GL_LINK_STATUS, &Result); 
    glGetProgramiv(programID, GL_INFO_LOG_LENGTH, &infoLogLength); 
    char shaderProgramErrorMessage[max(infoLogLength, (int)1)]; 
    glGetProgramInfoLog(programID, infoLogLength, NULL, shaderProgramErrorMessage); 
    // pring error message 
    NSLog(@"%@", [NSString stringWithUTF8String:shaderProgramErrorMessage]); 

    // delete shaders 
    glDeleteShader(vertexShaderID); 
    glDeleteShader(fragmentShaderID); 

    return programID; 

} 

最后的着色器:

#version 120 

attribute vec4 position; 
attribute vec4 inColor; 
varying vec4 outColor; 
void main() 
{ 
    gl_Position = position; 
    outColor = inColor; 
} 

而且

#version 120 

varying vec4 outColor; 
void main() 
{ 
    gl_FragColor = outColor; 
} 

回答

1

看起来相当不错,虽然我看到一个错误。

glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer[0]); 
glEnableVertexAttribArray(0); 
glVertexAttribPointer(VERTEX_POS_INDEX, 
         VERTEX_POS_SIZE, 
         GL_FLOAT, 
         GL_FALSE, 
         VERTEX_POS_SIZE*sizeof(vertices), 
         vertices); 

如果您正在使用VBO,那么最终属性glVertexAttribPointer应该是从当前绑定的缓冲区开始的偏移量

如果您使用的是顶点数组(无glBindBuffer),那么您将指向具有glVertexAttribPointer最终参数的顶点。

不过,既然你已经上传vertices到缓冲和约束它,glVertexAttribPointer的终值应为偏移从顶点缓冲区,而你的情况,应该是0的开始。

颜色缓冲区也是一样的错误。

+0

我明白了。将张贴代码,但我被网站通知我需要10分才有这个特权。 – xBACP 2012-08-11 22:19:39

+0

我不确定我是否理解。你想发布哪些代码?如果这篇文章解决了您的问题,则无需发布其他任何内容,但鼓励的操作是单击解决问题的答案旁边的绿色复选标记。否则,如果你仍然有麻烦,请让我知道。 @OneDaySoon – Tim 2012-08-11 22:25:46

+0

我想以一个答案的形式发布更正后的代码,但因为我是10岁以下的新成员,所以我无法做到。 – xBACP 2012-08-11 22:28:52