美文网首页iOS开发笔记
OpenGLES入门(二)创建program

OpenGLES入门(二)创建program

作者: 武小寺 | 来源:发表于2016-06-12 16:02 被阅读1824次

    iOS代码

    /*
     * 
     * VertexShader-用于渲染形状的顶点的OpenGLES 图形代码。
     * FragmentShader-用于渲染形状的外观(颜色或纹理)的OpenGLES 代码。
     * Program-一个OpenGLES对象,包含了你想要用来绘制一个或多个形状的shader。
     *
     */
    // 创建program
    + (GLuint)createAndLinkProgramWith:(GLuint)vsHandle fsHandle:(GLuint)fsHandle attrs:(NSArray*)attrs {
        //创建一个空的OpenGL ES Program
        GLuint programHandle = glCreateProgram();
        if (programHandle != 0) {
             // 将vertex shader添加到program
            glAttachShader(programHandle, vsHandle);
            // 将fragment shader添加到program
            glAttachShader(programHandle, fsHandle);
            
            if (attrs != nil) {
                for (int i = 0; i < attrs.count; i++) {
                    //把program的顶点属性索引与顶点shader中的变量名进行绑定
                    glBindAttribLocation(programHandle, i, [[attrs objectAtIndex:i] UTF8String]);
                }
            }
            GLint status;
             // 创建可执行的 OpenGL ES program
            glLinkProgram(programHandle);
            // glValidateProgram(programHandle);
            // 获取program对象的参数值
            glGetProgramiv(programHandle, GL_LINK_STATUS, &status);
            if (status == GL_FALSE){
                if (vsHandle) glDeleteShader(vsHandle);
                if (fsHandle) glDeleteShader(fsHandle);
                programHandle = 0;
            }
        }
        assert(programHandle != 0);
        
        return programHandle;
    }
    

    安卓代码

    private int createProgram(String vertexSource, String fragmentSource) 
    {
      // 加载顶点着色器
      int vertexShader = loadShader(GLES20.GL_VERTEX_SHADER, vertexSource);
      if (vertexShader == 0) 
      {
        return 0;
      }
      
      // 加载片元着色器
      int pixelShader = loadShader(GLES20.GL_FRAGMENT_SHADER, fragmentSource);
      if (pixelShader == 0) 
      {
        return 0;
      }
    
      // 创建着色器程序
      int program = GLES20.glCreateProgram();
      // 若程序创建成功则向程序中加入顶点着色器与片元着色器
      if (program != 0) 
      {
        // 向程序中加入顶点着色器
        GLES20.glAttachShader(program, vertexShader);
        // 向程序中加入片元着色器
        GLES20.glAttachShader(program, pixelShader);
        // 链接程序
        GLES20.glLinkProgram(program);
        // 存放链接成功program数量的数组
        int[] linkStatus = new int[1];
        // 获取program的链接情况
        GLES20.glGetProgramiv(program, GLES20.GL_LINK_STATUS, linkStatus, 0);
        // 若链接失败则报错并删除程序
        if (linkStatus[0] != GLES20.GL_TRUE) 
        {
          Log.e(TAG, "Could not link program: ");
          Log.e(TAG, GLES20.glGetProgramInfoLog(program));
          GLES20.glDeleteProgram(program);
          program = 0;
        }
      }
    
      // 释放shader资源
      GLES20.glDeleteShader(vertexShader );
      GLES20.glDeleteShader(pixelShader);
    
      return program;
    }
    

    1. glCreateProgram

    在连接shader之前,首先要创建一个容纳程序的容器,称为着色器程序容器。可以通过glCreateProgram函数来创建一个程序容器。

    函数原型:
    int glCreateProgram ()
    如果函数调用成功将返回一个正整数作为该着色器程序的id。

    2.glAttachShader

    接下来,我们要将shader容器添加到程序中。这时的shader容器不一定需要被编译,他们甚至不需要包含任何的代码。我们要做的只是将shader容器添加到程序中。使用glAttachShader函数来为程序添加shader容器。

    函数原型:
    void glAttachShader (int program, int shader)
    参数含义:
    program是着色器程序容器的id;
    shader是要添加的顶点或者片元shader容器的id。

    3. glLinkProgram

    链接程序。

    函数原型:
    void glLinkProgram (int program)
    参数含义:
    program是着色器程序容器的id。

    在链接操作执行以后,可以任意修改shader的源代码,对shader重新编译不会影响整个程序,除非重新链接程序。

    4.glUseProgram

    加载并使用链接好的程序。

    函数原型:
    void glUseProgram (int program)
    参数含义:
    program是要使用的着色器程序的id。

    如果将program设置为0,表示使用固定功能管线。如果程序已经在使用的时候,对程序进行重新编译,编译后的应用程序会自动替代以前的那个被调用,这时你不需要再次调用这个函数。

    相关文章

      网友评论

        本文标题:OpenGLES入门(二)创建program

        本文链接:https://www.haomeiwen.com/subject/bziedttx.html