mirror of
https://github.com/OpenRCT2/OpenRCT2
synced 2026-01-15 19:13:07 +01:00
Implement support for viewport shifting
This commit is contained in:
@@ -38,6 +38,7 @@
|
||||
#define glTexImage3D __static__glTexImage3D
|
||||
#define glGetIntegerv __static__glGetIntegerv
|
||||
#define glGetTexImage __static__glGetTexImage
|
||||
#define glTexSubImage2D __static__glTexSubImage2D
|
||||
|
||||
#endif
|
||||
|
||||
@@ -74,6 +75,7 @@
|
||||
#undef glTexImage3D
|
||||
#undef glGetIntegerv
|
||||
#undef glGetTexImage
|
||||
#undef glTexSubImage2D
|
||||
|
||||
// 1.1 function signatures
|
||||
using PFNGLBEGINPROC = void(APIENTRYP)(GLenum mode);
|
||||
@@ -106,6 +108,9 @@ using PFNGLTEXIMAGE3DPROC = void(APIENTRYP)(
|
||||
GLenum type, const GLvoid* data);
|
||||
using PFNGLGETINTERGERVPROC = void(APIENTRYP)(GLenum pname, GLint* data);
|
||||
using PFNGLGETTEXIMAGEPROC = void(APIENTRYP)(GLenum target, GLint level, GLenum format, GLenum type, GLvoid* img);
|
||||
using PFNGLTEXSUBIMAGE2D = void(APIENTRYP)(
|
||||
GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type,
|
||||
const GLvoid* pixels);
|
||||
|
||||
#define OPENGL_PROC(TYPE, PROC) extern TYPE PROC;
|
||||
#include "OpenGLAPIProc.h"
|
||||
|
||||
@@ -102,3 +102,4 @@ extern "C" void glDrawArraysInstanced(GLenum mode, GLint first, GLsizei count, G
|
||||
extern "C" void glVertexAttribDivisor(GLuint index, GLuint divisor);
|
||||
#endif
|
||||
OPENGL_PROC(PFNGLBLENDFUNCSEPARATEPROC, glBlendFuncSeparate)
|
||||
OPENGL_PROC(PFNGLTEXSUBIMAGE2D, glTexSubImage2D)
|
||||
|
||||
@@ -94,11 +94,17 @@ public:
|
||||
{
|
||||
return _textureCache.get();
|
||||
}
|
||||
|
||||
const OpenGLFramebuffer& GetFinalFramebuffer() const
|
||||
{
|
||||
return _swapFramebuffer->GetFinalFramebuffer();
|
||||
}
|
||||
|
||||
OpenGLFramebuffer& GetFinalFramebuffer()
|
||||
{
|
||||
return _swapFramebuffer->GetFinalFramebuffer();
|
||||
}
|
||||
|
||||
void Initialise();
|
||||
void Resize(int32_t width, int32_t height);
|
||||
void ResetPalette();
|
||||
@@ -371,7 +377,50 @@ public:
|
||||
|
||||
void CopyRect(int32_t x, int32_t y, int32_t width, int32_t height, int32_t dx, int32_t dy) override
|
||||
{
|
||||
// Not applicable for this engine
|
||||
if (dx == 0 && dy == 0)
|
||||
return;
|
||||
|
||||
_drawingContext->FlushCommandBuffers();
|
||||
|
||||
OpenGLFramebuffer& framebuffer = _drawingContext->GetFinalFramebuffer();
|
||||
framebuffer.Bind();
|
||||
framebuffer.GetPixels(_bitsDPI);
|
||||
|
||||
// Originally 0x00683359
|
||||
// Adjust for move off screen
|
||||
// NOTE: when zooming, there can be x, y, dx, dy combinations that go off the
|
||||
// screen; hence the checks. This code should ultimately not be called when
|
||||
// zooming because this function is specific to updating the screen on move
|
||||
int32_t lmargin = std::min(x - dx, 0);
|
||||
int32_t rmargin = std::min(static_cast<int32_t>(_width) - (x - dx + width), 0);
|
||||
int32_t tmargin = std::min(y - dy, 0);
|
||||
int32_t bmargin = std::min(static_cast<int32_t>(_height) - (y - dy + height), 0);
|
||||
x -= lmargin;
|
||||
y -= tmargin;
|
||||
width += lmargin + rmargin;
|
||||
height += tmargin + bmargin;
|
||||
|
||||
int32_t stride = _bitsDPI.LineStride();
|
||||
uint8_t* to = _bitsDPI.bits + y * stride + x;
|
||||
uint8_t* from = _bitsDPI.bits + (y - dy) * stride + x - dx;
|
||||
|
||||
if (dy > 0)
|
||||
{
|
||||
// If positive dy, reverse directions
|
||||
to += (height - 1) * stride;
|
||||
from += (height - 1) * stride;
|
||||
stride = -stride;
|
||||
}
|
||||
|
||||
// Move bytes
|
||||
for (int32_t i = 0; i < height; i++)
|
||||
{
|
||||
memmove(to, from, width);
|
||||
to += stride;
|
||||
from += stride;
|
||||
}
|
||||
|
||||
framebuffer.SetPixels(_bitsDPI);
|
||||
}
|
||||
|
||||
IDrawingContext* GetDrawingContext() override
|
||||
@@ -386,7 +435,7 @@ public:
|
||||
|
||||
DrawingEngineFlags GetFlags() override
|
||||
{
|
||||
return {};
|
||||
return DrawingEngineFlag::dirtyOptimisations;
|
||||
}
|
||||
|
||||
void InvalidateImage(uint32_t image) override
|
||||
|
||||
@@ -150,4 +150,27 @@ GLuint OpenGLFramebuffer::CreateDepthTexture(int32_t width, int32_t height)
|
||||
return depth;
|
||||
}
|
||||
|
||||
void OpenGLFramebuffer::SetPixels(const DrawPixelInfo& dpi)
|
||||
{
|
||||
assert(dpi.width == _width && dpi.height == _height);
|
||||
|
||||
auto pixels = std::make_unique<uint8_t[]>(_width * _height);
|
||||
// Flip pixels vertically on copy
|
||||
uint8_t* dst = pixels.get() + ((_height - 1) * _width);
|
||||
uint8_t* src = dpi.bits;
|
||||
for (int32_t y = 0; y < _height; y++)
|
||||
{
|
||||
std::copy_n(src, _width, dst);
|
||||
src += dpi.width + dpi.pitch;
|
||||
dst -= _width;
|
||||
}
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D, _texture);
|
||||
CheckGLError();
|
||||
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
|
||||
CheckGLError();
|
||||
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, _width, _height, GL_RED_INTEGER, GL_UNSIGNED_BYTE, pixels.get());
|
||||
CheckGLError();
|
||||
}
|
||||
|
||||
#endif /* DISABLE_OPENGL */
|
||||
|
||||
@@ -59,6 +59,7 @@ namespace OpenRCT2::Ui
|
||||
void SwapColourBuffer(OpenGLFramebuffer& other);
|
||||
GLuint SwapDepthTexture(GLuint depth);
|
||||
void Copy(OpenGLFramebuffer& src, GLenum filter);
|
||||
void SetPixels(const DrawPixelInfo& dpi);
|
||||
|
||||
static GLuint CreateDepthTexture(int32_t width, int32_t height);
|
||||
};
|
||||
|
||||
@@ -39,6 +39,10 @@ namespace OpenRCT2::Ui
|
||||
{
|
||||
return _opaqueFramebuffer;
|
||||
}
|
||||
OpenGLFramebuffer& GetFinalFramebuffer()
|
||||
{
|
||||
return _opaqueFramebuffer;
|
||||
}
|
||||
GLuint GetBackDepthTexture() const
|
||||
{
|
||||
return _backDepth;
|
||||
|
||||
Reference in New Issue
Block a user