Home

Awesome

GLFW C++ wrapper - glfwpp logo

CMake clang-format dependabot Total alerts Language grade: C/C++ Codacy Badge CodeFactor FOSSA Status

<p align="center"> <img src="https://i.stack.imgur.com/cmt94.gif"> </p>

GLFWPP or (GLFW C++ Wrapper) is a thin, modern C++17 layer on top of GLFW. It supports GLFW versions from 3.2 up to the current 3.3.6. From the official GLFW website:

GLFW is an Open Source, multi-platform library for OpenGL, OpenGL ES and Vulkan development on the desktop. It provides a simple API for creating windows, contexts and surfaces, receiving input and events. GLFW is written in C and supports Windows, macOS, X11 and Wayland. GLFW is licensed under the zlib/libpng license.

I like C++ and OOP, so when I find a C library, I immediately look for a wrapper which offers RAII objects instead of free create and destroy functions, identifiers wrapped in namespaces, methods instead of free functions, scoped enums instead of macros and exceptions instead of error codes. In case of GLFW I didn't really find such a library, so I made one myself.

<hr> <details><summary>:stopwatch: <b>Quick Start</b></summary><br />

To use, just clone the repo recursively:

git clone https://github.com/janekb04/glfwpp --recurse-submodules

Remember to install the necessary GLFW dependencies, if you're on Linux. Make sure to disable building the examples by setting the option GLFWPP_BUILD_EXAMPLES to OFF using set(GLFWPP_BUILD_EXAMPLES OFF CACHE BOOL "" FORCE) in your CMakeLists.txt, if you don't want them built, as they are built by default. If you don't disable them, you will also have to install the Vulkan SDK.

You can then link against the target GLFWPP using CMake:

add_executable(myExecutable mySource1.cpp mySource2.cpp mySource3.cpp)

set(GLFWPP_BUILD_EXAMPLES OFF CACHE BOOL "" FORCE) # disable building GLFWPP examples
add_subdirectory("path/to/glfwpp")
target_link_libraries(myExecutable PRIVATE GLFWPP)

Now, you just have to include glfwpp.h and you're ready to go:

#include <glfwpp/glfwpp.h>
int main()
{
    auto GLFW = glfw::init();
    glfw::Window window{ 640, 480, "Hello GLFWPP"};
    while (!window.shouldClose())
        glfw::pollEvents();
}

You can also consult cmake.yml to see the complete installation and building process of GLFWPP, its dependencies and the examples on Ubuntu, macOS and Windows. Examples may be found in the /examples directory. Alternatively, just copy-paste the headers and include glfwpp.h (not recommended).

Note: To use functionality from glfw3native.h, native.h has to be included separately.

</details> <details><summary>:pushpin: <b>Main Features</b></summary><br /> </details> <details><summary>:mortar_board: <b>Example</b></summary><br />

Here is a quick comparison of GLFW and GLFWPP. The following code creates a OpenGL 4.6 context and clears the screen.

<table> <tr> <th> GLFW </th> <th> GLFWPP </th> </tr> <tr> <td> <pre style="background-color:#2b2b2b;color:#a9b7c6;font-family:'JetBrains Mono',monospace;font-size:9.8pt;"><span style="color:#bbb529;">#include </span><span style="color:#0cc21a;">&lt;GLFW/glfw3.h&gt; </span><span style="color:#0cc21a;"> </span><span style="color:#ed3792;">int </span><span style="color:#ffc66d;font-weight:bold;">main</span><span style="color:#6989bb;">() </span><span style="color:#6897bb;">{ </span><span style="color:#6897bb;"> </span><span style="color:#ed3792;">if </span><span style="color:#6989bb;">(</span><span style="color:#af3681;">!</span><span style="color:#e0ff76;">glfwInit</span><span style="color:#6989bb;">()) </span><span style="color:#6989bb;"> </span><span style="color:#ed3792;">return </span><span style="color:#af3681;">-</span><span style="color:#0cc21a;">1</span><span style="color:#af3681;">; </span><span style="color:#af3681;"> </span><span style="color:#af3681;"> </span><span style="color:#e0ff76;">glfwWindowHint</span><span style="color:#6989bb;">(</span><span style="color:#58a517;">GLFW_CONTEXT_VERSION_MAJOR</span><span style="color:#af3681;">, </span><span style="color:#0cc21a;">4</span><span style="color:#6989bb;">)</span><span style="color:#af3681;">; </span><span style="color:#af3681;"> </span><span style="color:#e0ff76;">glfwWindowHint</span><span style="color:#6989bb;">(</span><span style="color:#58a517;">GLFW_CONTEXT_VERSION_MINOR</span><span style="color:#af3681;">, </span><span style="color:#0cc21a;">6</span><span style="color:#6989bb;">)</span><span style="color:#af3681;">; </span><span style="color:#af3681;"> </span><span style="color:#e0ff76;">glfwWindowHint</span><span style="color:#6989bb;">(</span><span style="color:#58a517;">GLFW_OPENGL_PROFILE</span><span style="color:#af3681;">, </span><span style="color:#58a517;">GLFW_OPENGL_CORE_PROFILE</span><span style="color:#6989bb;">)</span><span style="color:#af3681;">; </span><span style="color:#af3681;"> </span><span style="color:#836bc6;">GLFWwindow</span><span style="color:#af3681;">* </span><span style="color:#6dc68c;font-style:italic;">window </span><span style="color:#af3681;">= </span><span style="color:#e0ff76;">glfwCreateWindow</span><span style="color:#6989bb;">(</span><span style="color:#0cc21a;">640</span><span style="color:#af3681;">, </span><span style="color:#0cc21a;">480</span><span style="color:#af3681;">, </span><span style="color:#0cc21a;">&quot;Hello World&quot;</span><span style="color:#af3681;">, </span><span style="color:#ed3792;">nullptr</span><span style="color:#af3681;">, </span><span style="color:#ed3792;">nullptr</span><span style="color:#6989bb;">)</span><span style="color:#af3681;">; </span><span style="color:#af3681;"> </span><span style="color:#ed3792;">if </span><span style="color:#6989bb;">(</span><span style="color:#af3681;">!</span><span style="color:#6dc68c;font-style:italic;">window</span><span style="color:#6989bb;">) </span><span style="color:#6897bb;">{ </span><span style="color:#6897bb;"> </span><span style="color:#e0ff76;">glfwTerminate</span><span style="color:#6989bb;">()</span><span style="color:#af3681;">; </span><span style="color:#af3681;"> </span><span style="color:#ed3792;">return </span><span style="color:#af3681;">-</span><span style="color:#0cc21a;">1</span><span style="color:#af3681;">; </span><span style="color:#af3681;"> </span><span style="color:#6897bb;">} </span><span style="color:#6897bb;"> </span><span style="color:#6897bb;"> </span><span style="color:#e0ff76;">glfwMakeContextCurrent</span><span style="color:#6989bb;">(</span><span style="color:#6dc68c;font-style:italic;">window</span><span style="color:#6989bb;">)</span><span style="color:#af3681;">; </span><span style="color:#af3681;"> </span><span style="color:#af3681;"> </span><span style="color:#ed3792;">while </span><span style="color:#6989bb;">(</span><span style="color:#af3681;">!</span><span style="color:#e0ff76;">glfwWindowShouldClose</span><span style="color:#6989bb;">(</span><span style="color:#6dc68c;font-style:italic;">window</span><span style="color:#6989bb;">)) </span><span style="color:#6989bb;"> </span><span style="color:#6897bb;">{ </span><span style="color:#6897bb;"> </span><span style="color:#e0ff76;">glClear</span><span style="color:#6989bb;">(</span><span style="color:#58a517;">GL_COLOR_BUFFER_BIT</span><span style="color:#6989bb;">)</span><span style="color:#af3681;">; </span><span style="color:#af3681;"> </span><span style="color:#af3681;"> </span><span style="color:#e0ff76;">glfwSwapBuffers</span><span style="color:#6989bb;">(</span><span style="color:#6dc68c;font-style:italic;">window</span><span style="color:#6989bb;">)</span><span style="color:#af3681;">; </span><span style="color:#af3681;"> </span><span style="color:#e0ff76;">glfwPollEvents</span><span style="color:#6989bb;">()</span><span style="color:#af3681;">; </span><span style="color:#af3681;"> </span><span style="color:#6897bb;">} </span><span style="color:#6897bb;"> </span><span style="color:#6897bb;"> </span><span style="color:#e0ff76;">glfwTerminate</span><span style="color:#6989bb;">()</span><span style="color:#af3681;">; </span><span style="color:#6897bb;">}</span></pre> </td> <td> <pre style="background-color:#2b2b2b;color:#a9b7c6;font-family:'JetBrains Mono',monospace;font-size:9.8pt;"><span style="color:#bbb529;">#include </span><span style="color:#0cc21a;">&lt;glfwpp/glfwpp.h&gt; </span><span style="color:#0cc21a;"> </span><span style="color:#ed3792;">int </span><span style="color:#ffc66d;font-weight:bold;">main</span><span style="color:#6989bb;">() </span><span style="color:#6897bb;">{ </span><span style="color:#6897bb;"> </span><span style="color:#ed3792;">auto </span><span style="color:#6dc68c;font-style:italic;">GLFW </span><span style="color:#af3681;">= </span><span style="color:#51bcff;">glfw</span><span style="color:#af3681;">::</span><span style="color:#e0ff76;">init</span><span style="color:#6989bb;">()</span><span style="color:#af3681;">;<br> </span><span style="color:#af3681;"> </span><span style="color:#af3681;"> </span><span style="color:#51bcff;">glfw</span><span style="color:#af3681;">::</span><span style="color:#e0ff76;">WindowHints</span><span style="color:#6897bb;">{ </span><span style="color:#61c669;font-style:italic;">.contextVersionMajor </span><span style="color:#af3681;">= </span><span style="color:#0cc21a;">4</span><span style="color:#af3681;">, </span><span style="color:#af3681;"> </span><span style="color:#61c669;font-style:italic;">.contextVersionMinor </span><span style="color:#af3681;">= </span><span style="color:#0cc21a;">6</span><span style="color:#af3681;">, </span><span style="color:#af3681;"> </span><span style="color:#61c669;font-style:italic;">.openglProfile </span><span style="color:#af3681;">= </span><span style="color:#51bcff;">glfw</span><span style="color:#af3681;">::</span><span style="color:#5a60c6;">OpenGlProfile</span><span style="color:#af3681;">::</span><span style="color:#0aa516;font-style:italic;">Core </span><span style="color:#6897bb;">}</span><span style="color:#af3681;">.</span><span style="color:#e0ff76;">apply</span><span style="color:#6989bb;">()</span><span style="color:#af3681;">; </span><span style="color:#af3681;"> </span><span style="color:#51bcff;">glfw</span><span style="color:#af3681;">::</span><span style="color:#5a60c6;">Window </span><span style="color:#6dc68c;font-style:italic;">window</span><span style="color:#6897bb;">{</span><span style="color:#0cc21a;">640</span><span style="color:#af3681;">, </span><span style="color:#0cc21a;">480</span><span style="color:#af3681;">, </span><span style="color:#0cc21a;">&quot;Hello World&quot;</span><span style="color:#6897bb;">}</span><span style="color:#af3681;">; </span><span style="color:#af3681;"> </span><span style="color:#808080;">// If window creation fails, an exception is thrown </span><span style="color:#808080;"> </span><span style="color:#808080;"> </span><span style="color:#808080;"> </span><span style="color:#808080;"> </span><span style="color:#808080;"> </span><span style="color:#51bcff;">glfw</span><span style="color:#af3681;">::</span><span style="color:#e0ff76;">makeContextCurrent</span><span style="color:#6989bb;">(</span><span style="color:#6dc68c;font-style:italic;">window</span><span style="color:#6989bb;">)</span><span style="color:#af3681;">; </span><span style="color:#af3681;"> </span><span style="color:#af3681;"> </span><span style="color:#ed3792;">while </span><span style="color:#6989bb;">(</span><span style="color:#af3681;">!</span><span style="color:#6dc68c;font-style:italic;">window</span><span style="color:#af3681;">.</span><span style="color:#e0ff76;">shouldClose</span><span style="color:#6989bb;">()) </span><span style="color:#6989bb;"> </span><span style="color:#6897bb;">{ </span><span style="color:#6897bb;"> </span><span style="color:#e0ff76;">glClear</span><span style="color:#6989bb;">(</span><span style="color:#58a517;">GL_COLOR_BUFFER_BIT</span><span style="color:#6989bb;">)</span><span style="color:#af3681;">; </span><span style="color:#af3681;"> </span><span style="color:#af3681;"> </span><span style="color:#6dc68c;font-style:italic;">window</span><span style="color:#af3681;">.</span><span style="color:#e0ff76;">swapBuffers</span><span style="color:#6989bb;">()</span><span style="color:#af3681;">; </span><span style="color:#af3681;"> </span><span style="color:#51bcff;">glfw</span><span style="color:#af3681;">::</span><span style="color:#e0ff76;">pollEvents</span><span style="color:#6989bb;">()</span><span style="color:#af3681;">; </span><span style="color:#af3681;"> </span><span style="color:#6897bb;">} </span><span style="color:#6897bb;"> </span><span style="color:#6897bb;"> </span><span style="color:#808080;">// GlfwLibrary destructor calls glfwTerminate automatically </span><span style="color:#6897bb;">}</span></pre> </td> </tr> </table> </details> <details><summary>:open_file_folder: <b>File structure</b></summary><br />

The functionality is split between files, as follows:

</details> <details><summary>:link: <b>Interoperability</b></summary><br />

GLFWPP code and GLFW can be mixed with no issues as long as you mind these rules:

</details> <details><summary>:balance_scale: <b>License</b></summary><br />

FOSSA Status

</details>