diff --git a/.gitignore b/.gitignore
index 44a3101da701bd3b6e37b15a93a24e07f3c8c7ad..68ae9ca10740c9530df69bab77b88c587e84ea9f 100644
--- a/.gitignore
+++ b/.gitignore
@@ -9,3 +9,8 @@ compile_commands.json
 # dotfiles
 .idea/
 .cache/
+
+# windows vs stuff
+.vs/
+CMakePresets.json
+CMakeSettings.json
\ No newline at end of file
diff --git a/CMakeLists.txt b/CMakeLists.txt
index d854e292f907c79c95fa0f3d5d89c6d67b9a573f..af9ebf99df4e819b024e6505b28f179b3b37978a 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -1,21 +1,56 @@
-set(namespace "fggl")
-cmake_minimum_required(VERSION 3.13)
+cmake_minimum_required(VERSION 3.16)
 set(namespace "fggl")
 
-project(fggl
-	VERSION 0.1 
-	LANGUAGES CXX
-)
+# Define the project
 
-add_library(${PROJECT_NAME} STATIC)
+project(fggl
+	VERSION 0.1
+	DESCRIPTION ""
+	HOMEPAGE_URL ""
+	LANGUAGES CXX)
 
-set(FGGL_WAYLAND True)
+##
+# begin conan support
+##
+list(APPEND CMAKE_MODULE_PATH ${CMAKE_BINARY_DIR})
+list(APPEND CMAKE_PREFIX_PATH ${CMAKE_BINARY_DIR})
+
+if(NOT EXISTS "${CMAKE_BINARY_DIR}/conan.cmake")
+  message(STATUS "Downloading conan.cmake from https://github.com/conan-io/cmake-conan")
+  file(DOWNLOAD "https://raw.githubusercontent.com/conan-io/cmake-conan/0.18.1/conan.cmake"
+                "${CMAKE_BINARY_DIR}/conan.cmake"
+                TLS_VERIFY ON)
+endif()
+
+include(${CMAKE_BINARY_DIR}/conan.cmake)
+conan_cmake_run(CONANFILE conanfile.txt  # or relative build/conanfile.txt
+                BASIC_SETUP CMAKE_TARGETS
+                BUILD missing)
+##
+# end conan support
+##
 
 # Set C++ version
 set(CMAKE_CXX_STANDARD 17)
 set(CMAKE_CXX_STANDARD_REQUIRED True)
 set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
 
+add_library(${PROJECT_NAME} STATIC)
+
+##
+# begin windows support
+##
+if(MSVC)
+  target_compile_options(${PROJECT_NAME} PUBLIC "/ZI")
+  target_link_options(${PROJECT_NAME} PUBLIC "/INCREMENTAL")
+endif()
+##
+# end windows support
+##
+
+set(FGGL_WAYLAND True)
+
+
 include(GNUInstallDirs)
 target_include_directories(${PROJECT_NAME}
 	PRIVATE
@@ -48,21 +83,8 @@ if (DOXYGEN_FOUND)
 endif (DOXYGEN_FOUND)
 
 # depedencies
-find_package( glfw3 )
-if ( NOT glfw3_FOUND )
-  include(FetchContent)
-  set(GLFW_BUILD_DOCS OFF CACHE BOOL "" FORCE)
-  set(GLFW_BUILD_TESTS OFF CACHE BOOL "" FORCE)
-  set(GLFW_BUILD_EXAMPLES OFF CACHE BOOL "" FORCE)
-  if ( FGGL_WAYLAND )
-    set(GLFW_USE_WAYLAND True)
-  endif ()
-  FetchContent_Declare(
-    glfw3
-    URL https://github.com/glfw/glfw/releases/download/3.3.4/glfw-3.3.4.zip
-  )
-  FetchContent_MakeAvailable( glfw3 )
-endif ()
+find_package( glfw3 CONFIG REQUIRED )
+target_link_libraries(fggl PRIVATE glfw)
 
 # engine
 #add_subdirectory(vendor/imgui/)
diff --git a/conan.lock b/conan.lock
new file mode 100644
index 0000000000000000000000000000000000000000..4f78fb8b4a6def568283cf5054acc36ab8398063
--- /dev/null
+++ b/conan.lock
@@ -0,0 +1,34 @@
+{
+ "graph_lock": {
+  "nodes": {
+   "0": {
+    "options": "glfw:shared=False\nglfw:vulkan_static=False",
+    "requires": [
+     "1"
+    ],
+    "path": "conanfile.txt",
+    "context": "host"
+   },
+   "1": {
+    "ref": "glfw/3.3.7#b1675b8bd08103ef3974e36843431966",
+    "options": "shared=False\nvulkan_static=False",
+    "package_id": "d3cffeefc8c8bcb6be8abdd182cb1b56fc81bacc",
+    "prev": "7a205e7cb0d8ac4470491033ab29c8ac",
+    "requires": [
+     "2"
+    ],
+    "context": "host"
+   },
+   "2": {
+    "ref": "opengl/system#3582b5d3184289461f73339622c71d31",
+    "options": "",
+    "package_id": "5ab84d6acfe1f23c4fae0ab88f26e3a396351ac9",
+    "prev": "e0c823b9bed28348dd7f3bcedf045c58",
+    "context": "host"
+   }
+  },
+  "revisions_enabled": true
+ },
+ "version": "0.4",
+ "profile_host": "[settings]\narch=x86_64\narch_build=x86_64\nbuild_type=Release\ncompiler=Visual Studio\ncompiler.runtime=MD\ncompiler.version=16\nos=Windows\nos_build=Windows\n[options]\n[build_requires]\n[env]\n"
+}
\ No newline at end of file
diff --git a/conanfile.txt b/conanfile.txt
new file mode 100644
index 0000000000000000000000000000000000000000..90e6e04152622c4ab99e958cbdb1b13a2429960c
--- /dev/null
+++ b/conanfile.txt
@@ -0,0 +1,14 @@
+[requires]
+opengl/system
+glfw/3.3.7
+glad/0.1.35
+glm/0.9.9.8
+spdlog/1.10.0
+
+[generators]
+CMakeDeps
+CMakeToolchain
+
+[options]
+glad:gl_profile=core
+glad:gl_version=4.5
\ No newline at end of file
diff --git a/fggl/CMakeLists.txt b/fggl/CMakeLists.txt
index d9b16e98062c62e3014be1004de48c79a0408ab9..f1b055ddd3a89003bcb123991734f860c725a7f9 100644
--- a/fggl/CMakeLists.txt
+++ b/fggl/CMakeLists.txt
@@ -1,3 +1,8 @@
+
+# Config mode dependencies
+find_package(fmt CONFIG)
+find_package(spdlog CONFIG)
+
 configure_file(FgglConfig.h.in FgglConfig.h)
 
 # clang tidy
@@ -29,8 +34,8 @@ target_sources(${PROJECT_NAME}
 )
 
 # spdlog for cleaner logging
-find_package(spdlog REQUIRED)
-target_link_libraries(${PROJECT_NAME} PRIVATE fmt::fmt spdlog::spdlog)
+find_package( spdlog )
+target_link_libraries(${PROJECT_NAME} PRIVATE spdlog::spdlog)
 
 # Graphics backend
 add_subdirectory(gfx)
diff --git a/fggl/data/heightmap.cpp b/fggl/data/heightmap.cpp
index 1009cb677539ef392bcaaf9b3a8b80bfa2233826..c2a915dcafe2815d44278be7f44f693af0d60e9b 100644
--- a/fggl/data/heightmap.cpp
+++ b/fggl/data/heightmap.cpp
@@ -10,8 +10,8 @@
 namespace fggl::data {
 
     void gridVertexNormals(data::Vertex *locations) {
-        int sizeX = data::heightMaxX;
-        int sizeY = data::heightMaxZ;
+        const int sizeX = data::heightMaxX;
+        const int sizeY = data::heightMaxZ;
         const int gridOffset = sizeX * sizeY;
 
         // calculate normals for each triangle
diff --git a/fggl/data/procedural.cpp b/fggl/data/procedural.cpp
index f1239af75c2ac0281d47c229bad681bb58abcf6d..a89ecbb97527f246c1c813046e8b91ce39a7c82c 100644
--- a/fggl/data/procedural.cpp
+++ b/fggl/data/procedural.cpp
@@ -4,7 +4,9 @@
 
 #include <glm/ext/matrix_transform.hpp>
 #include <glm/gtc/quaternion.hpp>
+
 #include <iostream>
+#include <array>
 
 #include <glm/geometric.hpp>
 
@@ -155,7 +157,7 @@ fggl::data::Mesh fggl::data::make_quad_xz() {
 
 constexpr float HALF_PI = M_PI / 2.0F;
 static void populateMesh(fggl::data::Mesh& mesh, const fggl::math::mat4 transform, 
-		          int nIdx, const fggl::math::vec3* pos, const int* idx ) {
+		          const int nIdx, const fggl::math::vec3* pos, const int* idx ) {
 	int colIdx[nIdx];
 
 	// generate mesh
diff --git a/fggl/gfx/atlas.cpp b/fggl/gfx/atlas.cpp
index f4b34864d0e25938ce6e1654096a8fedd4fb0a6c..c8119a9a7f29c7011f0cafab0a58f37db5f5ff73 100644
--- a/fggl/gfx/atlas.cpp
+++ b/fggl/gfx/atlas.cpp
@@ -15,12 +15,12 @@ using Query = std::vector<fggl::gfx::Bounds2D>;
 static void populate_stbrp_query(Query& query, std::vector<stbrp_rect>& data) {
     for ( std::size_t i = 0; i < query.size(); i++ ) {
         data.push_back({
-            .id = (int)i,
-            .w = query[i].size.x,
-            .h = query[i].size.y,
-            .x = 0,
-            .y = 0,
-            .was_packed = 0
+            (int)i,
+            query[i].size.x,
+            query[i].size.y,
+            0,
+            0,
+            0
         });
     }
 }
diff --git a/fggl/gfx/ogl/CMakeLists.txt b/fggl/gfx/ogl/CMakeLists.txt
index 3eb9f94d1bfcdd66840c1ab2bdafc4a4b40bea3e..f065ca1684e56328e5a4b0dba2a2ac9b8dc714c0 100644
--- a/fggl/gfx/ogl/CMakeLists.txt
+++ b/fggl/gfx/ogl/CMakeLists.txt
@@ -11,16 +11,17 @@ target_sources(fggl
 # OpenGL Backend
 find_package( OpenGL REQUIRED )
 include_directories( ${OPENGL_INCLUDE_DIR} )
-target_link_libraries(fggl PUBLIC OpenGL::OpenGL GLEW)
+target_link_libraries(fggl PUBLIC opengl::opengl)
 
 # GLEW
-find_package( GLEW REQUIRED )
-include_directories( ${GLEW_INCLUDE_DIRS} )
+find_package( glad )
+target_link_libraries(${PROJECT_NAME} PRIVATE glad::glad)
 
 # Math
 # probably shouldn't be graphics dependent...
-find_package( glm REQUIRED )
+find_package( glm )
+target_link_libraries(${PROJECT_NAME} PRIVATE glm::glm)
 
 # FreeType
-find_package(Freetype REQUIRED )
-target_link_libraries(fggl PUBLIC Freetype::Freetype)
+#find_package(Freetype REQUIRED )
+#target_link_libraries(fggl PUBLIC Freetype::Freetype)
diff --git a/fggl/gfx/ogl/renderer.cpp b/fggl/gfx/ogl/renderer.cpp
index af9e019ad96d63917880cefd79e31ae4aa3f072a..04c73fc0285aa124b7b335346ed60cf48b244c2e 100644
--- a/fggl/gfx/ogl/renderer.cpp
+++ b/fggl/gfx/ogl/renderer.cpp
@@ -1,15 +1,20 @@
 #include <fggl/util/service.h>
 #include <spdlog/spdlog.h>
 
+#include "fggl/gfx/ogl/common.hpp"
+#include "fggl/gfx/window.hpp"
+
 #include <fggl/data/model.hpp>
 #include <fggl/gfx/camera.hpp>
 #include <fggl/gfx/ogl/renderer.hpp>
 #include <fggl/gfx/paint.hpp>
 #include <fggl/math/triangulation.hpp>
+
 #include <glm/ext/matrix_clip_space.hpp>
 #include <glm/ext/matrix_transform.hpp>
 #include <glm/glm.hpp>
 #include <glm/gtc/type_ptr.hpp>
+
 #include <memory>
 
 extern "C" {
@@ -68,8 +73,11 @@ constexpr auto static fggl_ogl_type(GLenum type) -> const char * {
 	return "unknown";
 }
 
-#pragma clang diagnostic push
-#pragma ide diagnostic ignored "bugprone-easily-swappable-parameters"
+#ifndef _MSC_VER
+	#pragma clang diagnostic push
+	#pragma ide diagnostic ignored "bugprone-easily-swappable-parameters"
+#endif
+
 void static fggl_ogl_to_spdlog(GLenum source, GLenum type, unsigned int msgId, GLenum severity, GLsizei  /*length*/,
 							   const char *message, const void * /*userParam*/) {
 	std::string fmt = "[GL] {}, {}: [{}]: {}";
@@ -90,8 +98,10 @@ void static fggl_ogl_to_spdlog(GLenum source, GLenum type, unsigned int msgId, G
 		break;
 	}
 }
-#pragma clang diagnostic pop
 
+#ifndef _MSC_VER
+	#pragma clang diagnostic pop
+#endif
 }
 
 /**
@@ -134,9 +144,10 @@ namespace fggl::gfx {
 
 	OpenGL4Backend::OpenGL4Backend(const Window &owner) : fggl::gfx::Graphics() {
 		// initialise GLEW, or fail
-		GLenum err = glewInit();
-		if (GLEW_OK != err) {
-			throw std::runtime_error("couldn't init glew");
+		// FIXME this binds the graphics stack to GLFW :'(
+		int version = gladLoadGLLoader(glfwGetProcAddress);
+		if (version == 0) {
+			printf("Failed to initialize OpenGL context\n");
 		}
 
 		// OpenGL debug Support
diff --git a/fggl/gfx/ogl/shader.cpp b/fggl/gfx/ogl/shader.cpp
index 0e922943feac0590d13126d598b1184020b47a8f..ec31c416887c5558c984ebd930c6b2c48bbae74b 100644
--- a/fggl/gfx/ogl/shader.cpp
+++ b/fggl/gfx/ogl/shader.cpp
@@ -179,7 +179,13 @@ bool ShaderCache::cacheLoad(GLuint pid, const BinaryCache* cache) {
 
 template<>
 bool fggl::data::fggl_deserialize(std::filesystem::path &data, fggl::gfx::BinaryCache *out) {
-	auto f = std::fopen( data.c_str(), "r");
+	auto f = 
+	#ifdef _MSC_VER
+		_wfopen(data.c_str(), L"r");
+	#else
+		std::fopen( data.c_str(), "r");
+	#endif
+
 	if ( f == nullptr ) {
         spdlog::warn("could not load cached shader, fp was null");
 		return false;
@@ -231,7 +237,13 @@ template<>
 bool fggl::data::fggl_serialize(std::filesystem::path &data, const fggl::gfx::BinaryCache *out) {
 
 	// try and write
-	auto f = std::fopen( data.c_str(), "w");
+	auto f =
+		#ifdef _MSC_VER
+			_wfopen( data.c_str(), L"w");
+		#else
+			std::fopen( data.c_str(), "w");
+		#endif
+
 	if ( f == nullptr ){
 		return false;
 	}
diff --git a/fggl/gfx/ogl4/canvas.cpp b/fggl/gfx/ogl4/canvas.cpp
index 36dcf09cccdca69e9c040b3e6fcfc6ab68bbf73d..8a51333b2de1780fec04a61abbe8777f54e07372 100644
--- a/fggl/gfx/ogl4/canvas.cpp
+++ b/fggl/gfx/ogl4/canvas.cpp
@@ -50,7 +50,7 @@ namespace fggl::gfx::ogl4 {
 
 			for (auto &type : path.m_types) {
 				if (type == PathType::PATH) {
-					verts.push_back({.position = path.m_points[idx++], .colour = colour});
+					verts.push_back({path.m_points[idx++], colour});
 				} else if (type == PathType::MOVE) {
 					// polygon finished
 					if (verts.size() < 3) {
@@ -65,7 +65,7 @@ namespace fggl::gfx::ogl4 {
 					}
 
 					verts.clear();
-					verts.push_back({.position = path.m_points[idx++], .colour = colour});
+					verts.push_back({path.m_points[idx++], colour});
 				} else if (type == PathType::COLOUR) {
 					colour = path.m_colours[colourIdx++];
 				} else {
@@ -126,4 +126,4 @@ namespace fggl::gfx::ogl4 {
 		glUseProgram( 0 );
 	}
 
-}
\ No newline at end of file
+}
diff --git a/include/fggl/debug/debug.h b/include/fggl/debug/debug.h
index 88419fbe36a422d40f07dc6f0a4bfaf50e1eb92e..4e303f65f6a20a1fc874bf7f5e6a90da5f32adae 100644
--- a/include/fggl/debug/debug.h
+++ b/include/fggl/debug/debug.h
@@ -25,10 +25,7 @@ namespace fggl::debug {
 			void draw();
 
 			inline void addWindow(const std::string &name, DebugUIDraw window) {
-				m_windows[name] = DebugWindow{
-					.m_visible = true,
-					.m_callback = std::move(window)
-				};
+				m_windows[name] = DebugWindow{true, std::move(window) };
 			}
 
 			inline void visible(bool state) {
diff --git a/include/fggl/ecs3/types.hpp b/include/fggl/ecs3/types.hpp
index 868447213b81c0095101bf604f6a21dac1878123..35b02f0112581818fa19c7e371b36b2d02af27eb 100644
--- a/include/fggl/ecs3/types.hpp
+++ b/include/fggl/ecs3/types.hpp
@@ -3,6 +3,7 @@
 
 #include <cstdarg>
 #include <utility>
+#include <functional>
 
 #include <fggl/ecs/component.hpp>
 #include <fggl/ecs3/utils.hpp>
diff --git a/include/fggl/gfx/ogl/common.hpp b/include/fggl/gfx/ogl/common.hpp
index 28786f54456740ddc12c6bdb53fb97b39e4b5417..855ac7d5683b1aef24473de4bb58639bee335dd4 100644
--- a/include/fggl/gfx/ogl/common.hpp
+++ b/include/fggl/gfx/ogl/common.hpp
@@ -5,6 +5,11 @@
  * Ensure Graphics libraries are in the right order.
  */
 
-#include <GL/glew.h>
+#ifdef _glfw_h_
+	#warning glfw included before opengl, bad things may happen
+#endif
+
+#include <glad/glad.h>
+typedef void* (* GLADloadproc)(const char *name);
 
 #endif
diff --git a/include/fggl/gfx/ogl/shader.hpp b/include/fggl/gfx/ogl/shader.hpp
index a6abc9466fabfa89cdf24c38979a4b76c0b372fa..1081f34fc978323ef329682189a142606c9e19d7 100644
--- a/include/fggl/gfx/ogl/shader.hpp
+++ b/include/fggl/gfx/ogl/shader.hpp
@@ -24,9 +24,9 @@ namespace fggl::gfx {
 
 	inline ShaderConfig ShaderFromName(const std::string &name) {
 		return {
-			.name = name,
-			.vertex = name + "_vert.glsl",
-			.fragment = name + "_frag.glsl"
+			name,
+			name + "_vert.glsl",
+			name + "_frag.glsl"
 		};
 	}
 
diff --git a/include/fggl/gfx/ogl/types.hpp b/include/fggl/gfx/ogl/types.hpp
index 5bc889772650171c9edfb5538c8d14d50cbcc1d8..e878cf0f3adb06f685ac0ea0d719e3922e51d0b9 100644
--- a/include/fggl/gfx/ogl/types.hpp
+++ b/include/fggl/gfx/ogl/types.hpp
@@ -255,10 +255,10 @@ namespace fggl::gfx::ogl {
 	template<typename V, typename T>
 	AttributeF attribute(std::size_t offset) {
 		return AttributeF{
-			.attrType = attr_type<T>::attr,
-			.elmCount = attr_type<T>::size,
-			.stride = sizeof(V),
-			.offset = offset
+			 attr_type<T>::attr,
+			attr_type<T>::size,
+			sizeof(V),
+			offset
 		};
 	}
 
diff --git a/include/fggl/math/triangulation.hpp b/include/fggl/math/triangulation.hpp
index a62860a22268cffd75ed46bed843965c8e20adf2..3b04935717a8b21ee5a6f233702e098dec8d550b 100644
--- a/include/fggl/math/triangulation.hpp
+++ b/include/fggl/math/triangulation.hpp
@@ -1,6 +1,9 @@
 #ifndef FGGL_MATH_TRIANGULATION_HPP
 #define FGGL_MATH_TRIANGULATION_HPP
 
+#define _USE_MATH_DEFINES
+#include <cmath>
+
 #include <fggl/math/types.hpp>
 #include <fggl/data/model.hpp>
 
@@ -17,10 +20,10 @@ namespace fggl::math {
 	 * Put an angle in the range [-PI, PI].
 	 */
 	inline float clampAngle(float radianAngle) {
-		if (radianAngle <= M_PI) {
-			return radianAngle + M_PI_2;
-		} else if (radianAngle > M_PI) {
-			return radianAngle - M_PI_2;
+		if (radianAngle <= math::PI) {
+			return radianAngle + math::HALF_PI;
+		} else if (radianAngle > math::PI) {
+			return radianAngle - math::HALF_PI;
 		} else {
 			return radianAngle;
 		}
@@ -110,10 +113,7 @@ namespace fggl::math {
 	}
 
 	static data::Vertex2D pointToVertex(const math::vec2 &point) {
-		return data::Vertex2D{
-			.position = point,
-			.colour = {1.0f, 1.0f, 1.0f}
-		};
+		return data::Vertex2D{ point, {1.0f, 1.0f, 1.0f} };
 	}
 
 	/**
diff --git a/include/fggl/math/types.hpp b/include/fggl/math/types.hpp
index bfce42938b26af8b285d9709f81ecadabdc44984..a91410011b146218cb90045dac03a5444f0cff84 100644
--- a/include/fggl/math/types.hpp
+++ b/include/fggl/math/types.hpp
@@ -3,13 +3,24 @@
 
 #include <tuple>
 
-#include <glm/ext/matrix_transform.hpp>
 #include <glm/glm.hpp>
+#include <glm/ext/matrix_transform.hpp>
 #include <glm/gtc/quaternion.hpp>
 #include <glm/gtx/quaternion.hpp>
 
+#ifndef M_PI
+    #define M_PI 3.14159265358979323846
+#endif
+
+#ifndef M_PI_2
+    #define M_PI_2 1.57079632679489661923
+#endif
+
 namespace fggl::math {
 
+	constexpr float PI = M_PI;
+	constexpr float HALF_PI = M_PI_2;
+
 	// math types (aliased for ease of use)
 	using vec4 = glm::vec4;
 	using vec4f = glm::vec4;