V4 - Shaders, ProgramState, and Program

I’ve just come back to my project after a break and decided to take the opportunity to update to v4. I’m targeting iOS/MACOS/Windows/Android

How do I now perform the following… I couldn’t see anything in the v4 migration that explains the change. None of this functionality seems to be available anymore.

    auto p1 = Program::createWithFilenames("terrain/standard.vsh", "terrain/dayNight.fsh");
    glProgramState = ProgramState::getOrCreateWithGLProgram( p1 );
    glProgramState->setUniformVec4("p_left", Vec4(0,0,(165.0f/255.0f),alpha_normal));      // outline
    glProgramState->setUniformVec4("p_right", Vec4(1,1,1,alpha_normal));               // body
    glProgramState->setUniformFloat("p_alpha", alpha_normal);               // alpha

The cpp-tests project has all the code examples you would need. Open up the ShaderTest.cpp file in the test project and you’ll see exactly how it works.

This post may be of help too: https://discuss.cocos2d-x.org/t/cocos2d-x-v4-0-released/48487/86

Many thanks!

I wrote a small utility to make shaders easier to use in v4 SimpleShader

1 Like

Many thanks for that, it was super helpful. However I can’t get my shaders to work.

Here is the fsh I was using previously. But now it seems like there are no uniforms. And I just see ’ Can not get metal shader: #define METAL

#ifdef GL_ES
precision mediump float;
#endif

varying vec2 v_texCoord;

vec4 m = vec4( 0.0, 0.0, 0.0, 0.0 ) ;
uniform vec4 p_left;
uniform vec4 p_right  ;
uniform float p_alpha  ;

void main()
{
    vec4 c = texture2D(CC_Texture0, v_texCoord).rgba;
    vec4 n;
    
    //if ( c.a > 0.0 ) {
    
        if ( c.g == 0.0  )
            n = vec4(p_left.r, p_left.g, p_left.b, c.a) ;
        else if ( c.g == 1.0 )
            n = vec4(p_right.r, p_right.g, p_right.b, c.a) ;
        else {
            m.r = 1.0 - c.r ;
            m.g = 1.0 - c.g ;
            m.b = 1.0 - c.b ;
            m.a = c.a;
            
            n = vec4((p_right.r*c.r)+(p_left.r*m.r), (p_right.g*c.g)+(p_left.g*m.g), (p_right.b*c.b)+(p_left.b*m.b), m.a) ;
        }
    //}else{
   //     n = c; //vec4(1,1,1,0.5) ;
   //}
    
    n.a = n.a * p_alpha;
   
    gl_FragColor = n ;
    
}

try it like this

vec4 m = vec4( 0.0, 0.0, 0.0, 0.0 ) ;
uniform vec4 p_left;
uniform vec4 p_right  ;
uniform float p_alpha  ;

void main()
{
    vec4 c = texture2D(u_texture, cc_FragTexCoord1).rgba;
    vec4 n;
    
    //if ( c.a > 0.0 ) {
    
        if ( c.g == 0.0  )
            n = vec4(p_left.r, p_left.g, p_left.b, c.a) ;
        else if ( c.g == 1.0 )
            n = vec4(p_right.r, p_right.g, p_right.b, c.a) ;
        else {
            m.r = 1.0 - c.r ;
            m.g = 1.0 - c.g ;
            m.b = 1.0 - c.b ;
            m.a = c.a;
            
            n = vec4((p_right.r*c.r)+(p_left.r*m.r), (p_right.g*c.g)+(p_left.g*m.g), (p_right.b*c.b)+(p_left.b*m.b), m.a) ;
        }
    //}else{
   //     n = c; //vec4(1,1,1,0.5) ;
   //}
    
    n.a = n.a * p_alpha;
   
    gl_FragColor = n ;
    
}
1 Like

Hi @IcemarkUK,
i think having a global variable like m (not uniform, not attribute) is not allowed for Metal.
Maybe you can try declaring vec4 m inside your main function?

1 Like

This topic was automatically closed 24 hours after the last reply. New replies are no longer allowed.