直接上代码,码完字就睡觉
class CC_DLL QuadCommand : public TrianglesCommand
{
public:
/**Constructor.*/
QuadCommand();
/**Destructor.*/
~QuadCommand();
/** Initializes the command.
@param globalOrder GlobalZOrder of the command.
@param textureID The openGL handle of the used texture.
@param glProgramState The glProgram with its uniform.
@param blendType Blend function for the command.
@param quads Rendered quads for the command.
@param quadCount The number of quads when rendering.
@param mv ModelView matrix for the command.
@param flags to indicate that the command is using 3D rendering or not.
*/
void init(float globalOrder, GLuint textureID, GLProgramState* glProgramState, const BlendFunc& blendType, V3F_C4B_T2F_Quad* quads, ssize_t quadCount,
const Mat4& mv, uint32_t flags);
/**Deprecated function, the params is similar as the upper init function, with flags equals 0.*/
CC_DEPRECATED_ATTRIBUTE void init(float globalOrder, GLuint textureID, GLProgramState* shader, const BlendFunc& blendType, V3F_C4B_T2F_Quad* quads, ssize_t quadCount,
const Mat4& mv);
void init(float globalOrder, Texture2D* textureID, GLProgramState* glProgramState, const BlendFunc& blendType, V3F_C4B_T2F_Quad* quads, ssize_t quadCount,
const Mat4& mv, uint32_t flags);
protected:
void reIndex(int indices);
int _indexSize;
std::vector<GLushort*> _ownedIndices;
// shared across all instances
static int __indexCapacity;
static GLushort* __indices;
};
复制代码
就想所有的RenderCommand一样, 每个command都只是记录了需要渲染的着色程序状态值和着色程序需要用到的参数 顶点属性和统一变量,混合函数等等
void QuadCommand::reIndex(int indicesCount)
{
// first time init: create a decent buffer size for indices to prevent too much resizing
if (__indexCapacity == -1)
{
indicesCount = std::max(indicesCount, 2048);
}
if (indicesCount > __indexCapacity)
{
// if resizing is needed, get needed size plus 25%, but not bigger that max size
indicesCount *= 1.25;
indicesCount = std::min(indicesCount, 65536);
CCLOG("cocos2d: QuadCommand: resizing index size from [%d] to [%d]", __indexCapacity, indicesCount);
_ownedIndices.push_back(__indices);
__indices = new (std::nothrow) GLushort[indicesCount];
__indexCapacity = indicesCount;
}
for( int i=0; i < __indexCapacity/6; i++)
{
__indices[i*6+0] = (GLushort) (i*4+0);
__indices[i*6+1] = (GLushort) (i*4+1);
__indices[i*6+2] = (GLushort) (i*4+2);
__indices[i*6+3] = (GLushort) (i*4+3);
__indices[i*6+4] = (GLushort) (i*4+2);
__indices[i*6+5] = (GLushort) (i*4+1);
}
_indexSize = indicesCount;
}
复制代码
这个reIndex方法实际上是对顶点索引数据的重排序,并不知道为啥要重排序,可能看了Renderer里的代码会弄明白.for 循环中的的六行实际上是以一个4变形的顶点绘制顺序 每3个点形成一个三角形,2个三角形形成一个4变形
void QuadCommand::init(float globalOrder, GLuint textureID, GLProgramState* glProgramState, const BlendFunc& blendType, V3F_C4B_T2F_Quad* quads, ssize_t quadCount,
const Mat4& mv, uint32_t flags)
{
CCASSERT(glProgramState, "Invalid GLProgramState");
CCASSERT(glProgramState->getVertexAttribsFlags() == 0, "No custom attributes are supported in QuadCommand");
if (quadCount * 6 > _indexSize)
reIndex((int)quadCount*6);
Triangles triangles;
triangles.verts = &quads->tl;
triangles.vertCount = (int)quadCount * 4;
triangles.indices = __indices;
triangles.indexCount = (int)quadCount * 6;
TrianglesCommand::init(globalOrder, textureID, glProgramState, blendType, triangles, mv, flags);
}
复制代码
这个是实际上创建的Command.这里我没看到最后生成的仍然是TriangleCommand, 就是说一个4边形最后还是用三角形去画的(谁让基础图元只有点线三角嘞, 其实用点也可以画正方形) 这里看到一个quads , 他是一个V3F_C4B_T2F_Quad结构体的数组, 它代表的是一组4边形的顶点属性
struct CC_DLL V3F_C4B_T2F_Quad
{
/// top left
V3F_C4B_T2F tl;
/// bottom left
V3F_C4B_T2F bl;
/// top right
V3F_C4B_T2F tr;
/// bottom right
V3F_C4B_T2F br;
};
复制代码
tl:topleft bl:bottomleft tr:topright bl:bottomright 每个又是一个V3F_C4B_T2F 结构体 struct CC_DLL V3F_C4B_T2F { /// vertices (3F) Vec3 vertices; // 12 bytes
/// colors (4B)
Color4B colors; // 4 bytes
// tex coords (2F)
Tex2F texCoords; // 8 bytes
复制代码
}; vec3 是3个Float分量的向量, color4B是4个Byte分量的向量, Tex2F是2个分量的向量 得益于结构体数据在内存中是紧密排列的我们可以仅仅获取第一个quad结构体的tl成员的地址就可以根据数据type的间隔获取下一个quad和每个顶点的数据, 方便用来做顶点属性绑定
mv代表的是模型视图转换矩阵,前面就提到过这个矩阵是将世界坐标转换到视图坐标的矩阵,再配以投影矩阵我们就能获得cocos渲染对象在视窗上的坐标
单纯的2d渲染还是很好理解的, 大部分仅仅只是4边形的矩阵计算和2d坐标转换,一个对像只有4个顶点2个三角形,3d就复杂太多了........明天看完Renderer的代码我们就可以好好看看Mesh模型相关的代码了