Cocos2dx源码记录(7) CCGLProgramState

CCGLProgramState 是存储GLProgram使用到的 Attribute和 Uniform 具体值的类 #1. GLProgramState

class CC_DLL GLProgramState : public Ref
{
............省略无数行
protected:
    GLProgramState();
    virtual ~GLProgramState();
    bool init(GLProgram* program);
    /*根据当前持有的数据对GLProgram进行重置*/
    void resetGLProgram();
    /*刷新统一变量和顶点属性的值*/
    void updateUniformsAndAttributes();
    /*获取保存当前的顶点属性的值的value 类*/
    VertexAttribValue* getVertexAttribValue(const std::string& attributeName);
    /*根据uniform变量名获取对应的保存当前uniform值的value类*/    
    UniformValue* getUniformValue(const std::string& uniformName);
    /*根据统一变量在统一变量空间内的location 获取uniform value*/
    UniformValue* getUniformValue(GLint uniformLocation);

    /*判定内存是否不关心具体对象可直接重写*/
    bool _uniformAttributeValueDirty;
    /*用name 保存的uniform value值*/
    std::unordered_map<std::string, GLint> _uniformsByName;
    /*用 location 保存的 uniform value值*/
    std::unordered_map<GLint, UniformValue> _uniforms;
    /*用name 绑定的顶点属性 value值*/
    std::unordered_map<std::string, VertexAttribValue> _attributes;
    /*绑定的纹理单元ID 应该是0-15 opengl 4.0 和 opengles2.0 支持的更多*/
    std::unordered_map<std::string, int> _boundTextureUnits;
    /*暂时不知道干啥的*/
    int _textureUnitIndex;
    /*对应使用到的顶点属性的位枚举值*/
    uint32_t _vertexAttribsFlags;
    /*引用的GLProgram*/
    GLProgram* _glprogram;
    /* 绑定的node*/
    Node* _nodeBinding; // weak ref
  
    // contains uniform name and variable
    /* 自动绑定的 uniform 变量 目的是代替之前的 _defauftUniform值, 减少hardcode的数量*/
    std::unordered_map<std::string, std::string> _autoBindings;

    // Map of custom auto binding resolvers.
    /* 用来直接操作 _autoBinding的值*/
    static std::vector<AutoBindingResolver*> _customAutoBindingResolvers;

#if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID || CC_TARGET_PLATFORM == CC_PLATFORM_WINRT)
    EventListenerCustom* _backToForegroundlistener;
#endif

};
复制代码

#2. UniformValue 保存实际统一变量值的类 每个uniform变量 是由一个uniformValue指定

class CC_DLL UniformValue
{
    friend class GLProgram;
    friend class GLProgramState;
public:
.........省略好多行
protected:
    //指明这个值的具体类型, 值, 保存的属性结构体的位置指针, 还是callback
    enum class Type {
        VALUE,
        POINTER,
        CALLBACK_FN     // CALLBACK is already defined in windows, can't use it.
    };

    /**Weak reference to Uniform.*/
    /*在GLProgram里定义的 uniform结构体*/
    Uniform* _uniform;
    /**Weak reference to GLprogram.*/
    /*绑定的GLProgram类*/
    GLProgram* _glprogram;
    /** What kind of type is the Uniform */
  /*uniformvalue 的类型*/ 
   Type _type;

    /**
     @name Uniform Value Uniform
     @{
     */
  /*实际保存的value值的 联合体*/
    union U{
        float floatValue;
        int intValue;
        float v2Value[2];
        float v3Value[3];
        float v4Value[4];
        float matrixValue[16];
        struct {
            GLuint textureId;
            GLuint textureUnit;
        } tex;
        struct {
            const float* pointer;
            GLsizei size;
        } floatv;
        struct {
            const float* pointer;
            GLsizei size;
        } v2f;
        struct {
            const float* pointer;
            GLsizei size;
        } v3f;
        struct {
            const float* pointer;
            GLsizei size;
        } v4f;
        std::function<void(GLProgram*, Uniform*)> *callback;

        U() { memset( this, 0, sizeof(*this) ); }
        ~U(){}
        U& operator=( const U& other ) {
            memcpy(this, &other, sizeof(*this));
            return *this;
        }
    } _value;
    /**
     @}
     */
};
复制代码

#3. VertexAttributeValue 保存使用到的顶点属性的值的类 每一个使用到的顶点属性由一个VertexAttributeValue指定, 保存在_attributes结构体里

class CC_DLL VertexAttribValue
{
    friend class GLProgram;
    friend class GLProgramState;
    friend class VertexAttribBinding;

public:
........省略一些行
protected:
    /*GLProgram里定义的vertexattribute结构体*/
    VertexAttrib* _vertexAttrib;  // weak ref
    /*是否使用回调*/
    bool _useCallback;
    /*开启或关闭该顶点属性*/
    bool _enabled;
    /*保存顶点属性的值*/
    union U{
        struct {
            GLint size;
            GLenum type;
            GLboolean normalized;
            GLsizei stride;
            GLvoid *pointer;
        } pointer;
        std::function<void(VertexAttrib*)> *callback;

        U() { memset( this, 0, sizeof(*this) ); }
        ~U(){}
        U& operator=( const U& other ) {
            memcpy(this, &other, sizeof(*this));
            return *this;
        }
    } _value;
};

复制代码

#4. GLProgramStateCache

按照GLProgram对象为键值保存GLProgramStateCache的类

class CC_DLL GLProgramStateCache
{
public:
    /**Get the GLProgramStateCache singleton instance.*/
    static GLProgramStateCache* getInstance();
    /**Destroy the GLProgramStateCache singleton.*/
    static void destroyInstance();
    
    /**Get the shared GLProgramState by the owner GLProgram.*/
    GLProgramState* getGLProgramState(GLProgram* program);
    /**Remove all the cached GLProgramState.*/
	void removeAllGLProgramState();
    /**Remove unused GLProgramState.*/
    void removeUnusedGLProgramState();

protected:
    GLProgramStateCache();
    ~GLProgramStateCache();
    
    Map<GLProgram*, GLProgramState*> _glProgramStates;
    static GLProgramStateCache* s_instance;
};

复制代码

##getGLProgramState

GLProgramState* GLProgramStateCache::getGLProgramState(GLProgram* glprogram)
{
    const auto& itr = _glProgramStates.find(glprogram);
    if (itr != _glProgramStates.end())
    {
        return itr->second;
    }
    
    auto ret = new (std::nothrow) GLProgramState;
    if(ret && ret->init(glprogram)) {
        _glProgramStates.insert(glprogram, ret);
        ret->release();
        return ret;
    }
    
    CC_SAFE_RELEASE(ret);
    return ret;
}
复制代码

好怀念的写法......现在写lua基本用不到了,思想类似,但代码不一样.想以前写app的时候也是这么写

#5. updateUniformsAndAttributes 看完renderer后发现这个函数的调用这里做个补充

void GLProgramState::updateUniformsAndAttributes()
{
    CCASSERT(_glprogram, "invalid glprogram");
    if(_uniformAttributeValueDirty)
    {
      // std::unordered_map<std::string, GLint> _uniformsByName;
      // first是string , second是GLint 
      //std::unordered_map<GLint, UniformValue> _uniforms;
      //保存的是uniformValue对象
        for(auto& uniformLocation : _uniformsByName)
        {
            _uniforms[uniformLocation.second]._uniform = _glprogram->getUniform(uniformLocation.first);
        }
        
        _vertexAttribsFlags = 0;
        for(auto& attributeValue : _attributes)
        {
            attributeValue.second._vertexAttrib = _glprogram->getVertexAttrib(attributeValue.first);;
            if(attributeValue.second._enabled)
                _vertexAttribsFlags |= 1 << attributeValue.second._vertexAttrib->index;
        }
        
        _uniformAttributeValueDirty = false;
        
    }
}
复制代码

apply

state提交uniforms
void GLProgramState::applyUniforms()
{
    // set uniforms
    updateUniformsAndAttributes();
    for(auto& uniform : _uniforms) {
        //uniform.second 是uniformValue
        uniform.second.apply();
    }
}

每个uniformValue各自提交
void UniformValue::apply()
{
    if (_type == Type::CALLBACK_FN)
    {
        (*_value.callback)(_glprogram, _uniform);
    }
    else if (_type == Type::POINTER)
    {
        switch (_uniform->type) {
            case GL_FLOAT:
                _glprogram->setUniformLocationWith1fv(_uniform->location, _value.floatv.pointer, _value.floatv.size);
                break;

            case GL_FLOAT_VEC2:
                _glprogram->setUniformLocationWith2fv(_uniform->location, _value.v2f.pointer, _value.v2f.size);
                break;

            case GL_FLOAT_VEC3:
                _glprogram->setUniformLocationWith3fv(_uniform->location, _value.v3f.pointer, _value.v3f.size);
                break;

            case GL_FLOAT_VEC4:
                _glprogram->setUniformLocationWith4fv(_uniform->location, _value.v4f.pointer, _value.v4f.size);
                break;

            default:
                CCASSERT(false, "Unsupported type");
                break;
        }
    }
    else /* _type == VALUE */
    {
        switch (_uniform->type) {
            case GL_SAMPLER_2D:
                _glprogram->setUniformLocationWith1i(_uniform->location, _value.tex.textureUnit);
                GL::bindTexture2DN(_value.tex.textureUnit, _value.tex.textureId);
                break;

            case GL_SAMPLER_CUBE:
                _glprogram->setUniformLocationWith1i(_uniform->location, _value.tex.textureUnit);
                GL::bindTextureN(_value.tex.textureUnit, _value.tex.textureId, GL_TEXTURE_CUBE_MAP);
                break;

            case GL_INT:
                _glprogram->setUniformLocationWith1i(_uniform->location, _value.intValue);
                break;

            case GL_FLOAT:
                _glprogram->setUniformLocationWith1f(_uniform->location, _value.floatValue);
                break;

            case GL_FLOAT_VEC2:
                _glprogram->setUniformLocationWith2f(_uniform->location, _value.v2Value[0], _value.v2Value[1]);
                break;

            case GL_FLOAT_VEC3:
                _glprogram->setUniformLocationWith3f(_uniform->location, _value.v3Value[0], _value.v3Value[1], _value.v3Value[2]);
                break;

            case GL_FLOAT_VEC4:
                _glprogram->setUniformLocationWith4f(_uniform->location, _value.v4Value[0], _value.v4Value[1], _value.v4Value[2], _value.v4Value[3]);
                break;

            case GL_FLOAT_MAT4:
                _glprogram->setUniformLocationWithMatrix4fv(_uniform->location, (GLfloat*)&_value.matrixValue, 1);
                break;

            default:
                CCASSERT(false, "Invalid UniformValue");
                break;
        }
    }
}
复制代码

转载于:https://juejin.im/post/5a30dd43f265da43133d23ba

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值