mirror of https://github.com/axmolengine/axmol.git
Renderer: Don't sort z=0 Commands
If Command has z==0, then those elements won't be sorted. Only Z !=0 will be sorted, and it will use `sort` instead of `stable_sort` for z!=0, since it is faster
This commit is contained in:
parent
ca58cc06b7
commit
069a4fb170
|
@ -17,10 +17,11 @@ cocos2d-x-3.0final ?.? ?
|
||||||
[FIX] ControlSlider doesn't support to set selected thumb sprite.
|
[FIX] ControlSlider doesn't support to set selected thumb sprite.
|
||||||
[FIX] ControlButton doesn't support to set scale ratio of touchdown state.
|
[FIX] ControlButton doesn't support to set scale ratio of touchdown state.
|
||||||
[FIX] Particles: Crash was triggered if there is not `textureFileName`section in particle plist file.
|
[FIX] Particles: Crash was triggered if there is not `textureFileName`section in particle plist file.
|
||||||
[FIX] Renderer: QuadCommand::init() does not copy the Quads, it only store a reference making the code faster
|
|
||||||
[FIX] Renderer: Performance improved in Sprite and SpriteBatchNode (and subclasses) sprites in about 20%
|
|
||||||
[FIX] Renderer: When note using VAO, call glBufferData() instead of glBufferSubData().
|
|
||||||
[FIX] Renderer: Uses a float as key with only the depth. Viewport, opaque are not needed now
|
[FIX] Renderer: Uses a float as key with only the depth. Viewport, opaque are not needed now
|
||||||
|
[FIX] Renderer Performance Fix: QuadCommand::init() does not copy the Quads, it only store a reference making the code faster
|
||||||
|
[FIX] Renderer Performance Fix: Sprite and SpriteBatchNode (and subclasses) has much better performance
|
||||||
|
[FIX] Renderer Performance Fix: When note using VAO, call glBufferData() instead of glBufferSubData().
|
||||||
|
[FIX] Renderer Performance Fix: Doesn't sort z=0 elements. It also uses sort() instead of stable_sort() for z!=0.
|
||||||
[FIX] Sprite: removed _hasChildren optimization. It uses !_children.empty() now which is super fast as well
|
[FIX] Sprite: removed _hasChildren optimization. It uses !_children.empty() now which is super fast as well
|
||||||
[FIX] Tests: TestCpp works with CMake on Windows.
|
[FIX] Tests: TestCpp works with CMake on Windows.
|
||||||
[FIX] Tests: Sprites Performance Test has 4 new tests
|
[FIX] Tests: Sprites Performance Test has 4 new tests
|
||||||
|
|
|
@ -54,7 +54,7 @@ BatchCommand::~BatchCommand()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
void BatchCommand::execute()
|
void BatchCommand::execute() const
|
||||||
{
|
{
|
||||||
// Set material
|
// Set material
|
||||||
_shader->use();
|
_shader->use();
|
||||||
|
|
|
@ -45,7 +45,7 @@ public:
|
||||||
|
|
||||||
void init(float depth, GLuint texutreID, GLProgram* shader, BlendFunc blendType, TextureAtlas *textureAtlas, const kmMat4& modelViewTransform);
|
void init(float depth, GLuint texutreID, GLProgram* shader, BlendFunc blendType, TextureAtlas *textureAtlas, const kmMat4& modelViewTransform);
|
||||||
|
|
||||||
void execute();
|
void execute() const;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
int32_t _materialID;
|
int32_t _materialID;
|
||||||
|
|
|
@ -42,7 +42,7 @@ CustomCommand::~CustomCommand()
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CustomCommand::execute()
|
void CustomCommand::execute() const
|
||||||
{
|
{
|
||||||
if(func)
|
if(func)
|
||||||
{
|
{
|
||||||
|
|
|
@ -41,7 +41,7 @@ public:
|
||||||
|
|
||||||
void init(float depth);
|
void init(float depth);
|
||||||
|
|
||||||
void execute();
|
void execute() const;
|
||||||
|
|
||||||
inline bool isTranslucent() { return true; }
|
inline bool isTranslucent() { return true; }
|
||||||
std::function<void()> func;
|
std::function<void()> func;
|
||||||
|
|
|
@ -56,12 +56,9 @@ public:
|
||||||
GroupCommand();
|
GroupCommand();
|
||||||
~GroupCommand();
|
~GroupCommand();
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
void init(float depth);
|
void init(float depth);
|
||||||
|
|
||||||
inline bool isTranslucent() {return true;}
|
inline int getRenderQueueID() const {return _renderQueueID;}
|
||||||
inline int getRenderQueueID() {return _renderQueueID;}
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
int _renderQueueID;
|
int _renderQueueID;
|
||||||
|
|
|
@ -101,7 +101,7 @@ void QuadCommand::generateMaterialID()
|
||||||
| (uint32_t)_textureID << 0;
|
| (uint32_t)_textureID << 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void QuadCommand::useMaterial()
|
void QuadCommand::useMaterial() const
|
||||||
{
|
{
|
||||||
_shader->use();
|
_shader->use();
|
||||||
|
|
||||||
|
|
|
@ -44,7 +44,7 @@ public:
|
||||||
void init(float depth, GLuint texutreID, GLProgram* shader, BlendFunc blendType, V3F_C4B_T2F_Quad* quads, ssize_t quadCount,
|
void init(float depth, GLuint texutreID, GLProgram* shader, BlendFunc blendType, V3F_C4B_T2F_Quad* quads, ssize_t quadCount,
|
||||||
const kmMat4& mv);
|
const kmMat4& mv);
|
||||||
|
|
||||||
void useMaterial();
|
void useMaterial() const;
|
||||||
|
|
||||||
//TODO use material to decide if it is translucent
|
//TODO use material to decide if it is translucent
|
||||||
inline bool isTranslucent() const { return true; }
|
inline bool isTranslucent() const { return true; }
|
||||||
|
|
|
@ -50,10 +50,10 @@ public:
|
||||||
};
|
};
|
||||||
|
|
||||||
/** Get Render Command Id */
|
/** Get Render Command Id */
|
||||||
inline float getDepth() { return _depth; }
|
inline float getDepth() const { return _depth; }
|
||||||
|
|
||||||
/** Returns the Command type */
|
/** Returns the Command type */
|
||||||
inline Type getType() { return _type; }
|
inline Type getType() const { return _type; }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
RenderCommand();
|
RenderCommand();
|
||||||
|
|
|
@ -37,9 +37,65 @@
|
||||||
#include <algorithm> // for std::stable_sort
|
#include <algorithm> // for std::stable_sort
|
||||||
|
|
||||||
NS_CC_BEGIN
|
NS_CC_BEGIN
|
||||||
using namespace std;
|
|
||||||
|
bool compareRenderCommand(RenderCommand* a, RenderCommand* b)
|
||||||
|
{
|
||||||
|
return a->getDepth() < b->getDepth();
|
||||||
|
}
|
||||||
|
|
||||||
|
void RenderQueue::push_back(RenderCommand* command)
|
||||||
|
{
|
||||||
|
float z = command->getDepth();
|
||||||
|
if(z < 0)
|
||||||
|
_queueNegZ.push_back(command);
|
||||||
|
if(z > 0)
|
||||||
|
_queuePosZ.push_back(command);
|
||||||
|
else
|
||||||
|
_queue0.push_back(command);
|
||||||
|
}
|
||||||
|
|
||||||
|
ssize_t RenderQueue::size() const
|
||||||
|
{
|
||||||
|
return _queueNegZ.size() + _queue0.size() + _queuePosZ.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
void RenderQueue::sort()
|
||||||
|
{
|
||||||
|
// Don't sort _queue0, it already comes sorted
|
||||||
|
std::sort(std::begin(_queueNegZ), std::end(_queueNegZ), compareRenderCommand);
|
||||||
|
std::sort(std::begin(_queuePosZ), std::end(_queuePosZ), compareRenderCommand);
|
||||||
|
}
|
||||||
|
|
||||||
|
const RenderCommand* RenderQueue::operator[](ssize_t index) const
|
||||||
|
{
|
||||||
|
if(index < _queueNegZ.size())
|
||||||
|
return _queueNegZ[index];
|
||||||
|
|
||||||
|
index -= _queueNegZ.size();
|
||||||
|
|
||||||
|
if(index < _queue0.size())
|
||||||
|
return _queue0[index];
|
||||||
|
|
||||||
|
index -= _queue0.size();
|
||||||
|
|
||||||
|
if(index < _queuePosZ.size())
|
||||||
|
return _queuePosZ[index];
|
||||||
|
|
||||||
|
CCASSERT(false, "invalid index");
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
void RenderQueue::clear()
|
||||||
|
{
|
||||||
|
_queueNegZ.clear();
|
||||||
|
_queue0.clear();
|
||||||
|
_queuePosZ.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
#define DEFAULT_RENDER_QUEUE 0
|
#define DEFAULT_RENDER_QUEUE 0
|
||||||
|
|
||||||
Renderer::Renderer()
|
Renderer::Renderer()
|
||||||
|
@ -205,11 +261,6 @@ int Renderer::createRenderQueue()
|
||||||
return (int)_renderGroups.size() - 1;
|
return (int)_renderGroups.size() - 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool compareRenderCommand(RenderCommand* a, RenderCommand* b)
|
|
||||||
{
|
|
||||||
return a->getDepth() < b->getDepth();
|
|
||||||
}
|
|
||||||
|
|
||||||
void Renderer::render()
|
void Renderer::render()
|
||||||
{
|
{
|
||||||
//Uncomment this once everything is rendered by new renderer
|
//Uncomment this once everything is rendered by new renderer
|
||||||
|
@ -221,9 +272,9 @@ void Renderer::render()
|
||||||
{
|
{
|
||||||
//Process render commands
|
//Process render commands
|
||||||
//1. Sort render commands based on ID
|
//1. Sort render commands based on ID
|
||||||
for (auto it = _renderGroups.begin(); it != _renderGroups.end(); ++it)
|
for (auto &renderqueue : _renderGroups)
|
||||||
{
|
{
|
||||||
std::stable_sort((*it).begin(), (*it).end(), compareRenderCommand);
|
renderqueue.sort();
|
||||||
}
|
}
|
||||||
|
|
||||||
while(!_renderStack.empty())
|
while(!_renderStack.empty())
|
||||||
|
@ -244,7 +295,7 @@ void Renderer::render()
|
||||||
|
|
||||||
if(commandType == RenderCommand::Type::QUAD_COMMAND)
|
if(commandType == RenderCommand::Type::QUAD_COMMAND)
|
||||||
{
|
{
|
||||||
QuadCommand* cmd = static_cast<QuadCommand*>(command);
|
auto cmd = static_cast<const QuadCommand*>(command);
|
||||||
ssize_t cmdQuadCount = cmd->getQuadCount();
|
ssize_t cmdQuadCount = cmd->getQuadCount();
|
||||||
|
|
||||||
//Batch quads
|
//Batch quads
|
||||||
|
@ -266,19 +317,19 @@ void Renderer::render()
|
||||||
else if(commandType == RenderCommand::Type::CUSTOM_COMMAND)
|
else if(commandType == RenderCommand::Type::CUSTOM_COMMAND)
|
||||||
{
|
{
|
||||||
flush();
|
flush();
|
||||||
CustomCommand* cmd = static_cast<CustomCommand*>(command);
|
auto cmd = static_cast<const CustomCommand*>(command);
|
||||||
cmd->execute();
|
cmd->execute();
|
||||||
}
|
}
|
||||||
else if(commandType == RenderCommand::Type::BATCH_COMMAND)
|
else if(commandType == RenderCommand::Type::BATCH_COMMAND)
|
||||||
{
|
{
|
||||||
flush();
|
flush();
|
||||||
BatchCommand* cmd = static_cast<BatchCommand*>(command);
|
auto cmd = static_cast<const BatchCommand*>(command);
|
||||||
cmd->execute();
|
cmd->execute();
|
||||||
}
|
}
|
||||||
else if(commandType == RenderCommand::Type::GROUP_COMMAND)
|
else if(commandType == RenderCommand::Type::GROUP_COMMAND)
|
||||||
{
|
{
|
||||||
flush();
|
flush();
|
||||||
GroupCommand* cmd = static_cast<GroupCommand*>(command);
|
auto cmd = static_cast<const GroupCommand*>(command);
|
||||||
|
|
||||||
_renderStack.top().currentIndex = i + 1;
|
_renderStack.top().currentIndex = i + 1;
|
||||||
|
|
||||||
|
@ -413,10 +464,10 @@ void Renderer::drawBatchedQuads()
|
||||||
//Start drawing verties in batch
|
//Start drawing verties in batch
|
||||||
for(ssize_t i = _firstCommand; i <= _lastCommand; i++)
|
for(ssize_t i = _firstCommand; i <= _lastCommand; i++)
|
||||||
{
|
{
|
||||||
RenderCommand* command = _renderGroups[_renderStack.top().renderQueueID][i];
|
auto command = _renderGroups[_renderStack.top().renderQueueID][i];
|
||||||
if (command->getType() == RenderCommand::Type::QUAD_COMMAND)
|
if (command->getType() == RenderCommand::Type::QUAD_COMMAND)
|
||||||
{
|
{
|
||||||
QuadCommand* cmd = static_cast<QuadCommand*>(command);
|
auto cmd = static_cast<const QuadCommand*>(command);
|
||||||
if(_lastMaterialID != cmd->getMaterialID())
|
if(_lastMaterialID != cmd->getMaterialID())
|
||||||
{
|
{
|
||||||
//Draw quads
|
//Draw quads
|
||||||
|
|
|
@ -37,7 +37,26 @@ NS_CC_BEGIN
|
||||||
|
|
||||||
class EventListenerCustom;
|
class EventListenerCustom;
|
||||||
|
|
||||||
typedef std::vector<RenderCommand*> RenderQueue;
|
/** Class that knows how to sort the Commands.
|
||||||
|
Since the commands that have z==0 are "pushed back" in
|
||||||
|
the correct order, the only Commands that need to be sorted,
|
||||||
|
are the ones that have z <0 and z >0.
|
||||||
|
And that is what this class does.
|
||||||
|
*/
|
||||||
|
class RenderQueue {
|
||||||
|
|
||||||
|
public:
|
||||||
|
void push_back(RenderCommand* command);
|
||||||
|
ssize_t size() const;
|
||||||
|
void sort();
|
||||||
|
const RenderCommand* operator[](ssize_t index) const;
|
||||||
|
void clear();
|
||||||
|
|
||||||
|
protected:
|
||||||
|
std::vector<RenderCommand*> _queueNegZ;
|
||||||
|
std::vector<RenderCommand*> _queue0;
|
||||||
|
std::vector<RenderCommand*> _queuePosZ;
|
||||||
|
};
|
||||||
|
|
||||||
struct RenderStackElement
|
struct RenderStackElement
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in New Issue