mirror of
https://github.com/melonDS-emu/melonDS.git
synced 2025-07-21 05:09:46 -06:00
integrate OSD into ScreenPanel and make it nicer
This commit is contained in:
@ -35,6 +35,7 @@
|
||||
#include <qpa/qplatformnativeinterface.h>
|
||||
#endif
|
||||
#endif
|
||||
#include <QDateTime>
|
||||
|
||||
#include "OpenGLSupport.h"
|
||||
#include "duckstation/gl/context.h"
|
||||
@ -49,8 +50,8 @@
|
||||
#include "Config.h"
|
||||
|
||||
#include "main_shaders.h"
|
||||
|
||||
#include "OSD.h"
|
||||
#include "OSD_shaders.h"
|
||||
#include "font.h"
|
||||
|
||||
using namespace melonDS;
|
||||
|
||||
@ -64,23 +65,31 @@ extern int autoScreenSizing;
|
||||
extern int videoRenderer;
|
||||
extern bool videoSettingsDirty;
|
||||
|
||||
const u32 kOSDMargin = 6;
|
||||
|
||||
ScreenHandler::ScreenHandler(QWidget* widget)
|
||||
|
||||
ScreenPanel::ScreenPanel(QWidget* parent) : QWidget(parent)
|
||||
{
|
||||
widget->setMouseTracking(true);
|
||||
widget->setAttribute(Qt::WA_AcceptTouchEvents);
|
||||
setMouseTracking(true);
|
||||
setAttribute(Qt::WA_AcceptTouchEvents);
|
||||
QTimer* mouseTimer = setupMouseTimer();
|
||||
widget->connect(mouseTimer, &QTimer::timeout, [=] { if (Config::MouseHide) widget->setCursor(Qt::BlankCursor);});
|
||||
connect(mouseTimer, &QTimer::timeout, [=] { if (Config::MouseHide) setCursor(Qt::BlankCursor);});
|
||||
|
||||
osdEnabled = false;
|
||||
osdID = 1;
|
||||
}
|
||||
|
||||
ScreenHandler::~ScreenHandler()
|
||||
ScreenPanel::~ScreenPanel()
|
||||
{
|
||||
mouseTimer->stop();
|
||||
delete mouseTimer;
|
||||
}
|
||||
|
||||
void ScreenHandler::screenSetupLayout(int w, int h)
|
||||
void ScreenPanel::setupScreenLayout()
|
||||
{
|
||||
int w = width();
|
||||
int h = height();
|
||||
|
||||
int sizing = Config::ScreenSizing;
|
||||
if (sizing == 3) sizing = autoScreenSizing;
|
||||
|
||||
@ -113,7 +122,7 @@ void ScreenHandler::screenSetupLayout(int w, int h)
|
||||
numScreens = Frontend::GetScreenTransforms(screenMatrix[0], screenKind);
|
||||
}
|
||||
|
||||
QSize ScreenHandler::screenGetMinSize(int factor = 1)
|
||||
QSize ScreenPanel::screenGetMinSize(int factor = 1)
|
||||
{
|
||||
bool isHori = (Config::ScreenRotation == Frontend::screenRot_90Deg
|
||||
|| Config::ScreenRotation == Frontend::screenRot_270Deg);
|
||||
@ -158,7 +167,19 @@ QSize ScreenHandler::screenGetMinSize(int factor = 1)
|
||||
}
|
||||
}
|
||||
|
||||
void ScreenHandler::screenOnMousePress(QMouseEvent* event)
|
||||
void ScreenPanel::onScreenLayoutChanged()
|
||||
{
|
||||
setMinimumSize(screenGetMinSize());
|
||||
setupScreenLayout();
|
||||
}
|
||||
|
||||
void ScreenPanel::resizeEvent(QResizeEvent* event)
|
||||
{
|
||||
setupScreenLayout();
|
||||
QWidget::resizeEvent(event);
|
||||
}
|
||||
|
||||
void ScreenPanel::mousePressEvent(QMouseEvent* event)
|
||||
{
|
||||
event->accept();
|
||||
if (event->button() != Qt::LeftButton) return;
|
||||
@ -174,7 +195,7 @@ void ScreenHandler::screenOnMousePress(QMouseEvent* event)
|
||||
}
|
||||
}
|
||||
|
||||
void ScreenHandler::screenOnMouseRelease(QMouseEvent* event)
|
||||
void ScreenPanel::mouseReleaseEvent(QMouseEvent* event)
|
||||
{
|
||||
event->accept();
|
||||
if (event->button() != Qt::LeftButton) return;
|
||||
@ -187,7 +208,7 @@ void ScreenHandler::screenOnMouseRelease(QMouseEvent* event)
|
||||
}
|
||||
}
|
||||
|
||||
void ScreenHandler::screenOnMouseMove(QMouseEvent* event)
|
||||
void ScreenPanel::mouseMoveEvent(QMouseEvent* event)
|
||||
{
|
||||
event->accept();
|
||||
|
||||
@ -206,7 +227,7 @@ void ScreenHandler::screenOnMouseMove(QMouseEvent* event)
|
||||
}
|
||||
}
|
||||
|
||||
void ScreenHandler::screenHandleTablet(QTabletEvent* event)
|
||||
void ScreenPanel::tabletEvent(QTabletEvent* event)
|
||||
{
|
||||
event->accept();
|
||||
|
||||
@ -239,7 +260,7 @@ void ScreenHandler::screenHandleTablet(QTabletEvent* event)
|
||||
}
|
||||
}
|
||||
|
||||
void ScreenHandler::screenHandleTouch(QTouchEvent* event)
|
||||
void ScreenPanel::touchEvent(QTouchEvent* event)
|
||||
{
|
||||
event->accept();
|
||||
|
||||
@ -274,13 +295,26 @@ void ScreenHandler::screenHandleTouch(QTouchEvent* event)
|
||||
}
|
||||
}
|
||||
|
||||
void ScreenHandler::showCursor()
|
||||
bool ScreenPanel::event(QEvent* event)
|
||||
{
|
||||
mainWindow->panelWidget->setCursor(Qt::ArrowCursor);
|
||||
if (event->type() == QEvent::TouchBegin
|
||||
|| event->type() == QEvent::TouchEnd
|
||||
|| event->type() == QEvent::TouchUpdate)
|
||||
{
|
||||
touchEvent((QTouchEvent*)event);
|
||||
return true;
|
||||
}
|
||||
|
||||
return QWidget::event(event);
|
||||
}
|
||||
|
||||
void ScreenPanel::showCursor()
|
||||
{
|
||||
mainWindow->panel->setCursor(Qt::ArrowCursor);
|
||||
mouseTimer->start();
|
||||
}
|
||||
|
||||
QTimer* ScreenHandler::setupMouseTimer()
|
||||
QTimer* ScreenPanel::setupMouseTimer()
|
||||
{
|
||||
mouseTimer = new QTimer();
|
||||
mouseTimer->setSingleShot(true);
|
||||
@ -290,35 +324,290 @@ QTimer* ScreenHandler::setupMouseTimer()
|
||||
return mouseTimer;
|
||||
}
|
||||
|
||||
ScreenPanelNative::ScreenPanelNative(QWidget* parent) : QWidget(parent), ScreenHandler(this)
|
||||
int ScreenPanel::osdFindBreakPoint(const char* text, int i)
|
||||
{
|
||||
// i = character that went out of bounds
|
||||
|
||||
for (int j = i; j >= 0; j--)
|
||||
{
|
||||
if (text[j] == ' ')
|
||||
return j;
|
||||
}
|
||||
|
||||
return i;
|
||||
}
|
||||
|
||||
void ScreenPanel::osdLayoutText(const char* text, int* width, int* height, int* breaks)
|
||||
{
|
||||
int w = 0;
|
||||
int h = 14;
|
||||
int totalw = 0;
|
||||
int maxw = ((QWidget*)this)->width() - (kOSDMargin*2);
|
||||
int lastbreak = -1;
|
||||
int numbrk = 0;
|
||||
u16* ptr;
|
||||
|
||||
memset(breaks, 0, sizeof(int)*64);
|
||||
|
||||
for (int i = 0; text[i] != '\0'; )
|
||||
{
|
||||
int glyphsize;
|
||||
if (text[i] == ' ')
|
||||
{
|
||||
glyphsize = 6;
|
||||
}
|
||||
else
|
||||
{
|
||||
u32 ch = text[i];
|
||||
if (ch < 0x10 || ch > 0x7E) ch = 0x7F;
|
||||
|
||||
ptr = &::font[(ch-0x10) << 4];
|
||||
glyphsize = ptr[0];
|
||||
if (!glyphsize) glyphsize = 6;
|
||||
else glyphsize += 2; // space around the character
|
||||
}
|
||||
|
||||
w += glyphsize;
|
||||
if (w > maxw)
|
||||
{
|
||||
// wrap shit as needed
|
||||
if (text[i] == ' ')
|
||||
{
|
||||
if (numbrk >= 64) break;
|
||||
breaks[numbrk++] = i;
|
||||
i++;
|
||||
}
|
||||
else
|
||||
{
|
||||
int brk = osdFindBreakPoint(text, i);
|
||||
if (brk != lastbreak) i = brk;
|
||||
|
||||
if (numbrk >= 64) break;
|
||||
breaks[numbrk++] = i;
|
||||
|
||||
lastbreak = brk;
|
||||
}
|
||||
|
||||
w = 0;
|
||||
h += 14;
|
||||
}
|
||||
else
|
||||
i++;
|
||||
|
||||
if (w > totalw) totalw = w;
|
||||
}
|
||||
|
||||
*width = totalw;
|
||||
*height = h;
|
||||
}
|
||||
|
||||
unsigned int ScreenPanel::osdRainbowColor(int inc)
|
||||
{
|
||||
// inspired from Acmlmboard
|
||||
|
||||
if (inc < 100) return 0xFFFF9B9B + (inc << 8);
|
||||
else if (inc < 200) return 0xFFFFFF9B - ((inc-100) << 16);
|
||||
else if (inc < 300) return 0xFF9BFF9B + (inc-200);
|
||||
else if (inc < 400) return 0xFF9BFFFF - ((inc-300) << 8);
|
||||
else if (inc < 500) return 0xFF9B9BFF + ((inc-400) << 16);
|
||||
else return 0xFFFF9BFF - (inc-500);
|
||||
}
|
||||
|
||||
void ScreenPanel::osdRenderItem(OSDItem* item)
|
||||
{
|
||||
int w, h;
|
||||
int breaks[64];
|
||||
|
||||
char* text = item->text;
|
||||
u32 color = item->color;
|
||||
|
||||
bool rainbow = (color == 0);
|
||||
u32 ticks = (u32)QDateTime::currentMSecsSinceEpoch();
|
||||
u32 rainbowinc = ((text[0] * 17) + (ticks * 13)) % 600;
|
||||
|
||||
color |= 0xFF000000;
|
||||
const u32 shadow = 0xE0000000;
|
||||
|
||||
osdLayoutText(text, &w, &h, breaks);
|
||||
|
||||
item->bitmap = QImage(w, h, QImage::Format_ARGB32_Premultiplied);
|
||||
u32* bitmap = (u32*)item->bitmap.bits();
|
||||
memset(bitmap, 0, w*h*sizeof(u32));
|
||||
|
||||
int x = 0, y = 1;
|
||||
u32 maxw = ((QWidget*)this)->width() - (kOSDMargin*2);
|
||||
int curline = 0;
|
||||
u16* ptr;
|
||||
|
||||
for (int i = 0; text[i] != '\0'; )
|
||||
{
|
||||
int glyphsize;
|
||||
if (text[i] == ' ')
|
||||
{
|
||||
x += 6;
|
||||
}
|
||||
else
|
||||
{
|
||||
u32 ch = text[i];
|
||||
if (ch < 0x10 || ch > 0x7E) ch = 0x7F;
|
||||
|
||||
ptr = &::font[(ch-0x10) << 4];
|
||||
int glyphsize = ptr[0];
|
||||
if (!glyphsize) x += 6;
|
||||
else
|
||||
{
|
||||
x++;
|
||||
|
||||
if (rainbow)
|
||||
{
|
||||
color = osdRainbowColor(rainbowinc);
|
||||
rainbowinc = (rainbowinc + 30) % 600;
|
||||
}
|
||||
|
||||
// draw character
|
||||
for (int cy = 0; cy < 12; cy++)
|
||||
{
|
||||
u16 val = ptr[4+cy];
|
||||
|
||||
for (int cx = 0; cx < glyphsize; cx++)
|
||||
{
|
||||
if (val & (1<<cx))
|
||||
bitmap[((y+cy) * w) + x+cx] = color;
|
||||
}
|
||||
}
|
||||
|
||||
x += glyphsize;
|
||||
x++;
|
||||
}
|
||||
}
|
||||
|
||||
i++;
|
||||
if (breaks[curline] && i >= breaks[curline])
|
||||
{
|
||||
i = breaks[curline++];
|
||||
if (text[i] == ' ') i++;
|
||||
|
||||
x = 0;
|
||||
y += 14;
|
||||
}
|
||||
}
|
||||
|
||||
// shadow
|
||||
for (y = 0; y < h; y++)
|
||||
{
|
||||
for (x = 0; x < w; x++)
|
||||
{
|
||||
u32 val;
|
||||
|
||||
val = bitmap[(y * w) + x];
|
||||
if ((val >> 24) == 0xFF) continue;
|
||||
|
||||
if (x > 0) val = bitmap[(y * w) + x-1];
|
||||
if (x < w-1) val |= bitmap[(y * w) + x+1];
|
||||
if (y > 0)
|
||||
{
|
||||
if (x > 0) val |= bitmap[((y-1) * w) + x-1];
|
||||
val |= bitmap[((y-1) * w) + x];
|
||||
if (x < w-1) val |= bitmap[((y-1) * w) + x+1];
|
||||
}
|
||||
if (y < h-1)
|
||||
{
|
||||
if (x > 0) val |= bitmap[((y+1) * w) + x-1];
|
||||
val |= bitmap[((y+1) * w) + x];
|
||||
if (x < w-1) val |= bitmap[((y+1) * w) + x+1];
|
||||
}
|
||||
|
||||
if ((val >> 24) == 0xFF)
|
||||
bitmap[(y * w) + x] = shadow;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ScreenPanel::osdDeleteItem(OSDItem* item)
|
||||
{
|
||||
}
|
||||
|
||||
void ScreenPanel::osdSetEnabled(bool enabled)
|
||||
{
|
||||
osdMutex.lock();
|
||||
osdEnabled = enabled;
|
||||
osdMutex.unlock();
|
||||
}
|
||||
|
||||
void ScreenPanel::osdAddMessage(unsigned int color, const char* text)
|
||||
{
|
||||
if (!osdEnabled) return;
|
||||
|
||||
osdMutex.lock();
|
||||
|
||||
OSDItem item;
|
||||
|
||||
item.id = osdID++;
|
||||
item.timestamp = QDateTime::currentMSecsSinceEpoch();
|
||||
strncpy(item.text, text, 255); item.text[255] = '\0';
|
||||
item.color = color;
|
||||
item.rendered = false;
|
||||
|
||||
osdItems.push_back(item);
|
||||
|
||||
osdMutex.unlock();
|
||||
}
|
||||
|
||||
void ScreenPanel::osdUpdate()
|
||||
{
|
||||
osdMutex.lock();
|
||||
|
||||
qint64 tick_now = QDateTime::currentMSecsSinceEpoch();
|
||||
qint64 tick_min = tick_now - 2500;
|
||||
|
||||
for (auto it = osdItems.begin(); it != osdItems.end(); )
|
||||
{
|
||||
OSDItem& item = *it;
|
||||
|
||||
if ((!osdEnabled) || (item.timestamp < tick_min))
|
||||
{
|
||||
osdDeleteItem(&item);
|
||||
it = osdItems.erase(it);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!item.rendered)
|
||||
{
|
||||
osdRenderItem(&item);
|
||||
item.rendered = true;
|
||||
}
|
||||
|
||||
it++;
|
||||
}
|
||||
|
||||
osdMutex.unlock();
|
||||
}
|
||||
|
||||
|
||||
|
||||
ScreenPanelNative::ScreenPanelNative(QWidget* parent) : ScreenPanel(parent)
|
||||
{
|
||||
screen[0] = QImage(256, 192, QImage::Format_RGB32);
|
||||
screen[1] = QImage(256, 192, QImage::Format_RGB32);
|
||||
|
||||
screenTrans[0].reset();
|
||||
screenTrans[1].reset();
|
||||
|
||||
OSD::Init(false);
|
||||
}
|
||||
|
||||
ScreenPanelNative::~ScreenPanelNative()
|
||||
{
|
||||
OSD::DeInit();
|
||||
}
|
||||
|
||||
void ScreenPanelNative::setupScreenLayout()
|
||||
{
|
||||
int w = width();
|
||||
int h = height();
|
||||
|
||||
screenSetupLayout(w, h);
|
||||
ScreenPanel::setupScreenLayout();
|
||||
|
||||
for (int i = 0; i < numScreens; i++)
|
||||
{
|
||||
float* mtx = screenMatrix[i];
|
||||
screenTrans[i].setMatrix(mtx[0], mtx[1], 0.f,
|
||||
mtx[2], mtx[3], 0.f,
|
||||
mtx[4], mtx[5], 1.f);
|
||||
mtx[2], mtx[3], 0.f,
|
||||
mtx[4], mtx[5], 1.f);
|
||||
}
|
||||
}
|
||||
|
||||
@ -353,55 +642,32 @@ void ScreenPanelNative::paintEvent(QPaintEvent* event)
|
||||
}
|
||||
}
|
||||
|
||||
OSD::Update();
|
||||
OSD::DrawNative(painter);
|
||||
}
|
||||
|
||||
void ScreenPanelNative::resizeEvent(QResizeEvent* event)
|
||||
{
|
||||
setupScreenLayout();
|
||||
}
|
||||
|
||||
void ScreenPanelNative::mousePressEvent(QMouseEvent* event)
|
||||
{
|
||||
screenOnMousePress(event);
|
||||
}
|
||||
|
||||
void ScreenPanelNative::mouseReleaseEvent(QMouseEvent* event)
|
||||
{
|
||||
screenOnMouseRelease(event);
|
||||
}
|
||||
|
||||
void ScreenPanelNative::mouseMoveEvent(QMouseEvent* event)
|
||||
{
|
||||
screenOnMouseMove(event);
|
||||
}
|
||||
|
||||
void ScreenPanelNative::tabletEvent(QTabletEvent* event)
|
||||
{
|
||||
screenHandleTablet(event);
|
||||
}
|
||||
|
||||
bool ScreenPanelNative::event(QEvent* event)
|
||||
{
|
||||
if (event->type() == QEvent::TouchBegin
|
||||
|| event->type() == QEvent::TouchEnd
|
||||
|| event->type() == QEvent::TouchUpdate)
|
||||
osdUpdate();
|
||||
if (osdEnabled)
|
||||
{
|
||||
screenHandleTouch((QTouchEvent*)event);
|
||||
return true;
|
||||
osdMutex.lock();
|
||||
|
||||
u32 y = kOSDMargin;
|
||||
|
||||
painter.resetTransform();
|
||||
|
||||
for (auto it = osdItems.begin(); it != osdItems.end(); )
|
||||
{
|
||||
OSDItem& item = *it;
|
||||
|
||||
painter.drawImage(kOSDMargin, y, item.bitmap);
|
||||
|
||||
y += item.bitmap.height();
|
||||
it++;
|
||||
}
|
||||
|
||||
osdMutex.unlock();
|
||||
}
|
||||
return QWidget::event(event);
|
||||
}
|
||||
|
||||
void ScreenPanelNative::onScreenLayoutChanged()
|
||||
{
|
||||
setMinimumSize(screenGetMinSize());
|
||||
setupScreenLayout();
|
||||
}
|
||||
|
||||
|
||||
ScreenPanelGL::ScreenPanelGL(QWidget* parent) : QWidget(parent), ScreenHandler(this)
|
||||
|
||||
ScreenPanelGL::ScreenPanelGL(QWidget* parent) : ScreenPanel(parent)
|
||||
{
|
||||
setAutoFillBackground(false);
|
||||
setAttribute(Qt::WA_NativeWindow, true);
|
||||
@ -503,7 +769,41 @@ void ScreenPanelGL::initOpenGL()
|
||||
memset(zeroData, 0, sizeof(zeroData));
|
||||
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 192, 256, 2, GL_RGBA, GL_UNSIGNED_BYTE, zeroData);
|
||||
|
||||
OSD::Init(true);
|
||||
|
||||
OpenGL::BuildShaderProgram(kScreenVS_OSD, kScreenFS_OSD, osdShader, "OSDShader");
|
||||
|
||||
pid = osdShader[2];
|
||||
glBindAttribLocation(pid, 0, "vPosition");
|
||||
glBindFragDataLocation(pid, 0, "oColor");
|
||||
|
||||
OpenGL::LinkShaderProgram(osdShader);
|
||||
glUseProgram(pid);
|
||||
glUniform1i(glGetUniformLocation(pid, "OSDTex"), 0);
|
||||
|
||||
osdScreenSizeULoc = glGetUniformLocation(pid, "uScreenSize");
|
||||
osdPosULoc = glGetUniformLocation(pid, "uOSDPos");
|
||||
osdSizeULoc = glGetUniformLocation(pid, "uOSDSize");
|
||||
osdScaleFactorULoc = glGetUniformLocation(pid, "uScaleFactor");
|
||||
|
||||
const float osdvertices[6*2] =
|
||||
{
|
||||
0, 0,
|
||||
1, 1,
|
||||
1, 0,
|
||||
0, 0,
|
||||
0, 1,
|
||||
1, 1
|
||||
};
|
||||
|
||||
glGenBuffers(1, &osdVertexBuffer);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, osdVertexBuffer);
|
||||
glBufferData(GL_ARRAY_BUFFER, sizeof(osdvertices), osdvertices, GL_STATIC_DRAW);
|
||||
|
||||
glGenVertexArrays(1, &osdVertexArray);
|
||||
glBindVertexArray(osdVertexArray);
|
||||
glEnableVertexAttribArray(0); // position
|
||||
glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, (void*)(0));
|
||||
|
||||
|
||||
glContext->SetSwapInterval(Config::ScreenVSync ? Config::ScreenVSyncInterval : 0);
|
||||
transferLayout();
|
||||
@ -520,13 +820,52 @@ void ScreenPanelGL::deinitOpenGL()
|
||||
|
||||
OpenGL::DeleteShaderProgram(screenShaderProgram);
|
||||
|
||||
OSD::DeInit();
|
||||
|
||||
for (const auto& [key, tex] : osdTextures)
|
||||
{
|
||||
glDeleteTextures(1, &tex);
|
||||
}
|
||||
osdTextures.clear();
|
||||
|
||||
glDeleteVertexArrays(1, &osdVertexArray);
|
||||
glDeleteBuffers(1, &osdVertexBuffer);
|
||||
|
||||
OpenGL::DeleteShaderProgram(osdShader);
|
||||
|
||||
|
||||
glContext->DoneCurrent();
|
||||
|
||||
lastScreenWidth = lastScreenHeight = -1;
|
||||
}
|
||||
|
||||
void ScreenPanelGL::osdRenderItem(OSDItem* item)
|
||||
{
|
||||
ScreenPanel::osdRenderItem(item);
|
||||
|
||||
GLuint tex;
|
||||
glGenTextures(1, &tex);
|
||||
glBindTexture(GL_TEXTURE_2D, tex);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, item->bitmap.width(), item->bitmap.height(), 0, GL_RGBA, GL_UNSIGNED_BYTE, item->bitmap.bits());
|
||||
|
||||
osdTextures[item->id] = tex;
|
||||
}
|
||||
|
||||
void ScreenPanelGL::osdDeleteItem(OSDItem* item)
|
||||
{
|
||||
if (osdTextures.count(item->id))
|
||||
{
|
||||
GLuint tex = osdTextures[item->id];
|
||||
glDeleteTextures(1, &tex);
|
||||
osdTextures.erase(item->id);
|
||||
}
|
||||
|
||||
ScreenPanel::osdDeleteItem(item);
|
||||
}
|
||||
|
||||
void ScreenPanelGL::drawScreenGL()
|
||||
{
|
||||
if (!glContext) return;
|
||||
@ -590,8 +929,47 @@ void ScreenPanelGL::drawScreenGL()
|
||||
|
||||
screenSettingsLock.unlock();
|
||||
|
||||
OSD::Update();
|
||||
OSD::DrawGL(w, h, factor);
|
||||
osdUpdate();
|
||||
if (osdEnabled)
|
||||
{
|
||||
osdMutex.lock();
|
||||
|
||||
u32 y = kOSDMargin;
|
||||
|
||||
glUseProgram(osdShader[2]);
|
||||
|
||||
glUniform2f(osdScreenSizeULoc, w, h);
|
||||
glUniform1f(osdScaleFactorULoc, factor);
|
||||
|
||||
glBindBuffer(GL_ARRAY_BUFFER, osdVertexBuffer);
|
||||
glBindVertexArray(osdVertexArray);
|
||||
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
|
||||
glEnable(GL_BLEND);
|
||||
glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
|
||||
|
||||
for (auto it = osdItems.begin(); it != osdItems.end(); )
|
||||
{
|
||||
OSDItem& item = *it;
|
||||
|
||||
if (!osdTextures.count(item.id))
|
||||
continue;
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D, osdTextures[item.id]);
|
||||
glUniform2i(osdPosULoc, kOSDMargin, y);
|
||||
glUniform2i(osdSizeULoc, item.bitmap.width(), item.bitmap.height());
|
||||
glDrawArrays(GL_TRIANGLES, 0, 2*3);
|
||||
|
||||
y += item.bitmap.height();
|
||||
it++;
|
||||
}
|
||||
|
||||
glDisable(GL_BLEND);
|
||||
glUseProgram(0);
|
||||
|
||||
osdMutex.unlock();
|
||||
}
|
||||
|
||||
glContext->SwapBuffers();
|
||||
}
|
||||
@ -667,52 +1045,10 @@ QPaintEngine* ScreenPanelGL::paintEngine() const
|
||||
|
||||
void ScreenPanelGL::setupScreenLayout()
|
||||
{
|
||||
int w = width();
|
||||
int h = height();
|
||||
|
||||
screenSetupLayout(w, h);
|
||||
ScreenPanel::setupScreenLayout();
|
||||
transferLayout();
|
||||
}
|
||||
|
||||
void ScreenPanelGL::resizeEvent(QResizeEvent* event)
|
||||
{
|
||||
setupScreenLayout();
|
||||
|
||||
QWidget::resizeEvent(event);
|
||||
}
|
||||
|
||||
void ScreenPanelGL::mousePressEvent(QMouseEvent* event)
|
||||
{
|
||||
screenOnMousePress(event);
|
||||
}
|
||||
|
||||
void ScreenPanelGL::mouseReleaseEvent(QMouseEvent* event)
|
||||
{
|
||||
screenOnMouseRelease(event);
|
||||
}
|
||||
|
||||
void ScreenPanelGL::mouseMoveEvent(QMouseEvent* event)
|
||||
{
|
||||
screenOnMouseMove(event);
|
||||
}
|
||||
|
||||
void ScreenPanelGL::tabletEvent(QTabletEvent* event)
|
||||
{
|
||||
screenHandleTablet(event);
|
||||
}
|
||||
|
||||
bool ScreenPanelGL::event(QEvent* event)
|
||||
{
|
||||
if (event->type() == QEvent::TouchBegin
|
||||
|| event->type() == QEvent::TouchEnd
|
||||
|| event->type() == QEvent::TouchUpdate)
|
||||
{
|
||||
screenHandleTouch((QTouchEvent*)event);
|
||||
return true;
|
||||
}
|
||||
return QWidget::event(event);
|
||||
}
|
||||
|
||||
void ScreenPanelGL::transferLayout()
|
||||
{
|
||||
std::optional<WindowInfo> windowInfo = getWindowInfo();
|
||||
@ -734,9 +1070,3 @@ void ScreenPanelGL::transferLayout()
|
||||
screenSettingsLock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
void ScreenPanelGL::onScreenLayoutChanged()
|
||||
{
|
||||
setMinimumSize(screenGetMinSize());
|
||||
setupScreenLayout();
|
||||
}
|
||||
|
Reference in New Issue
Block a user