diff --git a/src/ObjLoading/Techset/Parsing/TechniqueFileParser.cpp b/src/ObjLoading/Techset/Parsing/TechniqueFileParser.cpp new file mode 100644 index 00000000..16d41cc1 --- /dev/null +++ b/src/ObjLoading/Techset/Parsing/TechniqueFileParser.cpp @@ -0,0 +1,17 @@ +#include "TechniqueFileParser.h" + +using namespace techset; + +TechniqueParser::TechniqueParser(SimpleLexer* lexer, ITechniqueDefinitionAcceptor* acceptor) + : AbstractParser(lexer, std::make_unique(acceptor)) +{ +} + +const std::vector::sequence_t*>& TechniqueParser::GetTestsForState() +{ + // TODO: Tests + static std::vector tests({ + }); + + return tests; +} diff --git a/src/ObjLoading/Techset/Parsing/TechniqueFileParser.h b/src/ObjLoading/Techset/Parsing/TechniqueFileParser.h new file mode 100644 index 00000000..81570d13 --- /dev/null +++ b/src/ObjLoading/Techset/Parsing/TechniqueFileParser.h @@ -0,0 +1,18 @@ +#pragma once + +#include "TechniqueFileParserState.h" +#include "Parsing/Simple/SimpleLexer.h" +#include "Parsing/Simple/SimpleParserValue.h" +#include "Parsing/Impl/AbstractParser.h" + +namespace techset +{ + class TechniqueParser final : public AbstractParser + { + protected: + const std::vector& GetTestsForState() override; + + public: + TechniqueParser(SimpleLexer* lexer, ITechniqueDefinitionAcceptor* acceptor); + }; +} diff --git a/src/ObjLoading/Techset/Parsing/TechniqueFileParserState.cpp b/src/ObjLoading/Techset/Parsing/TechniqueFileParserState.cpp new file mode 100644 index 00000000..c146c108 --- /dev/null +++ b/src/ObjLoading/Techset/Parsing/TechniqueFileParserState.cpp @@ -0,0 +1,11 @@ +#include "TechniqueFileParserState.h" + +#include + +using namespace techset; + +TechniqueParserState::TechniqueParserState(ITechniqueDefinitionAcceptor* acceptor) + : m_acceptor(acceptor) +{ + assert(acceptor); +} diff --git a/src/ObjLoading/Techset/Parsing/TechniqueFileParserState.h b/src/ObjLoading/Techset/Parsing/TechniqueFileParserState.h new file mode 100644 index 00000000..3d688ea9 --- /dev/null +++ b/src/ObjLoading/Techset/Parsing/TechniqueFileParserState.h @@ -0,0 +1,14 @@ +#pragma once + +#include "Techset/TechniqueDefinitionAcceptor.h" + +namespace techset +{ + class TechniqueParserState + { + public: + ITechniqueDefinitionAcceptor* const m_acceptor; + + explicit TechniqueParserState(ITechniqueDefinitionAcceptor* acceptor); + }; +} diff --git a/src/ObjLoading/Techset/TechniqueDefinition.cpp b/src/ObjLoading/Techset/TechniqueDefinition.cpp new file mode 100644 index 00000000..6d6351c9 --- /dev/null +++ b/src/ObjLoading/Techset/TechniqueDefinition.cpp @@ -0,0 +1,54 @@ +#include "TechniqueDefinition.h" + +using namespace techset; + +ShaderArgumentLiteralConstant::ShaderArgumentLiteralConstant() + : m_value{} +{ +} + +ShaderArgumentLiteralConstant::ShaderArgumentLiteralConstant(const float v0, const float v1, const float v2, const float v3) + : m_value{v0, v1, v2, v3} +{ +} + +ShaderArgumentLiteralConstant::ShaderArgumentLiteralConstant(float value[4]) + : m_value{value[0], value[1], value[2], value[3]} +{ +} + +bool techset::operator<(const ShaderArgumentLiteralConstant& lhs, const ShaderArgumentLiteralConstant& rhs) +{ + if (lhs.m_value[0] < rhs.m_value[0]) + return true; + if (lhs.m_value[0] > rhs.m_value[0]) + return false; + if (lhs.m_value[1] < rhs.m_value[1]) + return true; + if (lhs.m_value[1] > rhs.m_value[1]) + return false; + if (lhs.m_value[2] < rhs.m_value[2]) + return true; + if (lhs.m_value[2] > rhs.m_value[2]) + return false; + if (lhs.m_value[3] < rhs.m_value[3]) + return true; + if (lhs.m_value[3] > rhs.m_value[3]) + return false; + return false; +} + +bool techset::operator<=(const ShaderArgumentLiteralConstant& lhs, const ShaderArgumentLiteralConstant& rhs) +{ + return !(rhs < lhs); +} + +bool techset::operator>(const ShaderArgumentLiteralConstant& lhs, const ShaderArgumentLiteralConstant& rhs) +{ + return rhs < lhs; +} + +bool techset::operator>=(const ShaderArgumentLiteralConstant& lhs, const ShaderArgumentLiteralConstant& rhs) +{ + return !(lhs < rhs); +} diff --git a/src/ObjLoading/Techset/TechniqueDefinition.h b/src/ObjLoading/Techset/TechniqueDefinition.h new file mode 100644 index 00000000..3be432e1 --- /dev/null +++ b/src/ObjLoading/Techset/TechniqueDefinition.h @@ -0,0 +1,70 @@ +#pragma once + +#include +#include +#include + +namespace techset +{ + enum class ShaderArgumentType + { + CODE_CONSTANT, + LITERAL_CONSTANT, + MATERIAL_CONSTANT + }; + + class ShaderArgumentLiteralConstant + { + public: + float m_value[4]; + + ShaderArgumentLiteralConstant(); + ShaderArgumentLiteralConstant(float v0, float v1, float v2, float v3); + explicit ShaderArgumentLiteralConstant(float value[4]); + + friend bool operator<(const ShaderArgumentLiteralConstant& lhs, const ShaderArgumentLiteralConstant& rhs); + friend bool operator<=(const ShaderArgumentLiteralConstant& lhs, const ShaderArgumentLiteralConstant& rhs); + friend bool operator>(const ShaderArgumentLiteralConstant& lhs, const ShaderArgumentLiteralConstant& rhs); + friend bool operator>=(const ShaderArgumentLiteralConstant& lhs, const ShaderArgumentLiteralConstant& rhs); + }; + + class ShaderArgumentDefinition + { + public: + ShaderArgumentType m_type; + std::string m_shader_argument_name; + size_t m_shader_argument_index; + + std::vector m_code_constant_accessors; + + ShaderArgumentLiteralConstant m_literal_constant; + + bool m_material_constant_is_hash; + size_t m_material_constant_hash; + std::string m_material_constant_name; + }; + + class ShaderDefinition + { + public: + size_t m_version_major; + size_t m_version_minor; + std::string m_shader_name; + std::vector m_arguments; + }; + + class VertexStreamRoutingDefinition + { + std::string m_destination_name; + std::string m_source_name; + }; + + class TechniqueDefinition + { + public: + std::string m_state_map; + std::unique_ptr m_vertex_shader; + std::unique_ptr m_pixel_shader; + std::vector m_vertex_stream_routing; + }; +} diff --git a/src/ObjLoading/Techset/TechniqueDefinitionAcceptor.cpp b/src/ObjLoading/Techset/TechniqueDefinitionAcceptor.cpp new file mode 100644 index 00000000..ae209e17 --- /dev/null +++ b/src/ObjLoading/Techset/TechniqueDefinitionAcceptor.cpp @@ -0,0 +1,104 @@ +#include "TechniqueDefinitionAcceptor.h" + +using namespace techset; + +ShaderArgument::ShaderArgument() + : m_argument_index(0u) +{ +} + +ShaderArgument::ShaderArgument(std::string argumentName, const size_t argumentIndex) + : m_argument_name(std::move(argumentName)), + m_argument_index(argumentIndex) +{ +} + +ShaderArgumentCodeSource::ShaderArgumentCodeSource() + : m_index_accessor_specified(false), + m_index_accessor(0u) +{ +} + +ShaderArgumentCodeSource::ShaderArgumentCodeSource(std::vector accessors) + : m_accessors(std::move(accessors)), + m_index_accessor_specified(false), + m_index_accessor(0u) +{ +} + +ShaderArgumentCodeSource::ShaderArgumentCodeSource(std::vector accessors, const size_t indexAccessor) + : m_accessors(std::move(accessors)), + m_index_accessor_specified(true), + m_index_accessor(indexAccessor) +{ +} + +ShaderArgumentLiteralSource::ShaderArgumentLiteralSource() + : m_value{} +{ +} + +ShaderArgumentLiteralSource::ShaderArgumentLiteralSource(const float v0, const float v1, const float v2, const float v3) + : m_value{v0, v1, v2, v3} +{ +} + +ShaderArgumentLiteralSource::ShaderArgumentLiteralSource(float value[4]) + : m_value{value[0], value[1], value[2], value[3]} +{ +} + +bool techset::operator<(const ShaderArgumentLiteralSource& lhs, const ShaderArgumentLiteralSource& rhs) +{ + if (lhs.m_value[0] < rhs.m_value[0]) + return true; + if (lhs.m_value[0] > rhs.m_value[0]) + return false; + if (lhs.m_value[1] < rhs.m_value[1]) + return true; + if (lhs.m_value[1] > rhs.m_value[1]) + return false; + if (lhs.m_value[2] < rhs.m_value[2]) + return true; + if (lhs.m_value[2] > rhs.m_value[2]) + return false; + if (lhs.m_value[3] < rhs.m_value[3]) + return true; + if (lhs.m_value[3] > rhs.m_value[3]) + return false; + return false; +} + +bool techset::operator<=(const ShaderArgumentLiteralSource& lhs, const ShaderArgumentLiteralSource& rhs) +{ + return !(rhs < lhs); +} + +bool techset::operator>(const ShaderArgumentLiteralSource& lhs, const ShaderArgumentLiteralSource& rhs) +{ + return rhs < lhs; +} + +bool techset::operator>=(const ShaderArgumentLiteralSource& lhs, const ShaderArgumentLiteralSource& rhs) +{ + return !(lhs < rhs); +} + +ShaderArgumentMaterialSource::ShaderArgumentMaterialSource() + : m_is_hash(false), + m_hash(0u) +{ +} + +ShaderArgumentMaterialSource::ShaderArgumentMaterialSource(const size_t hash) + : m_is_hash(true), + m_hash(hash) +{ +} + +ShaderArgumentMaterialSource::ShaderArgumentMaterialSource(std::string name) + : m_is_hash(false), + m_hash(0u), + m_name(std::move(name)) +{ +} diff --git a/src/ObjLoading/Techset/TechniqueDefinitionAcceptor.h b/src/ObjLoading/Techset/TechniqueDefinitionAcceptor.h new file mode 100644 index 00000000..4545bad1 --- /dev/null +++ b/src/ObjLoading/Techset/TechniqueDefinitionAcceptor.h @@ -0,0 +1,84 @@ +#pragma once +#include +#include + +namespace techset +{ + enum class ShaderSelector + { + VERTEX_SHADER, + PIXEL_SHADER + }; + + class ShaderArgument + { + public: + std::string m_argument_name; + size_t m_argument_index; + + ShaderArgument(); + ShaderArgument(std::string argumentName, size_t argumentIndex); + }; + + class ShaderArgumentCodeSource + { + public: + std::vector m_accessors; + bool m_index_accessor_specified; + size_t m_index_accessor; + + ShaderArgumentCodeSource(); + explicit ShaderArgumentCodeSource(std::vector accessors); + ShaderArgumentCodeSource(std::vector accessors, size_t indexAccessor); + }; + + class ShaderArgumentLiteralSource + { + public: + float m_value[4]; + + ShaderArgumentLiteralSource(); + ShaderArgumentLiteralSource(float v0, float v1, float v2, float v3); + explicit ShaderArgumentLiteralSource(float value[4]); + + friend bool operator<(const ShaderArgumentLiteralSource& lhs, const ShaderArgumentLiteralSource& rhs); + friend bool operator<=(const ShaderArgumentLiteralSource& lhs, const ShaderArgumentLiteralSource& rhs); + friend bool operator>(const ShaderArgumentLiteralSource& lhs, const ShaderArgumentLiteralSource& rhs); + friend bool operator>=(const ShaderArgumentLiteralSource& lhs, const ShaderArgumentLiteralSource& rhs); + }; + + class ShaderArgumentMaterialSource + { + public: + bool m_is_hash; + size_t m_hash; + std::string m_name; + + ShaderArgumentMaterialSource(); + explicit ShaderArgumentMaterialSource(size_t hash); + explicit ShaderArgumentMaterialSource(std::string name); + }; + + class ITechniqueDefinitionAcceptor + { + protected: + ITechniqueDefinitionAcceptor() = default; + public: + virtual ~ITechniqueDefinitionAcceptor() = default; + ITechniqueDefinitionAcceptor(const ITechniqueDefinitionAcceptor& other) = default; + ITechniqueDefinitionAcceptor(ITechniqueDefinitionAcceptor&& other) noexcept = default; + ITechniqueDefinitionAcceptor& operator=(const ITechniqueDefinitionAcceptor& other) = default; + ITechniqueDefinitionAcceptor& operator=(ITechniqueDefinitionAcceptor&& other) noexcept = default; + + virtual void AcceptStateMap(const std::string& stateMapName) = 0; + + virtual bool AcceptVertexShader(size_t shaderVersionMajor, size_t shaderVersionMinor, const std::string& vertexShaderName, std::string& errorMessage) = 0; + virtual bool AcceptPixelShader(size_t shaderVersionMajor, size_t shaderVersionMinor, const std::string& vertexShaderName, std::string& errorMessage) = 0; + + virtual bool AcceptShaderCodeArgument(ShaderSelector shader, ShaderArgument shaderArgument, ShaderArgumentCodeSource source, std::string& errorMessage) = 0; + virtual bool AcceptShaderLiteralArgument(ShaderSelector shader, ShaderArgument shaderArgument, ShaderArgumentLiteralSource source, std::string& errorMessage) = 0; + virtual bool AcceptShaderMaterialArgument(ShaderSelector shader, ShaderArgument shaderArgument, ShaderArgumentMaterialSource source, std::string& errorMessage) = 0; + + virtual bool AcceptVertexStreamRouting(const std::string& destination, const std::string& source, std::string& errorMessage) = 0; + }; +} diff --git a/src/ObjLoading/Techset/TechniqueFileReader.cpp b/src/ObjLoading/Techset/TechniqueFileReader.cpp new file mode 100644 index 00000000..3ced3da0 --- /dev/null +++ b/src/ObjLoading/Techset/TechniqueFileReader.cpp @@ -0,0 +1,36 @@ +#include "TechniqueFileReader.h" + +#include + +#include "Parsing/TechniqueFileParser.h" +#include "Parsing/Impl/CommentRemovingStreamProxy.h" +#include "Parsing/Impl/ParserSingleInputStream.h" +#include "Parsing/Simple/SimpleLexer.h" + +using namespace techset; + +TechniqueFileReader::TechniqueFileReader(std::istream& stream, std::string fileName, ITechniqueDefinitionAcceptor* acceptor) + : m_file_name(std::move(fileName)), + m_acceptor(acceptor) +{ + m_base_stream = std::make_unique(stream, m_file_name); + m_comment_proxy = std::make_unique(m_base_stream.get()); +} + +bool TechniqueFileReader::ReadTechniqueDefinition() const +{ + SimpleLexer::Config lexerConfig; + lexerConfig.m_emit_new_line_tokens = false; + lexerConfig.m_read_strings = true; + lexerConfig.m_read_numbers = true; + const auto lexer = std::make_unique(m_comment_proxy.get(), std::move(lexerConfig)); + + const auto parser = std::make_unique(lexer.get(), m_acceptor); + + const auto success = parser->Parse(); + if (success) + return true; + + std::cout << "Parsing technique file \"" << m_file_name << "\" failed!\n"; + return false; +} diff --git a/src/ObjLoading/Techset/TechniqueFileReader.h b/src/ObjLoading/Techset/TechniqueFileReader.h new file mode 100644 index 00000000..f508ea49 --- /dev/null +++ b/src/ObjLoading/Techset/TechniqueFileReader.h @@ -0,0 +1,24 @@ +#pragma once + +#include +#include + +#include "Utils/ClassUtils.h" +#include "TechniqueDefinitionAcceptor.h" +#include "Parsing/IParserLineStream.h" + +namespace techset +{ + class TechniqueFileReader + { + std::string m_file_name; + ITechniqueDefinitionAcceptor* m_acceptor; + std::unique_ptr m_base_stream; + std::unique_ptr m_comment_proxy; + + public: + TechniqueFileReader(std::istream& stream, std::string fileName, ITechniqueDefinitionAcceptor* acceptor); + + _NODISCARD bool ReadTechniqueDefinition() const; + }; +} \ No newline at end of file