diff --git a/DevScreenshots/8. Cubemap.png b/DevScreenshots/8. Cubemap.png
new file mode 100644
index 0000000..ea823d9
Binary files /dev/null and b/DevScreenshots/8. Cubemap.png differ
diff --git a/Game/src/MainState.cpp b/Game/src/MainState.cpp
index 04db89b..bbabee9 100644
--- a/Game/src/MainState.cpp
+++ b/Game/src/MainState.cpp
@@ -21,5 +21,4 @@ void MainState::render(nf::Renderer& renderer) {
 
 void MainState::onExit() {
 	Log("MainState onExit!");
-
 }
\ No newline at end of file
diff --git a/NFPackCreator/AssetBuild/base/shaders/cubemapFragment.shader b/NFPackCreator/AssetBuild/base/shaders/cubemapFragment.shader
new file mode 100644
index 0000000..ca2d0ee
--- /dev/null
+++ b/NFPackCreator/AssetBuild/base/shaders/cubemapFragment.shader
@@ -0,0 +1,16 @@
+#version 330 core
+
+in vec3 texCoord;
+
+uniform samplerCube cm;
+
+out vec4 color;
+
+void main() {
+	vec3 tc;
+	tc = vec3(-texCoord.x, texCoord.y, texCoord.z);
+	if (texCoord.y > 0.99 || texCoord.y < -0.99) {
+		tc = vec3(texCoord.x, texCoord.y, texCoord.z);
+	}
+	color = texture(cm, tc);
+}
diff --git a/NFPackCreator/AssetBuild/base/shaders/cubemapVertex.shader b/NFPackCreator/AssetBuild/base/shaders/cubemapVertex.shader
new file mode 100644
index 0000000..2fb68e1
--- /dev/null
+++ b/NFPackCreator/AssetBuild/base/shaders/cubemapVertex.shader
@@ -0,0 +1,15 @@
+#version 330 core
+
+layout(location = 0) in vec3 pos;
+
+uniform mat4 view;
+uniform mat4 proj;
+
+out vec3 texCoord;
+
+void main() {
+	texCoord = pos;
+
+	vec4 vertexPos = proj * view * vec4(pos, 1.0);
+	gl_Position = vertexPos.xyww;
+}
\ No newline at end of file
diff --git a/NothinFancy/NothinFancy.vcxproj b/NothinFancy/NothinFancy.vcxproj
index 31e9c3f..7585a7b 100644
--- a/NothinFancy/NothinFancy.vcxproj
+++ b/NothinFancy/NothinFancy.vcxproj
@@ -200,6 +200,7 @@
     
     
     
+    
     
     
     
@@ -218,6 +219,7 @@
   
     
     
+    
     
     
     
diff --git a/NothinFancy/NothinFancy.vcxproj.filters b/NothinFancy/NothinFancy.vcxproj.filters
index 20f3352..c80a66a 100644
--- a/NothinFancy/NothinFancy.vcxproj.filters
+++ b/NothinFancy/NothinFancy.vcxproj.filters
@@ -72,6 +72,9 @@
     
       Source Files
     
+    
+      Source Files
+    
   
   
     
@@ -140,6 +143,9 @@
     
       Header Files
     
+    
+      Header Files
+    
   
   
     
diff --git a/NothinFancy/src/Assets.cpp b/NothinFancy/src/Assets.cpp
index 3a77c9e..778164c 100644
--- a/NothinFancy/src/Assets.cpp
+++ b/NothinFancy/src/Assets.cpp
@@ -16,6 +16,15 @@ namespace nf {
 
 	}
 
+	ACubemap::~ACubemap() {
+		delete[] frontData;
+		delete[] backData;
+		delete[] topData;
+		delete[] bottomData;
+		delete[] leftData;
+		delete[] rightData;
+	}
+
 	AShader::~AShader() {
 
 	}
@@ -31,6 +40,7 @@ namespace nf {
 	void AssetPack::load(const char* packName) {
 		std::string path = "assets/" + (std::string)packName;
 		std::string packContents = readFile(path);
+		unsigned int cubemapCount = 0;
 		while (packContents.size()) {
 			unsigned int startingPos = packContents.find_first_of("#NFASSET ") + 9;
 			packContents = packContents.substr(9);
@@ -62,6 +72,56 @@ namespace nf {
 				continue;
 			}
 			if (extension == "png") {
+				if (assetName.find("_cmfront") != std::string::npos || assetName.find("_cmback") != std::string::npos || assetName.find("_cmtop") != std::string::npos || assetName.find("_cmbottom") != std::string::npos || assetName.find("_cmleft") != std::string::npos || assetName.find("_cmright") != std::string::npos) {
+					static std::unordered_map cubemaps;
+					std::string cmName = assetName.substr(0, assetName.find('_'));
+					ACubemap* curr;
+					if (cubemaps.find(cmName) == cubemaps.end()) {
+						cubemaps[cmName] = new ACubemap;
+						cubemaps[cmName]->numImages = 0;
+					}
+					curr = cubemaps[cmName];
+					if (curr->numImages == 6)
+						Error("Duplicate cubemap images in pack \"" + (std::string)packName + (std::string)"\"!");
+					if (assetName.find("_cmfront") != std::string::npos) {
+						curr->frontData = new char[assetSize];
+						std::memcpy(curr->frontData, &assetContents[0], assetSize);
+						curr->frontSize = assetSize;
+					}
+					if (assetName.find("_cmback") != std::string::npos) {
+						curr->backData = new char[assetSize];
+						std::memcpy(curr->backData, &assetContents[0], assetSize);
+						curr->backSize = assetSize;
+					}
+					if (assetName.find("_cmtop") != std::string::npos) {
+						curr->topData = new char[assetSize];
+						std::memcpy(curr->topData, &assetContents[0], assetSize);
+						curr->topSize = assetSize;
+					}
+					if (assetName.find("_cmbottom") != std::string::npos) {
+						curr->bottomData = new char[assetSize];
+						std::memcpy(curr->bottomData, &assetContents[0], assetSize);
+						curr->bottomSize = assetSize;
+					}
+					if (assetName.find("_cmleft") != std::string::npos) {
+						curr->leftData = new char[assetSize];
+						std::memcpy(curr->leftData, &assetContents[0], assetSize);
+						curr->leftSize = assetSize;
+					}
+					if (assetName.find("_cmright") != std::string::npos) {
+						curr->rightData = new char[assetSize];
+						std::memcpy(curr->rightData, &assetContents[0], assetSize);
+						curr->rightSize = assetSize;
+					}
+					curr->numImages++;
+
+					if (curr->numImages == 6) {
+						m_assets[cmName] = curr;
+					}
+
+					cubemapCount++;
+					continue;
+				}
 				ATexture* texture = new ATexture;
 				texture->data = new char[assetSize];
 				std::memcpy(texture->data, &assetContents[0], assetSize);
@@ -87,6 +147,8 @@ namespace nf {
 			}
 			Error("Invalid asset extention in pack \"" + (std::string)packName + (std::string)"\"!");
 		}
+		if (cubemapCount % 6 != 0)
+			Error("Could not find full cubemap in pack \"" + (std::string)packName + (std::string)"\"!")
 	}
 
 	Asset* AssetPack::operator[](const char* in) {
diff --git a/NothinFancy/src/Renderer/Camera.cpp b/NothinFancy/src/Renderer/Camera.cpp
index 4181953..5f0c483 100644
--- a/NothinFancy/src/Renderer/Camera.cpp
+++ b/NothinFancy/src/Renderer/Camera.cpp
@@ -71,7 +71,7 @@ namespace nf {
 		return m_front;
 	}
 
-	void Camera::bind(Shader* shader) {
+	void Camera::bind(Shader* entityShader, Shader* cubemapShader) {
 		glm::mat4 view;
 
 		switch (m_type) {
@@ -112,8 +112,11 @@ namespace nf {
 			}
 		}
 		glm::vec3 pos(m_position.x, m_position.y, m_position.z);
-		shader->setUniform("camera.pos", pos);
-		shader->setUniform("view", view);
+		entityShader->setUniform("camera.pos", pos);
+		entityShader->setUniform("view", view);
+
+		glm::mat4 cubemapView = glm::mat4(glm::mat3(view));
+		cubemapShader->setUniform("view", cubemapView);
 	}
 
 	Camera::~Camera() {
diff --git a/NothinFancy/src/Renderer/Drawable/Cubemap.cpp b/NothinFancy/src/Renderer/Drawable/Cubemap.cpp
new file mode 100644
index 0000000..36d4757
--- /dev/null
+++ b/NothinFancy/src/Renderer/Drawable/Cubemap.cpp
@@ -0,0 +1,129 @@
+#include "Cubemap.h"
+
+#include 
+#include "GL/glew.h"
+#include "stb_image.h"
+
+#include "Assets.h"
+
+namespace nf {
+	Cubemap::Cubemap() :
+		m_constructed(false),
+		m_id(0)
+	{
+
+	}
+
+	void Cubemap::create(Asset* cubemapAsset) {
+		m_constructed = true;
+		ACubemap& cm = *(ACubemap*)cubemapAsset;
+		glGenTextures(1, &m_id);
+		glBindTexture(GL_TEXTURE_CUBE_MAP, m_id);
+		struct CMFace {
+			CMFace(unsigned char* d, unsigned int w, unsigned int h, unsigned int nc) :
+				data(d),
+				width(w),
+				height(h),
+				nChannels(nc)
+			{
+
+			}
+			unsigned char* data;
+			unsigned int width;
+			unsigned int height;
+			unsigned int nChannels;
+		};
+		std::vector faces;
+		int tempWidth, tempHeight, tempNChannels;
+		unsigned char* tempData;
+		stbi_set_flip_vertically_on_load(false);
+		tempData = stbi_load_from_memory((unsigned char*)cm.leftData, cm.leftSize, &tempWidth, &tempHeight, &tempNChannels, 0);
+		faces.emplace_back(tempData, tempWidth, tempHeight, tempNChannels);
+		tempData = stbi_load_from_memory((unsigned char*)cm.rightData, cm.rightSize, &tempWidth, &tempHeight, &tempNChannels, 0);
+		faces.emplace_back(tempData, tempWidth, tempHeight, tempNChannels);
+		stbi_set_flip_vertically_on_load(true);
+		tempData = stbi_load_from_memory((unsigned char*)cm.topData, cm.topSize, &tempWidth, &tempHeight, &tempNChannels, 0);
+		faces.emplace_back(tempData, tempWidth, tempHeight, tempNChannels);
+		tempData = stbi_load_from_memory((unsigned char*)cm.bottomData, cm.bottomSize, &tempWidth, &tempHeight, &tempNChannels, 0);
+		faces.emplace_back(tempData, tempWidth, tempHeight, tempNChannels);
+		stbi_set_flip_vertically_on_load(false);
+		tempData = stbi_load_from_memory((unsigned char*)cm.backData, cm.backSize, &tempWidth, &tempHeight, &tempNChannels, 0);
+		faces.emplace_back(tempData, tempWidth, tempHeight, tempNChannels);
+		tempData = stbi_load_from_memory((unsigned char*)cm.frontData, cm.frontSize, &tempWidth, &tempHeight, &tempNChannels, 0);
+		faces.emplace_back(tempData, tempWidth, tempHeight, tempNChannels);
+		for (unsigned int i = 0; i < faces.size(); i++) {
+			glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, GL_RGBA, faces[i].width, faces[i].height, 0, faces[i].nChannels == 3 ? GL_RGB : GL_RGBA, GL_UNSIGNED_BYTE, faces[i].data);
+			stbi_image_free(faces[i].data);
+		}
+		glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+		glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+		glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+		glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+		glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
+
+		float vb[] = {
+			-1.0f,  1.0f, -1.0f,
+			-1.0f, -1.0f, -1.0f,
+			 1.0f, -1.0f, -1.0f,
+			 1.0f, -1.0f, -1.0f,
+			 1.0f,  1.0f, -1.0f,
+			-1.0f,  1.0f, -1.0f,
+
+			-1.0f, -1.0f,  1.0f,
+			-1.0f, -1.0f, -1.0f,
+			-1.0f,  1.0f, -1.0f,
+			-1.0f,  1.0f, -1.0f,
+			-1.0f,  1.0f,  1.0f,
+			-1.0f, -1.0f,  1.0f,
+
+			 1.0f, -1.0f, -1.0f,
+			 1.0f, -1.0f,  1.0f,
+			 1.0f,  1.0f,  1.0f,
+			 1.0f,  1.0f,  1.0f,
+			 1.0f,  1.0f, -1.0f,
+			 1.0f, -1.0f, -1.0f,
+
+			-1.0f, -1.0f,  1.0f,
+			-1.0f,  1.0f,  1.0f,
+			 1.0f,  1.0f,  1.0f,
+			 1.0f,  1.0f,  1.0f,
+			 1.0f, -1.0f,  1.0f,
+			-1.0f, -1.0f,  1.0f,
+
+			-1.0f,  1.0f, -1.0f,
+			 1.0f,  1.0f, -1.0f,
+			 1.0f,  1.0f,  1.0f,
+			 1.0f,  1.0f,  1.0f,
+			-1.0f,  1.0f,  1.0f,
+			-1.0f,  1.0f, -1.0f,
+
+			-1.0f, -1.0f, -1.0f,
+			-1.0f, -1.0f,  1.0f,
+			 1.0f, -1.0f, -1.0f,
+			 1.0f, -1.0f, -1.0f,
+			-1.0f, -1.0f,  1.0f,
+			 1.0f, -1.0f,  1.0f
+		};
+		m_vao = new VertexArray;
+		m_vao->addBuffer(vb, sizeof(vb));
+		m_vao->push(3);
+		m_vao->finishBufferLayout();
+	}
+
+	bool Cubemap::isConstructed() {
+		return m_constructed;
+	}
+
+	void Cubemap::render() {
+		m_vao->bind();
+		glBindTexture(GL_TEXTURE_CUBE_MAP, m_id);
+		glDepthFunc(GL_LEQUAL);
+		glDrawArrays(GL_TRIANGLES, 0, 36);
+		glDepthFunc(GL_LESS);
+	}
+
+	Cubemap::~Cubemap() {
+		if(m_constructed)
+			glDeleteTextures(1, &m_id);
+	}
+}
\ No newline at end of file
diff --git a/NothinFancy/src/Renderer/Drawable/Entity.cpp b/NothinFancy/src/Renderer/Drawable/Entity.cpp
index 8cca00b..9ffe35c 100644
--- a/NothinFancy/src/Renderer/Drawable/Entity.cpp
+++ b/NothinFancy/src/Renderer/Drawable/Entity.cpp
@@ -6,6 +6,7 @@
 
 namespace nf {
 	Entity::Entity() :
+		m_constructed(false),
 		m_model(nullptr),
 		m_position(0.0),
 		m_rotation(0.0),
@@ -15,6 +16,7 @@ namespace nf {
 	}
 
 	void Entity::create(Asset* modelAsset, Asset* textureAsset) {
+		m_constructed = true;
 		AModel& model = *(AModel*)modelAsset;
 		if (model.alreadyLoaded && textureAsset == nullptr) {
 			m_model = model.loadedModel;
@@ -36,6 +38,10 @@ namespace nf {
 		model.loadedModel = m_model;
 	}
 
+	bool Entity::isConstructed() {
+		return m_constructed;
+	}
+
 	void Entity::setPosition(double x, double y, double z) {
 		m_position = { x, y, z };
 	}
diff --git a/NothinFancy/src/Renderer/Drawable/UIElement.cpp b/NothinFancy/src/Renderer/Drawable/UIElement.cpp
index 945bf2e..c94a49d 100644
--- a/NothinFancy/src/Renderer/Drawable/UIElement.cpp
+++ b/NothinFancy/src/Renderer/Drawable/UIElement.cpp
@@ -2,6 +2,7 @@
 
 namespace nf {
 	UIElement::UIElement() :
+		m_constructed(false),
 		m_centeredX(false),
 		m_centeredY(false)
 	{
diff --git a/NothinFancy/src/Renderer/Drawable/UITexture.cpp b/NothinFancy/src/Renderer/Drawable/UITexture.cpp
index a32ccf6..dc6f5a5 100644
--- a/NothinFancy/src/Renderer/Drawable/UITexture.cpp
+++ b/NothinFancy/src/Renderer/Drawable/UITexture.cpp
@@ -7,14 +7,15 @@
 
 namespace nf {
 	UITexture::UITexture() :
-		m_texture(0)
+		m_texture(nullptr),
+		m_scale(1.0f)
 	{
 
 	}
 
-	void UITexture::create(Asset* texture, const Vec2& position, double scale) {
+	void UITexture::create(Asset* textureAsset, const Vec2& position, double scale) {
 		m_constructed = true;
-		ATexture* tex = (ATexture*)texture;
+		ATexture* tex = (ATexture*)textureAsset;
 		m_position = position;
 		m_scale = (float)scale;
 		if (tex->alreadyLoaded) {
diff --git a/NothinFancy/src/Renderer/Renderer.cpp b/NothinFancy/src/Renderer/Renderer.cpp
index b3c7617..060dfea 100644
--- a/NothinFancy/src/Renderer/Renderer.cpp
+++ b/NothinFancy/src/Renderer/Renderer.cpp
@@ -8,12 +8,15 @@
 #include "Shader.h"
 #include "Light.h"
 #include "Entity.h"
+#include "Cubemap.h"
 #include "UIElement.h"
 #include "Camera.h"
 #include "Utility.h"
 
 namespace nf {
-	Renderer::Renderer(Application* app) {
+	Renderer::Renderer(Application* app) :
+		m_cubemap(nullptr)
+	{
 		m_app = app;
 		m_hdc = GetDC(m_app->getWindow());
 		PIXELFORMATDESCRIPTOR pfd = {
@@ -69,6 +72,9 @@ namespace nf {
 		const char* uiTextureVertex = m_baseAP["uiTextureVertex.shader"]->data;
 		const char* uiTextureFragment = m_baseAP["uiTextureFragment.shader"]->data;
 		m_uiTextureShader = new Shader(uiTextureVertex, uiTextureFragment);
+		const char* cubemapVertex = m_baseAP["cubemapVertex.shader"]->data;
+		const char* cubemapFragment = m_baseAP["cubemapFragment.shader"]->data;
+		m_cubemapShader = new Shader(cubemapVertex, cubemapFragment);
 
 		BaseAssets::cube = (AModel*)m_baseAP["cube.obj"];
 		BaseAssets::plane = (AModel*)m_baseAP["plane.obj"];
@@ -80,7 +86,7 @@ namespace nf {
 	}
 
 	void Renderer::render(Entity& in) {
-		if (in.getModel() == nullptr)
+		if (in.isConstructed() == false)
 			Error("Tried to render Entity before being created!");
 		m_lGame.push_back(&in);
 		//TODO: Sort transparent objects by distance; Farthest first
@@ -95,10 +101,17 @@ namespace nf {
 			Error("Tried to render a light before being created!");
 		m_lights.push_back(&in);
 	}
+	void Renderer::render(Cubemap& in) {
+		if (in.isConstructed() == false)
+			Error("Tried to render a cubemap before being created!");
+		m_cubemap = ∈
+	}
 
 	void Renderer::doFrame(Camera* camera) {
+		//Begin frame
 		glViewport(0, 0, m_app->getConfig().width, m_app->getConfig().height);
 		glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+		camera->bind(m_entityShader, m_cubemapShader);
 
 		//Draw Entities (3D models)
 		glm::mat4 proj = glm::perspective(glm::radians(45.0f), (float)m_app->getConfig().width / (float)m_app->getConfig().height, 0.1f, 100000.0f);
@@ -107,7 +120,6 @@ namespace nf {
 		for (Entity* draw : m_lGame) {
 			Entity& curr = *draw;
 			curr.bind(m_entityShader);
-			camera->bind(m_entityShader);
 			//TODO: Clean this up a bit
 			m_entityShader->setUniform("numberOfLights", (int)m_lights.size() + 1);
 			for (unsigned int i = 0; i < m_lights.size(); i++) {
@@ -120,19 +132,24 @@ namespace nf {
 		m_lGame.clear();
 		m_lights.clear();
 
+		//Draw cubemap where there isn't anything else
+		if (m_cubemap != nullptr) {
+			m_cubemapShader->setUniform("proj", proj);
+			m_cubemap->render();
+		}
+		m_cubemap = nullptr;
+
 		//Draw UI elements
 		glDisable(GL_DEPTH_TEST);
 		proj = glm::ortho(0.0f, (float)m_app->getConfig().width, 0.0f, (float)m_app->getConfig().height);
 		for (UIElement* draw : m_lUI) {
 			UIElement& curr = *draw;
 			if (curr.identity() == "text") {
-				m_textShader->bind();
 				m_textShader->setUniform("proj", proj);
 				curr.render(m_textShader, m_app->getConfig().width, m_app->getConfig().height);
 				continue;
 			}
 			if (curr.identity() == "texture") {
-				m_uiTextureShader->bind();
 				m_uiTextureShader->setUniform("proj", proj);
 				curr.render(m_uiTextureShader, m_app->getConfig().width, m_app->getConfig().height);
 			}
diff --git a/NothinFancy/src/Renderer/Shader.cpp b/NothinFancy/src/Renderer/Shader.cpp
index 9932261..839ca51 100644
--- a/NothinFancy/src/Renderer/Shader.cpp
+++ b/NothinFancy/src/Renderer/Shader.cpp
@@ -48,21 +48,25 @@ namespace nf {
 	}
 
 	void Shader::setUniform(const std::string& name, glm::mat4& data) {
+		bind();
 		if (m_uniformLocations.find(name) == m_uniformLocations.end())
 			getUniformLocation(name);
 		glUniformMatrix4fv(m_uniformLocations[name], 1, GL_FALSE, glm::value_ptr(data));
 	}
 	void Shader::setUniform(const std::string& name, glm::vec3& data) {
+		bind();
 		if (m_uniformLocations.find(name) == m_uniformLocations.end())
 			getUniformLocation(name);
 		glUniform3fv(m_uniformLocations[name], 1, glm::value_ptr(data));
 	}
 	void Shader::setUniform(const std::string& name, int data) {
+		bind();
 		if (m_uniformLocations.find(name) == m_uniformLocations.end())
 			getUniformLocation(name);
 		glUniform1i(m_uniformLocations[name], data);
 	}
 	void Shader::setUniform(const std::string& name, float data) {
+		bind();
 		if (m_uniformLocations.find(name) == m_uniformLocations.end())
 			getUniformLocation(name);
 		glUniform1f(m_uniformLocations[name], data);
diff --git a/NothinFancy/src/Renderer/Texture.cpp b/NothinFancy/src/Renderer/Texture.cpp
index 911ac4d..331981e 100644
--- a/NothinFancy/src/Renderer/Texture.cpp
+++ b/NothinFancy/src/Renderer/Texture.cpp
@@ -20,7 +20,7 @@ namespace nf {
 		glBindTexture(GL_TEXTURE_2D, m_id);
 		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
 		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
-		glTexImage2D(GL_TEXTURE_2D, 0, nChannels == 3 ? GL_RGB : GL_RGBA, m_x, m_y, 0, nChannels == 3 ? GL_RGB : GL_RGBA, GL_UNSIGNED_BYTE, texture);
+		glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, m_x, m_y, 0, nChannels == 3 ? GL_RGB : GL_RGBA, GL_UNSIGNED_BYTE, texture);
 		glGenerateMipmap(GL_TEXTURE_2D);
 		stbi_image_free(texture);
 	}
diff --git a/NothinFancy/src/include/Assets.h b/NothinFancy/src/include/Assets.h
index 507693f..af7758c 100644
--- a/NothinFancy/src/include/Assets.h
+++ b/NothinFancy/src/include/Assets.h
@@ -9,7 +9,6 @@ namespace nf {
 	struct Asset {
 		char* data;
 		bool alreadyLoaded = false;
-
 		virtual ~Asset();
 	};
 
@@ -26,6 +25,25 @@ namespace nf {
 		~ATexture() override;
 	};
 
+	struct ACubemap : Asset {
+		char* frontData;
+		size_t frontSize;
+		char* backData;
+		size_t backSize;
+		char* topData;
+		size_t topSize;
+		char* bottomData;
+		size_t bottomSize;
+		char* leftData;
+		size_t leftSize;
+		char* rightData;
+		size_t rightSize;
+
+		unsigned int numImages;
+
+		~ACubemap();
+	};
+
 	struct AShader : Asset {
 		~AShader() override;
 	};
diff --git a/NothinFancy/src/include/Camera.h b/NothinFancy/src/include/Camera.h
index d594ba5..982f89d 100644
--- a/NothinFancy/src/include/Camera.h
+++ b/NothinFancy/src/include/Camera.h
@@ -27,7 +27,7 @@ namespace nf {
 		const Vec3& getPosition();
 		const Vec3& getRotation();
 
-		void bind(Shader* shader);
+		void bind(Shader* entityShader, Shader* cubemapShader);
 
 		~Camera();
 	private:
diff --git a/NothinFancy/src/include/Cubemap.h b/NothinFancy/src/include/Cubemap.h
new file mode 100644
index 0000000..604fa71
--- /dev/null
+++ b/NothinFancy/src/include/Cubemap.h
@@ -0,0 +1,20 @@
+#pragma once
+#include "Drawable.h"
+
+namespace nf {
+	struct Asset;
+
+	class Cubemap : public Drawable {
+	public:
+		Cubemap();
+
+		void create(Asset* cubemapAsset);
+		bool isConstructed();
+		void render();
+
+		~Cubemap();
+	private:
+		bool m_constructed;
+		unsigned int m_id;
+	};
+}
\ No newline at end of file
diff --git a/NothinFancy/src/include/Entity.h b/NothinFancy/src/include/Entity.h
index a229ce3..0a4eca5 100644
--- a/NothinFancy/src/include/Entity.h
+++ b/NothinFancy/src/include/Entity.h
@@ -11,6 +11,7 @@ namespace nf {
 		Entity();
 
 		void create(Asset* modelAsset, Asset* textureAsset = nullptr);
+		bool isConstructed();
 
 		void setPosition(double x, double y, double z);
 		void setPosition(const Vec3& position);
@@ -27,6 +28,7 @@ namespace nf {
 	private:
 		void setModelMatrix(Shader* shader);
 
+		bool m_constructed;
 		Model* m_model;
 
 		Vec3 m_position;
diff --git a/NothinFancy/src/include/NothinFancy.h b/NothinFancy/src/include/NothinFancy.h
index 9d9b649..a2f5961 100644
--- a/NothinFancy/src/include/NothinFancy.h
+++ b/NothinFancy/src/include/NothinFancy.h
@@ -10,6 +10,7 @@
 #include "IntroGamestate.h"
 #include "Assets.h"
 #include "Light.h"
+#include "Cubemap.h"
 #include "Text.h"
 #include "UITexture.h"
 #include "Input.h"
@@ -54,6 +55,7 @@ namespace nf {
 		void render(Entity& in);
 		void render(UIElement& in);
 		void render(Light& in);
+		void render(Cubemap& in);
 
 		void doFrame(Camera* camera);
 
@@ -68,10 +70,12 @@ namespace nf {
 
 		std::vector m_lights;
 		std::vector m_lGame;
+		Cubemap* m_cubemap;
 		std::vector m_lUI;
 		Shader* m_entityShader;
 		Shader* m_textShader;
 		Shader* m_uiTextureShader;
+		Shader* m_cubemapShader;
 	};
 
 	class Application {
diff --git a/NothinFancy/src/include/Renderer.h b/NothinFancy/src/include/Renderer.h
index bd74a00..ca5a2a3 100644
--- a/NothinFancy/src/include/Renderer.h
+++ b/NothinFancy/src/include/Renderer.h
@@ -10,6 +10,7 @@ namespace nf {
 	class Entity;
 	class UIElement;
 	class Light;
+	class Cubemap;
 	class Camera;
 
 	class Renderer {
@@ -19,6 +20,7 @@ namespace nf {
 		void render(Entity& in);
 		void render(UIElement& in);
 		void render(Light& in);
+		void render(Cubemap& in);
 
 		void doFrame(Camera* camera);
 
@@ -33,9 +35,11 @@ namespace nf {
 
 		std::vector m_lights;
 		std::vector m_lGame;
+		Cubemap* m_cubemap;
 		std::vector m_lUI;
 		Shader* m_entityShader;
 		Shader* m_textShader;
 		Shader* m_uiTextureShader;
+		Shader* m_cubemapShader;
 	};
 }
\ No newline at end of file
diff --git a/NothinFancy/src/include/UITexture.h b/NothinFancy/src/include/UITexture.h
index 2e34ac1..46999d8 100644
--- a/NothinFancy/src/include/UITexture.h
+++ b/NothinFancy/src/include/UITexture.h
@@ -10,7 +10,7 @@ namespace nf {
 	public:
 		UITexture();
 
-		void create(Asset* texture, const Vec2& position, double scale = 1.0);
+		void create(Asset* textureAsset, const Vec2& position, double scale = 1.0);
 		const char* identity() override;
 		void render(Shader* shader, unsigned int windowWidth, unsigned int windowHeight) override;