Miriam. 2022-04-14 15:46 采纳率: 0%
浏览 65

qt点击按钮向opengl传递图片路径,进行纹理贴图

点击按钮 无法将路径传递过去,opengl控件无法进行绘图
我将QOpenGLWidget_2控件提升为myOpengl的类

img

shaderTest是主页面的类

shaderTest::shaderTest(QWidget *parent)
    : QWidget(parent)
{
    ui.setupUi(this);
    
  //  qf = new QtFunctionWidget(ui.openGLWidget);

    connect(
        ui.pushButton,
        SIGNAL(clicked(bool)),
        this,
        SLOT(selectPath())
        );
}
void shaderTest::selectPath() {
    QString s= "C:/Users/Miriam/Pictures/Saved Pictures/123.jpg";
  //  qf = new QtFunctionWidget();
    ui.openGLWidget_2->getPath(s);
}

以下是myOpengl.h头文件代码

#pragma once

#include <QOpenGLWidget>
#include <QOpenGLExtraFunctions>
#include <QOpenGLFunctions_3_3_Core>
#include <QOpenGLShader>
#include <QOpenGLShaderProgram>

class myOpengl : public QOpenGLWidget, protected /*QOpenGLExtraFunctions*/QOpenGLFunctions_3_3_Core
{
    Q_OBJECT
public:
    explicit myOpengl(QWidget* parent = nullptr);
    ~myOpengl();
    QString _filePath;
public:
    void getPath(QString p);
protected:
    virtual void initializeGL();
    virtual void resizeGL(int w, int h);
    virtual void paintGL();
    

private:
    QOpenGLShaderProgram shaderProgram;
};


以下是myOpengl类的代码 传递图片路径的代码在initializeGL()函数里 获取texture1

static GLuint VBO, VAO, EBO, texture1;

myOpengl::myOpengl(QWidget* parent) : QOpenGLWidget(parent)
{

}

myOpengl::~myOpengl()
{
    glDeleteVertexArrays(1, &VAO);
    glDeleteBuffers(1, &VBO);
    glDeleteBuffers(1, &EBO);
}
void myOpengl::initializeGL() {
    this->initializeOpenGLFunctions();

    bool success = shaderProgram.addShaderFromSourceFile(QOpenGLShader::Vertex, "test.vert");
    if (!success) {
        qDebug() << "shaderProgram addShaderFromSourceFile failed!" << shaderProgram.log();
        return;
    }

    success = shaderProgram.addShaderFromSourceFile(QOpenGLShader::Fragment, "test.frag");
    if (!success) {
        qDebug() << "shaderProgram addShaderFromSourceFile failed!" << shaderProgram.log();
        return;
    }

    success = shaderProgram.link();
    if (!success) {
        qDebug() << "shaderProgram link failed!" << shaderProgram.log();
    }
    //存储四个点,但是可以指定绘制的顺序,EBO专门存储索引,OpenGL调用顶点的索引来决定绘制哪个顶点(opengl主要处理三角形)
    //VAO,VBO data VAO:顶点数组对象(array) VBO:顶点缓冲对象(buffer)

    float vertices[] = {
        // positions位置          // colors颜色           // texture coords纹理坐标
         1.0f,  1.0f, 0.0f,   1.0f, 0.0f, 0.0f,   1.0f, 1.0f, // top right 右上
         1.0f, -1.0f, 0.0f,   0.0f, 1.0f, 0.0f,  1.0f, 0.0f, // bottom right 右下
        -1.0f, -1.0f, 0.0f,   0.0f, 0.0f, 1.0f,   0.0f, 0.0f, // bottom left 左下
        -1.0f,  1.0f, 0.0f,   1.0f, 1.0f, 0.0f,   0.0f, 1.0f  // top left 左上
    };

    unsigned int indices[] = {  // 索引从0开始
        0, 1, 3,  // first Triangle
        1, 2, 3   // second Triangle
    };

    glGenVertexArrays(1, &VAO);
    glGenBuffers(1, &VBO);
    glGenBuffers(1, &EBO);
    // 绑定VAO
    //bind the Vertex Array Object first, then bind and set vertex buffer(s), and then configure vertex attributes(s).
    glBindVertexArray(VAO);
    //0.复制顶点数组到缓冲中供OpenGL使用
    glBindBuffer(GL_ARRAY_BUFFER, VBO);
    glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
    //先绑定EBO然后将索引复制到缓冲里
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);

    // position attribute 位置属性(指定顶点属性alyout locatin=0,指定顶点属性大小,指定数据类型,步长,参数类型)
    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void*)0);
    glEnableVertexAttribArray(0); //每个顶点属性从一个VBO管理的内存中获得它的数据
    // color attribute 颜色属性
    glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void*)(3 * sizeof(float)));
    glEnableVertexAttribArray(1);
    // texture coord attribute 纹理坐标
    glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void*)(6 * sizeof(float)));
    glEnableVertexAttribArray(2);

    // texture 1
    // ---------
    glGenTextures(1, &texture1);
    glBindTexture(GL_TEXTURE_2D, texture1);
    // 为当前绑定的纹理对象设置环绕,过滤方式
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);//纹理放大过滤,线性滤波
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);//纹理缩小
//    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);   // set texture wrapping to GL_REPEAT (default wrapping method)
 //   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
    // set texture filtering parameters
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    // 加载并生成纹理
 //  QImage img1 = QImage("C:/Users/Miriam/Pictures/QQplayerPic/1.png").convertToFormat(QImage::Format_RGB888);
   QImage img1 = QImage(_filePath).convertToFormat(QImage::Format_RGB888);  //传入图片路径

    if (!img1.isNull()) {
        glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, img1.width(), img1.height(), 0, GL_RGB, GL_UNSIGNED_BYTE, img1.bits());
        glGenerateMipmap(GL_TEXTURE_2D);
    }

    // tell opengl for each sampler to which texture unit it belongs to (only has to be done once)
    shaderProgram.bind();   // don't forget to activate/use the shader before setting uniforms!
    glUniform1i(shaderProgram.uniformLocation("texture1"), 0);
    //    glUniform1i(shaderProgram.uniformLocation("texture2"), 1);
    shaderProgram.release();

    //     glBindBuffer(GL_ARRAY_BUFFER, 0);//取消VBO的绑定

     //    remember: do NOT unbind the EBO while a VAO is active as the bound element buffer object IS stored in the VAO; keep the EBO bound.
     //    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);

     //    You can unbind the VAO afterwards so other VAO calls won't accidentally modify this VAO, but this rarely happens. Modifying other
     //    VAOs requires a call to glBindVertexArray anyways so we generally don't unbind VAOs (nor VBOs) when it's not directly necessary.
     //    glBindVertexArray(0);   //取消VAO绑定

         //线框模式,QOpenGLExtraFunctions没这函数, 3_3_Core有
     //    glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
}

void myOpengl::resizeGL(int w, int h) {
    glViewport(0, 0, w, h);
}
void myOpengl::paintGL() {
    glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
    glClear(GL_COLOR_BUFFER_BIT);

    shaderProgram.bind();
    {
        // bind textures on corresponding texture units
        glActiveTexture(GL_TEXTURE0);
        glBindTexture(GL_TEXTURE_2D, texture1);
        // render container
        glBindVertexArray(VAO);
        glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);
    }
    shaderProgram.release();
}
void myOpengl::getPath(QString p) {

    _filePath = p;
    update();
}

```

  • 写回答

2条回答 默认 最新

  • 无夜_ 2022-04-14 17:51
    关注

    信号槽连接正确的话,发送路径后好像没有调用渲染直接就更新控件结束了

    评论 编辑记录

报告相同问题?

问题事件

  • 修改了问题 4月16日
  • 修改了问题 4月16日
  • 创建了问题 4月14日

悬赏问题

  • ¥20 求一个html代码,有偿
  • ¥100 关于使用MATLAB中copularnd函数的问题
  • ¥20 在虚拟机的pycharm上
  • ¥15 jupyterthemes 设置完毕后没有效果
  • ¥15 matlab图像高斯低通滤波
  • ¥15 针对曲面部件的制孔路径规划,大家有什么思路吗
  • ¥15 钢筋实图交点识别,机器视觉代码
  • ¥15 如何在Linux系统中,但是在window系统上idea里面可以正常运行?(相关搜索:jar包)
  • ¥50 400g qsfp 光模块iphy方案
  • ¥15 两块ADC0804用proteus仿真时,出现异常