一、概述
需求:
1.将两纹理进行融合,改变其中一个透明度让其渐渐显示或隐藏
2.控制x轴像素互换,让笑脸达到向左看或向右看的目的。
大部分的代码都是常规代码。还是那一套流程:
1.定义顶点、纹理、顶点索引坐标。
2.创建并绑定VAO、VBO、EBO。
3.告知显卡顶点解析方式。
4.定义顶点着色器及片元着色器,编译程序。
5.创建纹理。
6.开始绘制
这里面最主要的是顶点即纹理的定义、着色器的传参、绘制代码
步骤:
1.定义顶点、纹理坐标
float vertices[] = { // ---- 位置 ---- - 纹理坐标 - 1.0f, 1.0f, 0.0f, 1.0f, 1.0f, // 右上 1.0f, -1.0f, 0.0f, 1.0f, 0.0f, // 右下 -1.0f, -1.0f, 0.0f, 0.0f, 0.0f, // 左下 -1.0f, 1.0f, 0.0f, 0.0f, 1.0f // 左上 }; unsigned int indices[] = { 0, 1, 3, // first triangle 1, 2, 3 // second triangle };
2.着色器的定义
//顶点着色器 #version 330 core layout (location = 0) in vec3 aPos; layout (location = 1) in vec2 aTexCoord; out vec2 ourTexCoord; void main(void) { gl_Position = vec4(aPos.x,aPos.y,aPos.z,1.0f); ourTexCoord = aTexCoord; } //片元着色器 #version 330 core out vec4 FragColor; in vec2 ourTexCoord; uniform float maxScale; uniform float flip_x; uniform sampler2D ourTexture1; uniform sampler2D ourTexture2; void main() { FragColor = mix(texture(ourTexture1,ourTexCoord),texture(ourTexture2,vec2(ourTexCoord.x*flip_x,ourTexCoord.y)),maxScale); }
3.给定义的着色器传参(绘制)
glUniform1f(glGetUniformLocation(programId, "flip_x"), flip_x); glUniform1f(glGetUniformLocation(programId, "maxScale"), mixScale); //指定纹理单元编号 GLint ourTextureLocation = glGetUniformLocation(programId, "ourTexture1"); glUniform1i(ourTextureLocation, 0); GLint ourTexture1Location = glGetUniformLocation(programId, "ourTexture2"); glUniform1i(ourTexture1Location, 1);
二、完整代码示例
1.GLTextureMixWindow.h
#pragma once #include "BaseOpenGLWindow.h" #ifndef STB_IMAGE_H #define STB_IMAGE_H #include "../../stb_image.h" #endif // STB_IMAGE_H #include <qmatrix4x4.h> #include <qvector3d.h> #include <QRectF> class GLTextureMixWindow : public BaseOpenGLWindow { Q_OBJECT public: GLTextureMixWindow(QWidget *parent = nullptr); ~GLTextureMixWindow(); protected: virtual void initializeGL();//初始化OpenGL virtual void resizeGL(int w, int h);//ResizeWindow大小 virtual void paintGL();//绘制OpenGL public: GLuint buildTexture(QString textureFileName, GLint imageColorType); void setMixScale(float mix); void flipToX(); private: unsigned int VAO, VBO, EBO; unsigned int texture, texture1, texture2; GLuint programId; float mixScale = 0.5f; float flip_x = 1.0f; };
2.GLTextureMixWindow.cpp
#include "GLTextureMixWindow.h" GLTextureMixWindow::GLTextureMixWindow(QWidget* parent) : BaseOpenGLWindow(parent) { this->setWindowTitle("纹理融合"); QHBoxLayout* hLayout = new QHBoxLayout(this); QPushButton* btnRed = new QPushButton(this); btnRed->setText("融合系数增大(+)"); QPushButton* btnGreen = new QPushButton(this); btnGreen->setText("融合系数减小(-)"); QPushButton* btnFlipX = new QPushButton(this); btnFlipX->setText("x轴像素位置互换"); hLayout->addWidget(btnRed); hLayout->addWidget(btnGreen); hLayout->addWidget(btnFlipX); hLayout->setAlignment(Qt::AlignTop); connect(btnRed, &QPushButton::clicked, [this]() { this->mixScale += 0.1f; if (this->mixScale >= 1.0f) this->mixScale = 1.0f; setMixScale(mixScale); }); connect(btnGreen, &QPushButton::clicked, [=]() { this->mixScale -= 0.1f; if (this->mixScale < 0.0f) this->mixScale = 0.0f; setMixScale(mixScale); }); connect(btnFlipX, &QPushButton::clicked, [=]() { flipToX(); }); } void GLTextureMixWindow::initializeGL() { this->initializeOpenGLFunctions(); glClearColor(1.0f, 1.0f, 1.0f, 1.0f); glClear(GL_COLOR_BUFFER_BIT); float vertices[] = { // ---- 位置 ---- - 纹理坐标 - 1.0f, 1.0f, 0.0f, 1.0f, 1.0f, // 右上 1.0f, -1.0f, 0.0f, 1.0f, 0.0f, // 右下 -1.0f, -1.0f, 0.0f, 0.0f, 0.0f, // 左下 -1.0f, 1.0f, 0.0f, 0.0f, 1.0f // 左上 }; //float vertices[] = { // // ---- 位置 ---- - 纹理坐标 - // 1.0f, 1.0f, 0.0f, 4.0f, 4.0f, // 右上 // 1.0f, -1.0f, 0.0f, 4.0f, 0.0f, // 右下 // -1.0f, -1.0f, 0.0f, 0.0f, 0.0f, // 左下 // -1.0f, 1.0f, 0.0f, 0.0f, 4.0f // 左上 //}; unsigned int indices[] = { 0, 1, 3, // first triangle 1, 2, 3 // second triangle }; //创建VAO、VBO、EBO glGenVertexArrays(1, &VAO); glGenBuffers(1, &VBO); glGenBuffers(1, &EBO); glBindVertexArray(VAO); ////顶点数据存入缓冲区 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); ////告知显卡顶点数据如何解析 glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void*)0); glEnableVertexAttribArray(0); ////告知显卡纹理坐标如何解析 glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void*)(3 * sizeof(float))); glEnableVertexAttribArray(1); stbi_set_flip_vertically_on_load(true); texture = buildTexture("E:/tony/demo/visualstudio_workspace/QtForOpenCV4Tool/QtForOpenCV4Tool/bin/images/flowers.jpeg", GL_RGB); texture1 = buildTexture("E:/tony/demo/visualstudio_workspace/QtForOpenCV4Tool/QtForOpenCV4Tool/bin/images/similing_face.png", GL_RGBA); //小程序 programId = buildAttachShaderAndReturnProgramId(":/QtForOpenCV4Tool/shader/texture_mix.vert", ":/QtForOpenCV4Tool/shader/texture_mix.frag"); } GLuint GLTextureMixWindow::buildTexture(QString textureFileName, GLint imageColorType) { GLuint mTexture; ////创建纹理 glGenTextures(1, &mTexture); glBindTexture(GL_TEXTURE_2D, mTexture); //设置纹理环绕方式 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); //设置纹理过滤方式 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); //生成纹理 int width, height, mChannels; //QString path = getTexturePath(textureFileName); //qDebug() << path.toStdString().c_str(); unsigned char* data = stbi_load(textureFileName.toStdString().c_str(), &width, &height, &mChannels, 0); if (data) { qDebug() << "图片加载成功,width=" << width << ",height=" << height; glTexImage2D(GL_TEXTURE_2D, 0, imageColorType, width, height, 0, imageColorType, GL_UNSIGNED_BYTE, data); glGenerateMipmap(GL_TEXTURE_2D); } else { qDebug() << "图像数据加载失败"; } stbi_image_free(data); return mTexture; } void GLTextureMixWindow::resizeGL(int w, int h) { glViewport(0, 0, w, h); } void GLTextureMixWindow::paintGL() { glBindVertexArray(VAO); glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, texture); glActiveTexture(GL_TEXTURE1); glBindTexture(GL_TEXTURE_2D, texture1); glUseProgram(programId); glUniform1f(glGetUniformLocation(programId, "flip_x"), flip_x); glUniform1f(glGetUniformLocation(programId, "maxScale"), mixScale); //指定纹理单元编号 GLint ourTextureLocation = glGetUniformLocation(programId, "ourTexture1"); glUniform1i(ourTextureLocation, 0); GLint ourTexture1Location = glGetUniformLocation(programId, "ourTexture2"); glUniform1i(ourTexture1Location, 1); glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0); } void GLTextureMixWindow::setMixScale(float mix) { this->mixScale = mix; update(); } void GLTextureMixWindow::flipToX() { this->flip_x = -this->flip_x; update(); } GLTextureMixWindow::~GLTextureMixWindow() { }
标签:1.0,Qt,OpenGL,0.0,void,纹理,GLTextureMixWindow,GL From: https://www.cnblogs.com/tony-yang-flutter/p/18376647