Hi,
I’m trying to port my old GL shader program to V.4. The doc says:
Create a backend::ProgramState object with ProgramState(const std::string& vertexShader, const std::string& fragmentShader)
Well, I’m stuck here. I don’t seem to have this constructor. I tried to have a look around cocos to spy how it’s done, but I’ve had no luck in finding examples of loading shaders from files.
What do I do? I must be missing something obvious!
Edit: Should I subclass Program?
Also:
Metal uses MSL as the shader development language. To support the OpenGL ES shader running on the Metal framework, V4 uses glsl-optimizer to convert the OpenGL ES shader to a Metal MSL shader.
Does this mean that my GL shaders will automatically be adapted to Metal without me having to rewrite them?
Thanks a lot!
I’ll check it out. Although I tried with cocos2d::backend::Device previously, getting a strange error “No member named ‘Device’ in namespace ‘cocos2d::backend’”, even though everything seems to be in place (backend.h includes Device.h so I should have it). Compiling for iOS/Xcode11.5.
I’ll get back to you when I get it right.
Super! Now my shaders load, hooray!
Except they fail to convert to Metal ( Can not get metal shader:).
I’ll mark your answer as a solution as soon as I’m sure I don’t want to ask any more questions :).
@kalika06
Hi, i’m just facing the same issue right now. @Darren is talking about a trick to get more verbose log.
Add NSLog(@"%s", glslopt_get_log(glslShader)); at line 52 at cocos/renderer/backend/metal/ShaderModuleMTL.mm then build again.
It is showing optimisation logs that may help debug.
In my case to illustrate, it is showing glsl errors like :
(1,1): error: syntax error, unexpected $end
Thank you guys, you’ve both been more than very helpful
Thanks to you both, I’ve managed to port the shaders for my Sprite. Here’s the code and some additional hints, in case someone finds them helpful:
std::string vertexSource = cocos2d::FileUtils::getInstance()->getStringFromFile(cocos2d::FileUtils::getInstance()->fullPathForFilename(“file/path/shader.vsh"));
std::string fragSource = cocos2d::FileUtils::getInstance()->getStringFromFile(cocos2d::FileUtils::getInstance()->fullPathForFilename(“file/path/shader.fsh”));
auto program = cocos2d::backend::Device::getInstance()->newProgram(vertexSource, fragSource);
auto programState = new cocos2d::backend::ProgramState(program);
setProgramState(programState);
SET_UNIFORM(_programState, "u_PMatrix", cocos2d::Director::getInstance()->getMatrix(cocos2d::MATRIX_STACK_TYPE::MATRIX_STACK_PROJECTION));
// (…)
// set some custom uniforms here…
auto res = getTexture()->getContentSizeInPixels();
SET_UNIFORM(_programState, "u_resolution", res);
CC_SAFE_RELEASE(programState);
CC_SAFE_RELEASE(program);
The shader files are located in the Resources folder.
Also:
CC_Texture0 became u_texture (declared as uniform sampler2D u_texture; in the fragment shader)
CC_PMatrix became u_PMatrix (declared as uniform mat4 u_PMatrix; in the vertex shader)
And other stuff, in case anyone needs it, has changed naming in a similar way.