在 cocos2d 中将额外的 N 个纹理传递给自定义着色器
Pass additional N textures to a custom shader in cocos2d
我想将 N 个纹理传递给自定义着色器。当我上网冲浪时,我得到的最佳选择是重写 Sprite::draw() 函数并将 CustomCommand 对象添加到绘制池中。
CPP 文件:
void SpriteSub::draw(Renderer *renderer, const Mat4 &transform, uint32_t flags) {
m_cmdCustom.init(_globalZOrder, transform, flags);
m_cmdCustom.func = CC_CALLBACK_0(SpriteSub::onDraw, this, transform, flags);
renderer->addCommand(&m_cmdCustom);
Sprite::draw(renderer, transform, flags);
}
void SpriteSub::onDraw(const Mat4 &transform, uint32_t /*flags*/) {
this->getGLProgram()->use();
auto wwProgram = m_shader->getProgram();
auto texBall0 = Director::getInstance()->getTextureCache()->addImage("ball.png")->getName();
GLuint locTexIcon0 = glGetUniformLocation(wwProgram, "texBall0");
glUniform1i(locTexIcon0, 0);
//glActiveTexture(GL_TEXTURE0 + 0); glBindTexture(GL_TEXTURE_2D, texBall0);
//glActiveTexture(GL_TEXTURE0 + 0);
GL::bindTexture2D(texBall0);
}
帧着色器:
#ifdef GL_ES
precision lowp float;
#endif
varying vec4 v_fragmentColor;
varying vec2 v_texCoord;
uniform sampler2D texBall0;
uniform sampler2D texBall1;
//uniform sampler2D texBall2;
//uniform sampler2D texBall3;
//uniform sampler2D texBall4;
//uniform sampler2D texBall5;
void main()
{
float t = 0.7f;
//gl_FragColor = texture2D(CC_Texture0, v_texCoord);
//this is just a sample code
gl_FragColor = texture2D(texBall0, v_texCoord) * t;
gl_FragColor += texture2D(texBall1, v_texCoord) * (t-1);
//some code that uses the other textures...
}
上面的着色器只是一个示例,并不是我正在使用的实际代码。现在,我只需要在单个着色器中成功传递多个纹理来处理它们的像素。
目前,我无法显示传递的纹理。应该怎么做才能实现这一目标? SpriteSub::draw() 中的 Sprite::draw() 是否取消了来自 onDraw() 的 gl 命令?
'解决了!
您甚至不需要覆盖绘图或添加 CustomCommand
到渲染队列。
步骤:
1.) 使用您使用自定义着色器创建的 GLProgram
对象创建一个 GLProgramState
。
2.) 使用GLProgramState::setUniformTexture("uniformVarName", tex2D)
定位统一变量并传递纹理名称。
3.) 调用 sprite->setGLProgramState(programState)
而不是 sprite->setGLProgram(program)
;
中共文件:
m_shader = GLProgram::createWithByteArrays(ccPositionTextureColor_noMVP_vert, shader_frag);
m_shader->retain();
auto shaderState = GLProgramState::getOrCreateWithGLProgram(m_shader);
auto textureCache = Director::getInstance()->getTextureCache();
auto img0 = textureCache->addImage("icon_tex0.png")->getName();
auto img1 = textureCache->addImage("icon_tex1.png")->getName();
auto img2 = textureCache->addImage("icon_tex2.png")->getName();
auto img3 = textureCache->addImage("icon_tex3.png")->getName();
auto img4 = textureCache->addImage("icon_tex4.png")->getName();
auto img5 = textureCache->addImage("icon_tex5.png")->getName();
shaderState->setUniformTexture("texIcon0", img0);
shaderState->setUniformTexture("texIcon1", img1);
shaderState->setUniformTexture("texIcon2", img2);
shaderState->setUniformTexture("texIcon3", img3);
shaderState->setUniformTexture("texIcon4", img4);
shaderState->setUniformTexture("texIcon5", img5);
//this->setGLProgram(m_shader);
this->setGLProgramState(shaderState);
片段着色器:
#ifdef GL_ES
precision lowp float;
#endif
varying vec4 v_fragmentColor;
varying vec2 v_texCoord;
uniform sampler2D texIcon0;
uniform sampler2D texIcon1;
uniform sampler2D texIcon2;
uniform sampler2D texIcon3;
uniform sampler2D texIcon4;
uniform sampler2D texIcon5;
void main()
{
int numTex = 6;
float fWeight = 1.0f/float(length);
//gl_FragColor = texture2D(CC_Texture0, v_texCoord);
gl_FragColor += texture2D(texIcon0, v_texCoord) * fWeight;
gl_FragColor += texture2D(texIcon1, v_texCoord) * fWeight;
gl_FragColor += texture2D(texIcon2, v_texCoord) * fWeight;
gl_FragColor += texture2D(texIcon3, v_texCoord) * fWeight;
gl_FragColor += texture2D(texIcon4, v_texCoord) * fWeight;
gl_FragColor += texture2D(texIcon5, v_texCoord) * fWeight;
}
来源:
我想将 N 个纹理传递给自定义着色器。当我上网冲浪时,我得到的最佳选择是重写 Sprite::draw() 函数并将 CustomCommand 对象添加到绘制池中。
CPP 文件:
void SpriteSub::draw(Renderer *renderer, const Mat4 &transform, uint32_t flags) {
m_cmdCustom.init(_globalZOrder, transform, flags);
m_cmdCustom.func = CC_CALLBACK_0(SpriteSub::onDraw, this, transform, flags);
renderer->addCommand(&m_cmdCustom);
Sprite::draw(renderer, transform, flags);
}
void SpriteSub::onDraw(const Mat4 &transform, uint32_t /*flags*/) {
this->getGLProgram()->use();
auto wwProgram = m_shader->getProgram();
auto texBall0 = Director::getInstance()->getTextureCache()->addImage("ball.png")->getName();
GLuint locTexIcon0 = glGetUniformLocation(wwProgram, "texBall0");
glUniform1i(locTexIcon0, 0);
//glActiveTexture(GL_TEXTURE0 + 0); glBindTexture(GL_TEXTURE_2D, texBall0);
//glActiveTexture(GL_TEXTURE0 + 0);
GL::bindTexture2D(texBall0);
}
帧着色器:
#ifdef GL_ES
precision lowp float;
#endif
varying vec4 v_fragmentColor;
varying vec2 v_texCoord;
uniform sampler2D texBall0;
uniform sampler2D texBall1;
//uniform sampler2D texBall2;
//uniform sampler2D texBall3;
//uniform sampler2D texBall4;
//uniform sampler2D texBall5;
void main()
{
float t = 0.7f;
//gl_FragColor = texture2D(CC_Texture0, v_texCoord);
//this is just a sample code
gl_FragColor = texture2D(texBall0, v_texCoord) * t;
gl_FragColor += texture2D(texBall1, v_texCoord) * (t-1);
//some code that uses the other textures...
}
上面的着色器只是一个示例,并不是我正在使用的实际代码。现在,我只需要在单个着色器中成功传递多个纹理来处理它们的像素。
目前,我无法显示传递的纹理。应该怎么做才能实现这一目标? SpriteSub::draw() 中的 Sprite::draw() 是否取消了来自 onDraw() 的 gl 命令?
'解决了!
您甚至不需要覆盖绘图或添加 CustomCommand
到渲染队列。
步骤:
1.) 使用您使用自定义着色器创建的 GLProgram
对象创建一个 GLProgramState
。
2.) 使用GLProgramState::setUniformTexture("uniformVarName", tex2D)
定位统一变量并传递纹理名称。
3.) 调用 sprite->setGLProgramState(programState)
而不是 sprite->setGLProgram(program)
;
中共文件:
m_shader = GLProgram::createWithByteArrays(ccPositionTextureColor_noMVP_vert, shader_frag);
m_shader->retain();
auto shaderState = GLProgramState::getOrCreateWithGLProgram(m_shader);
auto textureCache = Director::getInstance()->getTextureCache();
auto img0 = textureCache->addImage("icon_tex0.png")->getName();
auto img1 = textureCache->addImage("icon_tex1.png")->getName();
auto img2 = textureCache->addImage("icon_tex2.png")->getName();
auto img3 = textureCache->addImage("icon_tex3.png")->getName();
auto img4 = textureCache->addImage("icon_tex4.png")->getName();
auto img5 = textureCache->addImage("icon_tex5.png")->getName();
shaderState->setUniformTexture("texIcon0", img0);
shaderState->setUniformTexture("texIcon1", img1);
shaderState->setUniformTexture("texIcon2", img2);
shaderState->setUniformTexture("texIcon3", img3);
shaderState->setUniformTexture("texIcon4", img4);
shaderState->setUniformTexture("texIcon5", img5);
//this->setGLProgram(m_shader);
this->setGLProgramState(shaderState);
片段着色器:
#ifdef GL_ES
precision lowp float;
#endif
varying vec4 v_fragmentColor;
varying vec2 v_texCoord;
uniform sampler2D texIcon0;
uniform sampler2D texIcon1;
uniform sampler2D texIcon2;
uniform sampler2D texIcon3;
uniform sampler2D texIcon4;
uniform sampler2D texIcon5;
void main()
{
int numTex = 6;
float fWeight = 1.0f/float(length);
//gl_FragColor = texture2D(CC_Texture0, v_texCoord);
gl_FragColor += texture2D(texIcon0, v_texCoord) * fWeight;
gl_FragColor += texture2D(texIcon1, v_texCoord) * fWeight;
gl_FragColor += texture2D(texIcon2, v_texCoord) * fWeight;
gl_FragColor += texture2D(texIcon3, v_texCoord) * fWeight;
gl_FragColor += texture2D(texIcon4, v_texCoord) * fWeight;
gl_FragColor += texture2D(texIcon5, v_texCoord) * fWeight;
}
来源: