gpt4 book ai didi

c++ - Qt QQuickFramebufferObject OpenGL渲染侵入其他物体场景为红色

转载 作者:塔克拉玛干 更新时间:2023-11-03 07:39:16 26 4
gpt4 key购买 nike

我知道通常需要一个最小的完整且可验证的示例,但这个示例不能分解成更小的示例,因为从我的安全摄像头获取和解码视频需要太多的库。我希望有人可以通过指出使用 QQuickFrameBufferObject 进行渲染时可能出现的简单错误来帮助我。

enter image description here

我遇到的两个问题是图像是红色的,并且一个物体的图像以一种非常莫名其妙的方式侵入了另一个物体的空间。在上图中你可以看到什么应该是通过 QML 实例化的 4 个不同的相机源。

这是呈现所有内容的类。使用 update() 函数提供 YUV420P 数据。您可以看到将 YUV420P 解码为 RGB 的简单着色器。每个 QML 对象(相机流)都是此类的一个实例。

OpenGlBufferQtQuick.cpp :

#include "OpenGlBufferQtQuick.h"
#include <QOpenGLFramebufferObjectFormat>
#include <QRunnable>
#include <QEventLoop>
#include <QNetworkReply>
#include <QNetworkRequest>
#include <QMutexLocker>
#include <memory>
#include <iostream>
#include <QTimer>

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

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

//Simple shader. Outpus the same location as input, I guess
const char *vString3 = 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;
}
);


//The matrix below does YUV420P to RGB conversion https://en.wikipedia.org/wiki/YUV#Y%E2%80%B2UV420p_(and_Y%E2%80%B2V12_or_YV12)_to_RGB888_conversion
//This texture shader replaces the color of the pixel with the new color, but in RGB. (I guess)
const char *tString3 = 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);
}

);


OpenGlBufferItemRenderer::OpenGlBufferItemRenderer(string uri){
this->uri = uri;
}


void OpenGlBufferItemRenderer::render() {
QOpenGLFunctions *f = QOpenGLContext::currentContext()->functions();
if (firstFrameReceived) {
if (this->firstRender) {
std::cout << "Creating QOpenGLShaderProgram " << std::endl;
program = new QOpenGLShaderProgram();
f->initializeOpenGLFunctions();
//this->m_F = QOpenGLContext::currentContext()->functions();
std::cout << "frameWidth: " << frameWidth << + " frameHeight: " << frameHeight << std::endl;

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

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

f->glGenTextures(3, texs);//TODO: ERASE THIS WITH glDeleteTextures
this->firstRender = false;
}

// Not strictly needed for this example, but generally useful for when
// mixing with raw OpenGL.
//m_window->resetOpenGLState();//COMMENT OR NOT?

program->bind();

QMatrix4x4 transform;
transform.setToIdentity();
program->setUniformValue("u_transform", transform);

f->glVertexAttribPointer(A_VER, 2, GL_FLOAT, 0, 0, ver);
f->glEnableVertexAttribArray(A_VER);

f->glVertexAttribPointer(T_VER, 2, GL_FLOAT, 0, 0, tex);
f->glEnableVertexAttribArray(T_VER);

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

//Y
f->glBindTexture(GL_TEXTURE_2D, texs[0]);
f->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
f->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
f->glTexImage2D(GL_TEXTURE_2D, 0, GL_RED, frameWidth, frameHeight, 0, GL_RED, GL_UNSIGNED_BYTE, 0);

//U
f->glBindTexture(GL_TEXTURE_2D, texs[1]);
f->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
f->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
f->glTexImage2D(GL_TEXTURE_2D, 0, GL_RED, frameWidth/2, frameHeight / 2, 0, GL_RED, GL_UNSIGNED_BYTE, 0);

//V
f->glBindTexture(GL_TEXTURE_2D, texs[2]);
f->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
f->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
f->glTexImage2D(GL_TEXTURE_2D, 0, GL_RED, frameWidth / 2, frameHeight / 2, 0, GL_RED, GL_UNSIGNED_BYTE, 0);

f->glActiveTexture(GL_TEXTURE0);
f->glBindTexture(GL_TEXTURE_2D, texs[0]);
f->glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, frameWidth, frameHeight, GL_RED, GL_UNSIGNED_BYTE, datas[0]);
f->glUniform1i(unis[0], 0);


f->glActiveTexture(GL_TEXTURE0+1);
f->glBindTexture(GL_TEXTURE_2D, texs[1]);
f->glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, frameWidth/2, frameHeight / 2, GL_RED, GL_UNSIGNED_BYTE, datas[1]);
f->glUniform1i(unis[1],1);


f->glActiveTexture(GL_TEXTURE0+2);
f->glBindTexture(GL_TEXTURE_2D, texs[2]);
f->glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, frameWidth / 2, frameHeight / 2, GL_RED, GL_UNSIGNED_BYTE, datas[2]);
f->glUniform1i(unis[2], 2);

f->glDrawArrays(GL_TRIANGLE_STRIP,0,4);

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

}
update();
}

QOpenGLFramebufferObject *OpenGlBufferItemRenderer::createFramebufferObject(const QSize &size)
{
QOpenGLFramebufferObjectFormat format;
format.setAttachment(QOpenGLFramebufferObject::CombinedDepthStencil);
//format.setSamples(16);
return new QOpenGLFramebufferObject(size, format);
}
//https://blog.qt.io/blog/2015/05/11/integrating-custom-opengl-rendering-with-qt-quick-via-qquickframebufferobject/
void OpenGlBufferItemRenderer::synchronize(QQuickFramebufferObject *item)
{
OpenGlBufferItem *openGlBufferItem = static_cast<OpenGlBufferItem*>(item);

std::cout << "synchronize called " << std::endl;
std::cout << "starting new renderer for uri " << this-> uri << std::endl;

MediaStream* camera1 = new MediaStream(this->uri);
camera1->setFrameUpdater((FrameUpdater *) this);
//TODO: put mutex on std::cout of this thread
//TODO: make this thread actualy run here instead of on a thread, I guess.
boost::thread mediaThread(&MediaStream::run, camera1);
}

OpenGlBufferItem::OpenGlBufferItem(){}

void OpenGlBufferItemRenderer::updateData(unsigned char**data, int frameWidth, int frameHeight)
{
this->frameWidth = frameWidth;
this->frameHeight = frameHeight;
//Before first render, datas pointer isn't even created yet
if (!firstFrameReceived) {
datas[0] = new unsigned char[frameWidth*frameHeight]; //Y
datas[1] = new unsigned char[frameWidth*frameHeight/4]; //U
datas[2] = new unsigned char[frameWidth*frameHeight/4]; //V
firstFrameReceived = true;
} else {
memcpy(datas[0], data[0], frameWidth*frameHeight);
memcpy(datas[1], data[1], frameWidth*frameHeight/4);
memcpy(datas[2], data[2], frameWidth*frameHeight/4);
}
}

QQuickFramebufferObject::Renderer *OpenGlBufferItem::createRenderer() const
{
//std::cout << "createRenderer called ------------------------" << std::endl;
return new OpenGlBufferItemRenderer(this->uri);
}

这是 main.qml :

import QtQuick 2.0
import OpenGlBufferQtQuick 1.0

Grid {
columns: 2
spacing: 2
width: 1280
height: 720
OpenGlBufferQtQuick {
width: 640
height: 360
uri: "rtsp://admin:123456@192.168.0.103:10554/tcp/av0_0"
}
OpenGlBufferQtQuick {
width: 640
height: 360
uri: "rtsp://admin:123456@192.168.0.101:10554/tcp/av0_0"
}
OpenGlBufferQtQuick {
width: 640
height: 360
uri: "rtsp://admin:123456@192.168.0.104:10554/tcp/av0_0"
}
OpenGlBufferQtQuick {
width: 640
height: 360
uri: "rtsp://admin:123456@192.168.1.43:10554/tcp/av0_0"
}

}

如您所见,我调用了 4 个不同的相机流,但来自第一个相机的流侵入了其他流的空间,即使每个流都是一个完全不同的对象。

另外,图像是红色的。我使用几乎相同的代码来使用类 OpenGlVideoQtQuickRenderer : public QObject, protected QOpenGLFunctions 进行渲染,并且它在没有任何红屏或 opengl 侵入其他空间的情况下工作。

最佳答案

我付钱请人帮助我,但问题是纹理着色器未激活。这些是更改:

https://github.com/lucaszanella/orwell/commit/b2882768badb16e4334bc2bd0371611221283e97#diff-b089e4d46edc159fb6e7de932e64219b

基本上:

GLint originTextureUnit;
f->glGetIntegerv(GL_ACTIVE_TEXTURE, &originTextureUnit);

 f->glActiveTexture(originTextureUnit);

但是我仍然不明白为什么纹理没有被激活。

关于c++ - Qt QQuickFramebufferObject OpenGL渲染侵入其他物体场景为红色,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55113102/

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