我在尝试使用Cocos2Dx中的CCRenderTexture类时遇到了一些问题(据我所知,它只是一个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)
才能正常工作。
经过一些研究,我尝试用ccGLBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)
替换glBlendFuncSeparate(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA,GL_ONE, GL_SRC_ALPHA)
。我希望这会保持我的alpha级别,同时改变颜色值。不幸的是,这有相反的效果,似乎实际上使alpha变钝,导致纹理变暗。
这是我的三次测试的照片。这种比基尼底部资产让人很容易看到效果;)
有人能告诉我我做错了什么以及造成这些影响的原因是什么?是我的BlendFunc
吗?我需要能够连续几次绘制到CCRenderTexture
(或FBO),我不希望对图像产生任何不良影响。我还需要使用我的着色器......所以ccGLBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA)
不起作用......
任何帮助表示赞赏!提前谢谢!
答案 0 :(得分:2)
我能够找到适合我的解决方案。我不确定它是否理想,或者是否有更好的方法,但似乎有效。
正如我之前所说,使用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\
看起来有点傻,我宁愿找到一种根本不会对颜色进行这些改变的方法,因为这一步很浪费。但它有效!