#include
<oglplus/object/tags.hpp>
The object tag types allow to differentiate between OpenGL object types at compile time.
namespace tag { struct Texture { }; struct Buffer { }; struct Framebuffer { }; struct Renderbuffer { }; struct Query { }; struct ProgramPipeline { }; struct Program { }; struct TransformFeedback { }; struct Sampler { }; struct VertexArray { }; struct Shader { }; struct PerfMonitorAMD { }; struct PathNV { }; } // namespace tag
#include
<oglplus/object/type.hpp>
The ObjectType
type enumerates
the GL object type values.
enum class ObjectType : GLenum { Buffer = GL_BUFFER, Framebuffer = GL_FRAMEBUFFER, ProgramPipeline = GL_PROGRAM_PIPELINE, Program = GL_PROGRAM, Query = GL_QUERY, Renderbuffer = GL_RENDERBUFFER, Sampler = GL_SAMPLER, Shader = GL_SHADER, Texture = GL_TEXTURE, TransformFeedback = GL_TRANSFORM_FEEDBACK, VertexArray = GL_VERTEX_ARRAY, None = GL_NONE }; template <> Range<ObjectType> EnumValueRange<ObjectType>(void); StrCRef EnumValueName(ObjectType);
The object type can be obtained by calling the ObjectType
static member function of ObjTypeOps<ObjTag>
,
which is a public base class of OGLplus object
wrappers. It can also be used as a standalone class when instantiated
with one of the object tags.
For example ObjTypeOps<tag::Buffer>::ObjectType()
returns ObjectType::Buffer
,
etc.
Note | |
---|---|
If the underlying GL constant value like |
template <typename ObjTag> struct ObjTypeOps { static ObjectType ObjectType(void); };
#include
<oglplus/object/name.hpp>
The ObjectName
template
wraps the raw GLuint
name of a GL object (texture, VBO, FBO, RBO, sampler, query, etc.). Since
all types of GL objects share the same namespace (the domain of the
GLuint
type) it is easy
to confuse objects of different types.
In order to avoid such mismatches, the ObjTag
template parameter of ObjectName
conveys information about the actual object type and prevents for example
passing a texture name to a function requiring a buffer, etc.
template <typename ObjTag> class ObjectName { public: ObjectName(void) noexcept; explicit ObjectName(GLuint name) noexcept; ObjectName(const ObjectName&) noexcept; ObjectName(ObjectName&&) noexcept; ObjectName& operator = (const ObjectName&) noexcept; ObjectName& operator = (ObjectName&&) noexcept; friend bool operator == (ObjectName, ObjectName); friend bool operator != (ObjectName, ObjectName); friend bool operator < (ObjectName, ObjectName); }; template <typename ObjTag> GLuint GetGLName(ObjectName<ObjTag> named);
Constructs a wrapper for object with name |
|
Constructs a wrapper for an object with the specified |
|
Allows to access the 'raw' GL object name. |
typedef ObjectName<tag::Renderbuffer> RenderbufferName; typedef ObjectName<tag::Framebuffer> FramebufferName; typedef ObjectName<tag::Texture> TextureName; typedef ObjectName<tag::Buffer> BufferName; typedef ObjectName<tag::Query> QueryName; typedef ObjectName<tag::ProgramPipeline> ProgramPipelineName; typedef ObjectName<tag::Program> ProgramName; typedef ObjectName<tag::TransformFeedback> TransformFeedbackName; typedef ObjectName<tag::Sampler> SamplerName; typedef ObjectName<tag::VertexArray> VertexArrayName; typedef ObjectName<tag::Shader> ShaderName; typedef ObjectName<tag::PerfMonitorAMD> PerfMonitorAMDName; typedef ObjectName<tag::PathNV> PathNVName;
#include
<oglplus/object/desc.hpp>
Objects with OpenGL names (unsigned integers) can optionally have a textual description. This is useful for diagnostic purposes, for example in an application with lots of different shaders it is easier to track the source of compilation, linking or validation errors when the individual shader or program objects have a human-readable description which is attached to the exception raised by the error.
The descriptions are assigned to objects by using the ObjectDesc class.
class ObjectDesc { public: ObjectDesc(void) { } ObjectDesc(ObjectDesc&& tmp); ObjectDesc(std::string&& str); };
The following snippet shows how to attach textual descriptions to objects like Shader or Program and how to get it back from an exception thrown by one of the described objects.
try { VertexShader vxs(ObjectDesc("Vertex shader 1")); vxs.Source(/* ... */).Compile(); TessControlShader tcs(ObjectDesc("Tessellation control shader 1")); tcs.Source(/* ... */).Compile(); TessEvaluationShader tes(ObjectDesc("Tessellation evaluation shader 1")); tes.Source(/* ... */).Compile(); GeometryShader gys(ObjectDesc("Geometry shader 1")); gys.Source(/* ... */).Compile(); FragmentShader fgs(ObjectDesc("Fragment shader 1")); fgs.Source(/* ... */).Compile(); Program prog(ObjectDesc("Program 1")); prog << vxs << tcs << tes << gys << fgs; prog.Link(); return prog; } catch(ProgramBuildError& error) { std::cout << error.ObjectDesc() << std::cout; }
#include
<oglplus/object/wrapper.hpp>
The ObjGenDelOps
template class provides a unified
interface for the GL's glGen*
, glCreate*
,
glDelete*
and glIs*
functions for
various object types specified by the ObjTag
template parameter.
template <typename ObjTag> class ObjGenDelOps { protected: static void Gen(GenTag gen_tag, GLsizei count, GLuint* names); static void Delete(GLsizei count, GLuint* names); static GLboolean IsA(GLuint name); };
Generates |
|
Deletes |
|
Determines if |
#include
<oglplus/object/wrapper.hpp>
ObjBindingOps
implements operations related to binding
objects to an explicit or implicit binding point.
template <typename ObjTag> class ObjBindingOps { public: typedef <Unspecified> Target; static ObjectName<ObjTag> Binding(void); static ObjectName<ObjTag> Binding(Target target); static void Bind(ObjectName<ObjTag> object) static void Bind(Target target, ObjectName<ObjTag> object) };
Strongly typed enumeration specifying binding points for object type associated with ObjTag. This typedef is available only if the object type has named, explicit binding points. |
|
Returns the object currently bound to the implicit binding point for the object type specified by ObjTag. This overload is available only if the object type has only one implicit binding point. |
|
Returns the object currently bound to the explicit binding point
|
|
Binds the specified |
|
Binds the specified |
ObjCommonOps
implements operations applicable to any
object of the type specified by ObjTag
independent of the operation
kind.
template <typename ObjTag> class ObjCommonOps : public ObjectName<ObjTag> { public: };
The public interface depends on the ObjTag. |
ObjZeroOps
implements operations applicable to any
object of the type specified by ObjTag,
including objects with name zero (which has special meaning for certain
object types), using operations kind specified by OpsTag.
template <typename OpsTag, typename ObjTag> class ObjZeroOps : public ObjCommonOps<ObjTag> { public: };
The public interface depends on the OpsTag and ObjTag. If there are no operations that can work explicitly on object zero besides binding, then this class just inherits from the common object operations wrapper. |
The ObjectOps
template class is specialized for various
object types (like textures, buffers, queries, etc.) specified by the
ObjTag and operation
kinds specified by type OpsTag
and implements appropriate interface for the particular object type.
For example the specialization of ObjectOps
for tag::DirectState
OpsTag and tag::Texture
ObjTag wraps texture-related
GL functions with direct state access, etc.
template <typename OpsTag, typename ObjTag> class ObjectOps : public ObjZeroOps<OpsTag, ObjTag> { public: };
#include
<oglplus/object/wrapper.hpp>
Some object types (for example Shader,
Texture or Query) can be further classified
into subtypes. The ObjectSubtype
Metafunction
allows to query the type (usually an enumeration)
that is used to distinguish the individual subtypes.
template <typename ObjTag> struct ObjectSubtype : Nothing { };
Most object types don't have any subtypes, which is indicated by returning Nothing by default. |
#include
<oglplus/object/wrapper.hpp>
The main purpose of Object
is to do lifetime management
of the underlying GL objects and managing textual description assigned
to them. It uses the ObjGenDelOps
template to create new instance of an OpenGL object in the constructor
and to delete it in the destructor Object
unlike an
ObjHandle
also inherits from a specialization of ObjectOps
which implements wrappers for GL functions related to the underlying
GL object.
Since GL does not support object copying, instances of Object
are move-only.
template <typename OpsTag, typename ObjTag> class Object<ObjectOps<OpsTag, ObjTag>> : public ObjGenDelOps<ObjTag> , public ObjectOps<OpsTag, ObjTag> { public: Object(const Object&) = delete; Object(Object&& temp) noexcept; Object& operator = (Object&& temp); Object(void); Object(GenTag gen_tag); Object(ObjectDesc&& description); Object(GenTag gen_tag, ObjectDesc&& description); typedef typename ObjectSubtype<ObjTag>::Type Subtype; Object(Subtype subtype); Object(GenTag gen_tag, Subtype subtype); Object(Subtype subtype, ObjectDesc&& description); Object(GenTag gen_tag, Subtype subtype, ObjectDesc&& description); ~Object(void) noexcept; static Object FromRawName(ObjectName<ObjTag> name); const std::string& Description(void) const operator Sequence<ObjectName<ObjTag>> (void) const; };
|
|
|
|
Default-constructs an |
|
Constructs an |
|
Constructs an |
|
The subtype of the object. If this object type does not have any
subtypes, then |
|
Constructs an object of the specified |
|
Constructs an object of the specified |
|
Cleans up the wrapped GL object by calling the appropriate |
|
Wraps an existing GL object with the specified |
|
Returns the textual description of this object. |
|
|
The library end-users rarely need to use this template directly. Use
the typedef
s of the individual instantiations instead:
ObjectZero
wraps objects with GL name zero (0
).
Depending on the object type (specified by ObjTag)
the semantics is either "no-object" (for example NoBuffer,
NoRenderbuffer,
etc.) or "default-object" (for example DefaultTexture
or DefaultFramebuffer).
template <typename OpsTag, typename ObjTag> class ObjectZero<ObjZeroOps<OpsTag, ObjTag>> : public ObjZeroOps<OpsTag, ObjTag> { public: ObjectZero(void); ObjectZero(const ObjectZero&); };
In certain situations it is desirable to have a lifetime management wrapper
for GL objects without any specific set object operations attached to
it. The ObjHandle
serves for this purpose. Similar
to Object
it manages the lifetime of a GL object by
using the ObjGenDelOps,
but does not inherit from any ObjectOps
specialization.
template <typename ObjTag> class ObjHandle : public ObjGenDelOps<ObjTag> , public ObjectName<ObjTag> { public: ObjHandle(GenTag method); ObjHandle(GenTag method, ObjectDesc&& description); typedef typename ObjectSubtype<ObjTag>::Type Subtype; template <typename GenTag> ObjHandle(GenTag method, Subtype subtype); ObjHandle(ObjHandle&& temp); ObjHandle& operator = (ObjHandle&& temp); const std::string& Description(void) const operator Sequence<ObjectName<ObjTag>> (void) const; };
Constructs an |
|
Constructs an |
|
The subtype of the object. If this object type does not have any
subtypes, then |
|
Constructs a handle for object of the specified |
|
Returns the textual description of this object handle. |
|
|
#include
<oglplus/object/bound.hpp>
Specializations of BoundObjOps
for various object
tags (currently for tag::Buffer,
tag::Framebuffer,
tag::Renderbuffer
and tag::Texture)
have the same set of functions as ObjectOps<tag::ExplicitSel, ObjTag>
with the difference, that the static functions with a Target
parameter from ObjectOps
are turned into member functions of BoundObjOps
without
the Target argument. Instances of BoundObjOps
have
instead a data member called target
, which is passed
implicitly when calling one of the member functions.
template <typename ObjTag> class BoundObjOps { private: typedef ExplicitOps; public: typedef ObjectOps<tag::ExplicitSel, ObjTag>::Target Target; Target target; BoundObjOps(void); BoundObjOps(Target init_tgt); };
ObjectOps
template <typename ObjTag> class ObjectOps<tag::CurrentBound, ObjTag> : public ObjZeroOps<tag::CurrentBound, ObjTag> , public BoundObjOps<ObjTag> { public: typedef typename BoundObjOps<ObjTag>::Target Target; ObjectOps(ObjectOps&&); ObjectOps(const ObjectOps&); ObjectOps& operator = (ObjectOps&&); ObjectOps& operator = (const ObjectOps&); };
Reference
template <typename ObjTag> class Reference<ObjectOps<tag::CurrentBound, ObjTag>> : public ObjectOps<tag::CurrentBound, ObjTag> { public: Reference(void); Reference(typename ObjectOps<tag::CurrentBound, ObjTag>::Target); };
#include
<oglplus/object/optional.hpp>
The Optional
template class is a modifier for objects and in contrast
to Object
it does allow to construct uninitialized
instances which can be initialized later.
An Optional<Object>
can be used everywhere an Object
could be used, but it must be initialized (the HasValidName()
member function must return true), otherwise usage results in undefined
behavior.
template <typename Object> class Optional : public Object { public: Optional(void) noexcept; Optional(Optional&& temp) noexcept; Optional(Object&& temp) noexcept; Optional& operator = (Object&& temp); explicit operator bool (void) const; bool HasValidName(void) const noexcept; Object Release(void) noexcept; };
Construction of an uninitialized instance. The only things that can
safely be done with an uninitialized |
|
Optionals are move-constructible. |
|
Construction of an initialized instance. Initialized |
|
Optionals are move-assignable. |
|
Equivalent to |
|
Returns true if the object has a valid name, false otherwise. The
only things that can safely be done with an invalid name |
|
Releases and returns the stored object and makes this |
#include
<oglplus/object/reference.hpp>
Reference
allows to make managed copies of instances
of Object
.
Since OpenGL does not support copying of objects, the Object
wrapper is move-only.
There are however situations, when a temporary reference to the original
object (with the knowledge that this original will be kept alive during
the whole lifetime of the copy) is needed. The Reference
template class allows to do such temporary references, which have the
same members and friend functions as the original object, and can be
used in the same way, provided that the original instance is not destroyed
while the managed copy is in use.
Instances of Reference
are for example created when
accessing or iterating through the elements of a Sequence.
template <typename Object> class Reference : public ObjectOps<OpsTag, ObjTag> { public: Reference(ObjectName<ObjTag> name); };
#include
<oglplus/object/sequence.hpp>
Sequence
stores a constant sequence of object
names or references
to objects and is mostly used as the parameter type for functions
working on multiple objects.
template <typename ObjectT> class Sequence { public: bool empty(void) const; size_t size(void) const; ObjectT at(size_t index) const; ObjectT operator[](size_t index) const; Sequence slice(size_t start) const; Sequence slice(size_t start, size_t count) const; typedef SeqIterator<ObjectT> iterator; typedef SeqIterator<ObjectT> const_iterator; const_iterator begin(void) const; const_iterator end(void) const; }; template <typename ObjectT> const GLuint* GetNames(const Sequence<ObjectT>& sequence);
template <typename ObjectT> class SeqIterator { public: typedef ObjectT value_type; typedef <Unspecified> difference_type; friend bool operator == (SeqIterator a, SeqIterator b); friend bool operator != (SeqIterator a, SeqIterator b); friend bool operator < (SeqIterator a, SeqIterator b); friend SeqIterator operator + (SeqIterator a, difference_type d); friend SeqIterator operator - (SeqIterator a, difference_type d); friend difference_type operator - (SeqIterator a, SeqIterator b); value_type operator * (void) const; value_type operator [](size_t index) const; SeqIterator& operator ++ (void); SeqIterator operator ++ (int); SeqIterator& operator -- (void); SeqIterator operator -- (int); SeqIterator& operator += (difference_type d); SeqIterator& operator -= (difference_type d); };
#include
<oglplus/object/array.hpp>
template <typename Object> class Array; { public: Array(const Array&) = delete; Array(Array&&); Array(std::size_t count); Array(std::size_t n, typename ObjectSubtype<ObjTag>::Type type); ~Array(void); bool empty(void) const; std::size_t size(void) const; typedef Reference<Object> reference; typedef const reference const_reference; reference operator[](std::size_t index); const_reference operator[](std::size_t index) const; typedef SeqIterator<Object> iterator; typedef iterator const_iterator; const_iterator begin(void) const; const_iterator end(void) const; Sequence<ObjectName<ObjTag>> seq(void) const; operator Sequence<ObjectName<ObjTag>> (void) const; };
Constructs an an array of |
|
Constructs an an array of |
|
Returns true if the array is empty. |
|
Returns the number of instances in the array. |
|
Returns a reference to the i-th instance in the array. |
|
Returns a const reference to the i-th instance in the array. |
|
Returns an iterator pointing to the first element. |
|
Returns an iterator pointing past the last element. |
|
Implicit conversion to a sequence of object names, which can be passed as an argument to various functions. Note that the returned sequence must not be used after this array has been destroyed. |
Array<Buffer> vbos(3); std::size_t n = /* ... */ std::vector<GLfloat> pos(n * 3); std::vector<GLfloat> nms(n * 3); std::vector<GLfloat> tcs(n * 2); /* ... */ vbos[0].Bind(BufferTarget::Array); { Buffer::Data(BufferTarget::Array, pos); VertexArrayAttrib attr(prog, "Position"); attr.Setup<Vec3f>(); attr.Enable(); } vbos[1].Bind(BufferTarget::Array); { Buffer::Data(BufferTarget::Array, nms); VertexArrayAttrib attr(prog, "Normal"); attr.Setup<Vec3f>(); attr.Enable(); } vbos[2].Bind(BufferTarget::Array); { Buffer::Data(BufferTarget::Array, tcs); VertexArrayAttrib attr(prog, "TexCoord"); attr.Setup<Vec2f>(); attr.Enable(); }
#include
<oglplus/object/group.hpp>
The Group
class is a dynamic container storing object names, which is
implicitly convertible into a Sequence.
New object names can be added to Group
after it has
been constructed.
template <typename ObjectName>
class Group;
template <typename ObjTag>
class Group<ObjectName<ObjTag>>
{
public:
Group(const Group&);
Group(Group&&);
Group(void);
#if !OGLPLUS_NO_INITIALIZER_LISTS
Group(std::initializer_list<ObjectName<ObjTag>> names)
#endif
Group& Add(ObjectName<ObjTag> name);
Sequence<ObjectName<ObjTag>> seq(void) const;
operator Sequence<ObjectName<ObjTag>> (void) const;
};
template <typename ObjTag>
Group<ObjectName<ObjTag>>
operator , (ObjectName<ObjTag> a, ObjectName<ObjTag> b);
template <typename ObjTag>
Group<ObjectName<ObjTag>>&&
operator , (Group<ObjectName<ObjTag>>&&, ObjectName<ObjTag>);
|
|
Constructs an empty group |
|
Constructs the Group from an initializer list. |
|
Add a new name to this group. |
|
Implicit conversion to a sequence of object names, which can be passed as an argument to various functions. Note that the returned sequence must not be used after this group has been destroyed. |
|
This operator creates a |
|
This operator appends an object name to a group. |
StaticGroup
The StaticGroup
class is a static container storing
object names, which
is implicitly convertible into a Sequence.
New object names cannot be added to StaticGroup
after
it has been constructed.
template <typename ObjName, size_t N> class StaticGroup; template <typename ObjTag, std::size_t N> class StaticGroup<ObjectName<ObjTag>, N> { public: StaticGroup(const ObjectName<ObjTag> (&names)[N]); template <typename ... Tag> StaticGroup(ObjectName<Tag>... names); Sequence<ObjectName<ObjTag>> seq(void) const; operator Sequence<ObjectName<ObjTag>> (void) const; }; template <typename ... ObjTag> StaticGroup<ObjectName<ObjTag>, sizeof...(ObjTag)> MakeGroup(ObjectName<ObjTag> ... names);
Construction from an array of object names with known size. |
|
Construction from a pack of object names. All names must refer to objects of the same type. |
|
Implicit conversion to a sequence of object names, which can be passed as an argument to various functions. Note that the returned sequence must not be used after this static group has been destroyed. |
|
Creates a static group from a pack of object names. All names must refer to objects of the same type. |
VertexShader vxs; vxs.Source(/* ... */).Compile(); TessControlShader tcs; tcs.Source(/* ... */).Compile(); TessEvaluationShader tes; tes.Source(/* ... */).Compile(); GeometryShader gys; gys.Source(/* ... */).Compile(); FragmentShader fgs; fgs.Source(/* ... */).Compile(); Program prog; prog.AttachShaders(MakeGroup(vxs, tcs, tes, gys, fgs)); prog.Link();
MakeGroup
creates a StaticGroup<Shader> which is implicitly
convertible to Sequence<Shader>
accepted by |