mirror of
https://github.com/OpenRCT2/OpenRCT2
synced 2026-01-23 06:44:38 +01:00
Fixed OpenGL palette drawing
Added palettes to the texture atlas and now correctly use them to generate images. Transparency semi supported but the colours are not quite correct.
This commit is contained in:
@@ -10,6 +10,8 @@ flat in int fTexColourAtlas;
|
||||
in vec2 fTexColourCoords;
|
||||
flat in int fTexMaskAtlas;
|
||||
in vec2 fTexMaskCoords;
|
||||
flat in int fTexPaletteAtlas;
|
||||
flat in vec4 fTexPaletteBounds;
|
||||
flat in int fMask;
|
||||
|
||||
in vec2 fPosition;
|
||||
@@ -25,7 +27,38 @@ void main()
|
||||
discard;
|
||||
}
|
||||
|
||||
vec4 texel = uPalette[texture(uTexture, vec3(fTexColourCoords, float(fTexColourAtlas))).r];
|
||||
vec4 texel;
|
||||
|
||||
// If remap palette used
|
||||
if ((fFlags & (1 << 1)) != 0)
|
||||
{
|
||||
// z is the size of each x pixel in the atlas
|
||||
float x = fTexPaletteBounds.x + texture(uTexture, vec3(fTexColourCoords, float(fTexColourAtlas))).r * fTexPaletteBounds.z;
|
||||
texel = uPalette[texture(uTexture, vec3(x, fTexPaletteBounds.y, float(fTexPaletteAtlas))).r];
|
||||
} // If transparent or special transparent
|
||||
else if ((fFlags & ((1 << 2) | (1 << 3))) != 0)
|
||||
{
|
||||
float line = texture(uTexture,vec3(fTexColourCoords, float(fTexColourAtlas))).r;
|
||||
if (line == 0.0)
|
||||
{
|
||||
discard;
|
||||
}
|
||||
float alpha = 0.5;
|
||||
if ((fFlags & (1 << 2)) != 0)
|
||||
{
|
||||
alpha = 0.5 + (line - 1.0) / 10.0;
|
||||
}
|
||||
|
||||
// z is the size of each x pixel in the atlas
|
||||
float x = fTexPaletteBounds.x + fTexPaletteBounds.z * 50.0;
|
||||
oColour = vec4(uPalette[texture(uTexture, vec3(x, fTexPaletteBounds.y, float(fTexPaletteAtlas))).r].rgb, alpha);
|
||||
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
texel = uPalette[texture(uTexture, vec3(fTexColourCoords, float(fTexColourAtlas))).r];
|
||||
}
|
||||
vec4 mask = uPalette[texture(uTexture, vec3(fTexMaskCoords, float(fTexMaskAtlas))).r];
|
||||
|
||||
if (fMask != 0)
|
||||
|
||||
@@ -7,6 +7,8 @@ in int ivTexColourAtlas;
|
||||
in vec4 ivTexColourBounds;
|
||||
in int ivTexMaskAtlas;
|
||||
in vec4 ivTexMaskBounds;
|
||||
in int ivTexPaletteAtlas;
|
||||
in vec4 ivTexPaletteBounds;
|
||||
in int ivFlags;
|
||||
in vec4 ivColour;
|
||||
in ivec4 ivBounds;
|
||||
@@ -23,6 +25,8 @@ flat out int fTexColourAtlas;
|
||||
out vec2 fTexColourCoords;
|
||||
flat out int fTexMaskAtlas;
|
||||
out vec2 fTexMaskCoords;
|
||||
flat out int fTexPaletteAtlas;
|
||||
flat out vec4 fTexPaletteBounds;
|
||||
flat out int fMask;
|
||||
|
||||
void main()
|
||||
@@ -64,6 +68,8 @@ void main()
|
||||
fMask = ivMask;
|
||||
fTexColourAtlas = ivTexColourAtlas;
|
||||
fTexMaskAtlas = ivTexMaskAtlas;
|
||||
fTexPaletteAtlas = ivTexPaletteAtlas;
|
||||
fTexPaletteBounds = ivTexPaletteBounds;
|
||||
|
||||
gl_Position = vec4(pos, 0.0, 1.0);
|
||||
}
|
||||
|
||||
@@ -195,6 +195,7 @@ void FASTCALL gfx_draw_sprite_raw_masked(rct_drawpixelinfo *dpi, int x, int y, i
|
||||
void FASTCALL gfx_draw_sprite_solid(rct_drawpixelinfo * dpi, int image, int x, int y, uint8 colour);
|
||||
|
||||
void FASTCALL gfx_draw_sprite_software(rct_drawpixelinfo *dpi, int image_id, int x, int y, uint32 tertiary_colour);
|
||||
uint8* FASTCALL gfx_draw_sprite_get_palette(int image_id, uint32 tertiary_colour);
|
||||
void FASTCALL gfx_draw_sprite_palette_set_software(rct_drawpixelinfo *dpi, int image_id, int x, int y, uint8* palette_pointer, uint8* unknown_pointer);
|
||||
void FASTCALL gfx_draw_sprite_raw_masked_software(rct_drawpixelinfo *dpi, int x, int y, int maskImage, int colourImage);
|
||||
|
||||
|
||||
@@ -40,6 +40,7 @@ struct DrawImageCommand {
|
||||
sint32 clip[4];
|
||||
CachedTextureInfo texMask;
|
||||
CachedTextureInfo texColour;
|
||||
CachedTextureInfo texPalette;
|
||||
sint32 bounds[4];
|
||||
bool mask;
|
||||
};
|
||||
@@ -40,6 +40,8 @@ DrawImageShader::DrawImageShader() : OpenGLShaderProgram("drawimage")
|
||||
glVertexAttribPointer(vTexColourBounds, 4, GL_FLOAT, GL_FALSE, sizeof(DrawImageInstance), (void*) offsetof(DrawImageInstance, texColourBounds));
|
||||
glVertexAttribIPointer(vTexMaskAtlas, 1, GL_INT, sizeof(DrawImageInstance), (void*) offsetof(DrawImageInstance, texMaskAtlas));
|
||||
glVertexAttribPointer(vTexMaskBounds, 4, GL_FLOAT, GL_FALSE, sizeof(DrawImageInstance), (void*) offsetof(DrawImageInstance, texMaskBounds));
|
||||
glVertexAttribIPointer(vTexPaletteAtlas, 1, GL_INT, sizeof(DrawImageInstance), (void*) offsetof(DrawImageInstance, texPaletteAtlas));
|
||||
glVertexAttribPointer(vTexPaletteBounds, 4, GL_FLOAT, GL_FALSE, sizeof(DrawImageInstance), (void*) offsetof(DrawImageInstance, texPaletteBounds));
|
||||
glVertexAttribIPointer(vFlags, 1, GL_INT, sizeof(DrawImageInstance), (void*) offsetof(DrawImageInstance, flags));
|
||||
glVertexAttribPointer(vColour, 4, GL_FLOAT, GL_FALSE, sizeof(DrawImageInstance), (void*) offsetof(DrawImageInstance, colour));
|
||||
glVertexAttribIPointer(vBounds, 4, GL_INT, sizeof(DrawImageInstance), (void*) offsetof(DrawImageInstance, bounds));
|
||||
@@ -51,6 +53,8 @@ DrawImageShader::DrawImageShader() : OpenGLShaderProgram("drawimage")
|
||||
glEnableVertexAttribArray(vTexColourBounds);
|
||||
glEnableVertexAttribArray(vTexMaskAtlas);
|
||||
glEnableVertexAttribArray(vTexMaskBounds);
|
||||
glEnableVertexAttribArray(vTexPaletteAtlas);
|
||||
glEnableVertexAttribArray(vTexPaletteBounds);
|
||||
glEnableVertexAttribArray(vFlags);
|
||||
glEnableVertexAttribArray(vColour);
|
||||
glEnableVertexAttribArray(vBounds);
|
||||
@@ -61,6 +65,8 @@ DrawImageShader::DrawImageShader() : OpenGLShaderProgram("drawimage")
|
||||
glVertexAttribDivisor(vTexColourBounds, 1);
|
||||
glVertexAttribDivisor(vTexMaskAtlas, 1);
|
||||
glVertexAttribDivisor(vTexMaskBounds, 1);
|
||||
glVertexAttribDivisor(vTexPaletteAtlas, 1);
|
||||
glVertexAttribDivisor(vTexPaletteBounds, 1);
|
||||
glVertexAttribDivisor(vFlags, 1);
|
||||
glVertexAttribDivisor(vColour, 1);
|
||||
glVertexAttribDivisor(vBounds, 1);
|
||||
@@ -91,6 +97,8 @@ void DrawImageShader::GetLocations()
|
||||
vTexColourBounds = GetAttributeLocation("ivTexColourBounds");
|
||||
vTexMaskAtlas = GetAttributeLocation("ivTexMaskAtlas");
|
||||
vTexMaskBounds = GetAttributeLocation("ivTexMaskBounds");
|
||||
vTexPaletteAtlas = GetAttributeLocation("ivTexPaletteAtlas");
|
||||
vTexPaletteBounds = GetAttributeLocation("ivTexPaletteBounds");
|
||||
vFlags = GetAttributeLocation("ivFlags");
|
||||
vColour = GetAttributeLocation("ivColour");
|
||||
vBounds = GetAttributeLocation("ivBounds");
|
||||
|
||||
@@ -28,6 +28,8 @@ struct DrawImageInstance {
|
||||
vec4f texColourBounds;
|
||||
int texMaskAtlas;
|
||||
vec4f texMaskBounds;
|
||||
int texPaletteAtlas;
|
||||
vec4f texPaletteBounds;
|
||||
int flags;
|
||||
vec4f colour;
|
||||
vec4i bounds;
|
||||
@@ -47,6 +49,8 @@ private:
|
||||
GLuint vTexColourBounds;
|
||||
GLuint vTexMaskAtlas;
|
||||
GLuint vTexMaskBounds;
|
||||
GLuint vTexPaletteAtlas;
|
||||
GLuint vTexPaletteBounds;
|
||||
GLuint vFlags;
|
||||
GLuint vColour;
|
||||
GLuint vBounds;
|
||||
|
||||
@@ -720,6 +720,28 @@ void OpenGLDrawingContext::DrawSprite(uint32 image, sint32 x, sint32 y, uint32 t
|
||||
auto texture = _textureCache->GetOrLoadImageTexture(image);
|
||||
command.texColour = texture;
|
||||
|
||||
bool special = false;
|
||||
if (!(image & IMAGE_TYPE_REMAP_2_PLUS) && (image & IMAGE_TYPE_REMAP)) {
|
||||
if (((image >> 19) & 0x7F) == 32) {
|
||||
special = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (!((image & IMAGE_TYPE_REMAP_2_PLUS) && !(image & IMAGE_TYPE_REMAP))) {
|
||||
tertiaryColour = 0;
|
||||
}
|
||||
|
||||
texture = _textureCache->GetOrLoadPaletteTexture(image, tertiaryColour, special);
|
||||
command.texPalette = texture;
|
||||
|
||||
if (image & IMAGE_TYPE_TRANSPARENT) {
|
||||
command.flags |= (1 << 3);
|
||||
}
|
||||
else if (image & (IMAGE_TYPE_REMAP_2_PLUS | IMAGE_TYPE_REMAP)){
|
||||
command.flags |= (1 << 1);
|
||||
}
|
||||
command.flags |= special << 2;
|
||||
|
||||
command.bounds[0] = left;
|
||||
command.bounds[1] = top;
|
||||
command.bounds[2] = right;
|
||||
@@ -955,6 +977,15 @@ void OpenGLDrawingContext::FlushImages()
|
||||
instance.colour = command.colour;
|
||||
instance.bounds = {command.bounds[0], command.bounds[1], command.bounds[2], command.bounds[3]};
|
||||
instance.mask = command.mask;
|
||||
instance.texPaletteAtlas = command.texPalette.index;
|
||||
if (instance.flags != 0) {
|
||||
instance.texPaletteBounds = {
|
||||
command.texPalette.normalizedBounds.x,
|
||||
command.texPalette.normalizedBounds.y,
|
||||
(command.texPalette.normalizedBounds.z - command.texPalette.normalizedBounds.x) / (float)(command.texPalette.bounds.z - command.texPalette.bounds.x),
|
||||
(command.texPalette.normalizedBounds.w - command.texPalette.normalizedBounds.y) / (float)(command.texPalette.bounds.w - command.texPalette.bounds.y)
|
||||
};
|
||||
}
|
||||
|
||||
instances.push_back(instance);
|
||||
}
|
||||
|
||||
@@ -52,14 +52,48 @@ void TextureCache::InvalidateImage(uint32 image)
|
||||
|
||||
CachedTextureInfo TextureCache::GetOrLoadImageTexture(uint32 image)
|
||||
{
|
||||
auto kvp = _imageTextureMap.find(image & 0x7FFFF);
|
||||
image &= 0x7FFFF;
|
||||
auto kvp = _imageTextureMap.find(image);
|
||||
if (kvp != _imageTextureMap.end())
|
||||
{
|
||||
return kvp->second;
|
||||
}
|
||||
|
||||
auto cacheInfo = LoadImageTexture(image);
|
||||
_imageTextureMap[image & 0x7FFFF] = cacheInfo;
|
||||
_imageTextureMap[image] = cacheInfo;
|
||||
|
||||
return cacheInfo;
|
||||
}
|
||||
|
||||
CachedTextureInfo TextureCache::GetOrLoadPaletteTexture(uint32 image, uint32 tertiaryColour, bool special)
|
||||
{
|
||||
if ((image & (IMAGE_TYPE_REMAP | IMAGE_TYPE_REMAP_2_PLUS | IMAGE_TYPE_TRANSPARENT)) == 0)
|
||||
return CachedTextureInfo{ 0 };
|
||||
|
||||
uint32 uniquePaletteId = 0;
|
||||
if (!(image & IMAGE_TYPE_REMAP_2_PLUS)) {
|
||||
uniquePaletteId = (image >> 19) & 0xFF;
|
||||
if (!(image & IMAGE_TYPE_TRANSPARENT)) {
|
||||
uniquePaletteId &= 0x7F;
|
||||
}
|
||||
}
|
||||
else {
|
||||
uniquePaletteId |= ((image >> 19) & 0x1F);
|
||||
uniquePaletteId |= ((image >> 24) & 0x1F) << 8;
|
||||
|
||||
if (!(image & IMAGE_TYPE_REMAP)) {
|
||||
uniquePaletteId |= tertiaryColour << 16;
|
||||
}
|
||||
}
|
||||
|
||||
auto kvp = _paletteTextureMap.find(uniquePaletteId);
|
||||
if (kvp != _paletteTextureMap.end())
|
||||
{
|
||||
return kvp->second;
|
||||
}
|
||||
|
||||
auto cacheInfo = LoadPaletteTexture(image, tertiaryColour, special);
|
||||
_paletteTextureMap[uniquePaletteId] = cacheInfo;
|
||||
|
||||
return cacheInfo;
|
||||
}
|
||||
@@ -141,6 +175,20 @@ CachedTextureInfo TextureCache::LoadImageTexture(uint32 image)
|
||||
return cacheInfo;
|
||||
}
|
||||
|
||||
CachedTextureInfo TextureCache::LoadPaletteTexture(uint32 image, uint32 tertiaryColour, bool special)
|
||||
{
|
||||
rct_drawpixelinfo dpi;
|
||||
dpi.bits = gfx_draw_sprite_get_palette(image, tertiaryColour);
|
||||
dpi.width = 256;
|
||||
dpi.height = special ? 5 : 1;
|
||||
auto cacheInfo = AllocateImage(dpi.width, dpi.height);
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D_ARRAY, _atlasesTexture);
|
||||
glTexSubImage3D(GL_TEXTURE_2D_ARRAY, 0, cacheInfo.bounds.x, cacheInfo.bounds.y, cacheInfo.index, dpi.width, dpi.height, 1, GL_RED_INTEGER, GL_UNSIGNED_BYTE, dpi.bits);
|
||||
|
||||
return cacheInfo;
|
||||
}
|
||||
|
||||
CachedTextureInfo TextureCache::LoadGlyphTexture(uint32 image, uint8 * palette)
|
||||
{
|
||||
rct_drawpixelinfo * dpi = GetGlyphAsDPI(image, palette);
|
||||
|
||||
@@ -196,6 +196,7 @@ private:
|
||||
|
||||
std::unordered_map<uint32, CachedTextureInfo> _imageTextureMap;
|
||||
std::unordered_map<GlyphId, CachedTextureInfo, GlyphId::Hash, GlyphId::Equal> _glyphTextureMap;
|
||||
std::unordered_map<uint32, CachedTextureInfo> _paletteTextureMap;
|
||||
|
||||
SDL_Color _palette[256];
|
||||
|
||||
@@ -206,7 +207,8 @@ public:
|
||||
void InvalidateImage(uint32 image);
|
||||
CachedTextureInfo GetOrLoadImageTexture(uint32 image);
|
||||
CachedTextureInfo GetOrLoadGlyphTexture(uint32 image, uint8 * palette);
|
||||
|
||||
CachedTextureInfo GetOrLoadPaletteTexture(uint32 image, uint32 tertiaryColour, bool special);
|
||||
|
||||
GLuint GetAtlasesTexture();
|
||||
|
||||
private:
|
||||
@@ -214,6 +216,7 @@ private:
|
||||
void EnlargeAtlasesTexture(GLuint newEntries);
|
||||
CachedTextureInfo LoadImageTexture(uint32 image);
|
||||
CachedTextureInfo LoadGlyphTexture(uint32 image, uint8 * palette);
|
||||
CachedTextureInfo LoadPaletteTexture(uint32 image, uint32 tertiaryColour, bool special);
|
||||
CachedTextureInfo AllocateImage(int imageWidth, int imageHeight);
|
||||
void * GetImageAsARGB(uint32 image, uint32 tertiaryColour, uint32 * outWidth, uint32 * outHeight);
|
||||
rct_drawpixelinfo * GetImageAsDPI(uint32 image, uint32 tertiaryColour);
|
||||
|
||||
@@ -292,7 +292,7 @@ static void FASTCALL gfx_bmp_sprite_to_buffer(uint8* palette_pointer, uint8* unk
|
||||
return;
|
||||
}
|
||||
|
||||
static uint8* FASTCALL gfx_draw_sprite_get_palette(int image_id, uint32 tertiary_colour) {
|
||||
uint8* FASTCALL gfx_draw_sprite_get_palette(int image_id, uint32 tertiary_colour) {
|
||||
int image_type = (image_id & 0xE0000000);
|
||||
if (image_type == 0)
|
||||
return NULL;
|
||||
|
||||
@@ -176,7 +176,6 @@ static paint_struct * sub_9819_c(uint32 image_id, rct_xyz16 offset, rct_xyz16 bo
|
||||
ps->map_x = gPaintMapPosition.x;
|
||||
ps->map_y = gPaintMapPosition.y;
|
||||
ps->mapElement = g_currently_drawn_item;
|
||||
|
||||
return ps;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user