# [`gltraits`][]
A [C++11][]/[OpenGL][]>=[1.0][](/[GLM][]) [trait][]s library.
This library seeks to unify some parts of the OpenGL [API][] to ease [generic
programming][]. It also provides sensible default arguments, [optional][debug]
[check][]s for [version][]/[extension][] support, and optional support for
[OpenGL Mathematics (GLM)][GLM] (which provides [GLSL][]-like types).
A more philosophical description: it aims to make the implicit symmetries of
the OpenGL API explicit. In the process, some wrinkles in the symmetry are also
brought to light. Therefore, it may be useful for learning and understanding
the OpenGL API (although this use case may be limited due to the (ab)use of C++
language features).
This header-only library makes heavy use of macros. For easy inspection of the
results, a script that runs the preprocessor is available in
[`doc/preprocess`][] and its output in [`doc/preprocess.hpp`][].
A typical use case is demonstrated by this quote from [OGLDEV on YouTube][]:
> Notice, in order to make this an unsigned integer texture we use `GL_RGB32UI`
> as the `internal_format`, `GL_RGB_INTEGER` as the `format`, and
> `GL_UNSIGNED_INT` as the data `type`. Combining all these formats and types
> correctly in OpenGL can often be a pain, and I literally pulled the last few
> pieces of hair from my head trying to get this to work.
These constants are provided in `GLTraits::Value<glm::uvec3>`. Of course, this
becomes even more valuable when `glm::uvec3` is replaced by some unknown
template parameter.
[`gltraits`]: https://git.rcrnstn.net/rcrnstn/gltraits
[C++11]: https://en.wikipedia.org/wiki/C++11
[OpenGL]: https://en.wikipedia.org/wiki/OpenGL
[1.0]: https://en.wikipedia.org/wiki/OpenGL#Version_history
[GLM]: https://glm.g-truc.net
[trait]: https://en.wikipedia.org/wiki/Trait_(computer_programming)
[API]: https://en.wikipedia.org/wiki/API
[generic programming]: https://en.wikipedia.org/wiki/Generic_programming
[debug]: https://git.rcrnstn.net/rcrnstn/glbase#debug
[check]: https://git.rcrnstn.net/rcrnstn/glbase#check
[version]: https://en.wikipedia.org/wiki/OpenGL#Version_history
[extension]: https://www.khronos.org/opengl/wiki/OpenGL_Extension
[GLSL]: https://www.khronos.org/opengl/wiki/OpenGL_Shading_Language
[`doc/preprocess`]: doc/preprocess
[`doc/preprocess.hpp`]: doc/preprocess.hpp
[OGLDEV on YouTube]: https://www.youtube.com/watch?v=71G-PVpaVk8&t=5m17s
## Usage
### Value
The [empty][] `struct GLTraits::Value<typename Value>` is template specialized
on the following types.
- `GLfloat`
- `bool`
- `GL{,u}byte`
- `GL{,u}short`
- `GL{,u}int`
- `GLdouble`
[GLM][] support is enabled if `glm/glm.hpp` is included (specifically, if
`GLM_VERSION` is defined) before inclusion of `gltraits.hpp`. In that case
`GLTraits::Value` is additionally template specialized on the following types.
- `glm::{,i,u,d}vec{2,3,4}`
- `glm::{,d}mat{2{,x3,x4},3{x2,,x4},4{x2,x3,}}`
`GLTraits::Value` contains the following `static constexpr` member variables.
- `char const name[]`
- `GLint columns`
- `GLint rows`
- `GLenum glsl`
- `GLenum format`
- `GLenum type`
- `GLenum internal_format`
- `GLenum internal_format_srgb`
- `GLenum internal_format_compressed`
- `GLenum internal_format_compressed_srgb`
- `bool integer`
`GLTraits::Value` contains the following `static` member functions.
- ```cpp
void uniform(GLint location, Value const & value)
```
Generalization of `glUniform*`.
Uploads `value` to the [uniform][] indicated by `location` of the current
[shader][] program.
- ```cpp
void vertex_attrib(GLint location, Value const & value)
```
Generalization of `glVertexAttrib*`.
Uploads `value` to the [non-array attribute][] indicated by `location`.
Note that [`glDisableVertexAttribArray`][] is not called (for performance).
- ```cpp
void vertex_attrib_pointer(
GLint location,
std::size_t offset = 0,
std::size_t stride = sizeof(Value)
)
```
Generalization of `glVertexAttrib*Pointer`.
Sets the [format][] as well as the [offset and stride][] of the [array
attribute][] indicated by `location`. Note that
[`glEnableVertexAttribArray`][] is not called (for performance).
If `location` is `-1`, the above calls will do nothing. No error will be
generated in this case.
Note that matrix types (e.g. from [GLM][], if enabled), occupy several
consecutive attribute locations (one per column), which are all handled
automatically by `vertex_attrib{,_pointer}(...)` above.
`GLTRAITS_VALUE*` macros are defined to ease the definition of new template
specializations of `GLTraits::Value`. Consult the source for the definitions
and usage examples.
[empty]: https://en.cppreference.com/w/cpp/types/is_empty
[uniform]: https://www.khronos.org/opengl/wiki/Uniform_(GLSL)
[shader]: https://www.khronos.org/opengl/wiki/Shader
[non-array attribute]: https://www.khronos.org/opengl/wiki/Vertex_Specification#Non-array_attribute_values
[format]: https://www.khronos.org/opengl/wiki/Vertex_Specification#Vertex_format
[offset and stride]: https://www.khronos.org/opengl/wiki/Vertex_Specification#Vertex_buffer_offset_and_stride
[array attribute]: https://www.khronos.org/opengl/wiki/Vertex_Specification#Vertex_Buffer_Object
[`glDisableVertexAttribArray`]: https://registry.khronos.org/OpenGL-Refpages/gl4/html/glEnableVertexAttribArray.xhtml
[`glEnableVertexAttribArray`]: https://registry.khronos.org/OpenGL-Refpages/gl4/html/glEnableVertexAttribArray.xhtml
## Building
See [`BUILDING.md`][].
[`BUILDING.md`]: BUILDING.md
## License
Licensed under the [ISC License][] unless otherwise noted, see the
[`LICENSE`][] file.
[ISC License]: https://choosealicense.com/licenses/isc
[`LICENSE`]: LICENSE