oryol
oryol copied to clipboard
oryol_shader:how to compile the generated shader into lib?
When I write a render lib based on oryol, shader is also included in the lib, and the generated shader is also included in the lib project. The other project can't use the generated shader because the generated shader header is not avaliable to the third app.
Yes, this is sort-of by design because of hard-to-debug include collision when the generated shader headers are named identically, so the generated sources are created "out of source" in the fips-build directory, and the header search path to this location is only valid for the project of that file.
You should be able to fix this in your lib project though with a new variant of the oryol_shader()
cmake macro (see here: https://github.com/floooh/oryol/blob/095e81a8a8e977b20f70db33b540ebd510a7fe72/fips-include.cmake#L195)
It would work like this:
- in your lib project's root dir, create a file
fips-include.cmake
- copy the original
oryol_shader
macro there, but rename it to something else - remove the
OUT_OF_SOURCE
parameter from the call tofips_generate()
- finally replace the calls to
oryol_shader()
in your own lib with your own macro - run
./fips clean
+./fips gen
etc...
This will now place the generated files "in source" into the same directory where the shaders.shd file is, and this should be visible to external libraries, you need to make sure that the generated file names don't collide with other headers in the include search path though. The downside is however, that a whole bunch of other generated files will also be dumped there (all the intermediate shader source code and SPIRV-Files), so you'd probably want to add those to your .gitignore file (fixing this would require changes to the shader code generator python scripts in the Oryol project itself).
If this isn't acceptable for your use case the other option would be to have some sort of wrapper C++ API to access the generated ShaderSetup objects from outside your lib (almost sounds like the better solution to me, since it would eliminate the header-collision problem).
Let me know how this works for you.
PS: In general I want to have the shader/uniformblock-related API in the Gfx module a bit more "dynamic" in the future to aid more dynamic material systems. This probably includes exposing some sort of reflection information from the shader generation pass into the C++ code, and a more flexible version of Gfx::ApplyUniformBlock().
...on second thought, maybe the "wrapper API" solution won't work, because the code which actually uses the shaders must indeed include the generated header files. Some sort of forward-declaration won't work.
So I guess you're limited to the "in source tree" code generation for now.
for the first solution, if I want to generate OpenGL shader on window, and metal shader on iOS, will lead to source code conflict?
Ahh, yes you're right the generated header/source pair will be different on each platform, I think it's best if they go into a local .gitignore too.
But I just found another problem: switching between different build configs will not rebuild the shaders because the files are not detected as "dirty" :/
Wait a sec I'm trying something else...
...ok here's a better solution, the idea is to export an additional header search directory from your shader library project.
- first undo all the stuff describes above with the custom cmake macro
- then in the CMakeLists.txt file of your shader library module, add a
target_include_directories()
statement with PUBLIC visibility, this will inject the right header search path into "upstream projects"
Here's an example that I just tried out, let's say I want to "export" the shader of Oryol's Dbg module, I modified the CMakeLists.txt file of the Dbg module (https://github.com/floooh/oryol/blob/master/code/Modules/Dbg/CMakeLists.txt, just add a line to the end):
fips_begin_module(Dbg)
fips_vs_warning_level(3)
fips_files(Dbg.cc Dbg.h)
fips_dir(private)
fips_files(debugFont.cc debugTextRenderer.cc debugTextRenderer.h)
oryol_shader(DebugShaders.glsl)
fips_deps(Core Gfx)
fips_end_module()
target_include_directories(Dbg PUBLIC "${FIPS_PROJECT_BUILD_DIR}/oryol_Dbg")
Note the target_include_directories()
args, each is important :)
The Dbg
is the name of the module (in your case the shader library module).
The PUBLIC
is necessary so that the header path isn't only visible to this module.
${FIPS_PROJECT_BUILD_DIR}/oryol_Dbg
: The FIPS_PROJECT_BUILD_DIR is resolved to the current build directory under fips-build/[proj_name]/[config_name]
. The oryol_Dbg
is the file filename convention for imported modules, the first name oryol
is the name of the imported project, and the Dbg
is the name of the imported module.
In project which use the shader library module as dependency, it should be enough to do a fips clean
+fips_gen
now, and you can check in the Visual Studio or Xcode properties window if the new header path is there (I just tried this in Xcode, and it seems to work).
Good luck, and let me know how it goes :)
The later solution works fine, thank you!
FYI I'll reopen the ticket as a FAQ, if others have the same problem :)