// Copyright (c) 2023 Dominic Masters // // This software is released under the MIT License. // https://opensource.org/licenses/MIT #pragma ocne #include "display/shader/ShaderParameter.hpp" namespace Dawn { enum class ShaderOpenGLStructureType { STD140 }; struct IShaderStructure { std::string structureName; size_t offset; enum ShaderOpenGLStructureType structureType; size_t size; size_t count; std::vector parameters; GLint location = -1; GLuint buffer = -1; }; template struct ShaderStructure final : public IShaderStructure { public: /** * Constructs a new shader structure. Shader structures allow for larger * amounts/volumes of data to be passed to the shader in a single call. * Ideally I wouldn't really need this as I wanted the entire shader to * basically be a single large structure, but OpenGL doesn't support that * so I have to do this instead. * * @param structureName Structure name within the shader. * @param offset Offset, within the data structure, that this structure * starts at. * @param structureType The type of structure data format to use. * @param getParameters A callback that, when invoked, will populate the * parameters vector with the parameters for this * structure. * @param count The number of structures to create. */ ShaderStructure( const std::string &structureName, const void *offset, const enum ShaderOpenGLStructureType structureType, std::function< void(const T&, std::vector&) > getParameters, size_t count = 1 ) { this->structureName = structureName; this->offset = (size_t)offset; this->structureType = structureType; this->size = sizeof(T); this->count = count; this->parameters = std::vector(); T dummy; getParameters(dummy, this->parameters); // Update offsets. auto itParams = this->parameters.begin(); while(itParams != this->parameters.end()) { struct ShaderParameter ¶m = *itParams; param.offset -= (size_t)(&dummy); // Check for non-aligned OpenGL structures. if(param.offset % sizeof(glm::vec4) != 0) { assertUnreachable( "%s%s%s", "Non-aligned OpenGL structure detected on param ", param.name.c_str(), "!\nEnsure you have padded correctly." ); } if( itParams == (this->parameters.end() - 1) && count > 1 && (sizeof(T) % sizeof(glm::vec4)) != 0 ) { assertUnreachable( "%s%s%s", "Non-aligned OpenGL structure detected on last element in array structure on param ", param.name.c_str(), "!\nEnsure you have padded correctly." ); } ++itParams; } } }; }