Hi!
I have a very simple question, as stated in the title of this topic:
How can someone pass a varying parameter to a shader that is applied on a TextureAtlas.
We can’t subclass the TextureAtlas as the methods that pass those parameters are private (setupVBOandVAO, mapBuffers etc…)
My use case:
I need to add a varying parameter to my shader that is applied on a textureAtlas, let’s call it VERTEX_ATTRIB_TEX_STROKE.
Where could I put the:
glEnableVertexAttribArray(GLProgram::VERTEX_ATTRIB_TEX_STROKE);
glVertexAttribPointer(GLProgram::VERTEX_ATTRIB_TEX_STROKE, 4, GL_FLOAT, GL_FALSE, kQuadSize, (GLvoid*) offsetof( Vertex_t, MyStrokeData));
calls?
Right now I have duplicated the whole TextureAtlas class and duplicated all it’s method, however it causes problems of inheritance and signature function mismatch in issuing openGL command (command.init(…) requires a TextureAtlas and cannot take my custom atlas class that doesn’t inherit from the base TextureAtlas class)
If I am doing something wrong, or if it’s not the right way to do this, feel free to reply too.
Thanks
TextureAtlas has vertex objects in the form of V3F_C4B_T2F_Quad. They take a position, color and texture coordinate. You can’t change that functionality as far as I can tell. The problem with a lot of the Cocos2d-x classes are they don’t allow you to modify the VBO’s with ease.
Where is the use of command.init(… ) ?
it is used here, in The SpriteBatchNode
void SpriteBatchNode::draw(Renderer *renderer, const Mat4 &transform, uint32_t flags)
{
// Optimization: Fast Dispatch
if( _textureAtlas->getTotalQuads() == 0 )
{
return;
}
for (const auto &child : _children)
{
child->updateTransform();
}
_batchCommand.init(_globalZOrder, getGLProgram(), _blendFunc, _textureAtlas, transform, flags);
renderer->addCommand(&_batchCommand);
}
I have also created a duplicate of the SpriteBatchNode class that inherit from node in order to be able to use my new atlas which doesn’t inherit from TextureAtlas.
Thanks for your reply!
Yes, I have also created a custom MyStrokeData that store the additional parameters I need to pass to my shader.
I’m glad you got it working
Actually It is not working right now, I have just listed what I have done, until I hit the command.init problem. It is where I stand now.
I tried to used the old way of drawing things, like this:
void StrokeQuadBatchNode::draw(Renderer *renderer, const Mat4 &transform, uint32_t flags)
{
// [PORT] OUCH, That is messy, but we can't use commands as it expect a
// valid TextureAtlas
// Optimization: Fast Dispatch
if( _textureAtlas->getTotalQuads() == 0 )
{
return;
}
CC_NODE_DRAW_SETUP();
//arrayMakeObjectsPerformSelector(_children, updateTransform, Sprite*);
do {
if(_children.size() > 0)
{
for (int i = 0; i< _children.size(); ++i) {
Sprite* pNode = dynamic_cast<Sprite*>(_children.at(i));
if(pNode)
{
pNode->updateTransform();
}
}
}
}
while(false);
glBlendFunc( _blendFunc.src, _blendFunc.dst );
_textureAtlas->drawQuads();
// Optimization: Fast Dispatch
// if( _textureAtlas->getTotalQuads() == 0 )
// {
// return;
// }
//
// for (const auto &child : _children)
// {
// child->updateTransform();
// }
//
// this is where is doesn't compile using my _textureAtlas, which doesn't inherit from CCTextureAtlas...
// _batchCommand.init(_globalZOrder, getGLProgram(), _blendFunc, _textureAtlas, transform, flags);
// renderer->addCommand(&_batchCommand);
}
As you can see I commented out the command stuff and get back to the draw method of cocos2Dx v2, but I am REALLY not sure it still works, with the new way of passing command to the rendering pipeline etc.
It’s a bit hacky but since your custom textureatlas class is essentially identical to the original can’t you cast to to a pointer of type CCTextureAtlas then pass it through. Some sort of cast. I can’t think of anything else right now sorry.