Cocos2dx CCRendertexture 和 framebuffer 对象问题。我的新纹理看起来不一样。 Alpha 值不正确
Posted
技术标签:
【中文标题】Cocos2dx CCRendertexture 和 framebuffer 对象问题。我的新纹理看起来不一样。 Alpha 值不正确【英文标题】:Cocos2dx CCRendertexture and framebuffer object problems. My new texture doesn't look the same. Alpha values are incorrect 【发布时间】:2013-05-23 02:43:55 【问题描述】:我在尝试将 Cocos2Dx 中的 CCRenderTexture 类用于 iPhone 时遇到了一点问题(据我所知,它只是一个 FBO 类)。
我有一个派生自 CCSprite 的类。在其中,我尝试将纹理绘制到 CCrenderTexture,然后将其保存以备后用。但是,我注意到我的新纹理中的 alpha 值似乎已经增强了。我的新纹理看起来比原始纹理更褪色,它似乎只影响 alpha 小于 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)
才能正常工作。
经过一番研究,我尝试用glBlendFuncSeparate(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA,GL_ONE, GL_SRC_ALPHA)
替换ccGLBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)
。我希望这将保持我的 alpha 水平,同时改变颜色值。不幸的是,这产生了相反的效果,似乎实际上使 alpha 变暗,导致纹理变暗。
这是我的三个测试的图片。这个比基尼底部资产很容易看到效果;)
谁能告诉我我做错了什么以及是什么导致了这些影响?是我的BlendFunc
吗?我需要能够连续多次绘制CCRenderTexture
(或FBO),并且我不希望对图像产生任何不良影响。我还需要使用我的着色器……所以ccGLBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA)
不起作用……
感谢任何帮助!提前致谢!
【问题讨论】:
可能是预乘 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
时纹理都会变暗。
在 Photoshop 中比较纹理后,glBlendFuncSeparate(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA,GL_ONE, GL_SRC_ALPHA)
似乎会将我的颜色值乘以我的 alpha 值。我想这是有道理的,因为我将颜色混合设置为GL_ONE_MINUS_SRC_ALPHA
。
所以我的解决方案是通过将我的颜色值除以着色器中的 alpha 值来反转这种效果。我将这些行添加到我的着色器的末尾。
texColor.r = texColor.r / texColor.a; \n\
texColor.b = texColor.b / texColor.a; \n\
texColor.g = texColor.g / texColor.a; \n\
看起来有点傻,我宁愿找到一种根本不对颜色进行这些更改的方法,因为这一步很浪费。但它有效!
【讨论】:
以上是关于Cocos2dx CCRendertexture 和 framebuffer 对象问题。我的新纹理看起来不一样。 Alpha 值不正确的主要内容,如果未能解决你的问题,请参考以下文章