Cocos2d-x Program笔记

本文详细介绍了Cocos2d-x中与GLProgram相关的重要概念,包括GLProgram的数据包含和操作流程,GLProgramState的数据定义、创建与应用,以及GLProgramCache和GLProgramStateCache的使用流程,阐述了它们在渲染过程中的作用和缓存策略。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Cocos2d-x与program相关的类有:

  • GLProgram:包含Shader Compile,Uniform Cache,Attrib Cache
  • GLProgramState:每一个GLProgram对象都有一个与之对应的GLProgramState用于Cache所有的State,包括:Uniform和Attrib 。当前版本没有完善此类,因此所有的Cache都还在GLProgram中实现,而且glVertexAttribPointer这种东西还在Render类中,因此Attrib Cache现在没有太大的实质性的用处,另外并没有使用VAO和static draw VBO(每次Render的draw之前都会重新上传顶点属性数据)
  • GLProgramCache:单实例类,Cache all default GLProgram,init()函数会加载所有的Shader Code然后生成GLProgram保存到Cache中
  • GLProgramStateCache:单实例类,Cache all GLProgramState,init()函数会创建或获取已有GLProgramState,新创建的会加入到Cache
使用方法:用GLProgramStateCache中的接口获取GLProgramState,GLProgramState初始化时获取GLProgramCache单实例,GLProgramCache获取实例时创建所有的默认GLProgram。
待完善:当下,GLProgramState没有什么作用,其大部分功能还没有从GLProgram中分离出来,所以相关的apply()函数还是调用的GLProgram中的setUniform类函数。另外,Render类中draw函数没有将glVertexAttribPointer这种设置分离到GLProgramState中去。

GLProgram

1.包含的数据

    /**VertexAttrib is a structure to encapsulate data got from glGetActiveAttrib.*/
    struct VertexAttrib
    {
        /**Index of attribute, start from 0.*/
        GLuint index;
        /**Number of Data type in the attribute, could range from 0-4.*/
        GLint size;
        /**Data type of the attribute, could be GL_FLOAT, GL_UNSIGNED_BYTE etc.*/
        GLenum type;
        /**The string name in vertex shader.*/
        std::string name;
    };
    /**Uniform is a structure to encapsulate data got from glGetActiveUniform and glGetUniformLocation.*/
    struct Uniform
    {
        /**The place where the uniform placed, starts from 0.*/
        GLint location;
        /**Number of data type in attribute.*/
        GLint size;
        /**Data type of the attribute.*/
        GLenum type;
        /**String of the uniform name.*/
        std::string name;
    };

    /**OpenGL handle for program.*/
    GLuint            _program;
    /**OpenGL handle for vertex shader.*/
    GLuint            _vertShader;
    /**OpenGL handle for fragment shader.*/
    GLuint            _fragShader;
    /**Built in uniforms.*/
    GLint             _builtInUniforms[UNIFORM_MAX];
    /**Indicate whether it has a offline shader compiler or not.*/
    bool              _hasShaderCompiler;

    /**User defined Uniforms.*/
    std::unordered_map<std::string, Uniform> _userUniforms;
    /**User defined vertex attributes.*/
    std::unordered_map<std::string, VertexAttrib> _vertexAttribs;
    /**Hash value of uniforms for quick access.*/
    std::unordered_map<GLint, std::pair<GLvoid*, unsigned int>> _hashForUniforms;
    //cached director pointer for calling
    Director* _director;

    /*needed uniforms*/
    UniformFlags _flags;

VertexAttrib:保存VertexAttrib的location,name,size(if vec2 = 2, vec3 = 3),type(like GLfoat)
Uniform:保存Uniform的location,name,size,type
_builtInUniforms:用于保存共用的Uniform的location的数组,name是已知的不用保存
_userUniforms:用于保存Userdefine的Uniform的location和name的map
_hashForUniforms:用于Cache所有的Uniform的location,data,data length的map,这个功能将来会迁移到GLProgramState
_flags:用于标志相同类型的Uniform是否在Program中定义

2.操作流程

1)create
GLProgram* GLProgram::createWithByteArrays(const GLchar* vShaderByteArray, const GLchar* fShaderByteArray, const std::string& compileTimeDefines)
{
    auto ret = new (std::nothrow) GLProgram();
    if(ret && ret->initWithByteArrays(vShaderByteArray, fShaderByteArray, compileTimeDefines)) {
        ret->link();
        ret->updateUniforms();
        ret->autorelease();
        return ret;
    }

    CC_SAFE_DELETE(ret);
    return nullptr;
}

2)init
bool GLProgram::initWithByteArrays(const GLchar* vShaderByteArray, const GLchar* fShaderByteArray, const std::string& compileTimeDefines)
{
    _program = glCreateProgram();
    CHECK_GL_ERROR_DEBUG();

    // convert defines here. If we do it in "compileShader" we will do it twice.
    // a cache for the defines could be useful, but seems like overkill at this point
    std::string replacedDefines = "";
    replaceDefines(compileTimeDefines, replacedDefines);

    _vertShader = _fragShader = 0;

    if (vShaderByteArray)
    {
        if (!compileShader(&_vertShader, GL_VERTEX_SHADER, vShaderByteArray, replacedDefines))
        {
            CCLOG("cocos2d: ERROR: Failed to compile vertex shader");
            return false;
       }
    }

    // Create and compile fragment shader
    if (fShaderByteArray)
    {
        if (!compileShader(&_fragShader, GL_FRAGMENT_SHADER, fShaderByteArray, replacedDefines))
        {
            CCLOG("cocos2d: ERROR: Failed to compile fragment shader");
            return false;
        }
    }

    if (_vertShader)
    {
        glAttachShader(_program, _vertShader);
    }
    CHECK_GL_ERROR_DEBUG();

    if (_fragShader)
    {
        glAttachShader(_program, _fragShader);
    }

    _hashForUniforms.clear();

    CHECK_GL_ERROR_DEBUG();

    return true;
}

init包含了compile,attach两个过程,其中需要特别注意Compile过程,如下:
static const char * COCOS2D_SHADER_UNIFORMS =
        "uniform mat4 CC_PMatrix;\n"
        "uniform mat4 CC_MVMatrix;\n"
        "uniform mat4 CC_MVPMatrix;\n"
        "uniform mat3 CC_NormalMatrix;\n"
        "uniform vec4 CC_Time;\n"
        "uniform vec4 CC_SinTime;\n"
        "uniform vec4 CC_CosTime;\n"
        "uniform vec4 CC_Random01;\n"
        "uniform sampler2D CC_Texture0;\n"
        "uniform sampler2D CC_Texture1;\n"
        "uniform sampler2D CC_Texture2;\n"
        "uniform 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值