PrevUpHomeNext

OGLplus objects

Tags
Object type
Name
Textual descriptions
Gen/Delete operations
Type specific operations
Object subtype
Object
Currently bound objects
Optional
Reference
Sequence
Array
Group

#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);
Type-related functions

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] Note

If the underlying GL constant value like GL_FRAMEBUFFER or GL_TEXTURE, etc. is not defined, then the ObjectType member function returns ObjectType::None.

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; 1

	explicit ObjectName(GLuint name) noexcept; 2

	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); 3

1

Constructs a wrapper for object with name 0 (zero).

2

Constructs a wrapper for an object with the specified name.

3

Allows to access the 'raw' GL object name.

Convenience typedefs
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);
};
Examples of usage

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(); 1

	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; 2

	prog.Link(); 3

	return prog;
}
catch(ProgramBuildError& error) 4
{
	std::cout << error.ObjectDesc() << std::cout; 5
}

1

Compilation of any of these five shaders may fail.

2

Attach the shaders.

3

Linking may fail too.

4

This catches both compilation and linking errors.

5

Print the description of the object which caused the error.

#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); 1
	static void Delete(GLsizei count, GLuint* names); 2
	static GLboolean IsA(GLuint name); 3
};

1

Generates count objects of the type specified by ObjTag, using the method specified by gen_tag and stores them in names. Note that names must provide enough space for at least count instances of GLuint.

2

Deletes count objects of the type specified by ObjTag stored in names.

3

Determines if name is a valid name currently assigned by GL to some object of the type specified by ObjTag.

#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; 1

	static ObjectName<ObjTag> Binding(void); 2

	static ObjectName<ObjTag> Binding(Target target); 3

	static void Bind(ObjectName<ObjTag> object) 4

	static void Bind(Target target, ObjectName<ObjTag> object) 5
};

1

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.

2

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.

3

Returns the object currently bound to the explicit binding point target for the object type specified by ObjTag. This overload is available only if the object type has named, explicit binding points.

4

Binds the specified object 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.

5

Binds the specified object to the explicit binding point target for the object type specified by ObjTag. This overload is available only if the object type has named, explicit binding points.

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: 1
};

1

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: 1
};

1

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: 1
};

1

The public interface depends on the OpsTag and ObjTag.

#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 1
{ };

1

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; 1
	Object(Object&& temp) noexcept; 2
	Object& operator = (Object&& temp);

	Object(void); 3
	Object(GenTag gen_tag); 4
	Object(ObjectDesc&& description); 5
	Object(GenTag gen_tag, ObjectDesc&& description);

	typedef typename ObjectSubtype<ObjTag>::Type Subtype; 6

	Object(Subtype subtype); 7
	Object(GenTag gen_tag, Subtype subtype);
	Object(Subtype subtype, ObjectDesc&& description); 8
	Object(GenTag gen_tag, Subtype subtype, ObjectDesc&& description);

	~Object(void) noexcept; 9

	static Object FromRawName(ObjectName<ObjTag> name); 10

	const std::string& Description(void) const 11

	operator Sequence<ObjectName<ObjTag>> (void) const; 12
};

1

Objects are non-copyable.

2

Objects are move-constructible and move assignable.

3

Default-constructs an Object. This function creates a new GL object by calling the appropriate glGen* or glCreate* function. Note that object types with a Subtype may not support default construction and may require that the subtype is specified.

4

Constructs an object with gen_tag explicitly specifying the GL object creation method.

5

Constructs an Object and attaches the specified description to it.

6

The subtype of the object. If this object type does not have any subtypes, then Subtype is defined as Nothing.

7

Constructs an object of the specified subtype. If subtype is Nothing then this constructor is equivalent to the default constructor.

8

Constructs an object of the specified subtype and attaches the specified description to it.

9

Cleans up the wrapped GL object by calling the appropriate glDelete* function.

10

Wraps an existing GL object with the specified name. This function does not create a new GL object, instead it adopts the one passed as argument.

11

Returns the textual description of this object.

12

Objects are implicitly convertible to a sequence of object names. Note that the returned sequence must not be used after this object has been destroyed.

Typedefs

The library end-users rarely need to use this template directly. Use the typedefs of the individual instantiations instead:

Object zero

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); 1
	ObjectZero(const ObjectZero&);
};

1

ObjectZero is default constructible.

ObjHandle

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); 1

	ObjHandle(GenTag method, ObjectDesc&& description); 2

	typedef typename ObjectSubtype<ObjTag>::Type Subtype; 3

	template <typename GenTag>
	ObjHandle(GenTag method, Subtype subtype); 4

	ObjHandle(ObjHandle&& temp);
	ObjHandle& operator = (ObjHandle&& temp);

	const std::string& Description(void) const 5

	operator Sequence<ObjectName<ObjTag>> (void) const; 6
};

1

Constructs an ObjHandle with a specific method of object creation.

2

Constructs an ObjHandle with a specific method of object creation, and attaches the specified description to it.

3

The subtype of the object. If this object type does not have any subtypes, then Subtype is defined as Nothing.

4

Constructs a handle for object of the specified subtype. If subtype is Nothing then this constructor is equivalent to the constructor taking only the method.

5

Returns the textual description of this object handle.

6

ObjHandles are implicitly convertible to a sequence of object names. Note that the returned sequence must not be used after this object handle has been destroyed.

#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.

Operations
template <typename ObjTag>
class BoundObjOps
{
private:
	typedef  ExplicitOps;
public:
	typedef ObjectOps<tag::ExplicitSel, ObjTag>::Target Target;
	Target target;

	BoundObjOps(void);

	BoundObjOps(Target init_tgt);
};
Specialization of 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&);
};
Specialization of 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; 1
	Optional(Optional&& temp) noexcept; 2
	Optional(Object&& temp) noexcept; 3
	Optional& operator = (Object&& temp); 4

	explicit operator bool (void) const; 5
	bool HasValidName(void) const noexcept; 6

	Object Release(void) noexcept; 7
};

1

Construction of an uninitialized instance. The only things that can safely be done with an uninitialized Optional<Object> is assignment, moving, destruction and checking whether it is initialized.

2

Optionals are move-constructible.

3

Construction of an initialized instance. Initialized Optional<Object> can be used everywhere where a plain Object could be used, furthermore Optional<Object> can also be Released (this brings it in uninitialized state).

4

Optionals are move-assignable.

5

Equivalent to HasValidName.

6

Returns true if the object has a valid name, false otherwise. The only things that can safely be done with an invalid name Optional<Object> is assignment, moving, destruction and checking whether it is initialized. On the other hand initialized Optional<Object> can be used everywhere where a plain Object could be used.

7

Releases and returns the stored object and makes this Optional uninitialized.

#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);
Iterator
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); 1

	Array(std::size_t n, typename ObjectSubtype<ObjTag>::Type type); 2

	~Array(void);

	bool empty(void) const; 3

	std::size_t size(void) const; 4

	typedef Reference<Object> reference;
	typedef const reference const_reference;

	reference operator[](std::size_t index); 5

	const_reference operator[](std::size_t index) const; 6

	typedef SeqIterator<Object> iterator;
	typedef iterator const_iterator;

	const_iterator begin(void) const; 7
	const_iterator end(void) const; 8

	Sequence<ObjectName<ObjTag>> seq(void) const;

	operator Sequence<ObjectName<ObjTag>> (void) const; 9
};

1

Constructs an an array of count instances of Object.

2

Constructs an an array of n instances of Object with the specified type

3

Returns true if the array is empty.

4

Returns the number of instances in the array.

5

Returns a reference to the i-th instance in the array.

6

Returns a const reference to the i-th instance in the array.

7

Returns an iterator pointing to the first element.

8

Returns an iterator pointing past the last element.

9

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.

Examples of usage
Array<Buffer> vbos(3); 1

std::size_t n = /* ... */

std::vector<GLfloat> pos(n * 3); 2
std::vector<GLfloat> nms(n * 3); 3
std::vector<GLfloat> tcs(n * 2); 4

/* ... */

vbos[0].Bind(BufferTarget::Array); 5
{
	Buffer::Data(BufferTarget::Array, pos);

	VertexArrayAttrib attr(prog, "Position");
	attr.Setup<Vec3f>();
	attr.Enable();
}

vbos[1].Bind(BufferTarget::Array); 6
{
	Buffer::Data(BufferTarget::Array, nms);

	VertexArrayAttrib attr(prog, "Normal");
	attr.Setup<Vec3f>();
	attr.Enable();
}

vbos[2].Bind(BufferTarget::Array); 7
{
	Buffer::Data(BufferTarget::Array, tcs);

	VertexArrayAttrib attr(prog, "TexCoord");
	attr.Setup<Vec2f>();
	attr.Enable();
}

1

Array of three buffer objects.

2

Position data.

3

Normal vector data.

4

Texture coordinate data.

5

Bind and setup the buffer object on index 0.

6

Bind and setup the buffer object on index 1.

7

Bind and setup the buffer object on index 2.

#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&); 1
	Group(Group&&);

	Group(void); 2

#if !OGLPLUS_NO_INITIALIZER_LISTS
	Group(std::initializer_list<ObjectName<ObjTag>> names) 3
#endif

	Group& Add(ObjectName<ObjTag> name); 4

	Sequence<ObjectName<ObjTag>> seq(void) const;

	operator Sequence<ObjectName<ObjTag>> (void) const; 5
};

template <typename ObjTag>
Group<ObjectName<ObjTag>>
operator , (ObjectName<ObjTag> a, ObjectName<ObjTag> b); 6

template <typename ObjTag>
Group<ObjectName<ObjTag>>&&
operator , (Group<ObjectName<ObjTag>>&&, ObjectName<ObjTag>); 7

1

Group is copyable and movable.

2

Constructs an empty group

3

Constructs the Group from an initializer list.

4

Add a new name to this group.

5

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.

6

This operator creates a Group containing two object names.

7

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]); 1

	template <typename ... Tag>
	StaticGroup(ObjectName<Tag>... names); 2

	Sequence<ObjectName<ObjTag>> seq(void) const;

	operator Sequence<ObjectName<ObjTag>> (void) const; 3
};

template <typename ... ObjTag>
StaticGroup<ObjectName<ObjTag>, sizeof...(ObjTag)>
MakeGroup(ObjectName<ObjTag> ... names); 4

1

Construction from an array of object names with known size.

2

Construction from a pack of object names. All names must refer to objects of the same type.

3

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.

4

Creates a static group from a pack of object names. All names must refer to objects of the same type.

Examples
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)); 1
prog.Link();

1

MakeGroup creates a StaticGroup<Shader> which is implicitly convertible to Sequence<Shader> accepted by Program::AttachShaders.


PrevUpHomeNext