mirror of
https://github.com/OpenRCT2/OpenRCT2
synced 2025-12-10 09:32:29 +01:00
OpenGL: Add single-pass transparency
This commit is contained in:
committed by
Michał Janiszewski
parent
3d2d99817c
commit
d3d41ea724
@@ -263,6 +263,7 @@
|
||||
D45A395D1CF300AF00659A24 /* libSDL2_ttf.dylib in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = D45A38B71CF3006400659A24 /* libSDL2_ttf.dylib */; settings = {ATTRIBUTES = (CodeSignOnCopy, ); }; };
|
||||
D45A395E1CF300AF00659A24 /* libSDL2.dylib in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = D45A38B81CF3006400659A24 /* libSDL2.dylib */; settings = {ATTRIBUTES = (CodeSignOnCopy, ); }; };
|
||||
D45A395F1CF300AF00659A24 /* libspeexdsp.dylib in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = D45A38B91CF3006400659A24 /* libspeexdsp.dylib */; settings = {ATTRIBUTES = (CodeSignOnCopy, ); }; };
|
||||
D45E09171F99CF2F00854B2B /* ApplyTransparencyShader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = D45E09161F99CF2F00854B2B /* ApplyTransparencyShader.cpp */; };
|
||||
D47304D51C4FF8250015C0EA /* libz.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = D47304D41C4FF8250015C0EA /* libz.tbd */; };
|
||||
D48AFDB71EF78DBF0081C644 /* BenchGfxCommmands.cpp in Sources */ = {isa = PBXBuildFile; fileRef = D48AFDB61EF78DBF0081C644 /* BenchGfxCommmands.cpp */; };
|
||||
D4A8B4B41DB41873007A2F29 /* libpng16.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = D4A8B4B31DB41873007A2F29 /* libpng16.dylib */; };
|
||||
@@ -1034,6 +1035,8 @@
|
||||
D45A39561CF3007A00659A24 /* speex_resampler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = speex_resampler.h; sourceTree = "<group>"; };
|
||||
D45A39571CF3007A00659A24 /* speexdsp_config_types.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = speexdsp_config_types.h; sourceTree = "<group>"; };
|
||||
D45A39581CF3007A00659A24 /* speexdsp_types.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = speexdsp_types.h; sourceTree = "<group>"; };
|
||||
D45E09151F99CF2F00854B2B /* ApplyTransparencyShader.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ApplyTransparencyShader.h; sourceTree = "<group>"; };
|
||||
D45E09161F99CF2F00854B2B /* ApplyTransparencyShader.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = ApplyTransparencyShader.cpp; sourceTree = "<group>"; };
|
||||
D47304D41C4FF8250015C0EA /* libz.tbd */ = {isa = PBXFileReference; lastKnownFileType = "sourcecode.text-based-dylib-definition"; name = libz.tbd; path = usr/lib/libz.tbd; sourceTree = SDKROOT; };
|
||||
D4895D321C23EFDD000CD788 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = Info.plist; path = distribution/macos/Info.plist; sourceTree = SOURCE_ROOT; };
|
||||
D48AFDB61EF78DBF0081C644 /* BenchGfxCommmands.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = BenchGfxCommmands.cpp; sourceTree = "<group>"; };
|
||||
@@ -2663,6 +2666,8 @@
|
||||
F76C85901EC4E82600FA49E2 /* opengl */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
D45E09161F99CF2F00854B2B /* ApplyTransparencyShader.cpp */,
|
||||
D45E09151F99CF2F00854B2B /* ApplyTransparencyShader.h */,
|
||||
F76C85911EC4E82600FA49E2 /* CopyFramebufferShader.cpp */,
|
||||
F76C85921EC4E82600FA49E2 /* CopyFramebufferShader.h */,
|
||||
F76C85931EC4E82600FA49E2 /* DrawCommands.h */,
|
||||
@@ -3287,6 +3292,7 @@
|
||||
F76C88861EC5324E00FA49E2 /* OpenGLShaderProgram.cpp in Sources */,
|
||||
F76C88871EC5324E00FA49E2 /* SwapFramebuffer.cpp in Sources */,
|
||||
F76C88881EC5324E00FA49E2 /* TextureCache.cpp in Sources */,
|
||||
D45E09171F99CF2F00854B2B /* ApplyTransparencyShader.cpp in Sources */,
|
||||
4C93F1A61F8B748900A9330D /* DingySlide.cpp in Sources */,
|
||||
F76C88891EC5324E00FA49E2 /* SoftwareDrawingEngine.cpp in Sources */,
|
||||
4C93F1A91F8B748900A9330D /* SplashBoats.cpp in Sources */,
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
buildConfiguration = "Debug"
|
||||
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
||||
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
||||
language = ""
|
||||
shouldUseLaunchSchemeArgsEnv = "YES">
|
||||
<Testables>
|
||||
</Testables>
|
||||
@@ -45,6 +46,7 @@
|
||||
buildConfiguration = "Debug"
|
||||
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
||||
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
||||
language = ""
|
||||
launchStyle = "0"
|
||||
useCustomWorkingDirectory = "NO"
|
||||
ignoresPersistentStateOnLaunch = "NO"
|
||||
|
||||
26
data/shaders/applytransparency.frag
Normal file
26
data/shaders/applytransparency.frag
Normal file
@@ -0,0 +1,26 @@
|
||||
#version 150
|
||||
|
||||
uniform usampler2D uOpaqueTex;
|
||||
uniform sampler2D uOpaqueDepth;
|
||||
uniform usampler2D uTransparentTex;
|
||||
uniform sampler2D uTransparentDepth;
|
||||
uniform usampler2DRect uPaletteTex;
|
||||
|
||||
in vec2 fTextureCoordinate;
|
||||
|
||||
out uint oColour;
|
||||
|
||||
void main()
|
||||
{
|
||||
uint opaque = texture(uOpaqueTex, fTextureCoordinate).r;
|
||||
float opaqueDepth = texture(uOpaqueDepth, fTextureCoordinate).r;
|
||||
uint transparent = texture(uTransparentTex, fTextureCoordinate).r;
|
||||
float transparentDepth = texture(uTransparentDepth, fTextureCoordinate).r;
|
||||
|
||||
if (transparentDepth > opaqueDepth)
|
||||
{
|
||||
transparent = 0u;
|
||||
}
|
||||
|
||||
oColour = texture(uPaletteTex, vec2(opaque, transparent)).r;
|
||||
}
|
||||
12
data/shaders/applytransparency.vert
Normal file
12
data/shaders/applytransparency.vert
Normal file
@@ -0,0 +1,12 @@
|
||||
#version 150
|
||||
|
||||
in vec4 vPosition;
|
||||
in vec2 vTextureCoordinate;
|
||||
|
||||
out vec2 fTextureCoordinate;
|
||||
|
||||
void main()
|
||||
{
|
||||
fTextureCoordinate = vTextureCoordinate;
|
||||
gl_Position = vPosition;
|
||||
}
|
||||
@@ -22,7 +22,7 @@ void main()
|
||||
pos.x = (pos.x * (2.0 / uScreenSize.x)) - 1.0;
|
||||
pos.y = (pos.y * (2.0 / uScreenSize.y)) - 1.0;
|
||||
pos.y *= -1;
|
||||
float depth = 1.0 - vDepth * DEPTH_INCREMENT;
|
||||
float depth = 1.0 - (vDepth + 1) * DEPTH_INCREMENT;
|
||||
|
||||
fColour = vColour;
|
||||
|
||||
|
||||
@@ -40,7 +40,7 @@ void main()
|
||||
pos.x = (pos.x * (2.0 / uScreenSize.x)) - 1.0;
|
||||
pos.y = (pos.y * (2.0 / uScreenSize.y)) - 1.0;
|
||||
pos.y *= -1;
|
||||
float depth = 1.0 - vDepth * DEPTH_INCREMENT;
|
||||
float depth = 1.0 - (vDepth + 1) * DEPTH_INCREMENT;
|
||||
|
||||
fFlags = vFlags;
|
||||
fColour = vColour;
|
||||
|
||||
@@ -0,0 +1,93 @@
|
||||
#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 "ApplyTransparencyShader.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 },
|
||||
};
|
||||
|
||||
ApplyTransparencyShader::ApplyTransparencyShader() : OpenGLShaderProgram("applytransparency")
|
||||
{
|
||||
GetLocations();
|
||||
|
||||
glGenBuffers(1, &_vbo);
|
||||
glGenVertexArrays(1, &_vao);
|
||||
|
||||
glBindBuffer(GL_ARRAY_BUFFER, _vbo);
|
||||
glBufferData(GL_ARRAY_BUFFER, sizeof(VertexData), VertexData, GL_STATIC_DRAW);
|
||||
|
||||
glBindVertexArray(_vao);
|
||||
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();
|
||||
glUniform1i(uOpaqueTex, 0);
|
||||
glUniform1i(uOpaqueDepth, 1);
|
||||
glUniform1i(uTransparentTex, 2);
|
||||
glUniform1i(uTransparentDepth, 3);
|
||||
glUniform1i(uPaletteTex, 4);
|
||||
}
|
||||
|
||||
ApplyTransparencyShader::~ApplyTransparencyShader()
|
||||
{
|
||||
glDeleteBuffers(1, &_vbo);
|
||||
glDeleteVertexArrays(1, &_vao);
|
||||
}
|
||||
|
||||
void ApplyTransparencyShader::GetLocations()
|
||||
{
|
||||
uOpaqueTex = GetUniformLocation("uOpaqueTex");
|
||||
uOpaqueDepth = GetUniformLocation("uOpaqueDepth");
|
||||
uTransparentTex = GetUniformLocation("uTransparentTex");
|
||||
uTransparentDepth = GetUniformLocation("uTransparentDepth");
|
||||
uPaletteTex = GetUniformLocation("uPaletteTex");
|
||||
|
||||
vPosition = GetAttributeLocation("vPosition");
|
||||
vTextureCoordinate = GetAttributeLocation("vTextureCoordinate");
|
||||
}
|
||||
|
||||
void ApplyTransparencyShader::SetTextures(GLuint opaqueTex, GLuint opaqueDepth, GLuint transparentTex, GLuint transparentDepth, GLuint paletteTex)
|
||||
{
|
||||
OpenGLAPI::SetTexture(0, GL_TEXTURE_2D, opaqueTex);
|
||||
OpenGLAPI::SetTexture(1, GL_TEXTURE_2D, opaqueDepth);
|
||||
OpenGLAPI::SetTexture(2, GL_TEXTURE_2D, transparentTex);
|
||||
OpenGLAPI::SetTexture(3, GL_TEXTURE_2D, transparentDepth);
|
||||
OpenGLAPI::SetTexture(4, GL_TEXTURE_RECTANGLE, paletteTex);
|
||||
}
|
||||
|
||||
void ApplyTransparencyShader::Draw()
|
||||
{
|
||||
glBindVertexArray(_vao);
|
||||
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
|
||||
}
|
||||
|
||||
#endif /* DISABLE_OPENGL */
|
||||
@@ -0,0 +1,46 @@
|
||||
#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 ApplyTransparencyShader final : public OpenGLShaderProgram
|
||||
{
|
||||
private:
|
||||
GLuint uOpaqueTex;
|
||||
GLuint uOpaqueDepth;
|
||||
GLuint uTransparentTex;
|
||||
GLuint uTransparentDepth;
|
||||
GLuint uPaletteTex;
|
||||
|
||||
GLuint vPosition;
|
||||
GLuint vTextureCoordinate;
|
||||
|
||||
GLuint _vbo;
|
||||
GLuint _vao;
|
||||
|
||||
public:
|
||||
ApplyTransparencyShader();
|
||||
~ApplyTransparencyShader() override;
|
||||
|
||||
void SetTextures(GLuint opaqueTex, GLuint opaqueDepth, GLuint transparentTex, GLuint transparentDepth, GLuint paletteTex);
|
||||
void Draw();
|
||||
|
||||
private:
|
||||
void GetLocations();
|
||||
};
|
||||
@@ -38,7 +38,7 @@ public:
|
||||
{
|
||||
return _numInstances == 0;
|
||||
}
|
||||
void reset()
|
||||
void clear()
|
||||
{
|
||||
_numInstances = 0;
|
||||
}
|
||||
@@ -56,7 +56,7 @@ public:
|
||||
}
|
||||
const T* data() const
|
||||
{
|
||||
return &_instances.at(0);
|
||||
return _instances.data();
|
||||
}
|
||||
const T& operator[](size_t idx) const
|
||||
{
|
||||
|
||||
@@ -49,8 +49,10 @@ OPENGL_PROC(PFNGLBINDBUFFERPROC, glBindBuffer)
|
||||
OPENGL_PROC(PFNGLBINDFRAGDATALOCATIONPROC, glBindFragDataLocation)
|
||||
OPENGL_PROC(PFNGLBINDFRAMEBUFFERPROC, glBindFramebuffer)
|
||||
OPENGL_PROC(PFNGLBINDVERTEXARRAYPROC, glBindVertexArray)
|
||||
OPENGL_PROC(PFNGLBLITFRAMEBUFFERPROC, glBlitFramebuffer);
|
||||
OPENGL_PROC(PFNGLBLITFRAMEBUFFERPROC, glBlitFramebuffer)
|
||||
OPENGL_PROC(PFNGLBUFFERDATAPROC, glBufferData)
|
||||
OPENGL_PROC(PFNGLCLEARBUFFERFVPROC, glClearBufferfv)
|
||||
OPENGL_PROC(PFNGLCLEARBUFFERUIVPROC, glClearBufferuiv)
|
||||
OPENGL_PROC(PFNGLCOMPILESHADERPROC, glCompileShader)
|
||||
OPENGL_PROC(PFNGLCREATEPROGRAMPROC, glCreateProgram)
|
||||
OPENGL_PROC(PFNGLCREATESHADERPROC, glCreateShader)
|
||||
|
||||
@@ -67,8 +67,10 @@ private:
|
||||
OpenGLDrawingEngine * _engine = nullptr;
|
||||
rct_drawpixelinfo * _dpi = nullptr;
|
||||
|
||||
DrawLineShader * _drawLineShader = nullptr;
|
||||
DrawRectShader * _drawRectShader = nullptr;
|
||||
ApplyTransparencyShader * _applyTransparencyShader = nullptr;
|
||||
DrawLineShader * _drawLineShader = nullptr;
|
||||
DrawRectShader * _drawRectShader = nullptr;
|
||||
SwapFramebuffer * _swapFramebuffer = nullptr;
|
||||
|
||||
TextureCache * _textureCache = nullptr;
|
||||
|
||||
@@ -85,7 +87,9 @@ private:
|
||||
{
|
||||
LineCommandBatch lines;
|
||||
RectCommandBatch rects;
|
||||
} _commandBuffers;
|
||||
RectCommandBatch transparent;
|
||||
}
|
||||
_commandBuffers;
|
||||
|
||||
public:
|
||||
explicit OpenGLDrawingContext(OpenGLDrawingEngine * engine);
|
||||
@@ -93,11 +97,13 @@ public:
|
||||
|
||||
IDrawingEngine * GetEngine() override;
|
||||
TextureCache * GetTextureCache() const { return _textureCache; }
|
||||
SwapFramebuffer * GetSwapFramebuffer() const { return _swapFramebuffer; }
|
||||
const OpenGLFramebuffer & GetFinalFramebuffer() const { return _swapFramebuffer->GetFinalFramebuffer(); }
|
||||
|
||||
void Initialise();
|
||||
void Resize(sint32 width, sint32 height);
|
||||
void ResetPalette();
|
||||
void ResetDrawCount() { _drawCount = 0; }
|
||||
void StartNewDraw();
|
||||
|
||||
void Clear(uint8 paletteIndex) override;
|
||||
void FillRect(uint32 colour, sint32 x, sint32 y, sint32 w, sint32 h) override;
|
||||
@@ -110,8 +116,8 @@ public:
|
||||
|
||||
void FlushCommandBuffers();
|
||||
|
||||
void FlushLines();
|
||||
void FlushRectangles();
|
||||
void FlushLines(LineCommandBatch &batch);
|
||||
void FlushRectangles(RectCommandBatch &batch);
|
||||
|
||||
void SetDPI(rct_drawpixelinfo * dpi);
|
||||
};
|
||||
@@ -135,7 +141,6 @@ private:
|
||||
|
||||
CopyFramebufferShader * _copyFramebufferShader = nullptr;
|
||||
OpenGLFramebuffer * _screenFramebuffer = nullptr;
|
||||
SwapFramebuffer * _swapFramebuffer = nullptr;
|
||||
|
||||
public:
|
||||
SDL_Color Palette[256];
|
||||
@@ -155,7 +160,6 @@ public:
|
||||
{
|
||||
delete _copyFramebufferShader;
|
||||
delete _screenFramebuffer;
|
||||
delete _swapFramebuffer;
|
||||
|
||||
delete _drawingContext;
|
||||
delete [] _bits;
|
||||
@@ -230,11 +234,8 @@ public:
|
||||
void BeginDraw() override
|
||||
{
|
||||
assert(_screenFramebuffer != nullptr);
|
||||
assert(_swapFramebuffer != nullptr);
|
||||
|
||||
_drawingContext->ResetDrawCount();
|
||||
_swapFramebuffer->Bind();
|
||||
glClear(GL_DEPTH_BUFFER_BIT);
|
||||
_drawingContext->StartNewDraw();
|
||||
}
|
||||
|
||||
void EndDraw() override
|
||||
@@ -245,7 +246,7 @@ public:
|
||||
glDisable(GL_DEPTH_TEST);
|
||||
_screenFramebuffer->Bind();
|
||||
_copyFramebufferShader->Use();
|
||||
_copyFramebufferShader->SetTexture(_swapFramebuffer->GetTargetFramebuffer()->GetTexture());
|
||||
_copyFramebufferShader->SetTexture(_drawingContext->GetFinalFramebuffer().GetTexture());
|
||||
_copyFramebufferShader->Draw();
|
||||
|
||||
CheckGLError();
|
||||
@@ -268,9 +269,9 @@ public:
|
||||
|
||||
sint32 Screenshot() override
|
||||
{
|
||||
const OpenGLFramebuffer * framebuffer = _swapFramebuffer->GetTargetFramebuffer();
|
||||
framebuffer->Bind();
|
||||
framebuffer->GetPixels(_bitsDPI);
|
||||
const OpenGLFramebuffer & framebuffer = _drawingContext->GetFinalFramebuffer();
|
||||
framebuffer.Bind();
|
||||
framebuffer.GetPixels(_bitsDPI);
|
||||
sint32 result = screenshot_dump_png(&_bitsDPI);
|
||||
return result;
|
||||
}
|
||||
@@ -307,12 +308,6 @@ public:
|
||||
return &_bitsDPI;
|
||||
}
|
||||
|
||||
GLuint SwapCopyReturningSourceTexture()
|
||||
{
|
||||
_swapFramebuffer->SwapCopy();
|
||||
return _swapFramebuffer->GetSourceTexture();
|
||||
}
|
||||
|
||||
private:
|
||||
static OpenGLVersion GetOpenGLVersion()
|
||||
{
|
||||
@@ -381,11 +376,6 @@ private:
|
||||
delete _screenFramebuffer;
|
||||
_screenFramebuffer = new OpenGLFramebuffer(_window);
|
||||
|
||||
// Re-create canvas framebuffer
|
||||
delete _swapFramebuffer;
|
||||
_swapFramebuffer = new SwapFramebuffer(_width, _height);
|
||||
|
||||
_copyFramebufferShader->Use();
|
||||
}
|
||||
|
||||
void Display()
|
||||
@@ -406,8 +396,10 @@ OpenGLDrawingContext::OpenGLDrawingContext(OpenGLDrawingEngine * engine)
|
||||
|
||||
OpenGLDrawingContext::~OpenGLDrawingContext()
|
||||
{
|
||||
delete _applyTransparencyShader;
|
||||
delete _drawLineShader;
|
||||
delete _drawRectShader;
|
||||
delete _swapFramebuffer;
|
||||
|
||||
delete _textureCache;
|
||||
}
|
||||
@@ -420,18 +412,24 @@ IDrawingEngine * OpenGLDrawingContext::GetEngine()
|
||||
void OpenGLDrawingContext::Initialise()
|
||||
{
|
||||
_textureCache = new TextureCache();
|
||||
_applyTransparencyShader = new ApplyTransparencyShader();
|
||||
_drawRectShader = new DrawRectShader();
|
||||
_drawLineShader = new DrawLineShader();
|
||||
}
|
||||
|
||||
void OpenGLDrawingContext::Resize(sint32 width, sint32 height)
|
||||
{
|
||||
FlushCommandBuffers();
|
||||
_commandBuffers.lines.clear();
|
||||
_commandBuffers.rects.clear();
|
||||
|
||||
_drawRectShader->Use();
|
||||
_drawRectShader->SetScreenSize(width, height);
|
||||
_drawLineShader->Use();
|
||||
_drawLineShader->SetScreenSize(width, height);
|
||||
|
||||
// Re-create canvas framebuffer
|
||||
delete _swapFramebuffer;
|
||||
_swapFramebuffer = new SwapFramebuffer(width, height);
|
||||
}
|
||||
|
||||
void OpenGLDrawingContext::ResetPalette()
|
||||
@@ -439,6 +437,12 @@ void OpenGLDrawingContext::ResetPalette()
|
||||
//FlushCommandBuffers();
|
||||
}
|
||||
|
||||
void OpenGLDrawingContext::StartNewDraw()
|
||||
{
|
||||
_drawCount = 0;
|
||||
_swapFramebuffer->Clear();
|
||||
}
|
||||
|
||||
void OpenGLDrawingContext::Clear(uint8 paletteIndex)
|
||||
{
|
||||
FillRect(paletteIndex, _clipLeft - _offsetX, _clipTop - _offsetY, _clipRight - _offsetX, _clipBottom - _offsetY);
|
||||
@@ -478,44 +482,23 @@ void OpenGLDrawingContext::FillRect(uint32 colour, sint32 left, sint32 top, sint
|
||||
|
||||
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();
|
||||
|
||||
left += _offsetX;
|
||||
top += _offsetY;
|
||||
right += _offsetX;
|
||||
bottom += _offsetY;
|
||||
|
||||
DrawRectCommand& command = _commandBuffers.rectangles.allocate();
|
||||
|
||||
// START FILTER
|
||||
|
||||
GLuint srcTexture = _engine->SwapCopyReturningSourceTexture();
|
||||
command.flags = 0;
|
||||
command.sourceFramebuffer = srcTexture;
|
||||
|
||||
uint16 g1Index = palette_to_g1_offset[palette];
|
||||
rct_g1_element * g1Element = &g1Elements[g1Index];
|
||||
uint8 * g1Bits = g1Element->offset;
|
||||
|
||||
for (size_t i = 0; i < 256; i++)
|
||||
{
|
||||
command.paletteRemap[i] = g1Bits[i];
|
||||
}
|
||||
|
||||
// END FILTER
|
||||
DrawRectCommand& command = _commandBuffers.transparent.allocate();
|
||||
|
||||
command.clip = { _clipLeft, _clipTop, _clipRight, _clipBottom };
|
||||
|
||||
command.bounds[0] = left;
|
||||
command.bounds[1] = top;
|
||||
command.bounds[2] = right + 1;
|
||||
command.bounds[3] = bottom + 1;
|
||||
*/
|
||||
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 = TextureCache::PaletteToY(palette);
|
||||
command.bounds = { left, top, right + 1, bottom + 1 };
|
||||
command.flags = DrawRectCommand::FLAG_NO_TEXTURE;
|
||||
command.depth = _drawCount++;
|
||||
}
|
||||
|
||||
void OpenGLDrawingContext::DrawLine(uint32 colour, sint32 x1, sint32 y1, sint32 x2, sint32 y2)
|
||||
@@ -627,11 +610,12 @@ void OpenGLDrawingContext::DrawSprite(uint32 image, sint32 x, sint32 y, uint32 t
|
||||
palettes.z = TextureCache::PaletteToY(tertiaryColour & 0xFF);
|
||||
}
|
||||
}
|
||||
else if (image & IMAGE_TYPE_REMAP)
|
||||
else if ((image & IMAGE_TYPE_REMAP) || (image & IMAGE_TYPE_TRANSPARENT))
|
||||
{
|
||||
paletteCount = 1;
|
||||
palettes.x = TextureCache::PaletteToY((image >> 19) & 0xFF);
|
||||
if (palettes.x == 32)
|
||||
uint32 palette = (image >> 19) & 0xFF;
|
||||
palettes.x = TextureCache::PaletteToY(palette);
|
||||
if (palette == PALETTE_WATER)
|
||||
{
|
||||
special = true;
|
||||
}
|
||||
@@ -643,22 +627,34 @@ void OpenGLDrawingContext::DrawSprite(uint32 image, sint32 x, sint32 y, uint32 t
|
||||
|
||||
if (special || (image & IMAGE_TYPE_TRANSPARENT))
|
||||
{
|
||||
// ignore transparecy TODO
|
||||
return;
|
||||
DrawRectCommand& command = _commandBuffers.transparent.allocate();
|
||||
|
||||
command.clip = { _clipLeft, _clipTop, _clipRight, _clipBottom };
|
||||
command.texColourAtlas = texture->index;
|
||||
command.texColourBounds = texture->normalizedBounds;
|
||||
command.texMaskAtlas = texture->index;
|
||||
command.texMaskBounds = texture->normalizedBounds;
|
||||
command.palettes = palettes;
|
||||
command.colour = palettes.x - (special ? 1 : 0);
|
||||
command.bounds = { left, top, right, bottom };
|
||||
command.flags = special ? 0 : DrawRectCommand::FLAG_NO_TEXTURE | DrawRectCommand::FLAG_MASK;
|
||||
command.depth = _drawCount++;
|
||||
}
|
||||
else
|
||||
{
|
||||
DrawRectCommand& command = _commandBuffers.rects.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, 0.0f };
|
||||
command.palettes = palettes;
|
||||
command.colour = 0;
|
||||
command.bounds = { left, top, right, bottom };
|
||||
command.flags = paletteCount;
|
||||
command.depth = _drawCount++;
|
||||
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, 0.0f };
|
||||
command.palettes = palettes;
|
||||
command.colour = 0;
|
||||
command.bounds = { left, top, right, bottom };
|
||||
command.flags = paletteCount;
|
||||
command.depth = _drawCount++;
|
||||
}
|
||||
}
|
||||
|
||||
void OpenGLDrawingContext::DrawSpriteRawMasked(sint32 x, sint32 y, uint32 maskImage, uint32 colourImage)
|
||||
@@ -814,31 +810,35 @@ void OpenGLDrawingContext::DrawGlyph(uint32 image, sint32 x, sint32 y, uint8 * p
|
||||
void OpenGLDrawingContext::FlushCommandBuffers()
|
||||
{
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
FlushLines();
|
||||
FlushRectangles();
|
||||
_swapFramebuffer->BindOpaque();
|
||||
FlushLines(_commandBuffers.lines);
|
||||
FlushRectangles(_commandBuffers.rects);
|
||||
_swapFramebuffer->BindTransparent();
|
||||
FlushRectangles(_commandBuffers.transparent);
|
||||
_swapFramebuffer->ApplyTransparency(*_applyTransparencyShader, _textureCache->GetPaletteTexture());
|
||||
}
|
||||
|
||||
void OpenGLDrawingContext::FlushLines()
|
||||
void OpenGLDrawingContext::FlushLines(LineCommandBatch &batch)
|
||||
{
|
||||
if (_commandBuffers.lines.size() == 0) return;
|
||||
if (batch.size() == 0) return;
|
||||
|
||||
_drawLineShader->Use();
|
||||
_drawLineShader->DrawInstances(_commandBuffers.lines);
|
||||
_drawLineShader->DrawInstances(batch);
|
||||
|
||||
_commandBuffers.lines.reset();
|
||||
batch.clear();
|
||||
}
|
||||
|
||||
void OpenGLDrawingContext::FlushRectangles()
|
||||
void OpenGLDrawingContext::FlushRectangles(RectCommandBatch &batch)
|
||||
{
|
||||
if (_commandBuffers.rects.size() == 0) return;
|
||||
if (batch.size() == 0) return;
|
||||
|
||||
OpenGLAPI::SetTexture(0, GL_TEXTURE_2D_ARRAY, _textureCache->GetAtlasesTexture());
|
||||
OpenGLAPI::SetTexture(1, GL_TEXTURE_RECTANGLE, _textureCache->GetPaletteTexture());
|
||||
|
||||
_drawRectShader->Use();
|
||||
_drawRectShader->DrawInstances(_commandBuffers.rects);
|
||||
_drawRectShader->DrawInstances(batch);
|
||||
|
||||
_commandBuffers.rects.reset();
|
||||
batch.clear();
|
||||
}
|
||||
|
||||
void OpenGLDrawingContext::SetDPI(rct_drawpixelinfo * dpi)
|
||||
|
||||
@@ -31,7 +31,7 @@ OpenGLFramebuffer::OpenGLFramebuffer(SDL_Window * window)
|
||||
SDL_GetWindowSize(window, &_width, &_height);
|
||||
}
|
||||
|
||||
OpenGLFramebuffer::OpenGLFramebuffer(sint32 width, sint32 height)
|
||||
OpenGLFramebuffer::OpenGLFramebuffer(sint32 width, sint32 height, bool depth)
|
||||
{
|
||||
_width = width;
|
||||
_height = height;
|
||||
@@ -42,12 +42,19 @@ OpenGLFramebuffer::OpenGLFramebuffer(sint32 width, sint32 height)
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||
|
||||
glGenTextures(1, &_depth);
|
||||
glBindTexture(GL_TEXTURE_2D, _depth);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT24, width, height, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, nullptr);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_NONE);
|
||||
if (depth)
|
||||
{
|
||||
glGenTextures(1, &_depth);
|
||||
glBindTexture(GL_TEXTURE_2D, _depth);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT24, width, height, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, nullptr);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_NONE);
|
||||
}
|
||||
else
|
||||
{
|
||||
_depth = 0;
|
||||
}
|
||||
|
||||
glGenFramebuffers(1, &_id);
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, _id);
|
||||
|
||||
@@ -35,12 +35,13 @@ private:
|
||||
|
||||
public:
|
||||
explicit OpenGLFramebuffer(SDL_Window * window);
|
||||
OpenGLFramebuffer(sint32 width, sint32 height);
|
||||
OpenGLFramebuffer(sint32 width, sint32 height, bool depth = true);
|
||||
~OpenGLFramebuffer();
|
||||
|
||||
GLuint GetWidth() const { return _width; }
|
||||
GLuint GetHeight() const { return _height; }
|
||||
GLuint GetTexture() const { return _texture; }
|
||||
GLuint GetDepthTexture() const { return _depth; }
|
||||
|
||||
void Bind() const;
|
||||
void BindDraw() const;
|
||||
|
||||
@@ -21,30 +21,49 @@
|
||||
#include "SwapFramebuffer.h"
|
||||
|
||||
SwapFramebuffer::SwapFramebuffer(sint32 width, sint32 height) :
|
||||
_width(width), _height(height),
|
||||
_targetFramebuffer(width, height), _sourceFramebuffer(width, height)
|
||||
_opaqueFramebuffer(width, height), _transparentFramebuffer(width, height),
|
||||
_finalFramebuffer(width, height, false)
|
||||
{ }
|
||||
|
||||
GLuint SwapFramebuffer::GetSourceTexture() const
|
||||
void SwapFramebuffer::BindOpaque()
|
||||
{
|
||||
return _sourceFramebuffer.GetTexture();
|
||||
_opaqueFramebuffer.Bind();
|
||||
}
|
||||
|
||||
void SwapFramebuffer::SwapCopy()
|
||||
void SwapFramebuffer::BindTransparent()
|
||||
{
|
||||
// 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();
|
||||
_transparentFramebuffer.Bind();
|
||||
}
|
||||
|
||||
void SwapFramebuffer::Bind()
|
||||
void SwapFramebuffer::ApplyTransparency(ApplyTransparencyShader &shader, GLuint paletteTex)
|
||||
{
|
||||
_targetFramebuffer.Bind();
|
||||
_finalFramebuffer.Bind();
|
||||
glDisable(GL_DEPTH_TEST);
|
||||
shader.Use();
|
||||
shader.SetTextures(
|
||||
_opaqueFramebuffer.GetTexture(),
|
||||
_opaqueFramebuffer.GetDepthTexture(),
|
||||
_transparentFramebuffer.GetTexture(),
|
||||
_transparentFramebuffer.GetDepthTexture(),
|
||||
paletteTex
|
||||
);
|
||||
shader.Draw();
|
||||
|
||||
//Change binding to guaruntee no undefined behavior
|
||||
_opaqueFramebuffer.Bind();
|
||||
}
|
||||
|
||||
void SwapFramebuffer::Clear()
|
||||
{
|
||||
static const GLfloat depthValue[1] = { 1.0f };
|
||||
static const GLuint indexValue[4] = { 0, 0, 0, 0 };
|
||||
|
||||
_opaqueFramebuffer.Bind();
|
||||
glClearBufferfv(GL_DEPTH, 0, depthValue);
|
||||
|
||||
_transparentFramebuffer.Bind();
|
||||
glClearBufferuiv(GL_COLOR, 0, indexValue);
|
||||
glClearBufferfv(GL_DEPTH, 0, depthValue);
|
||||
}
|
||||
|
||||
#endif /* DISABLE_OPENGL */
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
|
||||
#include <openrct2/common.h>
|
||||
#include "OpenGLAPI.h"
|
||||
#include "ApplyTransparencyShader.h"
|
||||
|
||||
class CopyFramebufferShader;
|
||||
class OpenGLFramebuffer;
|
||||
@@ -33,33 +34,20 @@ class OpenGLFramebuffer;
|
||||
class SwapFramebuffer final
|
||||
{
|
||||
private:
|
||||
const sint32 _width;
|
||||
const sint32 _height;
|
||||
OpenGLFramebuffer _targetFramebuffer;
|
||||
OpenGLFramebuffer _sourceFramebuffer;
|
||||
OpenGLFramebuffer _opaqueFramebuffer;
|
||||
OpenGLFramebuffer _transparentFramebuffer;
|
||||
OpenGLFramebuffer _finalFramebuffer;
|
||||
|
||||
public:
|
||||
SwapFramebuffer(sint32 width, sint32 height);
|
||||
|
||||
/**
|
||||
* Gets the current target framebuffer.
|
||||
*/
|
||||
const OpenGLFramebuffer * GetTargetFramebuffer() const { return &_targetFramebuffer; }
|
||||
const OpenGLFramebuffer &GetOpaqueFramebuffer() const { return _opaqueFramebuffer; }
|
||||
const OpenGLFramebuffer &GetTransparentFramebuffer() const { return _transparentFramebuffer; }
|
||||
const OpenGLFramebuffer &GetFinalFramebuffer() const { return _finalFramebuffer; }
|
||||
GLuint GetFinalTexture() const { return _finalFramebuffer.GetTexture(); }
|
||||
|
||||
/**
|
||||
* Gets the texture ID for the source framebuffer.
|
||||
*/
|
||||
GLuint GetSourceTexture() const;
|
||||
|
||||
/**
|
||||
* Swaps the target framebuffer, binds it and then draws the previous
|
||||
* framebuffer resulting in the two buffers matching and ready for
|
||||
* pre-processing.
|
||||
*/
|
||||
void SwapCopy();
|
||||
|
||||
/**
|
||||
* Binds the current target framebuffer.
|
||||
*/
|
||||
void Bind();
|
||||
void BindOpaque();
|
||||
void BindTransparent();
|
||||
void ApplyTransparency(ApplyTransparencyShader &shader, GLuint paletteTex);
|
||||
void Clear();
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user