mirror of
https://github.com/OpenRCT2/OpenRCT2
synced 2025-12-23 15:52:55 +01:00
OpenGL: Delay Palette Mapping Until Final Framebuffer Copy to Screen
This commit is contained in:
committed by
Michał Janiszewski
parent
85b257cc2e
commit
f105237a2e
@@ -1,6 +1,7 @@
|
||||
#version 150
|
||||
|
||||
uniform sampler2D uTexture;
|
||||
uniform vec4 uPalette[256];
|
||||
uniform usampler2D uTexture;
|
||||
|
||||
in vec2 fPosition;
|
||||
in vec2 fTextureCoordinate;
|
||||
@@ -9,5 +10,5 @@ out vec4 oColour;
|
||||
|
||||
void main()
|
||||
{
|
||||
oColour = texture(uTexture, fTextureCoordinate);
|
||||
oColour = uPalette[texture(uTexture, fTextureCoordinate).r];
|
||||
}
|
||||
|
||||
@@ -5,12 +5,11 @@ const int FLAG_REMAP = (1 << 1);
|
||||
const int FLAG_TRANSPARENT = (1 << 2);
|
||||
const int FLAG_TRANSPARENT_SPECIAL = (1 << 3);
|
||||
|
||||
uniform vec4 uPalette[256];
|
||||
uniform usampler2DArray uTexture;
|
||||
|
||||
flat in ivec4 fClip;
|
||||
flat in int fFlags;
|
||||
in vec4 fColour;
|
||||
flat in uint fColour;
|
||||
flat in int fTexColourAtlas;
|
||||
in vec2 fTexColourCoords;
|
||||
flat in int fTexMaskAtlas;
|
||||
@@ -20,9 +19,8 @@ flat in vec4 fTexPaletteBounds;
|
||||
flat in int fMask;
|
||||
|
||||
in vec2 fPosition;
|
||||
in vec2 fTextureCoordinate;
|
||||
|
||||
out vec4 oColour;
|
||||
out uint oColour;
|
||||
|
||||
void main()
|
||||
{
|
||||
@@ -32,43 +30,46 @@ void main()
|
||||
discard;
|
||||
}
|
||||
|
||||
vec4 texel;
|
||||
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 = uPalette[texture(uTexture, vec3(x, fTexPaletteBounds.y, float(fTexPaletteAtlas))).r];
|
||||
texel = texture(uTexture, vec3(x, fTexPaletteBounds.y, float(fTexPaletteAtlas))).r;
|
||||
} // If transparent or special transparent
|
||||
else if ((fFlags & (FLAG_TRANSPARENT | FLAG_TRANSPARENT_SPECIAL)) != 0)
|
||||
{
|
||||
float line = texture(uTexture,vec3(fTexColourCoords, float(fTexColourAtlas))).r;
|
||||
if (line == 0.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 = 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 = uPalette[texture(uTexture, vec3(fTexColourCoords, float(fTexColourAtlas))).r];
|
||||
texel = texture(uTexture, vec3(fTexColourCoords, float(fTexColourAtlas))).r;
|
||||
}
|
||||
|
||||
if (fMask != 0)
|
||||
{
|
||||
float mask = texture(uTexture, vec3(fTexMaskCoords, float(fTexMaskAtlas))).r;
|
||||
if ( mask == 0.0 )
|
||||
uint mask = texture(uTexture, vec3(fTexMaskCoords, float(fTexMaskAtlas))).r;
|
||||
if ( mask == 0u )
|
||||
{
|
||||
discard;
|
||||
}
|
||||
@@ -77,9 +78,14 @@ void main()
|
||||
}
|
||||
else
|
||||
{
|
||||
if (texel == 0u)
|
||||
{
|
||||
discard;
|
||||
}
|
||||
if ((fFlags & FLAG_COLOUR) != 0)
|
||||
{
|
||||
oColour = vec4(fColour.rgb, fColour.a * texel.a);
|
||||
//oColour = vec4(fColour.rgb, fColour.a * texel.a);
|
||||
oColour = fColour;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -10,17 +10,16 @@ in vec4 ivTexMaskBounds;
|
||||
in int ivTexPaletteAtlas;
|
||||
in vec4 ivTexPaletteBounds;
|
||||
in int ivFlags;
|
||||
in vec4 ivColour;
|
||||
in uint ivColour;
|
||||
in ivec4 ivBounds;
|
||||
in int ivMask;
|
||||
|
||||
in uint vIndex;
|
||||
|
||||
out vec2 fTextureCoordinate;
|
||||
out vec2 fPosition;
|
||||
flat out ivec4 fClip;
|
||||
flat out int fFlags;
|
||||
out vec4 fColour;
|
||||
flat out uint fColour;
|
||||
flat out int fTexColourAtlas;
|
||||
out vec2 fTexColourCoords;
|
||||
flat out int fTexMaskAtlas;
|
||||
|
||||
@@ -1,12 +1,11 @@
|
||||
#version 150
|
||||
|
||||
uniform ivec2 uScreenSize;
|
||||
uniform ivec4 uClip;
|
||||
uniform vec4 uColour;
|
||||
uniform uint uColour;
|
||||
|
||||
in vec2 fPosition;
|
||||
|
||||
out vec4 oColour;
|
||||
out uint oColour;
|
||||
|
||||
void main()
|
||||
{
|
||||
|
||||
@@ -3,14 +3,12 @@
|
||||
uniform ivec2 uScreenSize;
|
||||
uniform ivec4 uClip;
|
||||
uniform int uFlags;
|
||||
uniform sampler2D uSourceFramebuffer;
|
||||
uniform ivec4 uBounds;
|
||||
uniform vec4 uPalette[256];
|
||||
uniform int uPaletteRemap[256];
|
||||
uniform usampler2D uSourceFramebuffer;
|
||||
uniform uint uPaletteRemap[256];
|
||||
|
||||
in vec2 fPosition;
|
||||
|
||||
out vec4 oColour;
|
||||
out uint oColour;
|
||||
|
||||
void main()
|
||||
{
|
||||
@@ -29,19 +27,7 @@ void main()
|
||||
}
|
||||
}
|
||||
|
||||
vec2 textureCoordinates = (fPosition / vec2(uScreenSize)) * vec2(1, -1);
|
||||
vec4 sourceColour = texture(uSourceFramebuffer, textureCoordinates);
|
||||
|
||||
// find "best match" palette index of the current 32 bit color
|
||||
float nearestDistance = length(uPalette[0] - sourceColour);
|
||||
uint bestPaletteIndexMatch = 0u;
|
||||
for (uint i = 1u; i < 256u; i++)
|
||||
{
|
||||
float distance = length(uPalette[i] - sourceColour);
|
||||
uint isBetter = -uint(distance < nearestDistance); // unpredictable
|
||||
bestPaletteIndexMatch = (bestPaletteIndexMatch & ~isBetter) | (i & isBetter);
|
||||
nearestDistance = min(nearestDistance, distance);
|
||||
}
|
||||
|
||||
oColour = uPalette[uPaletteRemap[bestPaletteIndexMatch]];
|
||||
vec2 textureCoordinates = (fPosition / vec2(uScreenSize)) * vec2(1.0, -1.0) + vec2(0.0, 1.0);
|
||||
uint sourceColour = texture(uSourceFramebuffer, textureCoordinates).r;
|
||||
oColour = uPaletteRemap[sourceColour];
|
||||
}
|
||||
|
||||
@@ -50,6 +50,7 @@ void CopyFramebufferShader::GetLocations()
|
||||
uBounds = GetUniformLocation("uBounds");
|
||||
uTextureCoordinates = GetUniformLocation("uTextureCoordinates");
|
||||
uTexture = GetUniformLocation("uTexture");
|
||||
uPalette = GetUniformLocation("uPalette");
|
||||
|
||||
vIndex = GetAttributeLocation("vIndex");
|
||||
}
|
||||
@@ -74,6 +75,10 @@ void CopyFramebufferShader::SetTexture(GLuint texture)
|
||||
OpenGLAPI::SetTexture(0, GL_TEXTURE_2D, texture);
|
||||
}
|
||||
|
||||
void CopyFramebufferShader::SetPalette(const vec4f * glPalette) {
|
||||
glUniform4fv(uPalette, 256, (const GLfloat *)glPalette);
|
||||
}
|
||||
|
||||
void CopyFramebufferShader::Draw()
|
||||
{
|
||||
glBindVertexArray(_vao);
|
||||
|
||||
@@ -26,6 +26,7 @@ private:
|
||||
GLuint uBounds;
|
||||
GLuint uTextureCoordinates;
|
||||
GLuint uTexture;
|
||||
GLuint uPalette;
|
||||
|
||||
GLuint vIndex;
|
||||
|
||||
@@ -40,6 +41,7 @@ public:
|
||||
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);
|
||||
|
||||
void Draw();
|
||||
|
||||
|
||||
@@ -69,11 +69,11 @@ struct DrawRectCommand {
|
||||
GLuint sourceFramebuffer;
|
||||
sint32 clip[4];
|
||||
sint32 bounds[4];
|
||||
GLint paletteRemap[256];
|
||||
GLuint paletteRemap[256];
|
||||
};
|
||||
|
||||
struct DrawLineCommand {
|
||||
vec4f colour;
|
||||
uint8 colour;
|
||||
sint32 clip[4];
|
||||
sint32 pos[4];
|
||||
};
|
||||
@@ -88,7 +88,7 @@ struct DrawImageCommand {
|
||||
sint32 texPaletteAtlas;
|
||||
vec4f texPaletteBounds;
|
||||
sint32 flags;
|
||||
vec4f colour;
|
||||
uint8 colour;
|
||||
vec4i bounds;
|
||||
sint32 mask;
|
||||
|
||||
|
||||
@@ -43,7 +43,7 @@ DrawImageShader::DrawImageShader() : OpenGLShaderProgram("drawimage")
|
||||
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));
|
||||
glVertexAttribPointer(vColour, 4, GL_FLOAT, GL_FALSE, sizeof(DrawImageCommand), (void*) offsetof(DrawImageCommand, colour));
|
||||
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));
|
||||
|
||||
@@ -87,7 +87,6 @@ void DrawImageShader::GetLocations()
|
||||
{
|
||||
uScreenSize = GetUniformLocation("uScreenSize");
|
||||
uTexture = GetUniformLocation("uTexture");
|
||||
uPalette = GetUniformLocation("uPalette");
|
||||
|
||||
vIndex = GetAttributeLocation("vIndex");
|
||||
vClip = GetAttributeLocation("ivClip");
|
||||
@@ -108,11 +107,6 @@ void DrawImageShader::SetScreenSize(sint32 width, sint32 height)
|
||||
glUniform2i(uScreenSize, width, height);
|
||||
}
|
||||
|
||||
void DrawImageShader::SetPalette(const vec4f *glPalette)
|
||||
{
|
||||
glUniform4fv(uPalette, 256, (const GLfloat *) glPalette);
|
||||
}
|
||||
|
||||
void DrawImageShader::DrawInstances(const ImageCommandBatch& instances)
|
||||
{
|
||||
glBindVertexArray(_vao);
|
||||
|
||||
@@ -27,7 +27,6 @@ class DrawImageShader final : public OpenGLShaderProgram
|
||||
private:
|
||||
GLuint uScreenSize;
|
||||
GLuint uTexture;
|
||||
GLuint uPalette;
|
||||
|
||||
GLuint vIndex;
|
||||
GLuint vClip;
|
||||
@@ -51,7 +50,6 @@ public:
|
||||
~DrawImageShader() override;
|
||||
|
||||
void SetScreenSize(sint32 width, sint32 height);
|
||||
void SetPalette(const vec4f *glPalette);
|
||||
void DrawInstances(const ImageCommandBatch& instances);
|
||||
|
||||
private:
|
||||
|
||||
@@ -68,9 +68,9 @@ void DrawLineShader::SetBounds(sint32 x0, sint32 y0, sint32 x1, sint32 y1)
|
||||
glUniform4i(uBounds, x0, y0, x1, y1);
|
||||
}
|
||||
|
||||
void DrawLineShader::SetColour(vec4f colour)
|
||||
void DrawLineShader::SetColour(uint8 colour)
|
||||
{
|
||||
glUniform4f(uColour, colour.r, colour.g, colour.b, colour.a);
|
||||
glUniform1ui(uColour, colour);
|
||||
}
|
||||
|
||||
void DrawLineShader::Draw(sint32 x0, sint32 y0, sint32 x1, sint32 y1)
|
||||
|
||||
@@ -39,7 +39,7 @@ public:
|
||||
void SetScreenSize(sint32 width, sint32 height);
|
||||
void SetClip(sint32 left, sint32 top, sint32 right, sint32 bottom);
|
||||
void SetBounds(sint32 x0, sint32 y0, sint32 x1, sint32 y1);
|
||||
void SetColour(vec4f colour);
|
||||
void SetColour(uint8 colour);
|
||||
|
||||
void Draw(sint32 x0, sint32 y0, sint32 x1, sint32 y1);
|
||||
|
||||
|
||||
@@ -52,7 +52,6 @@ void FillRectShader::GetLocations()
|
||||
uBounds = GetUniformLocation("uBounds");
|
||||
uFlags = GetUniformLocation("uFlags");
|
||||
uSourceFramebuffer = GetUniformLocation("uSourceFramebuffer");
|
||||
uPalette = GetUniformLocation("uPalette");
|
||||
uPaletteRemap = GetUniformLocation("uPaletteRemap");
|
||||
|
||||
vIndex = GetAttributeLocation("vIndex");
|
||||
@@ -84,14 +83,9 @@ void FillRectShader::SetSourceFramebuffer(GLuint texture)
|
||||
OpenGLAPI::SetTexture(0, GL_TEXTURE_2D, texture);
|
||||
}
|
||||
|
||||
void FillRectShader::SetPalette(const vec4f * glPalette)
|
||||
void FillRectShader::SetPaletteRemap(const GLuint * paletteRemap)
|
||||
{
|
||||
glUniform4fv(uPalette, 256, (const GLfloat *)glPalette);
|
||||
}
|
||||
|
||||
void FillRectShader::SetPaletteRemap(const GLint * paletteRemap)
|
||||
{
|
||||
glUniform1iv(uPaletteRemap, 256, paletteRemap);
|
||||
glUniform1uiv(uPaletteRemap, 256, paletteRemap);
|
||||
}
|
||||
|
||||
void FillRectShader::Draw(sint32 left, sint32 top, sint32 right, sint32 bottom)
|
||||
@@ -102,7 +96,8 @@ void FillRectShader::Draw(sint32 left, sint32 top, sint32 right, sint32 bottom)
|
||||
glDrawArrays(GL_TRIANGLES, 0, 6);
|
||||
}
|
||||
|
||||
GLuint FillRectShader::GetSourceFramebuffer() const {
|
||||
GLuint FillRectShader::GetSourceFramebuffer() const
|
||||
{
|
||||
return _sourceFramebuffer;
|
||||
}
|
||||
|
||||
|
||||
@@ -29,7 +29,6 @@ private:
|
||||
GLuint uBounds;
|
||||
GLuint uFlags;
|
||||
GLuint uSourceFramebuffer;
|
||||
GLuint uPalette;
|
||||
GLuint uPaletteRemap;
|
||||
|
||||
GLuint vIndex;
|
||||
@@ -48,8 +47,7 @@ public:
|
||||
void SetBounds(sint32 left, sint32 top, sint32 right, sint32 bottom);
|
||||
void SetFlags(uint32 flags);
|
||||
void SetSourceFramebuffer(GLuint texture);
|
||||
void SetPalette(const vec4f * glPalette);
|
||||
void SetPaletteRemap(const GLint * filterMap);
|
||||
void SetPaletteRemap(const GLuint * filterMap);
|
||||
|
||||
void Draw(sint32 left, sint32 top, sint32 right, sint32 bottom);
|
||||
|
||||
|
||||
@@ -49,6 +49,7 @@ OPENGL_PROC(PFNGLBINDBUFFERPROC, glBindBuffer)
|
||||
OPENGL_PROC(PFNGLBINDFRAGDATALOCATIONPROC, glBindFragDataLocation)
|
||||
OPENGL_PROC(PFNGLBINDFRAMEBUFFERPROC, glBindFramebuffer)
|
||||
OPENGL_PROC(PFNGLBINDVERTEXARRAYPROC, glBindVertexArray)
|
||||
OPENGL_PROC(PFNGLBLITFRAMEBUFFERPROC, glBlitFramebuffer);
|
||||
OPENGL_PROC(PFNGLBUFFERDATAPROC, glBufferData)
|
||||
OPENGL_PROC(PFNGLCOMPILESHADERPROC, glCompileShader)
|
||||
OPENGL_PROC(PFNGLCREATEPROGRAMPROC, glCreateProgram)
|
||||
@@ -74,6 +75,8 @@ OPENGL_PROC(PFNGLLINKPROGRAMPROC, glLinkProgram)
|
||||
OPENGL_PROC(PFNGLSHADERSOURCEPROC, glShaderSource)
|
||||
OPENGL_PROC(PFNGLUNIFORM1IPROC, glUniform1i)
|
||||
OPENGL_PROC(PFNGLUNIFORM1IVPROC, glUniform1iv)
|
||||
OPENGL_PROC(PFNGLUNIFORM1UIPROC, glUniform1ui);
|
||||
OPENGL_PROC(PFNGLUNIFORM1UIVPROC, glUniform1uiv);
|
||||
OPENGL_PROC(PFNGLUNIFORM2IPROC, glUniform2i)
|
||||
OPENGL_PROC(PFNGLUNIFORM2FPROC, glUniform2f)
|
||||
OPENGL_PROC(PFNGLUNIFORM4FPROC, glUniform4f)
|
||||
|
||||
@@ -186,9 +186,6 @@ public:
|
||||
|
||||
_drawingContext->Initialise();
|
||||
|
||||
glEnable(GL_BLEND);
|
||||
glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE);
|
||||
|
||||
_copyFramebufferShader = new CopyFramebufferShader();
|
||||
}
|
||||
|
||||
@@ -215,6 +212,9 @@ public:
|
||||
colour.b / 255.0f,
|
||||
colour.a / 255.0f };
|
||||
}
|
||||
|
||||
_copyFramebufferShader->Use();
|
||||
_copyFramebufferShader->SetPalette(GLPalette);
|
||||
_drawingContext->ResetPalette();
|
||||
}
|
||||
|
||||
@@ -267,10 +267,8 @@ public:
|
||||
{
|
||||
const OpenGLFramebuffer * framebuffer = _swapFramebuffer->GetTargetFramebuffer();
|
||||
framebuffer->Bind();
|
||||
void * pixels = framebuffer->GetPixels();
|
||||
|
||||
sint32 result = screenshot_dump_png_32bpp(_width, _height, pixels);
|
||||
Memory::Free(pixels);
|
||||
framebuffer->GetPixels(_bitsDPI);
|
||||
sint32 result = screenshot_dump_png(&_bitsDPI);
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -442,13 +440,9 @@ void OpenGLDrawingContext::Resize(sint32 width, sint32 height)
|
||||
|
||||
void OpenGLDrawingContext::ResetPalette()
|
||||
{
|
||||
FlushCommandBuffers();
|
||||
//FlushCommandBuffers();
|
||||
|
||||
_textureCache->SetPalette(_engine->Palette);
|
||||
_drawImageShader->Use();
|
||||
_drawImageShader->SetPalette(_engine->GLPalette);
|
||||
_fillRectShader->Use();
|
||||
_fillRectShader->SetPalette(_engine->GLPalette);
|
||||
}
|
||||
|
||||
void OpenGLDrawingContext::Clear(uint8 paletteIndex)
|
||||
@@ -548,11 +542,9 @@ void OpenGLDrawingContext::DrawLine(uint32 colour, sint32 x1, sint32 y1, sint32
|
||||
x2 += _offsetX;
|
||||
y2 += _offsetY;
|
||||
|
||||
vec4f paletteColour = _engine->GLPalette[colour & 0xFF];
|
||||
|
||||
DrawLineCommand& command = _commandBuffers.lines.allocate();
|
||||
|
||||
command.colour = paletteColour;
|
||||
command.colour = colour & 0xFF;
|
||||
|
||||
command.clip[0] = _clipLeft;
|
||||
command.clip[1] = _clipTop;
|
||||
@@ -672,7 +664,7 @@ void OpenGLDrawingContext::DrawSprite(uint32 image, sint32 x, sint32 y, uint32 t
|
||||
command.texMaskBounds = { 0.0f, 0.0f, 0.0f };
|
||||
command.texPaletteAtlas = texture2->index;
|
||||
command.texPaletteBounds = texture2->computedBounds;
|
||||
command.colour = { 0.0f, 0.0f, 0.0f };
|
||||
command.colour = 0;
|
||||
command.bounds = { left, top, right, bottom };
|
||||
command.mask = 0;
|
||||
command.flags = 0;
|
||||
@@ -746,15 +738,13 @@ void OpenGLDrawingContext::DrawSpriteRawMasked(sint32 x, sint32 y, uint32 maskIm
|
||||
command.texPaletteAtlas = 0;
|
||||
command.texPaletteBounds = {0.0f, 0.0f, 0.0f};
|
||||
command.flags = 0;
|
||||
command.colour = {0.0f, 0.0f, 0.0f};
|
||||
command.colour = 0;
|
||||
command.bounds = { left, top, right, bottom };
|
||||
command.mask = 1;
|
||||
}
|
||||
|
||||
void OpenGLDrawingContext::DrawSpriteSolid(uint32 image, sint32 x, sint32 y, uint8 colour)
|
||||
{
|
||||
vec4f paletteColour = _engine->GLPalette[colour & 0xFF];
|
||||
|
||||
sint32 g1Id = image & 0x7FFFF;
|
||||
rct_g1_element * g1Element = gfx_get_g1_element(g1Id);
|
||||
|
||||
@@ -794,7 +784,7 @@ void OpenGLDrawingContext::DrawSpriteSolid(uint32 image, sint32 x, sint32 y, uin
|
||||
command.texPaletteAtlas = texture->index;
|
||||
command.texPaletteBounds = texture->computedBounds;
|
||||
command.flags = DrawImageCommand::FLAG_COLOUR;
|
||||
command.colour = paletteColour;
|
||||
command.colour = colour & 0xFF;
|
||||
command.bounds = { left, top, right, bottom };
|
||||
command.mask = 0;
|
||||
}
|
||||
@@ -840,7 +830,7 @@ void OpenGLDrawingContext::DrawGlyph(uint32 image, sint32 x, sint32 y, uint8 * p
|
||||
command.texPaletteAtlas = 0;
|
||||
command.texPaletteBounds = { 0.0f, 0.0f, 0.0f};
|
||||
command.flags = 0;
|
||||
command.colour = { 0.0f, 0.0f, 0.0f };
|
||||
command.colour = 0;
|
||||
command.bounds = { left, top, right, bottom };
|
||||
command.mask = 0;
|
||||
}
|
||||
|
||||
@@ -37,9 +37,9 @@ OpenGLFramebuffer::OpenGLFramebuffer(sint32 width, sint32 height)
|
||||
|
||||
glGenTextures(1, &_texture);
|
||||
glBindTexture(GL_TEXTURE_2D, _texture);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_R8UI, width, height, 0, GL_RED_INTEGER, GL_UNSIGNED_BYTE, nullptr);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||
|
||||
glGenFramebuffers(1, &_id);
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, _id);
|
||||
@@ -61,25 +61,33 @@ void OpenGLFramebuffer::Bind() const
|
||||
glViewport(0, 0, (GLsizei)_width, (GLsizei)_height);
|
||||
}
|
||||
|
||||
void * OpenGLFramebuffer::GetPixels() const
|
||||
void OpenGLFramebuffer::BindDraw() const
|
||||
{
|
||||
void * pixels = Memory::Allocate<void>(_width * _height * 4);
|
||||
glReadPixels(0, 0, _width, _height, GL_RGBA, GL_UNSIGNED_BYTE, pixels);
|
||||
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, _id);
|
||||
}
|
||||
|
||||
// Flip pixels vertically
|
||||
void * flippedPixels = Memory::Allocate<void>(_width * _height * 4);
|
||||
size_t stride = _width * 4;
|
||||
uint8 * src = (uint8 *)pixels + ((_height - 1) * stride);
|
||||
uint8 * dst = (uint8 *)flippedPixels;
|
||||
void OpenGLFramebuffer::BindRead() const
|
||||
{
|
||||
glBindFramebuffer(GL_READ_FRAMEBUFFER, _id);
|
||||
}
|
||||
|
||||
void OpenGLFramebuffer::GetPixels(rct_drawpixelinfo &dpi) const
|
||||
{
|
||||
assert(dpi.width == _width && dpi.height == _height);
|
||||
|
||||
uint8 * pixels = Memory::Allocate<uint8>(_width * _height);
|
||||
glReadPixels(0, 0, _width, _height, GL_RED_INTEGER, GL_UNSIGNED_BYTE, pixels);
|
||||
|
||||
// Flip pixels vertically on copy
|
||||
uint8 * src = pixels + ((_height - 1) * _width);
|
||||
uint8 * dst = dpi.bits;
|
||||
for (sint32 y = 0; y < _height; y++)
|
||||
{
|
||||
Memory::Copy(dst, src, stride);
|
||||
src -= stride;
|
||||
dst += stride;
|
||||
Memory::Copy(dst, src, _width);
|
||||
src -= _width;
|
||||
dst += dpi.width + dpi.pitch;
|
||||
}
|
||||
Memory::Free(pixels);
|
||||
|
||||
return flippedPixels;
|
||||
}
|
||||
|
||||
#endif /* DISABLE_OPENGL */
|
||||
|
||||
@@ -17,8 +17,11 @@
|
||||
#pragma once
|
||||
|
||||
#include <openrct2/common.h>
|
||||
#include <openrct2/drawing/drawing.h>
|
||||
#include "OpenGLAPI.h"
|
||||
|
||||
#include <vector>
|
||||
|
||||
struct SDL_Window;
|
||||
|
||||
class OpenGLFramebuffer
|
||||
@@ -39,5 +42,7 @@ public:
|
||||
GLuint GetTexture() const { return _texture; }
|
||||
|
||||
void Bind() const;
|
||||
void * GetPixels() const;
|
||||
void BindDraw() const;
|
||||
void BindRead() const;
|
||||
void GetPixels(rct_drawpixelinfo &dpi) const;
|
||||
};
|
||||
|
||||
@@ -20,49 +20,31 @@
|
||||
#include "OpenGLFramebuffer.h"
|
||||
#include "SwapFramebuffer.h"
|
||||
|
||||
SwapFramebuffer::SwapFramebuffer(sint32 width, sint32 height)
|
||||
{
|
||||
_width = width;
|
||||
_height = height;
|
||||
_targetFramebufferIndex = 0;
|
||||
_framebuffer[0] = new OpenGLFramebuffer(width, height);
|
||||
_framebuffer[1] = new OpenGLFramebuffer(width, height);
|
||||
_targetFramebuffer = _framebuffer[0];
|
||||
|
||||
_copyFramebufferShader = new CopyFramebufferShader();
|
||||
_copyFramebufferShader->Use();
|
||||
_copyFramebufferShader->SetScreenSize(_width, _height);
|
||||
_copyFramebufferShader->SetBounds(0, 0, _width, _height);
|
||||
_copyFramebufferShader->SetTextureCoordinates(0, 1, 1, 0);
|
||||
}
|
||||
|
||||
SwapFramebuffer::~SwapFramebuffer()
|
||||
{
|
||||
delete _framebuffer[0];
|
||||
delete _framebuffer[1];
|
||||
delete _copyFramebufferShader;
|
||||
}
|
||||
SwapFramebuffer::SwapFramebuffer(sint32 width, sint32 height) :
|
||||
_width(width), _height(height),
|
||||
_targetFramebuffer(width, height), _sourceFramebuffer(width, height)
|
||||
{ }
|
||||
|
||||
GLuint SwapFramebuffer::GetSourceTexture() const
|
||||
{
|
||||
return _sourceFramebuffer->GetTexture();
|
||||
return _sourceFramebuffer.GetTexture();
|
||||
}
|
||||
|
||||
void SwapFramebuffer::SwapCopy()
|
||||
{
|
||||
_sourceFramebuffer = _targetFramebuffer;
|
||||
_targetFramebufferIndex = (_targetFramebufferIndex + 1) & 1;
|
||||
_targetFramebuffer = _framebuffer[_targetFramebufferIndex];
|
||||
_targetFramebuffer->Bind();
|
||||
|
||||
_copyFramebufferShader->Use();
|
||||
_copyFramebufferShader->SetTexture(GetSourceTexture());
|
||||
_copyFramebufferShader->Draw();
|
||||
// no longer performs swap, TODO rename function
|
||||
// blit target's texture to source's texture
|
||||
_sourceFramebuffer.BindDraw();
|
||||
_targetFramebuffer.BindRead();
|
||||
glBlitFramebuffer(0, 0, _width, _height,
|
||||
0, 0, _width, _height,
|
||||
GL_COLOR_BUFFER_BIT, GL_NEAREST);
|
||||
_targetFramebuffer.Bind();
|
||||
}
|
||||
|
||||
void SwapFramebuffer::Bind()
|
||||
{
|
||||
_targetFramebuffer->Bind();
|
||||
_targetFramebuffer.Bind();
|
||||
}
|
||||
|
||||
#endif /* DISABLE_OPENGL */
|
||||
|
||||
@@ -33,23 +33,18 @@ class OpenGLFramebuffer;
|
||||
class SwapFramebuffer final
|
||||
{
|
||||
private:
|
||||
sint32 _width = 0;
|
||||
sint32 _height = 0;
|
||||
uint8 _targetFramebufferIndex = 0;
|
||||
OpenGLFramebuffer * _targetFramebuffer = nullptr;
|
||||
OpenGLFramebuffer * _sourceFramebuffer = nullptr;
|
||||
OpenGLFramebuffer * _framebuffer[2] = { 0 };
|
||||
|
||||
CopyFramebufferShader * _copyFramebufferShader = nullptr;
|
||||
const sint32 _width;
|
||||
const sint32 _height;
|
||||
OpenGLFramebuffer _targetFramebuffer;
|
||||
OpenGLFramebuffer _sourceFramebuffer;
|
||||
|
||||
public:
|
||||
SwapFramebuffer(sint32 width, sint32 height);
|
||||
~SwapFramebuffer();
|
||||
|
||||
/**
|
||||
* Gets the current target framebuffer.
|
||||
*/
|
||||
const OpenGLFramebuffer * GetTargetFramebuffer() const { return _targetFramebuffer; }
|
||||
const OpenGLFramebuffer * GetTargetFramebuffer() const { return &_targetFramebuffer; }
|
||||
|
||||
/**
|
||||
* Gets the texture ID for the source framebuffer.
|
||||
|
||||
@@ -41,7 +41,6 @@ void TextureCache::InvalidateImage(uint32 image)
|
||||
_atlases[kvp->second.index].Free(kvp->second);
|
||||
_imageTextureMap.erase(kvp);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
const CachedTextureInfo* TextureCache::GetOrLoadImageTexture(uint32 image)
|
||||
@@ -153,7 +152,10 @@ void TextureCache::EnlargeAtlasesTexture(GLuint newEntries)
|
||||
|
||||
// Retrieve current array data
|
||||
auto oldPixels = std::vector<char>(_atlasesTextureDimensions * _atlasesTextureDimensions * _atlasesTextureIndices);
|
||||
glGetTexImage(GL_TEXTURE_2D_ARRAY, 0, GL_RED_INTEGER, GL_UNSIGNED_BYTE, oldPixels.data());
|
||||
if (oldPixels.size() > 0)
|
||||
{
|
||||
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);
|
||||
|
||||
@@ -81,8 +81,6 @@ extern "C"
|
||||
auto uiContext = context->GetUiContext();
|
||||
auto drawingEngine = uiContext->CreateDrawingEngine((DRAWING_ENGINE_TYPE)_drawingEngineType);
|
||||
|
||||
_painter = new Painter(uiContext);
|
||||
|
||||
if (drawingEngine == nullptr)
|
||||
{
|
||||
if (_drawingEngineType == DRAWING_ENGINE_SOFTWARE)
|
||||
@@ -103,6 +101,7 @@ extern "C"
|
||||
}
|
||||
else
|
||||
{
|
||||
_painter = new Painter(uiContext);
|
||||
try
|
||||
{
|
||||
drawingEngine->Initialise();
|
||||
@@ -111,6 +110,8 @@ extern "C"
|
||||
}
|
||||
catch (const Exception &ex)
|
||||
{
|
||||
delete _painter;
|
||||
_painter = nullptr;
|
||||
delete drawingEngine;
|
||||
drawingEngine = nullptr;
|
||||
if (_drawingEngineType == DRAWING_ENGINE_SOFTWARE)
|
||||
@@ -156,7 +157,7 @@ extern "C"
|
||||
if (_drawingEngine != nullptr && _painter != nullptr)
|
||||
{
|
||||
_drawingEngine->BeginDraw();
|
||||
_painter->Paint(_drawingEngine);
|
||||
_painter->Paint(_drawingEngine);
|
||||
_drawingEngine->EndDraw();
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user