Shaders in Cocos2dx 2.2.3 don't work

Hey,
I was trying to apply a simple shader to one of the buttons in the game, I did a lot of research but it doesnt seem to work.
Here is my code:

    auto* shader = new CCGLProgram;
    shader->initWithVertexShaderFilename("wave.vsh", "wave.fsh");
    shader->link();
    shader->updateUniforms();
    button->setShaderProgram(shader);

I put wave.vsh and wave.fsh in the Resources folder but the game crashes when finding the shader. Is that the correct way how to apply a shader to a Node in cocos2dx v2.2.3?

wave.vsh

attribute vec4 a_position;
attribute vec2 a_texCoord;
attribute vec4 a_color;
#ifdef GL_ES
varying lowp vec4 v_fragmentColor;
varying mediump vec2 v_texCoord;
#else
varying vec4 v_fragmentColor;
varying vec2 v_texCoord;
#endif
void main()
{
  gl_Position = CC_MVPMatrix * a_position;
  v_fragmentColor = a_color;
  v_texCoord = a_texCoord;
}

wave.fsh

#ifdef GL_ES
precision mediump float;
#endif

varying vec4 v_fragmentColor;
varying vec2 v_texCoord;  
 
uniform sampler2D u_texture;  
uniform float time;  
uniform vec2 resolution;  
const float PI = 3.1415926535897932;  

const float speed = 0.2;  
const float speed_x = 0.3;  
const float speed_y = 0.3;  
 
const float intensity = 3.0;  
const int steps = 8;  
const float frequency = 4.0;  
const int angle = 7; 
 
const float delta = 20.0;  
const float intence = 200.0;  
const float emboss = 0.3;  
 
float col(vec2 coord)  
{  
    float delta_theta = 2.0 * PI / float(angle);  
    float col = 0.0;  
    float theta = 0.0;  
    for (int i = 0; i < steps; i++)  
    {
        vec2 adjc = coord;
    theta = delta_theta * float(i);
    adjc.x += cos(theta)*time*speed + time * speed_x;  
        adjc.y -= sin(theta)*time*speed - time * speed_y;  
        col = col + cos((adjc.x*cos(theta) - adjc.y*sin(theta))  
            *frequency)*intensity;  
    }
    return cos(col);
}  

void main(void)  
{  
    vec2 p = (v_texCoord.xy) / resolution.xy, c1 = p, c2 = p;  
    float cc1 = col(c1);  
 
    c2.x += resolution.x/delta;  
    float dx = emboss*(cc1-col(c2))/delta;  
 
    c2.x = p.x;  
    c2.y += resolution.y/delta;  
    float dy = emboss*(cc1-col(c2))/delta;  
 
    c1.x += dx;  
    c1.y += dy;  
    float alpha = 1.+dot(dx,dy)*intence;  
    gl_FragColor = texture2D(u_texture,c1)*(alpha) *v_fragmentColor*(alpha);  
}

Is it crashing when finding the shader files, or when trying to use them, because they are two unrelated issues.

If you’re sure the files are being found and loaded correctly, then it’ll be a problem with the shader code. The best way to check is to use a simple shader (copy one from the built-in cocos2d-x shaders), load that and apply it to a node. If it works, then you know it’s an issue in the shader code that you posted above.

Thanks for the reply, i changed the code a little bit and it now works, but do you know how i can change the values from the vsh/fsh files in runtime?

    auto newSprite = CCSprite::create("color.png");
    auto* shader = new CCGLProgram();
    shader->initWithVertexShaderFilename("shader\\gray.vsh", "shader\\gray.fsh");
    shader->addAttribute(kCCAttributeNamePosition, kCCVertexAttrib_Position);
    shader->addAttribute(kCCAttributeNameColor, kCCVertexAttrib_Color);
    shader->addAttribute(kCCAttributeNameTexCoord, kCCVertexAttrib_TexCoords);

    addChild(newSprite, 1);


    shader->link();
    shader->updateUniforms();
    shader->use();
    //label->getShaderProgram()->reset();
    newSprite->getShaderProgram()->setUniformsForBuiltins();
    newSprite->setShaderProgram(shader);

gray.vsh

// Vertex
attribute vec4 a_position;
attribute vec2 a_texCoord;
attribute vec4 a_color;

varying vec4 v_fragmentColor;
varying vec2 v_texCoord;

uniform mat4 u_MVPMatrix;

void main() {
    gl_Position = u_MVPMatrix * a_position;
    v_texCoord = a_texCoord;
    v_fragmentColor = a_color;
}

gray.fsh

// Fragment
varying vec2 v_texCoord;

uniform vec3 u_random;
uniform sampler2D u_texture;

vec2 SineWave(vec2 p) 
{
    float x;
    x = 0.03 * sin( 25.0 * p.y + u_random.x * 5.0 );
    return vec2(p.x+x, p.y);
}

void main() {
    gl_FragColor = texture2D(u_texture, SineWave(v_texCoord));
}

Does the sample project not show how to do this? It should be located in cocos2d-x/samples/Cpp/TestCpp/Classes/ShaderTest/ShaderTest.cpp.

Other than that, I don’t actually know how it’s handled in v2 of the engine, since I’ve never used it myself. You really should consider moving to v3.17.2 or v4 of Cocos2d-x.

1 Like

Hi, @XcreatorGoal , Have u solved the problem of The Windows SDK version 8.1 was not found issue. I got this bug too, please let me know how do u cope it. Thanks so much.