Обработанные изображения OpenGL не могут отображаться в окне QMLC++

Программы на C++. Форум разработчиков
Ответить Пред. темаСлед. тема
Anonymous
 Обработанные изображения OpenGL не могут отображаться в окне QML

Сообщение Anonymous »

Я создал быстрый визуальный пользовательский компонент в C ++, который использует OpenGL для рендеринга. Но когда программа работает, я не вижу, что я рендерирую
Вопрос : как я могу увидеть изображение в окне?
Вот мой тестовый пример, который предназначен для визуализации локального изображения в окно.

Код: Выделить всё

#include 
#include 

#include"GLVideoWidget.h"

int main(int argc, char *argv[])
{
QGuiApplication app(argc, argv);

QQuickWindow::setGraphicsApi(QSGRendererInterface::OpenGL);

QQmlApplicationEngine engine;
QObject::connect(
&engine,
&QQmlApplicationEngine::objectCreationFailed,
&app,
[]() { QCoreApplication::exit(-1);  },
Qt::QueuedConnection);

qmlRegisterType("AvCom", 1, 0, "GLVideoWidget");

engine.loadFromModule("test", "Main");

return app.exec();
}
< /code>
glvideowidget.h
#ifndef PICTUREVIEW_H
#define PICTUREVIEW_H

#include 
#include 
#include 
#include 
#include 
#include 
#include 

class VideoGLRenderer;

class GLVideoWidget : public QQuickItem
{
Q_OBJECT
QML_ELEMENT
public:
GLVideoWidget(QQuickItem *parent = nullptr);
~GLVideoWidget();

public slots:
void handleWindowChanged(QQuickWindow *window);
void guiSync();
void cleanup();

protected:
void releaseResources() override;

private:
VideoGLRenderer *vgl_renderer;

};

class QOpenGLShaderProgram;
class QOpenGLBuffer;
class QOpenGLVertexArrayObject;
class QOpenGLTexture;

class VideoGLRenderer : public QObject,
protected QOpenGLFunctions

{
Q_OBJECT

public:
explicit VideoGLRenderer(QObject *parent = nullptr);
~VideoGLRenderer();

public slots:
void initRenderer();
void paint();
void setWindow(QQuickWindow *window);

protected:
private:
QQuickWindow *quick_window;
QOpenGLShaderProgram *shader_program;
QOpenGLBuffer *vbo;
QOpenGLBuffer *ebo;
QOpenGLVertexArrayObject *vao;
QOpenGLTexture *video_frame_texture;

QMutex mutex;

};

#endif // PICTUREVIEW_H
< /code>
glvideowidget.cpp
#include "GLVideoWidget.h"

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 

GLVideoWidget::GLVideoWidget(QQuickItem *parent)
: QQuickItem(parent)
, vgl_renderer(nullptr)

{
setFlag(ItemHasContents, true);

connect(this, &QQuickItem::windowChanged, this, &GLVideoWidget::handleWindowChanged);

}

GLVideoWidget::~GLVideoWidget()
{

}

void GLVideoWidget::handleWindowChanged(QQuickWindow *window)
{
if (window) {
connect(window, &QQuickWindow::beforeSynchronizing, this, &GLVideoWidget::guiSync, Qt::DirectConnection);
connect(window, &QQuickWindow::sceneGraphInvalidated, this, &GLVideoWidget::cleanup, Qt::DirectConnection);
}
}

void GLVideoWidget::guiSync()
{
if (this->vgl_renderer == nullptr) {
this->vgl_renderer = new VideoGLRenderer(this);

connect(window(), &QQuickWindow::beforeRendering, this->vgl_renderer, &VideoGLRenderer::initRenderer,
Qt::DirectConnection);
connect(window(), &QQuickWindow::beforeRenderPassRecording, this->vgl_renderer, &VideoGLRenderer::paint,
Qt::DirectConnection);

}
this->vgl_renderer->setWindow(window());
}

void GLVideoWidget::cleanup()
{
delete this->vgl_renderer;
this->vgl_renderer = nullptr;
}

class VideoRenderer;

class CleanupJob : public QRunnable
{
public:
CleanupJob(VideoGLRenderer *renderer) : renderer(renderer) {}

void run() override
{
if (this->renderer) {

delete this->renderer;
}
}

private:
VideoGLRenderer *renderer;
};

void GLVideoWidget::releaseResources()
{
window()->scheduleRenderJob(new CleanupJob(this->vgl_renderer), QQuickWindow::BeforeSynchronizingStage);
this->vgl_renderer = nullptr;
}

VideoGLRenderer::VideoGLRenderer(QObject *parent) : quick_window(nullptr), shader_program(nullptr){}

VideoGLRenderer::~VideoGLRenderer() { }

void VideoGLRenderer::initRenderer()
{
QString vertexSource = R"(
#version 330 core
layout(location = 0) in vec3 vPosition;
layout(location = 1) in vec2 vTexCoord;
out vec2 TexCoord;
uniform mat4 zoomMatrix;
void main() {
gl_Position = zoomMatrix * vec4(vPosition, 1.0);
TexCoord = vTexCoord;
}
)";

QString fragSource = R"(
#version 330 core
in vec2 TexCoord;
out vec4 FragColor;
uniform sampler2D frameTexture;
uniform bool IsTextureValid;
void main() {
if(!IsTextureValid)
{
FragColor = vec4(0.0,0.0,0.0,1.0);
} else {
FragColor = texture(frameTexture, TexCoord);
}
}
)";

if (this->shader_program != nullptr)
return;

QSGRendererInterface *rif = this->quick_window->rendererInterface();
Q_ASSERT(rif->graphicsApi() == QSGRendererInterface::OpenGL);

initializeOpenGLFunctions();

this->shader_program = new QOpenGLShaderProgram();
if (!this->shader_program->addShaderFromSourceCode(QOpenGLShader::Vertex, vertexSource))
qDebug() shader_program->log();
if (!this->shader_program->addShaderFromSourceCode(QOpenGLShader::Fragment, fragSource))
qDebug() shader_program->log();
if (!this->shader_program->link())
qDebug() shader_program->log();

QVector vertices = {
// positions         // texture coords
-1.0f, 1.0f,  0.0f, 0.0f, 1.0f, // top left
-1.0f, -1.0f, 0.0f, 0.0f, 0.0f, // bottom left
1.0f,  -1.0f, 0.0f, 1.0f, 0.0f, // bottom right
1.0f,  1.0f,  0.0f, 1.0f, 1.0f, // top right
};

QVector indices = {
0, 1, 2, 2, 3, 0,
};

this->vao = new QOpenGLVertexArrayObject();
this->vbo = new QOpenGLBuffer(QOpenGLBuffer::VertexBuffer);
this->ebo = new QOpenGLBuffer(QOpenGLBuffer::IndexBuffer);

this->vao->create();
this->vbo->create();
this->ebo->create();

this->vao->bind();
this->vbo->bind();
this->ebo->bind();

this->vbo->allocate(vertices.constData(), vertices.size() * sizeof(GLfloat));
this->ebo->allocate(indices.constData(), indices.size() * sizeof(GLuint));

this->shader_program->bind();

this->shader_program->setAttributeBuffer("vPosition", GL_FLOAT, 0, 3, 5 * sizeof(GLfloat));
this->shader_program->enableAttributeArray(0);
this->shader_program->setAttributeBuffer("vTexCoord", GL_FLOAT, 3 * sizeof(GLfloat), 2, 5 * sizeof(GLfloat));
this->shader_program->enableAttributeArray(1);

this->vao->release();

this->video_frame_texture = new QOpenGLTexture(QOpenGLTexture::Target2D);
this->video_frame_texture->setMagnificationFilter(QOpenGLTexture::Linear);
this->video_frame_texture->setMinificationFilter(QOpenGLTexture::Linear);
this->video_frame_texture->setWrapMode(QOpenGLTexture::Repeat);
}

void VideoGLRenderer::paint()
{
bool isTextureValid;
QMatrix4x4 zoom;

this->quick_window->beginExternalCommands();

glDisable(GL_DEPTH_TEST);

glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);

//The path needs to be replaced
QImage img("E:/qt_project/qmlTestProject/test/fufu.png");
if (img.isNull()) {

return;
}

video_frame_texture->destroy();
video_frame_texture->create();

video_frame_texture->setData(img.mirrored());

isTextureValid = true;

this->shader_program->bind();
this->shader_program->setUniformValue("IsTextureValid", isTextureValid);

this->vao->bind();
if (isTextureValid) {

this->video_frame_texture->bind(0);
}
this->shader_program->setUniformValue("zoomMatrix", zoom);

glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);

this->vao->release();
this->shader_program->release();
if (isTextureValid)
this->video_frame_texture->release();

this->quick_window->endExternalCommands();
}

void VideoGLRenderer::setWindow(QQuickWindow *window) { this->quick_window = window;  }
< /code>
main.qml
import QtQuick
import QtQuick.Dialogs
import QtQuick.Controls 2.3
import QtCore

import AvCom

ApplicationWindow {
id: appWindow
title: qsTr("MavPlayer")
visible: true
width: 1600
height: 920
color: 'white'

menuBar: MenuBar {
Menu {
title: qsTr("file")
MenuItem {
text: qsTr("open")
}
}
}

GLVideoWidget {
id: videoView

anchors.left: appWindow.left
anchors.right: appWindow.right
anchors.top: appWindow.menuBar.bottom
anchors.bottom: play_progress.top
anchors.leftMargin: 0
anchors.rightMargin: 0
anchors.topMargin: 5
anchors.bottomMargin: 5

}

Slider {
id: play_progress

value: 0.5
anchors.left: parent.left
anchors.right: parent.right
anchors.bottom: displayControlBar.top
anchors.leftMargin: 0
anchors.rightMargin: 0
anchors.bottomMargin: 1
}

Rectangle {
id: displayControlBar

height: 50
anchors.left: parent.left
anchors.right: parent.right
anchors.bottom: parent.bottom
anchors.leftMargin: 0
anchors.rightMargin: 0
anchors.bottomMargin: 20
}
}

QT -версия, которую я использую, qt6.8.0

stides 11

Подробнее здесь: https://stackoverflow.com/questions/795 ... qml-window
Реклама
Ответить Пред. темаСлед. тема

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

  • Похожие темы
    Ответы
    Просмотры
    Последнее сообщение

Вернуться в «C++»