我正在尝试在我的教育项目中使用Qt和OpenGL。我做的第一步-我在Qt文档中找到了openglwindow示例,并复制了它以了解这些东西应该如何工作。这个例子:example with explanations和所有源代码:repository的
我用与原始cmake有点不同的cmake构建了这个,因为(正如我所读到的)我的qt版本与doc中的qt版本不同。下面是我的CMakeLists.txt:
cmake_minimum_required(VERSION 3.16)
project(openglwindow LANGUAGES CXX)
set(CMAKE_AUTOMOC ON)
set(CMAKE_AUTORCC ON)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
if(NOT DEFINED INSTALL_EXAMPLESDIR)
set(INSTALL_EXAMPLESDIR "src")
endif()
set(INSTALL_EXAMPLEDIR "${INSTALL_EXAMPLESDIR}/test_view/build")
find_package(Qt6 REQUIRED COMPONENTS Core Gui OpenGL)
# qt_standard_project_setup()
qt_add_executable(openglwindow
main.cpp
openglwindow.cpp openglwindow.h
)
set_target_properties(openglwindow PROPERTIES
WIN32_EXECUTABLE TRUE
MACOSX_BUNDLE TRUE
)
target_link_libraries(openglwindow PRIVATE
Qt6::Core
Qt6::Gui
Qt6::OpenGL
)
install(TARGETS openglwindow
RUNTIME DESTINATION "${INSTALL_EXAMPLEDIR}"
BUNDLE DESTINATION "${INSTALL_EXAMPLEDIR}"
LIBRARY DESTINATION "${INSTALL_EXAMPLEDIR}"
)
字符串
main.cpp:
#include "openglwindow.h"
#include <QGuiApplication>
#include <QMatrix4x4>
#include <QOpenGLShaderProgram>
#include <QScreen>
#include <QtMath>
class TriangleWindow : public OpenGLWindow
{
public:
using OpenGLWindow::OpenGLWindow;
void initialize() override;
void render() override;
private:
GLint m_posAttr = 0;
GLint m_colAttr = 0;
GLint m_matrixUniform = 0;
QOpenGLShaderProgram *m_program = nullptr;
int m_frame = 0;
};
int main(int argc, char **argv)
{
QGuiApplication app(argc, argv);
QSurfaceFormat format;
format.setSamples(16);
TriangleWindow window;
window.setFormat(format);
window.resize(640, 480);
window.show();
window.setAnimating(true);
return app.exec();
}
static const char *vertexShaderSource =
"attribute highp vec4 posAttr;\n"
"attribute lowp vec4 colAttr;\n"
"varying lowp vec4 col;\n"
"uniform highp mat4 matrix;\n"
"void main() {\n"
" col = colAttr;\n"
" gl_Position = matrix * posAttr;\n"
"}\n";
static const char *fragmentShaderSource =
"varying lowp vec4 col;\n"
"void main() {\n"
" gl_FragColor = col;\n"
"}\n";
void TriangleWindow::initialize()
{
m_program = new QOpenGLShaderProgram(this);
m_program->addShaderFromSourceCode(QOpenGLShader::Vertex, vertexShaderSource);
m_program->addShaderFromSourceCode(QOpenGLShader::Fragment, fragmentShaderSource);
m_program->link();
m_posAttr = m_program->attributeLocation("posAttr");
Q_ASSERT(m_posAttr != -1);
m_colAttr = m_program->attributeLocation("colAttr");
Q_ASSERT(m_colAttr != -1);
m_matrixUniform = m_program->uniformLocation("matrix");
Q_ASSERT(m_matrixUniform != -1);
}
void TriangleWindow::render()
{
const qreal retinaScale = devicePixelRatio();
glViewport(0, 0, width() * retinaScale, height() * retinaScale);
glClear(GL_COLOR_BUFFER_BIT);
m_program->bind();
QMatrix4x4 matrix;
matrix.perspective(60.0f, 4.0f / 3.0f, 0.1f, 100.0f);
matrix.translate(0, 0, -2);
matrix.rotate(100.0f * m_frame / screen()->refreshRate(), 0, 1, 0);
m_program->setUniformValue(m_matrixUniform, matrix);
static const GLfloat vertices[] = {
0.0f, 0.707f,
-0.5f, -0.5f,
0.5f, -0.5f
};
static const GLfloat colors[] = {
1.0f, 0.0f, 0.0f,
0.0f, 1.0f, 0.0f,
0.0f, 0.0f, 1.0f
};
glVertexAttribPointer(m_posAttr, 2, GL_FLOAT, GL_FALSE, 0, vertices);
glVertexAttribPointer(m_colAttr, 3, GL_FLOAT, GL_FALSE, 0, colors);
glEnableVertexAttribArray(m_posAttr);
glEnableVertexAttribArray(m_colAttr);
glDrawArrays(GL_TRIANGLES, 0, 3);
glDisableVertexAttribArray(m_colAttr);
glDisableVertexAttribArray(m_posAttr);
m_program->release();
++m_frame;
}
型
openglwindow.h:
#ifndef OPENGLWINDOW_H
#define OPENGLWINDOW_H
#include <QWindow>
#include <QOpenGLFunctions>
QT_FORWARD_DECLARE_CLASS(QPainter)
QT_FORWARD_DECLARE_CLASS(QOpenGLContext)
QT_FORWARD_DECLARE_CLASS(QOpenGLPaintDevice)
class OpenGLWindow : public QWindow, protected QOpenGLFunctions
{
Q_OBJECT
public:
explicit OpenGLWindow(QWindow *parent = nullptr);
~OpenGLWindow();
virtual void render(QPainter *painter);
virtual void render();
virtual void initialize();
void setAnimating(bool animating);
public slots:
void renderLater();
void renderNow();
protected:
bool event(QEvent *event) override;
void exposeEvent(QExposeEvent *event) override;
private:
bool m_animating = false;
QOpenGLContext *m_context = nullptr;
QOpenGLPaintDevice *m_device = nullptr;
};
#endif // OPENGLWINDOW_H
型
openglwindow.cpp:
#include "openglwindow.h"
#include <QOpenGLContext>
#include <QOpenGLPaintDevice>
#include <QPainter>
OpenGLWindow::OpenGLWindow(QWindow *parent)
: QWindow(parent)
{
setSurfaceType(QWindow::OpenGLSurface);
}
OpenGLWindow::~OpenGLWindow()
{
delete m_device;
}
void OpenGLWindow::render(QPainter *painter)
{
Q_UNUSED(painter);
}
void OpenGLWindow::initialize()
{
}
void OpenGLWindow::render()
{
if (!m_device)
m_device = new QOpenGLPaintDevice;
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
m_device->setSize(size() * devicePixelRatio());
m_device->setDevicePixelRatio(devicePixelRatio());
QPainter painter(m_device);
render(&painter);
}
void OpenGLWindow::renderLater()
{
requestUpdate();
}
bool OpenGLWindow::event(QEvent *event)
{
switch (event->type()) {
case QEvent::UpdateRequest:
renderNow();
return true;
default:
return QWindow::event(event);
}
}
void OpenGLWindow::exposeEvent(QExposeEvent *event)
{
Q_UNUSED(event);
if (isExposed())
renderNow();
}
void OpenGLWindow::renderNow()
{
if (!isExposed())
return;
bool needsInitialize = false;
if (!m_context) {
m_context = new QOpenGLContext(this);
m_context->setFormat(requestedFormat());
m_context->create();
needsInitialize = true;
}
m_context->makeCurrent(this);
if (needsInitialize) {
initializeOpenGLFunctions();
initialize();
}
render();
m_context->swapBuffers(this);
if (m_animating)
renderLater();
}
void OpenGLWindow::setAnimating(bool animating)
{
m_animating = animating;
if (animating)
renderLater();
}
型
这里一切都很好,项目建设。但它不工作,我不知道为什么。因此,我有一个空的黑色窗口,没有任何三角形:execution当我使用fsanitize=address和valgrind检查内存泄漏时,两者都显示内存泄漏。在我解决它为什么能工作之前我不能再进一步了。也许是因为Qt版本之间的差异,这是我唯一的假设。
1条答案
按热度按时间p1iqtdky1#
字符串
在这段代码中,您将16设置为驱动程序的MSAA样本。(16x MSAA)
在这里,您应该知道支持的驱动程序的MSAA示例的最大数量随环境而异。可能您的环境不支持16x MSAA,这就是发生此问题的原因。
如果您的项目是用于实际用途,那么最好检查执行环境支持的驱动程序MSAA示例的最大数量,然后选择适当的示例。(How to determine the maximum number of supported multisample samples)
然而,在您的情况下,由于您的项目是用于业余爱好,我认为选择较低的2或4就足够了。