diff --git a/README.md b/README.md index 66f8ed4..32d1ef7 100644 --- a/README.md +++ b/README.md @@ -25,6 +25,8 @@ The Bad: - Teminal display - libconfig - Config file manager +- shaderc + - Runtime shader compilation #### Must have at least one: - portaudio(optional) @@ -39,6 +41,7 @@ AUR package - https://aur.archlinux.org/packages/recidia-audio-visualizer/ #### Requirements: - meson - ninja +- vulkan-headers #### To build: ``` @@ -52,6 +55,7 @@ And if you wish to install: ninja -C build install mkdir ~/.config/recidia/ cp settings.cfg ~/.config/recidia/ +cp -r shaders ~/.config/recidia/ ``` ## Usage diff --git a/meson.build b/meson.build index fb0e9c7..9143392 100644 --- a/meson.build +++ b/meson.build @@ -6,6 +6,7 @@ fftw = dependency('fftw3') threads = dependency('threads') curses = dependency('ncursesw') libconfig = dependency('libconfig++') +shaderc = dependency('shaderc') audio_check = false @@ -31,4 +32,4 @@ qt5 = dependency('qt5', modules: ['Core', 'Gui', 'Widgets']) executable(meson.project_name(), ['src/main.cpp', 'src/audio.c', 'src/processing.cpp', 'src/curses.cpp', 'src/config.cpp', 'src/window.cpp', 'src/vulkan.cpp'], include_directories : ['inc'], -dependencies: [gsl, fftw, threads, curses, libconfig, pulse_simple, portaudio, qt5], install: true) +dependencies: [gsl, fftw, threads, curses, libconfig, pulse_simple, portaudio, qt5, shaderc], install: true) diff --git a/vulkan/shader.frag b/shaders/default.frag similarity index 100% rename from vulkan/shader.frag rename to shaders/default.frag diff --git a/vulkan/shader.vert b/shaders/default.vert similarity index 100% rename from vulkan/shader.vert rename to shaders/default.vert diff --git a/src/vulkan.cpp b/src/vulkan.cpp index dbf8ef2..0f00b9c 100644 --- a/src/vulkan.cpp +++ b/src/vulkan.cpp @@ -3,6 +3,7 @@ #include #include +#include #include @@ -82,30 +83,42 @@ VulkanRenderer::VulkanRenderer(VulkanWindow *window) { vulkan_window = window; } -VkShaderModule createShader(const string name) { +VkShaderModule createShader(const string name, shaderc_shader_kind shader_kind) { + string homeDir = getenv("HOME"); + vector shaderFileLocations = {"shaders/", + "../shaders/", + homeDir + "/.config/recidia/shaders/", + "/etc/recidia/shaders/"}; // Read shader file - ifstream file(name, ios::ate | ios::binary); + ifstream file; + for (uint i=0; i < shaderFileLocations.size(); i++) { + file.open(shaderFileLocations[i] + name); + if (file.is_open()) { + break; + } + } if (!file.is_open()) { - throw std::runtime_error("failed to open file!"); + throw std::runtime_error("Failed to find shader file!"); } - size_t fileSize = (size_t) file.tellg(); - std::vector buffer(fileSize); - file.seekg(0); - file.read(buffer.data(), fileSize); + std::string shaderText( (std::istreambuf_iterator(file) ), + (std::istreambuf_iterator() ) ); file.close(); - auto shaderCode = buffer; + shaderc::Compiler compiler; + shaderc::SpvCompilationResult result = compiler.CompileGlslToSpv(shaderText, shader_kind, ""); + vector spvCode; + spvCode.assign(result.cbegin(), result.cend()); VkShaderModuleCreateInfo shaderInfo; shaderInfo.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO; - shaderInfo.codeSize = shaderCode.size(); - shaderInfo.pCode = reinterpret_cast(shaderCode.data()); + shaderInfo.codeSize = sizeof(uint32_t) * spvCode.size(); + shaderInfo.pCode = (const uint32_t*) spvCode.data(); shaderInfo.pNext = nullptr; // WILL SEGV WITHOUT VkShaderModule shaderModule; VkResult err = dev_funct->vkCreateShaderModule(vulkan_dev, &shaderInfo, nullptr, &shaderModule); if (err != VK_SUCCESS) { - qWarning("Failed to create shader module: %d", err); + printf("Failed to create shader module: %d\n", err); return VK_NULL_HANDLE; } @@ -167,8 +180,8 @@ void VulkanRenderer::initResources() { pipelineInfo.pVertexInputState = &vertexInputInfo; // Shaders - VkShaderModule vertShaderModule = createShader("../vulkan/vert.spv"); - VkShaderModule fragShaderModule = createShader("../vulkan/frag.spv"); + VkShaderModule vertShaderModule = createShader("default.vert", shaderc_shader_kind::shaderc_glsl_vertex_shader); + VkShaderModule fragShaderModule = createShader("default.frag", shaderc_shader_kind::shaderc_glsl_fragment_shader); VkPipelineShaderStageCreateInfo vertShaderStageInfo{}; vertShaderStageInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO; diff --git a/vulkan/frag.spv b/vulkan/frag.spv deleted file mode 100644 index 52738f7..0000000 Binary files a/vulkan/frag.spv and /dev/null differ diff --git a/vulkan/vert.spv b/vulkan/vert.spv deleted file mode 100644 index d9bf826..0000000 Binary files a/vulkan/vert.spv and /dev/null differ