From 672a6b11fc17838eb8a195c3c09f8bb85884ec1e Mon Sep 17 00:00:00 2001 From: m0dB <m0dB@mixxx.org> Date: Mon, 9 Dec 2024 17:00:52 +0100 Subject: [PATCH] rendergraph opengl with shaders --- CMakeLists.txt | 2 +- res/shaders/rendergraph/CMakeLists.txt | 53 +++++++++++++++ res/shaders/rendergraph/README.md | 29 ++++++++ .../rendergraph/generate_shaders_gl.pl | 68 +++++++++++++++++++ .../rendergraph/generated_shaders_gl.cmake | 13 ++++ res/shaders/rendergraph/pattern.frag | 9 +++ res/shaders/rendergraph/pattern.frag.gl | 11 +++ res/shaders/rendergraph/pattern.vert | 15 ++++ res/shaders/rendergraph/pattern.vert.gl | 19 ++++++ res/shaders/rendergraph/rgb.frag | 8 +++ res/shaders/rendergraph/rgb.frag.gl | 9 +++ res/shaders/rendergraph/rgb.vert | 15 ++++ res/shaders/rendergraph/rgb.vert.gl | 19 ++++++ res/shaders/rendergraph/rgba.frag | 8 +++ res/shaders/rendergraph/rgba.frag.gl | 9 +++ res/shaders/rendergraph/rgba.vert | 15 ++++ res/shaders/rendergraph/rgba.vert.gl | 19 ++++++ res/shaders/rendergraph/texture.frag | 9 +++ res/shaders/rendergraph/texture.frag.gl | 11 +++ res/shaders/rendergraph/texture.vert | 15 ++++ res/shaders/rendergraph/texture.vert.gl | 19 ++++++ res/shaders/rendergraph/unicolor.frag | 13 ++++ res/shaders/rendergraph/unicolor.frag.gl | 15 ++++ res/shaders/rendergraph/unicolor.vert | 13 ++++ res/shaders/rendergraph/unicolor.vert.gl | 17 +++++ src/rendergraph/CMakeLists.txt | 2 +- 26 files changed, 433 insertions(+), 2 deletions(-) create mode 100644 res/shaders/rendergraph/CMakeLists.txt create mode 100644 res/shaders/rendergraph/README.md create mode 100755 res/shaders/rendergraph/generate_shaders_gl.pl create mode 100644 res/shaders/rendergraph/generated_shaders_gl.cmake create mode 100644 res/shaders/rendergraph/pattern.frag create mode 100644 res/shaders/rendergraph/pattern.frag.gl create mode 100644 res/shaders/rendergraph/pattern.vert create mode 100644 res/shaders/rendergraph/pattern.vert.gl create mode 100644 res/shaders/rendergraph/rgb.frag create mode 100644 res/shaders/rendergraph/rgb.frag.gl create mode 100644 res/shaders/rendergraph/rgb.vert create mode 100644 res/shaders/rendergraph/rgb.vert.gl create mode 100644 res/shaders/rendergraph/rgba.frag create mode 100644 res/shaders/rendergraph/rgba.frag.gl create mode 100644 res/shaders/rendergraph/rgba.vert create mode 100644 res/shaders/rendergraph/rgba.vert.gl create mode 100644 res/shaders/rendergraph/texture.frag create mode 100644 res/shaders/rendergraph/texture.frag.gl create mode 100644 res/shaders/rendergraph/texture.vert create mode 100644 res/shaders/rendergraph/texture.vert.gl create mode 100644 res/shaders/rendergraph/unicolor.frag create mode 100644 res/shaders/rendergraph/unicolor.frag.gl create mode 100644 res/shaders/rendergraph/unicolor.vert create mode 100644 res/shaders/rendergraph/unicolor.vert.gl diff --git a/CMakeLists.txt b/CMakeLists.txt index f43b5d0dd45d..79de5df5ed00 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -4574,7 +4574,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/res/shaders/rendergraph/CMakeLists.txt b/res/shaders/rendergraph/CMakeLists.txt new file mode 100644 index 000000000000..42478758f46e --- /dev/null +++ b/res/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/res/shaders/rendergraph/README.md b/res/shaders/rendergraph/README.md new file mode 100644 index 000000000000..31f8a53fff1c --- /dev/null +++ b/res/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 <https://vulkan.org> + +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/res/shaders/rendergraph/generate_shaders_gl.pl b/res/shaders/rendergraph/generate_shaders_gl.pl new file mode 100755 index 000000000000..c528eb947475 --- /dev/null +++ b/res/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 (<INFILE>) + { + 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/res/shaders/rendergraph/generated_shaders_gl.cmake b/res/shaders/rendergraph/generated_shaders_gl.cmake new file mode 100644 index 000000000000..f3f89002e51c --- /dev/null +++ b/res/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/res/shaders/rendergraph/pattern.frag b/res/shaders/rendergraph/pattern.frag new file mode 100644 index 000000000000..5aa3d1556b1e --- /dev/null +++ b/res/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/res/shaders/rendergraph/pattern.frag.gl b/res/shaders/rendergraph/pattern.frag.gl new file mode 100644 index 000000000000..376c71668ba4 --- /dev/null +++ b/res/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/res/shaders/rendergraph/pattern.vert b/res/shaders/rendergraph/pattern.vert new file mode 100644 index 000000000000..07b3d7f1f3ba --- /dev/null +++ b/res/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/res/shaders/rendergraph/pattern.vert.gl b/res/shaders/rendergraph/pattern.vert.gl new file mode 100644 index 000000000000..a3d58014be32 --- /dev/null +++ b/res/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/res/shaders/rendergraph/rgb.frag b/res/shaders/rendergraph/rgb.frag new file mode 100644 index 000000000000..0a808489f5b2 --- /dev/null +++ b/res/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/res/shaders/rendergraph/rgb.frag.gl b/res/shaders/rendergraph/rgb.frag.gl new file mode 100644 index 000000000000..b8a61f8682f9 --- /dev/null +++ b/res/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/res/shaders/rendergraph/rgb.vert b/res/shaders/rendergraph/rgb.vert new file mode 100644 index 000000000000..6568d01f187c --- /dev/null +++ b/res/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/res/shaders/rendergraph/rgb.vert.gl b/res/shaders/rendergraph/rgb.vert.gl new file mode 100644 index 000000000000..53e86e4501cc --- /dev/null +++ b/res/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/res/shaders/rendergraph/rgba.frag b/res/shaders/rendergraph/rgba.frag new file mode 100644 index 000000000000..5cf90a770eae --- /dev/null +++ b/res/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/res/shaders/rendergraph/rgba.frag.gl b/res/shaders/rendergraph/rgba.frag.gl new file mode 100644 index 000000000000..a831457b9681 --- /dev/null +++ b/res/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/res/shaders/rendergraph/rgba.vert b/res/shaders/rendergraph/rgba.vert new file mode 100644 index 000000000000..d5ce8b2d9db6 --- /dev/null +++ b/res/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/res/shaders/rendergraph/rgba.vert.gl b/res/shaders/rendergraph/rgba.vert.gl new file mode 100644 index 000000000000..df2bcf93236e --- /dev/null +++ b/res/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/res/shaders/rendergraph/texture.frag b/res/shaders/rendergraph/texture.frag new file mode 100644 index 000000000000..bbe37bccd69c --- /dev/null +++ b/res/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/res/shaders/rendergraph/texture.frag.gl b/res/shaders/rendergraph/texture.frag.gl new file mode 100644 index 000000000000..b2d03f1352c6 --- /dev/null +++ b/res/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/res/shaders/rendergraph/texture.vert b/res/shaders/rendergraph/texture.vert new file mode 100644 index 000000000000..07b3d7f1f3ba --- /dev/null +++ b/res/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/res/shaders/rendergraph/texture.vert.gl b/res/shaders/rendergraph/texture.vert.gl new file mode 100644 index 000000000000..a3d58014be32 --- /dev/null +++ b/res/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/res/shaders/rendergraph/unicolor.frag b/res/shaders/rendergraph/unicolor.frag new file mode 100644 index 000000000000..7099bb8f3dd5 --- /dev/null +++ b/res/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/res/shaders/rendergraph/unicolor.frag.gl b/res/shaders/rendergraph/unicolor.frag.gl new file mode 100644 index 000000000000..bfef503120bd --- /dev/null +++ b/res/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/res/shaders/rendergraph/unicolor.vert b/res/shaders/rendergraph/unicolor.vert new file mode 100644 index 000000000000..9e268c18fbaa --- /dev/null +++ b/res/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/res/shaders/rendergraph/unicolor.vert.gl b/res/shaders/rendergraph/unicolor.vert.gl new file mode 100644 index 000000000000..d126f3dab584 --- /dev/null +++ b/res/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; +} diff --git a/src/rendergraph/CMakeLists.txt b/src/rendergraph/CMakeLists.txt index 731c47b5122a..6693043d76af 100644 --- a/src/rendergraph/CMakeLists.txt +++ b/src/rendergraph/CMakeLists.txt @@ -6,5 +6,5 @@ if(QT_VERSION_MINOR GREATER_EQUAL 6) endif() add_subdirectory(opengl) -add_subdirectory(scenegraph) +# add_subdirectory(scenegraph) add_subdirectory(../../res/shaders/rendergraph shaders)