|
|
- /*
- * Copyright (C) 2021 Christopher J. Howard
- *
- * This file is part of Antkeeper source code.
- *
- * Antkeeper source code is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * Antkeeper source code is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Antkeeper source code. If not, see <http://www.gnu.org/licenses/>.
- */
-
- #ifndef ANTKEEPER_MATERIAL_HPP
- #define ANTKEEPER_MATERIAL_HPP
-
- #include "renderer/material-property.hpp"
- #include "gl/shader-program.hpp"
- #include <cstdint>
- #include <cstddef>
- #include <list>
- #include <map>
- #include <string>
-
- /**
- * A material is associated with exactly one shader program and contains a set of material properties which can be uploaded to that shader program via shader inputs.
- */
- class material
- {
- public:
- /**
- * Creates a material.
- *
- * @param program Shader program with which to associate this material.
- */
- explicit material(gl::shader_program* program);
-
- /**
- * Creates a material.
- */
- material();
-
- /**
- * Creates a copy of another material.
- *
- * @param other Material to copy.
- */
- material(const material& other);
-
- /**
- * Destroys a material.
- */
- ~material();
-
- /**
- * Makes this material a copy of aother material.
- *
- * @param other Material to copy.
- * @return Reference to this material.
- */
- material& operator=(const material& other);
-
- /**
- * Sets state 0 = state 1 for each material property tween.
- */
- void update_tweens();
-
- /**
- * Uploads each material property to the material's shader program.
- *
- * @param a Interpolation factor. Should be on `[0.0, 1.0]`.
- * @return Number of material property uploads which failed.
- */
- std::size_t upload(double a) const;
-
- /**
- * Sets the material's shader program and reconnects all shader properties to their corresponding shader inputs.
- *
- * @param program Shader program with which to associate the material.
- */
- void set_shader_program(gl::shader_program* program);
-
- /**
- * Sets the material flags.
- *
- * @param flags Material flags.
- */
- void set_flags(std::uint32_t flags);
-
- /**
- * Adds a material array property to the material.
- *
- * @param name Name of the material array property.
- * @param element_count Number of elements in the array.
- * @return Pointer to the added material property.
- */
- template <typename T>
- material_property<T>* add_property(const std::string& name, std::size_t element_count = 1);
-
- /**
- * Returns the shader program with which this material is associated.
- */
- gl::shader_program* get_shader_program() const;
-
- /**
- * Returns the material flags.
- */
- std::uint32_t get_flags() const;
-
- /**
- * Returns the material property with the specified name, or `nullptr` if the material could not be found.
- */
- material_property_base* get_property(const std::string& name) const;
-
- /**
- * Returns a list of all material properties in the material.
- */
- const std::list<material_property_base*>* get_properties() const;
-
- private:
- /**
- * Attempts to reconnect all material properties to their corresponding shader inputs.
- *
- * @return Number of disconnected properties.
- */
- std::size_t reconnect_properties();
-
- gl::shader_program* program;
- std::uint32_t flags;
- std::list<material_property_base*> properties;
- std::map<std::string, material_property_base*> property_map;
- };
-
- template <typename T>
- material_property<T>* material::add_property(const std::string& name, std::size_t element_count)
- {
- // Allocate property
- material_property<T>* property = new material_property<T>(element_count);
-
- // Add to property list and map
- properties.push_back(property);
- property_map[name] = property;
-
- // Attempt to connect property to its corresponding shader input
- if (program)
- {
- property->connect(program->get_input(name));
- }
-
- return property;
- }
-
- inline gl::shader_program* material::get_shader_program() const
- {
- return program;
- }
-
- inline std::uint32_t material::get_flags() const
- {
- return flags;
- }
-
- inline material_property_base* material::get_property(const std::string& name) const
- {
- if (auto it = property_map.find(name); it != property_map.end())
- {
- return it->second;
- }
-
- return nullptr;
- }
-
- inline const std::list<material_property_base*>* material::get_properties() const
- {
- return &properties;
- }
-
- #endif // ANTKEEPER_MATERIAL_HPP
-
|