OpenGL ES学习之二---着色器与程序

主要代码来自《OpenGL.ES.3.0.Programming.Guide.2nd.Edition》 在原书代码基础上,加入到Cocos的工程。具体的使用及API介绍会在代码详细描述,原理及流程前面已经有所说明,不再赘述! 函数声明:

//加载编译Shader源码,返回shader实例句柄
static GLuint LoadShader(GLenum type, const char shaderSrc);
//加载程序,返回程序句柄
static GLuint LoadProgram(const char \
vertShaderSrc, const char *fragShaderSrc);

函数定义:

GLuint GLShader::LoadShader(GLenum type, const char *shaderSrc)
{
    GLuint shader;
    GLint compiled;

    // Create the shader object
    //函数原型:
    //    int glCreateShader(int type)
    //    方法参数:
    //    GL\_VERTEX\_SHADER(顶点shader)
    //    GL\_FRAGMENT\_SHADER(片元shader)
    shader = glCreateShader(type);

    if (shader == 0)
        return 0;

    // Load the shader source
    //函数原型:
    //    void glShaderSource(int shader, String string)
    //    参数含义:
    //    shader是代表shader容器的id(由glCreateShader返回的整形数);
    //    string是包含源程序的字符串数组。
    glShaderSource(shader, 1, &shaderSrc, NULL);

    // Compile the shader
    //函数原型:
    //    void glCompileShader(int shader)
    //    参数含义:
    //    shader是代表shader容器的id。
    glCompileShader(shader);

    // Check the compile status
    //编译阶段使用glGetShaderiv获取编译情况
    //函数原型:
    //    void glGetShaderiv(int shader, int pname, int\[\] params, int offset)
    //    参数含义:
    //    shader是一个shader的id;
    //    pname使用GL\_COMPILE\_STATUS;
    //    params是返回值,如果一切正常返回GL\_TRUE代,否则返回GL\_FALSE。
    glGetShaderiv(shader, GL\_COMPILE\_STATUS, &compiled);

    if (!compiled)
    {
        GLint infoLen = 0;

        glGetShaderiv(shader, GL\_INFO\_LOG_LENGTH, &infoLen);

        if (infoLen > 1)
        {
            char* infoLog = (char *)malloc(sizeof(char) * infoLen);

            //编译阶段使用glGetShaderInfoLog获取编译错误
            //函数原型:
            //    String glGetShaderInfoLog(int shader)
            //    参数含义:
            //    shader是一个顶点shader或者片元shader的id。
            glGetShaderInfoLog(shader, infoLen, NULL, infoLog);
            GLUtils::LogMessage("Error compiling shader:\\n%s\\n", infoLog);

            free(infoLog);
        }

        // Free up no longer needed shader resources
        //函数原型:
        //    void glDeleteShader(int shader);
        //    参数含义:
        //    shader是要被排除的顶点shader或者片元shader的id。
        glDeleteShader(shader);
        return 0;
    }

    return shader;
}

获取程序对象

uint GLShader::LoadProgram(const char \*vertShaderSrc, const char \*fragShaderSrc)
{
    GLuint vertexShader;
    GLuint fragmentShader;
    GLuint programObject;
    GLint linked;

    // Load the vertex/fragment shaders
    vertexShader = LoadShader(GL\_VERTEX\_SHADER, vertShaderSrc);
    if (vertexShader == 0)
        return 0;

    fragmentShader = LoadShader(GL\_FRAGMENT\_SHADER, fragShaderSrc);
    if (fragmentShader == 0)
    {
        glDeleteShader(vertexShader);
        return 0;
    }

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

    if (programObject == 0)
        return 0;

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

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

    // Check the link status
    //函数原型:
    //    void glGetProgramiv(int program, int pname, int\[\] params, int offset)
    //    参数含义:
    //    program是一个着色器程序的id;
    //    pname是GL\_LINK\_STATUS;
    //    param是返回值,如果一切正常返回GL\_TRUE代,否则返回GL\_FALSE。
    glGetProgramiv(programObject, GL\_LINK\_STATUS, &linked);

    if (!linked)
    {
        GLint infoLen = 0;

        glGetProgramiv(programObject, GL\_INFO\_LOG_LENGTH, &infoLen);

        if (infoLen > 1)
        {
            char* infoLog = (char*)malloc(sizeof(char) * infoLen);

            //在连接阶段使用glGetProgramInfoLog获取连接错误
            //函数原型:
            //    String glGetProgramInfoLog(int program)
            //    参数含义:
            //    program是一个着色器程序的id。
            glGetProgramInfoLog(programObject, infoLen, NULL, infoLog);
            GLUtils::LogMessage("Error linking program:\\n%s\\n", infoLog);

            free(infoLog);
        }


        glDeleteProgram(programObject);
        return 0;
    }

    // Free up no longer needed shader resources
    //函数原型:
    //    void glDeleteShader(int shader);
    //    参数含义:
    //    shader是要被排除的顶点shader或者片元shader的id。
    glDeleteShader(vertexShader);
    glDeleteShader(fragmentShader);

        //Query
        //QueryActiveUniform(programObject);

    return programObject;
}

查询统一变量

void QueryActiveUniform(GLuint programObject) {
    GLint maxUniformLen;
    GLint numUniforms;
    char *uniformName;
    GLint index;

    glGetProgramiv(programObject, GL\_ACTIVE\_UNIFORMS, &numUniforms);
    glGetProgramiv(programObject, GL\_ACTIVE\_UNIFORM\_MAX\_LENGTH,
        &maxUniformLen);
    uniformName = (char*)malloc(sizeof(char) * maxUniformLen);
    for (index = 0; index < numUniforms; index++)
    {
        GLint size;
        GLenum type;
        GLint location;

        // Get the uniform info
        glGetActiveUniform(programObject, index, maxUniformLen, NULL,
            &size, &type, uniformName);

        // Get the uniform location
        location = glGetUniformLocation(programObject, uniformName);
        switch (type)
        {
        case GL_FLOAT:
            //
            break;
        case GL\_FLOAT\_VEC2:
            //
            break;
        case GL\_FLOAT\_VEC3:
            //
            break;
        case GL\_FLOAT\_VEC4:
            //
            break;
        case GL_INT:
            //
            break;
            // ... Check for all the types ...
        default:
            // Unknown type
            break;
        }
    }
}

工程源码:CocosShader


转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至 xue_huashan@163.com

文章标题:OpenGL ES学习之二---着色器与程序

文章字数:899

本文作者:max-xue

发布时间:2017-06-02, 12:19:30

最后更新:2019-11-09, 21:37:13

原始链接:http://blog.le-more.com/2017/06/02/cocos/opengl-es-e5-ad-a6-e/

版权声明: "署名-非商用-相同方式共享 4.0" 转载请保留原文链接及作者。

目录
×

喜欢就点赞,疼爱就打赏