Went from V2 to V3.7 ported OpenGL code and got errors and questions now? Error: Failed to make complete framer buffer object 0x8CD9

Hi!
Did go from V2 to V3 but now i got an annoying error/issue in openGL? Used to get gradient but now i got plain color in V2 but after i’ve updated the code it doesn’t work as it should…
This is the code:

[code]Sprite* HelloWorld::spriteWithColor(Color4F bgColor, float textureWidth, float textureHeight)

{

// 1: Create new CCRenderTexture

RenderTexture* rt = RenderTexture::create(textureWidth, textureHeight);



// 2: Call CCRenderTexture:begin

rt->beginWithClear(bgColor.r, bgColor.g, bgColor.b, bgColor.a);



// 3: Draw into the texture

float gradientAlpha = 0.7;

Point vertices[4];

Color4F colors[4];

int nVertices = 0;



   vertices[nVertices] = Point(0, 0);

colors[nVertices++] = (Color4F){0, 0, 0, 0 };

vertices[nVertices] = Point(textureWidth, 0);

colors[nVertices++] = (Color4F){0, 0, 0, 0 };

vertices[nVertices] = Point(0, textureHeight);

colors[nVertices++] = (Color4F){0, 0, 0, gradientAlpha};

vertices[nVertices] = Point(textureWidth, textureHeight);

colors[nVertices++] = (Color4F){0, 0, 0, gradientAlpha};



// Set the shader program for OpenGL

  this->setGLProgram(ShaderCache::getInstance()->getGLProgram(GLProgram::SHADER_NAME_POSITION_COLOR));

CC_NODE_DRAW_SETUP();



GL::enableVertexAttribs(GL::VERTEX_ATTRIB_FLAG_COLOR  | GL::VERTEX_ATTRIB_FLAG_POSITION);



glVertexAttribPointer(GL::VERTEX_ATTRIB_FLAG_POSITION, 2, GL_FLOAT, GL_FALSE, 0, vertices);

glVertexAttribPointer(GL::VERTEX_ATTRIB_FLAG_COLOR, 4, GL_FLOAT, GL_FALSE, 0, colors);

glBlendFunc(CC_BLEND_SRC, CC_BLEND_DST);

glDrawArrays(GL_TRIANGLE_STRIP, 0, (GLsizei)nVertices);





Sprite* noise = Sprite::create("Noise.png");

noise->setScaleY(1536/512);

noise->setScaleX(2048/512);

BlendFunc myBlend;

myBlend.src = GL_DST_COLOR;

myBlend.dst = GL_ZERO;

noise->setBlendFunc(myBlend);



noise->setPosition(Vec2(textureWidth/2, textureHeight/2));

noise->visit();



// 4: Call CCRenderTexture:end

rt->end();



// 5: Create a new Sprite from the texture

return Sprite::createWithTexture(rt->getSprite()->getTexture());

}

[/code]
So, this works in V2 ofc without the updating of the code…But i know it should give the same…But in V3 it just gives a plain color, no gradient??
THEN i searched on google for some solutions and i found one without any comments on but it was from one of cocos2d-x’s developers so that should work too, here’s the code from him:

[code]Sprite* HelloWorld::spriteWithColor(cocos2d::Color4F bgColor, float textureWidth, float textureHeight)
{
RenderTexture *rt = RenderTexture::create(textureWidth, textureHeight);

rt->beginWithClear(bgColor.r, bgColor.g, bgColor.b, bgColor.a);

CustomCommand _customCommand;
// 3: Draw into the texture
//Caution!!!  if you want to use your own opengl draw call ,you must wrap them with a custom command
_customCommand.init(rt->getGlobalZOrder());
_customCommand.func = CC_CALLBACK_0(HelloWorld::onDraw,this);
auto renderer = Director::getInstance()->getRenderer();
renderer->addCommand(&_customCommand);



rt->end();


return Sprite::createWithTexture(rt->getSprite()->getTexture());

}

void HelloWorld::onDraw()
{
this->setGLProgram(ShaderCache::getInstance()->getGLProgram(GLProgram::SHADER_NAME_POSITION_COLOR));
this->getGLProgram()->use();
this->getGLProgram()->setUniformsForBuiltins();

Size winSize = Director::getInstance()->getVisibleSize();


float gradientAlpha =  0.7;
Vec2 vertices[4];
Color4F colors[4];
int nVertices = 0;

vertices[nVertices] = Vec2(0, 0);
colors[nVertices++] = (Color4F){0, 0, 0, 0 };
vertices[nVertices] = Vec2(winSize.width, 0);
colors[nVertices++] = (Color4F){0, 0, 0, 0};
vertices[nVertices] = Vec2(0, winSize.height);
colors[nVertices++] = (Color4F){0, 0, 0, gradientAlpha};
vertices[nVertices] = Vec2(winSize.width, winSize.height);
colors[nVertices++] = (Color4F){0, 0, 0, gradientAlpha};

GL::enableVertexAttribs(GL::VERTEX_ATTRIB_FLAG_COLOR | GL::VERTEX_ATTRIB_FLAG_POSITION);

glVertexAttribPointer(GLProgram::VERTEX_ATTRIB_POSITION, 2, GL_FLOAT, GL_FALSE, 0, vertices);
glVertexAttribPointer(GLProgram::VERTEX_ATTRIB_COLOR, 4, GL_FLOAT, GL_FALSE, 0, colors);
glBlendFunc(CC_BLEND_SRC, CC_BLEND_DST);
glDrawArrays(GL_TRIANGLE_STRIP, 0, (GLsizei)nVertices);

}
[/code]
But that gives me a plain color too!! This is so annoying and that’s one of the reasons i won’t change to V3
but everyone says i should…:confused:
Please help, Thanks!!
Much appreciated…
@slackmoehrle, @owen, @pandamicro…I think the second code snippet was from owen, so maybe you know that i shall do? I just tagged you guys because i know u are in with all this!
Thanks again!

The way Ive used custom commands is to create a subclassed sprite, and to add my GL calls to a custom command that I add to the renderer each time the visit member of the Sprite is called.

I can see that your use case is a bit different - you are trying to render to a RenderTexture just once at sprite creation, so I would guess that just getting a Renderer outside of the paint loop needs a bit more setup to work successfully. Does a breakpoint in the onDraw method ever actually break?

Thanks so much for the quick reply!
Okay, so i’ve tried to set a breakpoint the OnDraw func but apparently it’s not getting called?
Any suggestions? and why doesn’t the first code snippet work when it worked successfully in V2? I have even updated the code…

Thanks!

I would try adding a call to renderer->render(); to actually get it to execute the command list.

Thanks for ur time but it still doesn’t work…
Anybody, this is probably what the game consists…OpenGL? any suggestions?

Ok, so i’ve just tried @owen 's code snippet in a new project just in case:

[code]// on “init” you need to initialize your instance
bool HelloWorld::init()
{
//////////////////////////////
// 1. super init first
if ( !Layer::init() )
{
return false;
}

Size visibleSize = Director::getInstance()->getVisibleSize();
Vec2 origin = Director::getInstance()->getVisibleOrigin();

Color4F CCCc= Color4F(9, 244, 77, 1);

// add "HelloWorld" splash screen"
auto sprite = spriteWithColor(Color4F::BLUE, 1024, 768);

// position the sprite on the center of the screen
sprite->setPosition(Vec2(visibleSize.width/2 + origin.x, visibleSize.height/2 + origin.y));

// add the sprite as a child to this layer
this->addChild(sprite, 0);

return true;

}

Sprite* HelloWorld::spriteWithColor(cocos2d::Color4F bgColor, float textureWidth, float textureHeight)
{
RenderTexture *rt = RenderTexture::create(textureWidth, textureHeight);
rt->retain();
rt->beginWithClear(bgColor.r, bgColor.g, bgColor.b, bgColor.a);

CustomCommand _customCommand ;
// 3: Draw into the texture
//Caution!!!  if you want to use your own opengl draw call ,you must wrap them with a custom command
_customCommand.init(rt->getGlobalZOrder());
_customCommand.func = CC_CALLBACK_0(HelloWorld::onDraw,this);
auto renderer = Director::getInstance()->getRenderer();
renderer->addCommand(&_customCommand);

renderer->render();

rt->end();


return Sprite::createWithTexture(rt->getSprite()->getTexture());

}

void HelloWorld::onDraw()
{
this->setGLProgram(ShaderCache::getInstance()->getGLProgram(GLProgram::SHADER_NAME_POSITION_COLOR));
this->getGLProgram()->use();
this->getGLProgram()->setUniformsForBuiltins();

Size winSize = Director::getInstance()->getVisibleSize();


float gradientAlpha =  0.7;
Vec2 vertices[4];
Color4F colors[4];
int nVertices = 0;

vertices[nVertices] = Vec2(0, 0);
colors[nVertices++] = (Color4F){0, 0, 0, 0 };
vertices[nVertices] = Vec2(winSize.width, 0);
colors[nVertices++] = (Color4F){0, 0, 0, 0};
vertices[nVertices] = Vec2(0, winSize.height);
colors[nVertices++] = (Color4F){0, 0, 0, gradientAlpha};
vertices[nVertices] = Vec2(winSize.width, winSize.height);
colors[nVertices++] = (Color4F){0, 0, 0, gradientAlpha};

GL::enableVertexAttribs(GL::VERTEX_ATTRIB_FLAG_COLOR | GL::VERTEX_ATTRIB_FLAG_POSITION);

glVertexAttribPointer(GLProgram::VERTEX_ATTRIB_POSITION, 2, GL_FLOAT, GL_FALSE, 0, vertices);
glVertexAttribPointer(GLProgram::VERTEX_ATTRIB_COLOR, 4, GL_FLOAT, GL_FALSE, 0, colors);
glBlendFunc(CC_BLEND_SRC, CC_BLEND_DST);
glDrawArrays(GL_TRIANGLE_STRIP, 0, (GLsizei)nVertices);

}
[/code]
So there is a gradient and i tried it on a real device, iPad 4…But now it says,
TryOpenGl-mobile[941:494567] Failed to make complete framebuffer object 0x8CD9
OpenGL error 0x0506 in /Users/Admin/Downloads/cocos2d-x-3.7/TryOpenGl/cocos2d/cocos/renderer/CCFrameBuffer.cpp applyFBO 444

Why? If someone answer, Thank you so much<3

Update: And can’t i just use the first code snippet i showed, it’s way much faster to create and you can have different functions in the same class…??? and isn’t cocos2d-x 3 alpha 0 much more easier than v3.7…I don’t understand the developers atm…:confused: And no matter what size i put in the parameter of the "spriteWithColor func i’m always getting the outcome to be fullscreen? this is so annoying!
Last thing, this code works in cocos2d-x 3 alpha 0: [code]Sprite* HelloWorld::spriteWithColor(cocos2d::Color4F bgColor, float textureWidth, float textureHight)
{
//1: Create new RenderTexture
RenderTexture* rt = RenderTexture::create(textureWidth, textureHight);

//2: Call RenderTexture:begin
rt->beginWithClear(bgColor.r, bgColor.g, bgColor.b, bgColor.a);
this->setShaderProgram(ShaderCache::getInstance()->getProgram(GLProgram::SHADER_NAME_POSITION_COLOR));
CC_NODE_DRAW_SETUP();
//3: Draw into the texture
float gradientAlpha = 0.7f;
Point vertices[4];
Color4F colors[4];
int nVertices = 0;
vertices[nVertices] = Point(0, 0);
colors[nVertices++] = Color4F(0, 0, 0, 0);


vertices[nVertices] = Point(textureWidth, 0);
colors[nVertices++] = Color4F(0, 0, 0, 0);
vertices[nVertices] = Point(0, textureHight);

colors[nVertices++] = Color4F(0, 0, 0, gradientAlpha);
vertices[nVertices] = Point(textureWidth, textureHight);
colors[nVertices++] = Color4F(0, 0, 0, gradientAlpha);

GL::enableVertexAttribs(GL::VERTEX_ATTRIB_FLAG_POSITION | GL::VERTEX_ATTRIB_FLAG_COLOR);
glVertexAttribPointer(GLProgram::VERTEX_ATTRIB_POSITION, 2, GL_FLOAT, GL_FALSE, 0, vertices);
glVertexAttribPointer(GLProgram::VERTEX_ATTRIB_COLOR, 4, GL_FLOAT, GL_FALSE, 0, colors);


glBlendFunc(CC_BLEND_SRC, CC_BLEND_DST);
glDrawArrays(GL_TRIANGLE_STRIP, 0, (GLsizei)nVertices);
//3: Draw into the texture
//You'll add this later



//4: Call RenderTexture:end
rt->end();
return Sprite::createWithTexture(rt->getSprite()->getTexture());

}
[/code]
Why can’t you u just use that code in v 3.7? and what should ii do then!?
Please help!
Thanks!

I will investigate your code later. Thanks for mention me.

1 Like