- 已关闭。**此问题需要debugging details。当前不接受答案。
编辑问题以包含desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem。这将有助于其他人回答问题。
昨天关门了。
Improve this question
我用qt 6.4创建了一个应用程序渲染yuv图像与QOpenGLWidget.代码工作正常,在windows 10,但没有渲染任何在我的macbook pro(英特尔芯片,Ventura 13.1),并没有报告任何错误.
下面是我的代码:
主要内容:cpp:
#include "mainwindow.h"
#include <QApplication>
#include <QSurfaceFormat>
int main(int argc, char *argv[])
{
QCoreApplication::setAttribute(Qt::AA_UseDesktopOpenGL);
QSurfaceFormat glFormat;
glFormat.setVersion(4, 1);
glFormat.setProfile(QSurfaceFormat::CoreProfile);
glFormat.setSwapBehavior (QSurfaceFormat::DoubleBuffer);
glFormat.setRenderableType (QSurfaceFormat::OpenGL);
QSurfaceFormat::setDefaultFormat(glFormat);
QApplication a(argc, argv);
MainWindow w;
w.show();
return a.exec();
}
从屏幕h:
#include "QtOpenGLWidgets/qopenglwidget.h"
#include <QOpenGLWidget>
#include <QOpenGLShaderProgram>
#include <QOpenGLFunctions>
#include <QOpenGLTexture>
#include <QTimer>
#include <QFile>
namespace Ui {
class FrmScreen;
}
#define GET_STR(x) #x
#define A_VER 3
#define T_VER 4
class FrmScreen : public QOpenGLWidget, protected QOpenGLFunctions
{
Q_OBJECT
public:
explicit FrmScreen(QWidget *parent = nullptr);
~FrmScreen();
void displayImage(QString imgPath);
void displayYuvImage(QString yuvPath);
protected:
void initializeGL() Q_DECL_OVERRIDE;
void resizeGL(int w, int h) Q_DECL_OVERRIDE;
void paintGL() Q_DECL_OVERRIDE;
private:
Ui::FrmScreen *ui;
QString _img_path;
QOpenGLShaderProgram program;
GLuint unis[3] = {0};
GLuint texs[3] = {0};
int width = 2688;
int height = 1520;
QFile m_file;
QByteArray m_buf;
};
#endif // FRMSCREEN_H
FrmScreen.cpp:
#include "FrmScreen.h"
#include "QtGui/qpainter.h"
#include "ui_FrmScreen.h"
FrmScreen::FrmScreen(QWidget *parent) :
QOpenGLWidget(parent),
ui(new Ui::FrmScreen)
{
_img_path = "./frames/frame000.yuv";
ui->setupUi(this);
}
const char* vString =
"#version 410\n"
"in vec4 vertexIn;\n"
"in vec2 textureIn;\n"
"out vec2 textureOut;\n"
"void main(void)\n"
"{\n"
" gl_Position = vertexIn;\n"
" textureOut = textureIn;\n"
"}";
const char* tString = "#version 410\n"
"in vec2 textureOut;\n"
"out vec4 fragColor;\n"
"uniform sampler2D tex_y;\n"
"uniform sampler2D tex_u;\n"
"uniform sampler2D tex_v;\n"
"void main(void)\n"
"{\n"
" vec3 yuv;\n"
" vec3 rgb;\n"
" yuv.x = texture(tex_y, textureOut).r;\n"
" yuv.y = texture(tex_u, textureOut).r - 0.5;\n"
" yuv.z = texture(tex_v, textureOut).r - 0.5;\n"
" rgb = mat3( 1, 1, 1,\n"
" 0, -0.21482, 2.12798,\n"
" 1.28033, -0.38059, 0) * yuv;\n"
" fragColor = vec4(rgb, 1);\n"
"}";
FrmScreen::~FrmScreen()
{
delete ui;
}
void FrmScreen::initializeGL()
{
initializeOpenGLFunctions();
qDebug() << "load fragment:" <<program.addShaderFromSourceCode(QOpenGLShader::Fragment, tString);
qDebug() << "load shader:" <<program.addShaderFromSourceCode(QOpenGLShader::Vertex, vString);
program.bindAttributeLocation("vertexIn", A_VER);
program.bindAttributeLocation("textureIn", T_VER);
qDebug() << "compile shader:" << program.link();
qDebug() << "bind shader:" << program.bind();
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
};
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");
glGenTextures(3, texs);
// 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);
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);
glClearColor(0.3, 0.3, 0.3, 0.0);
m_file.setFileName(_img_path);
if(!m_file.open(QIODevice::ReadOnly))
{
qDebug() << "open yuv file failed";
return;
}
}
void FrmScreen::paintGL()
{
if(m_file.atEnd())
{
m_file.seek(0);
}
QByteArray buf = m_file.read(width * height);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, texs[0]);
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, width, height, GL_RED, GL_UNSIGNED_BYTE, buf.data());
glUniform1i(unis[0], 0);
buf = m_file.read(width * height / 4);
glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_2D, texs[1]);
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, width / 2, height / 2, GL_RED, GL_UNSIGNED_BYTE, buf.data());
glUniform1i(unis[1], 1);
buf = m_file.read(width * height / 4);
glActiveTexture(GL_TEXTURE2);
glBindTexture(GL_TEXTURE_2D, texs[2]);
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, width / 2, height / 2, GL_RED, GL_UNSIGNED_BYTE, buf.data());
glUniform1i(unis[2], 2);
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
return;
}
void FrmScreen::resizeGL(int width, int height)
{
if (height == 0)
{
height = 1;
}
glViewport(0, 0, width, height);
}
void FrmScreen::displayYuvImage(QString yuvPath)
{
_img_path = yuvPath;
update();
}
void FrmScreen::displayImage(QString imgPath)
{
_img_path = imgPath;
update();
}
为什么代码在macos上不能正常工作?
1条答案
按热度按时间628mspwn1#
在Mac上,您必须使用OpenGL 4.1 Core配置文件context,并设置向前兼容标志。在Qt 6上,这可以通过关闭
QSurfaceFormat::DeprecatedFunctions
来实现:着色器版本应为
#version 410 core
。