mirror of https://github.com/ZDoom/qzdoom.git
Add glsl shader version of the d3d9 shaders and get enough of it working for it to boot without errors
This commit is contained in:
parent
40df46f94e
commit
f4308b3184
|
@ -71,7 +71,6 @@
|
||||||
#include "gl/utility/gl_templates.h"
|
#include "gl/utility/gl_templates.h"
|
||||||
#include "gl/gl_functions.h"
|
#include "gl/gl_functions.h"
|
||||||
|
|
||||||
CVAR(Bool, gl_antilag, true, CVAR_ARCHIVE | CVAR_GLOBALCONFIG)
|
|
||||||
CVAR(Int, gl_showpacks, 0, 0)
|
CVAR(Int, gl_showpacks, 0, 0)
|
||||||
#ifndef WIN32 // Defined in fb_d3d9 for Windows
|
#ifndef WIN32 // Defined in fb_d3d9 for Windows
|
||||||
CVAR(Bool, vid_hwaalines, true, CVAR_ARCHIVE | CVAR_GLOBALCONFIG)
|
CVAR(Bool, vid_hwaalines, true, CVAR_ARCHIVE | CVAR_GLOBALCONFIG)
|
||||||
|
@ -88,63 +87,66 @@ EXTERN_CVAR(Int, vid_refreshrate)
|
||||||
|
|
||||||
extern cycle_t BlitCycles;
|
extern cycle_t BlitCycles;
|
||||||
|
|
||||||
|
void gl_LoadExtensions();
|
||||||
|
|
||||||
IMPLEMENT_CLASS(OpenGLSWFrameBuffer)
|
IMPLEMENT_CLASS(OpenGLSWFrameBuffer)
|
||||||
|
|
||||||
const char *const OpenGLSWFrameBuffer::ShaderNames[OpenGLSWFrameBuffer::NUM_SHADERS] =
|
const char *const OpenGLSWFrameBuffer::ShaderDefines[OpenGLSWFrameBuffer::NUM_SHADERS] =
|
||||||
{
|
{
|
||||||
"NormalColor",
|
"#define ENORMALCOLOR\n#define PALTEX 0\n#define DINVERT 0", // NormalColor
|
||||||
"NormalColorPal",
|
"#define ENORMALCOLOR\n#define PALTEX 1\n#define INVERT 0", // NormalColorPal
|
||||||
"NormalColorInv",
|
"#define ENORMALCOLOR\n#define PALTEX 0\n#define INVERT 1", // NormalColorInv
|
||||||
"NormalColorPalInv",
|
"#define ENORMALCOLOR\n#define PALTEX 1\n#define INVERT 1", // NormalColorPalInv
|
||||||
|
|
||||||
"RedToAlpha",
|
"#define EREDTOALPHA\n#define INVERT 0", // RedToAlpha
|
||||||
"RedToAlphaInv",
|
"#define EREDTOALPHA\n#define INVERT 1", // RedToAlphaInv
|
||||||
|
|
||||||
"VertexColor",
|
"#define EVERTEXCOLOR", // VertexColor
|
||||||
|
|
||||||
"SpecialColormap",
|
"#define ESPECIALCOLORMAP\n#define PALTEX 0\n#define INVERT 0", // SpecialColormap
|
||||||
"SpecialColorMapPal",
|
"#define ESPECIALCOLORMAP\n#define PALTEX 1\n#define INVERT 0", // SpecialColorMapPal
|
||||||
|
|
||||||
"InGameColormap",
|
"#define EINGAMECOLORMAP\n#define PALTEX 0\n#define INVERT 0\n#define DESAT 0", // InGameColormap
|
||||||
"InGameColormapDesat",
|
"#define EINGAMECOLORMAP\n#define PALTEX 0\n#define INVERT 0\n#define DESAT 1", // InGameColormapDesat
|
||||||
"InGameColormapInv",
|
"#define EINGAMECOLORMAP\n#define PALTEX 0\n#define INVERT 1\n#define DESAT 0", // InGameColormapInv
|
||||||
"InGameColormapInvDesat",
|
"#define EINGAMECOLORMAP\n#define PALTEX 0\n#define INVERT 1\n#define DESAT 1", // InGameColormapInvDesat
|
||||||
"InGameColormapPal",
|
"#define EINGAMECOLORMAP\n#define PALTEX 1\n#define INVERT 0\n#define DESAT 0", // InGameColormapPal
|
||||||
"InGameColormapPalDesat",
|
"#define EINGAMECOLORMAP\n#define PALTEX 1\n#define INVERT 0\n#define DESAT 1", // InGameColormapPalDesat
|
||||||
"InGameColormapPalInv",
|
"#define EINGAMECOLORMAP\n#define PALTEX 1\n#define INVERT 1\n#define DESAT 0", // InGameColormapPalInv
|
||||||
"InGameColormapPalInvDesat",
|
"#define EINGAMECOLORMAP\n#define PALTEX 1\n#define INVERT 1\n#define DESAT 1", // InGameColormapPalInvDesat
|
||||||
|
|
||||||
"BurnWipe",
|
"#define EBURNWIPE", // BurnWipe
|
||||||
"GammaCorrection",
|
"#define EGAMMACORRECTION", // GammaCorrection
|
||||||
};
|
};
|
||||||
|
|
||||||
OpenGLSWFrameBuffer::OpenGLSWFrameBuffer(void *hMonitor, int width, int height, int bits, int refreshHz, bool fullscreen) :
|
OpenGLSWFrameBuffer::OpenGLSWFrameBuffer(void *hMonitor, int width, int height, int bits, int refreshHz, bool fullscreen) :
|
||||||
Super(hMonitor, width, height, bits, refreshHz, fullscreen)
|
Super(hMonitor, width, height, bits, refreshHz, fullscreen)
|
||||||
{
|
{
|
||||||
|
// To do: this needs to cooperate with the same static in OpenGLFrameBuffer::InitializeState
|
||||||
|
static bool first = true;
|
||||||
|
if (first)
|
||||||
|
{
|
||||||
|
ogl_LoadFunctions();
|
||||||
|
}
|
||||||
|
gl_LoadExtensions();
|
||||||
|
Super::InitializeState();
|
||||||
|
|
||||||
// SetVSync needs to be at the very top to workaround a bug in Nvidia's OpenGL driver.
|
// SetVSync needs to be at the very top to workaround a bug in Nvidia's OpenGL driver.
|
||||||
// If wglSwapIntervalEXT is called after glBindFramebuffer in a frame the setting is not changed!
|
// If wglSwapIntervalEXT is called after glBindFramebuffer in a frame the setting is not changed!
|
||||||
SetVSync(vid_vsync);
|
//SetVSync(vid_vsync);
|
||||||
|
|
||||||
VertexBuffer = nullptr;
|
VertexBuffer = nullptr;
|
||||||
IndexBuffer = nullptr;
|
IndexBuffer = nullptr;
|
||||||
FBTexture = nullptr;
|
FBTexture = nullptr;
|
||||||
TempRenderTexture = nullptr;
|
|
||||||
RenderTexture[0] = nullptr;
|
|
||||||
RenderTexture[1] = nullptr;
|
|
||||||
InitialWipeScreen = nullptr;
|
InitialWipeScreen = nullptr;
|
||||||
ScreenshotTexture = nullptr;
|
ScreenshotTexture = nullptr;
|
||||||
ScreenshotSurface = nullptr;
|
|
||||||
FinalWipeScreen = nullptr;
|
FinalWipeScreen = nullptr;
|
||||||
PaletteTexture = nullptr;
|
PaletteTexture = nullptr;
|
||||||
GammaTexture = nullptr;
|
|
||||||
FrontCopySurface = nullptr;
|
|
||||||
for (int i = 0; i < NUM_SHADERS; ++i)
|
for (int i = 0; i < NUM_SHADERS; ++i)
|
||||||
{
|
{
|
||||||
Shaders[i] = nullptr;
|
Shaders[i] = nullptr;
|
||||||
}
|
}
|
||||||
GammaShader = nullptr;
|
GammaShader = nullptr;
|
||||||
BlockSurface[0] = nullptr;
|
|
||||||
BlockSurface[1] = nullptr;
|
|
||||||
VSync = vid_vsync;
|
VSync = vid_vsync;
|
||||||
BlendingRect.left = 0;
|
BlendingRect.left = 0;
|
||||||
BlendingRect.top = 0;
|
BlendingRect.top = 0;
|
||||||
|
@ -160,9 +162,6 @@ OpenGLSWFrameBuffer::OpenGLSWFrameBuffer(void *hMonitor, int width, int height,
|
||||||
QuadExtra = new BufferedTris[MAX_QUAD_BATCH];
|
QuadExtra = new BufferedTris[MAX_QUAD_BATCH];
|
||||||
Atlases = nullptr;
|
Atlases = nullptr;
|
||||||
PixelDoubling = 0;
|
PixelDoubling = 0;
|
||||||
SkipAt = -1;
|
|
||||||
CurrRenderTexture = 0;
|
|
||||||
RenderTextureToggle = 0;
|
|
||||||
|
|
||||||
Gamma = 1.0;
|
Gamma = 1.0;
|
||||||
FlashColor0 = 0;
|
FlashColor0 = 0;
|
||||||
|
@ -180,7 +179,7 @@ OpenGLSWFrameBuffer::OpenGLSWFrameBuffer(void *hMonitor, int width, int height,
|
||||||
|
|
||||||
memcpy(SourcePalette, GPalette.BaseColors, sizeof(PalEntry) * 256);
|
memcpy(SourcePalette, GPalette.BaseColors, sizeof(PalEntry) * 256);
|
||||||
|
|
||||||
Windowed = !(static_cast<Win32Video *>(Video)->GoFullscreen(fullscreen));
|
//Windowed = !(static_cast<Win32Video *>(Video)->GoFullscreen(fullscreen));
|
||||||
|
|
||||||
TrueHeight = height;
|
TrueHeight = height;
|
||||||
/*if (fullscreen)
|
/*if (fullscreen)
|
||||||
|
@ -209,7 +208,56 @@ OpenGLSWFrameBuffer::~OpenGLSWFrameBuffer()
|
||||||
delete[] QuadExtra;
|
delete[] QuadExtra;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool OpenGLSWFrameBuffer::CreatePixelShader(const void *vertexsrc, const void *fragmentsrc, HWPixelShader **outShader)
|
OpenGLSWFrameBuffer::HWTexture::~HWTexture()
|
||||||
|
{
|
||||||
|
if (Texture != 0) glDeleteTextures(1, (GLuint*)&Texture);
|
||||||
|
if (Buffer != 0) glDeleteBuffers(1, (GLuint*)&Buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
OpenGLSWFrameBuffer::HWVertexBuffer::~HWVertexBuffer()
|
||||||
|
{
|
||||||
|
if (VertexArray != 0) glDeleteVertexArrays(1, (GLuint*)&VertexArray);
|
||||||
|
if (Buffer != 0) glDeleteBuffers(1, (GLuint*)&Buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
OpenGLSWFrameBuffer::FBVERTEX *OpenGLSWFrameBuffer::HWVertexBuffer::Lock()
|
||||||
|
{
|
||||||
|
glBindBuffer(GL_ARRAY_BUFFER, Buffer);
|
||||||
|
return (FBVERTEX*)glMapBuffer(GL_ARRAY_BUFFER, GL_WRITE_ONLY);
|
||||||
|
}
|
||||||
|
|
||||||
|
void OpenGLSWFrameBuffer::HWVertexBuffer::Unlock()
|
||||||
|
{
|
||||||
|
glUnmapBuffer(GL_ARRAY_BUFFER);
|
||||||
|
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
OpenGLSWFrameBuffer::HWIndexBuffer::~HWIndexBuffer()
|
||||||
|
{
|
||||||
|
if (Buffer != 0) glDeleteBuffers(1, (GLuint*)&Buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint16_t *OpenGLSWFrameBuffer::HWIndexBuffer::Lock()
|
||||||
|
{
|
||||||
|
glGetIntegerv(GL_ELEMENT_ARRAY_BUFFER_BINDING, &LockedOldBinding);
|
||||||
|
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, Buffer);
|
||||||
|
return (uint16_t*)glMapBuffer(GL_ELEMENT_ARRAY_BUFFER, GL_WRITE_ONLY);
|
||||||
|
}
|
||||||
|
|
||||||
|
void OpenGLSWFrameBuffer::HWIndexBuffer::Unlock()
|
||||||
|
{
|
||||||
|
glUnmapBuffer(GL_ELEMENT_ARRAY_BUFFER);
|
||||||
|
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, LockedOldBinding);
|
||||||
|
}
|
||||||
|
|
||||||
|
OpenGLSWFrameBuffer::HWPixelShader::~HWPixelShader()
|
||||||
|
{
|
||||||
|
if (Program != 0) glDeleteProgram(Program);
|
||||||
|
if (VertexShader != 0) glDeleteShader(VertexShader);
|
||||||
|
if (FragmentShader != 0) glDeleteShader(FragmentShader);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool OpenGLSWFrameBuffer::CreatePixelShader(FString vertexsrc, FString fragmentsrc, const FString &defines, HWPixelShader **outShader)
|
||||||
{
|
{
|
||||||
auto shader = std::make_unique<HWPixelShader>();
|
auto shader = std::make_unique<HWPixelShader>();
|
||||||
|
|
||||||
|
@ -217,25 +265,34 @@ bool OpenGLSWFrameBuffer::CreatePixelShader(const void *vertexsrc, const void *f
|
||||||
shader->VertexShader = glCreateShader(GL_VERTEX_SHADER);
|
shader->VertexShader = glCreateShader(GL_VERTEX_SHADER);
|
||||||
shader->FragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
|
shader->FragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
|
||||||
|
|
||||||
|
vertexsrc = "#version 130\n" + defines + "\n#line 0\n" + vertexsrc;
|
||||||
|
fragmentsrc = "#version 130\n" + defines + "\n#line 0\n" + fragmentsrc;
|
||||||
|
|
||||||
{
|
{
|
||||||
int lengths[1] = { (int)strlen((const char*)vertexsrc) };
|
int lengths[1] = { (int)vertexsrc.Len() };
|
||||||
const char *sources[1] = { (const char*)vertexsrc };
|
const char *sources[1] = { vertexsrc.GetChars() };
|
||||||
glShaderSource(shader->VertexShader, 1, sources, lengths);
|
glShaderSource(shader->VertexShader, 1, sources, lengths);
|
||||||
glCompileShader(shader->VertexShader);
|
glCompileShader(shader->VertexShader);
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
int lengths[1] = { (int)strlen((const char*)fragmentsrc) };
|
int lengths[1] = { (int)fragmentsrc.Len() };
|
||||||
const char *sources[1] = { (const char*)fragmentsrc };
|
const char *sources[1] = { fragmentsrc.GetChars() };
|
||||||
glShaderSource(shader->FragmentShader, 1, sources, lengths);
|
glShaderSource(shader->FragmentShader, 1, sources, lengths);
|
||||||
glCompileShader(shader->FragmentShader);
|
glCompileShader(shader->FragmentShader);
|
||||||
}
|
}
|
||||||
|
|
||||||
GLint status = 0;
|
GLint status = 0;
|
||||||
|
int errorShader = shader->VertexShader;
|
||||||
glGetShaderiv(shader->VertexShader, GL_COMPILE_STATUS, &status);
|
glGetShaderiv(shader->VertexShader, GL_COMPILE_STATUS, &status);
|
||||||
if (status != GL_FALSE) glGetShaderiv(shader->FragmentShader, GL_COMPILE_STATUS, &status);
|
if (status != GL_FALSE) { errorShader = shader->FragmentShader; glGetShaderiv(shader->FragmentShader, GL_COMPILE_STATUS, &status); }
|
||||||
if (status == GL_FALSE)
|
if (status == GL_FALSE)
|
||||||
{
|
{
|
||||||
|
static char buffer[10000];
|
||||||
|
GLsizei length = 0;
|
||||||
|
buffer[0] = 0;
|
||||||
|
glGetShaderInfoLog(errorShader, 10000, &length, buffer);
|
||||||
|
|
||||||
*outShader = nullptr;
|
*outShader = nullptr;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -308,6 +365,8 @@ bool OpenGLSWFrameBuffer::CreateTexture(int width, int height, int levels, int f
|
||||||
{
|
{
|
||||||
auto obj = std::make_unique<HWTexture>();
|
auto obj = std::make_unique<HWTexture>();
|
||||||
|
|
||||||
|
obj->Format = format;
|
||||||
|
|
||||||
GLint oldBinding = 0;
|
GLint oldBinding = 0;
|
||||||
glGetIntegerv(GL_TEXTURE_BINDING_2D, &oldBinding);
|
glGetIntegerv(GL_TEXTURE_BINDING_2D, &oldBinding);
|
||||||
|
|
||||||
|
@ -317,7 +376,7 @@ bool OpenGLSWFrameBuffer::CreateTexture(int width, int height, int levels, int f
|
||||||
switch (format)
|
switch (format)
|
||||||
{
|
{
|
||||||
case GL_R8: srcformat = GL_RED; break;
|
case GL_R8: srcformat = GL_RED; break;
|
||||||
case GL_RGBA8: srcformat = GL_RGBA; break;
|
case GL_RGBA8: srcformat = GL_BGRA; break;
|
||||||
case GL_COMPRESSED_RGB_S3TC_DXT1_EXT: srcformat = GL_RGB; break;
|
case GL_COMPRESSED_RGB_S3TC_DXT1_EXT: srcformat = GL_RGB; break;
|
||||||
case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT: srcformat = GL_RGBA; break;
|
case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT: srcformat = GL_RGBA; break;
|
||||||
case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT: srcformat = GL_RGBA; break;
|
case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT: srcformat = GL_RGBA; break;
|
||||||
|
@ -327,6 +386,8 @@ bool OpenGLSWFrameBuffer::CreateTexture(int width, int height, int levels, int f
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
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_MAG_FILTER, GL_NEAREST);
|
||||||
|
|
||||||
glBindTexture(GL_TEXTURE_2D, oldBinding);
|
glBindTexture(GL_TEXTURE_2D, oldBinding);
|
||||||
|
|
||||||
|
@ -334,16 +395,9 @@ bool OpenGLSWFrameBuffer::CreateTexture(int width, int height, int levels, int f
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool OpenGLSWFrameBuffer::CreateOffscreenPlainSurface(int width, int height, int format, HWSurface **outSurface) { *outSurface = nullptr; return false; }
|
void OpenGLSWFrameBuffer::SetGammaRamp(const GammaRamp *ramp)
|
||||||
bool OpenGLSWFrameBuffer::CreateRenderTarget(int width, int height, int format, HWSurface **outSurface) { *outSurface = nullptr; return false; }
|
{
|
||||||
bool OpenGLSWFrameBuffer::GetBackBuffer(HWSurface **outSurface) { *outSurface = nullptr; return false; }
|
}
|
||||||
bool OpenGLSWFrameBuffer::GetRenderTarget(int index, HWSurface **outSurface) { *outSurface = nullptr; return false; }
|
|
||||||
void OpenGLSWFrameBuffer::GetRenderTargetData(HWSurface *a, HWSurface *b) { }
|
|
||||||
|
|
||||||
void OpenGLSWFrameBuffer::ColorFill(HWSurface *surface, float red, float green, float blue) { }
|
|
||||||
void OpenGLSWFrameBuffer::StretchRect(HWSurface *src, const LTRBRect *srcrect, HWSurface *dest) { }
|
|
||||||
bool OpenGLSWFrameBuffer::SetRenderTarget(int index, HWSurface *surface) { return true; }
|
|
||||||
void OpenGLSWFrameBuffer::SetGammaRamp(const GammaRamp *ramp) { }
|
|
||||||
|
|
||||||
void OpenGLSWFrameBuffer::SetPixelShaderConstantF(int uniformIndex, const float *data, int vec4fcount)
|
void OpenGLSWFrameBuffer::SetPixelShaderConstantF(int uniformIndex, const float *data, int vec4fcount)
|
||||||
{
|
{
|
||||||
|
@ -487,7 +541,6 @@ void OpenGLSWFrameBuffer::SetInitialState()
|
||||||
|
|
||||||
NeedGammaUpdate = true;
|
NeedGammaUpdate = true;
|
||||||
NeedPalUpdate = true;
|
NeedPalUpdate = true;
|
||||||
OldRenderTarget = nullptr;
|
|
||||||
|
|
||||||
// This constant is used for grayscaling weights (.xyz) and color inversion (.w)
|
// This constant is used for grayscaling weights (.xyz) and color inversion (.w)
|
||||||
float weights[4] = { 77 / 256.f, 143 / 256.f, 37 / 256.f, 1 };
|
float weights[4] = { 77 / 256.f, 143 / 256.f, 37 / 256.f, 1 };
|
||||||
|
@ -524,7 +577,6 @@ bool OpenGLSWFrameBuffer::CreateResources()
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
CreateBlockSurfaces();
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -539,32 +591,27 @@ bool OpenGLSWFrameBuffer::CreateResources()
|
||||||
|
|
||||||
bool OpenGLSWFrameBuffer::LoadShaders()
|
bool OpenGLSWFrameBuffer::LoadShaders()
|
||||||
{
|
{
|
||||||
static const char models[][4] = { "30/", "20/", "14/" };
|
int lumpvert = Wads.CheckNumForFullName("shaders/glsl/swshader.vp");
|
||||||
|
int lumpfrag = Wads.CheckNumForFullName("shaders/glsl/swshader.fp");
|
||||||
|
if (lumpvert < 0 || lumpfrag < 0)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
FString vertsource = Wads.ReadLump(lumpvert).GetString();
|
||||||
|
FString fragsource = Wads.ReadLump(lumpfrag).GetString();
|
||||||
|
|
||||||
FString shaderdir, shaderpath;
|
FString shaderdir, shaderpath;
|
||||||
unsigned model, i;
|
unsigned int i;
|
||||||
int lump, lumpvert;
|
|
||||||
|
|
||||||
// We determine the best available model simply by trying them all in
|
// We determine the best available model simply by trying them all in
|
||||||
// order of decreasing preference.
|
// order of decreasing preference.
|
||||||
for (model = 0; model < countof(models); ++model)
|
|
||||||
{
|
|
||||||
shaderdir = "shaders/gl/sm";
|
|
||||||
shaderdir += models[model];
|
|
||||||
for (i = 0; i < NUM_SHADERS; ++i)
|
for (i = 0; i < NUM_SHADERS; ++i)
|
||||||
{
|
{
|
||||||
shaderpath = shaderdir;
|
shaderpath = shaderdir;
|
||||||
lump = Wads.CheckNumForFullName(shaderpath + ShaderNames[i] + ".fp");
|
if (!CreatePixelShader(vertsource, fragsource, ShaderDefines[i], &Shaders[i]) && i < SHADER_BurnWipe)
|
||||||
lumpvert = Wads.CheckNumForFullName(shaderpath + ShaderNames[i] + ".vp");
|
|
||||||
if (lump >= 0 && lumpvert >= 0)
|
|
||||||
{
|
|
||||||
FMemLump data = Wads.ReadLump(lump);
|
|
||||||
FMemLump datavert = Wads.ReadLump(lumpvert);
|
|
||||||
if (!CreatePixelShader(datavert.GetMem(), data.GetMem(), &Shaders[i]) && i < SHADER_BurnWipe)
|
|
||||||
{
|
{
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
if (i == NUM_SHADERS)
|
if (i == NUM_SHADERS)
|
||||||
{ // Success!
|
{ // Success!
|
||||||
return true;
|
return true;
|
||||||
|
@ -574,7 +621,6 @@ bool OpenGLSWFrameBuffer::LoadShaders()
|
||||||
{
|
{
|
||||||
SafeRelease(Shaders[i]);
|
SafeRelease(Shaders[i]);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -590,7 +636,6 @@ void OpenGLSWFrameBuffer::ReleaseResources()
|
||||||
KillNativeTexs();
|
KillNativeTexs();
|
||||||
KillNativePals();
|
KillNativePals();
|
||||||
ReleaseDefaultPoolItems();
|
ReleaseDefaultPoolItems();
|
||||||
SafeRelease(ScreenshotSurface);
|
|
||||||
SafeRelease(ScreenshotTexture);
|
SafeRelease(ScreenshotTexture);
|
||||||
SafeRelease(PaletteTexture);
|
SafeRelease(PaletteTexture);
|
||||||
for (int i = 0; i < NUM_SHADERS; ++i)
|
for (int i = 0; i < NUM_SHADERS; ++i)
|
||||||
|
@ -616,14 +661,9 @@ void OpenGLSWFrameBuffer::ReleaseDefaultPoolItems()
|
||||||
{
|
{
|
||||||
SafeRelease(FBTexture);
|
SafeRelease(FBTexture);
|
||||||
SafeRelease(FinalWipeScreen);
|
SafeRelease(FinalWipeScreen);
|
||||||
SafeRelease(RenderTexture[0]);
|
|
||||||
SafeRelease(RenderTexture[1]);
|
|
||||||
SafeRelease(InitialWipeScreen);
|
SafeRelease(InitialWipeScreen);
|
||||||
SafeRelease(VertexBuffer);
|
SafeRelease(VertexBuffer);
|
||||||
SafeRelease(IndexBuffer);
|
SafeRelease(IndexBuffer);
|
||||||
SafeRelease(BlockSurface[0]);
|
|
||||||
SafeRelease(BlockSurface[1]);
|
|
||||||
SafeRelease(FrontCopySurface);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool OpenGLSWFrameBuffer::Reset()
|
bool OpenGLSWFrameBuffer::Reset()
|
||||||
|
@ -633,32 +673,10 @@ bool OpenGLSWFrameBuffer::Reset()
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
CreateBlockSurfaces();
|
|
||||||
SetInitialState();
|
SetInitialState();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
//==========================================================================
|
|
||||||
//
|
|
||||||
// OpenGLSWFrameBuffer :: CreateBlockSurfaces
|
|
||||||
//
|
|
||||||
// Create blocking surfaces for antilag. It's okay if these can't be
|
|
||||||
// created; antilag just won't work.
|
|
||||||
//
|
|
||||||
//==========================================================================
|
|
||||||
|
|
||||||
void OpenGLSWFrameBuffer::CreateBlockSurfaces()
|
|
||||||
{
|
|
||||||
BlockNum = 0;
|
|
||||||
if (CreateOffscreenPlainSurface(16, 16, GL_RGBA8, &BlockSurface[0]))
|
|
||||||
{
|
|
||||||
if (!CreateOffscreenPlainSurface(16, 16, GL_RGBA8, &BlockSurface[1]))
|
|
||||||
{
|
|
||||||
SafeRelease(BlockSurface[0]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
//
|
//
|
||||||
// OpenGLSWFrameBuffer :: KillNativePals
|
// OpenGLSWFrameBuffer :: KillNativePals
|
||||||
|
@ -691,80 +709,11 @@ void OpenGLSWFrameBuffer::KillNativeTexs()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//==========================================================================
|
|
||||||
//
|
|
||||||
// OpenGLSWFrameBuffer :: CreateFBTexture
|
|
||||||
//
|
|
||||||
// Creates the "Framebuffer" texture. With the advent of hardware-assisted
|
|
||||||
// 2D, this is something of a misnomer now. The FBTexture is only used for
|
|
||||||
// uploading the software 3D image to video memory so that it can be drawn
|
|
||||||
// to the real frame buffer.
|
|
||||||
//
|
|
||||||
// It also creates the TempRenderTexture, since this seemed like a
|
|
||||||
// convenient place to do so.
|
|
||||||
//
|
|
||||||
//==========================================================================
|
|
||||||
|
|
||||||
bool OpenGLSWFrameBuffer::CreateFBTexture()
|
bool OpenGLSWFrameBuffer::CreateFBTexture()
|
||||||
{
|
{
|
||||||
if (!CreateTexture(Width, Height, 1, GL_R8, &FBTexture))
|
CreateTexture(Width, Height, 1, GL_R8, &FBTexture);
|
||||||
{
|
|
||||||
int pow2width, pow2height, i;
|
|
||||||
|
|
||||||
for (i = 1; i < Width; i <<= 1) {} pow2width = i;
|
|
||||||
for (i = 1; i < Height; i <<= 1) {} pow2height = i;
|
|
||||||
|
|
||||||
if (!CreateTexture(pow2width, pow2height, 1, GL_R8, &FBTexture))
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
FBWidth = pow2width;
|
|
||||||
FBHeight = pow2height;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
FBWidth = Width;
|
FBWidth = Width;
|
||||||
FBHeight = Height;
|
FBHeight = Height;
|
||||||
}
|
|
||||||
RenderTextureToggle = 0;
|
|
||||||
RenderTexture[0] = nullptr;
|
|
||||||
RenderTexture[1] = nullptr;
|
|
||||||
if (!CreateTexture(FBWidth, FBHeight, 1, GL_RGBA8, &RenderTexture[0]))
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (Windowed || PixelDoubling)
|
|
||||||
{
|
|
||||||
// Windowed or pixel doubling: Create another render texture so we can flip between them.
|
|
||||||
RenderTextureToggle = 1;
|
|
||||||
if (!CreateTexture(FBWidth, FBHeight, 1, GL_RGBA8, &RenderTexture[1]))
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// Fullscreen and not pixel doubling: Create a render target to have the back buffer copied to.
|
|
||||||
if (!CreateRenderTarget(Width, Height, GL_RGBA8, &FrontCopySurface))
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// Initialize the TempRenderTextures to black.
|
|
||||||
for (int i = 0; i <= RenderTextureToggle; ++i)
|
|
||||||
{
|
|
||||||
HWSurface *surf;
|
|
||||||
if (RenderTexture[i]->GetSurfaceLevel(0, &surf))
|
|
||||||
{
|
|
||||||
ColorFill(surf, 0.0f, 0.0f, 0.0f);
|
|
||||||
delete surf;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
TempRenderTexture = RenderTexture[0];
|
|
||||||
CurrRenderTexture = 0;
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -814,7 +763,7 @@ bool OpenGLSWFrameBuffer::CreateVertexes()
|
||||||
|
|
||||||
void OpenGLSWFrameBuffer::CalcFullscreenCoords(FBVERTEX verts[4], bool viewarea_only, bool can_double, uint32_t color0, uint32_t color1) const
|
void OpenGLSWFrameBuffer::CalcFullscreenCoords(FBVERTEX verts[4], bool viewarea_only, bool can_double, uint32_t color0, uint32_t color1) const
|
||||||
{
|
{
|
||||||
float offset = OldRenderTarget != nullptr ? 0 : LBOffset;
|
float offset = LBOffset;//OldRenderTarget != nullptr ? 0 : LBOffset;
|
||||||
float top = offset - 0.5f;
|
float top = offset - 0.5f;
|
||||||
float texright = float(Width) / float(FBWidth);
|
float texright = float(Width) / float(FBWidth);
|
||||||
float texbot = float(Height) / float(FBHeight);
|
float texbot = float(Height) / float(FBHeight);
|
||||||
|
@ -1042,18 +991,6 @@ void OpenGLSWFrameBuffer::Update()
|
||||||
LOG("SetGammaRamp\n");
|
LOG("SetGammaRamp\n");
|
||||||
SetGammaRamp(&ramp);
|
SetGammaRamp(&ramp);
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
if (igamma != 1)
|
|
||||||
{
|
|
||||||
UpdateGammaTexture(igamma);
|
|
||||||
GammaShader = Shaders[SHADER_GammaCorrection];
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
GammaShader = nullptr;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
psgamma[2] = psgamma[1] = psgamma[0] = igamma;
|
psgamma[2] = psgamma[1] = psgamma[0] = igamma;
|
||||||
psgamma[3] = 0.5; // For SM14 version
|
psgamma[3] = 0.5; // For SM14 version
|
||||||
SetPixelShaderConstantF(PSCONST_Gamma, psgamma, 1);
|
SetPixelShaderConstantF(PSCONST_Gamma, psgamma, 1);
|
||||||
|
@ -1094,21 +1031,6 @@ void OpenGLSWFrameBuffer::Flip()
|
||||||
DrawLetterbox();
|
DrawLetterbox();
|
||||||
DoWindowedGamma();
|
DoWindowedGamma();
|
||||||
|
|
||||||
CopyNextFrontBuffer();
|
|
||||||
|
|
||||||
// Attempt to counter input lag.
|
|
||||||
if (gl_antilag && BlockSurface[0] != nullptr)
|
|
||||||
{
|
|
||||||
LockedRect lr;
|
|
||||||
volatile int dummy;
|
|
||||||
ColorFill(BlockSurface[BlockNum], 0.0f, 0x20/255.0f, 0x50/255.0f);
|
|
||||||
BlockNum ^= 1;
|
|
||||||
if (BlockSurface[BlockNum]->LockRect(&lr, nullptr, false))
|
|
||||||
{
|
|
||||||
dummy = *(int *)lr.pBits;
|
|
||||||
BlockSurface[BlockNum]->UnlockRect();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// Limiting the frame rate is as simple as waiting for the timer to signal this event.
|
// Limiting the frame rate is as simple as waiting for the timer to signal this event.
|
||||||
if (FPSLimitEvent != nullptr)
|
if (FPSLimitEvent != nullptr)
|
||||||
{
|
{
|
||||||
|
@ -1117,13 +1039,6 @@ void OpenGLSWFrameBuffer::Flip()
|
||||||
Present();
|
Present();
|
||||||
InScene = false;
|
InScene = false;
|
||||||
|
|
||||||
if (RenderTextureToggle)
|
|
||||||
{
|
|
||||||
// Flip the TempRenderTexture to the other one now.
|
|
||||||
CurrRenderTexture ^= RenderTextureToggle;
|
|
||||||
TempRenderTexture = RenderTexture[CurrRenderTexture];
|
|
||||||
}
|
|
||||||
|
|
||||||
if (Windowed)
|
if (Windowed)
|
||||||
{
|
{
|
||||||
int clientWidth = GetClientWidth();
|
int clientWidth = GetClientWidth();
|
||||||
|
@ -1143,42 +1058,6 @@ void OpenGLSWFrameBuffer::Flip()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//==========================================================================
|
|
||||||
//
|
|
||||||
// OpenGLSWFrameBuffer :: CopyNextFrontBuffer
|
|
||||||
//
|
|
||||||
// Duplicates the contents of the back buffer that will become the front
|
|
||||||
// buffer upon Present into FrontCopySurface so that we can get the
|
|
||||||
// contents of the display without wasting time in GetFrontBufferData().
|
|
||||||
//
|
|
||||||
//==========================================================================
|
|
||||||
|
|
||||||
void OpenGLSWFrameBuffer::CopyNextFrontBuffer()
|
|
||||||
{
|
|
||||||
HWSurface *backbuff;
|
|
||||||
|
|
||||||
if (Windowed || PixelDoubling)
|
|
||||||
{
|
|
||||||
// Windowed mode or pixel doubling: TempRenderTexture has what we want
|
|
||||||
SafeRelease(FrontCopySurface);
|
|
||||||
if (TempRenderTexture->GetSurfaceLevel(0, &backbuff))
|
|
||||||
{
|
|
||||||
FrontCopySurface = backbuff;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// Fullscreen, not pixel doubled: The back buffer has what we want,
|
|
||||||
// but it might be letter boxed.
|
|
||||||
if (GetBackBuffer(&backbuff))
|
|
||||||
{
|
|
||||||
LTRBRect srcrect = { 0, LBOffsetI, Width, LBOffsetI + Height };
|
|
||||||
StretchRect(backbuff, &srcrect, FrontCopySurface);
|
|
||||||
delete backbuff;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
//
|
//
|
||||||
// OpenGLSWFrameBuffer :: PaintToWindow
|
// OpenGLSWFrameBuffer :: PaintToWindow
|
||||||
|
@ -1207,50 +1086,49 @@ void OpenGLSWFrameBuffer::Draw3DPart(bool copy3d)
|
||||||
{
|
{
|
||||||
if (copy3d)
|
if (copy3d)
|
||||||
{
|
{
|
||||||
LTRBRect texrect = { 0, 0, Width, Height };
|
if (FBTexture->Buffer == 0)
|
||||||
LockedRect lockrect;
|
|
||||||
|
|
||||||
if ((FBWidth == Width && FBHeight == Height &&
|
|
||||||
FBTexture->LockRect(&lockrect, nullptr, true)) ||
|
|
||||||
FBTexture->LockRect(&lockrect, &texrect, false))
|
|
||||||
{
|
{
|
||||||
if (lockrect.Pitch == Pitch && Pitch == Width)
|
glGenBuffers(1, (GLuint*)&FBTexture->Buffer);
|
||||||
{
|
glBindBuffer(GL_PIXEL_UNPACK_BUFFER, FBTexture->Buffer);
|
||||||
memcpy(lockrect.pBits, MemBuffer, Width * Height);
|
glBufferData(GL_PIXEL_UNPACK_BUFFER, Width * Height, nullptr, GL_STREAM_DRAW);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
glBindBuffer(GL_PIXEL_UNPACK_BUFFER, FBTexture->Buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t *dest = (uint8_t*)glMapBuffer(GL_PIXEL_UNPACK_BUFFER, GL_WRITE_ONLY);
|
||||||
|
if (dest)
|
||||||
|
{
|
||||||
|
if (Pitch == Width)
|
||||||
|
{
|
||||||
|
memcpy(dest, MemBuffer, Width * Height);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
uint8_t *dest = (uint8_t *)lockrect.pBits;
|
|
||||||
uint8_t *src = MemBuffer;
|
uint8_t *src = MemBuffer;
|
||||||
for (int y = 0; y < Height; y++)
|
for (int y = 0; y < Height; y++)
|
||||||
{
|
{
|
||||||
memcpy(dest, src, Width);
|
memcpy(dest, src, Width);
|
||||||
dest += lockrect.Pitch;
|
dest += Width;
|
||||||
src += Pitch;
|
src += Pitch;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
FBTexture->UnlockRect();
|
glUnmapBuffer(GL_PIXEL_UNPACK_BUFFER);
|
||||||
|
GLint oldBinding = 0;
|
||||||
|
glGetIntegerv(GL_TEXTURE_BINDING_2D, &oldBinding);
|
||||||
|
glBindTexture(GL_TEXTURE_2D, FBTexture->Texture);
|
||||||
|
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, Width, Height, GL_R8, GL_UNSIGNED_BYTE, 0);
|
||||||
|
glBindTexture(GL_TEXTURE_2D, oldBinding);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
|
||||||
}
|
}
|
||||||
InScene = true;
|
InScene = true;
|
||||||
if (vid_hwaalines)
|
if (vid_hwaalines)
|
||||||
glEnable(GL_LINE_SMOOTH);
|
glEnable(GL_LINE_SMOOTH);
|
||||||
else
|
else
|
||||||
glDisable(GL_LINE_SMOOTH);
|
glDisable(GL_LINE_SMOOTH);
|
||||||
assert(OldRenderTarget == nullptr);
|
|
||||||
if (TempRenderTexture != nullptr &&
|
|
||||||
((Windowed && TempRenderTexture != FinalWipeScreen) || GatheringWipeScreen || PixelDoubling))
|
|
||||||
{
|
|
||||||
HWSurface *targetsurf;
|
|
||||||
if (TempRenderTexture->GetSurfaceLevel(0, &targetsurf))
|
|
||||||
{
|
|
||||||
if (GetRenderTarget(0, &OldRenderTarget))
|
|
||||||
{
|
|
||||||
SetRenderTarget(0, targetsurf);
|
|
||||||
}
|
|
||||||
delete targetsurf;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
SetTexture(0, FBTexture);
|
SetTexture(0, FBTexture);
|
||||||
SetPaletteTexture(PaletteTexture, 256, BorderColor);
|
SetPaletteTexture(PaletteTexture, 256, BorderColor);
|
||||||
|
@ -1271,10 +1149,8 @@ void OpenGLSWFrameBuffer::Draw3DPart(bool copy3d)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
color0 = ColorValue(realfixedcolormap->ColorizeStart[0] / 2,
|
color0 = ColorValue(realfixedcolormap->ColorizeStart[0] / 2, realfixedcolormap->ColorizeStart[1] / 2, realfixedcolormap->ColorizeStart[2] / 2, 0);
|
||||||
realfixedcolormap->ColorizeStart[1] / 2, realfixedcolormap->ColorizeStart[2] / 2, 0);
|
color1 = ColorValue(realfixedcolormap->ColorizeEnd[0] / 2, realfixedcolormap->ColorizeEnd[1] / 2, realfixedcolormap->ColorizeEnd[2] / 2, 1);
|
||||||
color1 = ColorValue(realfixedcolormap->ColorizeEnd[0] / 2,
|
|
||||||
realfixedcolormap->ColorizeEnd[1] / 2, realfixedcolormap->ColorizeEnd[2] / 2, 1);
|
|
||||||
SetPixelShader(Shaders[SHADER_SpecialColormapPal]);
|
SetPixelShader(Shaders[SHADER_SpecialColormapPal]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1323,7 +1199,7 @@ void OpenGLSWFrameBuffer::DrawLetterbox()
|
||||||
|
|
||||||
void OpenGLSWFrameBuffer::DoWindowedGamma()
|
void OpenGLSWFrameBuffer::DoWindowedGamma()
|
||||||
{
|
{
|
||||||
if (OldRenderTarget != nullptr)
|
/*if (OldRenderTarget != nullptr)
|
||||||
{
|
{
|
||||||
FBVERTEX verts[4];
|
FBVERTEX verts[4];
|
||||||
|
|
||||||
|
@ -1336,49 +1212,28 @@ void OpenGLSWFrameBuffer::DoWindowedGamma()
|
||||||
DrawTriangleFans(2, verts);
|
DrawTriangleFans(2, verts);
|
||||||
delete OldRenderTarget;
|
delete OldRenderTarget;
|
||||||
OldRenderTarget = nullptr;
|
OldRenderTarget = nullptr;
|
||||||
}
|
}*/
|
||||||
}
|
|
||||||
|
|
||||||
//==========================================================================
|
|
||||||
//
|
|
||||||
// OpenGLSWFrameBuffer :: UpdateGammaTexture
|
|
||||||
//
|
|
||||||
// Updates the gamma texture used by the PS14 shader. We only use the first
|
|
||||||
// half of the texture so that we needn't worry about imprecision causing
|
|
||||||
// it to grab from the border.
|
|
||||||
//
|
|
||||||
//==========================================================================
|
|
||||||
|
|
||||||
void OpenGLSWFrameBuffer::UpdateGammaTexture(float igamma)
|
|
||||||
{
|
|
||||||
LockedRect lockrect;
|
|
||||||
|
|
||||||
if (GammaTexture != nullptr && GammaTexture->LockRect(&lockrect, nullptr, false))
|
|
||||||
{
|
|
||||||
uint8_t *pix = (uint8_t *)lockrect.pBits;
|
|
||||||
for (int i = 0; i <= 128; ++i)
|
|
||||||
{
|
|
||||||
pix[i * 4 + 2] = pix[i * 4 + 1] = pix[i * 4] = uint8_t(255.f * powf(i / 128.f, igamma));
|
|
||||||
pix[i * 4 + 3] = 255;
|
|
||||||
}
|
|
||||||
GammaTexture->UnlockRect();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void OpenGLSWFrameBuffer::UploadPalette()
|
void OpenGLSWFrameBuffer::UploadPalette()
|
||||||
{
|
{
|
||||||
LockedRect lockrect;
|
if (PaletteTexture->Buffer == 0)
|
||||||
|
|
||||||
if (SkipAt < 0)
|
|
||||||
{
|
{
|
||||||
SkipAt = 256;
|
glGenBuffers(1, (GLuint*)&PaletteTexture->Buffer);
|
||||||
|
glBindBuffer(GL_PIXEL_UNPACK_BUFFER, PaletteTexture->Buffer);
|
||||||
|
glBufferData(GL_PIXEL_UNPACK_BUFFER, 256 * 4, nullptr, GL_STREAM_DRAW);
|
||||||
}
|
}
|
||||||
if (PaletteTexture->LockRect(&lockrect, nullptr, false))
|
else
|
||||||
|
{
|
||||||
|
glBindBuffer(GL_PIXEL_UNPACK_BUFFER, PaletteTexture->Buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t *pix = (uint8_t *)glMapBuffer(GL_PIXEL_UNPACK_BUFFER, GL_WRITE_ONLY);
|
||||||
|
if (pix)
|
||||||
{
|
{
|
||||||
uint8_t *pix = (uint8_t *)lockrect.pBits;
|
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
for (i = 0; i < SkipAt; ++i, pix += 4)
|
for (i = 0; i < 256; ++i, pix += 4)
|
||||||
{
|
{
|
||||||
pix[0] = SourcePalette[i].b;
|
pix[0] = SourcePalette[i].b;
|
||||||
pix[1] = SourcePalette[i].g;
|
pix[1] = SourcePalette[i].g;
|
||||||
|
@ -1394,9 +1249,16 @@ void OpenGLSWFrameBuffer::UploadPalette()
|
||||||
pix[2] = SourcePalette[i].r;
|
pix[2] = SourcePalette[i].r;
|
||||||
pix[3] = 255;
|
pix[3] = 255;
|
||||||
}
|
}
|
||||||
PaletteTexture->UnlockRect();
|
glUnmapBuffer(GL_PIXEL_UNPACK_BUFFER);
|
||||||
|
GLint oldBinding = 0;
|
||||||
|
glGetIntegerv(GL_TEXTURE_BINDING_2D, &oldBinding);
|
||||||
|
glBindTexture(GL_TEXTURE_2D, PaletteTexture->Texture);
|
||||||
|
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 256, 1, GL_BGRA, GL_UNSIGNED_BYTE, 0);
|
||||||
|
glBindTexture(GL_TEXTURE_2D, oldBinding);
|
||||||
BorderColor = ColorXRGB(SourcePalette[255].r, SourcePalette[255].g, SourcePalette[255].b);
|
BorderColor = ColorXRGB(SourcePalette[255].r, SourcePalette[255].g, SourcePalette[255].b);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
PalEntry *OpenGLSWFrameBuffer::GetPalette()
|
PalEntry *OpenGLSWFrameBuffer::GetPalette()
|
||||||
|
@ -1484,6 +1346,8 @@ void OpenGLSWFrameBuffer::SetBlendingRect(int x1, int y1, int x2, int y2)
|
||||||
|
|
||||||
void OpenGLSWFrameBuffer::GetScreenshotBuffer(const uint8_t *&buffer, int &pitch, ESSType &color_type)
|
void OpenGLSWFrameBuffer::GetScreenshotBuffer(const uint8_t *&buffer, int &pitch, ESSType &color_type)
|
||||||
{
|
{
|
||||||
|
Super::GetScreenshotBuffer(buffer, pitch, color_type);
|
||||||
|
/*
|
||||||
LockedRect lrect;
|
LockedRect lrect;
|
||||||
|
|
||||||
if (!Accel2D)
|
if (!Accel2D)
|
||||||
|
@ -1513,6 +1377,7 @@ void OpenGLSWFrameBuffer::GetScreenshotBuffer(const uint8_t *&buffer, int &pitch
|
||||||
color_type = SS_BGRA;
|
color_type = SS_BGRA;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
|
@ -1527,58 +1392,9 @@ void OpenGLSWFrameBuffer::ReleaseScreenshotBuffer()
|
||||||
{
|
{
|
||||||
Super::ReleaseScreenshotBuffer();
|
Super::ReleaseScreenshotBuffer();
|
||||||
}
|
}
|
||||||
if (ScreenshotSurface != nullptr)
|
|
||||||
{
|
|
||||||
ScreenshotSurface->UnlockRect();
|
|
||||||
delete ScreenshotSurface;
|
|
||||||
ScreenshotSurface = nullptr;
|
|
||||||
}
|
|
||||||
SafeRelease(ScreenshotTexture);
|
SafeRelease(ScreenshotTexture);
|
||||||
}
|
}
|
||||||
|
|
||||||
//==========================================================================
|
|
||||||
//
|
|
||||||
// OpenGLSWFrameBuffer :: GetCurrentScreen
|
|
||||||
//
|
|
||||||
// Returns a texture containing the pixels currently visible on-screen.
|
|
||||||
//
|
|
||||||
//==========================================================================
|
|
||||||
|
|
||||||
OpenGLSWFrameBuffer::HWTexture *OpenGLSWFrameBuffer::GetCurrentScreen()
|
|
||||||
{
|
|
||||||
HWTexture *tex;
|
|
||||||
HWSurface *surf;
|
|
||||||
bool hr;
|
|
||||||
|
|
||||||
if (FrontCopySurface == nullptr)
|
|
||||||
{
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
hr = CreateTexture(FBWidth, FBHeight, 1, GL_RGBA8, &tex);
|
|
||||||
|
|
||||||
if (!hr)
|
|
||||||
{
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
if (!tex->GetSurfaceLevel(0, &surf))
|
|
||||||
{
|
|
||||||
delete tex;
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Video -> System memory : use GetRenderTargetData
|
|
||||||
GetRenderTargetData(FrontCopySurface, surf);
|
|
||||||
delete surf;
|
|
||||||
|
|
||||||
if (!hr)
|
|
||||||
{
|
|
||||||
delete tex;
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
return tex;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**************************************************************************/
|
/**************************************************************************/
|
||||||
/* 2D Stuff */
|
/* 2D Stuff */
|
||||||
/**************************************************************************/
|
/**************************************************************************/
|
||||||
|
@ -2013,7 +1829,6 @@ bool OpenGLSWFrameBuffer::OpenGLTex::Create(OpenGLSWFrameBuffer *fb, bool wrappi
|
||||||
|
|
||||||
bool OpenGLSWFrameBuffer::OpenGLTex::Update()
|
bool OpenGLSWFrameBuffer::OpenGLTex::Update()
|
||||||
{
|
{
|
||||||
LockedRect lrect;
|
|
||||||
LTRBRect rect;
|
LTRBRect rect;
|
||||||
uint8_t *dest;
|
uint8_t *dest;
|
||||||
|
|
||||||
|
@ -2025,27 +1840,44 @@ bool OpenGLSWFrameBuffer::OpenGLTex::Update()
|
||||||
int format = Box->Owner->Tex->Format;
|
int format = Box->Owner->Tex->Format;
|
||||||
|
|
||||||
rect = Box->Area;
|
rect = Box->Area;
|
||||||
if (!Box->Owner->Tex->LockRect(&lrect, &rect, false))
|
|
||||||
|
if (Box->Owner->Tex->Buffer == 0)
|
||||||
|
glGenBuffers(1, (GLuint*)&Box->Owner->Tex->Buffer);
|
||||||
|
|
||||||
|
int bytesPerPixel = 4;
|
||||||
|
switch (format)
|
||||||
|
{
|
||||||
|
case GL_R8: bytesPerPixel = 1; break;
|
||||||
|
case GL_RGBA8: bytesPerPixel = 4; break;
|
||||||
|
default: return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
glBindBuffer(GL_PIXEL_UNPACK_BUFFER, Box->Owner->Tex->Buffer);
|
||||||
|
glBufferData(GL_PIXEL_UNPACK_BUFFER, (rect.right - rect.left) * (rect.bottom - rect.top) * bytesPerPixel, nullptr, GL_STREAM_DRAW);
|
||||||
|
|
||||||
|
int pitch = (rect.right - rect.left) * bytesPerPixel;
|
||||||
|
uint8_t *bits = (uint8_t *)glMapBuffer(GL_PIXEL_UNPACK_BUFFER, GL_WRITE_ONLY);
|
||||||
|
dest = bits;
|
||||||
|
if (!dest)
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
dest = (uint8_t *)lrect.pBits;
|
|
||||||
if (Box->Padded)
|
if (Box->Padded)
|
||||||
{
|
{
|
||||||
dest += lrect.Pitch + (format == GL_R8 ? 1 : 4);
|
dest += pitch + (format == GL_R8 ? 1 : 4);
|
||||||
}
|
}
|
||||||
GameTex->FillBuffer(dest, lrect.Pitch, GameTex->GetHeight(), ToTexFmt(format));
|
GameTex->FillBuffer(dest, pitch, GameTex->GetHeight(), ToTexFmt(format));
|
||||||
if (Box->Padded)
|
if (Box->Padded)
|
||||||
{
|
{
|
||||||
// Clear top padding row.
|
// Clear top padding row.
|
||||||
dest = (uint8_t *)lrect.pBits;
|
dest = bits;
|
||||||
int numbytes = GameTex->GetWidth() + 2;
|
int numbytes = GameTex->GetWidth() + 2;
|
||||||
if (format != GL_R8)
|
if (format != GL_R8)
|
||||||
{
|
{
|
||||||
numbytes <<= 2;
|
numbytes <<= 2;
|
||||||
}
|
}
|
||||||
memset(dest, 0, numbytes);
|
memset(dest, 0, numbytes);
|
||||||
dest += lrect.Pitch;
|
dest += pitch;
|
||||||
// Clear left and right padding columns.
|
// Clear left and right padding columns.
|
||||||
if (format == GL_R8)
|
if (format == GL_R8)
|
||||||
{
|
{
|
||||||
|
@ -2053,7 +1885,7 @@ bool OpenGLSWFrameBuffer::OpenGLTex::Update()
|
||||||
{
|
{
|
||||||
dest[0] = 0;
|
dest[0] = 0;
|
||||||
dest[numbytes - 1] = 0;
|
dest[numbytes - 1] = 0;
|
||||||
dest += lrect.Pitch;
|
dest += pitch;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -2062,13 +1894,20 @@ bool OpenGLSWFrameBuffer::OpenGLTex::Update()
|
||||||
{
|
{
|
||||||
*(uint32_t *)dest = 0;
|
*(uint32_t *)dest = 0;
|
||||||
*(uint32_t *)(dest + numbytes - 4) = 0;
|
*(uint32_t *)(dest + numbytes - 4) = 0;
|
||||||
dest += lrect.Pitch;
|
dest += pitch;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Clear bottom padding row.
|
// Clear bottom padding row.
|
||||||
memset(dest, 0, numbytes);
|
memset(dest, 0, numbytes);
|
||||||
}
|
}
|
||||||
Box->Owner->Tex->UnlockRect();
|
|
||||||
|
glUnmapBuffer(GL_PIXEL_UNPACK_BUFFER);
|
||||||
|
GLint oldBinding = 0;
|
||||||
|
glGetIntegerv(GL_TEXTURE_BINDING_2D, &oldBinding);
|
||||||
|
glBindTexture(GL_TEXTURE_2D, Box->Owner->Tex->Texture);
|
||||||
|
glTexSubImage2D(GL_TEXTURE_2D, 0, rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top, format == GL_RGBA8 ? GL_BGRA : GL_RED, GL_UNSIGNED_BYTE, 0);
|
||||||
|
glBindTexture(GL_TEXTURE_2D, oldBinding);
|
||||||
|
glBindTexture(GL_PIXEL_UNPACK_BUFFER, 0);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2199,18 +2038,28 @@ OpenGLSWFrameBuffer::OpenGLPal::~OpenGLPal()
|
||||||
|
|
||||||
bool OpenGLSWFrameBuffer::OpenGLPal::Update()
|
bool OpenGLSWFrameBuffer::OpenGLPal::Update()
|
||||||
{
|
{
|
||||||
LockedRect lrect;
|
|
||||||
uint32_t *buff;
|
uint32_t *buff;
|
||||||
const PalEntry *pal;
|
const PalEntry *pal;
|
||||||
int skipat, i;
|
int skipat, i;
|
||||||
|
|
||||||
assert(Tex != nullptr);
|
assert(Tex != nullptr);
|
||||||
|
|
||||||
if (!Tex->LockRect(&lrect, nullptr, 0))
|
if (Tex->Buffer == 0)
|
||||||
|
{
|
||||||
|
glGenBuffers(1, (GLuint*)&Tex->Buffer);
|
||||||
|
glBindBuffer(GL_PIXEL_UNPACK_BUFFER, Tex->Buffer);
|
||||||
|
glBufferData(GL_PIXEL_UNPACK_BUFFER, Remap->NumEntries * 4, nullptr, GL_STREAM_DRAW);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
glBindBuffer(GL_PIXEL_UNPACK_BUFFER, Tex->Buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
buff = (uint32_t *)glMapBuffer(GL_PIXEL_UNPACK_BUFFER, GL_WRITE_ONLY);
|
||||||
|
if (buff == nullptr)
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
buff = (uint32_t *)lrect.pBits;
|
|
||||||
pal = Remap->Palette;
|
pal = Remap->Palette;
|
||||||
|
|
||||||
// See explanation in UploadPalette() for skipat rationale.
|
// See explanation in UploadPalette() for skipat rationale.
|
||||||
|
@ -2226,7 +2075,14 @@ bool OpenGLSWFrameBuffer::OpenGLPal::Update()
|
||||||
}
|
}
|
||||||
BorderColor = ColorARGB(pal[i].a, pal[i - 1].r, pal[i - 1].g, pal[i - 1].b);
|
BorderColor = ColorARGB(pal[i].a, pal[i - 1].r, pal[i - 1].g, pal[i - 1].b);
|
||||||
|
|
||||||
Tex->UnlockRect();
|
glUnmapBuffer(GL_PIXEL_UNPACK_BUFFER);
|
||||||
|
GLint oldBinding = 0;
|
||||||
|
glGetIntegerv(GL_TEXTURE_BINDING_2D, &oldBinding);
|
||||||
|
glBindTexture(GL_TEXTURE_2D, Tex->Texture);
|
||||||
|
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, Remap->NumEntries, 1, GL_BGRA, GL_UNSIGNED_BYTE, 0);
|
||||||
|
glBindTexture(GL_TEXTURE_2D, oldBinding);
|
||||||
|
glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -85,32 +85,18 @@ private:
|
||||||
uint16_t red[256], green[256], blue[256];
|
uint16_t red[256], green[256], blue[256];
|
||||||
};
|
};
|
||||||
|
|
||||||
struct LockedRect
|
|
||||||
{
|
|
||||||
int Pitch;
|
|
||||||
void *pBits;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct LTRBRect
|
struct LTRBRect
|
||||||
{
|
{
|
||||||
int left, top, right, bottom;
|
int left, top, right, bottom;
|
||||||
};
|
};
|
||||||
|
|
||||||
class HWSurface
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
bool LockRect(LockedRect *outRect, LTRBRect *srcRect, bool discard) { outRect->Pitch = 0; outRect->pBits = nullptr; return false; }
|
|
||||||
void UnlockRect() { }
|
|
||||||
};
|
|
||||||
|
|
||||||
class HWTexture
|
class HWTexture
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
bool LockRect(LockedRect *outRect, LTRBRect *srcRect, bool discard) { outRect->Pitch = 0; outRect->pBits = nullptr; return false; }
|
~HWTexture();
|
||||||
void UnlockRect() { }
|
|
||||||
bool GetSurfaceLevel(int level, HWSurface **outSurface) { *outSurface = nullptr; return false; }
|
|
||||||
|
|
||||||
int Texture = 0;
|
int Texture = 0;
|
||||||
|
int Buffer = 0;
|
||||||
int WrapS = 0;
|
int WrapS = 0;
|
||||||
int WrapT = 0;
|
int WrapT = 0;
|
||||||
int Format = 0;
|
int Format = 0;
|
||||||
|
@ -119,60 +105,43 @@ private:
|
||||||
class HWVertexBuffer
|
class HWVertexBuffer
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
~HWVertexBuffer()
|
~HWVertexBuffer();
|
||||||
{
|
|
||||||
if (Buffer != 0) glDeleteVertexArrays(1, (GLuint*)&VertexArray);
|
|
||||||
if (Buffer != 0) glDeleteBuffers(1, (GLuint*)&Buffer);
|
|
||||||
}
|
|
||||||
|
|
||||||
FBVERTEX *Lock() { return nullptr; }
|
FBVERTEX *Lock();
|
||||||
void Unlock() { }
|
void Unlock();
|
||||||
|
|
||||||
int Buffer = 0;
|
|
||||||
int VertexArray = 0;
|
int VertexArray = 0;
|
||||||
|
int Buffer = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
class HWIndexBuffer
|
class HWIndexBuffer
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
~HWIndexBuffer()
|
~HWIndexBuffer();
|
||||||
{
|
|
||||||
if (Buffer != 0) glDeleteBuffers(1, (GLuint*)&Buffer);
|
|
||||||
}
|
|
||||||
|
|
||||||
uint16_t *Lock() { return nullptr; }
|
uint16_t *Lock();
|
||||||
void Unlock() { }
|
void Unlock();
|
||||||
|
|
||||||
int Buffer = 0;
|
int Buffer = 0;
|
||||||
|
|
||||||
|
private:
|
||||||
|
int LockedOldBinding = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
class HWPixelShader
|
class HWPixelShader
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
~HWPixelShader()
|
~HWPixelShader();
|
||||||
{
|
|
||||||
if (Program != 0) glDeleteProgram(Program);
|
|
||||||
if (VertexShader != 0) glDeleteShader(VertexShader);
|
|
||||||
if (FragmentShader != 0) glDeleteShader(FragmentShader);
|
|
||||||
}
|
|
||||||
|
|
||||||
int Program = 0;
|
int Program = 0;
|
||||||
int VertexShader = 0;
|
int VertexShader = 0;
|
||||||
int FragmentShader = 0;
|
int FragmentShader = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
bool CreatePixelShader(const void *vertexsrc, const void *fragmentsrc, HWPixelShader **outShader);
|
bool CreatePixelShader(FString vertexsrc, FString fragmentsrc, const FString &defines, HWPixelShader **outShader);
|
||||||
bool CreateVertexBuffer(int size, HWVertexBuffer **outVertexBuffer);
|
bool CreateVertexBuffer(int size, HWVertexBuffer **outVertexBuffer);
|
||||||
bool CreateIndexBuffer(int size, HWIndexBuffer **outIndexBuffer);
|
bool CreateIndexBuffer(int size, HWIndexBuffer **outIndexBuffer);
|
||||||
bool CreateOffscreenPlainSurface(int width, int height, int format, HWSurface **outSurface);
|
|
||||||
bool CreateTexture(int width, int height, int levels, int format, HWTexture **outTexture);
|
bool CreateTexture(int width, int height, int levels, int format, HWTexture **outTexture);
|
||||||
bool CreateRenderTarget(int width, int height, int format, HWSurface **outSurface);
|
|
||||||
bool GetBackBuffer(HWSurface **outSurface);
|
|
||||||
bool GetRenderTarget(int index, HWSurface **outSurface);
|
|
||||||
void GetRenderTargetData(HWSurface *a, HWSurface *b);
|
|
||||||
void ColorFill(HWSurface *surface, float red, float green, float blue);
|
|
||||||
void StretchRect(HWSurface *src, const LTRBRect *srcrect, HWSurface *dest);
|
|
||||||
bool SetRenderTarget(int index, HWSurface *surface);
|
|
||||||
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);
|
||||||
|
@ -362,19 +331,17 @@ private:
|
||||||
|
|
||||||
NUM_SHADERS
|
NUM_SHADERS
|
||||||
};
|
};
|
||||||
static const char *const ShaderNames[NUM_SHADERS];
|
static const char *const ShaderDefines[NUM_SHADERS];
|
||||||
|
|
||||||
void Flip();
|
void Flip();
|
||||||
void SetInitialState();
|
void SetInitialState();
|
||||||
bool CreateResources();
|
bool CreateResources();
|
||||||
void ReleaseResources();
|
void ReleaseResources();
|
||||||
bool LoadShaders();
|
bool LoadShaders();
|
||||||
void CreateBlockSurfaces();
|
|
||||||
bool CreateFBTexture();
|
bool CreateFBTexture();
|
||||||
bool CreatePaletteTexture();
|
bool CreatePaletteTexture();
|
||||||
bool CreateVertexes();
|
bool CreateVertexes();
|
||||||
void UploadPalette();
|
void UploadPalette();
|
||||||
void UpdateGammaTexture(float igamma);
|
|
||||||
void CalcFullscreenCoords(FBVERTEX verts[4], bool viewarea_only, bool can_double, uint32_t color0, uint32_t color1) const;
|
void CalcFullscreenCoords(FBVERTEX verts[4], bool viewarea_only, bool can_double, uint32_t color0, uint32_t color1) const;
|
||||||
bool Reset();
|
bool Reset();
|
||||||
HWTexture *GetCurrentScreen();
|
HWTexture *GetCurrentScreen();
|
||||||
|
@ -397,7 +364,6 @@ private:
|
||||||
void BeginLineBatch();
|
void BeginLineBatch();
|
||||||
void EndLineBatch();
|
void EndLineBatch();
|
||||||
void EndBatch();
|
void EndBatch();
|
||||||
void CopyNextFrontBuffer();
|
|
||||||
|
|
||||||
// State
|
// State
|
||||||
void EnableAlphaTest(BOOL enabled);
|
void EnableAlphaTest(BOOL enabled);
|
||||||
|
@ -431,10 +397,7 @@ private:
|
||||||
int FlashAmount;
|
int FlashAmount;
|
||||||
int TrueHeight;
|
int TrueHeight;
|
||||||
int PixelDoubling;
|
int PixelDoubling;
|
||||||
int SkipAt;
|
|
||||||
int LBOffsetI;
|
int LBOffsetI;
|
||||||
int RenderTextureToggle;
|
|
||||||
int CurrRenderTexture;
|
|
||||||
float LBOffset;
|
float LBOffset;
|
||||||
float Gamma;
|
float Gamma;
|
||||||
bool UpdatePending;
|
bool UpdatePending;
|
||||||
|
@ -448,34 +411,28 @@ private:
|
||||||
bool GatheringWipeScreen;
|
bool GatheringWipeScreen;
|
||||||
bool AALines;
|
bool AALines;
|
||||||
uint8_t BlockNum;
|
uint8_t BlockNum;
|
||||||
OpenGLPal *Palettes;
|
OpenGLPal *Palettes = nullptr;
|
||||||
OpenGLTex *Textures;
|
OpenGLTex *Textures = nullptr;
|
||||||
Atlas *Atlases;
|
Atlas *Atlases = nullptr;
|
||||||
|
|
||||||
HWTexture *FBTexture;
|
HWTexture *FBTexture = nullptr;
|
||||||
HWTexture *TempRenderTexture, *RenderTexture[2];
|
HWTexture *PaletteTexture = nullptr;
|
||||||
HWTexture *PaletteTexture;
|
HWTexture *ScreenshotTexture = nullptr;
|
||||||
HWTexture *GammaTexture;
|
|
||||||
HWTexture *ScreenshotTexture;
|
|
||||||
HWSurface *ScreenshotSurface;
|
|
||||||
HWSurface *FrontCopySurface;
|
|
||||||
|
|
||||||
HWVertexBuffer *VertexBuffer;
|
HWVertexBuffer *VertexBuffer = nullptr;
|
||||||
FBVERTEX *VertexData;
|
FBVERTEX *VertexData = nullptr;
|
||||||
HWIndexBuffer *IndexBuffer;
|
HWIndexBuffer *IndexBuffer = nullptr;
|
||||||
uint16_t *IndexData;
|
uint16_t *IndexData = nullptr;
|
||||||
BufferedTris *QuadExtra;
|
BufferedTris *QuadExtra = nullptr;
|
||||||
int VertexPos;
|
int VertexPos;
|
||||||
int IndexPos;
|
int IndexPos;
|
||||||
int QuadBatchPos;
|
int QuadBatchPos;
|
||||||
enum { BATCH_None, BATCH_Quads, BATCH_Lines } BatchType;
|
enum { BATCH_None, BATCH_Quads, BATCH_Lines } BatchType;
|
||||||
|
|
||||||
HWPixelShader *Shaders[NUM_SHADERS];
|
HWPixelShader *Shaders[NUM_SHADERS];
|
||||||
HWPixelShader *GammaShader;
|
HWPixelShader *GammaShader = nullptr;
|
||||||
|
|
||||||
HWSurface *BlockSurface[2];
|
HWTexture *InitialWipeScreen = nullptr, *FinalWipeScreen = nullptr;
|
||||||
HWSurface *OldRenderTarget;
|
|
||||||
HWTexture *InitialWipeScreen, *FinalWipeScreen;
|
|
||||||
|
|
||||||
class Wiper
|
class Wiper
|
||||||
{
|
{
|
||||||
|
|
|
@ -137,8 +137,9 @@ void I_InitGraphics ()
|
||||||
ticker.SetGenericRepDefault (val, CVAR_Bool);
|
ticker.SetGenericRepDefault (val, CVAR_Bool);
|
||||||
|
|
||||||
//currentrenderer = vid_renderer;
|
//currentrenderer = vid_renderer;
|
||||||
if (currentrenderer==1) Video = gl_CreateVideo();
|
Video = gl_CreateVideo();
|
||||||
else Video = new Win32Video (0);
|
//if (currentrenderer==1) Video = gl_CreateVideo();
|
||||||
|
//else Video = new Win32Video (0);
|
||||||
|
|
||||||
if (Video == NULL)
|
if (Video == NULL)
|
||||||
I_FatalError ("Failed to initialize display");
|
I_FatalError ("Failed to initialize display");
|
||||||
|
|
|
@ -25,6 +25,7 @@
|
||||||
|
|
||||||
#include "gl/renderer/gl_renderer.h"
|
#include "gl/renderer/gl_renderer.h"
|
||||||
#include "gl/system/gl_framebuffer.h"
|
#include "gl/system/gl_framebuffer.h"
|
||||||
|
#include "gl/system/gl_swframebuffer.h"
|
||||||
|
|
||||||
extern "C" {
|
extern "C" {
|
||||||
_declspec(dllexport) DWORD NvOptimusEnablement = 0x00000001;
|
_declspec(dllexport) DWORD NvOptimusEnablement = 0x00000001;
|
||||||
|
@ -386,7 +387,10 @@ DFrameBuffer *Win32GLVideo::CreateFrameBuffer(int width, int height, bool fs, DF
|
||||||
//old->GetFlash(flashColor, flashAmount);
|
//old->GetFlash(flashColor, flashAmount);
|
||||||
delete old;
|
delete old;
|
||||||
}
|
}
|
||||||
|
if (vid_renderer == 1)
|
||||||
fb = new OpenGLFrameBuffer(m_hMonitor, m_DisplayWidth, m_DisplayHeight, m_DisplayBits, m_DisplayHz, fs);
|
fb = new OpenGLFrameBuffer(m_hMonitor, m_DisplayWidth, m_DisplayHeight, m_DisplayBits, m_DisplayHz, fs);
|
||||||
|
else
|
||||||
|
fb = new OpenGLSWFrameBuffer(m_hMonitor, m_DisplayWidth, m_DisplayHeight, m_DisplayBits, m_DisplayHz, fs);
|
||||||
return fb;
|
return fb;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,146 @@
|
||||||
|
|
||||||
|
in vec4 PixelColor0;
|
||||||
|
in vec4 PixelColor1;
|
||||||
|
in vec4 PixelTexCoord0;
|
||||||
|
|
||||||
|
out vec4 FragColor;
|
||||||
|
|
||||||
|
uniform sampler2D Image;// : register(s0);
|
||||||
|
uniform sampler2D Palette;// : register(s1);
|
||||||
|
uniform sampler2D NewScreen;// : register(s0);
|
||||||
|
uniform sampler2D Burn;// : register(s1);
|
||||||
|
|
||||||
|
uniform vec4 Desaturation;// : register(c1); // { Desat, 1 - Desat }
|
||||||
|
uniform vec4 PaletteMod;// : register(c2);
|
||||||
|
uniform vec4 Weights;// : register(c6); // RGB->Gray weighting { 77/256.0, 143/256.0, 37/256.0, 1 }
|
||||||
|
uniform vec4 Gamma;// : register(c7);
|
||||||
|
|
||||||
|
vec4 TextureLookup(vec2 tex_coord)
|
||||||
|
{
|
||||||
|
#if PALTEX
|
||||||
|
float index = texture(Image, tex_coord).x;
|
||||||
|
index = index * PaletteMod.x + PaletteMod.y;
|
||||||
|
return texture(Palette, vec2(index, 0.5));
|
||||||
|
#else
|
||||||
|
return texture(Image, tex_coord);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
vec4 Invert(vec4 rgb)
|
||||||
|
{
|
||||||
|
#if INVERT
|
||||||
|
rgb.rgb = Weights.www - rgb.xyz;
|
||||||
|
#endif
|
||||||
|
return rgb;
|
||||||
|
}
|
||||||
|
|
||||||
|
float Grayscale(vec4 rgb)
|
||||||
|
{
|
||||||
|
return dot(rgb.rgb, Weights.rgb);
|
||||||
|
}
|
||||||
|
|
||||||
|
vec4 SampleTexture(vec2 tex_coord)
|
||||||
|
{
|
||||||
|
return Invert(TextureLookup(tex_coord));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Normal color calculation for most drawing modes.
|
||||||
|
|
||||||
|
vec4 NormalColor(vec2 tex_coord, vec4 Flash, vec4 InvFlash)
|
||||||
|
{
|
||||||
|
return Flash + SampleTexture(tex_coord) * InvFlash;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Copy the red channel to the alpha channel. Pays no attention to palettes.
|
||||||
|
|
||||||
|
vec4 RedToAlpha(vec2 tex_coord, vec4 Flash, vec4 InvFlash)
|
||||||
|
{
|
||||||
|
vec4 color = Invert(texture(Image, tex_coord));
|
||||||
|
color.a = color.r;
|
||||||
|
return Flash + color * InvFlash;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Just return the value of c0.
|
||||||
|
|
||||||
|
vec4 VertexColor(vec4 color)
|
||||||
|
{
|
||||||
|
return color;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Emulate one of the special colormaps. (Invulnerability, gold, etc.)
|
||||||
|
|
||||||
|
vec4 SpecialColormap(vec2 tex_coord, vec4 start, vec4 end)
|
||||||
|
{
|
||||||
|
vec4 color = SampleTexture(tex_coord);
|
||||||
|
vec4 range = end - start;
|
||||||
|
// We can't store values greater than 1.0 in a color register, so we multiply
|
||||||
|
// the final result by 2 and expect the caller to divide the start and end by 2.
|
||||||
|
color.rgb = 2 * (start + Grayscale(color) * range).rgb;
|
||||||
|
// Duplicate alpha semantics of NormalColor.
|
||||||
|
color.a = start.a + color.a * end.a;
|
||||||
|
return color;
|
||||||
|
}
|
||||||
|
|
||||||
|
// In-game colormap effect: fade to a particular color and multiply by another, with
|
||||||
|
// optional desaturation of the original color. Desaturation is stored in c1.
|
||||||
|
// Fade level is packed int fade.a. Fade.rgb has been premultiplied by alpha.
|
||||||
|
// Overall alpha is in color.a.
|
||||||
|
vec4 InGameColormap(vec2 tex_coord, vec4 color, vec4 fade)
|
||||||
|
{
|
||||||
|
vec4 rgb = SampleTexture(tex_coord);
|
||||||
|
|
||||||
|
// Desaturate
|
||||||
|
#if DESAT
|
||||||
|
vec3 intensity;
|
||||||
|
intensity.rgb = vec3(Grayscale(rgb) * Desaturation.x);
|
||||||
|
rgb.rgb = intensity.rgb + rgb.rgb * Desaturation.y;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Fade
|
||||||
|
rgb.rgb = rgb.rgb * fade.aaa + fade.rgb;
|
||||||
|
|
||||||
|
// Shade and Alpha
|
||||||
|
rgb = rgb * color;
|
||||||
|
|
||||||
|
return rgb;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Windowed gamma correction.
|
||||||
|
|
||||||
|
vec4 GammaCorrection(vec2 tex_coord)
|
||||||
|
{
|
||||||
|
vec4 color = texture(Image, tex_coord);
|
||||||
|
color.rgb = pow(color.rgb, Gamma.rgb);
|
||||||
|
return color;
|
||||||
|
}
|
||||||
|
|
||||||
|
// The burn wipe effect.
|
||||||
|
|
||||||
|
vec4 BurnWipe(vec4 coord)
|
||||||
|
{
|
||||||
|
vec4 color = texture(NewScreen, coord.xy);
|
||||||
|
vec4 alpha = texture(Burn, coord.zw);
|
||||||
|
color.a = alpha.r * 2;
|
||||||
|
return color;
|
||||||
|
}
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
#if defined(ENORMALCOLOR)
|
||||||
|
FragColor = NormalColor(PixelTexCoord0.xy, PixelColor0, PixelColor1);
|
||||||
|
#elif defined(EREDTOALPHA)
|
||||||
|
FragColor = RedToAlpha(PixelTexCoord0.xy, PixelColor0, PixelColor1);
|
||||||
|
#elif defined(EVERTEXCOLOR)
|
||||||
|
FragColor = VertexColor(PixelColor0);
|
||||||
|
#elif defined(ESPECIALCOLORMAP)
|
||||||
|
FragColor = SpecialColormap(PixelTexCoord0.xy, PixelColor0, PixelColor1);
|
||||||
|
#elif defined(EINGAMECOLORMAP)
|
||||||
|
FragColor = InGameColormap(PixelTexCoord0.xy, PixelColor0, PixelColor1);
|
||||||
|
#elif defined(EBURNWIPE)
|
||||||
|
FragColor = BurnWipe(PixelTexCoord0);
|
||||||
|
#elif defined(EGAMMACORRECTION)
|
||||||
|
FragColor = GammaCorrection(PixelTexCoord0.xy);
|
||||||
|
#else
|
||||||
|
#error Entry point define is missing
|
||||||
|
#endif
|
||||||
|
}
|
|
@ -0,0 +1,17 @@
|
||||||
|
|
||||||
|
in vec4 AttrPosition;
|
||||||
|
in vec4 AttrColor0;
|
||||||
|
in vec4 AttrColor1;
|
||||||
|
in vec4 AttrTexCoord0;
|
||||||
|
|
||||||
|
out vec4 PixelColor0;
|
||||||
|
out vec4 PixelColor1;
|
||||||
|
out vec4 PixelTexCoord0;
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
gl_Position = AttrPosition;
|
||||||
|
PixelColor0 = AttrColor0;
|
||||||
|
PixelColor1 = AttrColor1;
|
||||||
|
PixelTexCoord0 = AttrTexCoord0;
|
||||||
|
}
|
Loading…
Reference in New Issue