Shader structure done.
This commit is contained in:
		| @@ -1,9 +1,18 @@ | |||||||
| uniform float4x4 u_Projection; | struct Transforms { | ||||||
| uniform float4x4 u_View; |   float4x4 projection; | ||||||
| uniform float4x4 u_Model; |   float4x4 view; | ||||||
| uniform float4 u_Color; |   float4x4 model; | ||||||
| uniform bool u_HasTexture; | } | ||||||
| uniform Sampler2D u_Texture; |  | ||||||
|  | struct Colors { | ||||||
|  |   bool hasTexture; | ||||||
|  |   float4 colors[4]; | ||||||
|  |   int somethingElse; | ||||||
|  |   Sampler2D texture; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | uniform Transforms transforms; | ||||||
|  | uniform Colors colors; | ||||||
|  |  | ||||||
| struct AssembledVertex { | struct AssembledVertex { | ||||||
|   float3 position : POSITION; |   float3 position : POSITION; | ||||||
| @@ -19,10 +28,6 @@ struct VertexStageOutput { | |||||||
|   float4 sv_position : SV_Position; |   float4 sv_position : SV_Position; | ||||||
| }; | }; | ||||||
|  |  | ||||||
| float4 someFunction(float4 color) { |  | ||||||
|   return color * float4(0.5, 0.5, 0.5, 1.0); |  | ||||||
| } |  | ||||||
|  |  | ||||||
| [shader("vertex")] | [shader("vertex")] | ||||||
| VertexStageOutput vertexMain( | VertexStageOutput vertexMain( | ||||||
|   AssembledVertex assembledVertex |   AssembledVertex assembledVertex | ||||||
| @@ -35,7 +40,7 @@ VertexStageOutput vertexMain( | |||||||
|  |  | ||||||
|   output.sv_position = mul( |   output.sv_position = mul( | ||||||
|     float4(position, 1.0), |     float4(position, 1.0), | ||||||
|     mul(u_Model, mul(u_View, u_Projection)) |     mul(transforms.model, mul(transforms.view, transforms.projection)) | ||||||
|   ); |   ); | ||||||
|  |  | ||||||
|   return output; |   return output; | ||||||
| @@ -46,10 +51,10 @@ Fragment fragmentMain( | |||||||
|   float2 uv: UV |   float2 uv: UV | ||||||
| ) : SV_Target { | ) : SV_Target { | ||||||
|   Fragment output; |   Fragment output; | ||||||
|   if(u_HasTexture) { |   if (colors.hasTexture) { | ||||||
|     output.color = u_Texture.Sample(uv) * u_Color; |       output.color = colors.texture.Sample(uv) * colors.colors[0]; | ||||||
|   } else { |   } else { | ||||||
|       output.color = someFunction(u_Color); |       output.color = colors.colors[0] - float4(colors.somethingElse, 0, 0, 0); | ||||||
|   } |   } | ||||||
|   return output; |   return output; | ||||||
| } | } | ||||||
| @@ -8,10 +8,6 @@ | |||||||
| #include "asset/AssetManager.hpp" | #include "asset/AssetManager.hpp" | ||||||
| #include "game/Game.hpp" | #include "game/Game.hpp" | ||||||
|  |  | ||||||
| #if DAWN_DEBUG_SHADERS |  | ||||||
|   #include <fstream> |  | ||||||
| #endif |  | ||||||
|  |  | ||||||
| using namespace Dawn; | using namespace Dawn; | ||||||
|  |  | ||||||
| const std::string ShaderLoader::ASSET_TYPE = "shader"; | const std::string ShaderLoader::ASSET_TYPE = "shader"; | ||||||
| @@ -39,93 +35,13 @@ void ShaderLoader::updateSync() { | |||||||
|  |  | ||||||
|   // Load the shader string |   // Load the shader string | ||||||
|   Slang::ComPtr<IBlob> diagnostics; |   Slang::ComPtr<IBlob> diagnostics; | ||||||
|   module = sm->session->loadModule( |   auto module = sm->session->loadModule( | ||||||
|     this->name.c_str(), |     this->name.c_str(), | ||||||
|     diagnostics.writeRef() |     diagnostics.writeRef() | ||||||
|   ); |   ); | ||||||
|  |   shader->init(module, sm->session); | ||||||
|   // Get list of entry points and create components |  | ||||||
|   int32_t definedEntryPointCount = module->getDefinedEntryPointCount(); |  | ||||||
|   IComponentType** components = new IComponentType*[definedEntryPointCount + 1]; |  | ||||||
|   int32_t componentCount = 0; |  | ||||||
|   components[componentCount++] = module;// First component is module. |  | ||||||
|  |  | ||||||
|   // Get the entry point info and append to components list. |  | ||||||
|   for(auto i = 0; i < definedEntryPointCount; i++) { |  | ||||||
|     Slang::ComPtr<IEntryPoint> ep; |  | ||||||
|     auto result = module->getDefinedEntryPoint(i, ep.writeRef()); |  | ||||||
|     if(result != SLANG_OK) assertUnreachable("Failed to get entry point."); |  | ||||||
|     components[componentCount++] = ep; |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   // Create the composite component type |  | ||||||
|   sm->session->createCompositeComponentType( |  | ||||||
|     components, |  | ||||||
|     componentCount, |  | ||||||
|     program.writeRef(), |  | ||||||
|     diagnostics.writeRef() |  | ||||||
|   ); |  | ||||||
|   if(diagnostics) { |  | ||||||
|     assertUnreachable("%s\n", (const char*) diagnostics->getBufferPointer()); |  | ||||||
|     return; |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   // Link the program. |  | ||||||
|   auto result = program->link(linkedProgram.writeRef(), diagnostics.writeRef()); |  | ||||||
|   if(diagnostics) { |  | ||||||
|     assertUnreachable("%s\n", (const char*) diagnostics->getBufferPointer()); |  | ||||||
|     return; |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   // Create the shader program. |  | ||||||
|   Slang::ComPtr<IBlob> blob; |  | ||||||
|   slang::ProgramLayout* layout = program->getLayout(); |  | ||||||
|   std::vector<std::shared_ptr<ShaderStage>> shaderStages; |  | ||||||
|   for(auto i = 0; i < definedEntryPointCount; i++) { |  | ||||||
|     // Get the code |  | ||||||
|     auto result = linkedProgram->getEntryPointCode( |  | ||||||
|       i, |  | ||||||
|       0, |  | ||||||
|       blob.writeRef(), |  | ||||||
|       diagnostics.writeRef() |  | ||||||
|     ); |  | ||||||
|  |  | ||||||
|     if(diagnostics) { |  | ||||||
|       assertUnreachable("%s\n", (const char*) diagnostics->getBufferPointer()); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     // Get the stage information |  | ||||||
|     auto entryPointReflection = layout->getEntryPointByIndex(i); |  | ||||||
|     auto stage = entryPointReflection->getStage(); |  | ||||||
|  |  | ||||||
|     // Write out to file for debugging |  | ||||||
|     #if DAWN_DEBUG_SHADERS |  | ||||||
|       std::filesystem::path filePath = |  | ||||||
|         "debug/shaders/" + this->name + "/" + std::to_string(i) + ".glsl" |  | ||||||
|       ; |  | ||||||
|       std::filesystem::create_directories(filePath.parent_path()); |  | ||||||
|       std::cout << "Writing shader to " << filePath << std::endl; |  | ||||||
|       std::ofstream file(filePath); |  | ||||||
|       file << (const char*)blob->getBufferPointer(); |  | ||||||
|       file.close(); |  | ||||||
|     #endif |  | ||||||
|  |  | ||||||
|     // Create the shader entry |  | ||||||
|     auto shaderStage = std::make_shared<ShaderStage>(); |  | ||||||
|     shaderStage->init( |  | ||||||
|       stage, |  | ||||||
|       std::string((const char*)blob->getBufferPointer()) |  | ||||||
|     ); |  | ||||||
|  |  | ||||||
|     // Add to the list |  | ||||||
|     shaderStages.push_back(shaderStage); |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   // Create the shader program. |  | ||||||
|   shader->init(shaderStages); |  | ||||||
|  |  | ||||||
|   // Finished loading. |   // Finished loading. | ||||||
|   delete [] components; |  | ||||||
|   this->state = ShaderLoaderState::LOADED; |   this->state = ShaderLoaderState::LOADED; | ||||||
|   this->loaded = true; |   this->loaded = true; | ||||||
| } | } | ||||||
| @@ -141,9 +57,4 @@ std::shared_ptr<ShaderProgram> ShaderLoader::getShader() { | |||||||
|  |  | ||||||
| ShaderLoader::~ShaderLoader() { | ShaderLoader::~ShaderLoader() { | ||||||
|   shader = nullptr; |   shader = nullptr; | ||||||
|  |  | ||||||
|   if(linkedProgram) { |  | ||||||
|     linkedProgram->release(); |  | ||||||
|     linkedProgram = nullptr; |  | ||||||
|   } |  | ||||||
| } | } | ||||||
| @@ -24,11 +24,6 @@ namespace Dawn { | |||||||
|     public: |     public: | ||||||
|       const static std::string ASSET_TYPE; |       const static std::string ASSET_TYPE; | ||||||
|  |  | ||||||
|       Slang::ComPtr<IComponentType> linkedProgram; |  | ||||||
|       Slang::ComPtr<IComponentType> program; |  | ||||||
|  |  | ||||||
|       IModule* module; |  | ||||||
|  |  | ||||||
|       ShaderLoader( |       ShaderLoader( | ||||||
|         const std::shared_ptr<AssetManager> assetManager, |         const std::shared_ptr<AssetManager> assetManager, | ||||||
|         const std::string name |         const std::string name | ||||||
|   | |||||||
| @@ -28,21 +28,22 @@ void SimpleTexturedMaterial::load(std::shared_ptr<SceneLoadContext> ctx) { | |||||||
| } | } | ||||||
|  |  | ||||||
| struct Color SimpleTexturedMaterial::getColor() { | struct Color SimpleTexturedMaterial::getColor() { | ||||||
|   return this->data.color; |   // return this->data.color; | ||||||
|  |   return COLOR_WHITE; | ||||||
| } | } | ||||||
|  |  | ||||||
| std::shared_ptr<Texture> SimpleTexturedMaterial::getTexture() { | std::shared_ptr<Texture> SimpleTexturedMaterial::getTexture() { | ||||||
|   return this->data.texture; |   return this->texture; | ||||||
| } | } | ||||||
|  |  | ||||||
| void SimpleTexturedMaterial::setTexture( | void SimpleTexturedMaterial::setTexture( | ||||||
|   const std::shared_ptr<Texture> texture |   const std::shared_ptr<Texture> texture | ||||||
| ) { | ) { | ||||||
|   this->data.texture = texture; |   this->texture = texture; | ||||||
| } | } | ||||||
|  |  | ||||||
| void SimpleTexturedMaterial::setColor(const struct Color color) { | void SimpleTexturedMaterial::setColor(const struct Color color) { | ||||||
|   this->data.color = color; |   // this->data.color = color; | ||||||
| } | } | ||||||
|  |  | ||||||
| std::vector<std::shared_ptr<RenderPass>> SimpleTexturedMaterial::getPasses( | std::vector<std::shared_ptr<RenderPass>> SimpleTexturedMaterial::getPasses( | ||||||
|   | |||||||
| @@ -5,35 +5,12 @@ | |||||||
|  |  | ||||||
| #pragma once | #pragma once | ||||||
| #include "component/display/material/Material.hpp" | #include "component/display/material/Material.hpp" | ||||||
| #include "display/shader/ShaderData.hpp" |  | ||||||
|  |  | ||||||
| namespace Dawn { | namespace Dawn { | ||||||
|   struct SimpleTexturedMaterialShaderData : public ShaderData { |  | ||||||
|     protected: |  | ||||||
|       void writeData() override { |  | ||||||
|         this->beginStruct(); |  | ||||||
|         // this->writeMat4(this->projection); |  | ||||||
|         // this->writeMat4(this->view); |  | ||||||
|         // this->writeMat4(this->model); |  | ||||||
|         // this->writeColor(this->color); |  | ||||||
|         // this->writeBoolean(this->hasTexture); |  | ||||||
|         // this->writeTexture(this->texture); |  | ||||||
|         this->endStruct(); |  | ||||||
|       } |  | ||||||
|  |  | ||||||
|     public: |  | ||||||
|       struct Color color; |  | ||||||
|       glm::mat4 model; |  | ||||||
|       glm::mat4 projection; |  | ||||||
|       glm::mat4 view; |  | ||||||
|       bool hasTexture; |  | ||||||
|       std::shared_ptr<Texture> texture; |  | ||||||
|   }; |  | ||||||
|  |  | ||||||
|   class SimpleTexturedMaterial : public Material { |   class SimpleTexturedMaterial : public Material { | ||||||
|     private: |     private: | ||||||
|       struct SimpleTexturedMaterialShaderData data; |  | ||||||
|       std::shared_ptr<ShaderProgram> shader; |       std::shared_ptr<ShaderProgram> shader; | ||||||
|  |       std::shared_ptr<Texture> texture; | ||||||
|        |        | ||||||
|     protected: |     protected: | ||||||
|       void initShaderPrograms() override; |       void initShaderPrograms() override; | ||||||
|   | |||||||
| @@ -30,7 +30,7 @@ RenderPass::RenderPass( | |||||||
| } | } | ||||||
|  |  | ||||||
| void RenderPass::draw() { | void RenderPass::draw() { | ||||||
|   // mesh->draw(drawMode, indiceStart, indiceCount); |   mesh->draw(drawMode, indiceStart, indiceCount); | ||||||
| } | } | ||||||
|  |  | ||||||
| RenderPass::~RenderPass() { | RenderPass::~RenderPass() { | ||||||
|   | |||||||
| @@ -11,4 +11,5 @@ target_sources(${DAWN_TARGET_NAME} | |||||||
|     IShaderStage.cpp |     IShaderStage.cpp | ||||||
|     IShaderProgram.cpp |     IShaderProgram.cpp | ||||||
|     IShaderData.cpp |     IShaderData.cpp | ||||||
|  |     ShaderStructure.cpp | ||||||
| ) | ) | ||||||
| @@ -4,17 +4,18 @@ | |||||||
| // https://opensource.org/licenses/MIT | // https://opensource.org/licenses/MIT | ||||||
|  |  | ||||||
| #include "IShaderData.hpp" | #include "IShaderData.hpp" | ||||||
| #include "assert/assert.hpp" |  | ||||||
|  |  | ||||||
| using namespace Dawn; | using namespace Dawn; | ||||||
|  |  | ||||||
| void IShaderData::write(std::shared_ptr<ShaderProgram> shader) { | IShaderData::IShaderData( | ||||||
|   assertNotNull(shader, "Shader cannot be null."); |   const std::shared_ptr<ShaderStructure> &structure | ||||||
|   this->shader = shader; | ) : structure(structure) { | ||||||
|   this->writeData(); |   data = (void *)malloc(structure->size); | ||||||
|   this->shader = nullptr; |  | ||||||
| } | } | ||||||
|  |  | ||||||
| std::shared_ptr<ShaderProgram> IShaderData::getShader() { | IShaderData::~IShaderData() { | ||||||
|   return this->shader; |   if(data != nullptr) { | ||||||
|  |     free(data); | ||||||
|  |     data = nullptr; | ||||||
|  |   } | ||||||
| } | } | ||||||
| @@ -8,35 +8,16 @@ | |||||||
| #include "display/shader/ShaderProgram.hpp" | #include "display/shader/ShaderProgram.hpp" | ||||||
|  |  | ||||||
| namespace Dawn { | namespace Dawn { | ||||||
|   class IShaderData { |   struct IShaderData { | ||||||
|     private: |  | ||||||
|       std::shared_ptr<ShaderProgram> shader; |  | ||||||
|  |  | ||||||
|     protected: |     protected: | ||||||
|       virtual void writeData() = 0; |       std::shared_ptr<ShaderStructure> structure; | ||||||
|  |       void *data = nullptr; | ||||||
|       virtual void beginStruct() = 0; |  | ||||||
|       virtual void writeMat4(const glm::mat4 &mat) = 0; |  | ||||||
|       virtual void writeVec3(const glm::vec3 &vec) = 0; |  | ||||||
|       virtual void writeVec4(const glm::vec4 &vec) = 0; |  | ||||||
|       virtual void writeColor(const struct Color &color) = 0; |  | ||||||
|       virtual void writeBoolean(const bool &value) = 0; |  | ||||||
|       virtual void writeTexture(std::shared_ptr<Texture> &texture) = 0; |  | ||||||
|       virtual void endStruct() = 0; |  | ||||||
|  |  | ||||||
|     public: |     public: | ||||||
|       /** |       IShaderData( | ||||||
|        * Writes the data to the shader. |         const std::shared_ptr<ShaderStructure> &structure | ||||||
|        *  |       ); | ||||||
|        * @param shader The shader to write to. |  | ||||||
|        */ |  | ||||||
|       void write(std::shared_ptr<ShaderProgram> shader); |  | ||||||
|  |  | ||||||
|       /** |       virtual ~IShaderData(); | ||||||
|        * Returns the shader that was written to. |  | ||||||
|        *  |  | ||||||
|        * @return The shader that was written to. |  | ||||||
|        */ |  | ||||||
|       std::shared_ptr<ShaderProgram> getShader(); |  | ||||||
|   }; |   }; | ||||||
| } | } | ||||||
| @@ -4,14 +4,134 @@ | |||||||
| // https://opensource.org/licenses/MIT | // https://opensource.org/licenses/MIT | ||||||
|  |  | ||||||
| #include "IShaderProgram.hpp" | #include "IShaderProgram.hpp" | ||||||
|  | #include "assert/assert.hpp" | ||||||
|  | #if DAWN_DEBUG_SHADERS | ||||||
|  |   #include <fstream> | ||||||
|  | #endif | ||||||
|  |  | ||||||
| using namespace Dawn; | using namespace Dawn; | ||||||
|  |  | ||||||
| void IShaderProgram::init( | void IShaderProgram::init( | ||||||
|   const std::vector<std::shared_ptr<ShaderStage>> &stages |   IModule *module, | ||||||
|  |   Slang::ComPtr<ISession> session | ||||||
| ) { | ) { | ||||||
|   this->stages = stages; |   assertNotNull(module, "Module cannot be null."); | ||||||
|  |   this->module = module; | ||||||
|  |  | ||||||
|  |   // Get list of entry points and create components | ||||||
|  |   int32_t definedEntryPointCount = module->getDefinedEntryPointCount(); | ||||||
|  |   // +1 for module | ||||||
|  |   auto components = new IComponentType*[definedEntryPointCount + 1]; | ||||||
|  |   int32_t componentCount = 0; | ||||||
|  |   components[componentCount++] = module;// First component is module. | ||||||
|  |  | ||||||
|  |   // Get the entry point info and append to components list. | ||||||
|  |   for(auto i = 0; i < definedEntryPointCount; i++) { | ||||||
|  |     auto result = module->getDefinedEntryPoint( | ||||||
|  |       i, | ||||||
|  |       (IEntryPoint**)(&components[componentCount++]) | ||||||
|  |     ); | ||||||
|  |     if(result != SLANG_OK) assertUnreachable("Failed to get entry point."); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   // Create the composite component type | ||||||
|  |   Slang::ComPtr<IBlob> diagnostics; | ||||||
|  |   session->createCompositeComponentType( | ||||||
|  |     components, | ||||||
|  |     componentCount, | ||||||
|  |     program.writeRef(), | ||||||
|  |     diagnostics.writeRef() | ||||||
|  |   ); | ||||||
|  |   if(diagnostics) { | ||||||
|  |     assertUnreachable("%s\n", (const char*) diagnostics->getBufferPointer()); | ||||||
|  |     return; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   // Link the program. | ||||||
|  |   auto result = program->link(linkedProgram.writeRef(), diagnostics.writeRef()); | ||||||
|  |   if(diagnostics) { | ||||||
|  |     assertUnreachable("%s\n", (const char*) diagnostics->getBufferPointer()); | ||||||
|  |     return; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   // Get the layout | ||||||
|  |   layout = program->getLayout(); | ||||||
|  |  | ||||||
|  |   // Create the shader program. | ||||||
|  |   Slang::ComPtr<IBlob> blob; | ||||||
|  |   for(auto i = 0; i < definedEntryPointCount; i++) { | ||||||
|  |     // Get the code | ||||||
|  |     auto result = linkedProgram->getEntryPointCode( | ||||||
|  |       i, | ||||||
|  |       0, | ||||||
|  |       blob.writeRef(), | ||||||
|  |       diagnostics.writeRef() | ||||||
|  |     ); | ||||||
|  |  | ||||||
|  |     if(diagnostics) { | ||||||
|  |       assertUnreachable("%s\n", (const char*) diagnostics->getBufferPointer()); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     // Get the stage information | ||||||
|  |     auto entryPointReflection = layout->getEntryPointByIndex(i); | ||||||
|  |     auto stage = entryPointReflection->getStage(); | ||||||
|  |  | ||||||
|  |     // Write out to file for debugging | ||||||
|  |     #if DAWN_DEBUG_SHADERS | ||||||
|  |       std::filesystem::path filePath = ( | ||||||
|  |         "debug/" + | ||||||
|  |         std::string(module->getName()) + | ||||||
|  |         "/" + | ||||||
|  |         std::string(entryPointReflection->getName()) + | ||||||
|  |         ".glsl" | ||||||
|  |       ); | ||||||
|  |       std::filesystem::create_directories(filePath.parent_path()); | ||||||
|  |       std::cout << "Writing shader to " << filePath << std::endl; | ||||||
|  |       std::ofstream file(filePath); | ||||||
|  |       file << (const char*)blob->getBufferPointer(); | ||||||
|  |       file.close(); | ||||||
|  |     #endif | ||||||
|  |  | ||||||
|  |     // Create the shader entry | ||||||
|  |     auto shaderStage = std::make_shared<ShaderStage>(); | ||||||
|  |     shaderStage->init( | ||||||
|  |       stage, | ||||||
|  |       std::string((const char*)blob->getBufferPointer()) | ||||||
|  |     ); | ||||||
|  |  | ||||||
|  |     // Add to the list | ||||||
|  |     stages.push_back(shaderStage); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   // Cleanup components | ||||||
|  |   delete [] components; | ||||||
|  |  | ||||||
|  |   // Reflect out the data | ||||||
|  |   auto rootLayout = layout->getGlobalParamsVarLayout(); | ||||||
|  |   auto rootLayoutTypeLayout = rootLayout->getTypeLayout(); | ||||||
|  |   assertTrue( | ||||||
|  |     rootLayoutTypeLayout->getKind() == TypeReflection::Kind::ConstantBuffer, | ||||||
|  |     "Root layout, should and must be a constant buffer." | ||||||
|  |   ); | ||||||
|  |  | ||||||
|  |   auto realRootLayout = rootLayoutTypeLayout->getElementVarLayout(); | ||||||
|  |   auto realRootLayoutTypeLayout = realRootLayout->getTypeLayout(); | ||||||
|  |   assertTrue( | ||||||
|  |     realRootLayoutTypeLayout->getKind() == TypeReflection::Kind::Struct, | ||||||
|  |     "Real root layout should and must be a struct." | ||||||
|  |   ); | ||||||
|  |  | ||||||
|  |   // Now we can really begin parsing out the data. | ||||||
|  |   structure = std::make_shared<struct ShaderStructure>( | ||||||
|  |     realRootLayout | ||||||
|  |   ); | ||||||
|  |   assertTrue(structure->name == "", "Root structure should not have a name."); | ||||||
| } | } | ||||||
|  |  | ||||||
| IShaderProgram::~IShaderProgram() { | IShaderProgram::~IShaderProgram() { | ||||||
|  |   // Release the linked program | ||||||
|  |   if(linkedProgram) { | ||||||
|  |     linkedProgram->release(); | ||||||
|  |     linkedProgram = nullptr; | ||||||
|  |   } | ||||||
| } | } | ||||||
| @@ -5,12 +5,18 @@ | |||||||
|  |  | ||||||
| #pragma once | #pragma once | ||||||
| #include "display/shader/ShaderStage.hpp" | #include "display/shader/ShaderStage.hpp" | ||||||
|  | #include "display/shader/ShaderStructure.hpp" | ||||||
|  |  | ||||||
| namespace Dawn { | namespace Dawn { | ||||||
|  |  | ||||||
|   class IShaderProgram { |   class IShaderProgram { | ||||||
|     protected: |     protected: | ||||||
|  |       IModule *module; | ||||||
|       std::vector<std::shared_ptr<ShaderStage>> stages; |       std::vector<std::shared_ptr<ShaderStage>> stages; | ||||||
|  |       ComPtr<IComponentType> program; | ||||||
|  |       ComPtr<IComponentType> linkedProgram; | ||||||
|  |       ProgramLayout *layout; | ||||||
|  |       std::shared_ptr<struct ShaderStructure> structure; | ||||||
|  |  | ||||||
|     public: |     public: | ||||||
|       /** |       /** | ||||||
| @@ -25,10 +31,12 @@ namespace Dawn { | |||||||
|        * loading the shader code and "initializing" the stages before we create |        * loading the shader code and "initializing" the stages before we create | ||||||
|        * and initialize the program which will use and link the stages. |        * and initialize the program which will use and link the stages. | ||||||
|        *  |        *  | ||||||
|        * @param stages The stages to use in this program. |        * @param module The SLANG module that was loaded. | ||||||
|  |        * @param session The SLANG session that was used to load the module. | ||||||
|        */ |        */ | ||||||
|       virtual void init( |       virtual void init( | ||||||
|         const std::vector<std::shared_ptr<ShaderStage>> &stages |         IModule *module, | ||||||
|  |         ComPtr<ISession> session | ||||||
|       ); |       ); | ||||||
|  |  | ||||||
|       /** |       /** | ||||||
|   | |||||||
| @@ -6,8 +6,10 @@ | |||||||
| #pragma once | #pragma once | ||||||
| #include "dawn.hpp" | #include "dawn.hpp" | ||||||
| #include "slang.h" | #include "slang.h" | ||||||
|  | #include "slang-com-ptr.h" | ||||||
|  |  | ||||||
| using namespace slang; | using namespace slang; | ||||||
|  | using namespace Slang; | ||||||
|  |  | ||||||
| namespace Dawn { | namespace Dawn { | ||||||
|   class IShaderStage { |   class IShaderStage { | ||||||
|   | |||||||
							
								
								
									
										59
									
								
								src/dawn/display/shader/ShaderStructure.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										59
									
								
								src/dawn/display/shader/ShaderStructure.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,59 @@ | |||||||
|  | // Copyright (c) 2024 Dominic Masters | ||||||
|  | //  | ||||||
|  | // This software is released under the MIT License. | ||||||
|  | // https://opensource.org/licenses/MIT | ||||||
|  |  | ||||||
|  | #include "ShaderStructure.hpp" | ||||||
|  | #include "display/shader/ShaderData.hpp" | ||||||
|  | #include "assert/assert.hpp" | ||||||
|  |  | ||||||
|  | using namespace Dawn; | ||||||
|  |  | ||||||
|  | ShaderStructure::ShaderStructure(VariableLayoutReflection *reflection) { | ||||||
|  |   auto typeLayout = reflection->getTypeLayout(); | ||||||
|  |   auto cName = reflection->getName(); | ||||||
|  |   this->name = cName ? std::string(cName) : ""; | ||||||
|  |   this->size = typeLayout->getSize(); | ||||||
|  |   this->alignment = typeLayout->getAlignment(); | ||||||
|  |  | ||||||
|  |   switch(typeLayout->getKind()) { | ||||||
|  |     case TypeReflection::Kind::Struct: { | ||||||
|  |       this->type = ShaderStructureType::STRUCT; | ||||||
|  |       auto count = typeLayout->getFieldCount(); | ||||||
|  |       size_t offset = this->start; | ||||||
|  |       for(auto i = 0; i < count; i++) { | ||||||
|  |         auto field = typeLayout->getFieldByIndex(i); | ||||||
|  |         ShaderStructure member(field); | ||||||
|  |         member.start = offset; | ||||||
|  |         offset += member.size; | ||||||
|  |         this->members.push_back(member); | ||||||
|  |       } | ||||||
|  |       assertTrue(offset == this->size, "Struct size/offset mismatch?"); | ||||||
|  |       break; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     case TypeReflection::Kind::Array: { | ||||||
|  |       this->type = ShaderStructureType::ARRAY; | ||||||
|  |       this->length = typeLayout->getElementCount(); | ||||||
|  |       break; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     case TypeReflection::Kind::Matrix: | ||||||
|  |     case TypeReflection::Kind::Vector: | ||||||
|  |     case TypeReflection::Kind::Scalar: | ||||||
|  |       this->type = ShaderStructureType::VARIABLE; | ||||||
|  |       break; | ||||||
|  |  | ||||||
|  |     case TypeReflection::Kind::Resource: | ||||||
|  |       this->type = ShaderStructureType::RESOURCE; | ||||||
|  |       break; | ||||||
|  |  | ||||||
|  |     default: { | ||||||
|  |       assertUnreachable("Unknown type layout kind: %d", typeLayout->getKind()); | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | std::shared_ptr<ShaderData> ShaderStructure::createData() { | ||||||
|  |   return std::make_shared<ShaderData>(shared_from_this()); | ||||||
|  | } | ||||||
							
								
								
									
										57
									
								
								src/dawn/display/shader/ShaderStructure.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										57
									
								
								src/dawn/display/shader/ShaderStructure.hpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,57 @@ | |||||||
|  | // Copyright (c) 2024 Dominic Masters | ||||||
|  | //  | ||||||
|  | // This software is released under the MIT License. | ||||||
|  | // https://opensource.org/licenses/MIT | ||||||
|  |  | ||||||
|  | #pragma once | ||||||
|  | #include "dawn.hpp" | ||||||
|  | #include "slang.h" | ||||||
|  | #include "slang-com-ptr.h" | ||||||
|  |  | ||||||
|  | using namespace slang; | ||||||
|  | using namespace Slang; | ||||||
|  |  | ||||||
|  | namespace Dawn { | ||||||
|  |   class ShaderData; | ||||||
|  |  | ||||||
|  |   enum class ShaderStructureType { | ||||||
|  |     STRUCT, | ||||||
|  |     ARRAY, | ||||||
|  |     VARIABLE, | ||||||
|  |     RESOURCE | ||||||
|  |   }; | ||||||
|  |  | ||||||
|  |   struct ShaderStructure : | ||||||
|  |     public std::enable_shared_from_this<ShaderStructure> | ||||||
|  |   { | ||||||
|  |     public: | ||||||
|  |       std::string name; | ||||||
|  |       ShaderStructureType type; | ||||||
|  |  | ||||||
|  |       // Shared properties | ||||||
|  |       size_t start = 0; | ||||||
|  |       size_t alignment; | ||||||
|  |       size_t size; | ||||||
|  |  | ||||||
|  |       // Struct properties | ||||||
|  |       std::vector<struct ShaderStructure> members; | ||||||
|  |  | ||||||
|  |       // Array properties | ||||||
|  |       size_t length; | ||||||
|  |  | ||||||
|  |       /** | ||||||
|  |        * Constructs the ShaderStructure object | ||||||
|  |        *  | ||||||
|  |        * @param reflection Reflection data to construct the structure from. | ||||||
|  |        */ | ||||||
|  |       ShaderStructure(VariableLayoutReflection *reflection); | ||||||
|  |  | ||||||
|  |       /** | ||||||
|  |        * Creates data for a shader that matches this structure. | ||||||
|  |        *  | ||||||
|  |        * @param name Name of the member to get. | ||||||
|  |        * @return The member structure. | ||||||
|  |        */ | ||||||
|  |       std::shared_ptr<ShaderData> createData(); | ||||||
|  |   }; | ||||||
|  | } | ||||||
| @@ -3,61 +3,19 @@ | |||||||
| // This software is released under the MIT License. | // This software is released under the MIT License. | ||||||
| // https://opensource.org/licenses/MIT | // https://opensource.org/licenses/MIT | ||||||
|  |  | ||||||
| #include "ShaderData.hpp" | #include "display/shader/ShaderData.hpp" | ||||||
| #include "assert/assert.hpp" |  | ||||||
| #include "assert/assertgl.hpp" |  | ||||||
|  |  | ||||||
| using namespace Dawn; | using namespace Dawn; | ||||||
|  |  | ||||||
| void ShaderData::beginStruct() { | ShaderData::ShaderData( | ||||||
|   // Do nothing |   const std::shared_ptr<ShaderStructure> &structure | ||||||
|  | ) : IShaderData(structure) { | ||||||
|  |   glGenBuffers(1, &this->buffer); | ||||||
| } | } | ||||||
|  |  | ||||||
| void ShaderData::writeMat4(const glm::mat4 &mat) { | ShaderData::~ShaderData() { | ||||||
|   char_t name[1024]; |   if(this->buffer != -1) { | ||||||
|   GLsizei length; |     glDeleteBuffers(1, &this->buffer); | ||||||
|   GLint size; |     this->buffer = -1; | ||||||
|   GLenum type; |  | ||||||
|   glGetActiveUniform(getShader()->id, i, sizeof(name), &length, &size, &type, name); |  | ||||||
|   assertNoGLError(); |  | ||||||
|   std::cout << "Uniform: " << name << std::endl; |  | ||||||
|  |  | ||||||
|   glUniformMatrix4fv(this->i, 1, GL_FALSE, glm::value_ptr(mat)); |  | ||||||
|   assertNoGLError(); |  | ||||||
|   this->i++; |  | ||||||
|   } |   } | ||||||
|  |  | ||||||
| void ShaderData::writeVec3(const glm::vec3 &vec) { |  | ||||||
|   assertUnreachable("Not implemented"); |  | ||||||
| } |  | ||||||
|  |  | ||||||
| void ShaderData::writeVec4(const glm::vec4 &vec) { |  | ||||||
|   assertUnreachable("Not implemented"); |  | ||||||
| } |  | ||||||
|  |  | ||||||
| void ShaderData::writeColor(const struct Color &color) { |  | ||||||
|   glUniform4fv(this->i, 1, &color.r); |  | ||||||
|   assertNoGLError(); |  | ||||||
|   this->i++; |  | ||||||
| } |  | ||||||
|  |  | ||||||
| void ShaderData::writeBoolean(const bool &value) { |  | ||||||
|   glUniform1i(this->i, value ? 1 : 0); |  | ||||||
|   assertNoGLError(); |  | ||||||
|   this->i++; |  | ||||||
| } |  | ||||||
|  |  | ||||||
| void ShaderData::writeTexture(std::shared_ptr<Texture> &texture) { |  | ||||||
|   if(texture == nullptr) { |  | ||||||
|     this->i++; |  | ||||||
|     return; |  | ||||||
|   } |  | ||||||
|   texture->bind(0); |  | ||||||
|   glUniform1i(this->i, 0); |  | ||||||
|   assertNoGLError(); |  | ||||||
|   this->i++; |  | ||||||
| } |  | ||||||
|  |  | ||||||
| void ShaderData::endStruct() { |  | ||||||
|   // Do nothing |  | ||||||
| } | } | ||||||
| @@ -5,20 +5,18 @@ | |||||||
|  |  | ||||||
| #pragma once | #pragma once | ||||||
| #include "display/shader/IShaderData.hpp" | #include "display/shader/IShaderData.hpp" | ||||||
|  | #include "dawnopengl.hpp" | ||||||
|  |  | ||||||
| namespace Dawn { | namespace Dawn { | ||||||
|   class ShaderData : public IShaderData { |   class ShaderData : public IShaderData { | ||||||
|     private: |     private: | ||||||
|       int32_t i = 0; |       GLuint buffer = -1; | ||||||
|  |  | ||||||
|     protected: |     public: | ||||||
|       void beginStruct() override; |       ShaderData( | ||||||
|       void writeMat4(const glm::mat4 &mat) override; |         const std::shared_ptr<ShaderStructure> &structure | ||||||
|       void writeVec3(const glm::vec3 &vec) override; |       ); | ||||||
|       void writeVec4(const glm::vec4 &vec) override; |  | ||||||
|       void writeColor(const struct Color &color) override; |       ~ShaderData() override; | ||||||
|       void writeBoolean(const bool &value) override; |  | ||||||
|       void writeTexture(std::shared_ptr<Texture> &texture) override; |  | ||||||
|       void endStruct() override; |  | ||||||
|   }; |   }; | ||||||
| } | } | ||||||
| @@ -11,12 +11,22 @@ | |||||||
|  |  | ||||||
| using namespace Dawn; | using namespace Dawn; | ||||||
|  |  | ||||||
|  | struct TestData { | ||||||
|  |   glm::mat4 projection; | ||||||
|  |   glm::mat4 view; | ||||||
|  |   glm::mat4 model; | ||||||
|  |   int hasTexture; | ||||||
|  |   int padding[3]; | ||||||
|  |   struct Color color; | ||||||
|  |   int test; | ||||||
|  | }; | ||||||
|  |  | ||||||
| void ShaderProgram::init( | void ShaderProgram::init( | ||||||
|   const std::vector<std::shared_ptr<ShaderStage>> &stages |   IModule *module, | ||||||
|  |   Slang::ComPtr<ISession> session | ||||||
| ) { | ) { | ||||||
|   assertTrue(this->id == -1, "ShaderProgram already initialized?"); |   assertTrue(this->id == -1, "ShaderProgram already initialized?"); | ||||||
|  |   IShaderProgram::init(module, session); | ||||||
|   IShaderProgram::init(stages); |  | ||||||
|  |  | ||||||
|   // Create the program |   // Create the program | ||||||
|   this->id = glCreateProgram(); |   this->id = glCreateProgram(); | ||||||
| @@ -54,40 +64,75 @@ void ShaderProgram::init( | |||||||
|   // GLint numUniforms = 0; |   // GLint numUniforms = 0; | ||||||
|   // glGetProgramiv(this->id, GL_ACTIVE_UNIFORMS, &numUniforms); |   // glGetProgramiv(this->id, GL_ACTIVE_UNIFORMS, &numUniforms); | ||||||
|   // assertNoGLError(); |   // assertNoGLError(); | ||||||
|  |  | ||||||
|   // for(GLint i = 0; i < numUniforms; ++i) { |   // for(GLint i = 0; i < numUniforms; ++i) { | ||||||
|   //   char name[1024]; |   //   char name[1024]; | ||||||
|   //   GLsizei length; |   //   GLsizei length; | ||||||
|   //   GLint size; |   //   GLint size; | ||||||
|   //   GLenum type; |   //   GLenum type; | ||||||
|  |  | ||||||
|   //   glGetActiveUniform(this->id, i, sizeof(name), &length, &size, &type, name); |   //   glGetActiveUniform(this->id, i, sizeof(name), &length, &size, &type, name); | ||||||
|   //   assertNoGLError(); |   //   assertNoGLError(); | ||||||
|   //   std::cout << "Uniform: " << i << ": " << name << " has size " << size << " and length " << length << std::endl; |   //   std::cout << "Uniform: " << i << ": " << name << " has size " << size << " and length " << length << std::endl; | ||||||
|   // } |   // } | ||||||
|   // GLint numUniformBlocks = 0; |   // GLint numUniformBlocks = 0; | ||||||
|   // glGetProgramiv(this->id, GL_ACTIVE_UNIFORM_BLOCKS, &numUniformBlocks); |   // glGetProgramiv(this->id, GL_ACTIVE_UNIFORM_BLOCKS, &numUniformBlocks); | ||||||
|  |  | ||||||
|   // for(GLint i = 0; i < numUniformBlocks; ++i) { |   // for(GLint i = 0; i < numUniformBlocks; ++i) { | ||||||
|   //   GLint size; |   //   GLint size; | ||||||
|   //   glGetActiveUniformBlockiv(this->id, i, GL_UNIFORM_BLOCK_DATA_SIZE, &size); |   //   glGetActiveUniformBlockiv(this->id, i, GL_UNIFORM_BLOCK_DATA_SIZE, &size); | ||||||
|   //   assertNoGLError(); |   //   assertNoGLError(); | ||||||
|   //   std::cout << "Uniform Block: " << i << " has size " << size << std::endl; |   //   std::cout << "Uniform Block: " << i << " has size " << size << std::endl; | ||||||
|   // } |   // } | ||||||
|  |   // auto data = std::make_shared<SimpleTexturedMaterialShaderData>(); | ||||||
|  |   // data->color = COLOR_WHITE; | ||||||
|  |   // data->model = glm::mat4(1.0f); | ||||||
|  |   // data->projection = glm::perspective( | ||||||
|  |   //   glm::radians(45.0f), 800.0f / 600.0f, 0.1f, 100.0f | ||||||
|  |   // ); | ||||||
|  |   // data->view = glm::lookAt( | ||||||
|  |   //   glm::vec3(4,3,3), glm::vec3(0,0,0), glm::vec3(0,1,0) | ||||||
|  |   // ); | ||||||
|  |  | ||||||
|   glUseProgram(this->id); |   glUseProgram(this->id); | ||||||
|   assertNoGLError(); |   assertNoGLError(); | ||||||
|  |   GLuint ubo; | ||||||
|  |   glGenBuffers(1, &ubo); | ||||||
|  |   assertNoGLError(); | ||||||
|  |  | ||||||
|   auto data = std::make_shared<SimpleTexturedMaterialShaderData>(); |   struct TestData data; | ||||||
|   data->color = COLOR_WHITE; |   data.color = COLOR_WHITE; | ||||||
|   data->model = glm::mat4(1.0f); |   data.model = glm::mat4(1.0f); | ||||||
|   data->projection = glm::perspective( |   data.projection = glm::perspective( | ||||||
|     glm::radians(45.0f), 800.0f / 600.0f, 0.1f, 100.0f |     glm::radians(45.0f), 800.0f / 600.0f, 0.1f, 10000.0f | ||||||
|   ); |   ); | ||||||
|   data->view = glm::lookAt( |   data.view = glm::lookAt( | ||||||
|     glm::vec3(4,3,3), glm::vec3(0,0,0), glm::vec3(0,1,0) |     glm::vec3(300,300,300), glm::vec3(0,0,0), glm::vec3(0,1,0) | ||||||
|   ); |   ); | ||||||
|   data->write(shared_from_this()); |   data.hasTexture = false; | ||||||
|  |   data.test = 1; | ||||||
|  |  | ||||||
|  |   glBindBuffer(GL_UNIFORM_BUFFER, ubo); | ||||||
|  |   assertNoGLError(); | ||||||
|  |   glBindBufferBase(GL_UNIFORM_BUFFER, 0, ubo); | ||||||
|  |   assertNoGLError(); | ||||||
|  |   glBufferData(GL_UNIFORM_BUFFER, sizeof(struct TestData), &data, GL_STATIC_DRAW); | ||||||
|  |   assertNoGLError(); | ||||||
|  |  | ||||||
|  |   // testTexture = std::make_shared<Texture>(); | ||||||
|  |   // testTexture->setSize(2, 2, TextureFormat::RGBA, TextureDataFormat::UNSIGNED_BYTE); | ||||||
|  |   // uint8_t colors[4 * 4]; | ||||||
|  |   // colors[0] = 255; colors[1] = 0; colors[2] = 0; colors[3] = 255; | ||||||
|  |   // colors[4] = 0; colors[5] = 255; colors[6] = 0; colors[7] = 255; | ||||||
|  |   // colors[8] = 0; colors[9] = 0; colors[10] = 255; colors[11] = 255; | ||||||
|  |   // colors[12] = 255; colors[13] = 255; colors[14] = 255; colors[15] = 255; | ||||||
|  |   // testTexture->buffer(colors); | ||||||
|  |   // testTexture->bind(0); | ||||||
|  |  | ||||||
|  |   // int index = glGetUniformLocation(this->id, "globalParams_uniforms_texture_0"); | ||||||
|  |   // assertNoGLError(); | ||||||
|  |   // std::cout << "Index: " << index << std::endl; | ||||||
|  |   // glUniform1i(index, 0); | ||||||
|  |   // assertNoGLError();   | ||||||
|  |  | ||||||
|  |   // data->write(shared_from_this()); | ||||||
| } | } | ||||||
|  |  | ||||||
| ShaderProgram::~ShaderProgram() { | ShaderProgram::~ShaderProgram() { | ||||||
|   | |||||||
| @@ -6,23 +6,25 @@ | |||||||
| #pragma once | #pragma once | ||||||
| #include "display/shader/IShaderProgram.hpp" | #include "display/shader/IShaderProgram.hpp" | ||||||
| #include "dawnopengl.hpp" | #include "dawnopengl.hpp" | ||||||
|  | #include "display/Texture.hpp" | ||||||
|  | #include "slang.h" | ||||||
|  |  | ||||||
|  | using namespace slang; | ||||||
|  |  | ||||||
| namespace Dawn { | namespace Dawn { | ||||||
|   class ShaderData; |  | ||||||
|    |  | ||||||
|   class ShaderProgram : |   class ShaderProgram : | ||||||
|     public IShaderProgram, |     public IShaderProgram, | ||||||
|     public std::enable_shared_from_this<ShaderProgram> |     public std::enable_shared_from_this<ShaderProgram> | ||||||
|   { |   { | ||||||
|     private: |     private: | ||||||
|       GLuint id = -1; |       GLuint id = -1; | ||||||
|  |       std::shared_ptr<Texture> testTexture; | ||||||
|  |  | ||||||
|     public: |     public: | ||||||
|       void init( |       void init( | ||||||
|         const std::vector<std::shared_ptr<ShaderStage>> &stages |         IModule *module, | ||||||
|       ) override; |         Slang::ComPtr<ISession> session | ||||||
|       ~ShaderProgram(); |       ); | ||||||
|  |       ~ShaderProgram() override; | ||||||
|       friend class ShaderData; |  | ||||||
|   }; |   }; | ||||||
| } | } | ||||||
| @@ -48,7 +48,6 @@ function(tool_texture target file) | |||||||
|       ${DAWN_ASSETS_SOURCE_DIR}/${file} |       ${DAWN_ASSETS_SOURCE_DIR}/${file} | ||||||
|       ${Python3_EXECUTABLE} |       ${Python3_EXECUTABLE} | ||||||
|     USES_TERMINAL |     USES_TERMINAL | ||||||
|  |  | ||||||
|   ) |   ) | ||||||
|   add_dependencies(dawnassets ${target}_texture) |   add_dependencies(dawnassets ${target}_texture) | ||||||
| endfunction() | endfunction() | ||||||
		Reference in New Issue
	
	Block a user