mirror of https://github.com/OpenRCT2/OpenRCT2.git
extract texture generation code to new class
This commit is contained in:
parent
8185a88e47
commit
4896d14940
|
@ -62,6 +62,7 @@
|
|||
<ClCompile Include="src\drawing\engines\opengl\OpenGLFramebuffer.cpp" />
|
||||
<ClCompile Include="src\drawing\engines\opengl\OpenGLShaderProgram.cpp" />
|
||||
<ClCompile Include="src\drawing\engines\opengl\SwapFramebuffer.cpp" />
|
||||
<ClCompile Include="src\drawing\engines\opengl\TextureCache.cpp" />
|
||||
<ClCompile Include="src\drawing\engines\SoftwareDrawingEngine.cpp" />
|
||||
<ClCompile Include="src\drawing\font.c" />
|
||||
<ClCompile Include="src\drawing\line.c" />
|
||||
|
@ -366,6 +367,7 @@
|
|||
<ClInclude Include="src\drawing\engines\opengl\OpenGLFramebuffer.h" />
|
||||
<ClInclude Include="src\drawing\engines\opengl\OpenGLShaderProgram.h" />
|
||||
<ClInclude Include="src\drawing\engines\opengl\SwapFramebuffer.h" />
|
||||
<ClInclude Include="src\drawing\engines\opengl\TextureCache.h" />
|
||||
<ClInclude Include="src\drawing\font.h" />
|
||||
<ClInclude Include="src\drawing\IDrawingContext.h" />
|
||||
<ClInclude Include="src\drawing\IDrawingEngine.h" />
|
||||
|
|
|
@ -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<GLuint> _textures;
|
||||
std::unordered_map<uint32, GLuint> _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 */
|
||||
|
|
|
@ -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<GLuint>(numTextures);
|
||||
for (auto kvp : _imageTextureMap)
|
||||
{
|
||||
textures.push_back(kvp.second);
|
||||
}
|
||||
|
||||
glDeleteTextures(textures.size(), textures.data());
|
||||
}
|
|
@ -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 <unordered_map>
|
||||
#include <SDL_pixels.h>
|
||||
#include "../../../common.h"
|
||||
#include "OpenGLAPI.h"
|
||||
|
||||
class TextureCache
|
||||
{
|
||||
private:
|
||||
std::unordered_map<uint32, GLuint> _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();
|
||||
};
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue