mirror of https://github.com/axmolengine/axmol.git
Improved batching
This commit is contained in:
parent
5a1d92cbf2
commit
f68a2a47e7
|
@ -27,8 +27,7 @@ int64_t CustomCommand::generateID()
|
|||
|
||||
_id = (int64_t)_viewport << 61
|
||||
| (int64_t)1 << 60 // translucent
|
||||
| (int64_t)0 << 59 // is command
|
||||
| (int64_t)_depth << 35;
|
||||
| (int64_t)_depth << 36;
|
||||
|
||||
return _id;
|
||||
}
|
||||
|
|
|
@ -20,8 +20,8 @@ public:
|
|||
|
||||
// +----------+----------+-----+-----------------------------------+
|
||||
// | | | | | |
|
||||
// | ViewPort | Transluc | Cmd | Depth | |
|
||||
// | 3 bits | 1 bit | 1 | 24 bits | |
|
||||
// | ViewPort | Transluc | | Depth | |
|
||||
// | 3 bits | 1 bit | | 24 bits | |
|
||||
// +----------+----------+-----+----------------+------------------+
|
||||
virtual int64_t generateID();
|
||||
|
||||
|
@ -29,9 +29,6 @@ public:
|
|||
|
||||
inline bool isTranslucent() { return true; }
|
||||
|
||||
//TODO support non-graphical command
|
||||
inline bool isCommand() { return false; }
|
||||
|
||||
public:
|
||||
function<void()> func;
|
||||
|
||||
|
|
|
@ -18,6 +18,7 @@ QuadCommand::QuadCommand(int viewport, int32_t depth, GLuint textureID, GLProgra
|
|||
{
|
||||
_type = QUAD_COMMAND;
|
||||
_shader = shader;
|
||||
_quadCount = 1;
|
||||
}
|
||||
|
||||
QuadCommand::~QuadCommand()
|
||||
|
@ -65,8 +66,7 @@ int64_t QuadCommand::generateID()
|
|||
//Generate RenderCommandID
|
||||
_id = (int64_t)_viewport << 61
|
||||
| (int64_t)1 << 60 //translucent
|
||||
| (int64_t)0 << 59 //is command
|
||||
| (int64_t)_depth << 35;
|
||||
| (int64_t)_depth << 36;
|
||||
|
||||
return _id;
|
||||
}
|
||||
|
|
|
@ -21,8 +21,8 @@ public:
|
|||
|
||||
// +----------+----------+-----+-----------------------------------+
|
||||
// | | | | | |
|
||||
// | ViewPort | Transluc | Cmd | Depth | Material ID |
|
||||
// | 3 bits | 1 bit | 1 | 24 bits | 24 bit2 |
|
||||
// | ViewPort | Transluc | | Depth | Material ID |
|
||||
// | 3 bits | 1 bit | | 24 bits | 24 bit2 |
|
||||
// +----------+----------+-----+----------------+------------------+
|
||||
virtual int64_t generateID();
|
||||
|
||||
|
@ -31,14 +31,14 @@ public:
|
|||
//TODO use material to decide if it is translucent
|
||||
inline bool isTranslucent() { return true; }
|
||||
|
||||
inline bool isCommand() { return false; }
|
||||
|
||||
inline int32_t getMaterialID() { return _materialID; }
|
||||
|
||||
inline GLuint getTextureID() { return _textureID; }
|
||||
|
||||
inline V3F_C4B_T2F_Quad* getQuad() { return &_quad; }
|
||||
|
||||
inline int getQuadCount() { return _quadCount; }
|
||||
|
||||
inline GLProgram* getShader() { return _shader; }
|
||||
|
||||
inline BlendFunc getBlendType() { return _blendType; }
|
||||
|
@ -61,6 +61,7 @@ protected:
|
|||
BlendFunc _blendType;
|
||||
|
||||
V3F_C4B_T2F_Quad _quad;
|
||||
int _quadCount;
|
||||
};
|
||||
|
||||
NS_CC_END
|
||||
|
|
|
@ -36,27 +36,18 @@ void Renderer::destroyInstance()
|
|||
Renderer::Renderer()
|
||||
:_lastMaterialID(0)
|
||||
,_numQuads(0)
|
||||
,_firstCommand(0)
|
||||
,_lastCommand(0)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
Renderer::~Renderer()
|
||||
{
|
||||
free(_quads);
|
||||
}
|
||||
|
||||
bool Renderer::init()
|
||||
{
|
||||
_quads = (V3F_C4B_T2F_Quad*)malloc(sizeof(V3F_C4B_T2F_Quad) * VBO_SIZE);
|
||||
_indices = (GLushort*) malloc(sizeof(GLushort) * 6 * VBO_SIZE);
|
||||
if( ! ( _quads && _indices) )
|
||||
{
|
||||
//not enough memory
|
||||
CC_SAFE_FREE(_quads);
|
||||
CC_SAFE_FREE(_indices);
|
||||
return false;
|
||||
}
|
||||
|
||||
setupIndices();
|
||||
|
||||
setupVBOAndVAO();
|
||||
|
@ -132,57 +123,145 @@ void Renderer::render()
|
|||
//1. Sort render commands based on ID
|
||||
stable_sort(_renderQueue.begin(), _renderQueue.end(), compareRenderCommand);
|
||||
|
||||
//2. Process commands
|
||||
for(auto it = _renderQueue.begin(); it != _renderQueue.end(); ++it)
|
||||
size_t len = _renderQueue.size();
|
||||
|
||||
for (size_t i = 0; i < len; i++)
|
||||
{
|
||||
//TODO: Perform Sprite batching here
|
||||
auto command = *it;
|
||||
auto command = _renderQueue[i];
|
||||
|
||||
switch(command->getType())
|
||||
if( command->getType() == QUAD_COMMAND )
|
||||
{
|
||||
case QUAD_COMMAND:
|
||||
QuadCommand* cmd = static_cast<QuadCommand*>(command);
|
||||
|
||||
//
|
||||
if(_numQuads + cmd->getQuadCount() < VBO_SIZE)
|
||||
{
|
||||
QuadCommand* cmd = static_cast<QuadCommand*>(command);
|
||||
|
||||
if(_lastMaterialID != cmd->getMaterialID() || _numQuads >= VBO_SIZE)
|
||||
{
|
||||
//Draw batched data
|
||||
drawQuads();
|
||||
}
|
||||
|
||||
//Reset material if needed.
|
||||
if(_lastMaterialID != cmd->getMaterialID())
|
||||
{
|
||||
//Set new material
|
||||
_lastMaterialID = cmd->getMaterialID();
|
||||
|
||||
//Set Shader
|
||||
cmd->useMaterial();
|
||||
}
|
||||
|
||||
|
||||
batchQuads(cmd);
|
||||
|
||||
break;
|
||||
memcpy(_quads + _numQuads - 1, cmd->getQuad(), sizeof(V3F_C4B_T2F_Quad) * cmd->getQuadCount());
|
||||
_numQuads += cmd->getQuadCount();
|
||||
_lastCommand = i;
|
||||
}
|
||||
case CUSTOM_COMMAND:
|
||||
else
|
||||
{
|
||||
flush();
|
||||
CustomCommand* cmd = static_cast<CustomCommand*>(command);
|
||||
cmd->execute();
|
||||
|
||||
break;
|
||||
//Draw batched quads if VBO is full
|
||||
drawBatchedQuads();
|
||||
}
|
||||
default:
|
||||
break;
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
//Draw batched quads if we encountered a different command
|
||||
drawBatchedQuads();
|
||||
}
|
||||
|
||||
delete command;
|
||||
}
|
||||
|
||||
drawQuads();
|
||||
//Draw the batched quads
|
||||
drawBatchedQuads();
|
||||
|
||||
_firstCommand = _lastCommand = 0;
|
||||
_lastMaterialID = 0;
|
||||
_renderQueue.clear();
|
||||
|
||||
// //2. Process commands
|
||||
// for(auto it = _renderQueue.begin(); it != _renderQueue.end(); ++it)
|
||||
// {
|
||||
// //TODO: Perform Sprite batching here
|
||||
// auto command = *it;
|
||||
//
|
||||
// switch(command->getType())
|
||||
// {
|
||||
// case QUAD_COMMAND:
|
||||
// {
|
||||
// QuadCommand* cmd = static_cast<QuadCommand*>(command);
|
||||
//
|
||||
// if(_lastMaterialID != cmd->getMaterialID() || _numQuads >= VBO_SIZE)
|
||||
// {
|
||||
// //Draw batched data
|
||||
// drawQuads();
|
||||
// }
|
||||
//
|
||||
// //Reset material if needed.
|
||||
// if(_lastMaterialID != cmd->getMaterialID())
|
||||
// {
|
||||
// //Set new material
|
||||
// _lastMaterialID = cmd->getMaterialID();
|
||||
//
|
||||
// //Set Shader
|
||||
// cmd->useMaterial();
|
||||
// }
|
||||
//
|
||||
// batchQuads(cmd);
|
||||
//
|
||||
// break;
|
||||
// }
|
||||
// case CUSTOM_COMMAND:
|
||||
// {
|
||||
// flush();
|
||||
// CustomCommand* cmd = static_cast<CustomCommand*>(command);
|
||||
// cmd->execute();
|
||||
//
|
||||
// break;
|
||||
// }
|
||||
// default:
|
||||
// break;
|
||||
// }
|
||||
//
|
||||
// delete command;
|
||||
// }
|
||||
//
|
||||
// drawQuads();
|
||||
//
|
||||
// _renderQueue.clear();
|
||||
}
|
||||
|
||||
void Renderer::drawBatchedQuads()
|
||||
{
|
||||
int quadsToDraw = 0;
|
||||
int startQuad = 0;
|
||||
|
||||
//Upload buffer to VBO
|
||||
if(_numQuads <= 0)
|
||||
return;
|
||||
|
||||
//Set VBO data
|
||||
glBindBuffer(GL_ARRAY_BUFFER, _buffersVBO[0]);
|
||||
|
||||
glBufferData(GL_ARRAY_BUFFER, sizeof(_quads[0]) * (_numQuads), NULL, GL_DYNAMIC_DRAW);
|
||||
void *buf = glMapBuffer(GL_ARRAY_BUFFER, GL_WRITE_ONLY);
|
||||
memcpy(buf, _quads, sizeof(_quads[0])* (_numQuads));
|
||||
glUnmapBuffer(GL_ARRAY_BUFFER);
|
||||
|
||||
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||
|
||||
//Bind VAO
|
||||
GL::bindVAO(_VAOname);
|
||||
|
||||
for(size_t i = _firstCommand; i <= _lastCommand; i++)
|
||||
{
|
||||
RenderCommand* command = _renderQueue[i];
|
||||
if (command->getType() == QUAD_COMMAND)
|
||||
{
|
||||
QuadCommand* cmd = static_cast<QuadCommand*>(command);
|
||||
if(_lastMaterialID != cmd->getMaterialID())
|
||||
{
|
||||
//Draw quads
|
||||
if(quadsToDraw > 0)
|
||||
{
|
||||
glDrawElements(GL_TRIANGLES, (GLsizei) quadsToDraw*6, GL_UNSIGNED_SHORT, (GLvoid*) (startQuad*6*sizeof(_indices[0])) );
|
||||
startQuad += quadsToDraw;
|
||||
quadsToDraw = 0;
|
||||
}
|
||||
|
||||
//Use new material
|
||||
cmd->useMaterial();
|
||||
_lastMaterialID = cmd->getMaterialID();
|
||||
}
|
||||
|
||||
quadsToDraw += cmd->getQuadCount();
|
||||
}
|
||||
}
|
||||
|
||||
_firstCommand = _lastCommand;
|
||||
_numQuads = 0;
|
||||
}
|
||||
|
||||
void Renderer::drawQuads()
|
||||
|
|
|
@ -47,12 +47,17 @@ protected:
|
|||
vector<RenderCommand*> _renderQueue;
|
||||
int _lastMaterialID;
|
||||
|
||||
V3F_C4B_T2F_Quad*_quads;
|
||||
GLushort* _indices;
|
||||
size_t _firstCommand;
|
||||
size_t _lastCommand;
|
||||
|
||||
V3F_C4B_T2F_Quad _quads[VBO_SIZE];
|
||||
GLushort _indices[6 * VBO_SIZE];
|
||||
GLuint _VAOname;
|
||||
GLuint _buffersVBO[2]; //0: vertex 1: indices
|
||||
|
||||
int _numQuads;
|
||||
|
||||
void drawBatchedQuads();
|
||||
};
|
||||
|
||||
NS_CC_END
|
||||
|
|
Loading…
Reference in New Issue