/** * Application specific vertex objects. */ #pragma once #include "common.hpp" #include #include #include #include namespace render { /// Vertex properties struct VertexData { VertexData(const glm::vec3 &position, glm::u16 material, const glm::vec3 &normal): Position(position), Material(material), Normal(normal) { } glm::vec3 Position; glm::u16 Material; glm::vec3 Normal; }; /// Quantized vertex properties struct PackedVertexData { PackedVertexData(glm::u16 x, glm::u16 y, glm::u16 z, glm::u16 mat, glm::u16 nx, glm::u16 ny, glm::u16 nz, glm::u16 nw = 0) { PosMat[0] = x; PosMat[1] = y; PosMat[2] = z; PosMat[3] = mat; Nrm[0] = nx; Nrm[1] = ny; Nrm[2] = nz; Nrm[3] = nw; } glm::u16 PosMat[4]; glm::u16 Nrm[4]; //NOTE: Triplanar does not handle 10_10_10_2_REV bool operator<(const PackedVertexData that) const { return memcmp((void *)this, (void *)&that, sizeof(PackedVertexData)) > 0; }; }; /// Position only buffer class Shape { public: virtual ~Shape() { } static const std::vector SKY_CUBE; }; /// Color lines model class Indicator { public: virtual ~Indicator() { } static const std::pair, std::vector> CUBE; }; /// VertexData model with index class Model { public: virtual ~Model() { } /// Preindexed buffer data struct Data { std::vector indices; std::vector vertices; Data() { } Data(const std::vector &vertices, const std::vector &indices); Data(const std::vector &vertices) { index(vertices); } Data(std::ifstream &in); void index(const std::vector &vertices); bool empty() const { return indices.empty(); } void clear() { indices.clear(); vertices.clear(); } void serialize(std::ofstream &out); }; static _FORCE_INLINE_ std::unique_ptr Create(const Data& data) { assert(createFunc != nullptr && "Uninitialized renderer"); return createFunc(data); } protected: static std::unique_ptr (*createFunc)(const Data&); }; /// VertexData model with Level Of Detail indices class LodModel { public: virtual ~LodModel() { } using LodData = std::pair>; static _FORCE_INLINE_ std::unique_ptr Create(const LodData& data) { assert(createFunc != nullptr && "Uninitialized renderer"); return createFunc(data); } void inline setLevel(size_t l) { level = l; } protected: size_t level = 0; size_t indexSize; std::vector offsets; constexpr inline size_t getOffset(size_t level) const { return level <= 0 ? 0 : (level-1 < offsets.size() ? offsets[level-1] : indexSize); } static std::unique_ptr (*createFunc)(const LodData&); }; }