diff --git a/openrct2.vcxproj b/openrct2.vcxproj
index e55b959f7f..ec0c401011 100644
--- a/openrct2.vcxproj
+++ b/openrct2.vcxproj
@@ -62,6 +62,7 @@
+
@@ -366,6 +367,7 @@
+
diff --git a/src/drawing/engines/opengl/OpenGLDrawingEngine.cpp b/src/drawing/engines/opengl/OpenGLDrawingEngine.cpp
index abfcf329c1..eb7d88c0cb 100644
--- a/src/drawing/engines/opengl/OpenGLDrawingEngine.cpp
+++ b/src/drawing/engines/opengl/OpenGLDrawingEngine.cpp
@@ -38,6 +38,7 @@ IDrawingEngine * DrawingEngineFactory::CreateOpenGL()
#include "DrawLineShader.h"
#include "FillRectShader.h"
#include "SwapFramebuffer.h"
+#include "TextureCache.h"
#include "../../../core/Console.hpp"
#include "../../../core/Exception.hpp"
@@ -172,6 +173,9 @@ private:
DrawImageMaskedShader * _drawImageMaskedShader = nullptr;
DrawLineShader * _drawLineShader = nullptr;
FillRectShader * _fillRectShader = nullptr;
+
+ TextureCache * _textureCache = nullptr;
+
GLuint _vbo;
sint32 _offsetX;
@@ -181,14 +185,12 @@ private:
sint32 _clipRight;
sint32 _clipBottom;
- std::vector _textures;
- std::unordered_map _imageTextureMap;
-
public:
- OpenGLDrawingContext(OpenGLDrawingEngine * engine);
+ explicit OpenGLDrawingContext(OpenGLDrawingEngine * engine);
~OpenGLDrawingContext() override;
IDrawingEngine * GetEngine() override;
+ TextureCache * GetTextureCache() const { return _textureCache; }
void Initialise();
@@ -201,13 +203,6 @@ public:
void DrawSpriteSolid(uint32 image, sint32 x, sint32 y, uint8 colour) override;
void SetDPI(rct_drawpixelinfo * dpi);
- void InvalidateImage(uint32 image);
-
-private:
- GLuint GetOrLoadImageTexture(uint32 image);
- GLuint LoadImageTexture(uint32 image);
- void * GetImageAsARGB(uint32 image, uint32 tertiaryColour, uint32 * outWidth, uint32 * outHeight);
- void FreeTextures();
};
class OpenGLDrawingEngine : public IDrawingEngine
@@ -292,6 +287,8 @@ public:
colour.b / 255.0f,
colour.a / 255.0f };
}
+ _drawingContext->GetTextureCache()
+ ->SetPalette(Palette);
}
void Invalidate(sint32 left, sint32 top, sint32 right, sint32 bottom) override
@@ -366,7 +363,8 @@ public:
void InvalidateImage(uint32 image) override
{
- _drawingContext->InvalidateImage(image);
+ _drawingContext->GetTextureCache()
+ ->InvalidateImage(image);
}
rct_drawpixelinfo * GetDPI()
@@ -461,6 +459,7 @@ IDrawingEngine * DrawingEngineFactory::CreateOpenGL()
OpenGLDrawingContext::OpenGLDrawingContext(OpenGLDrawingEngine * engine)
{
_engine = engine;
+ _textureCache = new TextureCache();
}
OpenGLDrawingContext::~OpenGLDrawingContext()
@@ -469,6 +468,8 @@ OpenGLDrawingContext::~OpenGLDrawingContext()
delete _drawImageMaskedShader;
delete _drawLineShader;
delete _fillRectShader;
+
+ delete _textureCache;
}
IDrawingEngine * OpenGLDrawingContext::GetEngine()
@@ -571,7 +572,7 @@ void OpenGLDrawingContext::DrawSprite(uint32 image, sint32 x, sint32 y, uint32 t
}
}
- GLuint texture = GetOrLoadImageTexture(image);
+ GLuint texture = _textureCache->GetOrLoadImageTexture(image);
sint32 drawOffsetX = g1Element->x_offset;
sint32 drawOffsetY = g1Element->y_offset;
@@ -614,8 +615,8 @@ void OpenGLDrawingContext::DrawSpriteRawMasked(sint32 x, sint32 y, uint32 maskIm
rct_g1_element * g1ElementMask = gfx_get_g1_element(maskImage & 0x7FFFF);
rct_g1_element * g1ElementColour = gfx_get_g1_element(colourImage & 0x7FFFF);
- GLuint textureMask = GetOrLoadImageTexture(maskImage);
- GLuint textureColour = GetOrLoadImageTexture(colourImage);
+ GLuint textureMask = _textureCache->GetOrLoadImageTexture(maskImage);
+ GLuint textureColour = _textureCache->GetOrLoadImageTexture(colourImage);
sint32 drawOffsetX = g1ElementMask->x_offset;
sint32 drawOffsetY = g1ElementMask->y_offset;
@@ -656,7 +657,7 @@ void OpenGLDrawingContext::DrawSpriteSolid(uint32 image, sint32 x, sint32 y, uin
int g1Id = image & 0x7FFFF;
rct_g1_element * g1Element = gfx_get_g1_element(g1Id);
- GLuint texture = GetOrLoadImageTexture(image);
+ GLuint texture = _textureCache->GetOrLoadImageTexture(image);
sint32 drawOffsetX = g1Element->x_offset;
sint32 drawOffsetY = g1Element->y_offset;
@@ -711,112 +712,4 @@ void OpenGLDrawingContext::SetDPI(rct_drawpixelinfo * dpi)
_dpi = dpi;
}
-GLuint OpenGLDrawingContext::GetOrLoadImageTexture(uint32 image)
-{
- auto kvp = _imageTextureMap.find(image);
- if (kvp != _imageTextureMap.end())
- {
- return kvp->second;
- }
-
- GLuint texture = LoadImageTexture(image);
- _textures.push_back(texture);
- _imageTextureMap[image] = texture;
-
- // if ((_textures.size() % 100) == 0)
- // {
- // printf("Textures: %d\n", _textures.size());
- // }
-
- return texture;
-}
-
-GLuint OpenGLDrawingContext::LoadImageTexture(uint32 image)
-{
- GLuint texture;
- glGenTextures(1, &texture);
-
- uint32 width, height;
- void * pixels32 = GetImageAsARGB(image, 0, &width, &height);
-
- glBindTexture(GL_TEXTURE_2D, texture);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
- glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels32);
-
- delete [] (uint8 *) pixels32;
-
- return texture;
-}
-
-void * OpenGLDrawingContext::GetImageAsARGB(uint32 image, uint32 tertiaryColour, uint32 * outWidth, uint32 * outHeight)
-{
- int g1Id = image & 0x7FFFF;
- rct_g1_element * g1Element = gfx_get_g1_element(g1Id);
-
- uint32 width = (uint32)g1Element->width;
- uint32 height = (uint32)g1Element->height;
-
- size_t numPixels = width * height;
- uint8 * pixels8 = new uint8[numPixels];
- Memory::Set(pixels8, 0, numPixels);
-
- rct_drawpixelinfo dpi;
- dpi.bits = pixels8;
- dpi.pitch = 0;
- dpi.x = 0;
- dpi.y = 0;
- dpi.width = width;
- dpi.height = height;
- dpi.zoom_level = 0;
- gfx_draw_sprite_software(&dpi, image, -g1Element->x_offset, -g1Element->y_offset, tertiaryColour);
-
- uint8 * pixels32 = new uint8[width * height * 4];
- uint8 * src = pixels8;
- uint8 * dst = pixels32;
- for (size_t i = 0; i < numPixels; i++)
- {
- uint8 paletteIndex = *src++;
- if (paletteIndex == 0)
- {
- // Transparent
- *dst++ = 0;
- *dst++ = 0;
- *dst++ = 0;
- *dst++ = 0;
- }
- else
- {
- SDL_Color colour = _engine->Palette[paletteIndex];
- *dst++ = colour.r;
- *dst++ = colour.g;
- *dst++ = colour.b;
- *dst++ = colour.a;
- }
- }
-
- delete[] pixels8;
-
- *outWidth = width;
- *outHeight = height;
- return pixels32;
-}
-
-void OpenGLDrawingContext::InvalidateImage(uint32 image)
-{
- auto kvp = _imageTextureMap.find(image);
- if (kvp != _imageTextureMap.end())
- {
- GLuint texture = kvp->second;
- glDeleteTextures(1, &texture);
-
- _imageTextureMap.erase(kvp);
- }
-}
-
-void OpenGLDrawingContext::FreeTextures()
-{
- glDeleteTextures(_textures.size(), _textures.data());
-}
-
#endif /* DISABLE_OPENGL */
diff --git a/src/drawing/engines/opengl/TextureCache.cpp b/src/drawing/engines/opengl/TextureCache.cpp
new file mode 100644
index 0000000000..9f94bc916c
--- /dev/null
+++ b/src/drawing/engines/opengl/TextureCache.cpp
@@ -0,0 +1,151 @@
+#pragma region Copyright (c) 2014-2016 OpenRCT2 Developers
+/*****************************************************************************
+ * OpenRCT2, an open source clone of Roller Coaster Tycoon 2.
+ *
+ * OpenRCT2 is the work of many authors, a full list can be found in contributors.md
+ * For more information, visit https://github.com/OpenRCT2/OpenRCT2
+ *
+ * OpenRCT2 is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * A full copy of the GNU General Public License can be found in licence.txt
+ *****************************************************************************/
+#pragma endregion
+
+#include "../../../core/Memory.hpp"
+#include "TextureCache.h"
+
+extern "C"
+{
+ #include "../../drawing.h"
+}
+
+TextureCache::TextureCache()
+{
+}
+
+TextureCache::~TextureCache()
+{
+ FreeTextures();
+}
+
+void TextureCache::SetPalette(const SDL_Color * palette)
+{
+ Memory::CopyArray(_palette, palette, 256);
+}
+
+void TextureCache::InvalidateImage(uint32 image)
+{
+ auto kvp = _imageTextureMap.find(image);
+ if (kvp != _imageTextureMap.end())
+ {
+ GLuint texture = kvp->second;
+ glDeleteTextures(1, &texture);
+
+ _imageTextureMap.erase(kvp);
+ }
+}
+
+GLuint TextureCache::GetOrLoadImageTexture(uint32 image)
+{
+ auto kvp = _imageTextureMap.find(image);
+ if (kvp != _imageTextureMap.end())
+ {
+ return kvp->second;
+ }
+
+ GLuint texture = LoadImageTexture(image);
+ _imageTextureMap[image] = texture;
+
+ // if ((_textures.size() % 100) == 0)
+ // {
+ // printf("Textures: %d\n", _textures.size());
+ // }
+
+ return texture;
+}
+
+GLuint TextureCache::LoadImageTexture(uint32 image)
+{
+ GLuint texture;
+ glGenTextures(1, &texture);
+
+ uint32 width, height;
+ void * pixels32 = GetImageAsARGB(image, 0, &width, &height);
+
+ glBindTexture(GL_TEXTURE_2D, texture);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels32);
+
+ delete [] (uint8 *) pixels32;
+
+ return texture;
+}
+
+void * TextureCache::GetImageAsARGB(uint32 image, uint32 tertiaryColour, uint32* outWidth, uint32* outHeight)
+{
+ int g1Id = image & 0x7FFFF;
+ rct_g1_element * g1Element = gfx_get_g1_element(g1Id);
+
+ uint32 width = (uint32)g1Element->width;
+ uint32 height = (uint32)g1Element->height;
+
+ size_t numPixels = width * height;
+ uint8 * pixels8 = new uint8[numPixels];
+ Memory::Set(pixels8, 0, numPixels);
+
+ rct_drawpixelinfo dpi;
+ dpi.bits = pixels8;
+ dpi.pitch = 0;
+ dpi.x = 0;
+ dpi.y = 0;
+ dpi.width = width;
+ dpi.height = height;
+ dpi.zoom_level = 0;
+ gfx_draw_sprite_software(&dpi, image, -g1Element->x_offset, -g1Element->y_offset, tertiaryColour);
+
+ uint8 * pixels32 = new uint8[width * height * 4];
+ uint8 * src = pixels8;
+ uint8 * dst = pixels32;
+ for (size_t i = 0; i < numPixels; i++)
+ {
+ uint8 paletteIndex = *src++;
+ if (paletteIndex == 0)
+ {
+ // Transparent
+ *dst++ = 0;
+ *dst++ = 0;
+ *dst++ = 0;
+ *dst++ = 0;
+ }
+ else
+ {
+ SDL_Color colour = _palette[paletteIndex];
+ *dst++ = colour.r;
+ *dst++ = colour.g;
+ *dst++ = colour.b;
+ *dst++ = colour.a;
+ }
+ }
+
+ delete[] pixels8;
+
+ *outWidth = width;
+ *outHeight = height;
+ return pixels32;
+}
+
+void TextureCache::FreeTextures()
+{
+ size_t numTextures = _imageTextureMap.size();
+ auto textures = std::vector(numTextures);
+ for (auto kvp : _imageTextureMap)
+ {
+ textures.push_back(kvp.second);
+ }
+
+ glDeleteTextures(textures.size(), textures.data());
+}
diff --git a/src/drawing/engines/opengl/TextureCache.h b/src/drawing/engines/opengl/TextureCache.h
new file mode 100644
index 0000000000..d0e9f54b8e
--- /dev/null
+++ b/src/drawing/engines/opengl/TextureCache.h
@@ -0,0 +1,41 @@
+#pragma region Copyright (c) 2014-2016 OpenRCT2 Developers
+/*****************************************************************************
+ * OpenRCT2, an open source clone of Roller Coaster Tycoon 2.
+ *
+ * OpenRCT2 is the work of many authors, a full list can be found in contributors.md
+ * For more information, visit https://github.com/OpenRCT2/OpenRCT2
+ *
+ * OpenRCT2 is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * A full copy of the GNU General Public License can be found in licence.txt
+ *****************************************************************************/
+#pragma endregion
+
+#pragma once
+
+#include
+#include
+#include "../../../common.h"
+#include "OpenGLAPI.h"
+
+class TextureCache
+{
+private:
+ std::unordered_map _imageTextureMap;
+ SDL_Color _palette[256];
+
+public:
+ TextureCache();
+ ~TextureCache();
+ void SetPalette(const SDL_Color * palette);
+ void InvalidateImage(uint32 image);
+ GLuint GetOrLoadImageTexture(uint32 image);
+
+private:
+ GLuint LoadImageTexture(uint32 image);
+ void * GetImageAsARGB(uint32 image, uint32 tertiaryColour, uint32 * outWidth, uint32 * outHeight);
+ void FreeTextures();
+};
diff --git a/src/drawing/sprite.c b/src/drawing/sprite.c
index 3fb9dfed32..f04cd9a5cf 100644
--- a/src/drawing/sprite.c
+++ b/src/drawing/sprite.c
@@ -383,7 +383,7 @@ void FASTCALL gfx_draw_sprite_palette_set_software(rct_drawpixelinfo *dpi, int i
.pitch = dpi->pitch,
.zoom_level = dpi->zoom_level - 1
};
- gfx_draw_sprite_palette_set(&zoomed_dpi, (image_type << 28) | (image_element - g1_source->zoomed_offset), x >> 1, y >> 1, palette_pointer, unknown_pointer);
+ gfx_draw_sprite_palette_set_software(&zoomed_dpi, (image_type << 28) | (image_element - g1_source->zoomed_offset), x >> 1, y >> 1, palette_pointer, unknown_pointer);
return;
}