How to Set Up OpenGL GLFW GLEW GLM on a Project with Visual Studio

Setting up an OpenGL project in Visual Studio can feel less like software development and more like introducing four talented strangers at an awkward networking event. OpenGL handles graphics commands, GLFW creates the window and OpenGL context, GLEW loads modern OpenGL functions, and GLM provides graphics-friendly mathematics. They work beautifully togetheronce everybody knows where to sit.

This guide explains how to set up OpenGL, GLFW, GLEW, and GLM in a Visual Studio C++ project on Windows. It covers manual dependency configuration, static and dynamic linking, a working test program, common errors, and a faster alternative using vcpkg.

What OpenGL, GLFW, GLEW, and GLM Actually Do

Before changing Visual Studio settings, it helps to understand why all four components are needed. OpenGL is a graphics API specification used to communicate with graphics drivers. It knows how to process vertices, execute shaders, create textures, and draw pixels, but it does not create a Windows application window for you.

OpenGL: The Rendering API

OpenGL provides the commands that send graphics work to the GPU. On Windows, the operating system includes opengl32.lib, but the traditional Windows OpenGL header exposes only old functionality directly. Modern OpenGL programs therefore use an extension loader to obtain newer function pointers from the active graphics driver.

GLFW: Windows, Contexts, and Input

GLFW is a lightweight, cross-platform library for creating windows, creating OpenGL contexts, processing keyboard and mouse input, and managing events. It saves you from writing several pages of Win32 code before you can display your first suspiciously exciting blue rectangle.

GLEW: Modern OpenGL Function Loading

GLEW, short for OpenGL Extension Wrangler Library, loads modern OpenGL functions at runtime. Functions such as glGenVertexArrays, glCreateShader, and glBindBuffer are exposed only after an OpenGL context exists and GLEW has been initialized.

GLM: Mathematics for Graphics

GLM is a header-only C++ mathematics library designed around GLSL conventions. It supplies vectors, matrices, transformations, projections, quaternions, and related utilities. Because GLM is header-only, you add its include directory but do not link a GLM .lib file.

Official grounding:

Prerequisites for the Visual Studio OpenGL Setup

Open Visual Studio Installer and confirm that the Desktop development with C++ workload is installed. The installation should include the MSVC compiler, Windows SDK, C++ build tools, and Visual Studio project support.

Create or choose a 64-bit configuration unless you specifically need a 32-bit executable. The architecture must match across your application and every compiled library. An x64 application cannot link against an x86 GLFW or GLEW library. The linker will complain loudly, cryptically, and without a trace of sympathy.

Official grounding:

Recommended Dependency Folder Structure

Keeping third-party libraries inside the solution directory makes the project easier to move, archive, and share. One practical structure is:

The exact extracted folders may have longer versioned names. You can rename them for convenience, provided the include and library paths remain correct.

Step 1: Create a Visual Studio C++ Project

  1. Open Visual Studio.
  2. Select Create a new project.
  3. Choose Empty Project under C++ and Windows.
  4. Name the project and select a location.
  5. Open Build > Configuration Manager.
  6. Set the active solution platform to x64.
  7. Add a new C++ source file named main.cpp.

Using an empty project removes unrelated template code and makes dependency problems easier to diagnose.

Step 2: Download the Correct Libraries

Download GLFW

Download either the GLFW source package or a precompiled Windows binary package. When using binaries, choose the archive matching your target architecture and Visual C++ toolset. GLFW binary packages commonly contain separate library directories for different Visual Studio versions.

Download GLEW

Download the Windows binary release of GLEW. The package should contain:

  • include/GL/glew.h
  • lib/Release/x64/glew32.lib
  • lib/Release/x64/glew32s.lib
  • bin/Release/x64/glew32.dll

glew32s.lib is the static library. glew32.lib is an import library used with glew32.dll.

Download GLM

Download and extract GLM. The include path must point to the directory directly above the glm folder. A correct structure allows this include statement to work:

Official grounding:

Step 3: Configure Additional Include Directories

Right-click the C++ project in Solution Explorer and select Properties. At the top of the dialog, choose:

  • Configuration: All Configurations
  • Platform: x64

Navigate to:

Configuration Properties > C/C++ > General > Additional Include Directories

Add the following paths:

Preserve inherited values by leaving %(AdditionalIncludeDirectories) in the field. Visual Studio uses these directories when resolving preprocessor statements such as #include <GL/glew.h>.

Official grounding:

Step 4: Configure Additional Library Directories

Go to:

Configuration Properties > Linker > General > Additional Library Directories

Add the x64 library directories for GLFW and GLEW:

The directories must contain the actual .lib files. Do not place the filename itself in Additional Library Directories; this setting accepts folders, not individual libraries.

Step 5: Add the Linker Dependencies

For the simplest deployment, use static GLFW and static GLEW libraries. Navigate to:

Configuration Properties > Linker > Input > Additional Dependencies

Add:

opengl32.lib comes from the Windows SDK. glfw3.lib provides GLFW, while glew32s.lib provides the static version of GLEW.

Match the GLFW Runtime Library

Official GLFW binary archives may provide both glfw3.lib and glfw3_mt.lib. The correct choice depends on the Visual Studio runtime library setting under:

Configuration Properties > C/C++ > Code Generation > Runtime Library

  • Use glfw3.lib with /MD or /MDd.
  • Use glfw3_mt.lib with /MT or /MTd.

A runtime mismatch may produce linker warnings, unresolved symbols, or strange behavior that appears only when the application has already impressed your instructor.

Official grounding:

Step 6: Define GLEW_STATIC

When linking against glew32s.lib, GLEW must know that its functions are provided by a static library. Open:

Configuration Properties > C/C++ > Preprocessor > Preprocessor Definitions

Add:

You may alternatively place #define GLEW_STATIC before including glew.h, but a project-level definition is harder to forget when the code expands into multiple source files.

Step 7: Add a Working OpenGL Test Program

The following program creates an OpenGL 3.3 core-profile context, initializes GLEW, uses GLM to define a color, and clears the window every frame.

Why the Initialization Order Matters

GLEW must be initialized after glfwMakeContextCurrent. Modern OpenGL function addresses are associated with the active context and graphics driver. Calling glewInit before a context is current usually fails because GLEW has nowhere to retrieve those function pointers from.

GLFW_INCLUDE_NONE prevents GLFW from automatically including the platform’s legacy OpenGL header. This avoids header conflicts because GLEW already provides the declarations needed by the program.

The framebuffer callback updates glViewport whenever the drawable area changes. This matters on resized windows and high-DPI displays, where the framebuffer dimensions may differ from the window’s logical dimensions.

Official grounding:

Step 8: Build and Run the Project

Select Build > Build Solution. A successful run should display a dark blue window and print the OpenGL version and GPU renderer in the console.

If the application builds but the context cannot be created, update the graphics driver directly from NVIDIA, AMD, or Intel. OpenGL support on Windows is largely supplied by the installed graphics driver rather than by Visual Studio.

Using Dynamic Libraries Instead

Static linking is convenient for a small tutorial project because no GLFW or GLEW DLLs need to be distributed beside the executable. Dynamic linking is also valid, but the configuration changes.

For dynamic GLEW and GLFW, use:

Remove GLEW_STATIC, define GLFW_DLL, and copy these files into the same directory as the generated executable:

For a Debug x64 build, the executable is often placed under a path such as x64\Debug. Copying DLLs into the source directory does not help unless that directory is also part of the application’s DLL search path.

A Faster Setup with vcpkg

Manual configuration is valuable because it teaches how C++ headers, libraries, architectures, and runtime dependencies fit together. For ongoing projects, however, Microsoft’s vcpkg package manager can eliminate much of the path-editing ceremony.

Install the Dependencies

From a Developer Command Prompt or PowerShell session, set up vcpkg and run:

User-wide MSBuild integration automatically supplies include directories, link directories, libraries, and required DLL deployment for compatible Visual Studio projects. Make sure the project platform is x64 so it matches the x64-windows triplet.

Use a Manifest for Reproducible Projects

For a project intended to be shared or stored in version control, create a vcpkg.json file in the repository root:

Manifest mode records the project’s dependencies instead of relying on whatever happens to be installed globally. That makes the build easier to reproduce on another workstation or continuous integration server.

Official grounding:

Common OpenGL Visual Studio Errors

Cannot Open Include File: GL/glew.h

The compiler cannot find the GLEW headers. Confirm that Additional Include Directories points to the folder containing the GL directory, not directly to GL\glew.h.

Cannot Open Include File: GLFW/glfw3.h

The GLFW include path is incorrect. The selected directory should contain a child folder named GLFW.

LNK1104: Cannot Open File glfw3.lib

Visual Studio cannot locate the GLFW library. Check Additional Library Directories, verify the filename, and confirm that the property is configured for the currently active platform.

LNK2019 Unresolved External Symbol

This usually means that a required library is missing, the architecture is wrong, or static and dynamic configurations have been mixed. Confirm that x64 is used everywhere and that the selected GLEW library matches the preprocessor definitions.

Machine Type x86 Conflicts with x64

At least one dependency was built for 32-bit Windows while the application targets 64-bit Windows. Replace the library or change the entire project to Win32. Mixing architectures is not a compromise; it is simply a linker error wearing formal clothes.

glew32.dll or glfw3.dll Was Not Found

The project is dynamically linked, but Windows cannot locate the runtime DLL. Copy the DLL beside the executable or switch to static libraries.

GLEW Initialization Failed

Make sure GLFW successfully created a window and that glfwMakeContextCurrent was called before glewInit. Also check the graphics driver and requested OpenGL version.

The Window Opens but Displays Nothing

A blank window may be perfectly correct if your code only clears the framebuffer. To draw geometry, you still need shaders, vertex buffers, a vertex array object, and a draw call. Library setup opens the kitchen; it does not automatically cook the triangle.

Practical Experience and Lessons from OpenGL Project Setup

The most useful lesson from configuring OpenGL dependencies is that C++ build errors become much less mysterious when they are separated into stages. A missing header is a compiler problem. A missing symbol is a linker problem. A missing DLL is a runtime problem. Treating every failure as “OpenGL is broken” sends debugging in the wrong direction before the first pixel has even had a chance to misbehave.

A reliable setup process begins with architecture. Decide whether the project will use x64 or Win32, then verify every binary dependency before editing paths. Many beginners spend an hour rearranging include directories when the real issue is a 32-bit library hiding inside a 64-bit project. File Explorer does not advertise architecture clearly, so folder names and package descriptions matter.

Keeping dependencies inside a predictable project directory is another major improvement. Absolute paths such as C:\Users\Someone\Downloads\Libraries\GLFW may work today but fail when the project is copied, renamed, uploaded, or opened by a teammate. Paths based on $(SolutionDir) travel with the solution and reveal the dependency layout immediately.

It is also worth configuring Debug and Release deliberately. Developers often repair the Debug configuration, celebrate, switch to Release, and receive the same errors again because the properties were entered only for one configuration. Selecting All Configurations before adding include paths prevents that particular sequel. Library directories may still differ when separate Debug and Release binaries are used, so configuration-specific paths remain useful in larger projects.

Static linking is usually the calmest starting point. It reduces runtime deployment issues and creates an executable that does not depend on nearby GLFW and GLEW DLLs. Dynamic linking becomes more attractive when multiple applications share libraries, binary size matters, or dependencies are updated independently. Neither method is universally superior; the important part is avoiding a half-static, half-dynamic configuration assembled through optimism.

The include order teaches another valuable graphics-programming habit. GLEW must be included before a header that might include the old Windows OpenGL declarations. Defining GLFW_INCLUDE_NONE makes the intention explicit and protects the project from future include-order changes. Small defensive decisions like this become increasingly valuable as a project gains rendering modules, asset loaders, user-interface libraries, and precompiled headers.

Initialization should also be checked one operation at a time. Install a GLFW error callback, verify glfwInit, verify window creation, make the context current, initialize GLEW, and print GL_VERSION and GL_RENDERER. That sequence creates a diagnostic ladder. When something fails, the last successful step identifies the likely layer instead of leaving you to interrogate the entire graphics stack.

Finally, manual setup and package management serve different educational purposes. Manual configuration explains how Visual Studio compiles and links native libraries. vcpkg improves repeatability and reduces machine-specific configuration. A productive approach is to perform the manual setup once, understand every setting, and then use a manifest-based package workflow for serious projects. That way convenience does not become mystery, and mystery does not become three hours of staring at LNK2019.

Conclusion

To set up OpenGL, GLFW, GLEW, and GLM in Visual Studio, install the C++ desktop workload, choose a consistent architecture, add the required include and library directories, link opengl32.lib, GLFW, and GLEW, and initialize the components in the correct order.

GLFW must create and activate the OpenGL context before GLEW loads modern functions. GLM requires only an include path because it is header-only. Once the test window opens and prints the OpenGL version, the dependency setup is complete and the project is ready for shaders, vertex buffers, textures, cameras, lighting, and eventually a triangle you will defend as modern art.

Note: Library filenames and package folders may vary between releases and Visual Studio toolsets. Always use binaries that match the project architecture, runtime configuration, and compiler toolset.

SEO Metadata

This site uses cookies to offer you a better browsing experience. By browsing this website, you agree to our use of cookies.