1. 修复了以Debug编译时显示实时FPS信息显示,在嵌入式Linux上不显示的问题:直接以img的方式显示,防止因为Qt交叉编译等原因产生的找不到系统字体之类的问题
This commit is contained in:
@@ -95,7 +95,7 @@ private:
|
||||
PttButton *pttButton; /// 嵌入式平台PTT按钮
|
||||
#endif
|
||||
#ifdef YOSUGA_DEBUG
|
||||
FpsOverlay fpsOverlay; /// 调试用FPS显示
|
||||
FpsOverlay *fpsOverlay = nullptr; /// 调试用FPS显示
|
||||
#endif
|
||||
|
||||
bool isLeftPressed; /// 鼠标左键是否按下
|
||||
|
||||
@@ -87,6 +87,10 @@ GLCore::GLCore(const int width, const int height, QWidget *parent)
|
||||
// 启用鼠标跟踪,不启用的话鼠标按下才会回调mouseMoveEvent函数
|
||||
this->setMouseTracking(true);
|
||||
|
||||
#ifdef YOSUGA_DEBUG
|
||||
fpsOverlay = new FpsOverlay(this);
|
||||
#endif
|
||||
|
||||
// 连接一些必要的信号与槽
|
||||
#ifndef EMBEDDED_LINUX // 如果不是嵌入式Linux系统(注意如果你的嵌入式Linux平台启用了桌面系统,那么可能需要去掉这个条件宏)
|
||||
connect(contextMenu, &Menu::closeMainWindow, this, &GLCore::closeGL); // 关闭窗口信号
|
||||
@@ -330,7 +334,7 @@ void GLCore::initializeGL()
|
||||
}
|
||||
|
||||
#ifndef EMBEDDED_LINUX
|
||||
// 初始化GLEW 必须在任何Live2D渲染操作之前调用
|
||||
// 由于加入了对嵌入式平台的支持,因此桌面平台需要手动初始化GLEW 必须在任何Live2D渲染操作之前调用
|
||||
// Live2D预编译的libFramework.a使用GLEW函数指针(如glGenFramebuffers等),
|
||||
// 未调用glewInit()会导致空指针解引用SIGSEGV
|
||||
glewExperimental = GL_TRUE;
|
||||
@@ -356,8 +360,7 @@ void GLCore::paintGL()
|
||||
TextRenderer::getInstance()->update();
|
||||
TextRenderer::getInstance()->render();
|
||||
#ifdef YOSUGA_DEBUG
|
||||
fpsOverlay.tick();
|
||||
fpsOverlay.draw(width(), height());
|
||||
fpsOverlay->tick();
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -371,6 +374,9 @@ void GLCore::resizeGL(const int w, const int h)
|
||||
#ifdef EMBEDDED_LINUX
|
||||
pttButton->updateLayout(w, h);
|
||||
#endif
|
||||
#ifdef YOSUGA_DEBUG
|
||||
if (fpsOverlay) fpsOverlay->renderToPixmap(); // 窗口大小变化时重算位置
|
||||
#endif
|
||||
}
|
||||
|
||||
// 设置窗口大小,并触发 resizeGL 事件
|
||||
|
||||
@@ -1,33 +1,33 @@
|
||||
#pragma once
|
||||
|
||||
#ifdef YOSUGA_DEBUG
|
||||
|
||||
#include <QElapsedTimer>
|
||||
#include <QString>
|
||||
#include <QLabel>
|
||||
|
||||
class QTimer;
|
||||
class QElapsedTimer;
|
||||
|
||||
class FpsOverlay
|
||||
class FpsOverlay : public QLabel
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
FpsOverlay();
|
||||
explicit FpsOverlay(QWidget* parent = nullptr);
|
||||
~FpsOverlay();
|
||||
|
||||
void tick();
|
||||
void draw(int parentWidth, int parentHeight);
|
||||
void renderToPixmap(); // 离线渲染文字到 pixmap
|
||||
|
||||
|
||||
float rightMargin = 0.03f;
|
||||
float topMargin = 0.03f;
|
||||
int fontSize = 20;
|
||||
int fontSize = 18;
|
||||
|
||||
private:
|
||||
QElapsedTimer _elapsed;
|
||||
QTimer* _timer = nullptr;
|
||||
QElapsedTimer* _elapsed = nullptr;
|
||||
int _frameCount = 0;
|
||||
int _displayedFps = 0;
|
||||
QString _text = "FPS: --";
|
||||
|
||||
void recalcFps();
|
||||
};
|
||||
|
||||
#endif
|
||||
#endif
|
||||
@@ -1,22 +1,78 @@
|
||||
#ifdef YOSUGA_DEBUG
|
||||
#include "FpsOverlay.hpp"
|
||||
#include <QPainter>
|
||||
#include <QOpenGLPaintDevice>
|
||||
#include <QTimer>
|
||||
#include <QElapsedTimer>
|
||||
#include <QFont>
|
||||
#include <QFontMetrics>
|
||||
#include <QFontDatabase>
|
||||
#include <QImage>
|
||||
#include <QPainter>
|
||||
#include <QPixmap>
|
||||
#include <QFile>
|
||||
#include <cstdio>
|
||||
|
||||
FpsOverlay::FpsOverlay()
|
||||
FpsOverlay::FpsOverlay(QWidget* parent)
|
||||
: QLabel(parent)
|
||||
{
|
||||
_timer = new QTimer;
|
||||
setAttribute(Qt::WA_TransparentForMouseEvents);
|
||||
setAlignment(Qt::AlignCenter);
|
||||
raise();
|
||||
show();
|
||||
|
||||
// 尝试加载系统字体
|
||||
QStringList fontPaths = {
|
||||
"/usr/share/fonts/noto/NotoSansCJK-Regular.ttc",
|
||||
"/usr/share/fonts/noto/NotoSans-Regular.ttf",
|
||||
"/usr/share/fonts/noto/NotoSansCJKsc-Regular.otf",
|
||||
"/usr/share/fonts/TTF/DejaVuSans.ttf",
|
||||
"/usr/share/fonts/truetype/dejavu/DejaVuSans.ttf"
|
||||
};
|
||||
|
||||
bool loaded = false;
|
||||
for (const QString& path : fontPaths) {
|
||||
if (QFile::exists(path)) {
|
||||
int id = QFontDatabase::addApplicationFont(path);
|
||||
if (id != -1) {
|
||||
QString family = QFontDatabase::applicationFontFamilies(id).first();
|
||||
QFont f(family, fontSize);
|
||||
f.setBold(true);
|
||||
setFont(f);
|
||||
fprintf(stderr, "[FpsOverlay] Loaded font: %s from %s\n",
|
||||
family.toUtf8().constData(), path.toUtf8().constData());
|
||||
loaded = true;
|
||||
break;
|
||||
} else {
|
||||
fprintf(stderr, "[FpsOverlay] addApplicationFont failed: %s\n",
|
||||
path.toUtf8().constData());
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!loaded) {
|
||||
// fallback:不指定字体族,用 Qt 默认
|
||||
QFont f = font();
|
||||
f.setPointSize(fontSize);
|
||||
f.setBold(true);
|
||||
setFont(f);
|
||||
fprintf(stderr, "[FpsOverlay] WARNING: No font loaded, using default: %s\n",
|
||||
font().family().toUtf8().constData());
|
||||
}
|
||||
|
||||
// 先显示初始帧
|
||||
_displayedFps = 0;
|
||||
renderToPixmap();
|
||||
|
||||
_elapsed = new QElapsedTimer;
|
||||
_elapsed->start();
|
||||
|
||||
_timer = new QTimer(this);
|
||||
_timer->setTimerType(Qt::PreciseTimer);
|
||||
QObject::connect(_timer, &QTimer::timeout, [this]() { recalcFps(); });
|
||||
connect(_timer, &QTimer::timeout, this, &FpsOverlay::recalcFps);
|
||||
_timer->start(1000);
|
||||
_elapsed.start();
|
||||
}
|
||||
|
||||
FpsOverlay::~FpsOverlay()
|
||||
{
|
||||
delete _timer;
|
||||
delete _elapsed;
|
||||
}
|
||||
|
||||
void FpsOverlay::tick()
|
||||
@@ -24,48 +80,61 @@ void FpsOverlay::tick()
|
||||
++_frameCount;
|
||||
}
|
||||
|
||||
void FpsOverlay::draw(int parentWidth, int parentHeight)
|
||||
void FpsOverlay::renderToPixmap()
|
||||
{
|
||||
QOpenGLPaintDevice device(QSize(parentWidth, parentHeight));
|
||||
QPainter painter(&device);
|
||||
painter.setRenderHint(QPainter::Antialiasing);
|
||||
QString text = QString("FPS: %1").arg(_displayedFps);
|
||||
|
||||
QFont f;
|
||||
f.setPixelSize(fontSize);
|
||||
f.setBold(true);
|
||||
f.setStyleHint(QFont::Monospace);
|
||||
// 计算尺寸
|
||||
QFontMetrics fm(font());
|
||||
const int padX = 12;
|
||||
const int padY = 8;
|
||||
const int textW = fm.horizontalAdvance(text);
|
||||
const int textH = fm.height();
|
||||
const int w = textW + padX * 2;
|
||||
const int h = textH + padY * 2;
|
||||
|
||||
QFontMetrics fm(f);
|
||||
const int pad = 8;
|
||||
const int textW = fm.horizontalAdvance(_text) + pad * 2;
|
||||
const int textH = fm.height() + pad;
|
||||
const int x = parentWidth - textW - static_cast<int>(parentWidth * rightMargin);
|
||||
const int y = static_cast<int>(parentHeight * topMargin);
|
||||
// 父窗口大小决定位置
|
||||
int parentW = parentWidget() ? parentWidget()->width() : 1080;
|
||||
int parentH = parentWidget() ? parentWidget()->height() : 1920;
|
||||
const int x = parentW - w - static_cast<int>(parentW * rightMargin);
|
||||
const int y = static_cast<int>(parentH * topMargin);
|
||||
|
||||
painter.setBrush(QColor(0, 0, 0, 180));
|
||||
painter.setPen(Qt::NoPen);
|
||||
painter.drawRoundedRect(x, y, textW, textH, 4, 4);
|
||||
// 设置几何位置
|
||||
setGeometry(x, y, w, h);
|
||||
|
||||
painter.setFont(f);
|
||||
const QColor fg = _displayedFps <= 0 ? QColor(170, 170, 170) :
|
||||
_displayedFps <= 30 ? QColor(255, 68, 68) :
|
||||
_displayedFps <= 45 ? QColor(255, 170, 0) :
|
||||
QColor( 68, 255, 68);
|
||||
painter.setPen(fg);
|
||||
painter.drawText(QRect(x + pad, y, textW - pad * 2, textH),
|
||||
Qt::AlignVCenter | Qt::AlignLeft, _text);
|
||||
// 用 QImage 离线渲染,不依赖 QLabel 的字体系统
|
||||
QImage img(w, h, QImage::Format_ARGB32);
|
||||
img.fill(Qt::transparent); // 透明
|
||||
|
||||
QPainter p(&img);
|
||||
p.setRenderHint(QPainter::Antialiasing);
|
||||
|
||||
// 文字颜色:根据 FPS 变色
|
||||
const QColor fg = _displayedFps <= 0 ? QColor(170, 170, 170) :
|
||||
_displayedFps <= 30 ? QColor(255, 68, 68) :
|
||||
_displayedFps <= 45 ? QColor(255, 170, 0) :
|
||||
QColor( 68, 255, 68);
|
||||
p.setPen(fg);
|
||||
p.setFont(font());
|
||||
p.drawText(img.rect(), Qt::AlignCenter, text);
|
||||
p.end();
|
||||
|
||||
setPixmap(QPixmap::fromImage(img));
|
||||
}
|
||||
|
||||
void FpsOverlay::recalcFps()
|
||||
{
|
||||
const qint64 ms = _elapsed.elapsed();
|
||||
const qint64 ms = _elapsed->elapsed();
|
||||
if (ms == 0) return;
|
||||
|
||||
_displayedFps = static_cast<int>(_frameCount * 1000.0 / ms);
|
||||
_frameCount = 0;
|
||||
_elapsed.restart();
|
||||
_frameCount = 0;
|
||||
_elapsed->restart();
|
||||
|
||||
_text = QString("FPS: %1").arg(_displayedFps);
|
||||
fprintf(stderr, "[FPS] %s\n", _text.toUtf8().constData());
|
||||
// fprintf(stderr, "[FPS] %d\n", _displayedFps);
|
||||
|
||||
// 重新渲染为 pixmap
|
||||
renderToPixmap();
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user