diff --git a/CMakeLists.txt b/CMakeLists.txt index 76c1df0ce79..b11a94b40d3 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -4573,7 +4573,7 @@ if(VINYLCONTROL) endif() # rendergraph -add_subdirectory(src/rendergraph/opengl) +add_subdirectory(src/rendergraph) target_link_libraries(mixxx-lib PUBLIC rendergraph_gl) target_compile_definitions(mixxx-lib PRIVATE rendergraph=rendergraph_gl) diff --git a/src/rendergraph/CMakeLists.txt b/src/rendergraph/CMakeLists.txt index 8f14cb2f313..76e94ff1674 100644 --- a/src/rendergraph/CMakeLists.txt +++ b/src/rendergraph/CMakeLists.txt @@ -39,5 +39,5 @@ set( ) add_subdirectory(opengl) -add_subdirectory(scenegraph) +# add_subdirectory(scenegraph) add_subdirectory(shaders) diff --git a/src/rendergraph/shaders/rendergraph/CMakeLists.txt b/src/rendergraph/shaders/rendergraph/CMakeLists.txt new file mode 100644 index 00000000000..42478758f46 --- /dev/null +++ b/src/rendergraph/shaders/rendergraph/CMakeLists.txt @@ -0,0 +1,53 @@ +# included from src/rendergraph/CMakeLists.txt + +set( + shaders + pattern.frag + pattern.vert + rgb.frag + rgb.vert + rgba.frag + rgba.vert + texture.frag + texture.vert + unicolor.frag + unicolor.vert +) + +qt6_add_shaders(rendergraph_sg "shaders-qsb" + BATCHABLE + PRECOMPILE + OPTIMIZED + PREFIX + /shaders/rendergraph + FILES + ${shaders} +) + +# USE_QSHADER_FOR_GL is set in src/rendergraph/CMakeLists.txt when Qt >= 6.6 +if(USE_QSHADER_FOR_GL) + # Add the .qsb shader bundles; rendergraph::MaterialShader will use + # QShader to extract the GLSL shader from the bundle. + message(STATUS "Adding qsb shaders to rendergraph_gl") + qt6_add_shaders(rendergraph_gl "shaders-qsb" + BATCHABLE + PRECOMPILE + OPTIMIZED + PREFIX + /shaders/rendergraph + FILES + ${shaders} + ) +else() + # Use GLSL shaders extracted from the .qsb shader bundles using + # generate_shaders_gl.pl + message(STATUS "Adding gl shaders to rendergraph_gl") + include(generated_shaders_gl.cmake) + + qt_add_resources(rendergraph_gl "shaders-gl" + PREFIX + /shaders/rendergraph + FILES + ${generated_shaders_gl} + ) +endif() diff --git a/src/rendergraph/shaders/rendergraph/README.md b/src/rendergraph/shaders/rendergraph/README.md new file mode 100644 index 00000000000..31f8a53fff1 --- /dev/null +++ b/src/rendergraph/shaders/rendergraph/README.md @@ -0,0 +1,29 @@ +# rendergraph shaders + +The CMakeLists.txt in this folder generates qsb shader bundles from spirv shaders, to +be used by `rendergraph::MaterialShader`. + +## For use with QML / Qt scene graph + +The qsb files can be used directly through `QSGShader`. This includes the scenegraph +implementation of rendergraph. + +## For use with OpenGL + +Depending on the Qt version, the opengl implementation of `rendergraph::MaterialShader` +uses either the .qsb shader bundles directly, or the extracted GLSL shaders: + +### Qt >= 6.6 + +The GLSL shaders are extracted programmatically with `QShader` and then used with +`QOpenGLShader`. + +### Qt < 6.6 + +The GLSL shader have to extracted from the qsb shader bundles to be used by `QOpenGLShader`. +This can be done using the script `generate_shaders_gl.pl`. To use this script, make sure +that the qsb and spirv commands are in your path. qsb is part of Qt. spirv is part of the +Vulkan SDK and can be downloaded from + +The script also generates the file ```generated_shaders_gl.cmake``` which sets a cmake +variable containing a list of all GLSL shaders, used by the CMakeLists.txt in this folder. diff --git a/src/rendergraph/shaders/rendergraph/generate_shaders_gl.pl b/src/rendergraph/shaders/rendergraph/generate_shaders_gl.pl new file mode 100755 index 00000000000..c528eb94747 --- /dev/null +++ b/src/rendergraph/shaders/rendergraph/generate_shaders_gl.pl @@ -0,0 +1,68 @@ +#!/usr/bin/perl + +my @files = (glob("*.vert"),glob("*.frag")); + +open(GENERATED,">generated_shaders_gl.cmake"); +print(GENERATED "set(generated_shaders_gl\n"); +for $file (@files) +{ + system("qsb","--glsl","120",$file,"-o","/tmp/$$-$file.qsb"); + open(INFILE,"qsb --dump /tmp/$$-$file.qsb|"); + open(OUTFILE,">$file.gl"); + $ok = 0; + $comment_added = 0; + print "Generating $file.gl from $file\n"; + while () + { + if ($in_shader_block == 2) + { + if (m/^\*\*/) + { + $in_shader_block = 0; + $ok = 1; + } + else + { + if (!$comment_added) + { + if (!m/^#/) + { + print(OUTFILE "//// GENERATED - EDITS WILL BE OVERWRITTEN\n"); + $comment_added = 1; + } + } + print OUTFILE "$_"; + } + } + elsif ($in_shader_block == 1) + { + chomp($_); + if ($_ eq "Contents:") + { + $in_shader_block = 2; + } + } + else + { + chomp($_); + if ($_ eq "Shader 1: GLSL 120 [Standard]") + { + $in_shader_block = 1; + } + } + } + close INFILE; + close OUTFILE; + if($ok) + { + print(GENERATED " $file.gl\n"); + } + else + { + print STDERR "Failed to generated $file.gl"; + unlink("$file.gl") + } + unlink("/tmp/$$-$file.qsb"); +} +print(GENERATED ")\n"); +close GENERATED; diff --git a/src/rendergraph/shaders/rendergraph/generated_shaders_gl.cmake b/src/rendergraph/shaders/rendergraph/generated_shaders_gl.cmake new file mode 100644 index 00000000000..f3f89002e51 --- /dev/null +++ b/src/rendergraph/shaders/rendergraph/generated_shaders_gl.cmake @@ -0,0 +1,13 @@ +set( + generated_shaders_gl + pattern.vert.gl + rgb.vert.gl + rgba.vert.gl + texture.vert.gl + unicolor.vert.gl + pattern.frag.gl + rgb.frag.gl + rgba.frag.gl + texture.frag.gl + unicolor.frag.gl +) diff --git a/src/rendergraph/shaders/rendergraph/pattern.frag b/src/rendergraph/shaders/rendergraph/pattern.frag new file mode 100644 index 00000000000..5aa3d1556b1 --- /dev/null +++ b/src/rendergraph/shaders/rendergraph/pattern.frag @@ -0,0 +1,9 @@ +#version 440 + +layout(binding = 1) uniform sampler2D texture1; +layout(location = 0) in vec2 vTexcoord; +layout(location = 0) out vec4 fragColor; + +void main() { + fragColor = texture(texture1, fract(vTexcoord)); +} diff --git a/src/rendergraph/shaders/rendergraph/pattern.frag.gl b/src/rendergraph/shaders/rendergraph/pattern.frag.gl new file mode 100644 index 00000000000..376c71668ba --- /dev/null +++ b/src/rendergraph/shaders/rendergraph/pattern.frag.gl @@ -0,0 +1,11 @@ +#version 120 +//// GENERATED - EDITS WILL BE OVERWRITTEN + +uniform sampler2D texture1; + +varying vec2 vTexcoord; + +void main() +{ + gl_FragData[0] = texture2D(texture1, fract(vTexcoord)); +} diff --git a/src/rendergraph/shaders/rendergraph/pattern.vert b/src/rendergraph/shaders/rendergraph/pattern.vert new file mode 100644 index 00000000000..07b3d7f1f3b --- /dev/null +++ b/src/rendergraph/shaders/rendergraph/pattern.vert @@ -0,0 +1,15 @@ +#version 440 + +layout(std140, binding = 0) uniform buf { + mat4 matrix; +} +ubuf; + +layout(location = 0) in vec4 position; +layout(location = 1) in vec2 texcoord; +layout(location = 0) out vec2 vTexcoord; + +void main() { + vTexcoord = texcoord; + gl_Position = ubuf.matrix * position; +} diff --git a/src/rendergraph/shaders/rendergraph/pattern.vert.gl b/src/rendergraph/shaders/rendergraph/pattern.vert.gl new file mode 100644 index 00000000000..a3d58014be3 --- /dev/null +++ b/src/rendergraph/shaders/rendergraph/pattern.vert.gl @@ -0,0 +1,19 @@ +#version 120 +//// GENERATED - EDITS WILL BE OVERWRITTEN + +struct buf +{ + mat4 matrix; +}; + +uniform buf ubuf; + +varying vec2 vTexcoord; +attribute vec2 texcoord; +attribute vec4 position; + +void main() +{ + vTexcoord = texcoord; + gl_Position = ubuf.matrix * position; +} diff --git a/src/rendergraph/shaders/rendergraph/rgb.frag b/src/rendergraph/shaders/rendergraph/rgb.frag new file mode 100644 index 00000000000..0a808489f5b --- /dev/null +++ b/src/rendergraph/shaders/rendergraph/rgb.frag @@ -0,0 +1,8 @@ +#version 440 + +layout(location = 0) in vec3 vColor; +layout(location = 0) out vec4 fragColor; + +void main() { + fragColor = vec4(vColor, 1.0); +} diff --git a/src/rendergraph/shaders/rendergraph/rgb.frag.gl b/src/rendergraph/shaders/rendergraph/rgb.frag.gl new file mode 100644 index 00000000000..b8a61f8682f --- /dev/null +++ b/src/rendergraph/shaders/rendergraph/rgb.frag.gl @@ -0,0 +1,9 @@ +#version 120 +//// GENERATED - EDITS WILL BE OVERWRITTEN + +varying vec3 vColor; + +void main() +{ + gl_FragData[0] = vec4(vColor, 1.0); +} diff --git a/src/rendergraph/shaders/rendergraph/rgb.vert b/src/rendergraph/shaders/rendergraph/rgb.vert new file mode 100644 index 00000000000..6568d01f187 --- /dev/null +++ b/src/rendergraph/shaders/rendergraph/rgb.vert @@ -0,0 +1,15 @@ +#version 440 + +layout(std140, binding = 0) uniform buf { + mat4 matrix; +} +ubuf; + +layout(location = 0) in vec4 position; +layout(location = 1) in vec3 color; +layout(location = 0) out vec3 vColor; + +void main() { + vColor = color; + gl_Position = ubuf.matrix * position; +} diff --git a/src/rendergraph/shaders/rendergraph/rgb.vert.gl b/src/rendergraph/shaders/rendergraph/rgb.vert.gl new file mode 100644 index 00000000000..53e86e4501c --- /dev/null +++ b/src/rendergraph/shaders/rendergraph/rgb.vert.gl @@ -0,0 +1,19 @@ +#version 120 +//// GENERATED - EDITS WILL BE OVERWRITTEN + +struct buf +{ + mat4 matrix; +}; + +uniform buf ubuf; + +varying vec3 vColor; +attribute vec3 color; +attribute vec4 position; + +void main() +{ + vColor = color; + gl_Position = ubuf.matrix * position; +} diff --git a/src/rendergraph/shaders/rendergraph/rgba.frag b/src/rendergraph/shaders/rendergraph/rgba.frag new file mode 100644 index 00000000000..5cf90a770ea --- /dev/null +++ b/src/rendergraph/shaders/rendergraph/rgba.frag @@ -0,0 +1,8 @@ +#version 440 + +layout(location = 0) in vec4 vColor; +layout(location = 0) out vec4 fragColor; + +void main() { + fragColor = vec4(vColor.xyz * vColor.w, vColor.w); // premultiple alpha +} diff --git a/src/rendergraph/shaders/rendergraph/rgba.frag.gl b/src/rendergraph/shaders/rendergraph/rgba.frag.gl new file mode 100644 index 00000000000..a831457b968 --- /dev/null +++ b/src/rendergraph/shaders/rendergraph/rgba.frag.gl @@ -0,0 +1,9 @@ +#version 120 +//// GENERATED - EDITS WILL BE OVERWRITTEN + +varying vec4 vColor; + +void main() +{ + gl_FragData[0] = vec4(vColor.xyz * vColor.w, vColor.w); +} diff --git a/src/rendergraph/shaders/rendergraph/rgba.vert b/src/rendergraph/shaders/rendergraph/rgba.vert new file mode 100644 index 00000000000..d5ce8b2d9db --- /dev/null +++ b/src/rendergraph/shaders/rendergraph/rgba.vert @@ -0,0 +1,15 @@ +#version 440 + +layout(std140, binding = 0) uniform buf { + mat4 matrix; +} +ubuf; + +layout(location = 0) in vec4 position; +layout(location = 1) in vec4 color; +layout(location = 0) out vec4 vColor; + +void main() { + vColor = color; + gl_Position = ubuf.matrix * position; +} diff --git a/src/rendergraph/shaders/rendergraph/rgba.vert.gl b/src/rendergraph/shaders/rendergraph/rgba.vert.gl new file mode 100644 index 00000000000..df2bcf93236 --- /dev/null +++ b/src/rendergraph/shaders/rendergraph/rgba.vert.gl @@ -0,0 +1,19 @@ +#version 120 +//// GENERATED - EDITS WILL BE OVERWRITTEN + +struct buf +{ + mat4 matrix; +}; + +uniform buf ubuf; + +varying vec4 vColor; +attribute vec4 color; +attribute vec4 position; + +void main() +{ + vColor = color; + gl_Position = ubuf.matrix * position; +} diff --git a/src/rendergraph/shaders/rendergraph/texture.frag b/src/rendergraph/shaders/rendergraph/texture.frag new file mode 100644 index 00000000000..bbe37bccd69 --- /dev/null +++ b/src/rendergraph/shaders/rendergraph/texture.frag @@ -0,0 +1,9 @@ +#version 440 + +layout(binding = 1) uniform sampler2D texture1; +layout(location = 0) in vec2 vTexcoord; +layout(location = 0) out vec4 fragColor; + +void main() { + fragColor = texture(texture1, vTexcoord); +} diff --git a/src/rendergraph/shaders/rendergraph/texture.frag.gl b/src/rendergraph/shaders/rendergraph/texture.frag.gl new file mode 100644 index 00000000000..b2d03f1352c --- /dev/null +++ b/src/rendergraph/shaders/rendergraph/texture.frag.gl @@ -0,0 +1,11 @@ +#version 120 +//// GENERATED - EDITS WILL BE OVERWRITTEN + +uniform sampler2D texture1; + +varying vec2 vTexcoord; + +void main() +{ + gl_FragData[0] = texture2D(texture1, vTexcoord); +} diff --git a/src/rendergraph/shaders/rendergraph/texture.vert b/src/rendergraph/shaders/rendergraph/texture.vert new file mode 100644 index 00000000000..07b3d7f1f3b --- /dev/null +++ b/src/rendergraph/shaders/rendergraph/texture.vert @@ -0,0 +1,15 @@ +#version 440 + +layout(std140, binding = 0) uniform buf { + mat4 matrix; +} +ubuf; + +layout(location = 0) in vec4 position; +layout(location = 1) in vec2 texcoord; +layout(location = 0) out vec2 vTexcoord; + +void main() { + vTexcoord = texcoord; + gl_Position = ubuf.matrix * position; +} diff --git a/src/rendergraph/shaders/rendergraph/texture.vert.gl b/src/rendergraph/shaders/rendergraph/texture.vert.gl new file mode 100644 index 00000000000..a3d58014be3 --- /dev/null +++ b/src/rendergraph/shaders/rendergraph/texture.vert.gl @@ -0,0 +1,19 @@ +#version 120 +//// GENERATED - EDITS WILL BE OVERWRITTEN + +struct buf +{ + mat4 matrix; +}; + +uniform buf ubuf; + +varying vec2 vTexcoord; +attribute vec2 texcoord; +attribute vec4 position; + +void main() +{ + vTexcoord = texcoord; + gl_Position = ubuf.matrix * position; +} diff --git a/src/rendergraph/shaders/rendergraph/unicolor.frag b/src/rendergraph/shaders/rendergraph/unicolor.frag new file mode 100644 index 00000000000..7099bb8f3dd --- /dev/null +++ b/src/rendergraph/shaders/rendergraph/unicolor.frag @@ -0,0 +1,13 @@ +#version 440 + +layout(std140, binding = 0) uniform buf { + mat4 matrix; + vec4 color; +} +ubuf; + +layout(location = 0) out vec4 fragColor; + +void main() { + fragColor = vec4(ubuf.color.xyz * ubuf.color.w, ubuf.color.w); // premultiply alpha +} diff --git a/src/rendergraph/shaders/rendergraph/unicolor.frag.gl b/src/rendergraph/shaders/rendergraph/unicolor.frag.gl new file mode 100644 index 00000000000..bfef503120b --- /dev/null +++ b/src/rendergraph/shaders/rendergraph/unicolor.frag.gl @@ -0,0 +1,15 @@ +#version 120 +//// GENERATED - EDITS WILL BE OVERWRITTEN + +struct buf +{ + mat4 matrix; + vec4 color; +}; + +uniform buf ubuf; + +void main() +{ + gl_FragData[0] = vec4(ubuf.color.xyz * ubuf.color.w, ubuf.color.w); +} diff --git a/src/rendergraph/shaders/rendergraph/unicolor.vert b/src/rendergraph/shaders/rendergraph/unicolor.vert new file mode 100644 index 00000000000..9e268c18fba --- /dev/null +++ b/src/rendergraph/shaders/rendergraph/unicolor.vert @@ -0,0 +1,13 @@ +#version 440 + +layout(std140, binding = 0) uniform buf { + mat4 matrix; + vec4 color; +} +ubuf; + +layout(location = 0) in vec4 position; + +void main() { + gl_Position = ubuf.matrix * position; +} diff --git a/src/rendergraph/shaders/rendergraph/unicolor.vert.gl b/src/rendergraph/shaders/rendergraph/unicolor.vert.gl new file mode 100644 index 00000000000..d126f3dab58 --- /dev/null +++ b/src/rendergraph/shaders/rendergraph/unicolor.vert.gl @@ -0,0 +1,17 @@ +#version 120 +//// GENERATED - EDITS WILL BE OVERWRITTEN + +struct buf +{ + mat4 matrix; + vec4 color; +}; + +uniform buf ubuf; + +attribute vec4 position; + +void main() +{ + gl_Position = ubuf.matrix * position; +}