Проблемы с Cocos2dx CCRendertexture и framebuffer. Моя новая текстура не выглядит так же. Альфа-значения неверны

У меня возникла небольшая проблема при попытке использовать класс CCRenderTexture из Cocos2Dx для iPhone (который, насколько я понимаю, является просто классом FBO).

У меня есть класс, производный от CCSprite. В ней я пытаюсь нарисовать текстуру в текстуру CCrender, а затем сохранить ее на потом. Однако я заметил, что значения альфа в моей новой текстуре, похоже, усилились. Моя новая текстура выглядит немного более блеклой, чем оригинальная, кажется, что она воздействует только на пиксели с альфа-значением менее 1,0.

Вот код, который я использую:

CCRenderTexture* myRenderTexture = CCRenderTexture::create((int)getContentSize().width, (int)getContentSize().height);   //set RenderTexture to same size as sprite

myRenderTexture->begin();

CC_NODE_DRAW_SETUP();

ccGLEnableVertexAttribs(kCCVertexAttribFlag_PosColorTex);

ccGLBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);      //Is this where my problem is?  

glActiveTexture(GL_TEXTURE0);


glBindTexture( GL_TEXTURE_2D, finalTexture->getName());     //finalTexture is created before this code is run
glUniform1i(textureLocation, 0);


long offset = (long)&m_sQuad;

// vertex
int diff = offsetof( ccV3F_C4B_T2F, vertices);
glVertexAttribPointer(kCCVertexAttrib_Position, 3, GL_FLOAT, GL_FALSE, kQuadSize, (void*) (offset + diff));
// texCoods
diff = offsetof( ccV3F_C4B_T2F, texCoords);
glVertexAttribPointer(kCCVertexAttrib_TexCoords, 2, GL_FLOAT, GL_FALSE, kQuadSize, (void*)(offset + diff));
// color
diff = offsetof( ccV3F_C4B_T2F, colors);
glVertexAttribPointer(kCCVertexAttrib_Color, 4, GL_UNSIGNED_BYTE, GL_TRUE, kQuadSize, (void*)(offset + diff));

glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
glActiveTexture(GL_TEXTURE0);


myRenderTexture->end();
finalTexture = myRenderTexture->getSprite()->getTexture();   //Replace Final Texture with my new texture (Should be exact same)

finalTexture->retain();
myRenderTexture->release();

В качестве теста я запускал приведенный выше код 4 раза подряд. Каждый раз текстура, казалось, исчезала немного больше. Но я ожидаю, что он будет выглядеть одинаково каждый раз.

Следующим шагом я должен был заменить ccGLBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA) с ccGLBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA) Казалось, это решило мою проблему, так как полученная текстура выглядела одинаково, независимо от того, сколько раз я ее запускал. Тем не менее, я также запускаю пользовательский фрагментный шейдер на этой текстуре (шейдер не изображен и не работает во время этого теста), и он требует ccGLBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA) работать правильно.

После некоторых исследований я попытался заменить ccGLBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA) с glBlendFuncSeparate(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA,GL_ONE, GL_SRC_ALPHA), Я надеялся, что это поддержит мои уровни альфа, изменяя значения цвета. К сожалению, это имело противоположный эффект и, казалось, фактически притупляло альфу, вызывая темноту текстуры.

Вот картина с моими тремя тестами. Этот актив снизу бикини позволяет легко увидеть эффект;)

Может кто-нибудь сказать мне, что я делаю, делаю неправильно и что вызывает эти эффекты? Это мой BlendFunc? Я должен быть в состоянии привлечь к CCRenderTexture (или FBO) несколько раз подряд, и я не хочу никаких нежелательных эффектов на изображении. Мне также нужно использовать мои шейдеры... так ccGLBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA) не работает...

Любая помощь приветствуется! Заранее спасибо!

1 ответ

Решение

Я смог найти решение, которое сработало для меня. Я не уверен, что это идеально или есть лучший способ, но, похоже, он работает.

Как я уже говорил, используя ccGLBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA) позволил мне использовать CCRenderTexture столько раз, сколько я хотел, но мои шейдеры не работали правильно.

Изменение на glBlendFuncSeparate(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA,GL_ONE, GL_SRC_ALPHA) позволял шейдерам, но текстура темнела каждый раз, когда я делал это CCRenderTexture,

После сравнения текстур в фотошопе оказалось, что glBlendFuncSeparate(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA,GL_ONE, GL_SRC_ALPHA) умножил бы мои значения цвета на мое альфа-значение. Думаю, это имеет смысл, потому что я устанавливаю цветовую смесь на GL_ONE_MINUS_SRC_ALPHA,

Поэтому мое решение состояло в том, чтобы полностью изменить этот эффект, разделив мои значения цвета на значение альфа в шейдере. Я добавил эти строки в конец моего шейдера.

texColor.r = texColor.r / texColor.a;      \n\
texColor.b = texColor.b / texColor.a;      \n\
texColor.g = texColor.g / texColor.a;      \n\ 

Это кажется немного глупым, я бы предпочел найти способ, который вообще не вносит эти изменения в цвет, потому что этот шаг расточителен. Но это работает!

Другие вопросы по тегам