add triangles command, make quad command inherit from triangles command

This commit is contained in:
Huabing.Xu 2014-08-27 18:39:49 +08:00
parent 91e332c253
commit c627affa5e
4 changed files with 147 additions and 62 deletions

View File

@ -29,15 +29,78 @@
#include "renderer/CCGLProgram.h"
#include "renderer/CCGLProgramState.h"
#include "xxhash.h"
#include "renderer/CCRenderer.h"
NS_CC_BEGIN
QuadCommand::QuadCommand()
TrianglesCommand::TrianglesCommand()
:_materialID(0)
,_textureID(0)
,_glProgramState(nullptr)
,_blendType(BlendFunc::DISABLE)
{
_type = RenderCommand::Type::TRIANGLES_COMMAND;
}
void TrianglesCommand::init(float globalOrder, GLuint textureID, GLProgramState* glProgramState, BlendFunc blendType, const Triangles& triangles,const Mat4& mv)
{
CCASSERT(glProgramState, "Invalid GLProgramState");
CCASSERT(glProgramState->getVertexAttribsFlags() == 0, "No custom attributes are supported in QuadCommand");
_globalOrder = globalOrder;
_triangles = triangles;
if(_triangles.indexCount % 3 != 0)
{
ssize_t count = _triangles.indexCount;
_triangles.indexCount = count / 3 * 3;
CCLOGERROR("Resize indexCount from %zd to %zd, size must be multiple times of 3", count, _triangles.indexCount);
}
_mv = mv;
if( _textureID != textureID || _blendType.src != blendType.src || _blendType.dst != blendType.dst || _glProgramState != glProgramState) {
_textureID = textureID;
_blendType = blendType;
_glProgramState = glProgramState;
generateMaterialID();
}
}
TrianglesCommand::~TrianglesCommand()
{
}
void TrianglesCommand::generateMaterialID()
{
if(_glProgramState->getUniformCount() > 0)
{
_materialID = TrianglesCommand::MATERIAL_ID_DO_NOT_BATCH;
}
else
{
int glProgram = (int)_glProgramState->getGLProgram()->getProgram();
int intArray[4] = { glProgram, (int)_textureID, (int)_blendType.src, (int)_blendType.dst};
_materialID = XXH32((const void*)intArray, sizeof(intArray), 0);
}
}
void TrianglesCommand::useMaterial() const
{
//Set texture
GL::bindTexture2D(_textureID);
//set blend mode
GL::blendFunc(_blendType.src, _blendType.dst);
_glProgramState->apply(_mv);
}
QuadCommand::QuadCommand()
:TrianglesCommand()
,_quads(nullptr)
,_quadsCount(0)
{
@ -54,6 +117,29 @@ void QuadCommand::init(float globalOrder, GLuint textureID, GLProgramState* glPr
_quadsCount = quadCount;
_quads = quad;
//generate triangles
{
static std::vector<GLushort> QUADINDICESMAX;
if(QUADINDICESMAX.size() == 0)
{
QUADINDICESMAX.resize(Renderer::INDEX_VBO_SIZE);
for(ssize_t i = 0; i < Renderer::INDEX_VBO_SIZE / 6; ++i)
{
QUADINDICESMAX[ 6 * i + 0] = 4 * i + 0;
QUADINDICESMAX[ 6 * i + 1] = 4 * i + 1;
QUADINDICESMAX[ 6 * i + 2] = 4 * i + 2;
QUADINDICESMAX[ 6 * i + 3] = 4 * i + 3;
QUADINDICESMAX[ 6 * i + 4] = 4 * i + 2;
QUADINDICESMAX[ 6 * i + 5] = 4 * i + 1;
}
}
_triangles.vertCount = quadCount * 4;
_triangles.indexCount = quadCount * 6;
_triangles.indices = &QUADINDICESMAX[0];
_triangles.verts = &quad->tl;
}
_mv = mv;
if( _textureID != textureID || _blendType.src != blendType.src || _blendType.dst != blendType.dst || _glProgramState != glProgramState) {
@ -70,31 +156,4 @@ QuadCommand::~QuadCommand()
{
}
void QuadCommand::generateMaterialID()
{
if(_glProgramState->getUniformCount() > 0)
{
_materialID = QuadCommand::MATERIAL_ID_DO_NOT_BATCH;
}
else
{
int glProgram = (int)_glProgramState->getGLProgram()->getProgram();
int intArray[4] = { glProgram, (int)_textureID, (int)_blendType.src, (int)_blendType.dst};
_materialID = XXH32((const void*)intArray, sizeof(intArray), 0);
}
}
void QuadCommand::useMaterial() const
{
//Set texture
GL::bindTexture2D(_textureID);
//set blend mode
GL::blendFunc(_blendType.src, _blendType.dst);
_glProgramState->apply(_mv);
}
NS_CC_END

View File

@ -30,27 +30,36 @@
#include "renderer/CCRenderCommandPool.h"
NS_CC_BEGIN
/** Command used to render one or more Quads */
class CC_DLL QuadCommand : public RenderCommand
class CC_DLL TrianglesCommand : public RenderCommand
{
public:
static const int MATERIAL_ID_DO_NOT_BATCH = 0;
QuadCommand();
~QuadCommand();
public:
struct Triangles
{
V3F_C4B_T2F* verts;
unsigned short* indices;
ssize_t vertCount;
ssize_t indexCount;
};
/** Initializes the command with a globalZOrder, a texture ID, a `GLProgram`, a blending function, a pointer to quads,
TrianglesCommand();
~TrianglesCommand();
/** Initializes the command with a globalZOrder, a texture ID, a `GLProgram`, a blending function, a pointer to triangles,
* quantity of quads, and the Model View transform to be used for the quads */
void init(float globalOrder, GLuint texutreID, GLProgramState* shader, BlendFunc blendType, V3F_C4B_T2F_Quad* quads, ssize_t quadCount,
const Mat4& mv);
void init(float globalOrder, GLuint textureID, GLProgramState* glProgramState, BlendFunc blendType, const Triangles& triangles,const Mat4& mv);
void useMaterial() const;
inline uint32_t getMaterialID() const { return _materialID; }
inline GLuint getTextureID() const { return _textureID; }
inline V3F_C4B_T2F_Quad* getQuads() const { return _quads; }
inline ssize_t getQuadCount() const { return _quadsCount; }
inline const Triangles& getTriangles() const { return _triangles; }
inline ssize_t getVertexCount() const { return _triangles.vertCount; }
inline ssize_t getIndexCount() const { return _triangles.indexCount; }
inline const V3F_C4B_T2F* getVertices() const { return _triangles.verts; }
inline const unsigned short* getIndices() const { return _triangles.indices; }
inline GLProgramState* getGLProgramState() const { return _glProgramState; }
inline BlendFunc getBlendType() const { return _blendType; }
inline const Mat4& getModelView() const { return _mv; }
@ -62,9 +71,29 @@ protected:
GLuint _textureID;
GLProgramState* _glProgramState;
BlendFunc _blendType;
Triangles _triangles;
Mat4 _mv;
};
/** Command used to render one or more Quads */
class CC_DLL QuadCommand : public TrianglesCommand
{
public:
QuadCommand();
~QuadCommand();
/** Initializes the command with a globalZOrder, a texture ID, a `GLProgram`, a blending function, a pointer to quads,
* quantity of quads, and the Model View transform to be used for the quads */
void init(float globalOrder, GLuint texutreID, GLProgramState* shader, BlendFunc blendType, V3F_C4B_T2F_Quad* quads, ssize_t quadCount,
const Mat4& mv);
inline const V3F_C4B_T2F_Quad* getQuads() const { return _quads; }
inline ssize_t getQuadCount() const { return _quadsCount; }
protected:
V3F_C4B_T2F_Quad* _quads;
ssize_t _quadsCount;
Mat4 _mv;
};
NS_CC_END

View File

@ -50,6 +50,7 @@ public:
GROUP_COMMAND,
MESH_COMMAND,
PRIMITIVE_COMMAND,
TRIANGLES_COMMAND
};
/** Get Render Command Id */

View File

@ -274,10 +274,10 @@ void Renderer::visitRenderQueue(const RenderQueue& queue)
flush3D();
auto cmd = static_cast<QuadCommand*>(command);
//Batch quads
if( _filledVertex + cmd->getQuadCount() * 4 > VBO_SIZE || _filledIndex + cmd->getQuadCount() * 6 > INDEX_VBO_SIZE)
if( _filledVertex + cmd->getVertexCount() > VBO_SIZE || _filledIndex + cmd->getIndexCount() > INDEX_VBO_SIZE)
{
CCASSERT(cmd->getQuadCount()>= 0 && cmd->getQuadCount() < VBO_SIZE, "VBO is not big enough for quad data, please break the quad data down or use customized render command");
CCASSERT(cmd->getVertexCount()>= 0 && cmd->getVertexCount() < VBO_SIZE, "VBO for vertex is not big enough, please break the data down or use customized render command");
CCASSERT(cmd->getIndexCount()>= 0 && cmd->getIndexCount() < INDEX_VBO_SIZE, "VBO for index is not big enough, please break the data down or use customized render command");
//Draw batched quads if VBO is full
drawBatchedQuads();
}
@ -383,29 +383,25 @@ void Renderer::clean()
void Renderer::fillQuadVertices(const QuadCommand* cmd)
{
memcpy(_verts + _filledVertex, cmd->getQuads(), sizeof(V3F_C4B_T2F) * cmd->getQuadCount() * 4);
memcpy(_verts + _filledVertex, cmd->getQuads(), sizeof(V3F_C4B_T2F) * cmd->getVertexCount());
const Mat4& modelView = cmd->getModelView();
for(ssize_t i=0; i< cmd->getQuadCount() * 4; ++i)
for(ssize_t i=0; i< cmd->getVertexCount(); ++i)
{
V3F_C4B_T2F *q = &_verts[i + _filledVertex];
Vec3 *vec1 = (Vec3*)&q->vertices;
modelView.transformPoint(vec1);
}
const unsigned short* indices = cmd->getIndices();
//fill index
for(ssize_t i=0; i< cmd->getQuadCount(); ++i)
for(ssize_t i=0; i< cmd->getIndexCount(); ++i)
{
_indices[_filledIndex + i * 6 + 0] = _filledVertex + i * 4 + 0;
_indices[_filledIndex + i * 6 + 1] = _filledVertex + i * 4 + 1;
_indices[_filledIndex + i * 6 + 2] = _filledVertex + i * 4 + 2;
_indices[_filledIndex + i * 6 + 3] = _filledVertex + i * 4 + 3;
_indices[_filledIndex + i * 6 + 4] = _filledVertex + i * 4 + 2;
_indices[_filledIndex + i * 6 + 5] = _filledVertex + i * 4 + 1;
_indices[_filledIndex + i] = _filledVertex + indices[i];
}
_filledVertex += cmd->getQuadCount() * 4;
_filledIndex += cmd->getQuadCount() * 6;
_filledVertex += cmd->getVertexCount();
_filledIndex += cmd->getIndexCount();
}
void Renderer::drawBatchedQuads()
@ -491,7 +487,7 @@ void Renderer::drawBatchedQuads()
_lastMaterialID = newMaterialID;
}
indexToDraw += cmd->getQuadCount() * 6;
indexToDraw += cmd->getIndexCount();
}
//Draw any remaining quad