f085ab64 |
/// Guards
#ifndef GLOBJECT_HPP_
#define GLOBJECT_HPP_
/// Includes
#include <string>
#include <glbase.hpp>
#include <gltraits.hpp>
/// GLObject
template<GLenum object_type>
class GLObject;
template<>
class GLObject<0> : protected GLBase
{
protected:
//// Object
std::string static label_(
GLenum object_type,
GLuint object
);
void static label_(
GLenum object_type,
GLuint object,
std::string const & label
);
//// Name
std::string static name_(
GLenum object_type,
GLuint object,
std::string const & label = {}
);
};
template<GLenum object_type>
class GLObject
:
public GLObject<0>,
protected GLTraits::Object<object_type>
{
public:
//// Special member functions
template<typename... Args>
explicit GLObject(std::string const & label, Args... args)
try
:
object_{0}
{
if (debug() >= 2)
this->debug_action_("construct", name_(object_type, 0, label));
this->gen_objects(1, &object_, args...);
try
{
// Strictly speaking `glObjectLabel` needs a *created* object.
// `glGen*s` does not create objects (`glCreate*` does though), it
// just reserves names for them. *Binding* that name for the first
// time creates the object. Therefore, the below is not guaranteed
// to work, but seems to on most drivers... Forcing our subclasses
// to bind the name and call us back to set the label is deemed too
// inconvenient so here we are.
label_(object_type, object_, label);
check_error_(glGetError());
}
catch (...)
{
this->delete_objects(1, &object_);
object_ = 0;
throw;
}
}
catch (...)
{
this->fail_action_("construct", name_(object_type, 0, label));
}
~GLObject()
{
if (debug() >= 2)
debug_action_("destroy");
this->delete_objects(1, &object_);
}
GLObject(GLObject && other) noexcept
:
object_{other.object_}
{
if (debug() >= 2)
debug_action_("move construct");
other.object_ = 0;
}
GLObject & operator=(GLObject && other) noexcept
{
if (debug() >= 2)
debug_action_("move assign");
if (&other != this)
{
this->delete_objects(1, &object_);
object_ = other.object_;
other.object_ = 0;
}
return *this;
}
GLObject(GLObject const &) = delete;
GLObject & operator=(GLObject const &) = delete;
//// Object
GLBASE_GET(GLuint, object)
operator GLuint() const { return object(); }
//// Name
std::string name() const
{
return name_(object_type, object_);
}
protected:
//// Debug
void debug_action_(std::string const & action) const
{
return this->debug_action_(action, name());
}
//// Fail
void fail_action_(std::string const & action) const
{
return this->fail_action_(action, name());
}
private:
//// Object
GLuint object_;
};
/// Guards
#endif
|