Table of Contents >> Show >> Hide
- What You’ll Build
- Prerequisites
- The Stack in One Breath
- Option A (Recommended): One-Command Installs with vcpkg
- Option B: Manual Setup (If You Like Flipping Switches)
- Smoke Test: A Minimal main.cpp
- Common Build Errors (and Fast Fixes)
- Optional: CMakeLists.txt for Visual Studio
- Performance & Quality of Life Tips
- Conclusion
- Hands-On Experience Notes (Extra )
Short version: you’ll create a C++ project in Visual Studio, add a window/input library (GLFW), load modern OpenGL function pointers with GLAD, and draw your first triangle-ish background without wrestling dragons in Linker settings. We’ll cover the fast, package-manager route (vcpkg) and the classic manual route, with code that compiles on Windows 10/11 in Visual Studio 2019 or 2022.
What You’ll Build
A tiny, modern OpenGL app that opens a resizable window, initializes a core-profile context (e.g., 3.3+), loads OpenGL functions via GLAD, and clears the screen every frame. It’s the perfect base for writing shaders, uploading vertices, and pretending you’re a GPU whisperer.
Prerequisites
- Visual Studio 2019 or 2022 with the “Desktop development with C++” workload installed.
- Windows 10/11 with a graphics driver that supports the OpenGL version you plan to use (4.x on most modern GPUs). On Windows, you link against
opengl32.libthat’s the OS’s door into your driver.
The Stack in One Breath
OpenGL does the rendering, GLFW creates the window & input events, and GLAD loads modern OpenGL functions at runtime. Order matters: include GLAD before GLFW (or tell GLFW not to include the platform’s OpenGL headers). You also only call GLAD’s loader after a context exists (right after glfwMakeContextCurrent).
Option A (Recommended): One-Command Installs with vcpkg
Microsoft’s vcpkg cleanly installs and wires C/C++ libraries for Visual Studio. It supports both “classic” and “manifest” workflows. Below is the manifest approach (new-project-friendly), followed by the minimal “classic” commands.
Step 1 Install vcpkg and integrate with Visual Studio
- Clone vcpkg anywhere (e.g.,
C:devvcpkg) and runbootstrap-vcpkg.bat. - Run
vcpkg integrate installonce. Visual Studio then knows how to find headers/libs installed by vcpkg.
Step 2 Add a manifest and declare dependencies
In your project root (same folder as your .sln or top-level CMakeLists.txt), create a vcpkg.json:
Now install your declared ports:
Tip: If you aren’t using a manifest, you can do the “classic” install:
Step 3 Include order and initialization
For most setups:
- Include
<glad/glad.h>(or<glad/gl.h>if you generated GLAD 2) before<GLFW/glfw3.h>. - Alternatively, define
GLFW_INCLUDE_NONEbefore including GLFW so it won’t pull in the platform’sgl.h. - Only call GLAD’s load function after you’ve made an OpenGL context current.
Step 4 Minimal Visual Studio project
Create a new empty C++ Console App (or an Empty Project). Add a single main.cpp and paste the “Smoke Test” below. Thanks to vcpkg integration, you don’t need to touch Additional Include/Library DirectoriesVS sees the headers and libs automatically once the packages are installed for the matching triplet (x64).
Option B: Manual Setup (If You Like Flipping Switches)
- Get GLFW: Either download prebuilt Windows binaries or build from source with CMake to produce
glfw3.lib(static) orglfw3dll.lib + glfw3.dll(dynamic). Put headers under a knownincludepath and libs under a knownlibpath. - Get GLAD: Use the GLAD online generator. Pick “C/C++”, “OpenGL”, choose a version (3.3 Core is a sweet minimum, 4.6 Core if your hardware supports it), tick “Generate loader,” then download. You’ll get
includefiles and aglad.csourceadd that source file to your project so the GLAD symbols get compiled in. - Wire Visual Studio: In Project → Properties:
- C/C++ > General > Additional Include Directories: add your GLFW and GLAD include folders.
- Linker > General > Additional Library Directories: add your GLFW lib folder (e.g.,
lib-vc2022). - Linker > Input > Additional Dependencies: add
glfw3.lib(or the import lib if you’re using the DLL) andopengl32.lib. If you built GLAD as a static lib, add that too. If you addedglad.cto your project, you don’t need a GLAD libjust compile it.
Note: On Windows, you always link
opengl32.libif you call OpenGL directly. If you use the GLFW DLL, you still linkopengl32.libbecause your app uses OpenGL APIs. - Architecture must match: Use x64 for both your project configuration and the libraries you picked (glfw3 x64, glad x64).
Smoke Test: A Minimal main.cpp
Pick one GLAD include & load style. GLAD 1 (common in many packages) uses <glad/glad.h> + gladLoadGLLoader. GLAD 2 uses <glad/gl.h> + gladLoadGL. If you installed GLAD from vcpkg and aren’t sure, try GLAD 1 first.
Variant A GLAD 1 style
Variant B GLAD 2 style
Common Build Errors (and Fast Fixes)
“OpenGL header already included”
GLFW by default may include your platform OpenGL headers; GLAD also wants to include/own them. Fix either by including GLAD before GLFW (#include <glad/...> then #include <GLFW/glfw3.h>) or by #define GLFW_INCLUDE_NONE before including GLFW.
LNK2019 / unresolved external symbol glad...
You didn’t compile/link GLAD’s implementation. If you used the GLAD zip, make sure glad.c is in your project. If you used a package, ensure the GLAD library target is added and the architecture (x64) matches the project.
Can’t find opengl32.lib or “cannot open input file opengl32.lib”
Install the Windows SDK via Visual Studio Installer. Then verify you’re building x64 and that the Windows SDK is selected in Project Properties → General. (You normally don’t ship this DLL yourself; Windows provides it.)
Runtime library mismatch (/MT vs /MD)
If you built GLFW yourself and linked it into an MSBuild project, make sure your app and GLFW were compiled with compatible runtime options: /MDd for Debug, /MD for Release. Mixing static vs dynamic runtime flags across libs causes elusive link errors.
vcpkg isn’t “taking effect” in Visual Studio
Confirm you ran vcpkg integrate install, installed the right triplet (x64-windows if your project is x64), and actually built once so IntelliSense can see headers. With manifest mode, verify vcpkg.json sits at the project root.
Optional: CMakeLists.txt for Visual Studio
If you prefer CMake projects in Visual Studio, use a CMakePresets.json or pass the vcpkg toolchain on configure. A minimal CMake file:
Performance & Quality of Life Tips
- Call
glfwSwapInterval(1)during development to avoid burning your laptop fans. - Request the OpenGL version you actually need; 3.3 Core remains a widely compatible baseline on Windows PCs.
- Use a debug context during development:
glfwWindowHint(GLFW_OPENGL_DEBUG_CONTEXT, GLFW_TRUE);and hookglDebugMessageCallbackfor readable GPU errors. - Prefer core profile to avoid time-traveling into deprecated fixed-function APIs.
Conclusion
Setting up OpenGL in Visual Studio is straightforward once you separate concerns: GLFW for the window, GLAD for function loading, and a clean package manager (vcpkg) to do the wiring. From here, your next steps are vertex buffers, shaders, andeventuallyeither a cheerful renderer or a respectable pile of experiments. Both are wins.
SEO Goodies
sapo: Want a clean, modern OpenGL starter on Windows? This step-by-step Visual Studio guide shows two pathsvcpkg one-command installs or manual linkingplus a minimal app you can compile today. We cover include order, linking opengl32.lib, GLAD 1 vs GLAD 2, typical link errors, and a ready-to-paste main.cpp. Build a stable base, then jump straight to shaders and real-time graphics.
Hands-On Experience Notes (Extra )
Pick a baseline and stick to it. For beginners, OpenGL 3.3 Core hits the sweet spot: the shader pipeline is fully featured, examples are plentiful, and it runs on almost every discrete GPU plus many iGPUs. Requesting 4.6 is fine on modern hardware, but you can always raise the bar later.
Decide on GLAD 1 vs GLAD 2 early. Projects and tutorials mix these. GLAD 1 typically uses #include <glad/glad.h> and gladLoadGLLoader. GLAD 2 prefers #include <glad/gl.h> and gladLoadGL. Mixing headers between versions produces extremely confusing errors. If you use a package manager, check the version it ships and mirror that in your codebase. If you roll your own GLAD from the website, keep the generated files in a third_party/glad/ folder and commit them so teammates build the exact same bindings.
Header order is non-negotiable. “OpenGL header already included” happens when GLFW pulls in the platform OpenGL headers first. The fastest, least surprising rule: define GLFW_INCLUDE_NONE and then include GLAD, then GLFW. That makes the order explicit across translation units. If someone accidentally includes GLFW first in a new file, the macro still prevents surprises.
Always compile the GLAD implementation once. If you generated GLAD as source, add glad.c to exactly one target. Adding it twice gives duplicate symbol errors; adding it zero times yields “unresolved external” errors. In multi-target solutions, consider building GLAD into a small static library (e.g., gladlib) and link that everywhere you need it.
Mind your triplet/arch. When your project builds for x64, install glfw3:x64-windows and glad:x64-windows. Accidentally mixing x86 libraries into an x64 solution (or vice-versa) causes opaque link failures. Similarly, if you compile GLFW yourself, match the MSVC toolset and runtime (/MD Release, /MDd Debug) used by your app.
Use a Debug context and validation early. Creating an OpenGL debug context surfaces warnings like “invalid enum” or “buffer out of bounds” in a readable way. Without it, you’re often staring at a black screen with no clues. Pair this with glGetError() in assert-like helpers early on; remove or gate them later for performance.
VSync during development, uncapped later. glfwSwapInterval(1) keeps your app from spinning at 8000 FPS on the splash screen, which makes laptops toasty and fans dramatic. Disable VSync when profiling or measuring GPU timing; otherwise your frame time sits suspiciously near your monitor’s refresh interval.
Ship DLLs consciously. If you link the GLFW DLL import library, remember to ship the glfw3.dll next to your executable. If you statically link GLFW, know that you might need to link extra system libs depending on how it was built. With vcpkg, this is mostly handled, but manual setups should double-check the Linker Input list.
Prefer a CMake toolchain for teams. Even if you love MSBuild solutions, a CMakeLists can define targets, link libs, and generate projects for teammates on different IDEs. Visual Studio opens CMake projects out of the box now, and it integrates well with vcpkg manifests. That said, if your team is Windows-only and MSBuild-centric, vcpkg’s MSBuild integration alone often suffices.
Keep your drivers fresh. On Windows, OpenGL feature support flows through your GPU driver via opengl32.dll. If you request 4.6 but only get 3.0 at runtime, odds are you’re using Microsoft’s Basic Display Adapter driver or an outdated vendor driver. Install (or reinstall) the latest NVIDIA/AMD/Intel package and try again.
Iterate from “clear the screen” to “draw a triangle” methodically. Add VAO/VBO setup in tiny steps, compile/attach/link shaders, and check for errors after each call. When something breaks, revert to the last known working version quickly. OpenGL is powerful, but the error messages tend to be… let’s call it “zen.” Small steps preserve your sanity.
Document your environment. Note your GLAD flavor (1 or 2), OpenGL version, vcpkg triplet, and any custom CMake or MSBuild settings in a README.md. Future youand your future collaboratorwill thank you when they don’t spend Saturday reversing header orders.