This commit is contained in:
Rachael Alexanderson 2017-05-27 04:31:53 -04:00
commit 872db304f0
3 changed files with 117 additions and 121 deletions

View file

@ -272,7 +272,7 @@ void *OpenGLSWFrameBuffer::MapBuffer(int target, int size)
OpenGLSWFrameBuffer::HWFrameBuffer::~HWFrameBuffer() OpenGLSWFrameBuffer::HWFrameBuffer::~HWFrameBuffer()
{ {
if (Framebuffer != 0) glDeleteFramebuffers(1, (GLuint*)&Framebuffer); if (Framebuffer != 0) glDeleteFramebuffers(1, (GLuint*)&Framebuffer);
delete Texture; Texture.reset();
} }
OpenGLSWFrameBuffer::HWTexture::~HWTexture() OpenGLSWFrameBuffer::HWTexture::~HWTexture()
@ -324,17 +324,17 @@ OpenGLSWFrameBuffer::HWPixelShader::~HWPixelShader()
if (FragmentShader != 0) glDeleteShader(FragmentShader); if (FragmentShader != 0) glDeleteShader(FragmentShader);
} }
bool OpenGLSWFrameBuffer::CreateFrameBuffer(const FString &name, int width, int height, HWFrameBuffer **outFramebuffer) std::unique_ptr<OpenGLSWFrameBuffer::HWFrameBuffer> OpenGLSWFrameBuffer::CreateFrameBuffer(const FString &name, int width, int height)
{ {
std::unique_ptr<HWFrameBuffer> fb(new HWFrameBuffer()); std::unique_ptr<HWFrameBuffer> fb(new HWFrameBuffer());
GLint format = GL_RGBA16F; GLint format = GL_RGBA16F;
if (gl.es) format = GL_RGB; if (gl.es) format = GL_RGB;
if (!CreateTexture(name, width, height, 1, format, &fb->Texture)) fb->Texture = CreateTexture(name, width, height, 1, format);
if (!fb->Texture)
{ {
outFramebuffer = nullptr; return nullptr;
return false;
} }
glGenFramebuffers(1, (GLuint*)&fb->Framebuffer); glGenFramebuffers(1, (GLuint*)&fb->Framebuffer);
@ -357,24 +357,22 @@ bool OpenGLSWFrameBuffer::CreateFrameBuffer(const FString &name, int width, int
if (result != GL_FRAMEBUFFER_COMPLETE) if (result != GL_FRAMEBUFFER_COMPLETE)
{ {
Printf("Framebuffer is not complete\n"); Printf("Framebuffer is not complete\n");
outFramebuffer = nullptr; return nullptr;
return false;
} }
*outFramebuffer = fb.release(); return fb;
return true;
} }
bool OpenGLSWFrameBuffer::CreatePixelShader(FString vertexsrc, FString fragmentsrc, const FString &defines, HWPixelShader **outShader) std::unique_ptr<OpenGLSWFrameBuffer::HWPixelShader> OpenGLSWFrameBuffer::CreatePixelShader(FString vertexsrc, FString fragmentsrc, const FString &defines)
{ {
std::unique_ptr<HWPixelShader> shader(new HWPixelShader()); std::unique_ptr<HWPixelShader> shader(new HWPixelShader());
shader->Program = glCreateProgram(); shader->Program = glCreateProgram();
if (shader->Program == 0) { Printf("glCreateProgram failed. Disabling OpenGL hardware acceleration.\n"); return false; } if (shader->Program == 0) { Printf("glCreateProgram failed. Disabling OpenGL hardware acceleration.\n"); return nullptr; }
shader->VertexShader = glCreateShader(GL_VERTEX_SHADER); shader->VertexShader = glCreateShader(GL_VERTEX_SHADER);
if (shader->VertexShader == 0) { Printf("glCreateShader(GL_VERTEX_SHADER) failed. Disabling OpenGL hardware acceleration.\n"); return false; } if (shader->VertexShader == 0) { Printf("glCreateShader(GL_VERTEX_SHADER) failed. Disabling OpenGL hardware acceleration.\n"); return nullptr; }
shader->FragmentShader = glCreateShader(GL_FRAGMENT_SHADER); shader->FragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
if (shader->FragmentShader == 0) { Printf("glCreateShader(GL_FRAGMENT_SHADER) failed. Disabling OpenGL hardware acceleration.\n"); return false; } if (shader->FragmentShader == 0) { Printf("glCreateShader(GL_FRAGMENT_SHADER) failed. Disabling OpenGL hardware acceleration.\n"); return nullptr; }
int maxGlslVersion = 330; int maxGlslVersion = 330;
int shaderVersion = MIN((int)round(gl.glslversion * 10) * 10, maxGlslVersion); int shaderVersion = MIN((int)round(gl.glslversion * 10) * 10, maxGlslVersion);
@ -412,8 +410,7 @@ bool OpenGLSWFrameBuffer::CreatePixelShader(FString vertexsrc, FString fragments
glGetShaderInfoLog(errorShader, 10000, &length, buffer); glGetShaderInfoLog(errorShader, 10000, &length, buffer);
//Printf("Shader compile failed: %s", buffer); //Printf("Shader compile failed: %s", buffer);
*outShader = nullptr; return nullptr;
return false;
} }
glAttachShader(shader->Program, shader->VertexShader); glAttachShader(shader->Program, shader->VertexShader);
@ -433,8 +430,7 @@ bool OpenGLSWFrameBuffer::CreatePixelShader(FString vertexsrc, FString fragments
glGetProgramInfoLog(shader->Program, 10000, &length, buffer); glGetProgramInfoLog(shader->Program, 10000, &length, buffer);
//Printf("Shader link failed: %s", buffer); //Printf("Shader link failed: %s", buffer);
*outShader = nullptr; return nullptr;
return false;
} }
shader->ConstantLocations[PSCONST_Desaturation] = glGetUniformLocation(shader->Program, "Desaturation"); shader->ConstantLocations[PSCONST_Desaturation] = glGetUniformLocation(shader->Program, "Desaturation");
@ -447,11 +443,10 @@ bool OpenGLSWFrameBuffer::CreatePixelShader(FString vertexsrc, FString fragments
shader->NewScreenLocation = glGetUniformLocation(shader->Program, "NewScreen"); shader->NewScreenLocation = glGetUniformLocation(shader->Program, "NewScreen");
shader->BurnLocation = glGetUniformLocation(shader->Program, "Burn"); shader->BurnLocation = glGetUniformLocation(shader->Program, "Burn");
*outShader = shader.release(); return shader;
return true;
} }
bool OpenGLSWFrameBuffer::CreateVertexBuffer(int size, HWVertexBuffer **outVertexBuffer) std::unique_ptr<OpenGLSWFrameBuffer::HWVertexBuffer> OpenGLSWFrameBuffer::CreateVertexBuffer(int size)
{ {
std::unique_ptr<HWVertexBuffer> obj(new HWVertexBuffer()); std::unique_ptr<HWVertexBuffer> obj(new HWVertexBuffer());
@ -478,11 +473,10 @@ bool OpenGLSWFrameBuffer::CreateVertexBuffer(int size, HWVertexBuffer **outVerte
glBindBuffer(GL_ARRAY_BUFFER, 0); glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindVertexArray(oldBinding); glBindVertexArray(oldBinding);
*outVertexBuffer = obj.release(); return obj;
return true;
} }
bool OpenGLSWFrameBuffer::CreateIndexBuffer(int size, HWIndexBuffer **outIndexBuffer) std::unique_ptr<OpenGLSWFrameBuffer::HWIndexBuffer> OpenGLSWFrameBuffer::CreateIndexBuffer(int size)
{ {
std::unique_ptr<HWIndexBuffer> obj(new HWIndexBuffer()); std::unique_ptr<HWIndexBuffer> obj(new HWIndexBuffer());
@ -498,11 +492,10 @@ bool OpenGLSWFrameBuffer::CreateIndexBuffer(int size, HWIndexBuffer **outIndexBu
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, oldBinding); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, oldBinding);
*outIndexBuffer = obj.release(); return obj;
return true;
} }
bool OpenGLSWFrameBuffer::CreateTexture(const FString &name, int width, int height, int levels, int format, HWTexture **outTexture) std::unique_ptr<OpenGLSWFrameBuffer::HWTexture> OpenGLSWFrameBuffer::CreateTexture(const FString &name, int width, int height, int levels, int format)
{ {
std::unique_ptr<HWTexture> obj(new HWTexture()); std::unique_ptr<HWTexture> obj(new HWTexture());
@ -526,7 +519,7 @@ bool OpenGLSWFrameBuffer::CreateTexture(const FString &name, int width, int heig
case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT: srcformat = GL_RGBA; break; case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT: srcformat = GL_RGBA; break;
default: default:
I_FatalError("Unknown format passed to CreateTexture"); I_FatalError("Unknown format passed to CreateTexture");
return false; return nullptr;
} }
glTexImage2D(GL_TEXTURE_2D, 0, format, width, height, 0, srcformat, GL_UNSIGNED_BYTE, nullptr); glTexImage2D(GL_TEXTURE_2D, 0, format, width, height, 0, srcformat, GL_UNSIGNED_BYTE, nullptr);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
@ -536,11 +529,10 @@ bool OpenGLSWFrameBuffer::CreateTexture(const FString &name, int width, int heig
glBindTexture(GL_TEXTURE_2D, oldBinding); glBindTexture(GL_TEXTURE_2D, oldBinding);
*outTexture = obj.release(); return obj;
return true;
} }
OpenGLSWFrameBuffer::HWTexture *OpenGLSWFrameBuffer::CopyCurrentScreen() std::unique_ptr<OpenGLSWFrameBuffer::HWTexture> OpenGLSWFrameBuffer::CopyCurrentScreen()
{ {
std::unique_ptr<HWTexture> obj(new HWTexture()); std::unique_ptr<HWTexture> obj(new HWTexture());
obj->Format = GL_RGBA16F; obj->Format = GL_RGBA16F;
@ -559,7 +551,7 @@ OpenGLSWFrameBuffer::HWTexture *OpenGLSWFrameBuffer::CopyCurrentScreen()
glBindTexture(GL_TEXTURE_2D, oldBinding); glBindTexture(GL_TEXTURE_2D, oldBinding);
return obj.release(); return obj;
} }
void OpenGLSWFrameBuffer::SetGammaRamp(const GammaRamp *ramp) void OpenGLSWFrameBuffer::SetGammaRamp(const GammaRamp *ramp)
@ -747,8 +739,8 @@ void OpenGLSWFrameBuffer::Present()
FBVERTEX verts[4]; FBVERTEX verts[4];
CalcFullscreenCoords(verts, false, 0, 0xFFFFFFFF); CalcFullscreenCoords(verts, false, 0, 0xFFFFFFFF);
SetTexture(0, OutputFB->Texture); SetTexture(0, OutputFB->Texture.get());
SetPixelShader(Shaders[SHADER_GammaCorrection]); SetPixelShader(Shaders[SHADER_GammaCorrection].get());
SetAlphaBlend(0); SetAlphaBlend(0);
EnableAlphaTest(false); EnableAlphaTest(false);
DrawTriangleFans(2, verts); DrawTriangleFans(2, verts);
@ -823,7 +815,8 @@ bool OpenGLSWFrameBuffer::CreateResources()
if (!LoadShaders()) if (!LoadShaders())
return false; return false;
if (!CreateFrameBuffer("OutputFB", Width, Height, &OutputFB)) OutputFB = CreateFrameBuffer("OutputFB", Width, Height);
if (!OutputFB)
return false; return false;
glBindFramebuffer(GL_FRAMEBUFFER, OutputFB->Framebuffer); glBindFramebuffer(GL_FRAMEBUFFER, OutputFB->Framebuffer);
@ -865,7 +858,8 @@ bool OpenGLSWFrameBuffer::LoadShaders()
for (i = 0; i < NUM_SHADERS; ++i) for (i = 0; i < NUM_SHADERS; ++i)
{ {
shaderpath = shaderdir; shaderpath = shaderdir;
if (!CreatePixelShader(vertsource, fragsource, ShaderDefines[i], &Shaders[i]) && i < SHADER_BurnWipe) Shaders[i] = CreatePixelShader(vertsource, fragsource, ShaderDefines[i]);
if (!Shaders[i] && i < SHADER_BurnWipe)
{ {
break; break;
} }
@ -884,7 +878,7 @@ bool OpenGLSWFrameBuffer::LoadShaders()
// Failure. Release whatever managed to load (which is probably nothing.) // Failure. Release whatever managed to load (which is probably nothing.)
for (i = 0; i < NUM_SHADERS; ++i) for (i = 0; i < NUM_SHADERS; ++i)
{ {
SafeRelease(Shaders[i]); Shaders[i].reset();
} }
return false; return false;
} }
@ -903,11 +897,11 @@ void OpenGLSWFrameBuffer::ReleaseResources()
KillNativeTexs(); KillNativeTexs();
KillNativePals(); KillNativePals();
ReleaseDefaultPoolItems(); ReleaseDefaultPoolItems();
SafeRelease(ScreenshotTexture); ScreenshotTexture.reset();
SafeRelease(PaletteTexture); PaletteTexture.reset();
for (int i = 0; i < NUM_SHADERS; ++i) for (int i = 0; i < NUM_SHADERS; ++i)
{ {
SafeRelease(Shaders[i]); Shaders[i].reset();
} }
if (ScreenWipe != nullptr) if (ScreenWipe != nullptr)
{ {
@ -925,19 +919,20 @@ void OpenGLSWFrameBuffer::ReleaseResources()
void OpenGLSWFrameBuffer::ReleaseDefaultPoolItems() void OpenGLSWFrameBuffer::ReleaseDefaultPoolItems()
{ {
SafeRelease(FBTexture); FBTexture.reset();
SafeRelease(FinalWipeScreen); FinalWipeScreen.reset();
SafeRelease(InitialWipeScreen); InitialWipeScreen.reset();
SafeRelease(VertexBuffer); VertexBuffer.reset();
SafeRelease(IndexBuffer); IndexBuffer.reset();
SafeRelease(OutputFB); OutputFB.reset();
} }
bool OpenGLSWFrameBuffer::Reset() bool OpenGLSWFrameBuffer::Reset()
{ {
ReleaseDefaultPoolItems(); ReleaseDefaultPoolItems();
if (!CreateFrameBuffer("OutputFB", Width, Height, &OutputFB) || !CreateFBTexture() || !CreateVertexes()) OutputFB = CreateFrameBuffer("OutputFB", Width, Height);
if (!OutputFB || !CreateFBTexture() || !CreateVertexes())
{ {
return false; return false;
} }
@ -983,7 +978,8 @@ void OpenGLSWFrameBuffer::KillNativeTexs()
bool OpenGLSWFrameBuffer::CreateFBTexture() bool OpenGLSWFrameBuffer::CreateFBTexture()
{ {
return CreateTexture("FBTexture", Width, Height, 1, IsBgra() ? GL_RGBA8 : GL_R8, &FBTexture); FBTexture = CreateTexture("FBTexture", Width, Height, 1, IsBgra() ? GL_RGBA8 : GL_R8);
return FBTexture != nullptr;
} }
//========================================================================== //==========================================================================
@ -994,7 +990,8 @@ bool OpenGLSWFrameBuffer::CreateFBTexture()
bool OpenGLSWFrameBuffer::CreatePaletteTexture() bool OpenGLSWFrameBuffer::CreatePaletteTexture()
{ {
return CreateTexture("PaletteTexture", 256, 1, 1, GL_RGBA8, &PaletteTexture); PaletteTexture = CreateTexture("PaletteTexture", 256, 1, 1, GL_RGBA8);
return PaletteTexture != nullptr;
} }
//========================================================================== //==========================================================================
@ -1009,11 +1006,13 @@ bool OpenGLSWFrameBuffer::CreateVertexes()
IndexPos = -1; IndexPos = -1;
QuadBatchPos = -1; QuadBatchPos = -1;
BatchType = BATCH_None; BatchType = BATCH_None;
if (!CreateVertexBuffer(sizeof(FBVERTEX)*NUM_VERTS, &VertexBuffer)) VertexBuffer = CreateVertexBuffer(sizeof(FBVERTEX)*NUM_VERTS);
if (!VertexBuffer)
{ {
return false; return false;
} }
if (!CreateIndexBuffer(sizeof(uint16_t)*NUM_INDEXES, &IndexBuffer)) IndexBuffer = CreateIndexBuffer(sizeof(uint16_t)*NUM_INDEXES);
if (!IndexBuffer)
{ {
return false; return false;
} }
@ -1421,15 +1420,15 @@ void OpenGLSWFrameBuffer::Draw3DPart(bool copy3d)
else else
glDisable(GL_LINE_SMOOTH); glDisable(GL_LINE_SMOOTH);
SetTexture(0, FBTexture); SetTexture(0, FBTexture.get());
SetPaletteTexture(PaletteTexture, 256, BorderColor); SetPaletteTexture(PaletteTexture.get(), 256, BorderColor);
memset(Constant, 0, sizeof(Constant)); memset(Constant, 0, sizeof(Constant));
SetAlphaBlend(0); SetAlphaBlend(0);
EnableAlphaTest(false); EnableAlphaTest(false);
if (IsBgra()) if (IsBgra())
SetPixelShader(Shaders[SHADER_NormalColor]); SetPixelShader(Shaders[SHADER_NormalColor].get());
else else
SetPixelShader(Shaders[SHADER_NormalColorPal]); SetPixelShader(Shaders[SHADER_NormalColorPal].get());
if (copy3d) if (copy3d)
{ {
FBVERTEX verts[4]; FBVERTEX verts[4];
@ -1447,9 +1446,9 @@ void OpenGLSWFrameBuffer::Draw3DPart(bool copy3d)
color0 = ColorValue(map->ColorizeStart[0] / 2, map->ColorizeStart[1] / 2, map->ColorizeStart[2] / 2, 0); color0 = ColorValue(map->ColorizeStart[0] / 2, map->ColorizeStart[1] / 2, map->ColorizeStart[2] / 2, 0);
color1 = ColorValue(map->ColorizeEnd[0] / 2, map->ColorizeEnd[1] / 2, map->ColorizeEnd[2] / 2, 1); color1 = ColorValue(map->ColorizeEnd[0] / 2, map->ColorizeEnd[1] / 2, map->ColorizeEnd[2] / 2, 1);
if (IsBgra()) if (IsBgra())
SetPixelShader(Shaders[SHADER_SpecialColormap]); SetPixelShader(Shaders[SHADER_SpecialColormap].get());
else else
SetPixelShader(Shaders[SHADER_SpecialColormapPal]); SetPixelShader(Shaders[SHADER_SpecialColormapPal].get());
} }
} }
else else
@ -1461,9 +1460,9 @@ void OpenGLSWFrameBuffer::Draw3DPart(bool copy3d)
DrawTriangleFans(2, verts); DrawTriangleFans(2, verts);
} }
if (IsBgra()) if (IsBgra())
SetPixelShader(Shaders[SHADER_NormalColor]); SetPixelShader(Shaders[SHADER_NormalColor].get());
else else
SetPixelShader(Shaders[SHADER_NormalColorPal]); SetPixelShader(Shaders[SHADER_NormalColorPal].get());
} }
//========================================================================== //==========================================================================
@ -1696,7 +1695,7 @@ void OpenGLSWFrameBuffer::ReleaseScreenshotBuffer()
{ {
Super::ReleaseScreenshotBuffer(); Super::ReleaseScreenshotBuffer();
} }
SafeRelease(ScreenshotTexture); ScreenshotTexture.reset();
} }
/**************************************************************************/ /**************************************************************************/
@ -1782,7 +1781,7 @@ void OpenGLSWFrameBuffer::DrawPackedTextures(int packnum)
quad->ShaderNum = BQS_Plain; quad->ShaderNum = BQS_Plain;
} }
quad->Palette = nullptr; quad->Palette = nullptr;
quad->Texture = pack->Tex; quad->Texture = pack->Tex.get();
quad->NumVerts = 4; quad->NumVerts = 4;
quad->NumTris = 2; quad->NumTris = 2;
@ -1911,7 +1910,6 @@ OpenGLSWFrameBuffer::PackedTexture *OpenGLSWFrameBuffer::AllocPackedTexture(int
OpenGLSWFrameBuffer::Atlas::Atlas(OpenGLSWFrameBuffer *fb, int w, int h, int format) OpenGLSWFrameBuffer::Atlas::Atlas(OpenGLSWFrameBuffer *fb, int w, int h, int format)
: Packer(w, h, true) : Packer(w, h, true)
{ {
Tex = nullptr;
Format = format; Format = format;
UsedList = nullptr; UsedList = nullptr;
OneUse = false; OneUse = false;
@ -1927,7 +1925,7 @@ OpenGLSWFrameBuffer::Atlas::Atlas(OpenGLSWFrameBuffer *fb, int w, int h, int for
} }
*prev = this; *prev = this;
fb->CreateTexture("Atlas", w, h, 1, format, &Tex); Tex = fb->CreateTexture("Atlas", w, h, 1, format);
Width = w; Width = w;
Height = h; Height = h;
} }
@ -1942,7 +1940,7 @@ OpenGLSWFrameBuffer::Atlas::~Atlas()
{ {
PackedTexture *box, *next; PackedTexture *box, *next;
SafeRelease(Tex); Tex.reset();
for (box = UsedList; box != nullptr; box = next) for (box = UsedList; box != nullptr; box = next)
{ {
next = box->Next; next = box->Next;
@ -2293,7 +2291,7 @@ FTextureFormat OpenGLSWFrameBuffer::OpenGLTex::ToTexFmt(int fmt)
//========================================================================== //==========================================================================
OpenGLSWFrameBuffer::OpenGLPal::OpenGLPal(FRemapTable *remap, OpenGLSWFrameBuffer *fb) OpenGLSWFrameBuffer::OpenGLPal::OpenGLPal(FRemapTable *remap, OpenGLSWFrameBuffer *fb)
: Tex(nullptr), Remap(remap) : Remap(remap)
{ {
int count; int count;
@ -2317,12 +2315,12 @@ OpenGLSWFrameBuffer::OpenGLPal::OpenGLPal(FRemapTable *remap, OpenGLSWFrameBuffe
BorderColor = 0; BorderColor = 0;
RoundedPaletteSize = count; RoundedPaletteSize = count;
if (fb->CreateTexture("Pal", count, 1, 1, GL_RGBA8, &Tex)) Tex = fb->CreateTexture("Pal", count, 1, 1, GL_RGBA8);
if (Tex)
{ {
if (!Update()) if (!Update())
{ {
delete Tex; Tex.reset();
Tex = nullptr;
} }
} }
} }
@ -2335,7 +2333,7 @@ OpenGLSWFrameBuffer::OpenGLPal::OpenGLPal(FRemapTable *remap, OpenGLSWFrameBuffe
OpenGLSWFrameBuffer::OpenGLPal::~OpenGLPal() OpenGLSWFrameBuffer::OpenGLPal::~OpenGLPal()
{ {
SafeRelease(Tex); Tex.reset();
// Detach from the palette list // Detach from the palette list
*Prev = Next; *Prev = Next;
if (Next != nullptr) if (Next != nullptr)
@ -2639,9 +2637,9 @@ void OpenGLSWFrameBuffer::EndLineBatch()
VertexBuffer->Unlock(); VertexBuffer->Unlock();
if (VertexPos > 0) if (VertexPos > 0)
{ {
SetPixelShader(Shaders[SHADER_VertexColor]); SetPixelShader(Shaders[SHADER_VertexColor].get());
SetAlphaBlend(GL_FUNC_ADD, GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); SetAlphaBlend(GL_FUNC_ADD, GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
SetStreamSource(VertexBuffer); SetStreamSource(VertexBuffer.get());
DrawLineList(VertexPos / 2); DrawLineList(VertexPos / 2);
} }
VertexPos = -1; VertexPos = -1;
@ -2718,7 +2716,7 @@ void OpenGLSWFrameBuffer::DrawPixel(int x, int y, int palcolor, uint32_t color)
float(x), float(y), 0, 1, color float(x), float(y), 0, 1, color
}; };
EndBatch(); // Draw out any batched operations. EndBatch(); // Draw out any batched operations.
SetPixelShader(Shaders[SHADER_VertexColor]); SetPixelShader(Shaders[SHADER_VertexColor].get());
SetAlphaBlend(GL_FUNC_ADD, GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); SetAlphaBlend(GL_FUNC_ADD, GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
DrawPoints(1, &pt); DrawPoints(1, &pt);
} }
@ -2829,7 +2827,7 @@ void OpenGLSWFrameBuffer::DrawTextureParms(FTexture *img, DrawParms &parms)
goto done; goto done;
} }
quad->Texture = tex->Box->Owner->Tex; quad->Texture = tex->Box->Owner->Tex.get();
if (parms.bilinear) if (parms.bilinear)
{ {
quad->Flags |= BQF_Bilinear; quad->Flags |= BQF_Bilinear;
@ -2956,7 +2954,7 @@ void OpenGLSWFrameBuffer::FlatFill(int left, int top, int right, int bottom, FTe
quad->ShaderNum = BQS_Plain; quad->ShaderNum = BQS_Plain;
} }
quad->Palette = nullptr; quad->Palette = nullptr;
quad->Texture = tex->Box->Owner->Tex; quad->Texture = tex->Box->Owner->Tex.get();
quad->NumVerts = 4; quad->NumVerts = 4;
quad->NumTris = 2; quad->NumTris = 2;
@ -3085,7 +3083,7 @@ void OpenGLSWFrameBuffer::FillSimplePoly(FTexture *texture, FVector2 *points, in
quad->ShaderNum = BQS_Plain; quad->ShaderNum = BQS_Plain;
} }
quad->Palette = nullptr; quad->Palette = nullptr;
quad->Texture = tex->Box->Owner->Tex; quad->Texture = tex->Box->Owner->Tex.get();
quad->NumVerts = npoints; quad->NumVerts = npoints;
quad->NumTris = npoints - 2; quad->NumTris = npoints - 2;
@ -3295,8 +3293,8 @@ void OpenGLSWFrameBuffer::EndQuadBatch()
IndexPos = -1; IndexPos = -1;
return; return;
} }
SetStreamSource(VertexBuffer); SetStreamSource(VertexBuffer.get());
SetIndices(IndexBuffer); SetIndices(IndexBuffer.get());
bool uv_wrapped = false; bool uv_wrapped = false;
bool uv_should_wrap; bool uv_should_wrap;
int indexpos, vertpos; int indexpos, vertpos;
@ -3335,12 +3333,12 @@ void OpenGLSWFrameBuffer::EndQuadBatch()
// Set the palette (if one) // Set the palette (if one)
if ((quad->Flags & BQF_Paletted) == BQF_GamePalette) if ((quad->Flags & BQF_Paletted) == BQF_GamePalette)
{ {
SetPaletteTexture(PaletteTexture, 256, BorderColor); SetPaletteTexture(PaletteTexture.get(), 256, BorderColor);
} }
else if ((quad->Flags & BQF_Paletted) == BQF_CustomPalette) else if ((quad->Flags & BQF_Paletted) == BQF_CustomPalette)
{ {
assert(quad->Palette != nullptr); assert(quad->Palette != nullptr);
SetPaletteTexture(quad->Palette->Tex, quad->Palette->RoundedPaletteSize, quad->Palette->BorderColor); SetPaletteTexture(quad->Palette->Tex.get(), quad->Palette->RoundedPaletteSize, quad->Palette->BorderColor);
} }
// Set the alpha blending // Set the alpha blending
@ -3352,29 +3350,26 @@ void OpenGLSWFrameBuffer::EndQuadBatch()
// Set the pixel shader // Set the pixel shader
if (quad->ShaderNum == BQS_PalTex) if (quad->ShaderNum == BQS_PalTex)
{ {
SetPixelShader(Shaders[(quad->Flags & BQF_InvertSource) ? SetPixelShader(Shaders[(quad->Flags & BQF_InvertSource) ? SHADER_NormalColorPalInv : SHADER_NormalColorPal].get());
SHADER_NormalColorPalInv : SHADER_NormalColorPal]);
} }
else if (quad->ShaderNum == BQS_Plain) else if (quad->ShaderNum == BQS_Plain)
{ {
SetPixelShader(Shaders[(quad->Flags & BQF_InvertSource) ? SetPixelShader(Shaders[(quad->Flags & BQF_InvertSource) ? SHADER_NormalColorInv : SHADER_NormalColor].get());
SHADER_NormalColorInv : SHADER_NormalColor]);
} }
else if (quad->ShaderNum == BQS_RedToAlpha) else if (quad->ShaderNum == BQS_RedToAlpha)
{ {
SetPixelShader(Shaders[(quad->Flags & BQF_InvertSource) ? SetPixelShader(Shaders[(quad->Flags & BQF_InvertSource) ? SHADER_RedToAlphaInv : SHADER_RedToAlpha].get());
SHADER_RedToAlphaInv : SHADER_RedToAlpha]);
} }
else if (quad->ShaderNum == BQS_ColorOnly) else if (quad->ShaderNum == BQS_ColorOnly)
{ {
SetPixelShader(Shaders[SHADER_VertexColor]); SetPixelShader(Shaders[SHADER_VertexColor].get());
} }
else if (quad->ShaderNum == BQS_SpecialColormap) else if (quad->ShaderNum == BQS_SpecialColormap)
{ {
int select; int select;
select = !!(quad->Flags & BQF_Paletted); select = !!(quad->Flags & BQF_Paletted);
SetPixelShader(Shaders[SHADER_SpecialColormap + select]); SetPixelShader(Shaders[SHADER_SpecialColormap + select].get());
} }
else if (quad->ShaderNum == BQS_InGameColormap) else if (quad->ShaderNum == BQS_InGameColormap)
{ {
@ -3387,7 +3382,7 @@ void OpenGLSWFrameBuffer::EndQuadBatch()
{ {
SetConstant(PSCONST_Desaturation, quad->Desat / 255.f, (255 - quad->Desat) / 255.f, 0, 0); SetConstant(PSCONST_Desaturation, quad->Desat / 255.f, (255 - quad->Desat) / 255.f, 0, 0);
} }
SetPixelShader(Shaders[SHADER_InGameColormap + select]); SetPixelShader(Shaders[SHADER_InGameColormap + select].get());
} }
// Set the texture clamp addressing mode // Set the texture clamp addressing mode

View file

@ -129,7 +129,7 @@ private:
~HWFrameBuffer(); ~HWFrameBuffer();
int Framebuffer = 0; int Framebuffer = 0;
HWTexture *Texture = nullptr; std::unique_ptr<HWTexture> Texture;
}; };
@ -177,11 +177,12 @@ private:
int BurnLocation = -1; int BurnLocation = -1;
}; };
bool CreateFrameBuffer(const FString &name, int width, int height, HWFrameBuffer **outFramebuffer); std::unique_ptr<HWFrameBuffer> CreateFrameBuffer(const FString &name, int width, int height);
bool CreatePixelShader(FString vertexsrc, FString fragmentsrc, const FString &defines, HWPixelShader **outShader); std::unique_ptr<HWPixelShader> CreatePixelShader(FString vertexsrc, FString fragmentsrc, const FString &defines);
bool CreateVertexBuffer(int size, HWVertexBuffer **outVertexBuffer); std::unique_ptr<HWVertexBuffer> CreateVertexBuffer(int size);
bool CreateIndexBuffer(int size, HWIndexBuffer **outIndexBuffer); std::unique_ptr<HWIndexBuffer> CreateIndexBuffer(int size);
bool CreateTexture(const FString &name, int width, int height, int levels, int format, HWTexture **outTexture); std::unique_ptr<HWTexture> CreateTexture(const FString &name, int width, int height, int levels, int format);
void SetGammaRamp(const GammaRamp *ramp); void SetGammaRamp(const GammaRamp *ramp);
void SetPixelShaderConstantF(int uniformIndex, const float *data, int vec4fcount); void SetPixelShaderConstantF(int uniformIndex, const float *data, int vec4fcount);
void SetHWPixelShader(HWPixelShader *shader); void SetHWPixelShader(HWPixelShader *shader);
@ -250,7 +251,7 @@ private:
SkylineBinPack Packer; SkylineBinPack Packer;
Atlas *Next; Atlas *Next;
HWTexture *Tex; std::unique_ptr<HWTexture> Tex;
int Format; int Format;
PackedTexture *UsedList; // Boxes that contain images PackedTexture *UsedList; // Boxes that contain images
int Width, Height; int Width, Height;
@ -287,7 +288,7 @@ private:
OpenGLPal **Prev; OpenGLPal **Prev;
OpenGLPal *Next; OpenGLPal *Next;
HWTexture *Tex; std::unique_ptr<HWTexture> Tex;
uint32_t BorderColor; uint32_t BorderColor;
bool DoColorSkip; bool DoColorSkip;
@ -392,7 +393,7 @@ private:
void UploadPalette(); void UploadPalette();
void CalcFullscreenCoords(FBVERTEX verts[4], bool viewarea_only, uint32_t color0, uint32_t color1) const; void CalcFullscreenCoords(FBVERTEX verts[4], bool viewarea_only, uint32_t color0, uint32_t color1) const;
bool Reset(); bool Reset();
HWTexture *CopyCurrentScreen(); std::unique_ptr<HWTexture> CopyCurrentScreen();
void ReleaseDefaultPoolItems(); void ReleaseDefaultPoolItems();
void KillNativePals(); void KillNativePals();
void KillNativeTexs(); void KillNativeTexs();
@ -422,8 +423,6 @@ private:
void SetSamplerWrapT(int tnum, int mode); void SetSamplerWrapT(int tnum, int mode);
void SetPaletteTexture(HWTexture *texture, int count, uint32_t border_color); void SetPaletteTexture(HWTexture *texture, int count, uint32_t border_color);
template<typename T> static void SafeRelease(T &x) { if (x != nullptr) { delete x; x = nullptr; } }
bool Valid = false; bool Valid = false;
std::shared_ptr<FGLDebug> Debug; std::shared_ptr<FGLDebug> Debug;
@ -431,7 +430,7 @@ private:
float ShaderConstants[NumPSCONST * 4]; float ShaderConstants[NumPSCONST * 4];
HWPixelShader *CurrentShader = nullptr; HWPixelShader *CurrentShader = nullptr;
HWFrameBuffer *OutputFB = nullptr; std::unique_ptr<HWFrameBuffer> OutputFB;
bool AlphaTestEnabled = false; bool AlphaTestEnabled = false;
bool AlphaBlendEnabled = false; bool AlphaBlendEnabled = false;
@ -467,13 +466,13 @@ private:
OpenGLTex *Textures = nullptr; OpenGLTex *Textures = nullptr;
Atlas *Atlases = nullptr; Atlas *Atlases = nullptr;
HWTexture *FBTexture = nullptr; std::unique_ptr<HWTexture> FBTexture;
HWTexture *PaletteTexture = nullptr; std::unique_ptr<HWTexture> PaletteTexture;
HWTexture *ScreenshotTexture = nullptr; std::unique_ptr<HWTexture> ScreenshotTexture;
HWVertexBuffer *VertexBuffer = nullptr; std::unique_ptr<HWVertexBuffer> VertexBuffer;
FBVERTEX *VertexData = nullptr; FBVERTEX *VertexData = nullptr;
HWIndexBuffer *IndexBuffer = nullptr; std::unique_ptr<HWIndexBuffer> IndexBuffer;
uint16_t *IndexData = nullptr; uint16_t *IndexData = nullptr;
BufferedTris *QuadExtra = nullptr; BufferedTris *QuadExtra = nullptr;
int VertexPos; int VertexPos;
@ -481,9 +480,9 @@ private:
int QuadBatchPos; int QuadBatchPos;
enum { BATCH_None, BATCH_Quads, BATCH_Lines } BatchType; enum { BATCH_None, BATCH_Quads, BATCH_Lines } BatchType;
HWPixelShader *Shaders[NUM_SHADERS]; std::unique_ptr<HWPixelShader> Shaders[NUM_SHADERS];
HWTexture *InitialWipeScreen = nullptr, *FinalWipeScreen = nullptr; std::unique_ptr<HWTexture> InitialWipeScreen, FinalWipeScreen;
class Wiper class Wiper
{ {

View file

@ -98,7 +98,7 @@ public:
private: private:
static const int WIDTH = 64, HEIGHT = 64; static const int WIDTH = 64, HEIGHT = 64;
uint8_t BurnArray[WIDTH * (HEIGHT + 5)]; uint8_t BurnArray[WIDTH * (HEIGHT + 5)];
HWTexture *BurnTexture; std::unique_ptr<HWTexture> BurnTexture;
int Density; int Density;
int BurnTime; int BurnTime;
}; };
@ -247,8 +247,8 @@ void OpenGLSWFrameBuffer::WipeCleanup()
delete ScreenWipe; delete ScreenWipe;
ScreenWipe = NULL; ScreenWipe = NULL;
} }
SafeRelease( InitialWipeScreen ); InitialWipeScreen.reset();
SafeRelease( FinalWipeScreen ); FinalWipeScreen.reset();
GatheringWipeScreen = false; GatheringWipeScreen = false;
if (!Accel2D) if (!Accel2D)
{ {
@ -283,7 +283,7 @@ void OpenGLSWFrameBuffer::Wiper::DrawScreen(OpenGLSWFrameBuffer *fb, HWTexture *
fb->CalcFullscreenCoords(verts, false, color0, color1); fb->CalcFullscreenCoords(verts, false, color0, color1);
fb->SetTexture(0, tex); fb->SetTexture(0, tex);
fb->SetAlphaBlend(blendop, GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); fb->SetAlphaBlend(blendop, GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
fb->SetPixelShader(fb->Shaders[SHADER_NormalColor]); fb->SetPixelShader(fb->Shaders[SHADER_NormalColor].get());
fb->DrawTriangleFans(2, verts); fb->DrawTriangleFans(2, verts);
} }
@ -313,10 +313,10 @@ bool OpenGLSWFrameBuffer::Wiper_Crossfade::Run(int ticks, OpenGLSWFrameBuffer *f
Clock += ticks; Clock += ticks;
// Put the initial screen back to the buffer. // Put the initial screen back to the buffer.
DrawScreen(fb, fb->InitialWipeScreen); DrawScreen(fb, fb->InitialWipeScreen.get());
// Draw the new screen on top of it. // Draw the new screen on top of it.
DrawScreen(fb, fb->FinalWipeScreen, GL_FUNC_ADD, ColorValue(0,0,0,Clock / 32.f), ColorRGBA(255,255,255,0)); DrawScreen(fb, fb->FinalWipeScreen.get(), GL_FUNC_ADD, ColorValue(0,0,0,Clock / 32.f), ColorRGBA(255,255,255,0));
return Clock >= 32; return Clock >= 32;
} }
@ -354,7 +354,7 @@ OpenGLSWFrameBuffer::Wiper_Melt::Wiper_Melt()
bool OpenGLSWFrameBuffer::Wiper_Melt::Run(int ticks, OpenGLSWFrameBuffer *fb) bool OpenGLSWFrameBuffer::Wiper_Melt::Run(int ticks, OpenGLSWFrameBuffer *fb)
{ {
// Draw the new screen on the bottom. // Draw the new screen on the bottom.
DrawScreen(fb, fb->FinalWipeScreen); DrawScreen(fb, fb->FinalWipeScreen.get());
int i, dy; int i, dy;
int fbwidth = fb->Width; int fbwidth = fb->Width;
@ -401,7 +401,7 @@ bool OpenGLSWFrameBuffer::Wiper_Melt::Run(int ticks, OpenGLSWFrameBuffer *fb)
quad->Flags = BQF_DisableAlphaTest; quad->Flags = BQF_DisableAlphaTest;
quad->ShaderNum = BQS_Plain; quad->ShaderNum = BQS_Plain;
quad->Palette = NULL; quad->Palette = NULL;
quad->Texture = fb->InitialWipeScreen; quad->Texture = fb->InitialWipeScreen.get();
quad->NumVerts = 4; quad->NumVerts = 4;
quad->NumTris = 2; quad->NumTris = 2;
@ -485,10 +485,12 @@ OpenGLSWFrameBuffer::Wiper_Burn::Wiper_Burn(OpenGLSWFrameBuffer *fb)
Density = 4; Density = 4;
BurnTime = 0; BurnTime = 0;
memset(BurnArray, 0, sizeof(BurnArray)); memset(BurnArray, 0, sizeof(BurnArray));
if (fb->Shaders[SHADER_BurnWipe] == NULL || !fb->CreateTexture("BurnWipe", WIDTH, HEIGHT, 1, GL_R8, &BurnTexture)) if (fb->Shaders[SHADER_BurnWipe] == nullptr)
{ {
BurnTexture = NULL; BurnTexture = nullptr;
} }
BurnTexture = fb->CreateTexture("BurnWipe", WIDTH, HEIGHT, 1, GL_R8);
} }
//========================================================================== //==========================================================================
@ -499,7 +501,7 @@ OpenGLSWFrameBuffer::Wiper_Burn::Wiper_Burn(OpenGLSWFrameBuffer *fb)
OpenGLSWFrameBuffer::Wiper_Burn::~Wiper_Burn() OpenGLSWFrameBuffer::Wiper_Burn::~Wiper_Burn()
{ {
SafeRelease( BurnTexture ); BurnTexture.reset();
} }
//========================================================================== //==========================================================================
@ -555,7 +557,7 @@ bool OpenGLSWFrameBuffer::Wiper_Burn::Run(int ticks, OpenGLSWFrameBuffer *fb)
} }
// Put the initial screen back to the buffer. // Put the initial screen back to the buffer.
DrawScreen(fb, fb->InitialWipeScreen); DrawScreen(fb, fb->InitialWipeScreen.get());
// Burn the new screen on top of it. // Burn the new screen on top of it.
float right = float(fb->Width); float right = float(fb->Width);
@ -569,10 +571,10 @@ bool OpenGLSWFrameBuffer::Wiper_Burn::Run(int ticks, OpenGLSWFrameBuffer *fb)
{ 0.f, bot, 0.f, 1.f, 0.f, 1.f, 0, 1 } { 0.f, bot, 0.f, 1.f, 0.f, 1.f, 0, 1 }
}; };
fb->SetTexture(0, fb->FinalWipeScreen); fb->SetTexture(0, fb->FinalWipeScreen.get());
fb->SetTexture(1, BurnTexture); fb->SetTexture(1, BurnTexture.get());
fb->SetAlphaBlend(GL_FUNC_ADD, GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); fb->SetAlphaBlend(GL_FUNC_ADD, GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
fb->SetPixelShader(fb->Shaders[SHADER_BurnWipe]); fb->SetPixelShader(fb->Shaders[SHADER_BurnWipe].get());
glActiveTexture(GL_TEXTURE1); glActiveTexture(GL_TEXTURE1);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
fb->DrawTriangleFans(2, verts); fb->DrawTriangleFans(2, verts);