在cocos2d-x中创建自定义着色器会在android上显示黑屏

时间:2014-08-05 06:47:24

标签: android opengl-es cocos2d-x shader

我在cocos2d-x游戏中使用自定义着色器来显示聚光灯效果。它在iPhone上正常工作,但它不工作Android设备。它显示黑屏。

我从这个链接https://github.com/wantnon/2D-lighting

中得到了参考

以下是我的Sprite子类

这是CmaskedSceneSprite.cpp

bool CmaskedSceneSprite::init(Texture2D *texture) {  

    if(Sprite::initWithTexture(texture))
       {
           Size texSize=this->getContentSize();
           //mask shader
           {
               GLchar * fragSource = (GLchar*)FileUtils::getInstance()->getStringFromFile("mask.fsh").c_str();


               GLProgram* pProgram = new GLProgram();
               pProgram->reset();
               pProgram->initWithByteArrays(ccPositionTextureColor_vert, fragSource);
               //bind attribute
               pProgram->bindAttribLocation(GLProgram::ATTRIBUTE_NAME_POSITION, GLProgram::VERTEX_ATTRIB_POSITION);
               pProgram->bindAttribLocation(GLProgram::ATTRIBUTE_NAME_COLOR, GLProgram::VERTEX_ATTRIB_COLOR);
               pProgram->bindAttribLocation(GLProgram::ATTRIBUTE_NAME_TEX_COORD, GLProgram::VERTEX_ATTRIB_TEX_COORD);
               //link  (must after bindAttribute)
               pProgram->link();
               //get cocos2d-x build-in uniforms
               pProgram->updateUniforms();
               //get my own uniforms
               map<string,GLint> myUnifoMap;
               myUnifoMap["texSize"] = glGetUniformLocation(pProgram->getProgram(),"texSize");
               myUnifoMap["r"] = glGetUniformLocation(pProgram->getProgram(),"r");
               myUnifoMap["c"] = glGetUniformLocation(pProgram->getProgram(),"c");
               myUnifoMap["brightColor"] = glGetUniformLocation(pProgram->getProgram(),"brightColor");
               myUnifoMap["darkColor"] = glGetUniformLocation(pProgram->getProgram(),"darkColor");
               //make program
               program.myUnifoMap=myUnifoMap;
               program.setProgram(pProgram);
               //program can be released
               pProgram->release();
               //check gl error
               CHECK_GL_ERROR_DEBUG();
           }           
       }
    return true;
}

void CmaskedSceneSprite::draw(Renderer *renderer, const Mat4& transform, uint32_t flags) {

    //call father draw
    Sprite::draw(renderer,transform, flags);

    Size texSize = this->getContentSize();
    //----change shader

    this->setGLProgram(program.getProgram());
    //ccGLEnable(m_eGLServerState);
    //pass values for cocos2d-x build-in uniforms
    getGLProgram()->use();
    getGLProgram()->setUniformsForBuiltins();

    //pass values for my own uniforms
    float texSize_c[2]={texSize.width,texSize.height};
    glUniform2fv(program.myUnifoMap["texSize"],1,texSize_c);
    glUniform1f(program.myUnifoMap["r"], r);
    float c_c[2]={c.x,c.y};
    glUniform2fv(program.myUnifoMap["c"], 1, c_c);
    glUniform4fv(program.myUnifoMap["brightColor"], 1, brightColor);
    glUniform4fv(program.myUnifoMap["darkColor"], 1, darkColor);
}

这是我的自定义着色器程序mask.fsh

#ifdef GL_ES
precision mediump float;
#endif

varying vec2 v_texCoord;

uniform sampler2D CC_Texture01;

uniform vec2 texSize;
uniform float r;
uniform vec2 c;
uniform vec4 brightColor;
uniform vec4 darkColor;

void main() {
    vec2 texCoord=vec2(v_texCoord.s,1.0-v_texCoord.t);

    vec4 brightColor = max(brightColor,darkColor);
    vec4 darkColor = min(brightColor,darkColor);
    vec2 curPixelPos = vec2(texCoord.s*texSize.x,texCoord.t*texSize.y);//curPixel pos in world space
    float dis_curPixelToC = distance(curPixelPos,c);
    vec4 curPixelColor;
    if(dis_curPixelToC<r){
        //use the curve y=1/(r*r)*x*x-2/r*x+1
        //float temp=max(0.0,1.0-dis_curPixelToC/r);
        //float k=temp*temp;
        //curPixelColor=(brightColor-darkColor)*k+darkColor;

        //use the curve y=x
        curPixelColor=brightColor-(brightColor-darkColor)/r*dis_curPixelToC;
    }else{
        curPixelColor=darkColor;
    }
    gl_FragColor = texture2D(CC_Texture01, texCoord)*curPixelColor;
}

请帮我这个代码在iPhone上工作。仅在Android设备上它无法正常工作。

1 个答案:

答案 0 :(得分:0)

我解决了在cocos2dx中使用自定义着色器的问题。我将着色器程序移动到cocos2dx库中的内部着色器文件夹,以便它作为内部着色器工作。在我的着色器程序中一些非浮动变量,所以我将其转换为浮点数。它对我有用。