gpt4 book ai didi

c++ - 如何使我的 OpenGL 视频具有与 QQuickItem 相同的大小和位置?

转载 作者:行者123 更新时间:2023-11-28 01:23:45 24 4
gpt4 key购买 nike

按照我的最新问题:My OpenGL QQuickItem won't have the size I want ,我现在正在尝试,而不是为我的 OpenGL 视频设置任意大小,以将其放入我的 QQuickItem 中。

我听说 QQuickItem::transform() 会给我一个转换矩阵列表。我假设此列表包含所有需要的转换,以达到我的 QQuickItem 的大小和位置的正方形。 <<<< 这是真的吗?如果是这样,转换来自什么坐标和视口(viewport)尺寸?

鉴于此为真,我制作了以下最小的可验证和可编译示例,它试图使绿屏适合我的 QQuickItem 的大小。但目前,它只占用整个屏幕。

我使用函数 getModelMatrix()(您可以在下面找到)获取所有转换并从中创建一个矩阵。然后我将这些转换应用于我的顶点着色器,方法是

gl_Position = u_transform * vertexIn;

正如我所说,结果是绿屏。但是,它与我的窗口具有相同的尺寸,而不是 main.qml

中指定的尺寸 640x480 和 x,y=0

你可以在这里找到一个最小的可编译和可验证的例子:https://github.com/lucaszanella/openglqtquickexample/tree/88fe0092d663dd92c551c72acccd0bf058fe7e5b

OpenGlVideoQtQuick.cpp:

#include "OpenGlVideoQtQuick.h"

#define GET_STR(x) #x
#define A_VER 3
#define T_VER 4

//Simple shader. Outpus the same location as input, I guess
const char *vString2 = GET_STR(
attribute vec4 vertexIn;
attribute vec2 textureIn;
varying vec2 textureOut;
uniform mat4 u_transform;
void main(void)
{
gl_Position = u_transform * vertexIn;
textureOut = textureIn;
}
);

const char *tString2 = GET_STR(
varying vec2 textureOut;
uniform sampler2D tex_y;
uniform sampler2D tex_u;
uniform sampler2D tex_v;
void main(void)
{
vec3 yuv;
vec3 rgb;
yuv.x = texture2D(tex_y, textureOut).r;
yuv.y = texture2D(tex_u, textureOut).r - 0.5;
yuv.z = texture2D(tex_v, textureOut).r - 0.5;
rgb = mat3(1.0, 1.0, 1.0,
0.0, -0.39465, 2.03211,
1.13983, -0.58060, 0.0) * yuv;
gl_FragColor = vec4(rgb, 1.0);
}

);

OpenGlVideoQtQuick::OpenGlVideoQtQuick():
openGlVideoQtQuickRenderer(nullptr)
{
connect(this, &QQuickItem::windowChanged, this, &OpenGlVideoQtQuick::handleWindowChanged);

update();
}

void OpenGlVideoQtQuick::handleWindowChanged(QQuickWindow *win)
{
if (win) {
connect(win, &QQuickWindow::beforeSynchronizing, this, &OpenGlVideoQtQuick::sync, Qt::DirectConnection);
win->setClearBeforeRendering(false);
}
}

QMatrix4x4 OpenGlVideoQtQuick::getModelMatrix() {
QMatrix4x4 result;

// Compose model matrix from our transform properties in the QML
QQmlListProperty<QQuickTransform> transformations = transform();
const int count = transformations.count(&transformations);
for (int i=0; i<count; i++) {
QQuickTransform *transform = transformations.at(&transformations, i);
transform->applyTo(&result);
}

return result;
}


void OpenGlVideoQtQuick::update()
{
if (window())
window()->update();
}


OpenGlVideoQtQuickRenderer::~OpenGlVideoQtQuickRenderer()
{
delete program;
}



void OpenGlVideoQtQuick::sync()
{
if (!openGlVideoQtQuickRenderer) {
openGlVideoQtQuickRenderer = new OpenGlVideoQtQuickRenderer();
connect(window(), &QQuickWindow::beforeRendering, openGlVideoQtQuickRenderer, &OpenGlVideoQtQuickRenderer::render, Qt::DirectConnection);
connect(window(), &QQuickWindow::afterRendering, this, &OpenGlVideoQtQuick::update, Qt::DirectConnection);
}
this->openGlVideoQtQuickRenderer->qQuickVideoMatrix = getModelMatrix();
}

static const GLfloat ver[] = {
-1.0f,-1.0f,
1.0f,-1.0f,
-1.0f, 1.0f,
1.0f, 1.0f
};

static const GLfloat tex[] = {
0.0f, 1.0f,
1.0f, 1.0f,
0.0f, 0.0f,
1.0f, 0.0f
};


void OpenGlVideoQtQuickRenderer::render()
{
if (this->firstRun) {
std::cout << "Creating QOpenGLShaderProgram " << std::endl;
this->firstRun = false;
program = new QOpenGLShaderProgram();
initializeOpenGLFunctions();

std::cout << "Fragment Shader compilation: " << program->addShaderFromSourceCode(QOpenGLShader::Fragment, tString2) << std::endl;
std::cout << "Vertex Shader compilation: " << program->addShaderFromSourceCode(QOpenGLShader::Vertex, vString2) << std::endl;

program->bindAttributeLocation("vertexIn",A_VER);
program->bindAttributeLocation("textureIn",T_VER);
std::cout << "program->link() = " << program->link() << std::endl;

glGenTextures(3, texs);//TODO: ERASE THIS WITH glDeleteTextures
}
program->bind();
program->setUniformValue("u_transform", this->qQuickVideoMatrix);


//glViewport(50, 50, 50, 50);

glVertexAttribPointer(A_VER, 2, GL_FLOAT, 0, 0, ver);
glEnableVertexAttribArray(A_VER);

glVertexAttribPointer(T_VER, 2, GL_FLOAT, 0, 0, tex);
glEnableVertexAttribArray(T_VER);

unis[0] = program->uniformLocation("tex_y");
unis[1] = program->uniformLocation("tex_u");
unis[2] = program->uniformLocation("tex_v");

//Y
glBindTexture(GL_TEXTURE_2D, texs[0]);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RED, width, height, 0, GL_RED, GL_UNSIGNED_BYTE, 0);

//U
glBindTexture(GL_TEXTURE_2D, texs[1]);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RED, width/2, height / 2, 0, GL_RED, GL_UNSIGNED_BYTE, 0);

//V
glBindTexture(GL_TEXTURE_2D, texs[2]);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RED, width / 2, height / 2, 0, GL_RED, GL_UNSIGNED_BYTE, 0);



glDrawArrays(GL_TRIANGLE_STRIP,0,4);

program->disableAttributeArray(A_VER);
program->disableAttributeArray(T_VER);
program->release();

}

OpenGlVideoQtQuick.h:

#ifndef OpenGlVideoQtQuick_H
#define OpenGlVideoQtQuick_H

#include <QtQuick/QQuickItem>
#include <QtGui/QOpenGLShaderProgram>
#include <QtGui/QOpenGLFunctions>
#include <QtQuick/qquickwindow.h>
#include <QtGui/QOpenGLShaderProgram>
#include <QtGui/QOpenGLContext>
#include <QString>
#include <iostream>
#include <QTimer>



class OpenGlVideoQtQuickRenderer : public QObject, protected QOpenGLFunctions
{
Q_OBJECT

public:
OpenGlVideoQtQuickRenderer() {
}
~OpenGlVideoQtQuickRenderer();
QMatrix4x4 qQuickVideoMatrix;



public slots:
void render();

private:
QOpenGLShaderProgram* program;
GLuint unis[3] = {0};
GLuint texs[3] = {0};
unsigned char *datas[3] = { 0 };
bool firstRun = true;
//TODO: make this variable according to video data
int width = 1920;
int height = 1080;
};

class OpenGlVideoQtQuick : public QQuickItem
{
Q_OBJECT

public:
OpenGlVideoQtQuick();
QMatrix4x4 getModelMatrix();


private slots:
void handleWindowChanged(QQuickWindow *win);
public slots:
void sync();
void update();//Updates the window

private:
OpenGlVideoQtQuickRenderer *openGlVideoQtQuickRenderer;

};

#endif // OpenGlVideoQtQuick_H

ma​​in.qml:

import QtQuick 2.0
import OpenGLComponents 1.0
Item {
width: 1280
height: 720
OpenGlVideoQtQuick {
width: 640
height: 480

}
}

最佳答案

从你的问题和你的代码中,你“期望”看到的内容有点不清楚,但我确实看到了一些可能对你有帮助的问题:

  1. 我认为您的渲染循环实际上并未被调用。您必须在构造函数中执行此操作:setFlag(ItemHasContents);

  2. 确保将一些纹理/视频数据传递到您的 glTexImage2D() 调用中,否则您会得到一些垃圾(随机绿色垃圾?)

  3. 您可能想看看 QQuickItem::widthChangedQQuickItem::heightChanged 信号

  4. 确保在调试时调用 glViewport() 以及 glClear() 以避免混淆 - 您可以稍后在不需要时删除它们不再需要它们了

关于c++ - 如何使我的 OpenGL 视频具有与 QQuickItem 相同的大小和位置?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54902244/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com