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;
}
}
}
复制代码