mirror of
https://github.com/ZDoom/qzdoom.git
synced 2025-01-18 23:21:41 +00:00
Add bgra support to OpenGLSWFrameBuffer
This commit is contained in:
parent
f5c069c759
commit
f37ee3a024
9 changed files with 44 additions and 27 deletions
|
@ -79,7 +79,7 @@ CUSTOM_CVAR(Int, vid_hwgamma, 2, CVAR_ARCHIVE | CVAR_GLOBALCONFIG | CVAR_NOINITC
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
|
|
||||||
OpenGLFrameBuffer::OpenGLFrameBuffer(void *hMonitor, int width, int height, int bits, int refreshHz, bool fullscreen) :
|
OpenGLFrameBuffer::OpenGLFrameBuffer(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, false)
|
||||||
{
|
{
|
||||||
// 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!
|
||||||
|
|
|
@ -120,8 +120,8 @@ const char *const OpenGLSWFrameBuffer::ShaderDefines[OpenGLSWFrameBuffer::NUM_SH
|
||||||
"#define EGAMMACORRECTION", // 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, bool bgra) :
|
||||||
Super(hMonitor, width, height, bits, refreshHz, fullscreen)
|
Super(hMonitor, width, height, bits, refreshHz, fullscreen, bgra)
|
||||||
{
|
{
|
||||||
// To do: this needs to cooperate with the same static in OpenGLFrameBuffer::InitializeState
|
// To do: this needs to cooperate with the same static in OpenGLFrameBuffer::InitializeState
|
||||||
static bool first = true;
|
static bool first = true;
|
||||||
|
@ -892,7 +892,7 @@ void OpenGLSWFrameBuffer::KillNativeTexs()
|
||||||
|
|
||||||
bool OpenGLSWFrameBuffer::CreateFBTexture()
|
bool OpenGLSWFrameBuffer::CreateFBTexture()
|
||||||
{
|
{
|
||||||
CreateTexture("FBTexture", Width, Height, 1, GL_R8, &FBTexture);
|
CreateTexture("FBTexture", Width, Height, 1, IsBgra() ? GL_RGBA8 : GL_R8, &FBTexture);
|
||||||
FBWidth = Width;
|
FBWidth = Width;
|
||||||
FBHeight = Height;
|
FBHeight = Height;
|
||||||
return true;
|
return true;
|
||||||
|
@ -1262,13 +1262,16 @@ void OpenGLSWFrameBuffer::Draw3DPart(bool copy3d)
|
||||||
{
|
{
|
||||||
if (copy3d)
|
if (copy3d)
|
||||||
{
|
{
|
||||||
|
int pixelsize = IsBgra() ? 4 : 1;
|
||||||
|
int size = Width * Height * pixelsize;
|
||||||
|
|
||||||
if (FBTexture->Buffers[0] == 0)
|
if (FBTexture->Buffers[0] == 0)
|
||||||
{
|
{
|
||||||
glGenBuffers(2, (GLuint*)FBTexture->Buffers);
|
glGenBuffers(2, (GLuint*)FBTexture->Buffers);
|
||||||
glBindBuffer(GL_PIXEL_UNPACK_BUFFER, FBTexture->Buffers[0]);
|
glBindBuffer(GL_PIXEL_UNPACK_BUFFER, FBTexture->Buffers[0]);
|
||||||
glBufferData(GL_PIXEL_UNPACK_BUFFER, Width * Height, nullptr, GL_STREAM_DRAW);
|
glBufferData(GL_PIXEL_UNPACK_BUFFER, size, nullptr, GL_STREAM_DRAW);
|
||||||
glBindBuffer(GL_PIXEL_UNPACK_BUFFER, FBTexture->Buffers[1]);
|
glBindBuffer(GL_PIXEL_UNPACK_BUFFER, FBTexture->Buffers[1]);
|
||||||
glBufferData(GL_PIXEL_UNPACK_BUFFER, Width * Height, nullptr, GL_STREAM_DRAW);
|
glBufferData(GL_PIXEL_UNPACK_BUFFER, size, nullptr, GL_STREAM_DRAW);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -1276,27 +1279,30 @@ void OpenGLSWFrameBuffer::Draw3DPart(bool copy3d)
|
||||||
FBTexture->CurrentBuffer = (FBTexture->CurrentBuffer + 1) & 1;
|
FBTexture->CurrentBuffer = (FBTexture->CurrentBuffer + 1) & 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t *dest = (uint8_t*)glMapBufferRange(GL_PIXEL_UNPACK_BUFFER, 0, Width * Height, GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_RANGE_BIT | GL_MAP_INVALIDATE_BUFFER_BIT);
|
uint8_t *dest = (uint8_t*)glMapBufferRange(GL_PIXEL_UNPACK_BUFFER, 0, size, GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_RANGE_BIT | GL_MAP_INVALIDATE_BUFFER_BIT);
|
||||||
if (dest)
|
if (dest)
|
||||||
{
|
{
|
||||||
if (Pitch == Width)
|
if (Pitch == Width)
|
||||||
{
|
{
|
||||||
memcpy(dest, MemBuffer, Width * Height);
|
memcpy(dest, MemBuffer, Width * Height * pixelsize);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
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 * pixelsize);
|
||||||
dest += Width;
|
dest += Width * pixelsize;
|
||||||
src += Pitch;
|
src += Pitch * pixelsize;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
glUnmapBuffer(GL_PIXEL_UNPACK_BUFFER);
|
glUnmapBuffer(GL_PIXEL_UNPACK_BUFFER);
|
||||||
GLint oldBinding = 0;
|
GLint oldBinding = 0;
|
||||||
glGetIntegerv(GL_TEXTURE_BINDING_2D, &oldBinding);
|
glGetIntegerv(GL_TEXTURE_BINDING_2D, &oldBinding);
|
||||||
glBindTexture(GL_TEXTURE_2D, FBTexture->Texture);
|
glBindTexture(GL_TEXTURE_2D, FBTexture->Texture);
|
||||||
|
if (IsBgra())
|
||||||
|
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, Width, Height, GL_BGRA, GL_UNSIGNED_BYTE, 0);
|
||||||
|
else
|
||||||
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, Width, Height, GL_RED, GL_UNSIGNED_BYTE, 0);
|
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, Width, Height, GL_RED, GL_UNSIGNED_BYTE, 0);
|
||||||
glBindTexture(GL_TEXTURE_2D, oldBinding);
|
glBindTexture(GL_TEXTURE_2D, oldBinding);
|
||||||
}
|
}
|
||||||
|
@ -1314,6 +1320,9 @@ void OpenGLSWFrameBuffer::Draw3DPart(bool copy3d)
|
||||||
memset(Constant, 0, sizeof(Constant));
|
memset(Constant, 0, sizeof(Constant));
|
||||||
SetAlphaBlend(0);
|
SetAlphaBlend(0);
|
||||||
EnableAlphaTest(false);
|
EnableAlphaTest(false);
|
||||||
|
if (IsBgra())
|
||||||
|
SetPixelShader(Shaders[SHADER_NormalColor]);
|
||||||
|
else
|
||||||
SetPixelShader(Shaders[SHADER_NormalColorPal]);
|
SetPixelShader(Shaders[SHADER_NormalColorPal]);
|
||||||
if (copy3d)
|
if (copy3d)
|
||||||
{
|
{
|
||||||
|
@ -1330,6 +1339,9 @@ void OpenGLSWFrameBuffer::Draw3DPart(bool copy3d)
|
||||||
{
|
{
|
||||||
color0 = ColorValue(realfixedcolormap->ColorizeStart[0] / 2, realfixedcolormap->ColorizeStart[1] / 2, realfixedcolormap->ColorizeStart[2] / 2, 0);
|
color0 = ColorValue(realfixedcolormap->ColorizeStart[0] / 2, 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);
|
||||||
|
if (IsBgra())
|
||||||
|
SetPixelShader(Shaders[SHADER_SpecialColormap]);
|
||||||
|
else
|
||||||
SetPixelShader(Shaders[SHADER_SpecialColormapPal]);
|
SetPixelShader(Shaders[SHADER_SpecialColormapPal]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1341,6 +1353,9 @@ void OpenGLSWFrameBuffer::Draw3DPart(bool copy3d)
|
||||||
CalcFullscreenCoords(verts, Accel2D, false, color0, color1);
|
CalcFullscreenCoords(verts, Accel2D, false, color0, color1);
|
||||||
DrawTriangleFans(2, verts);
|
DrawTriangleFans(2, verts);
|
||||||
}
|
}
|
||||||
|
if (IsBgra())
|
||||||
|
SetPixelShader(Shaders[SHADER_NormalColor]);
|
||||||
|
else
|
||||||
SetPixelShader(Shaders[SHADER_NormalColorPal]);
|
SetPixelShader(Shaders[SHADER_NormalColorPal]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -29,7 +29,7 @@ class OpenGLFrameBuffer : public SDLGLFB
|
||||||
public:
|
public:
|
||||||
|
|
||||||
explicit OpenGLSWFrameBuffer() {}
|
explicit OpenGLSWFrameBuffer() {}
|
||||||
OpenGLSWFrameBuffer(void *hMonitor, int width, int height, int bits, int refreshHz, bool fullscreen);
|
OpenGLSWFrameBuffer(void *hMonitor, int width, int height, int bits, int refreshHz, bool fullscreen, bool bgra);
|
||||||
~OpenGLSWFrameBuffer();
|
~OpenGLSWFrameBuffer();
|
||||||
|
|
||||||
bool IsValid() override;
|
bool IsValid() override;
|
||||||
|
|
|
@ -1126,8 +1126,8 @@ void CocoaFrameBuffer::Flip()
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
SDLGLFB::SDLGLFB(void*, const int width, const int height, int, int, const bool fullscreen)
|
SDLGLFB::SDLGLFB(void*, const int width, const int height, int, int, const bool fullscreen, bool bgra)
|
||||||
: DFrameBuffer(width, height, false)
|
: DFrameBuffer(width, height, bgra)
|
||||||
, m_lock(-1)
|
, m_lock(-1)
|
||||||
, m_isUpdatePending(false)
|
, m_isUpdatePending(false)
|
||||||
{
|
{
|
||||||
|
|
|
@ -52,7 +52,7 @@ class SDLGLFB : public DFrameBuffer
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
// This must have the same parameters as the Windows version, even if they are not used!
|
// This must have the same parameters as the Windows version, even if they are not used!
|
||||||
SDLGLFB(void *hMonitor, int width, int height, int, int, bool fullscreen);
|
SDLGLFB(void *hMonitor, int width, int height, int, int, bool fullscreen, bool bgra);
|
||||||
~SDLGLFB();
|
~SDLGLFB();
|
||||||
|
|
||||||
virtual bool Lock(bool buffered = true);
|
virtual bool Lock(bool buffered = true);
|
||||||
|
|
|
@ -314,8 +314,8 @@ bool SDLGLVideo::InitHardware (bool allowsoftware, int multisample)
|
||||||
|
|
||||||
// FrameBuffer implementation -----------------------------------------------
|
// FrameBuffer implementation -----------------------------------------------
|
||||||
|
|
||||||
SDLGLFB::SDLGLFB (void *, int width, int height, int, int, bool fullscreen)
|
SDLGLFB::SDLGLFB (void *, int width, int height, int, int, bool fullscreen, bool bgra)
|
||||||
: DFrameBuffer (width, height, false)
|
: DFrameBuffer (width, height, bgra)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
|
|
|
@ -39,7 +39,7 @@ class SDLGLFB : public DFrameBuffer
|
||||||
DECLARE_CLASS(SDLGLFB, DFrameBuffer)
|
DECLARE_CLASS(SDLGLFB, DFrameBuffer)
|
||||||
public:
|
public:
|
||||||
// this must have the same parameters as the Windows version, even if they are not used!
|
// this must have the same parameters as the Windows version, even if they are not used!
|
||||||
SDLGLFB (void *hMonitor, int width, int height, int, int, bool fullscreen);
|
SDLGLFB (void *hMonitor, int width, int height, int, int, bool fullscreen, bool bgra);
|
||||||
~SDLGLFB ();
|
~SDLGLFB ();
|
||||||
|
|
||||||
void ForceBuffering (bool force);
|
void ForceBuffering (bool force);
|
||||||
|
|
|
@ -381,7 +381,8 @@ DFrameBuffer *Win32GLVideo::CreateFrameBuffer(int width, int height, bool bgra,
|
||||||
fb->m_Height == m_DisplayHeight &&
|
fb->m_Height == m_DisplayHeight &&
|
||||||
fb->m_Bits == m_DisplayBits &&
|
fb->m_Bits == m_DisplayBits &&
|
||||||
fb->m_RefreshHz == m_DisplayHz &&
|
fb->m_RefreshHz == m_DisplayHz &&
|
||||||
fb->m_Fullscreen == fs)
|
fb->m_Fullscreen == fs &&
|
||||||
|
fb->m_Bgra == bgra)
|
||||||
{
|
{
|
||||||
return old;
|
return old;
|
||||||
}
|
}
|
||||||
|
@ -391,7 +392,7 @@ DFrameBuffer *Win32GLVideo::CreateFrameBuffer(int width, int height, bool bgra,
|
||||||
if (vid_renderer == 1)
|
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
|
else
|
||||||
fb = new OpenGLSWFrameBuffer(m_hMonitor, m_DisplayWidth, m_DisplayHeight, m_DisplayBits, m_DisplayHz, fs);
|
fb = new OpenGLSWFrameBuffer(m_hMonitor, m_DisplayWidth, m_DisplayHeight, m_DisplayBits, m_DisplayHz, fs, bgra);
|
||||||
return fb;
|
return fb;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -867,13 +868,14 @@ IMPLEMENT_ABSTRACT_CLASS(Win32GLFrameBuffer)
|
||||||
//
|
//
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
|
|
||||||
Win32GLFrameBuffer::Win32GLFrameBuffer(void *hMonitor, int width, int height, int bits, int refreshHz, bool fullscreen) : BaseWinFB(width, height, false)
|
Win32GLFrameBuffer::Win32GLFrameBuffer(void *hMonitor, int width, int height, int bits, int refreshHz, bool fullscreen, bool bgra) : BaseWinFB(width, height, bgra)
|
||||||
{
|
{
|
||||||
m_Width = width;
|
m_Width = width;
|
||||||
m_Height = height;
|
m_Height = height;
|
||||||
m_Bits = bits;
|
m_Bits = bits;
|
||||||
m_RefreshHz = refreshHz;
|
m_RefreshHz = refreshHz;
|
||||||
m_Fullscreen = fullscreen;
|
m_Fullscreen = fullscreen;
|
||||||
|
m_Bgra = bgra;
|
||||||
m_Lock=0;
|
m_Lock=0;
|
||||||
|
|
||||||
RECT r;
|
RECT r;
|
||||||
|
|
|
@ -101,7 +101,7 @@ public:
|
||||||
Win32GLFrameBuffer() {}
|
Win32GLFrameBuffer() {}
|
||||||
// Actually, hMonitor is a HMONITOR, but it's passed as a void * as there
|
// Actually, hMonitor is a HMONITOR, but it's passed as a void * as there
|
||||||
// look to be some cross-platform bits in the way.
|
// look to be some cross-platform bits in the way.
|
||||||
Win32GLFrameBuffer(void *hMonitor, int width, int height, int bits, int refreshHz, bool fullscreen);
|
Win32GLFrameBuffer(void *hMonitor, int width, int height, int bits, int refreshHz, bool fullscreen, bool bgra);
|
||||||
virtual ~Win32GLFrameBuffer();
|
virtual ~Win32GLFrameBuffer();
|
||||||
|
|
||||||
|
|
||||||
|
@ -143,7 +143,7 @@ protected:
|
||||||
float m_Gamma, m_Brightness, m_Contrast;
|
float m_Gamma, m_Brightness, m_Contrast;
|
||||||
WORD m_origGamma[768];
|
WORD m_origGamma[768];
|
||||||
BOOL m_supportsGamma;
|
BOOL m_supportsGamma;
|
||||||
bool m_Fullscreen;
|
bool m_Fullscreen, m_Bgra;
|
||||||
int m_Width, m_Height, m_Bits, m_RefreshHz;
|
int m_Width, m_Height, m_Bits, m_RefreshHz;
|
||||||
int m_Lock;
|
int m_Lock;
|
||||||
char m_displayDeviceNameBuffer[CCHDEVICENAME];
|
char m_displayDeviceNameBuffer[CCHDEVICENAME];
|
||||||
|
|
Loading…
Reference in a new issue