spacebox/src/Model.cpp

198 lines
6.1 KiB
C++

/* +------------------------------------------------------+
____/ \____ /| - Open source game framework licensed to freely use, |
\ / / | copy, modify and sell without restriction |
+--\ ^__^ /--+ | |
| ~/ \~ | | - created for <https://foam.shampoo.ooo> |
| ~~~~~~~~~~~~ | +------------------------------------------------------+
| SPACE ~~~~~ | /
| ~~~~~~~ BOX |/
+-------------*/
#include "Model.hpp"
/* Default constructor for Model */
sb::Model::Model() {};
/* Construct a Model, adding Attributes each already wrapped in a shared pointer. The attributes should
* be passed as a map with each key being a name and each value being a shared pointer to attributes. */
sb::Model::Model(const std::map<std::string, std::shared_ptr<sb::Attributes>>& attributes_pack)
{
for (auto attributes : attributes_pack)
{
this->attributes(attributes.second, attributes.first);
}
}
/* Construct a Model, adding Attributes, which will each be wrapped in a shared pointer and stored in the
* created object. The attributes should be passed as a map with each key being a name and each value being
* an attributes object. */
sb::Model::Model(const std::map<std::string, sb::Attributes>& attributes_pack)
{
for (auto attributes : attributes_pack)
{
this->attributes(attributes.second, attributes.first);
}
}
/* Construct a new model object by passing a list of names which will be used to initialize
* empty attributes objects with the given names */
sb::Model::Model(const std::initializer_list<std::string>& names)
{
for (const std::string& name : names)
{
this->attributes(sb::Attributes(), name);
}
}
/* Get the entire map of attributes, each wrapped in its shared pointer held by this object.
* Can be used to iterate through the attributes. */
std::map<std::string, std::shared_ptr<sb::Attributes>>& sb::Model::attributes()
{
return model_attributes;
}
/* Get the attributes under name, wrapped in the shared pointer held by this object. This
* function uses the at method of std::map, so name must refer to attributes already
* stored in this model. Use this function to share ownership of the attributes or to gain
* access to the public interface of the attributes. */
std::shared_ptr<sb::Attributes>& sb::Model::attributes(const std::string& name)
{
return attributes().at(name);
}
/* Get the attributes under name, wrapped in the shared pointer held by this object. This
* function uses operator[] or std::map, so this can be used to add new attributes to the
* object if they are wrapped in a shared pointer. */
std::shared_ptr<sb::Attributes>& sb::Model::operator[](const std::string& name)
{
auto element = attributes().find(name);
/* add an empty Attributes at name if it doesn't exist yet */
if (element == attributes().end())
{
attributes(sb::Attributes{}, name);
}
return attributes()[name];
}
/* Assign name to attributes, copy and wrap in a shared pointer. The model can share
* ownership of the created attribute memory with callers that request it. */
void sb::Model::attributes(const sb::Attributes& attributes, const std::string& name)
{
this->attributes(std::make_shared<sb::Attributes>(attributes), name);
}
/* Assign name to attributes and share ownership. */
void sb::Model::attributes(const std::shared_ptr<sb::Attributes>& attributes, const std::string& name)
{
this->attributes()[name] = attributes;
}
/* Enable all attributes. */
void sb::Model::enable()
{
for (const auto& attributes : this->attributes())
{
attributes.second->enable();
}
}
/* Disable all attributes. */
void sb::Model::disable()
{
for (const auto& attributes : this->attributes())
{
attributes.second->disable();
}
}
/* Return a reference to the texture container. */
std::map<std::string, sb::Texture>& sb::Model::textures()
{
return model_textures;
}
/* Get the texture at name. This can be used to read the texture memory, share ownership of it, or
* anything else a Texture object can be used for with direct calls to GL functions. */
sb::Texture& sb::Model::texture(const std::string& name)
{
return textures().at(name);
}
/* Get the default texture. The default texture must have previously been set with the default key as
* the name, which can be done using sb::Model::texture(sb::Texture). */
sb::Texture& sb::Model::texture()
{
return texture(DEFAULT_TEXTURE_NAME);
}
/* Assign name to texture and share ownership. */
void sb::Model::texture(const sb::Texture& texture, const std::string& name)
{
textures()[name] = texture;
}
/* If no name is specified, use the default texture. This can be used to conveniently setup a model
* with only one texture. */
void sb::Model::texture(const sb::Texture& texture)
{
this->texture(texture, DEFAULT_TEXTURE_NAME);
}
/* Get the model's transformation matrix. */
const glm::mat4& sb::Model::transformation() const
{
return model_transformation;
}
/* Set the model's transformation matrix. */
void sb::Model::transformation(const glm::mat4& transformation)
{
model_transformation = transformation;
}
/* Return the size in bytes of the sum of the attributes. */
std::size_t sb::Model::size()
{
std::size_t sum = 0;
for (const auto& attributes : this->attributes())
{
sum += attributes.second->size();
}
return sum;
}
/* Return the transformation matrix. */
sb::Model::operator glm::mat4() const
{
return model_transformation;
}
sb::PlaneDoubleBuffer::PlaneDoubleBuffer() : Plane()
{
texture(sb::Texture(), "front");
texture(sb::Texture(), "back");
}
void sb::PlaneDoubleBuffer::generate(const glm::vec2& size)
{
for (sb::Texture* buffer : {&texture("front"), &texture("back")})
{
buffer->generate(size);
}
}
sb::Texture& sb::PlaneDoubleBuffer::active()
{
return swapped ? texture("back") : texture("front");
}
sb::Texture& sb::PlaneDoubleBuffer::inactive()
{
return swapped ? texture("front") : texture("back");
}
void sb::PlaneDoubleBuffer::swap()
{
swapped = !swapped;
}