Qt - 使用 QOpenGLWidget 显示图像的步骤

Posted

技术标签:

【中文标题】Qt - 使用 QOpenGLWidget 显示图像的步骤【英文标题】:Qt - steps to using QOpenGLWidget to display images 【发布时间】:2019-04-15 08:23:26 【问题描述】:

我正在尝试使用 QOpenGLWidget 来显示一些图像,而不是使用 QLabel。但是我对如何做到这一点有点困惑。

为了让小部件完成工作,我知道我需要重新实现initializeGL() 方法和paintGL() 方法。

为了获取图像的纹理,我使用的是SOIL_load_image()。为什么unsigned char* img_data 超过unsigned char* img_data[3]?我认为图像的每个像素都有 3 个值(RGB)。

获得纹理后,我不知道我应该做什么以及在initializeGL()paintGL() 中应该在哪里做。谁能告诉步骤?

void MyOpenGLWidget::loadTexture(const char* file_path)

    *image = cv::imread(file_path, cv::IMREAD_COLOR);
    width = image->rows;
    height = image->cols;
    int channels = image->channels();
    img_data = SOIL_load_image(file_path, &width, &height, &channels, SOIL_LOAD_RGB);

【问题讨论】:

您是否已阅读文档?见doc.qt.io/qt-5/qopenglwidget.html#details 【参考方案1】:

为什么 unsigned char* img_data 优于 unsigned char* img_data[3]

unsigned char* 是指向数据缓冲区(任意长度)的指针。 unsigned char* …[3] 是一个包含 3 个指向数据缓冲区的指针的数组。您只有一个缓冲区,而不是 3 个。

由于某种原因,您同时使用 OpenCV 和 SOIL 两次读取同一图像。为什么?

一旦你加载了图像,你必须用 OpenGL 显示它

    创建纹理对象(glGenTextures、glBindTexture、glTexImage) 通过填充顶点缓冲区对象(glGenBuffers、glBindBuffer、glBufferData)并将缓冲区中的数据与顶点数组对象( glGenVertexArrays, glBindVertexArray, glEnableVertexArrayAttrib, glVertexAttribPointer) 创建一个着色器程序,由一个顶点着色器组成,该顶点着色器用于放置几何图形并参数化片段着色器,它实际上是从纹理中采样的。 (glCreateShader、glShaderSource、glCreateProgram、glLinkProgram)

然后画

    选择着色器程序 (glUseProgram) 设置参数(glUniform) 绘制 (glDrawArrays)

【讨论】:

是的,你是对的。但我不确定是否需要处理 RGB 值,就像我需要将 img_data 与 new_img_data[0]、new_img_data[1] 和 new_im_data[2] 分开。但我似乎不需要这样做 @Jinx:不需要创建平面(图像分为单独的红色、绿色和蓝色单色层)图像。您应该将原始数据缓冲区传递给 OpenGL,并告诉 OpenGL 数据以什么格式到达。

以上是关于Qt - 使用 QOpenGLWidget 显示图像的步骤的主要内容,如果未能解决你的问题,请参考以下文章

Qt音视频开发24-视频显示QOpenGLWidget方式(占用GPU)

Qt 5.5 示例,缺少 QOpenGLWidget

Qt OpenGL (QOpenGLWidget) - 简单三角形

没有子类化的 QOpenGLWidget

将OpenGL帧缓冲区对象与Qt(QOpenGLWidget)一起使用,绘制到帧缓冲区时如何禁用多重采样

Qt 从 QOpenGLWidget 访问 MainWindow