保存时间:2026/4/2 04:32:11
glClearColor 函数设置清除颜色,例如 glClearColor(1.0f, 1.0f, 1.0f, 1.0f) 将清除颜色设置为白色。glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT) 来清除颜色缓冲区和深度缓冲区。glEnable(GL_DEPTH_TEST) 开启深度测试。glDepthFunc(GL_LESS)。glBufferData 或 glBufferSubData 函数将顶点数据和索引数据上传到 GPU 缓冲区。QWindow和QDrawable在使用 OpenGL 进行渲染时有以下一些不同:QOpenGLFunctions、QOpenGLContext等)来进行 OpenGL 渲染。QWindow提供了更强大的渲染控制和交互能力。QWindow更适合用于创建完整的窗口并进行复杂的 OpenGL 渲染和交互,而QDrawable则更灵活,可以用于各种特定的绘图场景,但需要更多的手动管理和设置。选择使用哪个取决于具体的应用需求和渲染场景。QWindow 和 OpenGL 进行简单渲染的“Hello World”示例程序:#include <QGuiApplication>
#include <QWindow>
#include <QOpenGLContext>
#include <QOpenGLFunctions>
#include <QSurfaceFormat>
class OpenGLWindow : public QWindow, protected QOpenGLFunctions
{
public:
OpenGLWindow()
{
setSurfaceType(QWindow::OpenGLSurface);
QSurfaceFormat format;
format.setVersion(3, 3);
format.setProfile(QSurfaceFormat::CoreProfile);
setFormat(format);
}
protected:
void exposeEvent(QExposeEvent *) override
{
if (isExposed())
render();
}
void render()
{
if (!isExposed())
return;
glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);
swapBuffers();
}
};
int main(int argc, char *argv[])
{
QGuiApplication app(argc, argv);
OpenGLWindow window;
window.show();
return app.exec();
}
OpenGLWindow 类,继承自 QWindow 并实现了 OpenGL 渲染功能。在 render 函数中,设置了清除颜色并进行了简单的渲染操作。当窗口暴露时,会触发 exposeEvent 并调用 render 函数进行渲染。swapBuffers是QWindow的一个函数。swapBuffers通常用于交换前后缓冲区,将渲染结果显示在屏幕上。swapBuffers之前,确保已经创建并激活了有效的 OpenGL 上下文。QOpenGLContext以及正确使用swapBuffers:#include <QGuiApplication>
#include <QWindow>
#include <QOpenGLContext>
#include <QOpenGLFunctions>
#include <QSurfaceFormat>
class OpenGLWindow : public QWindow, protected QOpenGLFunctions
{
public:
OpenGLWindow()
{
setSurfaceType(QWindow::OpenGLSurface);
QSurfaceFormat format;
format.setVersion(3, 3);
format.setProfile(QSurfaceFormat::CoreProfile);
setFormat(format);
m_context = new QOpenGLContext(this);
m_context->setFormat(format);
if (!m_context->create())
{
qCritical() << "Failed to create OpenGL context.";
return;
}
}
protected:
void exposeEvent(QExposeEvent *) override
{
if (isExposed())
render();
}
void render()
{
if (!isExposed())
return;
if (!m_context->makeCurrent(this))
{
qCritical() << "Failed to make context current.";
return;
}
glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);
m_context->swapBuffers(this);
m_context->doneCurrent();
}
private:
QOpenGLContext *m_context;
};
int main(int argc, char *argv[])
{
QGuiApplication app(argc, argv);
OpenGLWindow window;
window.show();
return app.exec();
}
QOpenGLContext对象,并设置了和窗口相同的格式。如果创建失败,会输出错误信息。render函数中,首先调用makeCurrent将当前上下文设置为与当前窗口关联的上下文,然后进行渲染操作,最后调用swapBuffers交换缓冲区,并调用doneCurrent结束当前上下文的使用。qDebug(),需要包含 <QDebug> 头文件。同时,确保你的项目中正确链接了 Qt 的核心库。#include <QGuiApplication>
#include <QWindow>
#include <QOpenGLContext>
#include <QOpenGLFunctions>
#include <QSurfaceFormat>
#include <QDebug> // 添加这一行
class OpenGLWindow : public QWindow, protected QOpenGLFunctions
{
public:
OpenGLWindow()
{
setSurfaceType(QWindow::OpenGLSurface);
QSurfaceFormat format;
format.setVersion(3, 3);
format.setProfile(QSurfaceFormat::CoreProfile);
setFormat(format);
m_context = new QOpenGLContext(this);
m_context->setFormat(format);
if (!m_context->create())
{
qCritical() << "Failed to create OpenGL context.";
return;
}
}
protected:
void exposeEvent(QExposeEvent *) override
{
if (isExposed())
render();
}
void render()
{
if (!isExposed())
return;
if (!m_context->makeCurrent(this))
{
qCritical() << "Failed to make context current.";
return;
}
glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);
m_context->swapBuffers(this);
m_context->doneCurrent();
}
private:
QOpenGLContext *m_context;
};
int main(int argc, char *argv[])
{
QGuiApplication app(argc, argv);
OpenGLWindow window;
window.show();
return app.exec();
}
QOpenGLContext 对象后,正确设置了格式并且上下文创建成功。可以在创建上下文后添加一些调试输出,以确认上下文是否成功创建。if (!m_context->create())
{
qCritical() << "Failed to create OpenGL context.";
return;
}
qDebug() << "OpenGL context created successfully.";
glClearColor 和其他 OpenGL 函数时,上下文已经被正确设置为当前上下文。在 render 函数中,可以再次确认上下文的当前状态。if (!m_context->makeCurrent(this))
{
qCritical() << "Failed to make context current.";
return;
}
qDebug() << "Context is current.";
QOpenGLFunctions 的类中,可以在构造函数或合适的初始化函数中调用 initializeOpenGLFunctions() 来加载函数指针。OpenGLWindow()
{
//...
initializeOpenGLFunctions();
}
QOpenGLFunctions_3_3_Core 类来明确指定 OpenGL 版本和核心配置,并手动加载函数指针。glClearColor 出现核心转储的原因,并正确初始化 OpenGL 上下文以进行渲染。QWindow和QOpenGLContext时,都需要调用它们的create方法以确保正确初始化。以下是修正后的代码示例:#include <QGuiApplication>
#include <QWindow>
#include <QOpenGLContext>
#include <QOpenGLFunctions>
#include <QSurfaceFormat>
#include <QDebug>
class OpenGLWindow : public QWindow, protected QOpenGLFunctions
{
public:
OpenGLWindow()
{
setSurfaceType(QWindow::OpenGLSurface);
QSurfaceFormat format;
format.setVersion(3, 3);
format.setProfile(QSurfaceFormat::CoreProfile);
setFormat(format);
m_context = new QOpenGLContext(this);
m_context->setFormat(format);
if (!m_context->create())
{
qCritical() << "Failed to create OpenGL context.";
return;
}
if (!create()) // 添加这一行,确保 QWindow 也正确创建
{
qCritical() << "Failed to create QWindow.";
return;
}
}
protected:
void exposeEvent(QExposeEvent *) override
{
if (isExposed())
render();
}
void render()
{
if (!isExposed())
return;
if (!m_context->makeCurrent(this))
{
qCritical() << "Failed to make context current.";
return;
}
glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);
m_context->swapBuffers(this);
m_context->doneCurrent();
}
private:
QOpenGLContext *m_context;
};
int main(int argc, char *argv[])
{
QGuiApplication app(argc, argv);
OpenGLWindow window;
window.show();
return app.exec();
}
#include <QGuiApplication>
#include <QWindow>
#include <QOpenGLContext>
#include <QOpenGLFunctions>
#include <QSurfaceFormat>
#include <QDebug>
class OpenGLWindow : public QWindow, protected QOpenGLFunctions
{
public:
OpenGLWindow()
{
setSurfaceType(QWindow::OpenGLSurface);
QSurfaceFormat format;
format.setVersion(3, 3);
format.setProfile(QSurfaceFormat::CoreProfile);
setFormat(format);
m_context = new QOpenGLContext(this);
m_context->setFormat(format);
if (!m_context->create())
{
qCritical() << "Failed to create OpenGL context.";
return;
}
create();
if (!isValid()) // 使用 isValid 检查窗口是否成功创建
{
qCritical() << "Failed to create QWindow.";
return;
}
}
protected:
void exposeEvent(QExposeEvent *) override
{
if (isExposed())
render();
}
void render()
{
if (!isExposed())
return;
if (!m_context->makeCurrent(this))
{
qCritical() << "Failed to make context current.";
return;
}
glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);
m_context->swapBuffers(this);
m_context->doneCurrent();
}
private:
QOpenGLContext *m_context;
};
int main(int argc, char *argv[])
{
QGuiApplication app(argc, argv);
OpenGLWindow window;
window.show();
return app.exec();
}
isValid()函数来检查QWindow是否成功创建。QWindow 和 OpenGL 的窗口上输出 “Hello, World!” 这样的文字,可以使用以下步骤:#include <QGuiApplication>
#include <QWindow>
#include <QOpenGLContext>
#include <QOpenGLFunctions>
#include <QSurfaceFormat>
#include <QPainter>
#include <QFont>
#include <QDebug>
class OpenGLWindow : public QWindow, protected QOpenGLFunctions
{
public:
OpenGLWindow()
{
setSurfaceType(QWindow::OpenGLSurface);
QSurfaceFormat format;
format.setVersion(3, 3);
format.setProfile(QSurfaceFormat::CoreProfile);
setFormat(format);
m_context = new QOpenGLContext(this);
m_context->setFormat(format);
if (!m_context->create())
{
qCritical() << "Failed to create OpenGL context.";
return;
}
create();
if (!isValid())
{
qCritical() << "Failed to create QWindow.";
return;
}
}
protected:
void exposeEvent(QExposeEvent *) override
{
if (isExposed())
render();
}
void render()
{
if (!isExposed())
return;
if (!m_context->makeCurrent(this))
{
qCritical() << "Failed to make context current.";
return;
}
glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);
QPainter painter(this);
painter.begin(this);
painter.setFont(QFont("Arial", 20));
painter.setPen(Qt::white);
painter.drawText(rect(), Qt::AlignCenter, "Hello, World!");
painter.end();
m_context->swapBuffers(this);
m_context->doneCurrent();
}
private:
QOpenGLContext *m_context;
};
render 函数中,使用 QPainter 在窗口上绘制文本 “Hello, World!”。首先创建 QPainter 对象并将其关联到当前窗口,设置字体和颜色,然后使用 drawText 方法绘制文本,最后结束绘画并交换缓冲区。QPainter的构造函数可以接受一个QPaintDevice *类型的参数,而QWindow继承自QPaintDevice,所以从理论上来说可以将QWindow指针作为参数传递给QPainter的构造函数。#include <QGuiApplication>
#include <QWindow>
#include <QOpenGLContext>
#include <QOpenGLFunctions>
#include <QSurfaceFormat>
#include <QPainter>
#include <QFont>
#include <QDebug>
class OpenGLWindow : public QWindow, protected QOpenGLFunctions
{
public:
OpenGLWindow()
{
setSurfaceType(QWindow::OpenGLSurface);
QSurfaceFormat format;
format.setVersion(3, 3);
format.setProfile(QSurfaceFormat::CoreProfile);
setFormat(format);
m_context = new QOpenGLContext(this);
m_context->setFormat(format);
if (!m_context->create())
{
qCritical() << "Failed to create OpenGL context.";
return;
}
create();
if (!isValid())
{
qCritical() << "Failed to create QWindow.";
return;
}
}
protected:
void exposeEvent(QExposeEvent *) override
{
if (isExposed())
render();
}
void render()
{
if (!isExposed())
return;
if (!m_context->makeCurrent(this))
{
qCritical() << "Failed to make context current.";
return;
}
glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);
QPainter painter(this);
painter.begin(this);
painter.setFont(QFont("Arial", 20));
painter.setPen(Qt::white);
painter.drawText(rect(), Qt::AlignCenter, "Hello, World!");
painter.end();
m_context->swapBuffers(this);
m_context->doneCurrent();
}
private:
QOpenGLContext *m_context;
};
int main(int argc, char *argv[])
{
QGuiApplication app(argc, argv);
OpenGLWindow window;
window.show();
return app.exec();
}
QWindow不是继承自 QPaintDevice,可以考虑以下方法在窗口上绘制文本:#include <QGuiApplication>
#include <QWindow>
#include <QOpenGLContext>
#include <QOpenGLFunctions>
#include <QSurfaceFormat>
#include <QDebug>
#include <QPainter>
#include <QPaintEvent>
class OpenGLWindow : public QWindow, protected QOpenGLFunctions
{
public:
OpenGLWindow()
{
setSurfaceType(QWindow::OpenGLSurface);
QSurfaceFormat format;
format.setVersion(3, 3);
format.setProfile(QSurfaceFormat::CoreProfile);
setFormat(format);
m_context = new QOpenGLContext(this);
m_context->setFormat(format);
if (!m_context->create())
{
qCritical() << "Failed to create OpenGL context.";
return;
}
create();
if (!isValid())
{
qCritical() << "Failed to create QWindow.";
return;
}
}
protected:
void exposeEvent(QExposeEvent *) override
{
if (isExposed())
render();
}
void render()
{
if (!isExposed())
return;
if (!m_context->makeCurrent(this))
{
qCritical() << "Failed to make context current.";
return;
}
glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);
m_context->swapBuffers(this);
m_context->doneCurrent();
}
void paintEvent(QPaintEvent *event)
{
Q_UNUSED(event);
QPainter painter;
painter.begin(this);
painter.setFont(QFont("Arial", 20));
painter.setPen(Qt::white);
painter.drawText(rect(), Qt::AlignCenter, "Hello, World!");
painter.end();
}
private:
QOpenGLContext *m_context;
};
int main(int argc, char *argv[])
{
QGuiApplication app(argc, argv);
OpenGLWindow window;
window.show();
return app.exec();
}
paintEvent方法,使用 QPainter在窗口上绘制文本。在 paintEvent中,确保 QPainter正确地在窗口上进行绘制操作。QWindow 作为 QPainter 的参数,可以尝试以下方法:#include <QGuiApplication>
#include <QWindow>
#include <QOpenGLContext>
#include <QOpenGLFunctions>
#include <QSurfaceFormat>
#include <QDebug>
#include <QPaintEvent>
#include <QImage>
class OpenGLWindow : public QWindow, protected QOpenGLFunctions
{
public:
OpenGLWindow()
{
setSurfaceType(QWindow::OpenGLSurface);
QSurfaceFormat format;
format.setVersion(3, 3);
format.setProfile(QSurfaceFormat::CoreProfile);
setFormat(format);
m_context = new QOpenGLContext(this);
m_context->setFormat(format);
if (!m_context->create())
{
qCritical() << "Failed to create OpenGL context.";
return;
}
create();
if (!isValid())
{
qCritical() << "Failed to create QWindow.";
return;
}
}
protected:
void exposeEvent(QExposeEvent *) override
{
if (isExposed())
render();
}
void render()
{
if (!isExposed())
return;
if (!m_context->makeCurrent(this))
{
qCritical() << "Failed to make context current.";
return;
}
glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);
QImage image(size(), QImage::Format_ARGB32);
image.fill(Qt::transparent);
QPainter painter(&image);
painter.setFont(QFont("Arial", 20));
painter.setPen(Qt::white);
painter.drawText(image.rect(), Qt::AlignCenter, "Hello, World!");
QPainter windowPainter(this);
windowPainter.drawImage(rect(), image);
m_context->swapBuffers(this);
m_context->doneCurrent();
}
private:
QOpenGLContext *m_context;
};
int main(int argc, char *argv[])
{
QGuiApplication app(argc, argv);
OpenGLWindow window;
window.show();
return app.exec();
}
QImage 上绘制文本,然后再将这个 QImage 绘制到窗口上。这样可以绕过 QPainter 不能直接以 QWindow 为参数的问题。QBackingStore 来间接实现绘制:#include <QGuiApplication>
#include <QWindow>
#include <QOpenGLContext>
#include <QOpenGLFunctions>
#include <QSurfaceFormat>
#include <QDebug>
#include <QPaintEvent>
#include <QBackingStore>
#include <QPainter>
class OpenGLWindow : public QWindow, protected QOpenGLFunctions
{
public:
OpenGLWindow()
{
setSurfaceType(QWindow::OpenGLSurface);
QSurfaceFormat format;
format.setVersion(3, 3);
format.setProfile(QSurfaceFormat::CoreProfile);
setFormat(format);
m_context = new QOpenGLContext(this);
m_context->setFormat(format);
if (!m_context->create())
{
qCritical() << "Failed to create OpenGL context.";
return;
}
create();
if (!isValid())
{
qCritical() << "Failed to create QWindow.";
return;
}
m_backingStore = new QBackingStore(this);
}
protected:
void exposeEvent(QExposeEvent *) override
{
if (isExposed())
render();
}
void render()
{
if (!isExposed())
return;
if (!m_context->makeCurrent(this))
{
qCritical() << "Failed to make context current.";
return;
}
glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);
QRect rect = this->geometry();
QImage image(rect.size(), QImage::Format_ARGB32);
image.fill(Qt::transparent);
QPainter painter(&image);
painter.setFont(QFont("Arial", 20));
painter.setPen(Qt::white);
painter.drawText(image.rect(), Qt::AlignCenter, "Hello, World!");
QPaintDevice *device = m_backingStore->paintDevice();
QPainter windowPainter(device);
windowPainter.drawImage(rect.topLeft(), image);
m_backingStore->flush(rect);
m_context->swapBuffers(this);
m_context->doneCurrent();
}
private:
QOpenGLContext *m_context;
QBackingStore *m_backingStore;
};
int main(int argc, char *argv[])
{
QGuiApplication app(argc, argv);
OpenGLWindow window;
window.show();
return app.exec();
}
QBackingStore 对象,通过它的 paintDevice 获取一个可以被 QPainter 使用的绘制设备,然后在这个设备上进行绘制操作,最后将绘制结果显示在窗口上。QWidget作为绘制目标,再将其绘制到窗口上:#include <QGuiApplication>
#include <QWindow>
#include <QOpenGLContext>
#include <QOpenGLFunctions>
#include <QSurfaceFormat>
#include <QDebug>
#include <QPaintEvent>
#include <QWidget>
#include <QPainter>
class OpenGLWindow : public QWindow, protected QOpenGLFunctions
{
public:
OpenGLWindow()
{
setSurfaceType(QWindow::OpenGLSurface);
QSurfaceFormat format;
format.setVersion(3, 3);
format.setProfile(QSurfaceFormat::CoreProfile);
setFormat(format);
m_context = new QOpenGLContext(this);
m_context->setFormat(format);
if (!m_context->create())
{
qCritical() << "Failed to create OpenGL context.";
return;
}
create();
if (!isValid())
{
qCritical() << "Failed to create QWindow.";
return;
}
}
protected:
void exposeEvent(QExposeEvent *) override
{
if (isExposed())
render();
}
void render()
{
if (!isExposed())
return;
if (!m_context->makeCurrent(this))
{
qCritical() << "Failed to make context current.";
return;
}
glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);
QWidget tempWidget;
tempWidget.resize(size());
QPainter painter(&tempWidget);
painter.setFont(QFont("Arial", 20));
painter.setPen(Qt::white);
painter.drawText(tempWidget.rect(), Qt::AlignCenter, "Hello, World!");
QPainter windowPainter(this);
windowPainter.drawPixmap(rect(), tempWidget.grab());
m_context->swapBuffers(this);
m_context->doneCurrent();
}
private:
QOpenGLContext *m_context;
};
int main(int argc, char *argv[])
{
QGuiApplication app(argc, argv);
OpenGLWindow window;
window.show();
return app.exec();
}
QWidget,在上面进行绘制,然后将其内容抓取为QPixmap并绘制到窗口上。QOpenGLPaintDevice并将其设置为绘制目标:#include <QGuiApplication>
#include <QWindow>
#include <QOpenGLContext>
#include <QOpenGLFunctions>
#include <QSurfaceFormat>
#include <QDebug>
#include <QPaintEvent>
#include <QOpenGLPaintDevice>
#include <QPainter>
class OpenGLWindow : public QWindow, protected QOpenGLFunctions
{
public:
OpenGLWindow()
{
setSurfaceType(QWindow::OpenGLSurface);
QSurfaceFormat format;
format.setVersion(3, 3);
format.setProfile(QSurfaceFormat::CoreProfile);
setFormat(format);
m_context = new QOpenGLContext(this);
m_context->setFormat(format);
if (!m_context->create())
{
qCritical() << "Failed to create OpenGL context.";
return;
}
create();
if (!isValid())
{
qCritical() << "Failed to create QWindow.";
return;
}
}
protected:
void exposeEvent(QExposeEvent *) override
{
if (isExposed())
render();
}
void render()
{
if (!isExposed())
return;
if (!m_context->makeCurrent(this))
{
qCritical() << "Failed to make context current.";
return;
}
glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);
QOpenGLPaintDevice *device = new QOpenGLPaintDevice(size());
QPainter painter(device);
painter.setFont(QFont("Arial", 20));
painter.setPen(Qt::white);
painter.drawText(device->rect(), Qt::AlignCenter, "Hello, World!");
QPainter windowPainter(this);
windowPainter.drawImage(rect(), device->toImage());
delete device;
m_context->swapBuffers(this);
m_context->doneCurrent();
}
private:
QOpenGLContext *m_context;
};
int main(int argc, char *argv[])
{
QGuiApplication app(argc, argv);
OpenGLWindow window;
window.show();
return app.exec();
}
QOpenGLPaintDevice对象作为绘制目标,在上面绘制文本后,再将其转换为QImage并绘制到窗口上。#include <QGuiApplication>
#include <QWindow>
#include <QOpenGLContext>
#include <QOpenGLFunctions>
#include <QSurfaceFormat>
#include <QDebug>
#include <QPaintEvent>
#include <QOpenGLPaintDevice>
#include <QPainter>
class OpenGLWindow : public QWindow, protected QOpenGLFunctions
{
public:
OpenGLWindow()
{
setSurfaceType(QWindow::OpenGLSurface);
QSurfaceFormat format;
format.setVersion(3, 3);
format.setProfile(QSurfaceFormat::CoreProfile);
setFormat(format);
m_context = new QOpenGLContext(this);
m_context->setFormat(format);
if (!m_context->create())
{
qCritical() << "Failed to create OpenGL context.";
return;
}
create();
if (!isValid())
{
qCritical() << "Failed to create QWindow.";
return;
}
}
protected:
void exposeEvent(QExposeEvent *) override
{
if (isExposed())
render();
}
void render()
{
if (!isExposed())
return;
if (!m_context->makeCurrent(this))
{
qCritical() << "Failed to make context current.";
return;
}
glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);
QOpenGLPaintDevice *device = new QOpenGLPaintDevice(size());
QPainter painter(device);
painter.setFont(QFont("Arial", 20));
painter.setPen(Qt::white);
QRect rect(0, 0, device->width(), device->height());
painter.drawText(rect, Qt::AlignCenter, "Hello, World!");
QPainter windowPainter(this);
windowPainter.drawImage(rect(), device->toImage());
delete device;
m_context->swapBuffers(this);
m_context->doneCurrent();
}
private:
QOpenGLContext *m_context;
};
int main(int argc, char *argv[])
{
QGuiApplication app(argc, argv);
OpenGLWindow window;
window.show();
return app.exec();
}
QRect对象来替代之前错误的调用。QPainter windowPainter(device)。QWindow)上绘制内容,而不是在临时创建的QOpenGLPaintDevice上再次绘制。QPainter windowPainter(this)是正确的,它将以当前的QWindow对象作为绘制目标,将之前在QOpenGLPaintDevice上绘制好的内容通过windowPainter.drawImage绘制到窗口上。QWidget作为中介并利用QPainter在其上绘制后再将结果绘制到QWindow的方法:#include <QGuiApplication>
#include <QWindow>
#include <QOpenGLContext>
#include <QOpenGLFunctions>
#include <QSurfaceFormat>
#include <QDebug>
#include <QWidget>
#include <QPainter>
class OpenGLWidget : public QWidget
{
public:
OpenGLWidget()
{
setFixedSize(640, 480);
}
protected:
void paintEvent(QPaintEvent *event) override
{
Q_UNUSED(event);
QPainter painter(this);
painter.setFont(QFont("Arial", 20));
painter.setPen(Qt::white);
painter.drawText(rect(), Qt::AlignCenter, "Hello, World!");
}
};
class OpenGLWindow : public QWindow, protected QOpenGLFunctions
{
public:
OpenGLWindow()
{
setSurfaceType(QWindow::OpenGLSurface);
QSurfaceFormat format;
format.setVersion(3, 3);
format.setProfile(QSurfaceFormat::CoreProfile);
setFormat(format);
m_context = new QOpenGLContext(this);
m_context->setFormat(format);
if (!m_context->create())
{
qCritical() << "Failed to create OpenGL context.";
return;
}
create();
if (!isValid())
{
qCritical() << "Failed to create QWindow.";
return;
}
}
protected:
void exposeEvent(QExposeEvent *) override
{
if (isExposed())
render();
}
void render()
{
if (!isExposed())
return;
if (!m_context->makeCurrent(this))
{
qCritical() << "Failed to make context current.";
return;
}
glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);
OpenGLWidget widget;
QPixmap pixmap = widget.grab();
QPainter windowPainter(this);
windowPainter.drawPixmap(rect(), pixmap);
m_context->swapBuffers(this);
m_context->doneCurrent();
}
private:
QOpenGLContext *m_context;
};
int main(int argc, char *argv[])
{
QGuiApplication app(argc, argv);
OpenGLWindow window;
window.show();
return app.exec();
}
OpenGLWidget,在其上使用QPainter绘制文本,然后在OpenGLWindow的render方法中,将这个QWidget抓取为QPixmap并绘制到窗口上。QPaintDevice的类上使用QPainter,而QWindow不满足这个条件的话,可以考虑以下方法:QOpenGLWidget,在这个类中进行 OpenGL 初始化和绘制文本的操作。QOpenGLWidget设置为QWindow的中心窗口部件(central widget)。#include <QGuiApplication>
#include <QWindow>
#include <QOpenGLContext>
#include <QOpenGLFunctions>
#include <QSurfaceFormat>
#include <QDebug>
#include <QOpenGLWidget>
#include <QPainter>
class MyOpenGLWidget : public QOpenGLWidget
{
public:
MyOpenGLWidget(QWidget *parent = nullptr) : QOpenGLWidget(parent) {}
protected:
void paintEvent(QPaintEvent *event) override
{
Q_UNUSED(event);
QPainter painter(this);
painter.setFont(QFont("Arial", 20));
painter.setPen(Qt::white);
painter.drawText(rect(), Qt::AlignCenter, "Hello, World!");
}
};
class OpenGLWindow : public QWindow, protected QOpenGLFunctions
{
public:
OpenGLWindow()
{
setSurfaceType(QWindow::OpenGLSurface);
QSurfaceFormat format;
format.setVersion(3, 3);
format.setProfile(QSurfaceFormat::CoreProfile);
setFormat(format);
m_context = new QOpenGLContext(this);
m_context->setFormat(format);
if (!m_context->create())
{
qCritical() << "Failed to create OpenGL context.";
return;
}
create();
if (!isValid())
{
qCritical() << "Failed to create QWindow.";
return;
}
// 创建自定义的 OpenGL 部件并设置为中心窗口部件
m_openglWidget = new MyOpenGLWidget();
setCentralWidget(m_openglWidget);
}
private:
QOpenGLContext *m_context;
MyOpenGLWidget *m_openglWidget;
};
int main(int argc, char *argv[])
{
QGuiApplication app(argc, argv);
OpenGLWindow window;
window.show();
return app.exec();
}
MyOpenGLWidget类继承自QOpenGLWidget,在其中重写paintEvent方法来绘制文本。然后在OpenGLWindow类中创建这个自定义部件的实例,并将其设置为窗口的中心窗口部件。这样就可以在窗口中显示绘制有“Hello, World!”的部件。MyOpenGLWidget设置为QWindow的中心窗口部件的代码示例:#include <QGuiApplication>
#include <QWindow>
#include <QOpenGLContext>
#include <QOpenGLFunctions>
#include <QSurfaceFormat>
#include <QDebug>
#include <QOpenGLWidget>
#include <QPainter>
class MyOpenGLWidget : public QOpenGLWidget
{
public:
MyOpenGLWidget(QWidget *parent = nullptr) : QOpenGLWidget(parent) {}
protected:
void paintEvent(QPaintEvent *event) override
{
Q_UNUSED(event);
QPainter painter(this);
painter.setFont(QFont("Arial", 20));
painter.setPen(Qt::white);
painter.drawText(rect(), Qt::AlignCenter, "Hello, World!");
}
};
class OpenGLWindow : public QWindow, protected QOpenGLFunctions
{
public:
OpenGLWindow()
{
setSurfaceType(QWindow::OpenGLSurface);
QSurfaceFormat format;
format.setVersion(3, 3);
format.setProfile(QSurfaceFormat::CoreProfile);
setFormat(format);
m_context = new QOpenGLContext(this);
m_context->setFormat(format);
if (!m_context->create())
{
qCritical() << "Failed to create OpenGL context.";
return;
}
create();
if (!isValid())
{
qCritical() << "Failed to create QWindow.";
return;
}
// 创建自定义的 OpenGL 部件
m_openglWidget = new MyOpenGLWidget();
// 设置中心窗口部件
setCentralWidget(m_openglWidget);
// 设置窗口大小适应部件
resize(m_openglWidget->size());
}
private:
QOpenGLContext *m_context;
MyOpenGLWidget *m_openglWidget;
};
int main(int argc, char *argv[])
{
QGuiApplication app(argc, argv);
OpenGLWindow window;
window.show();
return app.exec();
}
OpenGLWindow类的实例,然后在构造函数中进行了一系列的初始化操作,包括设置窗口的表面类型、格式等。接着创建了一个MyOpenGLWidget的实例作为自定义的 OpenGL 部件,并将其设置为窗口的中心窗口部件。最后,调整窗口大小以适应部件的大小并显示窗口。setCentralWidget是QMainWindow的方法,而不是QWindow的方法。QWindow中显示一个自定义的QWidget或类似的组件,可以考虑以下方法:QWindow的paintEvent或exposeEvent中手动绘制自定义组件的内容。QWidget作为容器,将自定义组件添加到这个容器中,然后在QWindow中显示这个容器(可能需要一些手动的绘制和布局管理)。QWindow的paintEvent中手动绘制一个类似于QWidget的内容:#include <QGuiApplication>
#include <QWindow>
#include <QPainter>
class MyWidgetContent
{
public:
void paint(QPainter *painter)
{
painter->setFont(QFont("Arial", 20));
painter->setPen(Qt::white);
painter->drawText(QRect(0, 0, 400, 300), Qt::AlignCenter, "Hello, World!");
}
};
class OpenGLWindow : public QWindow
{
public:
OpenGLWindow()
{
setSurfaceType(QWindow::OpenGLSurface);
create();
if (!isValid())
{
qCritical() << "Failed to create QWindow.";
return;
}
}
protected:
void paintEvent(QPaintEvent *event) override
{
Q_UNUSED(event);
QPainter painter(this);
MyWidgetContent content;
content.paint(&painter);
}
};
int main(int argc, char *argv[])
{
QGuiApplication app(argc, argv);
OpenGLWindow window;
window.show();
return app.exec();
}
MyWidgetContent类来模拟一个小部件的绘制逻辑,然后在OpenGLWindow的paintEvent中调用这个类的paint方法来绘制内容。#include <QGuiApplication>
#include <QMainWindow>
#include <QOpenGLContext>
#include <QOpenGLFunctions>
#include <QSurfaceFormat>
#include <QDebug>
#include <QOpenGLWidget>
#include <QPainter>
class MyOpenGLWidget : public QOpenGLWidget
{
public:
MyOpenGLWidget(QWidget *parent = nullptr) : QOpenGLWidget(parent) {}
protected:
void paintEvent(QPaintEvent *event) override
{
Q_UNUSED(event);
QPainter painter(this);
painter.setFont(QFont("Arial", 20));
painter.setPen(Qt::white);
painter.drawText(rect(), Qt::AlignCenter, "Hello, World!");
}
};
class OpenGLWindow : public QMainWindow, protected QOpenGLFunctions
{
public:
OpenGLWindow()
{
setSurfaceType(QWindow::OpenGLSurface);
QSurfaceFormat format;
format.setVersion(3, 3);
format.setProfile(QSurfaceFormat::CoreProfile);
setFormat(format);
m_context = new QOpenGLContext(this);
m_context->setFormat(format);
if (!m_context->create())
{
qCritical() << "Failed to create OpenGL context.";
return;
}
create();
if (!isValid())
{
qCritical() << "Failed to create QWindow.";
return;
}
// 创建自定义的 OpenGL 部件
m_openglWidget = new MyOpenGLWidget();
// 设置中心窗口部件
setCentralWidget(m_openglWidget);
}
private:
QOpenGLContext *m_context;
MyOpenGLWidget *m_openglWidget;
};
int main(int argc, char *argv[])
{
QGuiApplication app(argc, argv);
OpenGLWindow window;
window.show();
return app.exec();
}
OpenGLWindow继承自QMainWindow,可以使用setCentralWidget方法来设置中心部件。这样就可以在窗口中显示包含 “Hello, World!” 文本的自定义QOpenGLWidget。CMAKE_POLICY(VERSION...) command sets the minimum version of CMake policies to consider. The policy CMP0063 is related to the handling of generator expressions in target properties.cmake_policy(VERSION...) to explicitly set the policy version.CMP0063 to understand what changes it brings and how it might affect your project.cmake_policy(VERSION <version>) at the top of your CMakeLists.txt file. For example:cmake_policy(VERSION 3.20)
<version> with the appropriate CMake version that you want to target. This will ensure that CMake uses a specific set of policies and you can avoid warnings related to newer policies being used without your knowledge.CMP0071、CMP0063、CMP0054、CMP0042均是 CMake 中的策略编号,用于控制 CMake 的不同行为以保持向后兼容性。以下是对它们的具体解释:automoc 和 autouic 处理生成的文件。在 3.10 版本之前,CMake 在 automoc 和 auto uic 中仅处理常规源文件,对生成的源文件会默默地忽略;3.10 及以上版本,则会像处理常规源文件一样处理生成的源文件。旧的行为是忽略 automoc 和 auto uic 中的生成源文件,新的行为是对其进行处理。<lang>_visibility_preset 和 visibility_in_lines_hidden 等目标属性会影响动态链接期间符号的可见性。最初这些属性仅影响共享库、模块库以及设置了 enable_exports 属性的可执行文件的源文件编译。但有些源文件可能先被编译为静态库或对象库,之后再链接到共享库中,从 CMake 3.3 及以上版本开始,倾向于对所有目标类型的源文件都遵守这些可见性属性。旧行为是忽略静态库、对象库和没有导出的可执行文件的可见性属性,新行为是对所有目标类型都遵守可见性属性。if() 的参数解释为变量或关键字。在 CMake 3.1 及以上版本中,如果 if() 命令的参数是加引号的或在括号内的,将不再隐式解引用变量或解释关键字。旧行为是即使参数加引号或在括号内也会解引用变量和解释关键字,新行为是对加引号或在括号内的参数不进行解引用和关键字解释。