【OpenGL】--- 使用Qt与OpenGL绘制纹理贴图的正方形

OpenGL是一款强大的图形渲染库,而Qt则提供了一套方便的工具集,使得在Qt应用程序中集成OpenGL变得相对简单。本文将介绍如何使用Qt和OpenGL,通过单独的顶点着色器和片段着色器文件,绘制一个带有纹理贴图的正方形。我们将分步讲解,确保你能轻松理解每个步骤。

1. 准备工作

在创建一个Qt Widgets应用程序项目后,首先在项目的根目录下创建两个文件,分别命名为vertexshader.glslfragmentshader.glsl。这两个文件将包含我们的顶点着色器和片段着色器代码。

vertexshader.glsl
#version 330 core
layout (location = 0) in vec3 aPos;
layout (location = 1) in vec2 aTexCoord;

out vec2 TexCoord;

void main()
{
    gl_Position = vec4(aPos, 1.0);
    TexCoord = aTexCoord;
}

fragmentshader.glsl

#version 330 core
in vec2 TexCoord;
out vec4 FragColor;

uniform sampler2D ourTexture;

void main()
{
    FragColor = texture(ourTexture, TexCoord);
}

2. 主窗口类的修改

修改主窗口类的头文件和源文件,添加对应的成员变量和函数,以便使用着色器文件和绘制正方形。

mainwindow.h

// mainwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include 
#include 
#include 
#include 

namespace Ui {
class MainWindow;
}

class MyOpenGLWidget : public QOpenGLWidget, protected QOpenGLFunctions
{
    Q_OBJECT

public:
    MyOpenGLWidget(QWidget *parent = nullptr);
    ~MyOpenGLWidget() override;

protected:
    void initializeGL() override;
    void resizeGL(int w, int h) override;
    void paintGL() override;

private:
    QOpenGLShaderProgram shaderProgram;
    GLuint VAO, VBO, EBO;
    GLuint textureID;

    void setupShaderProgram();
    void setupVertices();
    void setupTexture();
};

#endif // MAINWINDOW_H

mainwindow.cpp

// mainwindow.cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include 
#include 
#include 

MyOpenGLWidget::MyOpenGLWidget(QWidget *parent)
    : QOpenGLWidget(parent)
{
}

MyOpenGLWidget::~MyOpenGLWidget()
{
}

void MyOpenGLWidget::initializeGL()
{
    initializeOpenGLFunctions();

    glEnable(GL_DEPTH_TEST);

    setupShaderProgram();
    setupVertices();
    setupTexture();
}

void MyOpenGLWidget::resizeGL(int w, int h)
{
    glViewport(0, 0, w, h);
}

void MyOpenGLWidget::paintGL()
{
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    shaderProgram.bind();

    glBindVertexArray(VAO);
    glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);

    glBindVertexArray(0);
    shaderProgram.release();
}

void MyOpenGLWidget::setupShaderProgram()
{
    // 加载顶点着色器和片段着色器
    shaderProgram.addShaderFromSourceFile(QOpenGLShader::Vertex, ":/vertexshader.glsl");
    shaderProgram.addShaderFromSourceFile(QOpenGLShader::Fragment, ":/fragmentshader.glsl");

    // 链接着色器程序
    shaderProgram.link();
}

void MyOpenGLWidget::setupVertices()
{
    GLfloat vertices[] = {
        // 位置            // 纹理坐标
         0.5f,  0.5f, 0.0f,  1.0f, 1.0f, // 右上角
         0.5f, -0.5f, 0.0f,  1.0f, 0.0f, // 右下角
        -0.5f, -0.5f, 0.0f,  0.0f, 0.0f, // 左下角
        -0.5f,  0.5f, 0.0f,  0.0f, 1.0f  // 左上角
    };

    GLuint indices[] = {
        0, 1, 3, // 第一个三角形
        1, 2, 3  // 第二个三角形
    };

    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);

    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);

    glBindBuffer(GL_ARRAY_BUFFER, 0);

    glBindVertexArray(0);
}

void MyOpenGLWidget::setupTexture()
{
    QImage image(":/texture.jpg");
    if (image.isNull()) {
        qDebug() << "Failed to load texture image";
        return;
    }

    QOpenGLTexture* texture = new QOpenGLTexture(image.mirrored());
    texture->setMinificationFilter(QOpenGLTexture::Linear);
    texture->setMagnificationFilter(QOpenGLTexture::Linear);
    texture->setWrapMode(QOpenGLTexture::Repeat);

    textureID = texture->textureId();
    shaderProgram.bind();
    shaderProgram.setUniformValue("ourTexture", 0);
    shaderProgram.release();
}

3. 加载纹理和设置参数

确保将你的纹理图片(如texture.jpg)放在项目的资源文件夹中。然后运行程序,你应该能够看到一个带有纹理的正方形。

这个简单的例子展示了如何在Qt中使用OpenGL,加载纹理贴图,并通过顶点着色器和片段着色器文件绘制一个带有纹理的正方形。你可以基于这个例子进行更复杂的OpenGL应用程序的开发。

你可能感兴趣的:(OpenGL,计算机视觉,图形渲染)