CCQuadCommand类继承自CCTrianglesCommand类, 因为一个4个点的封闭图形由两个三角形组成.下面先介绍父类CCTrianglesCommand 然后再简单地介绍下CCQuadCommand类 #1. CCTrianglesCommand 三角形图形的渲染指令, vertsNum = 3....... ##1.1 Triangles 结构体
struct Triangles
{
/**Vertex data pointer.*/
/** 有时候真的不知道这里面的pointer指的是数据的指针还是属性的位置pointer
这里的pointer应该是保存的cpu使用的内存中顶点属性的指针 (x, y, z) (r, g, b, a)(s,t) PS:忘了s, t, r 里的那两个了,
反正是纹理坐标里的2个, 这里应该是2D纹理 不考虑第三个轴方向
*/
V3F_C4B_T2F* verts;
/**Index data pointer.*/
/** 顶点索引的值的数组的指针*/
unsigned short* indices;
/**The number of vertices.*/
/** 顶点数, triangle 是3*/
int vertCount;
/** 一般性和vertCount相同, 但是其实可以重复使用比如(0, 1, 2, 0, 2, 1,.....)*/
/**The number of indices.*/
int indexCount;
};
复制代码
这里面除了这个结构体还使用到了前面不曾介绍到的一些类,但是可以简单的介绍下用途, 具体的介绍会放在后面 ##1.2 一些使用到的属性变量
protected:
/**Generate the material ID by textureID, glProgramState, and blend function.*/
void generateMaterialID();
/**Generated material id.*/
/** 就像注释里介绍到的 材质Id是有绑定的纹理ID, 着色程序状态 和混合函数生成的*/
uint32_t _materialID;
/**OpenGL handle for texture.*/
/** 这个ID是由opengl 管理的纹理单元ID(或者普通纹理缓存对象ID) 纹理单元的数量是有限的具体的数量由各个平台具体的实现决定, opengl es 2.0要求不低于16个*/
GLuint _textureID;
/**GLprogramstate for the command. encapsulate shaders and uniforms.*/
/** 保存了着色程序的状态和需要用到的统一变量和属性变量*/
GLProgramState* _glProgramState;
/**Blend function when rendering the triangles.*/
/** 混合函数的类形, 具体的结构会在下面放出*/
BlendFunc _blendType;
/**Rendered triangles.*/
/** 定义了对应的渲染shader需要使用到的属性的值*/
Triangles _triangles;
/**Model view matrix when rendering the triangles.*/
/** 模型视图矩阵, 将三角形顶点的opengl世界坐标转移到对应camera的相机坐标系内 再加一个projectionMatrix 就可以获得在可视区域内的坐标*/
Mat4 _mv;
GLuint _alphaTextureID; // ANDROID ETC1 ALPHA supports.
};
复制代码
###1.2.2BlendFunc BlendFunc 是在ccTypes.h 文件中定义的一个保存了混合函数参数的结构体 决定了新绘制的图形绘制在已有颜色的区域该怎么去混合
/** @struct BlendFunc
* Blend Function used for textures.
*/
struct CC_DLL BlendFunc
{
/** source blend function */
/** 类似的像 GL_ONE, GL_ZERO, GL_SRC_ALPHA, GL_ONE_MINUS_ALPHA等等*/
GLenum src;
/** destination blend function */
GLenum dst;
/** Blending disabled. Uses {GL_ONE, GL_ZERO} */
static const BlendFunc DISABLE;
/** Blending enabled for textures with Alpha premultiplied. Uses {GL_ONE, GL_ONE_MINUS_SRC_ALPHA} */
static const BlendFunc ALPHA_PREMULTIPLIED;
/** Blending enabled for textures with Alpha NON premultiplied. Uses {GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA} */
static const BlendFunc ALPHA_NON_PREMULTIPLIED;
/** Enables Additive blending. Uses {GL_SRC_ALPHA, GL_ONE} */
static const BlendFunc ADDITIVE;
bool operator==(const BlendFunc &a) const
{
return src == a.src && dst == a.dst;
}
bool operator!=(const BlendFunc &a) const
{
return src != a.src || dst != a.dst;
}
bool operator<(const BlendFunc &a) const
{
return src < a.src || (src == a.src && dst < a.dst);
}
};
复制代码
##1.3 use方法的实现
void TrianglesCommand::useMaterial() const
{
//Set texture
GL::bindTexture2D(_textureID);
if (_alphaTextureID > 0)
{ // ANDROID ETC1 ALPHA supports.
GL::bindTexture2DN(1, _alphaTextureID);
}
//set blend mode
GL::blendFunc(_blendType.src, _blendType.dst);
_glProgramState->apply(_mv);
}
就像我们看到的那样command 只是保存了需要绘制图形的一系列参数,具体的渲染还是要在renderer中进行, 这里的useMaterial实际上是renderer渲染这个图形前使用command带的参数对opengl状态机和缓存进行设置以便运行类似glDrawArray()和glDrawElements()或glDrawInstance() :ps:最后这个不知道opengles2.0有没有
复制代码
##1.4 _materiaId实质上是一个hash 32值 不多说贴代码
void TrianglesCommand::generateMaterialID()
{
// glProgramState is hashed because it contains:
// * uniforms/values
// * glProgram
//
// we safely can when the same glProgramState is being used then they share those states
// if they don't have the same glProgramState, they might still have the same
// uniforms/values and glProgram, but it would be too expensive to check the uniforms.
struct {
GLuint textureId;
GLenum blendSrc;
GLenum blendDst;
void* glProgramState;
} hashMe;
hashMe.textureId = _textureID;
hashMe.blendSrc = _blendType.src;
hashMe.blendDst = _blendType.dst;
hashMe.glProgramState = _glProgramState;
_materialID = XXH32((const void*)&hashMe, sizeof(hashMe), 0);
}
复制代码
后面的文章应该会先介绍 CCGLProgramState类 然后接着介绍使用最多的QuadCommand类