Technically working shaders.
This commit is contained in:
		
							
								
								
									
										8
									
								
								assets/materials/simple-textured.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										8
									
								
								assets/materials/simple-textured.json
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,8 @@ | |||||||
|  | { | ||||||
|  |   "assets": { | ||||||
|  |     "simpleTexturedShader": { | ||||||
|  |       "type": "shader", | ||||||
|  |       "path": "shaders/simple-textured.shader" | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  | } | ||||||
| @@ -13,6 +13,10 @@ | |||||||
|     "rosatext": { |     "rosatext": { | ||||||
|       "type": "texture", |       "type": "texture", | ||||||
|       "path": "rosa.texture" |       "path": "rosa.texture" | ||||||
|  |     }, | ||||||
|  |     "simpleTexturedShader": { | ||||||
|  |       "type": "shader", | ||||||
|  |       "path": "shaders/simple-textured.slang" | ||||||
|     } |     } | ||||||
|   }, |   }, | ||||||
|  |  | ||||||
|   | |||||||
| @@ -1,13 +1,9 @@ | |||||||
| struct Uniforms { | uniform float4x4 projection; | ||||||
|   float4x4 projection; | uniform float4x4 view; | ||||||
|   float4x4 view; | uniform float4x4 model; | ||||||
|   float4x4 model; | uniform float4 color; | ||||||
|   float4 color; | uniform bool hasTexture; | ||||||
|   bool hasTexture; | uniform Sampler2D texture; | ||||||
|   Sampler2D texture; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| uniform Uniforms uniforms; |  | ||||||
| 
 | 
 | ||||||
| struct AssembledVertex { | struct AssembledVertex { | ||||||
|   float3 position : POSITION; |   float3 position : POSITION; | ||||||
| @@ -35,7 +31,7 @@ VertexStageOutput vertexMain( | |||||||
| 
 | 
 | ||||||
|   output.sv_position = mul( |   output.sv_position = mul( | ||||||
|     float4(position, 1.0), |     float4(position, 1.0), | ||||||
|     mul(uniforms.model, mul(uniforms.view, uniforms.projection)) |     mul(model, mul(view, projection)) | ||||||
|   ); |   ); | ||||||
| 
 | 
 | ||||||
|   return output; |   return output; | ||||||
| @@ -46,10 +42,11 @@ Fragment fragmentMain( | |||||||
|   float2 uv: UV |   float2 uv: UV | ||||||
| ) : SV_Target { | ) : SV_Target { | ||||||
|   Fragment output; |   Fragment output; | ||||||
|   if (uniforms.hasTexture) { |    | ||||||
|     output.color = uniforms.texture.Sample(uv) * uniforms.color; |   if (hasTexture) { | ||||||
|  |     output.color = texture.Sample(uv) * color; | ||||||
|   } else { |   } else { | ||||||
|     output.color = uniforms.color; |     output.color = color; | ||||||
|   } |   } | ||||||
|    |    | ||||||
|   return output; |   return output; | ||||||
| @@ -43,6 +43,6 @@ add_subdirectory(util) | |||||||
|  |  | ||||||
| # Assets | # Assets | ||||||
| tool_copy(en en.json) | tool_copy(en en.json) | ||||||
| tool_copy(helloShader shaders/hello-world.slang) | tool_copy(simpleTexturedShader shaders/simple-textured.slang) | ||||||
|  |  | ||||||
| add_dependencies(${DAWN_TARGET_NAME} dawnassets) | add_dependencies(${DAWN_TARGET_NAME} dawnassets) | ||||||
| @@ -6,6 +6,7 @@ | |||||||
| #include "LoaderForSceneItems.hpp" | #include "LoaderForSceneItems.hpp" | ||||||
| #include "asset/loader/TextureLoader.hpp" | #include "asset/loader/TextureLoader.hpp" | ||||||
| #include "asset/loader/scene/PrefabLoader.hpp" | #include "asset/loader/scene/PrefabLoader.hpp" | ||||||
|  | #include "asset/loader/ShaderLoader.hpp" | ||||||
|  |  | ||||||
| using namespace Dawn; | using namespace Dawn; | ||||||
|  |  | ||||||
| @@ -58,6 +59,9 @@ void LoaderForSceneItems::setupDependencies() { | |||||||
|         prefabLoader->ctx->parent = ctx; |         prefabLoader->ctx->parent = ctx; | ||||||
|         loader = prefabLoader; |         loader = prefabLoader; | ||||||
|  |  | ||||||
|  |       } else if(type == "shader") { | ||||||
|  |         loader = getAssetManager()->get<ShaderLoader>(path); | ||||||
|  |  | ||||||
|       } else { |       } else { | ||||||
|         assertUnreachable("Unknown asset type: %s", type.c_str()); |         assertUnreachable("Unknown asset type: %s", type.c_str()); | ||||||
|       } |       } | ||||||
|   | |||||||
| @@ -11,10 +11,21 @@ | |||||||
| using namespace Dawn; | using namespace Dawn; | ||||||
|  |  | ||||||
| void SimpleTexturedMaterial::initShaderPrograms() { | void SimpleTexturedMaterial::initShaderPrograms() { | ||||||
|   this->shader = getGame()->assetManager->get<ShaderLoader>("shaders/hello-world.slang")->getShader(); |   if(this->shader) return; | ||||||
|  |  | ||||||
|  |   auto shaderFile = getGame()->assetManager->get<ShaderLoader>("shaders/simple-textured.slang"); | ||||||
|  |   this->shader = shaderFile->getShader(); | ||||||
|  |  | ||||||
|  |   auto structure = this->shader->getStructure(); | ||||||
|  |   this->data = structure->createData(); | ||||||
|  |  | ||||||
|  |   this->setColor(COLOR_WHITE); | ||||||
|  |   this->setTexture(nullptr); | ||||||
| } | } | ||||||
|  |  | ||||||
| void SimpleTexturedMaterial::load(std::shared_ptr<SceneLoadContext> ctx) { | void SimpleTexturedMaterial::load(std::shared_ptr<SceneLoadContext> ctx) { | ||||||
|  |   this->initShaderPrograms(); | ||||||
|  |  | ||||||
|   if(ctx->data.contains("color")) { |   if(ctx->data.contains("color")) { | ||||||
|     this->setColor(JSON::color(ctx->data["color"])); |     this->setColor(JSON::color(ctx->data["color"])); | ||||||
|   } |   } | ||||||
| @@ -28,41 +39,47 @@ void SimpleTexturedMaterial::load(std::shared_ptr<SceneLoadContext> ctx) { | |||||||
| } | } | ||||||
|  |  | ||||||
| struct Color SimpleTexturedMaterial::getColor() { | struct Color SimpleTexturedMaterial::getColor() { | ||||||
|   // return this->data.color; |   auto structure = this->shader->getStructure(); | ||||||
|   return COLOR_WHITE; |   return data->get<struct Color>(structure->getOffset("color")); | ||||||
| } | } | ||||||
|  |  | ||||||
| std::shared_ptr<Texture> SimpleTexturedMaterial::getTexture() { | std::shared_ptr<Texture> SimpleTexturedMaterial::getTexture() { | ||||||
|   return this->texture; |   auto structure = this->shader->getStructure(); | ||||||
|  |   return data->get<std::shared_ptr<Texture>>(structure->getOffset("texture")); | ||||||
| } | } | ||||||
|  |  | ||||||
| void SimpleTexturedMaterial::setTexture( | void SimpleTexturedMaterial::setTexture( | ||||||
|   const std::shared_ptr<Texture> texture |   const std::shared_ptr<Texture> texture | ||||||
| ) { | ) { | ||||||
|   this->texture = texture; |   auto structure = this->shader->getStructure(); | ||||||
|  |   data->set<std::shared_ptr<Texture>>(structure->getOffset("texture"), texture); | ||||||
|  |   data->set<bool_t>(structure->getOffset("hasTexture"), texture != nullptr); | ||||||
| } | } | ||||||
|  |  | ||||||
| void SimpleTexturedMaterial::setColor(const struct Color color) { | void SimpleTexturedMaterial::setColor(const struct Color color) { | ||||||
|   // this->data.color = color; |   auto structure = this->shader->getStructure(); | ||||||
|  |   data->set<struct Color>(structure->getOffset("color"), color); | ||||||
| } | } | ||||||
|  |  | ||||||
| std::vector<std::shared_ptr<RenderPass>> SimpleTexturedMaterial::getPasses( | std::vector<std::shared_ptr<RenderPass>> SimpleTexturedMaterial::getPasses( | ||||||
|   struct RenderPassContext &ctx |   struct RenderPassContext &ctx | ||||||
| ) { | ) { | ||||||
|   // this->data.model = this->getItem()->getWorldTransform(); |   auto structure = this->shader->getStructure(); | ||||||
|   // this->data.projection = ctx.camera->getProjection(); |  | ||||||
|   // this->data.view = ctx.camera->getItem()->getWorldTransform(); |  | ||||||
|   // auto textures = std::unordered_map< |  | ||||||
|   //   shadertexturebinding_t, std::shared_ptr<Texture> |  | ||||||
|   // >(); |  | ||||||
|  |  | ||||||
|   // if(this->texture) { |   data->set<glm::mat4>( | ||||||
|   //   this->data.hasTexture = true; |     structure->getOffset("projection"), | ||||||
|   //   this->data.texture = 0; |     ctx.camera->getProjection() | ||||||
|   //   textures[this->data.texture] = this->texture; |   ); | ||||||
|   // } else { |  | ||||||
|   //   this->data.data.hasTexture = false; |   data->set<glm::mat4>( | ||||||
|   // } |     structure->getOffset("view"), | ||||||
|  |     ctx.camera->getItem()->getWorldTransform() | ||||||
|  |   ); | ||||||
|  |  | ||||||
|  |   data->set<glm::mat4>( | ||||||
|  |     structure->getOffset("model"), | ||||||
|  |     this->getItem()->getWorldTransform() | ||||||
|  |   ); | ||||||
|  |  | ||||||
|   return { |   return { | ||||||
|     std::make_shared<RenderPass>( |     std::make_shared<RenderPass>( | ||||||
| @@ -71,7 +88,8 @@ std::vector<std::shared_ptr<RenderPass>> SimpleTexturedMaterial::getPasses( | |||||||
|       MeshDrawMode::TRIANGLES,// Move this later. |       MeshDrawMode::TRIANGLES,// Move this later. | ||||||
|       0,// Move this later. |       0,// Move this later. | ||||||
|       -1,// Move this later. |       -1,// Move this later. | ||||||
|       this->shader |       this->shader, | ||||||
|  |       this->data | ||||||
|     ) |     ) | ||||||
|   }; |   }; | ||||||
| } | } | ||||||
|   | |||||||
| @@ -9,8 +9,8 @@ | |||||||
| namespace Dawn { | namespace Dawn { | ||||||
|   class SimpleTexturedMaterial : public Material { |   class SimpleTexturedMaterial : public Material { | ||||||
|     private: |     private: | ||||||
|       std::shared_ptr<ShaderProgram> shader; |       std::shared_ptr<ShaderProgram> shader = nullptr; | ||||||
|       std::shared_ptr<Texture> texture; |       std::shared_ptr<ShaderData> data; | ||||||
|        |        | ||||||
|     protected: |     protected: | ||||||
|       void initShaderPrograms() override; |       void initShaderPrograms() override; | ||||||
|   | |||||||
| @@ -14,13 +14,15 @@ RenderPass::RenderPass( | |||||||
|   const enum MeshDrawMode drawMode, |   const enum MeshDrawMode drawMode, | ||||||
|   const int32_t indiceStart, |   const int32_t indiceStart, | ||||||
|   const int32_t indiceCount, |   const int32_t indiceCount, | ||||||
|   const std::shared_ptr<ShaderProgram> shaderProgram |   const std::shared_ptr<ShaderProgram> shaderProgram, | ||||||
|  |   const std::shared_ptr<ShaderData> shaderData | ||||||
| ) : | ) : | ||||||
|   mesh(mesh), |   mesh(mesh), | ||||||
|   drawMode(drawMode), |   drawMode(drawMode), | ||||||
|   indiceStart(indiceStart), |   indiceStart(indiceStart), | ||||||
|   indiceCount(indiceCount), |   indiceCount(indiceCount), | ||||||
|   shaderProgram(shaderProgram) |   shaderProgram(shaderProgram), | ||||||
|  |   shaderData(shaderData) | ||||||
| { | { | ||||||
|   // Need mesh? |   // Need mesh? | ||||||
|   if(!this->mesh) { |   if(!this->mesh) { | ||||||
| @@ -30,6 +32,10 @@ RenderPass::RenderPass( | |||||||
| } | } | ||||||
|  |  | ||||||
| void RenderPass::draw() { | void RenderPass::draw() { | ||||||
|  |   shaderProgram->bind(); | ||||||
|  |   shaderData->bind(); | ||||||
|  |   shaderData->upload(); | ||||||
|  |  | ||||||
|   mesh->draw(drawMode, indiceStart, indiceCount); |   mesh->draw(drawMode, indiceStart, indiceCount); | ||||||
| } | } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -7,12 +7,14 @@ | |||||||
| #include "display/mesh/Mesh.hpp" | #include "display/mesh/Mesh.hpp" | ||||||
| #include "scene/SceneComponent.hpp" | #include "scene/SceneComponent.hpp" | ||||||
| #include "display/shader/ShaderProgram.hpp" | #include "display/shader/ShaderProgram.hpp" | ||||||
|  | #include "display/shader/ShaderData.hpp" | ||||||
|  |  | ||||||
| namespace Dawn { | namespace Dawn { | ||||||
|   class RenderPass { |   class RenderPass { | ||||||
|     private: |     private: | ||||||
|       std::shared_ptr<Mesh> mesh; |       std::shared_ptr<Mesh> mesh; | ||||||
|       std::shared_ptr<ShaderProgram> shaderProgram; |       std::shared_ptr<ShaderProgram> shaderProgram; | ||||||
|  |       std::shared_ptr<ShaderData> shaderData; | ||||||
|       const enum MeshDrawMode drawMode; |       const enum MeshDrawMode drawMode; | ||||||
|       const int32_t indiceStart; |       const int32_t indiceStart; | ||||||
|       const int32_t indiceCount; |       const int32_t indiceCount; | ||||||
| @@ -27,6 +29,7 @@ namespace Dawn { | |||||||
|        * @param indiceStart The indice to start drawing from. |        * @param indiceStart The indice to start drawing from. | ||||||
|        * @param indiceCount The number of indices to draw. |        * @param indiceCount The number of indices to draw. | ||||||
|        * @param shaderProgram The shader program to use for this render pass. |        * @param shaderProgram The shader program to use for this render pass. | ||||||
|  |        * @param shaderData The shader data to use for this render pass. | ||||||
|        */ |        */ | ||||||
|       RenderPass( |       RenderPass( | ||||||
|         SceneComponent &self, |         SceneComponent &self, | ||||||
| @@ -36,7 +39,8 @@ namespace Dawn { | |||||||
|         const int32_t indiceStart, |         const int32_t indiceStart, | ||||||
|         const int32_t indiceCount, |         const int32_t indiceCount, | ||||||
|          |          | ||||||
|         const std::shared_ptr<ShaderProgram> shaderProgram |         const std::shared_ptr<ShaderProgram> shaderProgram, | ||||||
|  |         const std::shared_ptr<ShaderData> shaderData | ||||||
|       ); |       ); | ||||||
|  |  | ||||||
|       /** |       /** | ||||||
|   | |||||||
| @@ -51,6 +51,16 @@ namespace Dawn { | |||||||
|       template<typename T> |       template<typename T> | ||||||
|       void set(const size_t offset, const T value); |       void set(const size_t offset, const T value); | ||||||
|  |  | ||||||
|  |       /** | ||||||
|  |        * Binds the buffer to the shader. | ||||||
|  |        */ | ||||||
|  |       virtual void bind() = 0; | ||||||
|  |  | ||||||
|  |       /** | ||||||
|  |        * Uploads the data to the GPU. | ||||||
|  |        */ | ||||||
|  |       virtual void upload() = 0; | ||||||
|  |  | ||||||
|       /** |       /** | ||||||
|        * Cleans up the data. |        * Cleans up the data. | ||||||
|        */ |        */ | ||||||
|   | |||||||
| @@ -129,6 +129,10 @@ void IShaderProgram::init( | |||||||
|   ); |   ); | ||||||
| } | } | ||||||
|  |  | ||||||
|  | std::shared_ptr<struct ShaderStructure> IShaderProgram::getStructure() { | ||||||
|  |   return structure; | ||||||
|  | } | ||||||
|  |  | ||||||
| IShaderProgram::~IShaderProgram() { | IShaderProgram::~IShaderProgram() { | ||||||
|   // Release the linked program |   // Release the linked program | ||||||
|   if(linkedProgram) { |   if(linkedProgram) { | ||||||
|   | |||||||
| @@ -39,6 +39,18 @@ namespace Dawn { | |||||||
|         ComPtr<ISession> session |         ComPtr<ISession> session | ||||||
|       ); |       ); | ||||||
|  |  | ||||||
|  |       /** | ||||||
|  |        * Returns the structure of the shader program. | ||||||
|  |        *  | ||||||
|  |        * @return The structure of the shader program. | ||||||
|  |        */ | ||||||
|  |       std::shared_ptr<struct ShaderStructure> getStructure(); | ||||||
|  |  | ||||||
|  |       /** | ||||||
|  |        * Binds this shader program as the currently active shader program. | ||||||
|  |        */ | ||||||
|  |       virtual void bind() = 0; | ||||||
|  |  | ||||||
|       /** |       /** | ||||||
|        * Destroy the IShaderProgram2 object |        * Destroy the IShaderProgram2 object | ||||||
|        */ |        */ | ||||||
|   | |||||||
| @@ -27,6 +27,7 @@ void ShaderManager::init(const std::shared_ptr<Game> &game) { | |||||||
|   createGlobalSession(globalSession.writeRef()); |   createGlobalSession(globalSession.writeRef()); | ||||||
|  |  | ||||||
|   // Set the target description, TODO: interface |   // Set the target description, TODO: interface | ||||||
|  |   std::cout << "Need to fix GLSL hard code" << std::endl; | ||||||
|   targetDescription.format = SLANG_GLSL; |   targetDescription.format = SLANG_GLSL; | ||||||
|   targetDescription.profile = globalSession->findProfile("glsl_330"); |   targetDescription.profile = globalSession->findProfile("glsl_330"); | ||||||
|  |  | ||||||
|   | |||||||
| @@ -60,7 +60,18 @@ ShaderStructure::ShaderStructure( | |||||||
|       break; |       break; | ||||||
|  |  | ||||||
|     case TypeReflection::Kind::Resource: |     case TypeReflection::Kind::Resource: | ||||||
|       this->type = ShaderStructureType::RESOURCE; |       switch(typeLayout->getResourceShape()) { | ||||||
|  |         case SlangResourceShape::SLANG_TEXTURE_2D: | ||||||
|  |           this->type = ShaderStructureType::TEXTURE2D; | ||||||
|  |           break; | ||||||
|  |  | ||||||
|  |         default: | ||||||
|  |           assertUnreachable( | ||||||
|  |             "Unknown resource shape: %d", | ||||||
|  |             typeLayout->getResourceShape() | ||||||
|  |           ); | ||||||
|  |           break; | ||||||
|  |       } | ||||||
|       break; |       break; | ||||||
|  |  | ||||||
|     default: { |     default: { | ||||||
| @@ -93,6 +104,18 @@ std::shared_ptr<ShaderStructure> ShaderStructure::getArrayMember( | |||||||
|   return this->members.at(index); |   return this->members.at(index); | ||||||
| } | } | ||||||
|  |  | ||||||
|  | size_t ShaderStructure::getOffset() { | ||||||
|  |   return this->start; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | size_t ShaderStructure::getOffset(const std::string &name) { | ||||||
|  |   return this->getStructMember(name)->getOffset(); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | size_t ShaderStructure::getOffset(size_t index) { | ||||||
|  |   return this->getArrayMember(index)->getOffset(); | ||||||
|  | } | ||||||
|  |  | ||||||
| std::shared_ptr<ShaderData> ShaderStructure::createData() { | std::shared_ptr<ShaderData> ShaderStructure::createData() { | ||||||
|   return std::make_shared<ShaderData>(shared_from_this()); |   return std::make_shared<ShaderData>(shared_from_this()); | ||||||
| } | } | ||||||
| @@ -18,6 +18,7 @@ namespace Dawn { | |||||||
|     STRUCT, |     STRUCT, | ||||||
|     ARRAY, |     ARRAY, | ||||||
|     VARIABLE, |     VARIABLE, | ||||||
|  |     TEXTURE2D, | ||||||
|     RESOURCE |     RESOURCE | ||||||
|   }; |   }; | ||||||
|  |  | ||||||
| @@ -67,6 +68,29 @@ namespace Dawn { | |||||||
|        */ |        */ | ||||||
|       std::shared_ptr<ShaderStructure> getArrayMember(size_t index); |       std::shared_ptr<ShaderStructure> getArrayMember(size_t index); | ||||||
|  |  | ||||||
|  |       /** | ||||||
|  |        * Gets the offset of this structure. | ||||||
|  |        *  | ||||||
|  |        * @return The offset of this structure. | ||||||
|  |        */ | ||||||
|  |       size_t getOffset(); | ||||||
|  |  | ||||||
|  |       /** | ||||||
|  |        * Gets the offset of a member of this structure. | ||||||
|  |        *  | ||||||
|  |        * @param name Name of the member to get. | ||||||
|  |        * @return The offset of the member. | ||||||
|  |        */ | ||||||
|  |       size_t getOffset(const std::string &name); | ||||||
|  |  | ||||||
|  |       /** | ||||||
|  |        * Gets the offset of a member of this array structure. | ||||||
|  |        *  | ||||||
|  |        * @param index Index of the member to get. | ||||||
|  |        * @return The offset of the member. | ||||||
|  |        */ | ||||||
|  |       size_t getOffset(size_t index); | ||||||
|  |  | ||||||
|       /** |       /** | ||||||
|        * Creates data for a shader that matches this structure. |        * Creates data for a shader that matches this structure. | ||||||
|        *  |        *  | ||||||
|   | |||||||
| @@ -10,7 +10,12 @@ | |||||||
|  |  | ||||||
| using namespace Dawn; | using namespace Dawn; | ||||||
|  |  | ||||||
| void SceneComponent::init(const std::shared_ptr<SceneItem> item) { | void SceneComponent::init() { | ||||||
|  |   assertNotNull( | ||||||
|  |     this->item.lock(), | ||||||
|  |     "SceneItem has unloaded, or was not set before initialization" | ||||||
|  |   ); | ||||||
|  |    | ||||||
|   assertFlagOff( |   assertFlagOff( | ||||||
|     state, |     state, | ||||||
|     SceneComponentState::INITIALIZED, |     SceneComponentState::INITIALIZED, | ||||||
|   | |||||||
| @@ -10,6 +10,7 @@ namespace Dawn { | |||||||
|   class Game; |   class Game; | ||||||
|   class Scene; |   class Scene; | ||||||
|   class SceneItem; |   class SceneItem; | ||||||
|  |   class SceneItemComponents; | ||||||
|  |  | ||||||
|   enum class SceneComponentState : flag_t { |   enum class SceneComponentState : flag_t { | ||||||
|     INITIAL = FLAG(0), |     INITIAL = FLAG(0), | ||||||
| @@ -42,10 +43,8 @@ namespace Dawn { | |||||||
|  |  | ||||||
|       /** |       /** | ||||||
|        * Initializes this scene component. |        * Initializes this scene component. | ||||||
|        *  |  | ||||||
|        * @param item Scene item that this component belongs to. |  | ||||||
|        */ |        */ | ||||||
|       void init(const std::shared_ptr<SceneItem> item); |       void init(); | ||||||
|  |  | ||||||
|       /** |       /** | ||||||
|        * Disposes this scene component. |        * Disposes this scene component. | ||||||
| @@ -92,5 +91,8 @@ namespace Dawn { | |||||||
|        * Disposes this scene component. |        * Disposes this scene component. | ||||||
|        */ |        */ | ||||||
|       virtual ~SceneComponent(); |       virtual ~SceneComponent(); | ||||||
|  |        | ||||||
|  |       friend class SceneItem; | ||||||
|  |       friend class SceneItemComponents; | ||||||
|   }; |   }; | ||||||
| } | } | ||||||
| @@ -34,8 +34,6 @@ void SceneItem::init() { | |||||||
|   assertFlagOff(state, SceneItemState::DEINITIALIZED, "Already deinited."); |   assertFlagOff(state, SceneItemState::DEINITIALIZED, "Already deinited."); | ||||||
|   Flag::turnOn(state, SceneItemState::INITIALIZED); |   Flag::turnOn(state, SceneItemState::INITIALIZED); | ||||||
|  |  | ||||||
|   auto sharedThis = shared_from_this(); |  | ||||||
|  |  | ||||||
|   // Loop until all components initialized... |   // Loop until all components initialized... | ||||||
|   while(true) { |   while(true) { | ||||||
|     // Create copy of the components, components may chose to add more |     // Create copy of the components, components may chose to add more | ||||||
| @@ -43,7 +41,7 @@ void SceneItem::init() { | |||||||
|     auto components = this->components; |     auto components = this->components; | ||||||
|     for(auto &component : components) { |     for(auto &component : components) { | ||||||
|       if(component->isInitialized()) continue; |       if(component->isInitialized()) continue; | ||||||
|       component->init(sharedThis); |       component->init(); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     // If they are all initalized we are fine. |     // If they are all initalized we are fine. | ||||||
|   | |||||||
| @@ -4,6 +4,8 @@ | |||||||
| // https://opensource.org/licenses/MIT | // https://opensource.org/licenses/MIT | ||||||
|  |  | ||||||
| #include "SceneItemComponents.hpp" | #include "SceneItemComponents.hpp" | ||||||
|  | #include "scene/SceneItem.hpp" | ||||||
|  | #include "assert/assert.hpp" | ||||||
|  |  | ||||||
| using namespace Dawn; | using namespace Dawn; | ||||||
|  |  | ||||||
| @@ -20,6 +22,14 @@ void SceneItemComponents::removeComponent( | |||||||
|   components.erase(it); |   components.erase(it); | ||||||
| } | } | ||||||
|  |  | ||||||
|  | void SceneItemComponents::sceneItemComponentsReferenceSelf( | ||||||
|  |   std::shared_ptr<SceneComponent> component | ||||||
|  | ) { | ||||||
|  |   assertNotNull(component, "Component cannot be NULL"); | ||||||
|  |   auto self = (SceneItem *)this; | ||||||
|  |   component->item = self->shared_from_this(); | ||||||
|  | } | ||||||
|  |  | ||||||
| SceneItemComponents::~SceneItemComponents() { | SceneItemComponents::~SceneItemComponents() { | ||||||
|  |  | ||||||
| } | } | ||||||
| @@ -10,6 +10,16 @@ namespace Dawn { | |||||||
|   class SceneItem; |   class SceneItem; | ||||||
|  |  | ||||||
|   class SceneItemComponents { |   class SceneItemComponents { | ||||||
|  |     private: | ||||||
|  |       /** | ||||||
|  |        * Internal method to set the scene item reference on a component. | ||||||
|  |        *  | ||||||
|  |        * @param component Component to check. | ||||||
|  |        */ | ||||||
|  |       void sceneItemComponentsReferenceSelf( | ||||||
|  |         std::shared_ptr<SceneComponent> component | ||||||
|  |       ); | ||||||
|  |  | ||||||
|     protected: |     protected: | ||||||
|       std::vector<std::shared_ptr<SceneComponent>> components; |       std::vector<std::shared_ptr<SceneComponent>> components; | ||||||
|  |  | ||||||
| @@ -40,9 +50,9 @@ namespace Dawn { | |||||||
|       std::shared_ptr<T> addComponent() { |       std::shared_ptr<T> addComponent() { | ||||||
|         //Create the component and add it. |         //Create the component and add it. | ||||||
|         std::shared_ptr<T> component = std::make_shared<T>(); |         std::shared_ptr<T> component = std::make_shared<T>(); | ||||||
|         this->components.push_back( |         auto asSceneComponent = static_pointer_cast<SceneComponent>(component); | ||||||
|           static_pointer_cast<SceneComponent>(component) |         this->sceneItemComponentsReferenceSelf(asSceneComponent); | ||||||
|         ); |         this->components.push_back(asSceneComponent); | ||||||
|         return component; |         return component; | ||||||
|       } |       } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -4,6 +4,7 @@ | |||||||
| // https://opensource.org/licenses/MIT | // https://opensource.org/licenses/MIT | ||||||
|  |  | ||||||
| #include "display/shader/ShaderData.hpp" | #include "display/shader/ShaderData.hpp" | ||||||
|  | #include "assert/assert.hpp" | ||||||
| #include "assert/assertgl.hpp" | #include "assert/assertgl.hpp" | ||||||
|  |  | ||||||
| using namespace Dawn; | using namespace Dawn; | ||||||
| @@ -13,6 +14,37 @@ ShaderData::ShaderData( | |||||||
| ) : IShaderData(structure) { | ) : IShaderData(structure) { | ||||||
|   glGenBuffers(1, &this->buffer); |   glGenBuffers(1, &this->buffer); | ||||||
|   assertNoGLError(); |   assertNoGLError(); | ||||||
|  |  | ||||||
|  |   // Quickly scan the structure for textures that we can bind to. | ||||||
|  |   int32_t nextTexture = 0; | ||||||
|  |   std::function<void(const std::shared_ptr<ShaderStructure>&)> | ||||||
|  |     recursivelyAppendTextures | ||||||
|  |   ; | ||||||
|  |   recursivelyAppendTextures = [&]( | ||||||
|  |     const std::shared_ptr<ShaderStructure> &structure | ||||||
|  |   ) { | ||||||
|  |     assertTrue( | ||||||
|  |       structure->type == ShaderStructureType::STRUCT, | ||||||
|  |       "Can only scan for texture indices in structures." | ||||||
|  |     ); | ||||||
|  |  | ||||||
|  |     for(auto &field : structure->members) { | ||||||
|  |       switch(field->type) { | ||||||
|  |         case ShaderStructureType::STRUCT: | ||||||
|  |           recursivelyAppendTextures(field); | ||||||
|  |           break; | ||||||
|  |          | ||||||
|  |         case ShaderStructureType::TEXTURE2D: | ||||||
|  |           this->textureIndices[field->getOffset()] = nextTexture++; | ||||||
|  |           break; | ||||||
|  |  | ||||||
|  |         default: | ||||||
|  |           break; | ||||||
|  |       } | ||||||
|  |     } | ||||||
|  |   }; | ||||||
|  |   recursivelyAppendTextures(structure); | ||||||
|  |  | ||||||
| } | } | ||||||
|  |  | ||||||
| void ShaderData::upload() { | void ShaderData::upload() { | ||||||
| @@ -20,19 +52,59 @@ void ShaderData::upload() { | |||||||
|  |  | ||||||
|   glBindBuffer(GL_UNIFORM_BUFFER, this->buffer); |   glBindBuffer(GL_UNIFORM_BUFFER, this->buffer); | ||||||
|   assertNoGLError(); |   assertNoGLError(); | ||||||
|   glBindBufferBase(GL_UNIFORM_BUFFER, 0, this->buffer); |   this->bind(); | ||||||
|   assertNoGLError(); |  | ||||||
|   glBufferData(GL_UNIFORM_BUFFER, this->structure->size, this->data, GL_STATIC_DRAW); |   glBufferData(GL_UNIFORM_BUFFER, this->structure->size, this->data, GL_STATIC_DRAW); | ||||||
|   assertNoGLError(); |   assertNoGLError(); | ||||||
|  |  | ||||||
|  |   for(auto &pair : this->textureBindings) { | ||||||
|  |     if(!pair.second) continue; | ||||||
|  |     pair.second->bind(pair.first); | ||||||
|  |     glUniform1i(pair.first, pair.first); | ||||||
|  |   } | ||||||
|  |    | ||||||
|   this->dirty = false; |   this->dirty = false; | ||||||
| } | } | ||||||
|  |  | ||||||
| void ShaderData::bind(const GLuint index) { | void ShaderData::bind() { | ||||||
|   glBindBufferBase(GL_UNIFORM_BUFFER, index, this->buffer); |   glBindBufferBase(GL_UNIFORM_BUFFER, 0, this->buffer); | ||||||
|   assertNoGLError(); |   assertNoGLError(); | ||||||
| } | } | ||||||
|  |  | ||||||
|  | template<> | ||||||
|  | std::shared_ptr<Texture> IShaderData::get<std::shared_ptr<Texture>>( | ||||||
|  |   const size_t offset | ||||||
|  | ) { | ||||||
|  |   ShaderData *self = (ShaderData *)this; | ||||||
|  |   auto map = self->textureIndices.find(offset); | ||||||
|  |   assertTrue( | ||||||
|  |     map != self->textureIndices.end(), | ||||||
|  |     "Texture is not found in the structure or the offset is incorrect." | ||||||
|  |   ); | ||||||
|  |  | ||||||
|  |   auto index = map->second; | ||||||
|  |   return self->textureBindings[index]; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | template<> | ||||||
|  | void IShaderData::set<std::shared_ptr<Texture>>( | ||||||
|  |   const size_t offset, const std::shared_ptr<Texture> value | ||||||
|  | ) { | ||||||
|  |   ShaderData *self = (ShaderData *)this; | ||||||
|  |   auto map = self->textureIndices.find(offset); | ||||||
|  |   assertTrue( | ||||||
|  |     map != self->textureIndices.end(), | ||||||
|  |     "Texture is not found in the structure or the offset is incorrect." | ||||||
|  |   ); | ||||||
|  |  | ||||||
|  |   // I didn't implement it, but in theory we can check if the texture is | ||||||
|  |   // already bound to an index and reuse its existing index to avoid | ||||||
|  |   // binding a texture twice if we don't need to, however this would | ||||||
|  |   // require all bindings be flushed and re-bound each frame. | ||||||
|  |   auto index = map->second; | ||||||
|  |   self->textureBindings[map->second] = value;// Releases textures too. | ||||||
|  |   if(value) this->dirty = true; | ||||||
|  | } | ||||||
|  |  | ||||||
| ShaderData::~ShaderData() { | ShaderData::~ShaderData() { | ||||||
|   if(this->buffer != -1) { |   if(this->buffer != -1) { | ||||||
|     glDeleteBuffers(1, &this->buffer); |     glDeleteBuffers(1, &this->buffer); | ||||||
|   | |||||||
| @@ -13,11 +13,16 @@ namespace Dawn { | |||||||
|       GLuint buffer = -1; |       GLuint buffer = -1; | ||||||
|  |  | ||||||
|     public: |     public: | ||||||
|  |       std::unordered_map<size_t, uint8_t> textureIndices; | ||||||
|  |       std::unordered_map<uint8_t, std::shared_ptr<Texture>> textureBindings; | ||||||
|  |  | ||||||
|       ShaderData( |       ShaderData( | ||||||
|         const std::shared_ptr<ShaderStructure> &structure |         const std::shared_ptr<ShaderStructure> &structure | ||||||
|       ); |       ); | ||||||
|       void upload(); |  | ||||||
|       void bind(const GLuint index); |       void upload() override; | ||||||
|  |       void bind() override; | ||||||
|  |        | ||||||
|       ~ShaderData() override; |       ~ShaderData() override; | ||||||
|   }; |   }; | ||||||
| } | } | ||||||
| @@ -7,20 +7,9 @@ | |||||||
| #include "assert/assert.hpp" | #include "assert/assert.hpp" | ||||||
| #include "assert/assertgl.hpp" | #include "assert/assertgl.hpp" | ||||||
| #include "display/shader/ShaderData.hpp" | #include "display/shader/ShaderData.hpp" | ||||||
| #include "component/display/material/SimpleTexturedMaterial.hpp" |  | ||||||
|  |  | ||||||
| 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( | ||||||
|   IModule *module, |   IModule *module, | ||||||
|   Slang::ComPtr<ISession> session |   Slang::ComPtr<ISession> session | ||||||
| @@ -57,73 +46,11 @@ void ShaderProgram::init( | |||||||
|     assertNoGLError(); |     assertNoGLError(); | ||||||
|     assertUnreachable("Failed to link shader program:\n%s", log); |     assertUnreachable("Failed to link shader program:\n%s", log); | ||||||
|   } |   } | ||||||
|  | } | ||||||
|  |  | ||||||
|   // So the uniforms that are in slang are kinda odd when compiled. | void ShaderProgram::bind() { | ||||||
|   glUseProgram(this->id); |   glUseProgram(this->id); | ||||||
|   assertNoGLError(); |   assertNoGLError(); | ||||||
|  |  | ||||||
|   data = this->structure->createData(); |  | ||||||
|  |  | ||||||
|   size_t offset = 0; |  | ||||||
|   data->set<glm::mat4>(offset, glm::perspective( |  | ||||||
|     glm::radians(45.0f), 800.0f / 600.0f, 0.1f, 10000.0f |  | ||||||
|   )); |  | ||||||
|   offset += sizeof(glm::mat4); |  | ||||||
|  |  | ||||||
|   data->set<glm::mat4>(offset, glm::lookAt( |  | ||||||
|     glm::vec3(300,300,300), glm::vec3(0,0,0), glm::vec3(0,1,0) |  | ||||||
|   )); |  | ||||||
|   offset += sizeof(glm::mat4); |  | ||||||
|  |  | ||||||
|   data->set<glm::mat4>(offset, glm::mat4(1.0f)); |  | ||||||
|   offset += sizeof(glm::mat4); |  | ||||||
|  |  | ||||||
|   data->set<struct Color>(offset, COLOR_WHITE); |  | ||||||
|   offset += sizeof(glm::vec4); |  | ||||||
|  |  | ||||||
|   data->set<bool_t>(offset, true); |  | ||||||
|   offset += sizeof(bool_t); |  | ||||||
|  |  | ||||||
|   data->upload(); |  | ||||||
|   data->bind(0); |  | ||||||
|  |  | ||||||
|  |  | ||||||
|   // struct TestData data; |  | ||||||
|   // data.color = COLOR_WHITE; |  | ||||||
|   // data.model = glm::mat4(1.0f); |  | ||||||
|   // data.projection = glm::perspective( |  | ||||||
|   //   glm::radians(45.0f), 800.0f / 600.0f, 0.1f, 10000.0f |  | ||||||
|   // ); |  | ||||||
|   // data.view = glm::lookAt( |  | ||||||
|   //   glm::vec3(300,300,300), glm::vec3(0,0,0), glm::vec3(0,1,0) |  | ||||||
|   // ); |  | ||||||
|   // 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] = 255; 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() { | ||||||
|   | |||||||
| @@ -27,7 +27,10 @@ namespace Dawn { | |||||||
|       void init( |       void init( | ||||||
|         IModule *module, |         IModule *module, | ||||||
|         Slang::ComPtr<ISession> session |         Slang::ComPtr<ISession> session | ||||||
|       ); |       ) override; | ||||||
|  |  | ||||||
|  |       void bind() override; | ||||||
|  |  | ||||||
|       ~ShaderProgram() override; |       ~ShaderProgram() override; | ||||||
|   }; |   }; | ||||||
| } | } | ||||||
		Reference in New Issue
	
	Block a user