点击按钮 无法将路径传递过去,opengl控件无法进行绘图
我将QOpenGLWidget_2控件提升为myOpengl的类
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();
}
```