当前位置: 首页 > article >正文

【QA】Qt中直接渲染和离屏渲染有什么区别

直接渲染

在Qt里,直接在屏幕渲染是较为常见的操作,通常借助QWidget及其子类,通过重写paintEvent方法来达成。下面为你提供几个直接在屏幕渲染的示例。

示例一:绘制简单图形

此示例会在QWidget上绘制一个矩形和一个圆形。

#include <QApplication>
#include <QWidget>
#include <QPainter>

class MyWidget : public QWidget {
public:
    void paintEvent(QPaintEvent *event) override {
        Q_UNUSED(event);
        QPainter painter(this);

        // 绘制矩形
        painter.setPen(Qt::blue);
        painter.setBrush(Qt::green);
        painter.drawRect(50, 50, 100, 100);

        // 绘制圆形
        painter.setPen(Qt::red);
        painter.setBrush(Qt::yellow);
        painter.drawEllipse(200, 50, 100, 100);
    }
};

int main(int argc, char *argv[]) {
    QApplication a(argc, argv);
    MyWidget w;
    w.show();
    return a.exec();
}
代码解释
  1. 创建自定义QWidgetMyWidget继承自QWidget,并重写了paintEvent方法。
  2. 重写paintEvent方法:在该方法里创建QPainter对象,用于在QWidget上绘制图形。
  3. 绘制图形:借助drawRectdrawEllipse方法分别绘制矩形和圆形。

示例二:绘制文本

此示例会在QWidget上绘制一段文本。

#include <QApplication>
#include <QWidget>
#include <QPainter>
#include <QFont>

class MyWidget : public QWidget {
public:
    void paintEvent(QPaintEvent *event) override {
        Q_UNUSED(event);
        QPainter painter(this);

        // 设置字体
        QFont font("Arial", 24);
        painter.setFont(font);

        // 设置文本颜色
        painter.setPen(Qt::black);

        // 绘制文本
        painter.drawText(50, 50, "Hello, Qt!");
    }
};

int main(int argc, char *argv[]) {
    QApplication a(argc, argv);
    MyWidget w;
    w.show();
    return a.exec();
}
代码解释
  1. 设置字体:运用QFont类设置文本的字体和大小。
  2. 设置文本颜色:使用setPen方法设置文本的颜色。
  3. 绘制文本:通过drawText方法在指定位置绘制文本。

示例三:绘制图片

此示例会在QWidget上绘制一张图片。

#include <QApplication>
#include <QWidget>
#include <QPainter>
#include <QPixmap>

class MyWidget : public QWidget {
public:
    void paintEvent(QPaintEvent *event) override {
        Q_UNUSED(event);
        QPainter painter(this);

        // 加载图片
        QPixmap pixmap("path_to_your_image.jpg");
        if (!pixmap.isNull()) {
            // 绘制图片
            painter.drawPixmap(50, 50, pixmap);
        }
    }
};

int main(int argc, char *argv[]) {
    QApplication a(argc, argv);
    MyWidget w;
    w.show();
    return a.exec();
}
代码解释
  1. 加载图片:利用QPixmap类加载指定路径的图片。
  2. 绘制图片:若图片加载成功,使用drawPixmap方法在指定位置绘制图片。

这些示例都直接在屏幕上进行渲染,借助重写paintEvent方法,利用QPainter对象绘制不同的图形、文本和图片。


示例四:使用QOpenGL渲染

Qt 中的 QOpenGL 相关类是可以进行直接渲染的。下面为你详细介绍相关的原理、示例和解释。

原理

直接渲染指的是将图形数据直接绘制到屏幕上对应的缓冲区。在 Qt 里,QOpenGLWidget 类能实现直接渲染,它是一个专门用于 OpenGL 渲染的窗口部件,继承自 QWidget。当 QOpenGLWidget 接收到绘制事件时,会调用 paintGL 方法,在这个方法中可以使用 OpenGL 函数直接在屏幕上绘制图形。

示例代码

#include <QApplication>
#include <QOpenGLWidget>
#include <QOpenGLFunctions>

class OpenGLWidget : public QOpenGLWidget, protected QOpenGLFunctions
{
public:
    OpenGLWidget(QWidget *parent = nullptr) : QOpenGLWidget(parent) {}

protected:
    // 初始化 OpenGL 上下文
    void initializeGL() override
    {
        initializeOpenGLFunctions();
        glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
    }

    // 设置视口和投影矩阵
    void resizeGL(int w, int h) override
    {
        glViewport(0, 0, w, h);
    }

    // 进行 OpenGL 绘制
    void paintGL() override
    {
        glClear(GL_COLOR_BUFFER_BIT);

        glBegin(GL_TRIANGLES);
        glColor3f(1.0f, 0.0f, 0.0f);
        glVertex2f(-0.5f, -0.5f);
        glColor3f(0.0f, 1.0f, 0.0f);
        glVertex2f(0.5f, -0.5f);
        glColor3f(0.0f, 0.0f, 1.0f);
        glVertex2f(0.0f, 0.5f);
        glEnd();
    }
};

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);

    OpenGLWidget w;
    w.show();

    return a.exec();
}

代码解释

  1. 类的定义OpenGLWidget 继承自 QOpenGLWidgetQOpenGLFunctionsQOpenGLFunctions 提供了 OpenGL 函数的访问接口。
  2. initializeGL 方法:在这个方法中进行 OpenGL 上下文的初始化操作,例如调用 initializeOpenGLFunctions 来初始化 OpenGL 函数,设置清屏颜色。
  3. resizeGL 方法:当窗口大小改变时,这个方法会被调用,在其中设置视口的大小。
  4. paintGL 方法:这是进行 OpenGL 绘制的核心方法,在这个方法中首先清除颜色缓冲区,然后使用 glBeginglEnd 来定义一个三角形,并设置顶点的颜色和位置。
  5. 主函数:创建 QApplication 实例,创建 OpenGLWidget 对象并显示,最后进入应用程序的事件循环。

总结

通过 QOpenGLWidget 及其相关方法,能够在 Qt 中方便地实现 OpenGL 的直接渲染,开发者可以在 paintGL 方法中使用 OpenGL 函数进行各种图形的绘制。

离屏渲染

离屏渲染(Off-screen rendering)是一种图形渲染技术,它指的是在屏幕外的缓冲区中进行渲染操作,而不是直接在屏幕上进行绘制。完成渲染后,再将结果复制到屏幕上显示。下面结合Qt来详细介绍离屏渲染。

离屏渲染的原理

在传统的渲染过程中,图形数据会直接绘制到屏幕缓冲区,然后显示在屏幕上。而离屏渲染则是先将图形数据绘制到一个离屏缓冲区(也称为帧缓冲区对象,Frame Buffer Object,FBO),这个缓冲区并不直接对应屏幕上的显示区域。当离屏缓冲区完成渲染后,再将其中的内容传输到屏幕缓冲区进行显示。

离屏渲染的用途

  • 提高性能:在某些复杂的渲染场景中,离屏渲染可以避免频繁的屏幕刷新,减少渲染过程中的闪烁和卡顿现象,提高渲染效率。
  • 实现特效:通过离屏渲染可以方便地实现一些特效,如模糊、阴影等,因为可以在离屏缓冲区对图像进行处理后再显示。
  • 多步骤渲染:对于需要多个渲染步骤的场景,离屏渲染可以将每个步骤的结果保存下来,便于后续处理和组合。

Qt中的离屏渲染示例

在Qt中,可以使用QImageQPixmapQOpenGLFramebufferObject来实现离屏渲染。以下是一个使用QImage进行离屏渲染的示例:

#include <QApplication>
#include <QImage>
#include <QPainter>
#include <QLabel>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);

    // 创建一个离屏的QImage对象
    QImage offscreenImage(200, 200, QImage::Format_RGB32);
    offscreenImage.fill(Qt::white);

    // 创建一个QPainter对象,用于在离屏图像上进行绘制
    QPainter painter(&offscreenImage);

    // 设置画笔和画刷
    painter.setPen(Qt::blue);
    painter.setBrush(Qt::green);

    // 绘制一个矩形
    painter.drawRect(50, 50, 100, 100);

    // 结束绘制
    painter.end();

    // 创建一个QLabel对象,用于显示离屏渲染的结果
    QLabel label;
    label.setPixmap(QPixmap::fromImage(offscreenImage));
    label.show();

    return a.exec();
}

代码解释

  1. 创建离屏图像:使用QImage类创建一个200x200像素的离屏图像,并将其填充为白色。
  2. 创建QPainter对象:使用QPainter类在离屏图像上进行绘制操作。可以设置画笔和画刷的属性,然后调用drawRect方法绘制一个矩形。
  3. 结束绘制:调用painter.end()方法结束绘制操作。
  4. 显示结果:将离屏图像转换为QPixmap对象,并设置给QLabel对象进行显示。

使用QOpenGLFramebufferObject进行离屏渲染

对于更复杂的3D渲染场景,可以使用QOpenGLFramebufferObject进行离屏渲染。以下是一个简单的示例:

#include <QApplication>
#include <QOpenGLWidget>
#include <QOpenGLFramebufferObject>
#include <QOpenGLFunctions>
#include <QLabel>

class OffscreenRenderer : public QOpenGLWidget, protected QOpenGLFunctions
{
public:
    OffscreenRenderer(QWidget *parent = nullptr) : QOpenGLWidget(parent) {}

protected:
    void initializeGL() override
    {
        initializeOpenGLFunctions();
    }

    void paintGL() override
    {
        // 创建一个离屏帧缓冲区对象
        QOpenGLFramebufferObject fbo(200, 200);
        fbo.bind();

        // 清除颜色缓冲区
        glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
        glClear(GL_COLOR_BUFFER_BIT);

        // 设置视口
        glViewport(0, 0, 200, 200);

        // 绘制一个三角形
        glBegin(GL_TRIANGLES);
        glColor3f(1.0f, 0.0f, 0.0f);
        glVertex2f(-0.5f, -0.5f);
        glColor3f(0.0f, 1.0f, 0.0f);
        glVertex2f(0.5f, -0.5f);
        glColor3f(0.0f, 0.0f, 1.0f);
        glVertex2f(0.0f, 0.5f);
        glEnd();

        // 解除绑定
        fbo.release();

        // 将离屏渲染的结果保存为QImage
        QImage image = fbo.toImage();

        // 创建一个QLabel对象,用于显示离屏渲染的结果
        QLabel label;
        label.setPixmap(QPixmap::fromImage(image));
        label.show();
    }
};

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);

    OffscreenRenderer renderer;
    renderer.show();

    return a.exec();
}

代码解释

  1. 创建离屏帧缓冲区对象:使用QOpenGLFramebufferObject类创建一个200x200像素的离屏帧缓冲区对象,并将其绑定。
  2. 进行渲染操作:在离屏帧缓冲区对象上进行OpenGL渲染操作,如清除颜色缓冲区、设置视口、绘制三角形等。
  3. 解除绑定:渲染完成后,解除离屏帧缓冲区对象的绑定。
  4. 保存结果:将离屏渲染的结果保存为QImage对象,并显示在QLabel上。

通过上述示例可以看到,在Qt中可以方便地使用离屏渲染技术来实现复杂的图形渲染效果。


http://www.kler.cn/a/599088.html

相关文章:

  • 爬虫入门re+bs4
  • 构建高效的LinkedIn图像爬取工具
  • 《Operating System Concepts》阅读笔记:p460-p4470
  • stc8g1k08a+cd4017红绿灯
  • Linux 文件操作-文件IO函数2- write向文件写入数据、read从文件读取数据、lseek重定位文件描述符的偏移量的验证
  • (UI自动化测试web端)第二篇:元素定位的方法_xpath路径定位
  • 记录 macOS 上使用 Homebrew 安装的软件
  • 批量删除或替换多个 PPT 文档中的首页、尾页或其它任意范围的页
  • 【实战指南】用MongoDB存储文档和图片等大文件(Java实现)
  • EasyRTC嵌入式音视频通话SDK:微信生态支持、轻量化架构与跨平台兼容性(Linix/Windows/ARM/Android/iOS/LiteOS)
  • Windows安装Jenkins配置Allure踩坑,必须单独配置当前windows系统为新的node节点,才可在工具位置中指定节点服务器allure的位置
  • and滚动下拉加载
  • 【无标题】vue项目,浏览器打印时,永远只显示一页的问题
  • JSX入门
  • 第31章:Istio安全:mTLS与服务间身份认证
  • Python爬虫获取Shopee店铺的所有商品?
  • git使用经验(一)
  • 算法方法快速回顾
  • leetcode 的T5 最长回文字符串
  • 【Linux之Shell脚本实战】Linux服务器输出美观漂亮的html巡检报告