With the new renderer, every time you call visit on, lets say, a sprite, even when inside a RenderTexture begin() / end() pair, what you are actually doing is changing the _quadCommand inside the sprite, which in turn is changing the quadCommand that is in renderer’s the render group, since it is storing a pointer to that quad command.
(See Using RenderTexture to render one sprite multiple times and RenderTexture visit problem for two examples of users having problems with their code in v3.x that worked in v2.x)
This makes it so that running the following example
_renderTarget->begin(); _sprite->setScale(4); _sprite->setPosition(Point(10, 10)); _sprite->visit(); _sprite->setPosition(Point(50, 50)); _sprite->visit(); _sprite->setPosition(Point(250, 250)); _sprite->visit(); _renderTarget->end();
is pointless since you are just changing the underlying QuadCommand three times, making its last change the one that will actually count and be used in the rendering itself.
This only happens because a sprite uses only one quad command for everything.
So if you want to emulate the behavior in the code above in v3.x, you would have to create 3 Sprites, wasting both time and space to the developer and to the running program.
I am thinking of adding a new “visit” method inside Sprite, that submits a new QuadCommand to the renderer instead of changing the only one that it currently has. This way the code above works correctly (I have implemented it and tested it) and it just seems more natural and intuitive.
I was wondering what do you guys think of this approach, and what was the rationale behind the decision of just having one quad command inside the Sprite class.
Wouldn’t it just make more sense to have a vector of quad commands inside Sprite, that would be cleared after each render for example? This way, both the normal visit cycle case and the render texture case would work just fine
Something along these lines
In the header:
private std::vector<QuadCommand*> _quadCommands;
QuadCommand* quadCmd = new QuadCommand; quadCmd->init(_globalZOrder, _texture->getName(), getGLProgramState(), _blendFunc, &_quad, 1, transform); _quadCommands.push_back(quadCmd); renderer->addCommand(quadCmd);
with proper memory management etc of course