2017-04-03 2 views
0

Ich möchte N Textur an einen benutzerdefinierten Shader übergeben. Während ich durch das Netz surfte, ist die beste Option, die ich habe, die Sprite :: draw() - Funktion zu überschreiben und ein CustomCommand-Objekt zum Draw-Pool hinzuzufügen.Übergeben Sie zusätzliche N Texturen an einen benutzerdefinierten Shader in cocos2d

CPP-Datei:

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); 

} 

frament Shader:

#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... 

    } 

Der Shader oben ist nur ein Beispiel und nicht der eigentliche Code ich verwende. Im Moment muss ich nur mehrere Texturen in einem Shader erfolgreich verarbeiten, um ihre Pixel zu verarbeiten.

Derzeit kann ich die übergebene Textur nicht anzeigen. Was sollte getan werden, um dies zu erreichen? Setzt Sprite :: draw() in SpriteSub :: draw() die gl-Befehle von onDraw() aus?

Antwort

0

'Gelöst es!

Sie müssen nicht einmal die Zeichnung überschreiben oder eine CustomCommand hinzufügen, um die Warteschlange zu rendern.

Schritte:

1.) Erstellen Sie eine GLProgramState mit dem GLProgram Objekt, das Sie mit Ihrem eigenen Shadern erstellt.

2.) Verwenden Sie GLProgramState::setUniformTexture("uniformVarName", tex2D), um eine einheitliche Variable zu finden und den Texturnamen zu übergeben.

3.) Rufen Sie sprite->setGLProgramState(programState) statt sprite->setGLProgram(program);

CCP File:

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); 

Fragment-Shader:

#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; 


    } 

Quellen:

Verwandte Themen