mirror of https://github.com/OpenRCT2/OpenRCT2.git
OpenGL: Improve Shaders
This commit is contained in:
parent
f105237a2e
commit
6bf2e0157b
|
@ -470,9 +470,8 @@
|
|||
F76C887D1EC5324E00FA49E2 /* CursorData.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F76C858A1EC4E82600FA49E2 /* CursorData.cpp */; };
|
||||
F76C887E1EC5324E00FA49E2 /* CursorRepository.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F76C858B1EC4E82600FA49E2 /* CursorRepository.cpp */; };
|
||||
F76C887F1EC5324E00FA49E2 /* CopyFramebufferShader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F76C85911EC4E82600FA49E2 /* CopyFramebufferShader.cpp */; };
|
||||
F76C88801EC5324E00FA49E2 /* DrawImageShader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F76C85941EC4E82600FA49E2 /* DrawImageShader.cpp */; };
|
||||
F76C88801EC5324E00FA49E2 /* DrawRectShader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F76C85941EC4E82600FA49E2 /* DrawRectShader.cpp */; };
|
||||
F76C88811EC5324E00FA49E2 /* DrawLineShader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F76C85961EC4E82600FA49E2 /* DrawLineShader.cpp */; };
|
||||
F76C88821EC5324E00FA49E2 /* FillRectShader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F76C85981EC4E82600FA49E2 /* FillRectShader.cpp */; };
|
||||
F76C88831EC5324E00FA49E2 /* OpenGLAPI.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F76C859B1EC4E82600FA49E2 /* OpenGLAPI.cpp */; };
|
||||
F76C88841EC5324E00FA49E2 /* OpenGLDrawingEngine.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F76C859D1EC4E82600FA49E2 /* OpenGLDrawingEngine.cpp */; };
|
||||
F76C88851EC5324E00FA49E2 /* OpenGLFramebuffer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F76C859E1EC4E82600FA49E2 /* OpenGLFramebuffer.cpp */; };
|
||||
|
@ -1392,12 +1391,10 @@
|
|||
F76C85911EC4E82600FA49E2 /* CopyFramebufferShader.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = CopyFramebufferShader.cpp; sourceTree = "<group>"; };
|
||||
F76C85921EC4E82600FA49E2 /* CopyFramebufferShader.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = CopyFramebufferShader.h; sourceTree = "<group>"; };
|
||||
F76C85931EC4E82600FA49E2 /* DrawCommands.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = DrawCommands.h; sourceTree = "<group>"; };
|
||||
F76C85941EC4E82600FA49E2 /* DrawImageShader.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = DrawImageShader.cpp; sourceTree = "<group>"; };
|
||||
F76C85951EC4E82600FA49E2 /* DrawImageShader.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = DrawImageShader.h; sourceTree = "<group>"; };
|
||||
F76C85941EC4E82600FA49E2 /* DrawRectShader.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = DrawRectShader.cpp; sourceTree = "<group>"; };
|
||||
F76C85951EC4E82600FA49E2 /* DrawRectShader.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = DrawRectShader.h; sourceTree = "<group>"; };
|
||||
F76C85961EC4E82600FA49E2 /* DrawLineShader.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = DrawLineShader.cpp; sourceTree = "<group>"; };
|
||||
F76C85971EC4E82600FA49E2 /* DrawLineShader.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = DrawLineShader.h; sourceTree = "<group>"; };
|
||||
F76C85981EC4E82600FA49E2 /* FillRectShader.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = FillRectShader.cpp; sourceTree = "<group>"; };
|
||||
F76C85991EC4E82600FA49E2 /* FillRectShader.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = FillRectShader.h; sourceTree = "<group>"; };
|
||||
F76C859A1EC4E82600FA49E2 /* GLSLTypes.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GLSLTypes.h; sourceTree = "<group>"; };
|
||||
F76C859B1EC4E82600FA49E2 /* OpenGLAPI.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = OpenGLAPI.cpp; sourceTree = "<group>"; };
|
||||
F76C859C1EC4E82600FA49E2 /* OpenGLAPI.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = OpenGLAPI.h; sourceTree = "<group>"; };
|
||||
|
@ -2669,12 +2666,10 @@
|
|||
F76C85911EC4E82600FA49E2 /* CopyFramebufferShader.cpp */,
|
||||
F76C85921EC4E82600FA49E2 /* CopyFramebufferShader.h */,
|
||||
F76C85931EC4E82600FA49E2 /* DrawCommands.h */,
|
||||
F76C85941EC4E82600FA49E2 /* DrawImageShader.cpp */,
|
||||
F76C85951EC4E82600FA49E2 /* DrawImageShader.h */,
|
||||
F76C85961EC4E82600FA49E2 /* DrawLineShader.cpp */,
|
||||
F76C85971EC4E82600FA49E2 /* DrawLineShader.h */,
|
||||
F76C85981EC4E82600FA49E2 /* FillRectShader.cpp */,
|
||||
F76C85991EC4E82600FA49E2 /* FillRectShader.h */,
|
||||
F76C85941EC4E82600FA49E2 /* DrawRectShader.cpp */,
|
||||
F76C85951EC4E82600FA49E2 /* DrawRectShader.h */,
|
||||
F76C859A1EC4E82600FA49E2 /* GLSLTypes.h */,
|
||||
F76C859B1EC4E82600FA49E2 /* OpenGLAPI.cpp */,
|
||||
F76C859C1EC4E82600FA49E2 /* OpenGLAPI.h */,
|
||||
|
@ -3232,7 +3227,7 @@
|
|||
4C93F18F1F8B747A00A9330D /* PirateShip.cpp in Sources */,
|
||||
C654DF381F69C0430040F43D /* StaffFirePrompt.cpp in Sources */,
|
||||
C651A8D91F30204300443BCA /* Text.cpp in Sources */,
|
||||
F76C88801EC5324E00FA49E2 /* DrawImageShader.cpp in Sources */,
|
||||
F76C88801EC5324E00FA49E2 /* DrawRectShader.cpp in Sources */,
|
||||
C685E51D1F8907850090598F /* Research.cpp in Sources */,
|
||||
C64644FB1F3FA4120026AC2D /* EditorScenarioOptions.cpp in Sources */,
|
||||
F775F5371EE3724F001F00E7 /* DummyAudioContext.cpp in Sources */,
|
||||
|
@ -3263,7 +3258,6 @@
|
|||
4CFE4E801F90A3F1005243C2 /* Peep.cpp in Sources */,
|
||||
C654DF3A1F69C0430040F43D /* TitleEditor.cpp in Sources */,
|
||||
C666EE6F1F37ACB10061AA04 /* DebugPaint.cpp in Sources */,
|
||||
F76C88821EC5324E00FA49E2 /* FillRectShader.cpp in Sources */,
|
||||
F76C88831EC5324E00FA49E2 /* OpenGLAPI.cpp in Sources */,
|
||||
4C93F1521F8B744400A9330D /* Steeplechase.cpp in Sources */,
|
||||
4C93F1BD1F8E185600A9330D /* NewsItem.cpp in Sources */,
|
||||
|
|
|
@ -3,7 +3,6 @@
|
|||
uniform vec4 uPalette[256];
|
||||
uniform usampler2D uTexture;
|
||||
|
||||
in vec2 fPosition;
|
||||
in vec2 fTextureCoordinate;
|
||||
|
||||
out vec4 oColour;
|
||||
|
|
|
@ -1,42 +1,12 @@
|
|||
#version 150
|
||||
|
||||
uniform ivec2 uScreenSize;
|
||||
uniform ivec4 uBounds;
|
||||
uniform ivec4 uTextureCoordinates;
|
||||
in vec4 vPosition;
|
||||
in vec2 vTextureCoordinate;
|
||||
|
||||
in uint vIndex;
|
||||
|
||||
out vec2 fPosition;
|
||||
out vec2 fTextureCoordinate;
|
||||
|
||||
void main()
|
||||
{
|
||||
vec2 pos;
|
||||
switch (vIndex) {
|
||||
case 0u:
|
||||
pos = uBounds.xy;
|
||||
fTextureCoordinate = uTextureCoordinates.xy;
|
||||
break;
|
||||
case 1u:
|
||||
pos = uBounds.zy;
|
||||
fTextureCoordinate = uTextureCoordinates.zy;
|
||||
break;
|
||||
case 2u:
|
||||
pos = uBounds.xw;
|
||||
fTextureCoordinate = uTextureCoordinates.xw;
|
||||
break;
|
||||
case 3u:
|
||||
pos = uBounds.zw;
|
||||
fTextureCoordinate = uTextureCoordinates.zw;
|
||||
break;
|
||||
}
|
||||
|
||||
fPosition = pos;
|
||||
|
||||
// Transform screen coordinates to viewport
|
||||
pos.x = (pos.x * (2.0 / uScreenSize.x)) - 1.0;
|
||||
pos.y = (pos.y * (2.0 / uScreenSize.y)) - 1.0;
|
||||
pos.y *= -1;
|
||||
|
||||
gl_Position = vec4(pos, 0.0, 1.0);
|
||||
fTextureCoordinate = vTextureCoordinate;
|
||||
gl_Position = vPosition;
|
||||
}
|
||||
|
|
|
@ -1,95 +0,0 @@
|
|||
#version 150
|
||||
|
||||
const int FLAG_COLOUR = (1 << 0);
|
||||
const int FLAG_REMAP = (1 << 1);
|
||||
const int FLAG_TRANSPARENT = (1 << 2);
|
||||
const int FLAG_TRANSPARENT_SPECIAL = (1 << 3);
|
||||
|
||||
uniform usampler2DArray uTexture;
|
||||
|
||||
flat in ivec4 fClip;
|
||||
flat in int fFlags;
|
||||
flat in uint fColour;
|
||||
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;
|
||||
|
||||
out uint oColour;
|
||||
|
||||
void main()
|
||||
{
|
||||
if (fPosition.x < fClip.x || fPosition.x > fClip.z ||
|
||||
fPosition.y < fClip.y || fPosition.y > fClip.w)
|
||||
{
|
||||
discard;
|
||||
}
|
||||
|
||||
uint texel;
|
||||
|
||||
// If remap palette used
|
||||
if ((fFlags & FLAG_REMAP) != 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 = texture(uTexture, vec3(x, fTexPaletteBounds.y, float(fTexPaletteAtlas))).r;
|
||||
} // If transparent or special transparent
|
||||
else if ((fFlags & (FLAG_TRANSPARENT | FLAG_TRANSPARENT_SPECIAL)) != 0)
|
||||
{
|
||||
uint line = texture(uTexture, vec3(fTexColourCoords, float(fTexColourAtlas))).r;
|
||||
if (line == 0u)
|
||||
{
|
||||
discard;
|
||||
}
|
||||
/*
|
||||
float alpha = 0.5;
|
||||
if ((fFlags & FLAG_TRANSPARENT_SPECIAL) != 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);
|
||||
oColour = texture(uTexture, vec3(x, fTexPaletteBounds.y, float(fTexPaletteAtlas))).r;
|
||||
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
texel = texture(uTexture, vec3(fTexColourCoords, float(fTexColourAtlas))).r;
|
||||
}
|
||||
|
||||
if (fMask != 0)
|
||||
{
|
||||
uint mask = texture(uTexture, vec3(fTexMaskCoords, float(fTexMaskAtlas))).r;
|
||||
if ( mask == 0u )
|
||||
{
|
||||
discard;
|
||||
}
|
||||
|
||||
oColour = texel;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (texel == 0u)
|
||||
{
|
||||
discard;
|
||||
}
|
||||
if ((fFlags & FLAG_COLOUR) != 0)
|
||||
{
|
||||
//oColour = vec4(fColour.rgb, fColour.a * texel.a);
|
||||
oColour = fColour;
|
||||
}
|
||||
else
|
||||
{
|
||||
oColour = texel;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,74 +0,0 @@
|
|||
#version 150
|
||||
|
||||
uniform ivec2 uScreenSize;
|
||||
|
||||
in ivec4 ivClip;
|
||||
in int ivTexColourAtlas;
|
||||
in vec4 ivTexColourBounds;
|
||||
in int ivTexMaskAtlas;
|
||||
in vec4 ivTexMaskBounds;
|
||||
in int ivTexPaletteAtlas;
|
||||
in vec4 ivTexPaletteBounds;
|
||||
in int ivFlags;
|
||||
in uint ivColour;
|
||||
in ivec4 ivBounds;
|
||||
in int ivMask;
|
||||
|
||||
in uint vIndex;
|
||||
|
||||
out vec2 fPosition;
|
||||
flat out ivec4 fClip;
|
||||
flat out int fFlags;
|
||||
flat out uint fColour;
|
||||
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()
|
||||
{
|
||||
vec2 pos;
|
||||
switch (vIndex) {
|
||||
case 0u:
|
||||
pos = ivBounds.xy;
|
||||
fTexColourCoords = ivTexColourBounds.xy;
|
||||
fTexMaskCoords = ivTexMaskBounds.xy;
|
||||
break;
|
||||
case 1u:
|
||||
pos = ivBounds.zy;
|
||||
fTexColourCoords = ivTexColourBounds.zy;
|
||||
fTexMaskCoords = ivTexMaskBounds.zy;
|
||||
break;
|
||||
case 2u:
|
||||
pos = ivBounds.xw;
|
||||
fTexColourCoords = ivTexColourBounds.xw;
|
||||
fTexMaskCoords = ivTexMaskBounds.xw;
|
||||
break;
|
||||
case 3u:
|
||||
pos = ivBounds.zw;
|
||||
fTexColourCoords = ivTexColourBounds.zw;
|
||||
fTexMaskCoords = ivTexMaskBounds.zw;
|
||||
break;
|
||||
}
|
||||
|
||||
fPosition = pos;
|
||||
|
||||
// Transform screen coordinates to viewport
|
||||
pos.x = (pos.x * (2.0 / uScreenSize.x)) - 1.0;
|
||||
pos.y = (pos.y * (2.0 / uScreenSize.y)) - 1.0;
|
||||
pos.y *= -1;
|
||||
|
||||
fClip = ivClip;
|
||||
fFlags = ivFlags;
|
||||
fColour = ivColour;
|
||||
fMask = ivMask;
|
||||
fTexColourAtlas = ivTexColourAtlas;
|
||||
fTexMaskAtlas = ivTexMaskAtlas;
|
||||
fTexPaletteAtlas = ivTexPaletteAtlas;
|
||||
fTexPaletteBounds = ivTexPaletteBounds;
|
||||
|
||||
gl_Position = vec4(pos, 0.0, 1.0);
|
||||
}
|
|
@ -1,6 +1,5 @@
|
|||
#version 150
|
||||
|
||||
uniform ivec4 uClip;
|
||||
uniform uint uColour;
|
||||
|
||||
in vec2 fPosition;
|
||||
|
@ -9,11 +8,5 @@ out uint oColour;
|
|||
|
||||
void main()
|
||||
{
|
||||
if (fPosition.x < uClip.x || fPosition.x > uClip.z ||
|
||||
fPosition.y < uClip.y || fPosition.y > uClip.w)
|
||||
{
|
||||
discard;
|
||||
}
|
||||
|
||||
oColour = uColour;
|
||||
}
|
||||
|
|
|
@ -2,23 +2,15 @@
|
|||
|
||||
uniform ivec2 uScreenSize;
|
||||
uniform ivec4 uBounds;
|
||||
uniform ivec4 uClip;
|
||||
|
||||
in uint vIndex;
|
||||
in mat4x2 vVertMat;
|
||||
|
||||
out vec2 fPosition;
|
||||
|
||||
void main()
|
||||
{
|
||||
vec2 pos;
|
||||
if (vIndex == 0u)
|
||||
{
|
||||
pos = uBounds.xy;
|
||||
}
|
||||
else
|
||||
{
|
||||
pos = uBounds.zw;
|
||||
}
|
||||
|
||||
vec2 pos = clamp(vVertMat * uBounds, uClip.xy, uClip.zw);
|
||||
fPosition = pos;
|
||||
|
||||
// Transform screen coordinates to viewport
|
||||
|
|
|
@ -0,0 +1,76 @@
|
|||
#version 150
|
||||
|
||||
const int MASK_REMAP_COUNT = 3;
|
||||
const int FLAG_NO_TEXTURE = (1 << 2);
|
||||
const int FLAG_MASK = (1 << 3);
|
||||
const int FLAG_CROSS_HATCH = (1 << 4);
|
||||
|
||||
uniform usampler2DArray uTexture;
|
||||
uniform usampler2DRect uPaletteTex;
|
||||
|
||||
flat in int fFlags;
|
||||
flat in uint fColour;
|
||||
in vec3 fTexColour;
|
||||
in vec3 fTexMask;
|
||||
flat in vec3 fPalettes;
|
||||
|
||||
in vec2 fPosition;
|
||||
|
||||
out uint oColour;
|
||||
|
||||
void main()
|
||||
{
|
||||
uint texel;
|
||||
if ((fFlags & FLAG_NO_TEXTURE) == 0)
|
||||
{
|
||||
texel = texture(uTexture, fTexColour).r;
|
||||
if (texel == 0u)
|
||||
{
|
||||
discard;
|
||||
}
|
||||
texel += fColour;
|
||||
}
|
||||
else
|
||||
{
|
||||
texel = fColour;
|
||||
}
|
||||
|
||||
int paletteCount = fFlags & MASK_REMAP_COUNT;
|
||||
if (paletteCount >= 3 && texel >= 0x2Eu && texel < 0x3Au)
|
||||
{
|
||||
texel = texture(uPaletteTex, vec2(texel + 0xC5u, fPalettes.z)).r;
|
||||
}
|
||||
else if (paletteCount >= 2 && texel >= 0xCAu && texel < 0xD6u)
|
||||
{
|
||||
texel = texture(uPaletteTex, vec2(texel + 0x29u, fPalettes.y)).r;
|
||||
}
|
||||
else if (paletteCount >= 1)
|
||||
{
|
||||
texel = texture(uPaletteTex, vec2(texel, fPalettes.x)).r;
|
||||
}
|
||||
|
||||
if (texel == 0u)
|
||||
{
|
||||
discard;
|
||||
}
|
||||
|
||||
if ((fFlags & FLAG_CROSS_HATCH) != 0)
|
||||
{
|
||||
int posSum = int(fPosition.x) + int(fPosition.y);
|
||||
if ((posSum % 2) == 0)
|
||||
{
|
||||
discard;
|
||||
}
|
||||
}
|
||||
|
||||
if ((fFlags & FLAG_MASK) != 0)
|
||||
{
|
||||
uint mask = texture(uTexture, fTexMask).r;
|
||||
if ( mask == 0u )
|
||||
{
|
||||
discard;
|
||||
}
|
||||
}
|
||||
|
||||
oColour = texel;
|
||||
}
|
|
@ -0,0 +1,45 @@
|
|||
#version 150
|
||||
|
||||
uniform ivec2 uScreenSize;
|
||||
|
||||
in ivec4 vClip;
|
||||
in int vTexColourAtlas;
|
||||
in vec4 vTexColourBounds;
|
||||
in int vTexMaskAtlas;
|
||||
in vec4 vTexMaskBounds;
|
||||
in ivec3 vPalettes;
|
||||
in int vFlags;
|
||||
in uint vColour;
|
||||
in ivec4 vBounds;
|
||||
|
||||
in mat4x2 vVertMat;
|
||||
in vec2 vVertVec;
|
||||
|
||||
out vec2 fPosition;
|
||||
flat out int fFlags;
|
||||
flat out uint fColour;
|
||||
out vec3 fTexColour;
|
||||
out vec3 fTexMask;
|
||||
flat out vec3 fPalettes;
|
||||
|
||||
void main()
|
||||
{
|
||||
// Clamp position by vClip, correcting interpolated values for the clipping
|
||||
vec2 m = clamp(((vVertMat * vClip) - (vVertMat * vBounds))/(vBounds.zw - vBounds.xy) + vVertVec, 0.0, 1.0);
|
||||
vec2 pos = mix(vBounds.xy, vBounds.zw, m);
|
||||
fTexColour = vec3(mix(vTexColourBounds.xy, vTexColourBounds.zw, m), vTexColourAtlas);
|
||||
fTexMask = vec3(mix(vTexMaskBounds.xy, vTexMaskBounds.zw, m), vTexMaskAtlas);
|
||||
|
||||
fPosition = pos;
|
||||
|
||||
// Transform screen coordinates to viewport
|
||||
pos.x = (pos.x * (2.0 / uScreenSize.x)) - 1.0;
|
||||
pos.y = (pos.y * (2.0 / uScreenSize.y)) - 1.0;
|
||||
pos.y *= -1;
|
||||
|
||||
fFlags = vFlags;
|
||||
fColour = vColour;
|
||||
fPalettes = vec3(vPalettes);
|
||||
|
||||
gl_Position = vec4(pos, 0.0, 1.0);
|
||||
}
|
|
@ -1,33 +0,0 @@
|
|||
#version 150
|
||||
|
||||
uniform ivec2 uScreenSize;
|
||||
uniform ivec4 uClip;
|
||||
uniform int uFlags;
|
||||
uniform usampler2D uSourceFramebuffer;
|
||||
uniform uint uPaletteRemap[256];
|
||||
|
||||
in vec2 fPosition;
|
||||
|
||||
out uint oColour;
|
||||
|
||||
void main()
|
||||
{
|
||||
if (fPosition.x < uClip.x || fPosition.x > uClip.z ||
|
||||
fPosition.y < uClip.y || fPosition.y > uClip.w)
|
||||
{
|
||||
discard;
|
||||
}
|
||||
|
||||
if ((uFlags & 1) != 0) // cross-hatch pattern
|
||||
{
|
||||
int posSum = int(fPosition.x) + int(fPosition.y);
|
||||
if ((posSum % 2) == 0)
|
||||
{
|
||||
discard;
|
||||
}
|
||||
}
|
||||
|
||||
vec2 textureCoordinates = (fPosition / vec2(uScreenSize)) * vec2(1.0, -1.0) + vec2(0.0, 1.0);
|
||||
uint sourceColour = texture(uSourceFramebuffer, textureCoordinates).r;
|
||||
oColour = uPaletteRemap[sourceColour];
|
||||
}
|
|
@ -1,36 +0,0 @@
|
|||
#version 150
|
||||
|
||||
uniform ivec2 uScreenSize;
|
||||
uniform ivec4 uBounds;
|
||||
|
||||
in uint vIndex;
|
||||
|
||||
out vec2 fPosition;
|
||||
|
||||
void main()
|
||||
{
|
||||
vec2 pos;
|
||||
switch (vIndex) {
|
||||
case 0u:
|
||||
pos = uBounds.xy;
|
||||
break;
|
||||
case 1u:
|
||||
pos = uBounds.zy;
|
||||
break;
|
||||
case 2u:
|
||||
pos = uBounds.xw;
|
||||
break;
|
||||
case 3u:
|
||||
pos = uBounds.zw;
|
||||
break;
|
||||
}
|
||||
|
||||
fPosition = pos;
|
||||
|
||||
// Transform screen coordinates to viewport
|
||||
pos.x = (pos.x * (2.0 / uScreenSize.x)) - 1.0;
|
||||
pos.y = (pos.y * (2.0 / uScreenSize.y)) - 1.0;
|
||||
pos.y *= -1;
|
||||
|
||||
gl_Position = vec4(pos, 0.0, 1.0);
|
||||
}
|
|
@ -18,6 +18,20 @@
|
|||
|
||||
#include "CopyFramebufferShader.h"
|
||||
|
||||
struct VDStruct
|
||||
{
|
||||
GLfloat position[2];
|
||||
GLfloat texturecoordinate[2];
|
||||
};
|
||||
|
||||
constexpr VDStruct VertexData[4] =
|
||||
{
|
||||
{ -1.0f, -1.0f, 0.0f, 0.0f },
|
||||
{ 1.0f, -1.0f, 1.0f, 0.0f },
|
||||
{ -1.0f, 1.0f, 0.0f, 1.0f },
|
||||
{ 1.0f, 1.0f, 1.0f, 1.0f },
|
||||
};
|
||||
|
||||
CopyFramebufferShader::CopyFramebufferShader() : OpenGLShaderProgram("copyframebuffer")
|
||||
{
|
||||
GetLocations();
|
||||
|
@ -25,16 +39,17 @@ CopyFramebufferShader::CopyFramebufferShader() : OpenGLShaderProgram("copyframeb
|
|||
glGenBuffers(1, &_vbo);
|
||||
glGenVertexArrays(1, &_vao);
|
||||
|
||||
GLuint vertices[] = { 0, 1, 2, 2, 1, 3 };
|
||||
glBindBuffer(GL_ARRAY_BUFFER, _vbo);
|
||||
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
|
||||
glBufferData(GL_ARRAY_BUFFER, sizeof(VertexData), VertexData, GL_STATIC_DRAW);
|
||||
|
||||
glBindVertexArray(_vao);
|
||||
glEnableVertexAttribArray(vIndex);
|
||||
glVertexAttribIPointer(vIndex, 1, GL_INT, 0, nullptr);
|
||||
glVertexAttribPointer(vPosition, 2, GL_FLOAT, GL_FALSE, sizeof(VDStruct), (void*) offsetof(VDStruct, position));
|
||||
glVertexAttribPointer(vTextureCoordinate, 2, GL_FLOAT, GL_FALSE, sizeof(VDStruct), (void*) offsetof(VDStruct, texturecoordinate));
|
||||
|
||||
glEnableVertexAttribArray(vPosition);
|
||||
glEnableVertexAttribArray(vTextureCoordinate);
|
||||
|
||||
Use();
|
||||
SetTextureCoordinates(0, 0, 1, 1);
|
||||
glUniform1i(uTexture, 0);
|
||||
}
|
||||
|
||||
|
@ -46,28 +61,11 @@ CopyFramebufferShader::~CopyFramebufferShader()
|
|||
|
||||
void CopyFramebufferShader::GetLocations()
|
||||
{
|
||||
uScreenSize = GetUniformLocation("uScreenSize");
|
||||
uBounds = GetUniformLocation("uBounds");
|
||||
uTextureCoordinates = GetUniformLocation("uTextureCoordinates");
|
||||
uTexture = GetUniformLocation("uTexture");
|
||||
uPalette = GetUniformLocation("uPalette");
|
||||
|
||||
vIndex = GetAttributeLocation("vIndex");
|
||||
}
|
||||
|
||||
void CopyFramebufferShader::SetScreenSize(sint32 width, sint32 height)
|
||||
{
|
||||
glUniform2i(uScreenSize, width, height);
|
||||
}
|
||||
|
||||
void CopyFramebufferShader::SetBounds(sint32 left, sint32 top, sint32 right, sint32 bottom)
|
||||
{
|
||||
glUniform4i(uBounds, left, top, right, bottom);
|
||||
}
|
||||
|
||||
void CopyFramebufferShader::SetTextureCoordinates(sint32 left, sint32 top, sint32 right, sint32 bottom)
|
||||
{
|
||||
glUniform4i(uTextureCoordinates, left, top, right, bottom);
|
||||
vPosition = GetAttributeLocation("vPosition");
|
||||
vTextureCoordinate = GetAttributeLocation("vTextureCoordinate");
|
||||
}
|
||||
|
||||
void CopyFramebufferShader::SetTexture(GLuint texture)
|
||||
|
@ -82,7 +80,7 @@ void CopyFramebufferShader::SetPalette(const vec4f * glPalette) {
|
|||
void CopyFramebufferShader::Draw()
|
||||
{
|
||||
glBindVertexArray(_vao);
|
||||
glDrawArrays(GL_TRIANGLES, 0, 6);
|
||||
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
|
||||
}
|
||||
|
||||
#endif /* DISABLE_OPENGL */
|
||||
|
|
|
@ -22,13 +22,11 @@
|
|||
class CopyFramebufferShader final : public OpenGLShaderProgram
|
||||
{
|
||||
private:
|
||||
GLuint uScreenSize;
|
||||
GLuint uBounds;
|
||||
GLuint uTextureCoordinates;
|
||||
GLuint uTexture;
|
||||
GLuint uPalette;
|
||||
|
||||
GLuint vIndex;
|
||||
GLuint vPosition;
|
||||
GLuint vTextureCoordinate;
|
||||
|
||||
GLuint _vbo;
|
||||
GLuint _vao;
|
||||
|
@ -37,9 +35,6 @@ public:
|
|||
CopyFramebufferShader();
|
||||
~CopyFramebufferShader() override;
|
||||
|
||||
void SetScreenSize(sint32 width, sint32 height);
|
||||
void SetBounds(sint32 left, sint32 top, sint32 right, sint32 bottom);
|
||||
void SetTextureCoordinates(sint32 left, sint32 top, sint32 right, sint32 bottom);
|
||||
void SetTexture(GLuint texture);
|
||||
void SetPalette(const vec4f * glPalette);
|
||||
|
||||
|
|
|
@ -64,43 +64,33 @@ public:
|
|||
}
|
||||
};
|
||||
|
||||
struct DrawRectCommand {
|
||||
uint32 flags;
|
||||
GLuint sourceFramebuffer;
|
||||
sint32 clip[4];
|
||||
sint32 bounds[4];
|
||||
GLuint paletteRemap[256];
|
||||
};
|
||||
|
||||
struct DrawLineCommand {
|
||||
struct DrawLineCommand
|
||||
{
|
||||
uint8 colour;
|
||||
sint32 clip[4];
|
||||
vec4i clip;
|
||||
sint32 pos[4];
|
||||
};
|
||||
|
||||
// Per-instance data for images
|
||||
struct DrawImageCommand {
|
||||
struct DrawRectCommand
|
||||
{
|
||||
vec4i clip;
|
||||
sint32 texColourAtlas;
|
||||
vec4f texColourBounds;
|
||||
sint32 texMaskAtlas;
|
||||
vec4f texMaskBounds;
|
||||
sint32 texPaletteAtlas;
|
||||
vec4f texPaletteBounds;
|
||||
vec3i palettes;
|
||||
sint32 flags;
|
||||
uint8 colour;
|
||||
uint32 colour;
|
||||
vec4i bounds;
|
||||
sint32 mask;
|
||||
|
||||
enum
|
||||
{
|
||||
FLAG_COLOUR = (1 << 0),
|
||||
FLAG_REMAP = (1 << 1),
|
||||
FLAG_TRANSPARENT = (1 << 2),
|
||||
FLAG_TRANSPARENT_SPECIAL = (1 << 3),
|
||||
FLAG_NO_TEXTURE = (1 << 2),
|
||||
FLAG_MASK = (1 << 3),
|
||||
FLAG_CROSS_HATCH = (1 << 4),
|
||||
};
|
||||
};
|
||||
|
||||
typedef CommandBatch<DrawImageCommand> ImageCommandBatch;
|
||||
typedef CommandBatch<DrawLineCommand> LineCommandBatch;
|
||||
typedef CommandBatch<DrawRectCommand> RectCommandBatch;
|
||||
|
|
|
@ -1,120 +0,0 @@
|
|||
#pragma region Copyright (c) 2014-2017 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
|
||||
|
||||
#ifndef DISABLE_OPENGL
|
||||
|
||||
#include "DrawImageShader.h"
|
||||
|
||||
DrawImageShader::DrawImageShader() : OpenGLShaderProgram("drawimage")
|
||||
{
|
||||
GetLocations();
|
||||
|
||||
glGenBuffers(1, &_vbo);
|
||||
glGenBuffers(1, &_vboInstances);
|
||||
glGenVertexArrays(1, &_vao);
|
||||
|
||||
GLuint vertices[] = { 0, 1, 2, 2, 1, 3 };
|
||||
glBindBuffer(GL_ARRAY_BUFFER, _vbo);
|
||||
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
|
||||
|
||||
glBindVertexArray(_vao);
|
||||
|
||||
glVertexAttribIPointer(vIndex, 1, GL_INT, 0, nullptr);
|
||||
|
||||
glBindBuffer(GL_ARRAY_BUFFER, _vboInstances);
|
||||
glVertexAttribIPointer(vClip, 4, GL_INT, sizeof(DrawImageCommand), (void*) offsetof(DrawImageCommand, clip));
|
||||
glVertexAttribIPointer(vTexColourAtlas, 1, GL_INT, sizeof(DrawImageCommand), (void*) offsetof(DrawImageCommand, texColourAtlas));
|
||||
glVertexAttribPointer(vTexColourBounds, 4, GL_FLOAT, GL_FALSE, sizeof(DrawImageCommand), (void*) offsetof(DrawImageCommand, texColourBounds));
|
||||
glVertexAttribIPointer(vTexMaskAtlas, 1, GL_INT, sizeof(DrawImageCommand), (void*) offsetof(DrawImageCommand, texMaskAtlas));
|
||||
glVertexAttribPointer(vTexMaskBounds, 4, GL_FLOAT, GL_FALSE, sizeof(DrawImageCommand), (void*) offsetof(DrawImageCommand, texMaskBounds));
|
||||
glVertexAttribIPointer(vTexPaletteAtlas, 1, GL_INT, sizeof(DrawImageCommand), (void*) offsetof(DrawImageCommand, texPaletteAtlas));
|
||||
glVertexAttribPointer(vTexPaletteBounds, 4, GL_FLOAT, GL_FALSE, sizeof(DrawImageCommand), (void*) offsetof(DrawImageCommand, texPaletteBounds));
|
||||
glVertexAttribIPointer(vFlags, 1, GL_INT, sizeof(DrawImageCommand), (void*) offsetof(DrawImageCommand, flags));
|
||||
glVertexAttribIPointer(vColour, 1, GL_UNSIGNED_INT, sizeof(DrawImageCommand), (void*) offsetof(DrawImageCommand, colour));
|
||||
glVertexAttribIPointer(vBounds, 4, GL_INT, sizeof(DrawImageCommand), (void*) offsetof(DrawImageCommand, bounds));
|
||||
glVertexAttribIPointer(vMask, 1, GL_INT, sizeof(DrawImageCommand), (void*) offsetof(DrawImageCommand, mask));
|
||||
|
||||
glEnableVertexAttribArray(vIndex);
|
||||
glEnableVertexAttribArray(vClip);
|
||||
glEnableVertexAttribArray(vTexColourAtlas);
|
||||
glEnableVertexAttribArray(vTexColourBounds);
|
||||
glEnableVertexAttribArray(vTexMaskAtlas);
|
||||
glEnableVertexAttribArray(vTexMaskBounds);
|
||||
glEnableVertexAttribArray(vTexPaletteAtlas);
|
||||
glEnableVertexAttribArray(vTexPaletteBounds);
|
||||
glEnableVertexAttribArray(vFlags);
|
||||
glEnableVertexAttribArray(vColour);
|
||||
glEnableVertexAttribArray(vBounds);
|
||||
glEnableVertexAttribArray(vMask);
|
||||
|
||||
glVertexAttribDivisor(vClip, 1);
|
||||
glVertexAttribDivisor(vTexColourAtlas, 1);
|
||||
glVertexAttribDivisor(vTexColourBounds, 1);
|
||||
glVertexAttribDivisor(vTexMaskAtlas, 1);
|
||||
glVertexAttribDivisor(vTexMaskBounds, 1);
|
||||
glVertexAttribDivisor(vTexPaletteAtlas, 1);
|
||||
glVertexAttribDivisor(vTexPaletteBounds, 1);
|
||||
glVertexAttribDivisor(vFlags, 1);
|
||||
glVertexAttribDivisor(vColour, 1);
|
||||
glVertexAttribDivisor(vBounds, 1);
|
||||
glVertexAttribDivisor(vMask, 1);
|
||||
|
||||
Use();
|
||||
glUniform1i(uTexture, 0);
|
||||
}
|
||||
|
||||
DrawImageShader::~DrawImageShader()
|
||||
{
|
||||
glDeleteBuffers(1, &_vbo);
|
||||
glDeleteBuffers(1, &_vboInstances);
|
||||
glDeleteVertexArrays(1, &_vao);
|
||||
}
|
||||
|
||||
void DrawImageShader::GetLocations()
|
||||
{
|
||||
uScreenSize = GetUniformLocation("uScreenSize");
|
||||
uTexture = GetUniformLocation("uTexture");
|
||||
|
||||
vIndex = GetAttributeLocation("vIndex");
|
||||
vClip = GetAttributeLocation("ivClip");
|
||||
vTexColourAtlas = GetAttributeLocation("ivTexColourAtlas");
|
||||
vTexColourBounds = GetAttributeLocation("ivTexColourBounds");
|
||||
vTexMaskAtlas = GetAttributeLocation("ivTexMaskAtlas");
|
||||
vTexMaskBounds = GetAttributeLocation("ivTexMaskBounds");
|
||||
vTexPaletteAtlas = GetAttributeLocation("ivTexPaletteAtlas");
|
||||
vTexPaletteBounds = GetAttributeLocation("ivTexPaletteBounds");
|
||||
vFlags = GetAttributeLocation("ivFlags");
|
||||
vColour = GetAttributeLocation("ivColour");
|
||||
vBounds = GetAttributeLocation("ivBounds");
|
||||
vMask = GetAttributeLocation("ivMask");
|
||||
}
|
||||
|
||||
void DrawImageShader::SetScreenSize(sint32 width, sint32 height)
|
||||
{
|
||||
glUniform2i(uScreenSize, width, height);
|
||||
}
|
||||
|
||||
void DrawImageShader::DrawInstances(const ImageCommandBatch& instances)
|
||||
{
|
||||
glBindVertexArray(_vao);
|
||||
|
||||
glBindBuffer(GL_ARRAY_BUFFER, _vboInstances);
|
||||
glBufferData(GL_ARRAY_BUFFER, sizeof(DrawImageCommand) * instances.size(), instances.data(), GL_STREAM_DRAW);
|
||||
|
||||
glDrawArraysInstanced(GL_TRIANGLES, 0, 6, (GLsizei)instances.size());
|
||||
}
|
||||
|
||||
#endif /* DISABLE_OPENGL */
|
|
@ -19,6 +19,17 @@
|
|||
#include "DrawLineShader.h"
|
||||
#include "OpenGLFramebuffer.h"
|
||||
|
||||
struct VDStruct
|
||||
{
|
||||
GLfloat mat[4][2];
|
||||
};
|
||||
|
||||
constexpr VDStruct VertexData[2] =
|
||||
{
|
||||
{ 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f },
|
||||
{ 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f },
|
||||
};
|
||||
|
||||
DrawLineShader::DrawLineShader() : OpenGLShaderProgram("drawline")
|
||||
{
|
||||
GetLocations();
|
||||
|
@ -26,13 +37,19 @@ DrawLineShader::DrawLineShader() : OpenGLShaderProgram("drawline")
|
|||
glGenBuffers(1, &_vbo);
|
||||
glGenVertexArrays(1, &_vao);
|
||||
|
||||
GLuint vertices[] = { 0, 1 };
|
||||
glBindBuffer(GL_ARRAY_BUFFER, _vbo);
|
||||
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
|
||||
glBufferData(GL_ARRAY_BUFFER, sizeof(VertexData), VertexData, GL_STATIC_DRAW);
|
||||
|
||||
glBindVertexArray(_vao);
|
||||
glEnableVertexAttribArray(vIndex);
|
||||
glVertexAttribIPointer(vIndex, 1, GL_INT, 0, nullptr);
|
||||
glVertexAttribPointer(vVertMat+0, 2, GL_FLOAT, GL_FALSE, sizeof(VDStruct), (void*) offsetof(VDStruct, mat[0]));
|
||||
glVertexAttribPointer(vVertMat+1, 2, GL_FLOAT, GL_FALSE, sizeof(VDStruct), (void*) offsetof(VDStruct, mat[1]));
|
||||
glVertexAttribPointer(vVertMat+2, 2, GL_FLOAT, GL_FALSE, sizeof(VDStruct), (void*) offsetof(VDStruct, mat[2]));
|
||||
glVertexAttribPointer(vVertMat+3, 2, GL_FLOAT, GL_FALSE, sizeof(VDStruct), (void*) offsetof(VDStruct, mat[3]));
|
||||
|
||||
glEnableVertexAttribArray(vVertMat+0);
|
||||
glEnableVertexAttribArray(vVertMat+1);
|
||||
glEnableVertexAttribArray(vVertMat+2);
|
||||
glEnableVertexAttribArray(vVertMat+3);
|
||||
|
||||
Use();
|
||||
}
|
||||
|
@ -50,7 +67,7 @@ void DrawLineShader::GetLocations()
|
|||
uBounds = GetUniformLocation("uBounds");
|
||||
uColour = GetUniformLocation("uColour");
|
||||
|
||||
vIndex = GetAttributeLocation("vIndex");
|
||||
vVertMat = GetAttributeLocation("vVertMat");
|
||||
}
|
||||
|
||||
void DrawLineShader::SetScreenSize(sint32 width, sint32 height)
|
||||
|
|
|
@ -27,7 +27,7 @@ private:
|
|||
GLuint uBounds;
|
||||
GLuint uColour;
|
||||
|
||||
GLuint vIndex;
|
||||
GLuint vVertMat;
|
||||
|
||||
GLuint _vbo;
|
||||
GLuint _vao;
|
||||
|
|
|
@ -0,0 +1,138 @@
|
|||
#pragma region Copyright (c) 2014-2017 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
|
||||
|
||||
#ifndef DISABLE_OPENGL
|
||||
|
||||
#include "DrawRectShader.h"
|
||||
|
||||
struct VDStruct
|
||||
{
|
||||
GLfloat mat[4][2];
|
||||
GLfloat vec[2];
|
||||
};
|
||||
|
||||
constexpr VDStruct VertexData[4] =
|
||||
{
|
||||
{ 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f },
|
||||
{ 0.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f },
|
||||
{ 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f },
|
||||
{ 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f },
|
||||
};
|
||||
|
||||
DrawRectShader::DrawRectShader() : OpenGLShaderProgram("drawrect")
|
||||
{
|
||||
GetLocations();
|
||||
|
||||
glGenBuffers(1, &_vbo);
|
||||
glGenBuffers(1, &_vboInstances);
|
||||
glGenVertexArrays(1, &_vao);
|
||||
|
||||
glBindBuffer(GL_ARRAY_BUFFER, _vbo);
|
||||
glBufferData(GL_ARRAY_BUFFER, sizeof(VertexData), VertexData, GL_STATIC_DRAW);
|
||||
|
||||
glBindVertexArray(_vao);
|
||||
|
||||
glVertexAttribPointer(vVertMat+0, 2, GL_FLOAT, GL_FALSE, sizeof(VDStruct), (void*) offsetof(VDStruct, mat[0]));
|
||||
glVertexAttribPointer(vVertMat+1, 2, GL_FLOAT, GL_FALSE, sizeof(VDStruct), (void*) offsetof(VDStruct, mat[1]));
|
||||
glVertexAttribPointer(vVertMat+2, 2, GL_FLOAT, GL_FALSE, sizeof(VDStruct), (void*) offsetof(VDStruct, mat[2]));
|
||||
glVertexAttribPointer(vVertMat+3, 2, GL_FLOAT, GL_FALSE, sizeof(VDStruct), (void*) offsetof(VDStruct, mat[3]));
|
||||
glVertexAttribPointer(vVertVec, 2, GL_FLOAT, GL_FALSE, sizeof(VDStruct), (void*) offsetof(VDStruct, vec) );
|
||||
|
||||
glBindBuffer(GL_ARRAY_BUFFER, _vboInstances);
|
||||
glVertexAttribIPointer(vClip, 4, GL_INT, sizeof(DrawRectCommand), (void*) offsetof(DrawRectCommand, clip));
|
||||
glVertexAttribIPointer(vTexColourAtlas, 1, GL_INT, sizeof(DrawRectCommand), (void*) offsetof(DrawRectCommand, texColourAtlas));
|
||||
glVertexAttribPointer(vTexColourBounds, 4, GL_FLOAT, GL_FALSE, sizeof(DrawRectCommand), (void*) offsetof(DrawRectCommand, texColourBounds));
|
||||
glVertexAttribIPointer(vTexMaskAtlas, 1, GL_INT, sizeof(DrawRectCommand), (void*) offsetof(DrawRectCommand, texMaskAtlas));
|
||||
glVertexAttribPointer(vTexMaskBounds, 4, GL_FLOAT, GL_FALSE, sizeof(DrawRectCommand), (void*) offsetof(DrawRectCommand, texMaskBounds));
|
||||
glVertexAttribIPointer(vPalettes, 3, GL_INT, sizeof(DrawRectCommand), (void*) offsetof(DrawRectCommand, palettes));
|
||||
glVertexAttribIPointer(vFlags, 1, GL_INT, sizeof(DrawRectCommand), (void*) offsetof(DrawRectCommand, flags));
|
||||
glVertexAttribIPointer(vColour, 1, GL_UNSIGNED_INT, sizeof(DrawRectCommand), (void*) offsetof(DrawRectCommand, colour));
|
||||
glVertexAttribIPointer(vBounds, 4, GL_INT, sizeof(DrawRectCommand), (void*) offsetof(DrawRectCommand, bounds));
|
||||
|
||||
glEnableVertexAttribArray(vVertMat+0);
|
||||
glEnableVertexAttribArray(vVertMat+1);
|
||||
glEnableVertexAttribArray(vVertMat+2);
|
||||
glEnableVertexAttribArray(vVertMat+3);
|
||||
glEnableVertexAttribArray(vVertVec);
|
||||
|
||||
glEnableVertexAttribArray(vClip);
|
||||
glEnableVertexAttribArray(vTexColourAtlas);
|
||||
glEnableVertexAttribArray(vTexColourBounds);
|
||||
glEnableVertexAttribArray(vTexMaskAtlas);
|
||||
glEnableVertexAttribArray(vTexMaskBounds);
|
||||
glEnableVertexAttribArray(vPalettes);
|
||||
glEnableVertexAttribArray(vFlags);
|
||||
glEnableVertexAttribArray(vColour);
|
||||
glEnableVertexAttribArray(vBounds);
|
||||
|
||||
glVertexAttribDivisor(vClip, 1);
|
||||
glVertexAttribDivisor(vTexColourAtlas, 1);
|
||||
glVertexAttribDivisor(vTexColourBounds, 1);
|
||||
glVertexAttribDivisor(vTexMaskAtlas, 1);
|
||||
glVertexAttribDivisor(vTexMaskBounds, 1);
|
||||
glVertexAttribDivisor(vPalettes, 1);
|
||||
glVertexAttribDivisor(vFlags, 1);
|
||||
glVertexAttribDivisor(vColour, 1);
|
||||
glVertexAttribDivisor(vBounds, 1);
|
||||
|
||||
Use();
|
||||
glUniform1i(uTexture, 0);
|
||||
glUniform1i(uPaletteTex, 1);
|
||||
}
|
||||
|
||||
DrawRectShader::~DrawRectShader()
|
||||
{
|
||||
glDeleteBuffers(1, &_vbo);
|
||||
glDeleteBuffers(1, &_vboInstances);
|
||||
glDeleteVertexArrays(1, &_vao);
|
||||
}
|
||||
|
||||
void DrawRectShader::GetLocations()
|
||||
{
|
||||
uScreenSize = GetUniformLocation("uScreenSize");
|
||||
uTexture = GetUniformLocation("uTexture");
|
||||
uPaletteTex = GetUniformLocation("uPaletteTex");
|
||||
|
||||
vClip = GetAttributeLocation("vClip");
|
||||
vTexColourAtlas = GetAttributeLocation("vTexColourAtlas");
|
||||
vTexColourBounds = GetAttributeLocation("vTexColourBounds");
|
||||
vTexMaskAtlas = GetAttributeLocation("vTexMaskAtlas");
|
||||
vTexMaskBounds = GetAttributeLocation("vTexMaskBounds");
|
||||
vPalettes = GetAttributeLocation("vPalettes");
|
||||
vFlags = GetAttributeLocation("vFlags");
|
||||
vColour = GetAttributeLocation("vColour");
|
||||
vBounds = GetAttributeLocation("vBounds");
|
||||
|
||||
vVertMat = GetAttributeLocation("vVertMat");
|
||||
vVertVec = GetAttributeLocation("vVertVec");
|
||||
}
|
||||
|
||||
void DrawRectShader::SetScreenSize(sint32 width, sint32 height)
|
||||
{
|
||||
glUniform2i(uScreenSize, width, height);
|
||||
}
|
||||
|
||||
void DrawRectShader::DrawInstances(const RectCommandBatch& instances)
|
||||
{
|
||||
glBindVertexArray(_vao);
|
||||
|
||||
glBindBuffer(GL_ARRAY_BUFFER, _vboInstances);
|
||||
glBufferData(GL_ARRAY_BUFFER, sizeof(DrawRectCommand) * instances.size(), instances.data(), GL_STREAM_DRAW);
|
||||
|
||||
glDrawArraysInstanced(GL_TRIANGLE_STRIP, 0, 4, (GLsizei)instances.size());
|
||||
}
|
||||
|
||||
#endif /* DISABLE_OPENGL */
|
|
@ -22,35 +22,36 @@
|
|||
#include <SDL_pixels.h>
|
||||
#include <vector>
|
||||
|
||||
class DrawImageShader final : public OpenGLShaderProgram
|
||||
class DrawRectShader final : public OpenGLShaderProgram
|
||||
{
|
||||
private:
|
||||
GLuint uScreenSize;
|
||||
GLuint uTexture;
|
||||
GLuint uPaletteTex;
|
||||
|
||||
GLuint vVertMat;
|
||||
GLuint vVertVec;
|
||||
|
||||
GLuint vIndex;
|
||||
GLuint vClip;
|
||||
GLuint vTexColourAtlas;
|
||||
GLuint vTexColourBounds;
|
||||
GLuint vTexMaskAtlas;
|
||||
GLuint vTexMaskBounds;
|
||||
GLuint vTexPaletteAtlas;
|
||||
GLuint vTexPaletteBounds;
|
||||
GLuint vPalettes;
|
||||
GLuint vFlags;
|
||||
GLuint vColour;
|
||||
GLuint vBounds;
|
||||
GLuint vMask;
|
||||
|
||||
GLuint _vbo;
|
||||
GLuint _vboInstances;
|
||||
GLuint _vao;
|
||||
|
||||
public:
|
||||
DrawImageShader();
|
||||
~DrawImageShader() override;
|
||||
DrawRectShader();
|
||||
~DrawRectShader() override;
|
||||
|
||||
void SetScreenSize(sint32 width, sint32 height);
|
||||
void DrawInstances(const ImageCommandBatch& instances);
|
||||
void DrawInstances(const RectCommandBatch& instances);
|
||||
|
||||
private:
|
||||
void GetLocations();
|
|
@ -1,104 +0,0 @@
|
|||
#pragma region Copyright (c) 2014-2017 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
|
||||
|
||||
#ifndef DISABLE_OPENGL
|
||||
|
||||
#include "FillRectShader.h"
|
||||
#include "OpenGLFramebuffer.h"
|
||||
|
||||
FillRectShader::FillRectShader() : OpenGLShaderProgram("fillrect")
|
||||
{
|
||||
GetLocations();
|
||||
|
||||
glGenBuffers(1, &_vbo);
|
||||
glGenVertexArrays(1, &_vao);
|
||||
|
||||
GLuint vertices[] = { 0, 1, 2, 2, 1, 3 };
|
||||
glBindBuffer(GL_ARRAY_BUFFER, _vbo);
|
||||
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
|
||||
|
||||
glBindVertexArray(_vao);
|
||||
glEnableVertexAttribArray(vIndex);
|
||||
glVertexAttribIPointer(vIndex, 1, GL_INT, 0, 0);
|
||||
|
||||
Use();
|
||||
SetFlags(0);
|
||||
glUniform1i(uSourceFramebuffer, 0);
|
||||
}
|
||||
|
||||
FillRectShader::~FillRectShader()
|
||||
{
|
||||
glDeleteBuffers(1, &_vbo);
|
||||
glDeleteVertexArrays(1, &_vao);
|
||||
}
|
||||
|
||||
void FillRectShader::GetLocations()
|
||||
{
|
||||
uScreenSize = GetUniformLocation("uScreenSize");
|
||||
uClip = GetUniformLocation("uClip");
|
||||
uBounds = GetUniformLocation("uBounds");
|
||||
uFlags = GetUniformLocation("uFlags");
|
||||
uSourceFramebuffer = GetUniformLocation("uSourceFramebuffer");
|
||||
uPaletteRemap = GetUniformLocation("uPaletteRemap");
|
||||
|
||||
vIndex = GetAttributeLocation("vIndex");
|
||||
}
|
||||
|
||||
void FillRectShader::SetScreenSize(sint32 width, sint32 height)
|
||||
{
|
||||
glUniform2i(uScreenSize, width, height);
|
||||
}
|
||||
|
||||
void FillRectShader::SetClip(sint32 left, sint32 top, sint32 right, sint32 bottom)
|
||||
{
|
||||
glUniform4i(uClip, left, top, right, bottom);
|
||||
}
|
||||
|
||||
void FillRectShader::SetBounds(sint32 left, sint32 top, sint32 right, sint32 bottom)
|
||||
{
|
||||
glUniform4i(uBounds, left, top, right, bottom);
|
||||
}
|
||||
|
||||
void FillRectShader::SetFlags(uint32 flags)
|
||||
{
|
||||
glUniform1i(uFlags, flags);
|
||||
}
|
||||
|
||||
void FillRectShader::SetSourceFramebuffer(GLuint texture)
|
||||
{
|
||||
_sourceFramebuffer = texture;
|
||||
OpenGLAPI::SetTexture(0, GL_TEXTURE_2D, texture);
|
||||
}
|
||||
|
||||
void FillRectShader::SetPaletteRemap(const GLuint * paletteRemap)
|
||||
{
|
||||
glUniform1uiv(uPaletteRemap, 256, paletteRemap);
|
||||
}
|
||||
|
||||
void FillRectShader::Draw(sint32 left, sint32 top, sint32 right, sint32 bottom)
|
||||
{
|
||||
SetBounds(left, top, right, bottom);
|
||||
|
||||
glBindVertexArray(_vao);
|
||||
glDrawArrays(GL_TRIANGLES, 0, 6);
|
||||
}
|
||||
|
||||
GLuint FillRectShader::GetSourceFramebuffer() const
|
||||
{
|
||||
return _sourceFramebuffer;
|
||||
}
|
||||
|
||||
#endif /* DISABLE_OPENGL */
|
|
@ -1,58 +0,0 @@
|
|||
#pragma region Copyright (c) 2014-2017 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 "GLSLTypes.h"
|
||||
#include "OpenGLShaderProgram.h"
|
||||
|
||||
class OpenGLFramebuffer;
|
||||
|
||||
class FillRectShader final : public OpenGLShaderProgram
|
||||
{
|
||||
private:
|
||||
GLuint uScreenSize;
|
||||
GLuint uClip;
|
||||
GLuint uBounds;
|
||||
GLuint uFlags;
|
||||
GLuint uSourceFramebuffer;
|
||||
GLuint uPaletteRemap;
|
||||
|
||||
GLuint vIndex;
|
||||
|
||||
GLuint _vbo;
|
||||
GLuint _vao;
|
||||
|
||||
GLuint _sourceFramebuffer = 0;
|
||||
|
||||
public:
|
||||
FillRectShader();
|
||||
~FillRectShader() override;
|
||||
|
||||
void SetScreenSize(sint32 width, sint32 height);
|
||||
void SetClip(sint32 left, sint32 top, sint32 right, sint32 bottom);
|
||||
void SetBounds(sint32 left, sint32 top, sint32 right, sint32 bottom);
|
||||
void SetFlags(uint32 flags);
|
||||
void SetSourceFramebuffer(GLuint texture);
|
||||
void SetPaletteRemap(const GLuint * filterMap);
|
||||
|
||||
void Draw(sint32 left, sint32 top, sint32 right, sint32 bottom);
|
||||
|
||||
GLuint GetSourceFramebuffer() const;
|
||||
|
||||
private:
|
||||
void GetLocations();
|
||||
};
|
|
@ -32,6 +32,13 @@ struct vec2f
|
|||
union { float y; float t; float g; };
|
||||
};
|
||||
|
||||
struct vec3i
|
||||
{
|
||||
union { sint32 x; sint32 s; sint32 r; };
|
||||
union { sint32 y; sint32 t; sint32 g; };
|
||||
union { sint32 z; sint32 p; sint32 b; };
|
||||
};
|
||||
|
||||
struct vec3f
|
||||
{
|
||||
union { float x; float s; float r; };
|
||||
|
|
|
@ -41,9 +41,8 @@
|
|||
#include "OpenGLAPI.h"
|
||||
#include "OpenGLFramebuffer.h"
|
||||
#include "CopyFramebufferShader.h"
|
||||
#include "DrawImageShader.h"
|
||||
#include "DrawLineShader.h"
|
||||
#include "FillRectShader.h"
|
||||
#include "DrawRectShader.h"
|
||||
#include "SwapFramebuffer.h"
|
||||
#include "TextureCache.h"
|
||||
#include "DrawCommands.h"
|
||||
|
@ -68,9 +67,8 @@ private:
|
|||
OpenGLDrawingEngine * _engine = nullptr;
|
||||
rct_drawpixelinfo * _dpi = nullptr;
|
||||
|
||||
DrawImageShader * _drawImageShader = nullptr;
|
||||
DrawLineShader * _drawLineShader = nullptr;
|
||||
FillRectShader * _fillRectShader = nullptr;
|
||||
DrawRectShader * _drawRectShader = nullptr;
|
||||
|
||||
TextureCache * _textureCache = nullptr;
|
||||
|
||||
|
@ -82,9 +80,8 @@ private:
|
|||
sint32 _clipBottom = 0;
|
||||
|
||||
struct {
|
||||
RectCommandBatch rectangles;
|
||||
LineCommandBatch lines;
|
||||
ImageCommandBatch images;
|
||||
RectCommandBatch rects;
|
||||
} _commandBuffers;
|
||||
|
||||
public:
|
||||
|
@ -109,9 +106,8 @@ public:
|
|||
|
||||
void FlushCommandBuffers();
|
||||
|
||||
void FlushRectangles();
|
||||
void FlushLines();
|
||||
void FlushImages();
|
||||
void FlushRectangles();
|
||||
|
||||
void SetDPI(rct_drawpixelinfo * dpi);
|
||||
};
|
||||
|
@ -383,9 +379,6 @@ private:
|
|||
_swapFramebuffer = new SwapFramebuffer(_width, _height);
|
||||
|
||||
_copyFramebufferShader->Use();
|
||||
_copyFramebufferShader->SetScreenSize(_width, _height);
|
||||
_copyFramebufferShader->SetBounds(0, 0, _width, _height);
|
||||
_copyFramebufferShader->SetTextureCoordinates(0, 1, 1, 0);
|
||||
}
|
||||
|
||||
void Display()
|
||||
|
@ -406,9 +399,8 @@ OpenGLDrawingContext::OpenGLDrawingContext(OpenGLDrawingEngine * engine)
|
|||
|
||||
OpenGLDrawingContext::~OpenGLDrawingContext()
|
||||
{
|
||||
delete _drawImageShader;
|
||||
delete _drawLineShader;
|
||||
delete _fillRectShader;
|
||||
delete _drawRectShader;
|
||||
|
||||
delete _textureCache;
|
||||
}
|
||||
|
@ -421,82 +413,67 @@ IDrawingEngine * OpenGLDrawingContext::GetEngine()
|
|||
void OpenGLDrawingContext::Initialise()
|
||||
{
|
||||
_textureCache = new TextureCache();
|
||||
_drawImageShader = new DrawImageShader();
|
||||
_drawRectShader = new DrawRectShader();
|
||||
_drawLineShader = new DrawLineShader();
|
||||
_fillRectShader = new FillRectShader();
|
||||
}
|
||||
|
||||
void OpenGLDrawingContext::Resize(sint32 width, sint32 height)
|
||||
{
|
||||
FlushCommandBuffers();
|
||||
|
||||
_drawImageShader->Use();
|
||||
_drawImageShader->SetScreenSize(width, height);
|
||||
_drawRectShader->Use();
|
||||
_drawRectShader->SetScreenSize(width, height);
|
||||
_drawLineShader->Use();
|
||||
_drawLineShader->SetScreenSize(width, height);
|
||||
_fillRectShader->Use();
|
||||
_fillRectShader->SetScreenSize(width, height);
|
||||
}
|
||||
|
||||
void OpenGLDrawingContext::ResetPalette()
|
||||
{
|
||||
//FlushCommandBuffers();
|
||||
|
||||
_textureCache->SetPalette(_engine->Palette);
|
||||
}
|
||||
|
||||
void OpenGLDrawingContext::Clear(uint8 paletteIndex)
|
||||
{
|
||||
FillRect(paletteIndex, _clipLeft - _offsetX, _clipTop - _offsetY, _clipRight, _clipBottom);
|
||||
FillRect(paletteIndex, _clipLeft - _offsetX, _clipTop - _offsetY, _clipRight - _offsetX, _clipBottom - _offsetY);
|
||||
}
|
||||
|
||||
void OpenGLDrawingContext::FillRect(uint32 colour, sint32 left, sint32 top, sint32 right, sint32 bottom)
|
||||
{
|
||||
// Must be rendered in order, depends on already rendered contents
|
||||
FlushCommandBuffers();
|
||||
|
||||
left += _offsetX;
|
||||
top += _offsetY;
|
||||
right += _offsetX;
|
||||
bottom += _offsetY;
|
||||
|
||||
DrawRectCommand& command = _commandBuffers.rectangles.allocate();
|
||||
DrawRectCommand& command = _commandBuffers.rects.allocate();
|
||||
|
||||
command.sourceFramebuffer = _fillRectShader->GetSourceFramebuffer();
|
||||
command.clip = { _clipLeft, _clipTop, _clipRight, _clipBottom };
|
||||
command.texColourAtlas = 0;
|
||||
command.texColourBounds = { 0.0f, 0.0f, 0.0f, 0.0f };
|
||||
command.texMaskAtlas = 0;
|
||||
command.texMaskBounds = { 0.0f, 0.0f, 0.0f, 0.0f };
|
||||
command.palettes = { 0, 0, 0 };
|
||||
command.colour = colour & 0xFF;
|
||||
command.bounds = { left + _offsetX, top + _offsetY, right + 1, bottom + 1 };
|
||||
command.flags = DrawRectCommand::FLAG_NO_TEXTURE;
|
||||
|
||||
if (colour & 0x1000000)
|
||||
{
|
||||
// cross-pattern
|
||||
command.flags = 1;
|
||||
command.flags = DrawRectCommand::FLAG_CROSS_HATCH;
|
||||
}
|
||||
else if (colour & 0x2000000)
|
||||
{
|
||||
assert(false);
|
||||
// Should be FilterRect
|
||||
}
|
||||
else
|
||||
{
|
||||
command.flags = 0;
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < 256; i++)
|
||||
{
|
||||
command.paletteRemap[i] = colour & 0xFF;
|
||||
}
|
||||
|
||||
command.clip[0] = _clipLeft;
|
||||
command.clip[1] = _clipTop;
|
||||
command.clip[2] = _clipRight;
|
||||
command.clip[3] = _clipBottom;
|
||||
|
||||
command.bounds[0] = left;
|
||||
command.bounds[1] = top;
|
||||
command.bounds[2] = right + 1;
|
||||
command.bounds[3] = bottom + 1;
|
||||
}
|
||||
|
||||
void OpenGLDrawingContext::FilterRect(FILTER_PALETTE_ID palette, sint32 left, sint32 top, sint32 right, sint32 bottom)
|
||||
{
|
||||
// ignore transparency TODO
|
||||
return;
|
||||
|
||||
/*
|
||||
// Must be rendered in order, depends on already rendered contents
|
||||
FlushCommandBuffers();
|
||||
|
||||
|
@ -524,15 +501,13 @@ void OpenGLDrawingContext::FilterRect(FILTER_PALETTE_ID palette, sint32 left, si
|
|||
|
||||
// END FILTER
|
||||
|
||||
command.clip[0] = _clipLeft;
|
||||
command.clip[1] = _clipTop;
|
||||
command.clip[2] = _clipRight;
|
||||
command.clip[3] = _clipBottom;
|
||||
command.clip = { _clipLeft, _clipTop, _clipRight, _clipBottom };
|
||||
|
||||
command.bounds[0] = left;
|
||||
command.bounds[1] = top;
|
||||
command.bounds[2] = right + 1;
|
||||
command.bounds[3] = bottom + 1;
|
||||
*/
|
||||
}
|
||||
|
||||
void OpenGLDrawingContext::DrawLine(uint32 colour, sint32 x1, sint32 y1, sint32 x2, sint32 y2)
|
||||
|
@ -546,10 +521,7 @@ void OpenGLDrawingContext::DrawLine(uint32 colour, sint32 x1, sint32 y1, sint32
|
|||
|
||||
command.colour = colour & 0xFF;
|
||||
|
||||
command.clip[0] = _clipLeft;
|
||||
command.clip[1] = _clipTop;
|
||||
command.clip[2] = _clipRight;
|
||||
command.clip[3] = _clipBottom;
|
||||
command.clip = { _clipLeft, _clipTop, _clipRight, _clipBottom };
|
||||
|
||||
command.pos[0] = x1;
|
||||
command.pos[1] = y1;
|
||||
|
@ -589,13 +561,8 @@ void OpenGLDrawingContext::DrawSprite(uint32 image, sint32 x, sint32 y, uint32 t
|
|||
|
||||
uint8 zoomLevel = (1 << _dpi->zoom_level);
|
||||
|
||||
sint32 drawOffsetX = g1Element->x_offset;
|
||||
sint32 drawOffsetY = g1Element->y_offset;
|
||||
sint32 drawWidth = g1Element->width;
|
||||
sint32 drawHeight = g1Element->height;
|
||||
|
||||
sint32 left = x + drawOffsetX;
|
||||
sint32 top = y + drawOffsetY;
|
||||
sint32 left = x + g1Element->x_offset;
|
||||
sint32 top = y + g1Element->y_offset;
|
||||
|
||||
sint32 zoom_mask = 0xFFFFFFFF << _dpi->zoom_level;
|
||||
if (_dpi->zoom_level && g1Element->flags & G1_FLAG_RLE_COMPRESSION){
|
||||
|
@ -609,8 +576,8 @@ void OpenGLDrawingContext::DrawSprite(uint32 image, sint32 x, sint32 y, uint32 t
|
|||
|
||||
left &= zoom_mask;
|
||||
|
||||
sint32 right = left + drawWidth;
|
||||
sint32 bottom = top + drawHeight;
|
||||
sint32 right = left + g1Element->width;
|
||||
sint32 bottom = top + g1Element->height;
|
||||
|
||||
if (_dpi->zoom_level && g1Element->flags & G1_FLAG_RLE_COMPRESSION) {
|
||||
bottom += top & ~zoom_mask;
|
||||
|
@ -642,46 +609,54 @@ void OpenGLDrawingContext::DrawSprite(uint32 image, sint32 x, sint32 y, uint32 t
|
|||
|
||||
auto texture = _textureCache->GetOrLoadImageTexture(image);
|
||||
|
||||
int paletteCount;
|
||||
vec3i palettes{};
|
||||
bool special = false;
|
||||
if (!(image & IMAGE_TYPE_REMAP_2_PLUS) && (image & IMAGE_TYPE_REMAP)) {
|
||||
if (((image >> 19) & 0x7F) == 32) {
|
||||
if (image & IMAGE_TYPE_REMAP_2_PLUS)
|
||||
{
|
||||
palettes.x = TextureCache::PaletteToY((image >> 19) & 0x1F);
|
||||
palettes.y = TextureCache::PaletteToY((image >> 24) & 0x1F);
|
||||
if (image & IMAGE_TYPE_REMAP)
|
||||
{
|
||||
paletteCount = 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
paletteCount = 3;
|
||||
palettes.z = TextureCache::PaletteToY(tertiaryColour & 0xFF);
|
||||
}
|
||||
}
|
||||
else if (image & IMAGE_TYPE_REMAP)
|
||||
{
|
||||
paletteCount = 1;
|
||||
palettes.x = TextureCache::PaletteToY((image >> 19) & 0xFF);
|
||||
if (palettes.x == 32)
|
||||
{
|
||||
special = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (!((image & IMAGE_TYPE_REMAP_2_PLUS) && !(image & IMAGE_TYPE_REMAP))) {
|
||||
tertiaryColour = 0;
|
||||
else
|
||||
{
|
||||
paletteCount = 0;
|
||||
}
|
||||
|
||||
auto texture2 = _textureCache->GetOrLoadPaletteTexture(image, tertiaryColour, special);
|
||||
if (special || (image & IMAGE_TYPE_TRANSPARENT))
|
||||
{
|
||||
// ignore transparecy TODO
|
||||
return;
|
||||
}
|
||||
|
||||
DrawImageCommand& command = _commandBuffers.images.allocate();
|
||||
DrawRectCommand& command = _commandBuffers.rects.allocate();
|
||||
|
||||
command.clip = { _clipLeft, _clipTop, _clipRight, _clipBottom };
|
||||
command.texColourAtlas = texture->index;
|
||||
command.texColourBounds = texture->normalizedBounds;
|
||||
command.texMaskAtlas = 0;
|
||||
command.texMaskBounds = { 0.0f, 0.0f, 0.0f };
|
||||
command.texPaletteAtlas = texture2->index;
|
||||
command.texPaletteBounds = texture2->computedBounds;
|
||||
command.texMaskBounds = { 0.0f, 0.0f, 0.0f, 0.0f };
|
||||
command.palettes = palettes;
|
||||
command.colour = 0;
|
||||
command.bounds = { left, top, right, bottom };
|
||||
command.mask = 0;
|
||||
command.flags = 0;
|
||||
|
||||
if (special)
|
||||
{
|
||||
command.flags |= DrawImageCommand::FLAG_TRANSPARENT_SPECIAL;
|
||||
}
|
||||
|
||||
if (image & IMAGE_TYPE_TRANSPARENT)
|
||||
{
|
||||
command.flags |= DrawImageCommand::FLAG_TRANSPARENT;
|
||||
}
|
||||
else if (image & (IMAGE_TYPE_REMAP_2_PLUS | IMAGE_TYPE_REMAP))
|
||||
{
|
||||
command.flags |= DrawImageCommand::FLAG_REMAP;
|
||||
}
|
||||
command.flags = paletteCount;
|
||||
}
|
||||
|
||||
void OpenGLDrawingContext::DrawSpriteRawMasked(sint32 x, sint32 y, uint32 maskImage, uint32 colourImage)
|
||||
|
@ -728,23 +703,23 @@ void OpenGLDrawingContext::DrawSpriteRawMasked(sint32 x, sint32 y, uint32 maskIm
|
|||
right += _clipLeft;
|
||||
bottom += _clipTop;
|
||||
|
||||
DrawImageCommand& command = _commandBuffers.images.allocate();
|
||||
DrawRectCommand& command = _commandBuffers.rects.allocate();
|
||||
|
||||
command.clip = { _clipLeft, _clipTop, _clipRight, _clipBottom };
|
||||
command.texColourAtlas = textureColour->index;
|
||||
command.texColourBounds = textureColour->normalizedBounds;
|
||||
command.texMaskAtlas = textureMask->index;
|
||||
command.texMaskBounds = textureMask->normalizedBounds;
|
||||
command.texPaletteAtlas = 0;
|
||||
command.texPaletteBounds = {0.0f, 0.0f, 0.0f};
|
||||
command.flags = 0;
|
||||
command.palettes = { 0, 0, 0 };
|
||||
command.flags = DrawRectCommand::FLAG_MASK;
|
||||
command.colour = 0;
|
||||
command.bounds = { left, top, right, bottom };
|
||||
command.mask = 1;
|
||||
}
|
||||
|
||||
void OpenGLDrawingContext::DrawSpriteSolid(uint32 image, sint32 x, sint32 y, uint8 colour)
|
||||
{
|
||||
assert((colour & 0xFF) > 0u);
|
||||
|
||||
sint32 g1Id = image & 0x7FFFF;
|
||||
rct_g1_element * g1Element = gfx_get_g1_element(g1Id);
|
||||
|
||||
|
@ -774,19 +749,17 @@ void OpenGLDrawingContext::DrawSpriteSolid(uint32 image, sint32 x, sint32 y, uin
|
|||
right += _offsetX;
|
||||
bottom += _offsetY;
|
||||
|
||||
DrawImageCommand& command = _commandBuffers.images.allocate();
|
||||
DrawRectCommand& command = _commandBuffers.rects.allocate();
|
||||
|
||||
command.clip = { _clipLeft, _clipTop, _clipRight, _clipBottom };
|
||||
command.texColourAtlas = texture->index;
|
||||
command.texColourBounds = texture->normalizedBounds;
|
||||
command.texMaskAtlas = 0;
|
||||
command.texMaskBounds = { 0.0f, 0.0f, 0.0f };
|
||||
command.texPaletteAtlas = texture->index;
|
||||
command.texPaletteBounds = texture->computedBounds;
|
||||
command.flags = DrawImageCommand::FLAG_COLOUR;
|
||||
command.texColourAtlas = 0;
|
||||
command.texColourBounds = { 0.0f, 0.0f, 0.0f, 0.0f };
|
||||
command.texMaskAtlas = texture->index;
|
||||
command.texMaskBounds = texture->normalizedBounds;
|
||||
command.palettes = { 0, 0, 0 };
|
||||
command.flags = DrawRectCommand::FLAG_NO_TEXTURE | DrawRectCommand::FLAG_MASK;
|
||||
command.colour = colour & 0xFF;
|
||||
command.bounds = { left, top, right, bottom };
|
||||
command.mask = 0;
|
||||
}
|
||||
|
||||
void OpenGLDrawingContext::DrawGlyph(uint32 image, sint32 x, sint32 y, uint8 * palette)
|
||||
|
@ -820,43 +793,23 @@ void OpenGLDrawingContext::DrawGlyph(uint32 image, sint32 x, sint32 y, uint8 * p
|
|||
right += _offsetX;
|
||||
bottom += _offsetY;
|
||||
|
||||
DrawImageCommand& command = _commandBuffers.images.allocate();
|
||||
DrawRectCommand& command = _commandBuffers.rects.allocate();
|
||||
|
||||
command.clip = { _clipLeft, _clipTop, _clipRight, _clipBottom };
|
||||
command.texColourAtlas = texture.index;
|
||||
command.texColourBounds = texture.normalizedBounds;
|
||||
command.texMaskAtlas = 0;
|
||||
command.texMaskBounds = { 0.0f, 0.0f, 0.0f };
|
||||
command.texPaletteAtlas = 0;
|
||||
command.texPaletteBounds = { 0.0f, 0.0f, 0.0f};
|
||||
command.texMaskBounds = { 0.0f, 0.0f, 0.0f, 0.0f };
|
||||
command.palettes = { 0, 0, 0 };
|
||||
command.flags = 0;
|
||||
command.colour = 0;
|
||||
command.bounds = { left, top, right, bottom };
|
||||
command.mask = 0;
|
||||
}
|
||||
|
||||
void OpenGLDrawingContext::FlushCommandBuffers()
|
||||
{
|
||||
FlushRectangles();
|
||||
FlushLines();
|
||||
FlushImages();
|
||||
}
|
||||
|
||||
void OpenGLDrawingContext::FlushRectangles()
|
||||
{
|
||||
for(size_t n = 0; n < _commandBuffers.rectangles.size(); n++)
|
||||
{
|
||||
const auto& command = _commandBuffers.rectangles[n];
|
||||
|
||||
_fillRectShader->Use();
|
||||
_fillRectShader->SetFlags(command.flags);
|
||||
_fillRectShader->SetSourceFramebuffer(command.sourceFramebuffer);
|
||||
_fillRectShader->SetClip(command.clip[0], command.clip[1], command.clip[2], command.clip[3]);
|
||||
_fillRectShader->SetPaletteRemap(command.paletteRemap);
|
||||
_fillRectShader->Draw(command.bounds[0], command.bounds[1], command.bounds[2], command.bounds[3]);
|
||||
}
|
||||
|
||||
_commandBuffers.rectangles.reset();
|
||||
FlushRectangles();
|
||||
}
|
||||
|
||||
void OpenGLDrawingContext::FlushLines()
|
||||
|
@ -867,23 +820,24 @@ void OpenGLDrawingContext::FlushLines()
|
|||
|
||||
_drawLineShader->Use();
|
||||
_drawLineShader->SetColour(command.colour);
|
||||
_drawLineShader->SetClip(command.clip[0], command.clip[1], command.clip[2], command.clip[3]);
|
||||
_drawLineShader->SetClip(command.clip.x, command.clip.y, command.clip.z, command.clip.w);
|
||||
_drawLineShader->Draw(command.pos[0], command.pos[1], command.pos[2], command.pos[3]);
|
||||
}
|
||||
|
||||
_commandBuffers.lines.reset();
|
||||
}
|
||||
|
||||
void OpenGLDrawingContext::FlushImages()
|
||||
void OpenGLDrawingContext::FlushRectangles()
|
||||
{
|
||||
if (_commandBuffers.images.size() == 0) return;
|
||||
if (_commandBuffers.rects.size() == 0) return;
|
||||
|
||||
OpenGLAPI::SetTexture(0, GL_TEXTURE_2D_ARRAY, _textureCache->GetAtlasesTexture());
|
||||
OpenGLAPI::SetTexture(1, GL_TEXTURE_RECTANGLE, _textureCache->GetPaletteTexture());
|
||||
|
||||
_drawImageShader->Use();
|
||||
_drawImageShader->DrawInstances(_commandBuffers.images);
|
||||
_drawRectShader->Use();
|
||||
_drawRectShader->DrawInstances(_commandBuffers.rects);
|
||||
|
||||
_commandBuffers.images.reset();
|
||||
_commandBuffers.rects.reset();
|
||||
}
|
||||
|
||||
void OpenGLDrawingContext::SetDPI(rct_drawpixelinfo * dpi)
|
||||
|
|
|
@ -28,11 +28,6 @@ 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);
|
||||
|
@ -59,42 +54,6 @@ const CachedTextureInfo* TextureCache::GetOrLoadImageTexture(uint32 image)
|
|||
return &(cacheItr.first->second);
|
||||
}
|
||||
|
||||
const CachedTextureInfo* TextureCache::GetOrLoadPaletteTexture(uint32 image, uint32 tertiaryColour, bool special)
|
||||
{
|
||||
if ((image & (IMAGE_TYPE_REMAP | IMAGE_TYPE_REMAP_2_PLUS | IMAGE_TYPE_TRANSPARENT)) == 0)
|
||||
{
|
||||
static CachedTextureInfo invalidEntry{ 0 };
|
||||
return &invalidEntry;
|
||||
}
|
||||
|
||||
uint32 uniquePaletteId = image & (IMAGE_TYPE_REMAP | IMAGE_TYPE_REMAP_2_PLUS | IMAGE_TYPE_TRANSPARENT);
|
||||
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);
|
||||
auto cacheItr = _paletteTextureMap.insert(std::make_pair(uniquePaletteId, cacheInfo));
|
||||
|
||||
return &(cacheItr.first->second);
|
||||
}
|
||||
|
||||
CachedTextureInfo TextureCache::GetOrLoadGlyphTexture(uint32 image, uint8 * palette)
|
||||
{
|
||||
GlyphId glyphId;
|
||||
|
@ -113,9 +72,9 @@ CachedTextureInfo TextureCache::GetOrLoadGlyphTexture(uint32 image, uint8 * pale
|
|||
return cacheInfo;
|
||||
}
|
||||
|
||||
void TextureCache::CreateAtlasesTexture()
|
||||
void TextureCache::CreateTextures()
|
||||
{
|
||||
if (!_atlasesTextureInitialised)
|
||||
if (!_initialized)
|
||||
{
|
||||
// Determine width and height to use for texture atlases
|
||||
glGetIntegerv(GL_MAX_TEXTURE_SIZE, &_atlasesTextureDimensions);
|
||||
|
@ -127,26 +86,50 @@ void TextureCache::CreateAtlasesTexture()
|
|||
glGetIntegerv(GL_MAX_ARRAY_TEXTURE_LAYERS, &_atlasesTextureIndicesLimit);
|
||||
if (_atlasesTextureDimensions < _atlasesTextureIndicesLimit) _atlasesTextureIndicesLimit = _atlasesTextureDimensions;
|
||||
|
||||
AllocateAtlasesTexture();
|
||||
glGenTextures(1, &_atlasesTexture);
|
||||
glBindTexture(GL_TEXTURE_2D_ARRAY, _atlasesTexture);
|
||||
glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||
glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
|
||||
|
||||
_atlasesTextureInitialised = true;
|
||||
glGenTextures(1, &_paletteTexture);
|
||||
glBindTexture(GL_TEXTURE_RECTANGLE, _paletteTexture);
|
||||
glTexParameteri(GL_TEXTURE_RECTANGLE, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||
glTexParameteri(GL_TEXTURE_RECTANGLE, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
|
||||
GeneratePaletteTexture();
|
||||
|
||||
_initialized = true;
|
||||
_atlasesTextureIndices = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void TextureCache::AllocateAtlasesTexture()
|
||||
void TextureCache::GeneratePaletteTexture()
|
||||
{
|
||||
// Create an array texture to hold all of the atlases
|
||||
glGenTextures(1, &_atlasesTexture);
|
||||
glBindTexture(GL_TEXTURE_2D_ARRAY, _atlasesTexture);
|
||||
glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||
glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
|
||||
rct_drawpixelinfo dpi = CreateDPI(256, PALETTE_TO_G1_OFFSET_COUNT + 5);
|
||||
|
||||
// Init no-op palette
|
||||
for (int i=0; i < 256; ++i)
|
||||
{
|
||||
dpi.bits[i] = i;
|
||||
}
|
||||
|
||||
for (int i=0; i < PALETTE_TO_G1_OFFSET_COUNT; ++i)
|
||||
{
|
||||
GLint y = PaletteToY(i);
|
||||
uint16 image = palette_to_g1_offset[i];
|
||||
const rct_g1_element &element = g1Elements[image];
|
||||
gfx_draw_sprite_software(&dpi, image, -element.x_offset, y - element.y_offset, 0);
|
||||
}
|
||||
|
||||
glBindTexture(GL_TEXTURE_RECTANGLE, _paletteTexture);
|
||||
glTexImage2D(GL_TEXTURE_RECTANGLE, 0, GL_R8UI, 256, PALETTE_TO_G1_OFFSET_COUNT + 5, 0, GL_RED_INTEGER, GL_UNSIGNED_BYTE, dpi.bits);
|
||||
DeleteDPI(dpi);
|
||||
}
|
||||
|
||||
void TextureCache::EnlargeAtlasesTexture(GLuint newEntries)
|
||||
{
|
||||
CreateAtlasesTexture();
|
||||
CreateTextures();
|
||||
|
||||
GLuint newIndices = _atlasesTextureIndices + newEntries;
|
||||
|
||||
|
@ -157,9 +140,7 @@ void TextureCache::EnlargeAtlasesTexture(GLuint newEntries)
|
|||
glGetTexImage(GL_TEXTURE_2D_ARRAY, 0, GL_RED_INTEGER, GL_UNSIGNED_BYTE, oldPixels.data());
|
||||
}
|
||||
|
||||
// Delete old texture, allocate a new one, then define the new format on the newly created texture
|
||||
glDeleteTextures(1, &_atlasesTexture);
|
||||
AllocateAtlasesTexture();
|
||||
glBindTexture(GL_TEXTURE_2D_ARRAY, _atlasesTexture);
|
||||
glTexImage3D(GL_TEXTURE_2D_ARRAY, 0, GL_R8UI, _atlasesTextureDimensions, _atlasesTextureDimensions, newIndices, 0, GL_RED_INTEGER, GL_UNSIGNED_BYTE, nullptr);
|
||||
|
||||
// Restore old data
|
||||
|
@ -170,12 +151,12 @@ void TextureCache::EnlargeAtlasesTexture(GLuint newEntries)
|
|||
|
||||
CachedTextureInfo TextureCache::LoadImageTexture(uint32 image)
|
||||
{
|
||||
rct_drawpixelinfo * dpi = GetImageAsDPI(image, 0);
|
||||
rct_drawpixelinfo dpi = GetImageAsDPI(image, 0);
|
||||
|
||||
auto cacheInfo = AllocateImage(dpi->width, dpi->height);
|
||||
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);
|
||||
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);
|
||||
|
||||
DeleteDPI(dpi);
|
||||
|
||||
|
@ -190,61 +171,23 @@ CachedTextureInfo TextureCache::LoadImageTexture(uint32 image)
|
|||
return cacheInfo;
|
||||
}
|
||||
|
||||
CachedTextureInfo TextureCache::LoadPaletteTexture(uint32 image, uint32 tertiaryColour, bool special)
|
||||
CachedTextureInfo TextureCache::LoadGlyphTexture(uint32 image, uint8 * palette)
|
||||
{
|
||||
rct_drawpixelinfo dpi;
|
||||
dpi.bits = gfx_draw_sprite_get_palette(image, tertiaryColour);
|
||||
dpi.width = 256;
|
||||
dpi.height = special ? 5 : 1;
|
||||
rct_drawpixelinfo dpi = GetGlyphAsDPI(image, palette);
|
||||
|
||||
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);
|
||||
|
||||
cacheInfo.computedBounds =
|
||||
{
|
||||
cacheInfo.normalizedBounds.x,
|
||||
cacheInfo.normalizedBounds.y,
|
||||
(cacheInfo.normalizedBounds.z - cacheInfo.normalizedBounds.x) / (float)(cacheInfo.bounds.z - cacheInfo.bounds.x),
|
||||
(cacheInfo.normalizedBounds.w - cacheInfo.normalizedBounds.y) / (float)(cacheInfo.bounds.w - cacheInfo.bounds.y)
|
||||
};
|
||||
|
||||
return cacheInfo;
|
||||
}
|
||||
|
||||
CachedTextureInfo TextureCache::LoadGlyphTexture(uint32 image, uint8 * palette)
|
||||
{
|
||||
rct_drawpixelinfo * dpi = GetGlyphAsDPI(image, palette);
|
||||
|
||||
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);
|
||||
|
||||
DeleteDPI(dpi);
|
||||
|
||||
return cacheInfo;
|
||||
}
|
||||
|
||||
void * TextureCache::GetImageAsARGB(uint32 image, uint32 tertiaryColour, uint32 * outWidth, uint32 * outHeight)
|
||||
{
|
||||
rct_g1_element * g1Element = gfx_get_g1_element(image & 0x7FFFF);
|
||||
sint32 width = g1Element->width;
|
||||
sint32 height = g1Element->height;
|
||||
|
||||
rct_drawpixelinfo * dpi = CreateDPI(width, height);
|
||||
gfx_draw_sprite_software(dpi, image, -g1Element->x_offset, -g1Element->y_offset, tertiaryColour);
|
||||
void * pixels32 = ConvertDPIto32bpp(dpi);
|
||||
DeleteDPI(dpi);
|
||||
|
||||
*outWidth = width;
|
||||
*outHeight = height;
|
||||
return pixels32;
|
||||
}
|
||||
|
||||
CachedTextureInfo TextureCache::AllocateImage(sint32 imageWidth, sint32 imageHeight)
|
||||
{
|
||||
CreateAtlasesTexture();
|
||||
CreateTextures();
|
||||
|
||||
// Find an atlas that fits this image
|
||||
for (Atlas& atlas : _atlases)
|
||||
|
@ -278,73 +221,28 @@ CachedTextureInfo TextureCache::AllocateImage(sint32 imageWidth, sint32 imageHei
|
|||
return _atlases.back().Allocate(imageWidth, imageHeight);
|
||||
}
|
||||
|
||||
rct_drawpixelinfo * TextureCache::GetImageAsDPI(uint32 image, uint32 tertiaryColour)
|
||||
rct_drawpixelinfo TextureCache::GetImageAsDPI(uint32 image, uint32 tertiaryColour)
|
||||
{
|
||||
rct_g1_element * g1Element = gfx_get_g1_element(image & 0x7FFFF);
|
||||
sint32 width = g1Element->width;
|
||||
sint32 height = g1Element->height;
|
||||
|
||||
rct_drawpixelinfo * dpi = CreateDPI(width, height);
|
||||
gfx_draw_sprite_software(dpi, image, -g1Element->x_offset, -g1Element->y_offset, tertiaryColour);
|
||||
rct_drawpixelinfo dpi = CreateDPI(width, height);
|
||||
gfx_draw_sprite_software(&dpi, image, -g1Element->x_offset, -g1Element->y_offset, tertiaryColour);
|
||||
return dpi;
|
||||
}
|
||||
|
||||
void * TextureCache::GetGlyphAsARGB(uint32 image, uint8 * palette, uint32 * outWidth, uint32 * outHeight)
|
||||
rct_drawpixelinfo TextureCache::GetGlyphAsDPI(uint32 image, uint8 * palette)
|
||||
{
|
||||
rct_g1_element * g1Element = gfx_get_g1_element(image & 0x7FFFF);
|
||||
sint32 width = g1Element->width;
|
||||
sint32 height = g1Element->height;
|
||||
|
||||
rct_drawpixelinfo * dpi = CreateDPI(width, height);
|
||||
gfx_draw_sprite_palette_set_software(dpi, image, -g1Element->x_offset, -g1Element->y_offset, palette, nullptr);
|
||||
void * pixels32 = ConvertDPIto32bpp(dpi);
|
||||
DeleteDPI(dpi);
|
||||
|
||||
*outWidth = width;
|
||||
*outHeight = height;
|
||||
return pixels32;
|
||||
}
|
||||
|
||||
rct_drawpixelinfo * TextureCache::GetGlyphAsDPI(uint32 image, uint8 * palette)
|
||||
{
|
||||
rct_g1_element * g1Element = gfx_get_g1_element(image & 0x7FFFF);
|
||||
sint32 width = g1Element->width;
|
||||
sint32 height = g1Element->height;
|
||||
|
||||
rct_drawpixelinfo * dpi = CreateDPI(width, height);
|
||||
gfx_draw_sprite_palette_set_software(dpi, image, -g1Element->x_offset, -g1Element->y_offset, palette, nullptr);
|
||||
rct_drawpixelinfo dpi = CreateDPI(width, height);
|
||||
gfx_draw_sprite_palette_set_software(&dpi, image, -g1Element->x_offset, -g1Element->y_offset, palette, nullptr);
|
||||
return dpi;
|
||||
}
|
||||
|
||||
void * TextureCache::ConvertDPIto32bpp(const rct_drawpixelinfo * dpi)
|
||||
{
|
||||
size_t numPixels = dpi->width * dpi->height;
|
||||
uint8 * pixels32 = Memory::Allocate<uint8>(numPixels * 4);
|
||||
uint8 * src = dpi->bits;
|
||||
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;
|
||||
}
|
||||
}
|
||||
return pixels32;
|
||||
}
|
||||
|
||||
void TextureCache::FreeTextures()
|
||||
{
|
||||
// Free array texture
|
||||
|
@ -352,27 +250,26 @@ void TextureCache::FreeTextures()
|
|||
_imageTextureMap.clear();
|
||||
}
|
||||
|
||||
rct_drawpixelinfo * TextureCache::CreateDPI(sint32 width, sint32 height)
|
||||
rct_drawpixelinfo TextureCache::CreateDPI(sint32 width, sint32 height)
|
||||
{
|
||||
size_t numPixels = width * height;
|
||||
uint8 * pixels8 = Memory::Allocate<uint8>(numPixels);
|
||||
Memory::Set(pixels8, 0, numPixels);
|
||||
|
||||
rct_drawpixelinfo * dpi = new rct_drawpixelinfo();
|
||||
dpi->bits = pixels8;
|
||||
dpi->pitch = 0;
|
||||
dpi->x = 0;
|
||||
dpi->y = 0;
|
||||
dpi->width = width;
|
||||
dpi->height = height;
|
||||
dpi->zoom_level = 0;
|
||||
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;
|
||||
return dpi;
|
||||
}
|
||||
|
||||
void TextureCache::DeleteDPI(rct_drawpixelinfo* dpi)
|
||||
void TextureCache::DeleteDPI(rct_drawpixelinfo dpi)
|
||||
{
|
||||
Memory::Free(dpi->bits);
|
||||
delete dpi;
|
||||
Memory::Free(dpi.bits);
|
||||
}
|
||||
|
||||
GLuint TextureCache::GetAtlasesTexture()
|
||||
|
@ -380,4 +277,14 @@ GLuint TextureCache::GetAtlasesTexture()
|
|||
return _atlasesTexture;
|
||||
}
|
||||
|
||||
GLuint TextureCache::GetPaletteTexture()
|
||||
{
|
||||
return _paletteTexture;
|
||||
}
|
||||
|
||||
GLint TextureCache::PaletteToY(uint32 palette)
|
||||
{
|
||||
return palette > PALETTE_WATER ? palette + 5 : palette + 1;
|
||||
}
|
||||
|
||||
#endif /* DISABLE_OPENGL */
|
||||
|
|
|
@ -188,7 +188,7 @@ private:
|
|||
class TextureCache final
|
||||
{
|
||||
private:
|
||||
bool _atlasesTextureInitialised = false;
|
||||
bool _initialized = false;
|
||||
|
||||
GLuint _atlasesTexture = 0;
|
||||
GLint _atlasesTextureDimensions = 0;
|
||||
|
@ -200,34 +200,30 @@ private:
|
|||
std::unordered_map<uint32, CachedTextureInfo> _imageTextureMap;
|
||||
std::unordered_map<uint32, CachedTextureInfo> _paletteTextureMap;
|
||||
|
||||
SDL_Color _palette[256];
|
||||
GLuint _paletteTexture = 0;
|
||||
|
||||
public:
|
||||
TextureCache() = default;
|
||||
~TextureCache();
|
||||
void SetPalette(const SDL_Color * palette);
|
||||
void InvalidateImage(uint32 image);
|
||||
const CachedTextureInfo* GetOrLoadImageTexture(uint32 image);
|
||||
CachedTextureInfo GetOrLoadGlyphTexture(uint32 image, uint8 * palette);
|
||||
const CachedTextureInfo* GetOrLoadPaletteTexture(uint32 image, uint32 tertiaryColour, bool special);
|
||||
|
||||
GLuint GetAtlasesTexture();
|
||||
GLuint GetPaletteTexture();
|
||||
static GLint PaletteToY(uint32 palette);
|
||||
|
||||
private:
|
||||
void CreateAtlasesTexture();
|
||||
void AllocateAtlasesTexture();
|
||||
void CreateTextures();
|
||||
void GeneratePaletteTexture();
|
||||
void EnlargeAtlasesTexture(GLuint newEntries);
|
||||
CachedTextureInfo LoadImageTexture(uint32 image);
|
||||
CachedTextureInfo LoadGlyphTexture(uint32 image, uint8 * palette);
|
||||
CachedTextureInfo LoadPaletteTexture(uint32 image, uint32 tertiaryColour, bool special);
|
||||
CachedTextureInfo AllocateImage(sint32 imageWidth, sint32 imageHeight);
|
||||
void * GetImageAsARGB(uint32 image, uint32 tertiaryColour, uint32 * outWidth, uint32 * outHeight);
|
||||
rct_drawpixelinfo * GetImageAsDPI(uint32 image, uint32 tertiaryColour);
|
||||
void * GetGlyphAsARGB(uint32 image, uint8 * palette, uint32 * outWidth, uint32 * outHeight);
|
||||
rct_drawpixelinfo * GetGlyphAsDPI(uint32 image, uint8 * palette);
|
||||
void * ConvertDPIto32bpp(const rct_drawpixelinfo * dpi);
|
||||
rct_drawpixelinfo GetImageAsDPI(uint32 image, uint32 tertiaryColour);
|
||||
rct_drawpixelinfo GetGlyphAsDPI(uint32 image, uint8 * palette);
|
||||
void FreeTextures();
|
||||
|
||||
static rct_drawpixelinfo * CreateDPI(sint32 width, sint32 height);
|
||||
static void DeleteDPI(rct_drawpixelinfo * dpi);
|
||||
static rct_drawpixelinfo CreateDPI(sint32 width, sint32 height);
|
||||
static void DeleteDPI(rct_drawpixelinfo dpi);
|
||||
};
|
||||
|
|
Loading…
Reference in New Issue