This commit is contained in:
Christoph Oelckers 2016-07-30 13:26:37 +02:00
commit 39059b3b5c
2 changed files with 3 additions and 341 deletions

View file

@ -333,74 +333,6 @@ private:
// ---------------------------------------------------------------------------
class NonCopyable
{
protected:
NonCopyable() { }
~NonCopyable() { }
private:
NonCopyable(const NonCopyable&);
const NonCopyable& operator=(const NonCopyable&);
};
// ---------------------------------------------------------------------------
class RenderTarget : private NonCopyable
{
public:
RenderTarget(const GLsizei width, const GLsizei height);
~RenderTarget();
void Bind();
void Unbind();
FHardwareTexture& GetColorTexture()
{
return m_texture;
}
private:
GLuint m_ID;
GLuint m_oldID;
FHardwareTexture m_texture;
static GLuint GetBoundID();
}; // class RenderTarget
// ---------------------------------------------------------------------------
class CocoaOpenGLFrameBuffer : public OpenGLFrameBuffer, private NonCopyable
{
typedef OpenGLFrameBuffer Super;
public:
CocoaOpenGLFrameBuffer(void* hMonitor, int width, int height, int bits, int refreshHz, bool fullscreen);
virtual bool Lock(bool buffered);
virtual void Update();
virtual void GetScreenshotBuffer(const BYTE*& buffer, int& pitch, ESSType& color_type);
virtual void SetSmoothPicture(bool smooth);
private:
RenderTarget m_renderTarget;
void DrawRenderTarget();
}; // class CocoaOpenGLFrameBuffer
// ---------------------------------------------------------------------------
EXTERN_CVAR(Float, Gamma)
CUSTOM_CVAR(Float, rgamma, 1.0f, CVAR_ARCHIVE | CVAR_GLOBALCONFIG)
@ -661,7 +593,7 @@ DFrameBuffer* CocoaVideo::CreateFrameBuffer(const int width, const int height, c
if (1 == s_currentRenderer)
{
fb = new CocoaOpenGLFrameBuffer(NULL, width, height, 32, 60, fullscreen);
fb = new OpenGLFrameBuffer(NULL, width, height, 32, 60, fullscreen);
}
else
{
@ -1245,280 +1177,12 @@ void SDLGLFB::ResetGammaTable()
int SDLGLFB::GetClientWidth()
{
return GetWidth();
return static_cast<int>(rbOpts.width + 2.0f * rbOpts.shiftX);
}
int SDLGLFB::GetClientHeight()
{
return GetHeight();
}
// ---------------------------------------------------------------------------
void BoundTextureSetFilter(const GLenum target, const GLint filter)
{
glTexParameteri(target, GL_TEXTURE_MIN_FILTER, filter);
glTexParameteri(target, GL_TEXTURE_MAG_FILTER, filter);
glTexParameteri(target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
}
EXTERN_CVAR(Float, vid_brightness)
EXTERN_CVAR(Float, vid_contrast)
void BoundTextureDraw2D(const GLsizei width, const GLsizei height)
{
gl_RenderState.SetEffect(EFF_GAMMACORRECTION);
gl_RenderState.SetTextureMode(TM_OPAQUE);
gl_RenderState.AlphaFunc(GL_GEQUAL, 0.f);
gl_RenderState.SetColor(Gamma, vid_contrast, vid_brightness);
gl_RenderState.Apply();
static const float x = 0.f;
static const float y = 0.f;
const float w = float(width);
const float h = float(height);
static const float u1 = 0.f;
static const float v1 = 1.f;
static const float u2 = 1.f;
static const float v2 = 0.f;
FFlatVertexBuffer* const vbo = GLRenderer->mVBO;
FFlatVertex* ptr = vbo->GetBuffer();
ptr->Set(x, y, 0, u1, v1); ++ptr;
ptr->Set(x, y + h, 0, u1, v2); ++ptr;
ptr->Set(x + w, y, 0, u2, v1); ++ptr;
ptr->Set(x + w, y + h, 0, u2, v2); ++ptr;
vbo->RenderCurrent(ptr, GL_TRIANGLE_STRIP);
gl_RenderState.SetEffect(EFF_NONE);
gl_RenderState.SetTextureMode(TM_MODULATE);
}
bool BoundTextureSaveAsPNG(const GLenum target, const char* const path)
{
if (NULL == path)
{
return false;
}
GLint width = 0;
GLint height = 0;
glGetTexLevelParameteriv(target, 0, GL_TEXTURE_WIDTH, &width );
glGetTexLevelParameteriv(target, 0, GL_TEXTURE_HEIGHT, &height);
if (0 == width || 0 == height)
{
Printf("BoundTextureSaveAsPNG: invalid texture size %ix%i\n", width, height);
return false;
}
static const int BYTES_PER_PIXEL = 4;
const int imageSize = width * height * BYTES_PER_PIXEL;
unsigned char* imageBuffer = static_cast<unsigned char*>(malloc(imageSize));
if (NULL == imageBuffer)
{
Printf("BoundTextureSaveAsPNG: cannot allocate %i bytes\n", imageSize);
return false;
}
glGetTexImage(target, 0, GL_BGRA, GL_UNSIGNED_BYTE, imageBuffer);
const int lineSize = width * BYTES_PER_PIXEL;
unsigned char lineBuffer[lineSize];
for (GLint line = 0; line < height / 2; ++line)
{
void* frontLinePtr = &imageBuffer[line * lineSize];
void* backLinePtr = &imageBuffer[(height - line - 1) * lineSize];
memcpy( lineBuffer, frontLinePtr, lineSize);
memcpy(frontLinePtr, backLinePtr, lineSize);
memcpy( backLinePtr, lineBuffer, lineSize);
}
FILE* file = fopen(path, "w");
if (NULL == file)
{
Printf("BoundTextureSaveAsPNG: cannot open file %s\n", path);
free(imageBuffer);
return false;
}
const bool result =
M_CreatePNG(file, &imageBuffer[0], NULL, SS_BGRA, width, height, width * BYTES_PER_PIXEL)
&& M_FinishPNG(file);
fclose(file);
free(imageBuffer);
return result;
}
// ---------------------------------------------------------------------------
RenderTarget::RenderTarget(const GLsizei width, const GLsizei height)
: m_ID(0)
, m_oldID(0)
, m_texture(width, height, true)
{
glGenFramebuffersEXT(1, &m_ID);
Bind();
m_texture.CreateTexture(NULL, width, height, 0, false, 0);
m_texture.BindToFrameBuffer();
Unbind();
}
RenderTarget::~RenderTarget()
{
glDeleteFramebuffersEXT(1, &m_ID);
}
void RenderTarget::Bind()
{
const GLuint boundID = GetBoundID();
if (m_ID != boundID)
{
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_ID);
m_oldID = boundID;
}
}
void RenderTarget::Unbind()
{
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_oldID);
m_oldID = 0;
}
GLuint RenderTarget::GetBoundID()
{
GLint result;
glGetIntegerv(GL_FRAMEBUFFER_BINDING_EXT, &result);
return static_cast<GLuint>(result);
}
// ---------------------------------------------------------------------------
CocoaOpenGLFrameBuffer::CocoaOpenGLFrameBuffer(void* hMonitor, int width, int height, int bits, int refreshHz, bool fullscreen)
: OpenGLFrameBuffer(hMonitor, width, height, bits, refreshHz, fullscreen)
, m_renderTarget(width, height)
{
SetSmoothPicture(gl_smooth_rendered);
// Fill render target with black color
m_renderTarget.Bind();
glClear(GL_COLOR_BUFFER_BIT);
m_renderTarget.Unbind();
}
bool CocoaOpenGLFrameBuffer::Lock(bool buffered)
{
if (0 == m_lock)
{
m_renderTarget.Bind();
}
return Super::Lock(buffered);
}
void CocoaOpenGLFrameBuffer::Update()
{
if (!CanUpdate())
{
GLRenderer->Flush();
return;
}
Begin2D(false);
DrawRateStuff();
GLRenderer->Flush();
DrawRenderTarget();
Swap();
Unlock();
CheckBench();
}
void CocoaOpenGLFrameBuffer::GetScreenshotBuffer(const BYTE*& buffer, int& pitch, ESSType& color_type)
{
m_renderTarget.Bind();
Super::GetScreenshotBuffer(buffer, pitch, color_type);
m_renderTarget.Unbind();
}
void CocoaOpenGLFrameBuffer::DrawRenderTarget()
{
m_renderTarget.Unbind();
m_renderTarget.GetColorTexture().Bind(0, 0, false);
if (rbOpts.dirty)
{
// TODO: Figure out why the following glClear() call is needed
// to avoid drawing of garbage in fullscreen mode when
// in-game's aspect ratio is different from display one
glClear(GL_COLOR_BUFFER_BIT);
rbOpts.dirty = false;
}
glViewport(rbOpts.shiftX, rbOpts.shiftY, rbOpts.width, rbOpts.height);
BoundTextureDraw2D(Width, Height);
glViewport(0, 0, Width, Height);
}
void CocoaOpenGLFrameBuffer::SetSmoothPicture(const bool smooth)
{
FHardwareTexture& texture = m_renderTarget.GetColorTexture();
texture.Bind(0, 0, false);
BoundTextureSetFilter(GL_TEXTURE_2D, smooth ? GL_LINEAR : GL_NEAREST);
}
// ---------------------------------------------------------------------------
CUSTOM_CVAR(Bool, gl_smooth_rendered, false, CVAR_ARCHIVE | CVAR_GLOBALCONFIG | CVAR_NOINITCALL)
{
if (NULL != screen)
{
screen->SetSmoothPicture(self);
}
return static_cast<int>(rbOpts.height + 2.0f * rbOpts.shiftY);
}

View file

@ -415,8 +415,6 @@ public:
virtual bool Is8BitMode() = 0;
#endif
virtual void SetSmoothPicture(bool smooth) {}
protected:
void DrawRateStuff ();
void CopyFromBuff (BYTE *src, int srcPitch, int width, int height, BYTE *dest);