mirror of
https://github.com/ZDoom/qzdoom.git
synced 2024-11-11 15:22:16 +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) :
|
||||
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.
|
||||
// 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
|
||||
};
|
||||
|
||||
OpenGLSWFrameBuffer::OpenGLSWFrameBuffer(void *hMonitor, int width, int height, int bits, int refreshHz, bool fullscreen) :
|
||||
Super(hMonitor, width, height, bits, refreshHz, fullscreen)
|
||||
OpenGLSWFrameBuffer::OpenGLSWFrameBuffer(void *hMonitor, int width, int height, int bits, int refreshHz, bool fullscreen, bool bgra) :
|
||||
Super(hMonitor, width, height, bits, refreshHz, fullscreen, bgra)
|
||||
{
|
||||
// To do: this needs to cooperate with the same static in OpenGLFrameBuffer::InitializeState
|
||||
static bool first = true;
|
||||
|
@ -892,7 +892,7 @@ void OpenGLSWFrameBuffer::KillNativeTexs()
|
|||
|
||||
bool OpenGLSWFrameBuffer::CreateFBTexture()
|
||||
{
|
||||
CreateTexture("FBTexture", Width, Height, 1, GL_R8, &FBTexture);
|
||||
CreateTexture("FBTexture", Width, Height, 1, IsBgra() ? GL_RGBA8 : GL_R8, &FBTexture);
|
||||
FBWidth = Width;
|
||||
FBHeight = Height;
|
||||
return true;
|
||||
|
@ -1262,13 +1262,16 @@ void OpenGLSWFrameBuffer::Draw3DPart(bool copy3d)
|
|||
{
|
||||
if (copy3d)
|
||||
{
|
||||
int pixelsize = IsBgra() ? 4 : 1;
|
||||
int size = Width * Height * pixelsize;
|
||||
|
||||
if (FBTexture->Buffers[0] == 0)
|
||||
{
|
||||
glGenBuffers(2, (GLuint*)FBTexture->Buffers);
|
||||
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]);
|
||||
glBufferData(GL_PIXEL_UNPACK_BUFFER, Width * Height, nullptr, GL_STREAM_DRAW);
|
||||
glBufferData(GL_PIXEL_UNPACK_BUFFER, size, nullptr, GL_STREAM_DRAW);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -1276,27 +1279,30 @@ void OpenGLSWFrameBuffer::Draw3DPart(bool copy3d)
|
|||
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 (Pitch == Width)
|
||||
{
|
||||
memcpy(dest, MemBuffer, Width * Height);
|
||||
memcpy(dest, MemBuffer, Width * Height * pixelsize);
|
||||
}
|
||||
else
|
||||
{
|
||||
uint8_t *src = MemBuffer;
|
||||
for (int y = 0; y < Height; y++)
|
||||
{
|
||||
memcpy(dest, src, Width);
|
||||
dest += Width;
|
||||
src += Pitch;
|
||||
memcpy(dest, src, Width * pixelsize);
|
||||
dest += Width * pixelsize;
|
||||
src += Pitch * pixelsize;
|
||||
}
|
||||
}
|
||||
glUnmapBuffer(GL_PIXEL_UNPACK_BUFFER);
|
||||
GLint oldBinding = 0;
|
||||
glGetIntegerv(GL_TEXTURE_BINDING_2D, &oldBinding);
|
||||
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);
|
||||
glBindTexture(GL_TEXTURE_2D, oldBinding);
|
||||
}
|
||||
|
@ -1314,6 +1320,9 @@ void OpenGLSWFrameBuffer::Draw3DPart(bool copy3d)
|
|||
memset(Constant, 0, sizeof(Constant));
|
||||
SetAlphaBlend(0);
|
||||
EnableAlphaTest(false);
|
||||
if (IsBgra())
|
||||
SetPixelShader(Shaders[SHADER_NormalColor]);
|
||||
else
|
||||
SetPixelShader(Shaders[SHADER_NormalColorPal]);
|
||||
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);
|
||||
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]);
|
||||
}
|
||||
}
|
||||
|
@ -1341,6 +1353,9 @@ void OpenGLSWFrameBuffer::Draw3DPart(bool copy3d)
|
|||
CalcFullscreenCoords(verts, Accel2D, false, color0, color1);
|
||||
DrawTriangleFans(2, verts);
|
||||
}
|
||||
if (IsBgra())
|
||||
SetPixelShader(Shaders[SHADER_NormalColor]);
|
||||
else
|
||||
SetPixelShader(Shaders[SHADER_NormalColorPal]);
|
||||
}
|
||||
|
||||
|
|
|
@ -29,7 +29,7 @@ class OpenGLFrameBuffer : public SDLGLFB
|
|||
public:
|
||||
|
||||
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();
|
||||
|
||||
bool IsValid() override;
|
||||
|
|
|
@ -1126,8 +1126,8 @@ void CocoaFrameBuffer::Flip()
|
|||
// ---------------------------------------------------------------------------
|
||||
|
||||
|
||||
SDLGLFB::SDLGLFB(void*, const int width, const int height, int, int, const bool fullscreen)
|
||||
: DFrameBuffer(width, height, false)
|
||||
SDLGLFB::SDLGLFB(void*, const int width, const int height, int, int, const bool fullscreen, bool bgra)
|
||||
: DFrameBuffer(width, height, bgra)
|
||||
, m_lock(-1)
|
||||
, m_isUpdatePending(false)
|
||||
{
|
||||
|
|
|
@ -52,7 +52,7 @@ class SDLGLFB : public DFrameBuffer
|
|||
{
|
||||
public:
|
||||
// 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();
|
||||
|
||||
virtual bool Lock(bool buffered = true);
|
||||
|
|
|
@ -314,8 +314,8 @@ bool SDLGLVideo::InitHardware (bool allowsoftware, int multisample)
|
|||
|
||||
// FrameBuffer implementation -----------------------------------------------
|
||||
|
||||
SDLGLFB::SDLGLFB (void *, int width, int height, int, int, bool fullscreen)
|
||||
: DFrameBuffer (width, height, false)
|
||||
SDLGLFB::SDLGLFB (void *, int width, int height, int, int, bool fullscreen, bool bgra)
|
||||
: DFrameBuffer (width, height, bgra)
|
||||
{
|
||||
int i;
|
||||
|
||||
|
|
|
@ -39,7 +39,7 @@ class SDLGLFB : public DFrameBuffer
|
|||
DECLARE_CLASS(SDLGLFB, DFrameBuffer)
|
||||
public:
|
||||
// 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 ();
|
||||
|
||||
void ForceBuffering (bool force);
|
||||
|
|
|
@ -381,7 +381,8 @@ DFrameBuffer *Win32GLVideo::CreateFrameBuffer(int width, int height, bool bgra,
|
|||
fb->m_Height == m_DisplayHeight &&
|
||||
fb->m_Bits == m_DisplayBits &&
|
||||
fb->m_RefreshHz == m_DisplayHz &&
|
||||
fb->m_Fullscreen == fs)
|
||||
fb->m_Fullscreen == fs &&
|
||||
fb->m_Bgra == bgra)
|
||||
{
|
||||
return old;
|
||||
}
|
||||
|
@ -391,7 +392,7 @@ DFrameBuffer *Win32GLVideo::CreateFrameBuffer(int width, int height, bool bgra,
|
|||
if (vid_renderer == 1)
|
||||
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);
|
||||
fb = new OpenGLSWFrameBuffer(m_hMonitor, m_DisplayWidth, m_DisplayHeight, m_DisplayBits, m_DisplayHz, fs, bgra);
|
||||
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_Height = height;
|
||||
m_Bits = bits;
|
||||
m_RefreshHz = refreshHz;
|
||||
m_Fullscreen = fullscreen;
|
||||
m_Bgra = bgra;
|
||||
m_Lock=0;
|
||||
|
||||
RECT r;
|
||||
|
|
|
@ -101,7 +101,7 @@ public:
|
|||
Win32GLFrameBuffer() {}
|
||||
// Actually, hMonitor is a HMONITOR, but it's passed as a void * as there
|
||||
// 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();
|
||||
|
||||
|
||||
|
@ -143,7 +143,7 @@ protected:
|
|||
float m_Gamma, m_Brightness, m_Contrast;
|
||||
WORD m_origGamma[768];
|
||||
BOOL m_supportsGamma;
|
||||
bool m_Fullscreen;
|
||||
bool m_Fullscreen, m_Bgra;
|
||||
int m_Width, m_Height, m_Bits, m_RefreshHz;
|
||||
int m_Lock;
|
||||
char m_displayDeviceNameBuffer[CCHDEVICENAME];
|
||||
|
|
Loading…
Reference in a new issue