diff --git a/source/build/src/animvpx.cpp b/source/build/src/animvpx.cpp
index a612db7b0..88446425c 100644
--- a/source/build/src/animvpx.cpp
+++ b/source/build/src/animvpx.cpp
@@ -398,7 +398,7 @@ int32_t animvpx_render_frame(animvpx_codec_ctx *codec, double animvpx_aspect)
 
     if (!texuploaded)
     {
-		texture->CreateTexture(codec->width, codec->height, false, false);
+		texture->CreateTexture(codec->width, codec->height, FHardwareTexture::TrueColor, false);
         texuploaded = 1;
     }
 	texture->LoadTexture(codec->pic);
diff --git a/source/build/src/glsurface.cpp b/source/build/src/glsurface.cpp
index 1e5589725..d396eb7b2 100644
--- a/source/build/src/glsurface.cpp
+++ b/source/build/src/glsurface.cpp
@@ -27,7 +27,7 @@ bool glsurface_initialize(vec2_t bufferResolution)
 	buffer.Resize(bufferRes.x * bufferRes.y);
 
 	bufferTexture = GLInterface.NewTexture();
-	bufferTexture->CreateTexture(bufferRes.x, bufferRes.y, true, false);
+	bufferTexture->CreateTexture(bufferRes.x, bufferRes.y, FHardwareTexture::Indexed, false);
 
     glsurface_setPalette(curpalettefaded);
 	GLInterface.SetSurfaceShader();
@@ -52,7 +52,7 @@ void glsurface_setPalette(void* pPalette)
 	if (!paletteTexture)
 	{
 		paletteTexture = GLInterface.NewTexture();
-		paletteTexture->CreateTexture(256, 1, false, false);
+		paletteTexture->CreateTexture(256, 1, FHardwareTexture::TrueColor, false);
 	}
 	paletteTexture->LoadTexture(palette);
 	GLInterface.BindTexture(1, paletteTexture, SamplerNoFilterClampXY);
diff --git a/source/build/src/polymost.cpp b/source/build/src/polymost.cpp
index 87467ac80..eca268cd7 100644
--- a/source/build/src/polymost.cpp
+++ b/source/build/src/polymost.cpp
@@ -5230,7 +5230,7 @@ static int32_t gen_font_glyph_tex(void)
         }
     }
 
-	polymosttext->CreateTexture(256, 128, false, false);
+	polymosttext->CreateTexture(256, 128, FHardwareTexture::TrueColor, false);
 	polymosttext->LoadTexture((uint8_t*)tbuf);
 	polymosttext->SetSampler(SamplerNoFilterClampXY);
     Xfree(tbuf);
diff --git a/source/build/src/texcache.cpp b/source/build/src/texcache.cpp
index 4d47805a3..7ff1586e1 100644
--- a/source/build/src/texcache.cpp
+++ b/source/build/src/texcache.cpp
@@ -51,7 +51,7 @@ FHardwareTexture* GLInstance::CreateIndexedTexture(FTexture* tex)
 	}
 
 	auto glpic = GLInterface.NewTexture();
-	glpic->CreateTexture(siz.x, siz.y, true, false);
+	glpic->CreateTexture(siz.x, siz.y, FHardwareTexture::Indexed, false);
 
 	TArray<uint8_t> flipped(siz.x * siz.y, true);
 	FlipNonSquareBlock(flipped.Data(), p, siz.y, siz.x, siz.y);
@@ -65,7 +65,7 @@ FHardwareTexture* GLInstance::CreateIndexedTexture(FTexture* tex)
 //
 //===========================================================================
 
-FHardwareTexture* GLInstance::CreateTrueColorTexture(FTexture* tex, int palid, bool checkfulltransparency)
+FHardwareTexture* GLInstance::CreateTrueColorTexture(FTexture* tex, int palid, bool checkfulltransparency, bool rgb8bit)
 {
 	auto siz = tex->GetSize();
 	bool npoty = false;
@@ -89,7 +89,10 @@ FHardwareTexture* GLInstance::CreateTrueColorTexture(FTexture* tex, int palid, b
 	}
 
 	auto glpic = GLInterface.NewTexture();
-	glpic->CreateTexture(texbuffer.mWidth, texbuffer.mHeight, false, true);
+	if (!rgb8bit)
+		glpic->CreateTexture(texbuffer.mWidth, texbuffer.mHeight, FHardwareTexture::TrueColor, true);
+	else
+		glpic->CreateTexture(texbuffer.mWidth, texbuffer.mHeight, FHardwareTexture::Brightmap, false);	// Use a more memory friendly format for simple brightmaps.
 	glpic->LoadTexture(texbuffer.mBuffer);
 	return glpic;
 }
@@ -110,7 +113,7 @@ FHardwareTexture* GLInstance::LoadTexture(FTexture* tex, int textype, int palid)
 	if (textype == TT_INDEXED)
 		hwtex = CreateIndexedTexture(tex);
 	else
-		hwtex = CreateTrueColorTexture(tex, textype == TT_HICREPLACE? -1 : palid, textype == TT_BRIGHTMAP);
+		hwtex = CreateTrueColorTexture(tex, textype == TT_HICREPLACE? -1 : palid, textype == TT_BRIGHTMAP, textype == TT_BRIGHTMAP);
 	
 	tex->SetHardwareTexture(palid, hwtex);
 	return hwtex;
diff --git a/source/build/src/voxmodel.cpp b/source/build/src/voxmodel.cpp
index dd1343513..55ffcbec3 100644
--- a/source/build/src/voxmodel.cpp
+++ b/source/build/src/voxmodel.cpp
@@ -69,7 +69,7 @@ FHardwareTexture *gloadtex(const int32_t *picbuf, int32_t xsiz, int32_t ysiz, in
     }
 
 	auto tex = GLInterface.NewTexture();
-	tex->CreateTexture(xsiz, ysiz, false, false);
+	tex->CreateTexture(xsiz, ysiz, FHardwareTexture::TrueColor, false);
 	tex->LoadTexture((uint8_t*)pic2);
 	tex->SetSampler(SamplerNoFilterClampXY);
     Xfree(pic2);
diff --git a/source/glbackend/gl_hwtexture.cpp b/source/glbackend/gl_hwtexture.cpp
index 61a0330a1..0ee7aedc1 100644
--- a/source/glbackend/gl_hwtexture.cpp
+++ b/source/glbackend/gl_hwtexture.cpp
@@ -38,20 +38,21 @@
 //
 //===========================================================================
 
-unsigned int FHardwareTexture::CreateTexture(int w, int h, bool eightbit, bool mipmapped)
+unsigned int FHardwareTexture::CreateTexture(int w, int h, int type, bool mipmapped)
 {
+	static int gltypes[] = { GL_R8, GL_RGBA8, GL_RGB5_A1, GL_RGBA2 };
 	glTexID = GLInterface.GetTextureID();
 	glActiveTexture(GL_TEXTURE15);
 	glBindTexture(GL_TEXTURE_2D, glTexID);
 	int size = std::max(w, h);
 	int bits = 0;
 	while (size) bits++, size >>= 1;
-	glTextureBytes = eightbit? 1 : 4;
-	if (eightbit) mipmapped = false;
+	internalType = type;
+	if (type == Indexed) mipmapped = false;
 	mWidth = w;
 	mHeight = h;
 
-	glTexStorage2D(GL_TEXTURE_2D, mipmapped? bits : 1, eightbit? GL_R8 : GL_RGBA8, w, h);
+	glTexStorage2D(GL_TEXTURE_2D, mipmapped? bits : 1, gltypes[type], w, h);
 	glBindTexture(GL_TEXTURE_2D, 0);
 	glActiveTexture(GL_TEXTURE0);
 	this->mipmapped = mipmapped;
@@ -85,20 +86,19 @@ unsigned int FHardwareTexture::LoadTexturePart(const unsigned char* buffer, int
 {
 	if (glTexID == 0) return 0;
 
-	int dstformat = glTextureBytes == 1 ? GL_R8 : GL_RGBA8;// TexFormat[gl_texture_format];
-	int srcformat = glTextureBytes == 1 ? GL_RED : GL_BGRA;// TexFormat[gl_texture_format];
+	int srcformat = internalType == Indexed ? GL_RED : GL_BGRA;// TexFormat[gl_texture_format];
 
 	glActiveTexture(GL_TEXTURE15);
 	glBindTexture(GL_TEXTURE_2D, glTexID);
 
-	if (glTextureBytes < 4) glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
+	if (internalType == Indexed) glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
 
 	glTexSubImage2D(GL_TEXTURE_2D, 0, x, y, w, h, srcformat, GL_UNSIGNED_BYTE, buffer);
 	if (mipmapped) glGenerateMipmap(GL_TEXTURE_2D);
 
 	glBindTexture(GL_TEXTURE_2D, 0);
 	glActiveTexture(GL_TEXTURE0);
-	if (glTextureBytes < 4) glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
+	if (internalType == Indexed) glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
 	return glTexID;
 }
 
diff --git a/source/glbackend/gl_hwtexture.h b/source/glbackend/gl_hwtexture.h
index 363663f33..917661701 100644
--- a/source/glbackend/gl_hwtexture.h
+++ b/source/glbackend/gl_hwtexture.h
@@ -10,12 +10,19 @@ class FTexture;
 class FHardwareTexture //: public IHardwareTexture
 {
 public:
+	enum
+	{
+		Indexed,
+		TrueColor,
+		HighColor,		// 16 bit - Can be used to save space in memory constrained scenarios at the cost of visual accuracy.
+		Brightmap,		// This can be stored as RGBA2 to save space, it also doesn't really need a mipmap.
+	};
 
 private:
 
 	int mSampler = 0;
 	unsigned int glTexID = 0;
-	int glTextureBytes = 4;
+	int internalType = TrueColor;
 	bool mipmapped = true;
 	int mWidth = 0, mHeight = 0;
 	int colorId = 0;
@@ -26,56 +33,18 @@ public:
 
 	//bool BindOrCreate(FTexture *tex, int texunit, int clampmode, int translation, int flags);
 
-	unsigned int CreateTexture(int w, int h, bool eightbit, bool mipmapped);
+	unsigned int CreateTexture(int w, int h, bool type, bool mipmapped) = delete;
+	unsigned int CreateTexture(int w, int h, int type, bool mipmapped);
 	unsigned int LoadTexture(const unsigned char * buffer);
 	unsigned int LoadTexturePart(const unsigned char* buffer, int x, int y, int w, int h);
 	unsigned int LoadTexture(FBitmap &bmp);
 	unsigned int GetTextureHandle();
 	int GetSampler() { return mSampler; }
 	void SetSampler(int sampler) { mSampler = sampler;  }
-	bool isIndexed() const { return glTextureBytes == 1; }
+	bool isIndexed() const { return internalType == Indexed; }
 
 	friend class FGameTexture;
 };
 
-// This class identifies a single source image to the game.
-// Since hightile palette variations are identified by file name, they will create separate game textures.
-class FGameTexture
-{
-	int Width, Height;
-	bool isHightile;
-
-	// Source image for this texture.
-	FTexture* sourceData = nullptr;
-	// indexed or the sole image for hightiles. 
-	FHardwareTexture* hwBase = nullptr;	
-	// If the number was large a TMap would be better - 
-	// but in most cases the maximum number of palettes for a single tile is less than 10 where a linear search is much faster than a TMap.
-	TArray<FHardwareTexture*> hwTextures;	
-public:
-	FGameTexture(bool hightile, int width, int height);
-	virtual ~FGameTexture();
-
-	// For dynamic subtypes.
-	virtual void SizeChanged(int width, int height);
-	static constexpr int MakeId(int palette, int palswap)
-	{
-		return palette + 256 * palswap;
-	}
-
-	FHardwareTexture* GetBaseTexture();
-	FHardwareTexture* CreateHardwareTexture(int palette, int palswap);
-
-	FHardwareTexture* GetHardwareTexture(int palette, int palswap)
-	{
-		if (isHightile) return GetBaseTexture();
-		auto id = MakeId(palette, palswap);
-		auto found = hwTextures.FindEx([=](FHardwareTexture* tex)
-			{
-				return tex->colorId == id;
-			});
-		if (!found) return CreateHardwareTexture(palette, palswap);
-	}
-};
 
 #endif
diff --git a/source/glbackend/gl_palmanager.cpp b/source/glbackend/gl_palmanager.cpp
index 5a25e643b..4a02ee4e2 100644
--- a/source/glbackend/gl_palmanager.cpp
+++ b/source/glbackend/gl_palmanager.cpp
@@ -195,7 +195,7 @@ void PaletteManager::BindPalette(int index)
 			if (palettes[uindex].paltexture == nullptr)
 			{
 				auto p = GLInterface.NewTexture();
-				p->CreateTexture(256, 1, false, false);
+				p->CreateTexture(256, 1, FHardwareTexture::TrueColor, false);
 				p->LoadTexture((uint8_t*)palettes[uindex].colors);
 				p->SetSampler(SamplerNoFilterClampXY);
 				palettes[uindex].paltexture = p;
@@ -237,7 +237,7 @@ void PaletteManager::BindPalswap(int index)
 			if (ps.swaptexture == nullptr)
 			{
 				auto p = GLInterface.NewTexture();
-				p->CreateTexture(256, numshades, true, false);
+				p->CreateTexture(256, numshades, FHardwareTexture::Indexed, false);
 				p->LoadTexture((uint8_t*)ps.lookup);
 				p->SetSampler(SamplerNoFilterClampXY);
 				ps.swaptexture = p;
diff --git a/source/glbackend/glbackend.h b/source/glbackend/glbackend.h
index d659a5ef3..5c44220cf 100644
--- a/source/glbackend/glbackend.h
+++ b/source/glbackend/glbackend.h
@@ -245,9 +245,7 @@ public:
 	
 	int GetTextureID();
 	FHardwareTexture* NewTexture();
-	FGameTexture* NewTexture(const char *name, bool hightile);
 	void BindTexture(int texunit, FHardwareTexture *texid, int sampler = NoSampler);
-	void BindTexture(int texunit, FGameTexture* texid, int sampler = NoSampler);
 	void UnbindTexture(int texunit);
 	void UnbindAllTextures();
 	void EnableBlend(bool on);
@@ -395,7 +393,7 @@ public:
 	}
 	
 	FHardwareTexture* CreateIndexedTexture(FTexture* tex);
-	FHardwareTexture* CreateTrueColorTexture(FTexture* tex, int palid, bool checkfulltransparency = false);
+	FHardwareTexture* CreateTrueColorTexture(FTexture* tex, int palid, bool checkfulltransparency = false, bool rgb8bit = false);
 	FHardwareTexture *LoadTexture(FTexture* tex, int texturetype, int palid);
 	bool SetTextureInternal(int globalpicnum, FTexture* tex, int palette, int method, int sampleroverride, float xpanning, float ypanning, FTexture *det, float detscale, FTexture *glow);