HTML5   发布时间:2022-04-27  发布网站:大佬教程  code.js-code.com
大佬教程收集整理的这篇文章主要介绍了OpenGL ES 2.0如何在iOS中使用不同的着色器程序绘制多个VBO大佬教程大佬觉得挺不错的,现在分享给大家,也给大家做个参考。
我试图破解通用 @L_262_0@ iOS OpenGL游戏模板来绘制两个顶点缓冲区对象并使用不同的GLSL着色器渲染它们.
我想’我正在渲染两个VBO? (因为我在通过第一个着色器程序运行两个VBO时都看到它们)但是,我的第二个着色器似乎根本不渲染我的第二个对象.

这是两个正方形的顶点数据:

GLfloat gCubeVertexData[36] = 
{
    // Data layout for each line below is:
    // positionX,positionY,positionZ,normalX,normalY,normalZ,0.5f,0.0f,1.0f,-0.5f,1.0f

};

GLfloat fooVertexData[36] = 
{
    // Data layout for each line below is:
    // positionX,normalZ

    0.5f,1.0f
};@H_616_11@ 
 

这是我试生成两个VBO并将它们绑定到数据的地方.不知道’glBindVertexArrayOES(0)’的目的是什么呢?

- (void)setupGL
{
    [EAGLContext setCurrentContext:self.context];

    [self loadShaders];

    //---- First Vertex Array Object --------
    glGenVertexArraysOES(1,&_vertexArray1);
    glGenBuffers(1,&_vertexBuffer1);   

    glBindVertexArrayOES(_vertexArray1);

    glBindBuffer(GL_ARRAY_BUFFER,_vertexBuffer1);
    glBufferData(GL_ARRAY_BUFFER,sizeof(gCubeVertexData),gCubeVertexData,GL_STATIC_DRAW);

    glEnabLevertexAttribArray(GLKVertexAttribPosition);
    glVertexAttribPointer(GLKVertexAttribPosition,3,GL_FLOAT,GL_falSE,24,BUFFER_OFFSET(0));
    glEnabLevertexAttribArray(GLKVertexAttribNormal);
    glVertexAttribPointer(GLKVertexAttribNormal,BUFFER_OFFSET(12));

    //----- Second Vertex Array Object ----------
    glGenVertexArraysOES(1,&_vertexArray2);
    glGenBuffers(1,&_vertexBuffer2);

    glBindVertexArrayOES(_vertexArray2);

    glBindBuffer(GL_ARRAY_BUFFER,_vertexBuffer2);
    glBufferData(GL_ARRAY_BUFFER,sizeof(fooVertexData),fooVertexData,BUFFER_OFFSET(12));

    glBindBuffer(GL_ARRAY_BUFFER,0);
    glBindVertexArrayOES(0);
}@H_616_11@ 
 

我正在使用此更新代码为模型 – 视图 – 投影矩阵设置动画:

- (void)update
{
    _rotation += self.timeSinceLastupdate * 0.2f;

    float aspect = fabsf(self.view.bounds.size.width / self.view.bounds.size.height);

    GLKMatrix4 projectionMatrix = GLKMatrix4MakeOrtho(-1.0f,-1.0f / aspect,1.0f / aspect,-10.0f,10.0f);
    GLKMatrix4 modelViewMatrix = GLKMatrix4MakeTranslation(0.5f,0.0f);
    modelViewMatrix = GLKMatrix4Multiply(modelViewMatrix,GLKMatrix4MakeZRotation(0.0 - _rotation));
    _modelViewProjectionMatrix = GLKMatrix4Multiply(projectionMatrix,modelViewMatriX);

    GLKMatrix4 modelViewMatrix2 = GLKMatrix4MakeTranslation(-0.5f,0.0f);
    modelViewMatrix2 = GLKMatrix4Multiply(modelViewMatrix2,GLKMatrix4MakeZRotation(_rotation));
    _modelViewProjectionMatrix2 = GLKMatrix4Multiply(projectionMatrix,modelViewMatrix2);
}@H_616_11@ 
 

当我调用’_program2’着色器时,我看不到第二个方块:

- (void)glkView:(GLKView *)view drawInRect:(CGRect)rect
{
    glClearColor(0.65f,0.65f,1.0f);
    glClear(GL_COLOR_BUFFER_BIT);

    glBindVertexArrayOES(_vertexArray1);
    glBindBuffer(GL_ARRAY_BUFFER,_vertexBuffer1);

    glUseProgram(_program);
    glUniformMatrix4fv(uniforms[UNIFORM_MODELVIEWPROjeCTION_MATRIX],1,_modelViewProjectionMatrix.m);
    glDrawArrays(GL_TRIANGLES,6);

    ///////// second object and shader program:
    glBindVertexArrayOES(_vertexArray2);
    glBindBuffer(GL_ARRAY_BUFFER,_vertexBuffer2);

    glUseProgram(_program2);
    glUniformMatrix4fv(uniforms[UNIFORM_MODELVIEWPROjeCTION_MATRIX2],_modelViewProjectionMatrix2.m);
    glDrawArrays(GL_TRIANGLES,6);

}@H_616_11@ 
 

我基本上尝试复制加载第一个着色器的代码,加载第二个着色器.我怀疑我可能在这里做错了..但我不确定是什么:

- (BOOL)loadShaders
{
    GLuint vertShader,fragShader,vertShader2,fragShader2;
    NSString *vertShaderPathname,*fragShaderPathname,*vertShaderPathname2,*fragShaderPathname2;

    // Create shader program.
    _program = glCreateProgram();


    // Create and compile vertex shader.
    vertShaderPathname = [[NSBundle mainBundle] pathForresource:@"Shader" ofType:@"vsh"];
    if (![self compileShader:&vertShader type:GL_VERTEX_SHADER file:vertShaderPathname]) {
        NSLog(@"Failed to compile vertex shader");
        return NO;
    }

    // Create and compile fragment shader.
    fragShaderPathname = [[NSBundle mainBundle] pathForresource:@"Shader" ofType:@"fsh"];
    if (![self compileShader:&fragShader type:GL_FRAGMENT_SHADER file:fragShaderPathname]) {
        NSLog(@"Failed to compile fragment shader");
        return NO;
    }

    // Attach vertex shader to program.
    glAttachShader(_program,vertShader);

    // Attach fragment shader to program.
    glAttachShader(_program,fragShader);

    // Bind attribute LOCATIOns.
    // This needs to be done prior to linking.
    glBindAttribLOCATIOn(_program,ATTRIB_VERTEX,"position");

    // Link program.
    if (![self linkProgram:_program]) {
        NSLog(@"Failed to link program: %d",_program);

        if (vertShader) {
            gldeleteShader(vertShader);
            vertShader = 0;
        }
        if (fragShader) {
            gldeleteShader(fragShader);
            fragShader = 0;
        }
        if (_program) {
            gldeleteProgram(_program);
            _program = 0;
        }

        return NO;
    }

    // Get uniform LOCATIOns.
    uniforms[UNIFORM_MODELVIEWPROjeCTION_MATRIX] = glGetUniformLOCATIOn(_program,"modelViewProjectionMatrix");

    // Release vertex and fragment shaders.
    if (vertShader) {
        glDetachShader(_program,vertShader);
        gldeleteShader(vertShader);
    }
    if (fragShader) {
        glDetachShader(_program,fragShader);
        gldeleteShader(fragShader);
    }


    ///////////////// the second shader:

    _program2 = glCreateProgram();

    vertShaderPathname2 = [[NSBundle mainBundle] pathForresource:@"Shader2" ofType:@"vsh"];
    if (![self compileShader:&vertShader2 type:GL_VERTEX_SHADER file:vertShaderPathname2]) {
        NSLog(@"Failed to compile vertex shader2");
        return NO;
    }

    fragShaderPathname2 = [[NSBundle mainBundle] pathForresource:@"Shader2" ofType:@"fsh"];
    if (![self compileShader:&fragShader2 type:GL_FRAGMENT_SHADER file:fragShaderPathname2]) {
        NSLog(@"Failed to compile fragment shader2");
        return NO;
    }

        glAttachShader(_program2,vertShader2);
        glAttachShader(_program2,fragShader2);

        glBindAttribLOCATIOn(_program2,ATTRIB_VERTEX2,"position2");

    if (![self linkProgram:_program2]) {
        NSLog(@"Failed to link program: %d",_program2);

        if (vertShader2) {
            gldeleteShader(vertShader2);
            vertShader2 = 0;
        }
        if (fragShader2) {
            gldeleteShader(fragShader2);
            fragShader2 = 0;
        }
        if (_program2) {
            gldeleteProgram(_program2);
            _program2 = 0;
        }

        return NO;
    }

        uniforms[UNIFORM_MODELVIEWPROjeCTION_MATRIX2] = glGetUniformLOCATIOn(_program2,"modelViewProjectionMatrix2");
    if (vertShader2) {
        glDetachShader(_program2,vertShader2);
        gldeleteShader(vertShader2);
    }
    if (fragShader2) {
        glDetachShader(_program2,fragShader2);
        gldeleteShader(fragShader2);
    }    



    return YES;
}

- (BOOL)compileShader:(GLuint *)shader type:(GLenum)type file:(NSString *)file
{
    GLint status;
    const GLchar *source;

    source = (GLchar *)[[NSString StringWithContentsOfFile:file encoding:NSUTF8StringEncoding error:nil] UTF8String];
    if (!sourcE) {
        NSLog(@"Failed to load vertex shader");
        return NO;
    }

    *shader = glCreateShader(typE);
    glShadersource(*shader,&source,null);
    glCompileShader(*shader);

#if Defined(DEBUG)
    GLint logLength;
    glGetShaderiv(*shader,GL_INFO_LOG_LENGTH,&logLength);
    if (logLength > 0) {
        GLchar *log = (GLchar *)malloc(logLength);
        glGetShaderInfoLog(*shader,logLength,&logLength,log);
        NSLog(@"Shader compile log:\n%s",log);
        free(log);
    }
#endif

    glGetShaderiv(*shader,GL_COMPILE_STATUS,&status);
    if (status == 0) {
        gldeleteShader(*shader);
        return NO;
    }

    return YES;
}

- (BOOL)linkProgram:(GLuint)prog
{
    GLint status;
    glLinkProgram(prog);

#if Defined(DEBUG)
    GLint logLength;
    glGetProgramiv(prog,&logLength);
    if (logLength > 0) {
        GLchar *log = (GLchar *)malloc(logLength);
        glGetProgramInfoLog(prog,log);
        NSLog(@"Program link log:\n%s",log);
        free(log);
    }
#endif

    glGetProgramiv(prog,GL_LINK_STATUS,&status);
    if (status == 0) {
        return NO;
    }

    return YES;
}

- (BOOL)validateProgram:(GLuint)prog
{
    GLint logLength,status;

    glValidateProgram(prog);
    glGetProgramiv(prog,log);
        NSLog(@"Program validate log:\n%s",log);
        free(log);
    }

    glGetProgramiv(prog,GL_VALIDATE_STATUS,&status);
    if (status == 0) {
        return NO;
    }

    return YES;
}@H_616_11@ 
 

我的vert和片段着色器很简单:

// vert shader1:
attribute vec4 position;
uniform mat4 modelViewProjectionMatrix;

void main()
{
    gl_Position = modelViewProjectionMatrix * position;
}


// vert shader2:
attribute vec4 position2;
uniform mat4 modelViewProjectionMatrix2;

void main()
{
    gl_Position = modelViewProjectionMatrix2 * position2;
}


// frag shader(s):
void main()
{
    gl_FragColor = vec4(0.12,0.32,0.54,1.0);
}@H_616_11@

解决方法

使用OpenGL ES时最重要的一点是,您正在使用OOP语言中的过程语言.

您一次只能将一个顶点数组绑定到顶点缓冲区.

将两个顶点数组一个一个地绑定到VBO,然后应用变换,只会转换附加到VBO的最后一个顶点数组.

在主循环中,您必须遍历顶点数组列表.对于每个顶点数组,将其绑定到VBO,然后执行任何转换.

大佬总结

以上是大佬教程为你收集整理的OpenGL ES 2.0如何在iOS中使用不同的着色器程序绘制多个VBO全部内容,希望文章能够帮你解决OpenGL ES 2.0如何在iOS中使用不同的着色器程序绘制多个VBO所遇到的程序开发问题。

如果觉得大佬教程网站内容还不错,欢迎将大佬教程推荐给程序员好友。

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。