# `glshader`

A C++11 helper for [OpenGL][] >=2.0 [shaders][Shader].

`glshader` can load an arbitrary number of [shaders][Shader] with the type
autodetected by the file extension (using the same rules as the [OpenGL /
OpenGL ES Reference Compiler][]). [Uniforms][Uniform] are set with a unified
interface (using template specialization). Data can be provided by [OpenGL
Mathematics (GLM)][] objects (which uses [OpenGL Shading Language (GLSL)][]
naming conventions). For other types of data [uniform blocks][Uniform block]
are used with (shared, per name) [Uniform Buffer Object (UBO)][] backing
(beware of alignment). UBOs can also be accessed directly and bound to a
uniform block by name. The expected usage pattern (as used by
[`glBufferData`][]) can optionally be specified (defaults to
`GL_DYNAMIC_DRAW`). For example:

```cpp
Shader shader({
    "test.vert",
    "test.frag",
});
shader.use();

glm::vec4 color(1, 0, 0, 1);
shader.uniform("color", color);

struct Matrices {
    glm::mat4 view;
    glm::mat4 projection;
} matrices;
// Either:
shader.uniform("matrices", matrices);
// or:
Shader::ubo("matrices", matrices);
shader.uniform("matrices", "matrices");
```

Errors are handled by throwing [`std::runtime_error`][] with a [`what()`][]
that returns helpful context as well as the OpenGL info log where appropriate.
See the [tests](#tests) source for an overview of (some of) the generated error
messages.

[OpenGL]: https://www.opengl.org
[Shader]: https://www.khronos.org/opengl/wiki/Shader
[Uniform]: https://www.khronos.org/opengl/wiki/Uniform
[Uniform block]: https://www.khronos.org/opengl/wiki/Interface_Block_(GLSL)#Uniform_blocks
[Uniform Buffer Object (UBO)]: https://www.khronos.org/opengl/wiki/Uniform_Buffer_Object
[`glBufferData`]: https://www.khronos.org/registry/OpenGL-Refpages/gl4/html/glBufferData.xhtml
[OpenGL / OpenGL ES Reference Compiler]: https://www.khronos.org/opengles/sdk/tools/Reference-Compiler/
[OpenGL Mathematics (GLM)]: https://glm.g-truc.net
[OpenGL Shading Language (GLSL)]: https://www.khronos.org/opengl/wiki/OpenGL_Shading_Language
[`std::runtime_error`]: https://en.cppreference.com/w/cpp/error/runtime_error
[`what()`]: https://en.cppreference.com/w/cpp/error/exception/what

## Tests

A test, using [GLFW][], is provided in [`test/`](test/) and can be run with
`make test` from the repository root.

[GLFW]: https://www.glfw.org/

## Dependencies

The [OpenGL Extension Wrangler (GLEW)][] library is used for extension loading.

[`str.hpp`][] is bundled.

Installing dependencies on a Linux distribution using the [APT package
manager][] can be done with:

```sh
// Library dependencies.
sudo apt-get install \
    libgl1-mesa-dev \
    libglew-dev \
    libglm-dev

// Test dependencies.
sudo apt-get install \
    libglfw3-dev
```

[OpenGL Extension Wrangler (GLEW)]: http://glew.sourceforge.net
[`str.hpp`]: https://git.rcrnstn.net/rcrnstn/str.hpp
[APT package manager]: https://en.wikipedia.org/wiki/APT_(software)

## License

Licensed under the [ISC license][], see the [`LICENSE`](LICENSE) file.

[ISC license]: https://en.wikipedia.org/wiki/ISC_license
