gpt4 book ai didi

c++ - 我的 OpenGL QQuickItem 没有我想要的大小

转载 作者:行者123 更新时间:2023-11-30 04:51:17 25 4
gpt4 key购买 nike

我在 Qtquick 上使用 OpenGL 绘图,无论我在 QML 上的 OpenGlVideoQtQuick 上放置什么尺寸,它总是占据窗口的整个空间。我希望能够控制它的大小。

我创建了这个使用 OpenGL 绘制绿屏的最小示例。我应该能够控制 QQuickItem 的大小,从而控制绿屏的大小,例如占据屏幕的 1/4。

您可以看到,我什至尝试(并评论)了 QQuickItem 上的 setWidthsetHeight 方法。这是行不通的。

你可以在这里看到一个最小的工作和可编译的例子:https://github.com/lucaszanella/openglqtquickexample/tree/4de3ec1535eb40c31788512a027c1e86f76d4090

如何控制 QQuickItem 的大小?

主.qml:

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

}
}

主要.cpp:

#include <iostream>
#include <QApplication>
#include <QMediaPlayer>
#include <QPushButton>
#include <QGuiApplication>

#include <QtQuick/QQuickView>

#include "OpenGlVideoQtQuick.h"

int main(int argc, char **argv)
{
QGuiApplication app(argc, argv);
QCoreApplication::addLibraryPath("./");
qmlRegisterType<OpenGlVideoQtQuick>("OpenGLComponents", 1, 0, "OpenGlVideoQtQuick");

QQuickView view;
view.setResizeMode(QQuickView::SizeRootObjectToView);
view.setSource(QUrl("qrc:/main.qml"));
view.show();

return app.exec();
}

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;
void main(void)
{
gl_Position = 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();
//setWidth(640);
//setHeight(480);
//width=640
//height=480
}

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

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);
}
}

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();

//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();

}

最佳答案

您必须在顶点着色器中缩放顶点坐标。这可以通过 4x4 矩阵 (mat4) 来完成。声明 uniform variable类型 mat4 并通过矩阵转换(乘以)顶点坐标,然后将其分配给剪辑空间位置 gl_Position:

attribute vec4 vertexIn;
attribute vec2 textureIn;

varying vec2 textureOut;

uniform mat4 u_transform;

void main(void)
{
gl_Position = u_transform * vertexIn;
textureOut = textureIn;
}

必须在程序中设置制服的值,由 QOpenGLShaderProgram::setUniformValue() .值的类型必须是 QMatrix4x4 .

例如

program->bind();

QMatrix4x4 transform;
transform.setToIdentity();
transform.scale(0.25, 0.25);

program->setUniformValue("u_transform", transform);

当然也可以使用glm::mat4。在这种情况下,制服的值必须由 glUniformMatrix4fv 设置:

GLint transformLoc = program->uniformLocation("u_transform");

program->bind();

glm::mat4 transform(1.0f);
transform = glm::scale(transform, glm::vec3(0.25f, 0.25f, 1.0f));
glUniformMatrix4fv(transformLoc , 1, GL_FALSE, glm::value_ptr(transform ));

关于c++ - 我的 OpenGL QQuickItem 没有我想要的大小,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54872975/

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