SGL (Simple GL) is a lightweight C++ library designed to simplify the process of compiling, linking, and configuring GLSL shaders in OpenGL applications. It also provides utilities for working with uniform variables, supports hot reloading of shaders, parses local work group values from compute shaders, and includes compile-time assertions to catch OpenGL-related errors.
- Shader Compilation & Linking: Simplifies compiling and linking GLSL shader files into OpenGL programs.
- Uniform Variable Management: Provides easy setters and getters for shader uniform variables.
- Hot Reload: Supports hot reloading of shader files at runtime for quicker iteration during development.
- Compute Shader Work Group Parsing: Automatically parses local work group sizes from compute shaders.
- Assertions for Shader Uniforms & State: Automatically checks if shader uniforms or other OpenGL states are correctly set. If an error occurs (such as an invalid uniform name or missing shader program), the program will fail to compile.
- GLM: A header-only mathematics library for graphics software.
- Glad: OpenGL loader for managing OpenGL function pointers.
To build SGL, you can use CMake, which will automatically find and link the required dependencies (GLM and Glad). The library is compatible with modern C++ standards (C++17).
cmake_minimum_required(VERSION 3.16)Clone the repository and build using CMake:
git clone https://github.com/omar-owis/sgl.git
cd sgl && mkdir build && cd build
cmake .. && cmake --build .Note: If you are using a package manager such as vcpkg, you may need to specify a CMake toolchain file when configuring the project:
cmake .. -DCMAKE_TOOLCHAIN_FILE=/path/to/vcpkg/scripts/buildsystems/vcpkg.cmakeThis ensures that dependencies like GLM and Glad are correctly discovered during configuration.
#include <SGL/Shader.h>
glm::mat4 viewMat;
glm::mat4 projMat;
// Compile and link shaders
SGL::Shader shader({
{"main.vert", GL_VERTEX_SHADER},
{"main.frag", GL_FRAGMENT_SHADER}
});
// Use the shader program
shader.use();
shader.SetMat4("uViewMat", viewMat);
shader.SetMat4("uProjMat", projMat);
Note:
- Uniform Name Error: If
uViewMatoruProjMatdoesn't exist in the shader, the program will fail to compile. - Shader Not in Use: Attempting to set or get uniforms without an active shader program will trigger a compile-time failure
#include <SGL/Shader.h>
glm::mat4 viewMat;
glm::mat4 projMat;
// Compile and link shaders
SGL::Shader shader({
{"main.vert", GL_VERTEX_SHADER},
{"main.frag", GL_FRAGMENT_SHADER}
});
// Use the shader program
shader.use();
// Cache uniform locations
unsigned int viewUniLoc = shader.GetUniformLocation("uViewMat");
unsigned int projUniLoc = shader.GetUniformLocation("uProjMat");
shader.SetMat4(viewUniLoc, viewMat);
shader.SetMat4(projUniLoc, projMat);
You can manually reload (recompile & relink) shaders at runtime:
shader.reload();
For automatic hot reloading, integrate this call with a file-watching system.
To extract local work group sizes from a compute shader:
SGL::ComputeShader computeShader("shader.comp");
SGL::LocalWorkGroup workGroupSize = computeShader.GetLocalSize();
Or query individual dimensions:
SGL::ComputeShader computeShader("shader.comp");
unsigned int x = computeShader.GetLocalSizeX();
unsigned int y = computeShader.GetLocalSizeY();
unsigned int z = computeShader.GetLocalSizeZ();
SGL provides helpers to query the locaal work group size from a compute shader and dispatch it corretly.
#include <SGL/ComputeShader.h>
// Load compute shader
SGL::ComputeShader computeShader("shader.comp");
// Query local work group size declared in the shader
unsigned int localX = computeShader.GetLocalSizeX();
unsigned int localY = computeShader.GetLocalSizeY();
unsigned int localZ = computeShader.GetLocalSizeZ();
// Define total work size (e.g. number of elements to process)
unsigned int totalX = 1024;
unsigned int totalY = 1;
unsigned int totalZ = 1;
// Calculate dispatch group counts
unsigned int groupX = (totalX + localX - 1) / localX;
unsigned int groupY = (totalY + localY - 1) / localY;
unsigned int groupZ = (totalZ + localZ - 1) / localZ;
// Dispatch compute shader
computeShader.Dispatch(groupX, groupY, groupZ);
Note:
- You may need a memory barrier after dispatch, depending on usage:
glMemoryBarrier(GL_SHADER_STORAGE_BARRIER_BIT);
SGL is licensed under the MIT License See LICENSE for more information