From 91e50f31efe4d0f47ae2f20a904006af471e903e Mon Sep 17 00:00:00 2001
From: Joseph Walton-Rivers <joseph@walton-rivers.uk>
Date: Sun, 5 Jun 2022 17:06:47 +0100
Subject: [PATCH] add support for include extention

---
 CMakeLists.txt                  |  2 +-
 demo/data/include/phong.glsl    |  5 +++++
 demo/data/phong_frag.glsl       |  4 +++-
 fggl/gfx/ogl/shader.cpp         | 18 ++++++++++++++++++
 include/fggl/data/storage.hpp   | 15 +++++++++++++++
 include/fggl/gfx/ogl/shader.hpp |  4 ++++
 6 files changed, 46 insertions(+), 2 deletions(-)
 create mode 100644 demo/data/include/phong.glsl

diff --git a/CMakeLists.txt b/CMakeLists.txt
index 181ae3f..c806330 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -37,7 +37,7 @@ if (CMAKE_PROJECT_NAME STREQUAL PROJECT_NAME)
                 glfw:shared=True
                 glad:gl_profile=core
                 glad:gl_version=4.5
-                glad:extensions="GL_ARB_get_program_binary"
+                glad:extensions="GL_ARB_get_program_binary,GL_ARB_shading_language_include"
         )
 
         if ( CMAKE_CONFIGURATION_TYPES )
diff --git a/demo/data/include/phong.glsl b/demo/data/include/phong.glsl
new file mode 100644
index 0000000..1cf3dfb
--- /dev/null
+++ b/demo/data/include/phong.glsl
@@ -0,0 +1,5 @@
+/**
+ * OpenGL phong lighting model.
+ */
+
+// TODO write script
\ No newline at end of file
diff --git a/demo/data/phong_frag.glsl b/demo/data/phong_frag.glsl
index 5215769..aea3b86 100644
--- a/demo/data/phong_frag.glsl
+++ b/demo/data/phong_frag.glsl
@@ -1,4 +1,6 @@
 #version 330 core
+#extension GL_ARB_shading_language_include : require
+
 // based on http://www.opengl-tutorial.org, WTFPL
 // features lighting additions from https://learnopengl.com/, CC BY-NC 4.0
 
@@ -24,7 +26,7 @@ out vec4 FragColor;
 
 void main()
 {
-    vec3 lightColour = vec3( 1.0, 1.0, 1.0 );
+    vec3 lightColour = vec3(1, 1, 1);
     float lightPower = 200.0;
 
     vec3 n = normalize( normal_cs );
diff --git a/fggl/gfx/ogl/shader.cpp b/fggl/gfx/ogl/shader.cpp
index e512f56..6479b0e 100644
--- a/fggl/gfx/ogl/shader.cpp
+++ b/fggl/gfx/ogl/shader.cpp
@@ -47,6 +47,24 @@ ShaderCache::ShaderCache(std::shared_ptr<fggl::data::Storage> storage) : m_stora
 		m_binary = false;
 	}
 
+	if ( GLAD_GL_ARB_shading_language_include ) {
+		setupIncludes();
+	}
+}
+
+void ShaderCache::setupIncludes() {
+	auto root = m_storage->resolvePath( data::StorageType::Data, "include" );
+	auto paths = m_storage->findResources( root, ".glsl");
+
+	for ( auto& path : paths ){
+		std::string source;
+		m_storage->load( fggl::data::Data, path, &source );
+
+		auto relPath = std::filesystem::relative(path, root);
+		const auto relPathStr = "/" + std::string(relPath);
+		glNamedStringARB(GL_SHADER_INCLUDE_ARB, -1, relPathStr.c_str(), -1, source.c_str() );
+	}
+
 }
 
 bool ShaderCache::loadFromDisk(GLuint pid, const ShaderConfig& config) {
diff --git a/include/fggl/data/storage.hpp b/include/fggl/data/storage.hpp
index 872c753..c041504 100644
--- a/include/fggl/data/storage.hpp
+++ b/include/fggl/data/storage.hpp
@@ -4,6 +4,7 @@
 #include <iostream>
 #include <string>
 #include <filesystem>
+#include <vector>
 
 namespace fggl::data {
 
@@ -28,6 +29,20 @@ namespace fggl::data {
 				return fggl_deserialize<T>(path, out);
 			}
 
+			std::vector<std::filesystem::path> findResources(std::filesystem::path root, const std::string ext) {
+				if ( !std::filesystem::exists(root) ) {
+					return {};
+				}
+
+				std::vector<std::filesystem::path> paths;
+				for ( const auto& entry : std::filesystem::recursive_directory_iterator(root) ) {
+					if ( entry.is_regular_file() && entry.path().extension() == ext ) {
+						paths.push_back( entry );
+					}
+				}
+				return paths;
+			}
+
 			template<typename T>
 			void save(StorageType pool, const std::string &name, const T *out) {
 				auto path = resolvePath(pool, name);
diff --git a/include/fggl/gfx/ogl/shader.hpp b/include/fggl/gfx/ogl/shader.hpp
index 1081f34..582112a 100644
--- a/include/fggl/gfx/ogl/shader.hpp
+++ b/include/fggl/gfx/ogl/shader.hpp
@@ -46,10 +46,14 @@ namespace fggl::gfx {
 
 			GLuint get(const std::string &name);
 
+
 		private:
 			std::shared_ptr<fggl::data::Storage> m_storage;
 			std::unordered_map<std::string, GLuint> m_shaders;
 
+			// extensions
+			void setupIncludes();
+
 			// opengl operations
 			bool compileShader(const std::string &, GLuint);
 
-- 
GitLab