简单做个记录吧,调了半天终于能显示出来了。.h
#ifndef OPENGL_IMAGE_H
#define OPENGL_IMAGE_H
#include <QGLWidget>
#include <QImage>
#include <QPainter>
#include <queue>
#include <QMutex>
#include <QTimer>
#include <QOpenGLVertexArrayObject>
#include <QOpenGLBuffer>
#include <QMatrix4x4>
#include <QOpenGLFunctions>
#include <QOpenGLVertexArrayObject>
#include <QOpenGLBuffer>
#include <QOpenGLShaderProgram>
#include <QOpenGLWidget>
class opengl_image : public QOpenGLWidget, protected QOpenGLFunctions
{
Q_OBJECT
public:
explicit opengl_image(QWidget* parent = 0);
void set_image(const QImage & ppp1image);
void refresh();
void hide_view(bool state);
void clear();
signals:
void signal_refresh();
void signal_hide(bool state);
void signal_clear();
public slots:
void slot_refresh();
void slot_hide(bool state);
void slot_clear();
protected:
void initializeGL() override;
void paintGL() override;
void resizeGL(int width, int height) override;
void initializeShaderProgram();
private:
QOpenGLVertexArrayObject vao;
QOpenGLBuffer vbo;
QOpenGLShaderProgram *program;
GLuint texture;
QImage image;
QMutex image_mutex_;
};
#endif
.cpp
#include "opengl_image.h"
#include <QDebug>
#include <iostream>
#include <QDateTime>
opengl_image::opengl_image(QWidget* parent)
: QOpenGLWidget(parent)
{
this->setWindowFlags(Qt::FramelessWindowHint); //delete title
this->setAttribute(Qt::WA_TranslucentBackground, true);
connect(this, SIGNAL(signal_refresh()), this, SLOT(slot_refresh()), Qt::QueuedConnection);
connect(this, SIGNAL(signal_hide(bool)), this, SLOT(slot_hide(bool)), Qt::QueuedConnection);
connect(this, SIGNAL(signal_clear()), this, SLOT(slot_clear()), Qt::QueuedConnection);
}
void opengl_image::set_image(const QImage & ppp1image){
if (ppp1image.isNull()) {
qDebug() << "Image is null!";
return;
}
image_mutex_.lock();
qDebug() << "Image convertToFormat format ="<<image.format() <<endl;
if (ppp1image.format() != QImage::Format_RGB888) {
qDebug() << "Image convertToFormat format ="<<image.format() <<endl;
image = ppp1image.convertToFormat(QImage::Format_RGB888);
qDebug() << "Image convertToFormat Format_RGB32!"<<endl;
}
else
{
image = ppp1image;
}
image_mutex_.unlock();
refresh();
}
void opengl_image::initializeGL()
{
initializeOpenGLFunctions();
// 初始化着色器程序
initializeShaderProgram();
// 创建 VAO
vao.create();
vao.bind();
// 创建 VBO
vbo.create();
vbo.bind();
// 顶点数据 (位置和纹理坐标)
const GLfloat vertexData[] = {
// 第一个三角形: 左下角、右下角、左上角
-1.0f, -1.0f, 0.0f, 0.0f, 1.0f,
1.0f, -1.0f, 0.0f, 1.0f, 1.0f,
-1.0f, 1.0f, 0.0f, 0.0f, 0.0f,
// 第二个三角形: 左上角、右下角、右上角
-1.0f, 1.0f, 0.0f, 0.0f, 0.0f,
1.0f, -1.0f, 0.0f, 1.0f, 1.0f,
1.0f, 1.0f, 0.0f, 1.0f, 0.0f,
};
vbo.allocate(vertexData, sizeof(vertexData));
// 顶点属性 (位置)
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 5 * sizeof(GLfloat), 0);
glEnableVertexAttribArray(0);
// 顶点属性 (纹理坐标)
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 5 * sizeof(GLfloat), reinterpret_cast<void*>(3 * sizeof(GLfloat)));
glEnableVertexAttribArray(1);
// 解绑 VBO
vbo.release();
// 解绑 VAO
vao.release();
// 生成纹理
glGenTextures(1, &texture);
// 绑定纹理
glBindTexture(GL_TEXTURE_2D, texture);
// 设置纹理参数
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
}
void opengl_image::initializeShaderProgram()
{
// 创建顶点着色器
QOpenGLShader *vertexShader = new QOpenGLShader(QOpenGLShader::Vertex);
vertexShader->compileSourceFile("./res/v.glsl");
if (!vertexShader->isCompiled()) {
qDebug() << "Vertex shader compilation failed:" << vertexShader->log();
}
// 创建片段着色器
QOpenGLShader *fragmentShader = new QOpenGLShader(QOpenGLShader::Fragment);
fragmentShader->compileSourceFile("./res/f.glsl");
if (!fragmentShader->isCompiled()) {
qDebug() << "Fragment shader compilation failed:" << fragmentShader->log();
}
// 创建着色器程序
program = new QOpenGLShaderProgram;
program->addShader(vertexShader);
program->addShader(fragmentShader);
program->link();
if (!program->isLinked()) {
qDebug() << "Shader program linking failed:" << program->log();
}
delete vertexShader;
delete fragmentShader;
}
void opengl_image::paintGL()
{
// 清除颜色缓冲区
glClear(GL_COLOR_BUFFER_BIT);
// 绑定着色器程序
program->bind();
// 绑定纹理
glBindTexture(GL_TEXTURE_2D, texture);
// 上传纹理数据 (这里需要根据你的 QImage 对象进行修改)
image_mutex_.lock();
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, image.width(), image.height(), 0, GL_RGB, GL_UNSIGNED_BYTE, image.bits());
qDebug()<<"width:"<< image.width()<<endl;
qDebug()<<"height:"<< image.height()<<endl;
image_mutex_.unlock();
// 设置投影矩阵 (这里需要根据你的需求进行修改)
QMatrix4x4 projection;
projection.ortho(-1.0f, 1.0f, -1.0f, 1.0f, -1.0f, 1.0f);
program->setUniformValue("projection", projection);
// 设置模型视图矩阵 (这里需要根据你的需求进行修改)
QMatrix4x4 modelView;
program->setUniformValue("modelView", modelView);
// 绑定 VAO
vao.bind();
// 绘制
glDrawArrays(GL_TRIANGLES, 0, 6);
// 解绑 VAO
vao.release();
// 解绑着色器程序
program->release();
}
void opengl_image::resizeGL(int width, int height)
{
// 设置视口
glViewport(0, 0, width, height);
// 设置投影矩阵 (根据需要进行修改)
QMatrix4x4 projection;
projection.ortho(-1.0f, 1.0f, -1.0f, 1.0f, -1.0f, 1.0f);
program->setUniformValue("projection", projection);
}
void opengl_image::slot_clear()
{
QImage image("./res/black.png");
set_image(image);
}
void opengl_image::hide_view(bool state)
{
emit signal_hide(state);
}
void opengl_image::refresh()
{
emit signal_refresh();
}
void opengl_image::slot_refresh()
{
update();
}
void opengl_image::slot_hide(bool state)
{
qDebug()<<"opengl_img_render::slot_hide()"<<endl;
if(state)
{
this->show();
}
else
{
this->hide();
}
}
v.glsl
#version 320 es
layout (location = 0) in vec3 aPos;
layout (location = 1) in vec2 aTexCoord;
out vec2 TexCoord;
uniform mat4 projection;
uniform mat4 modelView;
void main()
{
gl_Position = projection * modelView * vec4(aPos, 1.0);
TexCoord = aTexCoord;
}
f.glsl
#version 320 es
precision mediump float;
in vec2 TexCoord;
uniform sampler2D ourTexture;
out vec4 FragColor;
void main()
{
FragColor = texture(ourTexture, TexCoord);
}
由于是用在Rk3568上的,版本是openes 3.2所以只能这样了,x86平台需要自己修改一下,后面空了把x86的也放出来