A framework for implementing reconfigurable rendering pipelines in C++ / OpenGL

github project


GPUKit is a C++ framework for rendering with OpenGL in an object-oriented way. The framework implements the following:

  • vertex, geometry and fragment shaders.
  • programs.
  • buffers (FBO).
  • 2D and 3D (Cubemap) textures.
  • geometry (VAO + VBO + EBO).

Additionally, GPUKit implements the following convenience classes:

  • Material: A proxy between programs and per-instance uniform values, allowing multiple materials to share a common program.
  • Pass: a way to organize the rendering code associated with a program and buffer combination.
  • AssetImporter: allows importing shaders, 3D geometry and textures and automatically obtaining C++ objects from these.

The project includes an example implementation of a rendering pipeline consisting of:

  • deferred shading.
  • skybox.
  • dynamic point shadows.
  • bloom.
  • rudimentary rigid-body animation.
Video 1. Demo scene rendered with GPUKit, included in the project.

Example Shader Program

Creating a vertex + fragment program involves two steps:

  1. Implement the shaders in a single file annotated with GPUKit commands (Code 1).
#version 410 core
#pragma debug(on)

// your uniforms, ins and outs...

void main() {
  // your vertex code...

#version 410 core
#pragma debug(on)

// your uniforms, ins and outs...

void main() {
  // your fragment code...
Code 1: A glsl file with both vertex and fragment shader code.
  1. Import the program via the framework’s AssetImporter and link it (Code 2).
Program* program = AssetImporter<Program*>::import("example.glsl");
Code 2: Importing and linking a GPUKit program.

The framework automatically maps uniform locations and pre-sets texture-unit indices. After linking, setting attributes of a program in C++ is straightforward (Code 3).

program->setUniform<vec3>("uniform name", { 1., 1., 1. });
Code 3: Setting a uniform value.

Materials work in a similar way. Any attributes declared as Material structs in glsl files are automatically picked up by GPUKit and the Material class proxies their values to the corresponding Program object, allowing many materials to reference a single program.

For an example on how the rest of the framework’s classes work take a look at the repo.