QT中学习Opengl---(纹理基本加载opengl写法)

前言:

本文的代码是 LearnOpenGL 中对应代码,这里提供学习,大家喜欢的可去官方网站去看看:

LearnOpenGL-CNhttps://learnopengl-cn.readthedocs.io/zh/latest/本章为加载纹理,qt有自己简单的封装方式,可以更快的加载,代码简洁,但是为了学习,本章采用了。

纹理(Textures)

        艺术家和程序员更喜欢使用纹理(Texture)。 纹理是一个2D图片(也有1D和3D), 它用来添加物体的细节; 这就像有一张绘有砖块的图片贴到你的3D的房子上, 你的房子看起来就像一堵砖
墙。 因为我们可以在一张图片上插入足够多的细节, 这样物体就会拥有很多细节而不用增加
额外的顶点。

纹理坐标:

QT中学习Opengl---(纹理基本加载opengl写法)_第1张图片 

 加载纹理图:

这里使用的是 LearnOpenGL 提供的stb_image.h 文件,用它来加载数据。

基本使用:

#define STB_IMAGE_IMPLEMENTATION
#include "stb_image.h"

 使用这个头文件,你要定义宏,不然你对应的函数使用不了。

图形运行:

QT中学习Opengl---(纹理基本加载opengl写法)_第2张图片

 原图:

 如果你只是加载数据,图片是反过来的。可以顶点着色器修改对应的y值。

顶点着色器

#version 330 core
layout (location = 0) in vec3 aPos;
layout (location = 1) in vec3 aColor;
layout (location = 2) in vec2 aTexCoord;

out vec3 ourColor;
out vec2 TexCoord;

void main()
{
        gl_Position = vec4(aPos, 1.0);
        ourColor = aColor;
        TexCoord = vec2(aTexCoord.x,1- aTexCoord.y);
}

这里用了 1- aTexCoord.y  就是把y反过来。

片段着色器

#version 330 core
out vec4 FragColor;

in vec3 ourColor;
in vec2 TexCoord;

// texture sampler
uniform sampler2D texture1;

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

 绑定纹理:

//绑定纹理
    glGenTextures(1, &texture);
    glBindTexture(GL_TEXTURE_2D, texture); // all upcoming GL_TEXTURE_2D operations now have effect on this texture object

 设置环绕模式:

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_MIPMAP_LINEAR);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);

加载纹理到缓存:

 unsigned char *data  = stbi_load("G:/dataQt/OpenglLearn/chap03/triangleTextures/brickwall.jpg",&width,&height,&nrChannels,0);
    //unsigned char *data  = stbi_load("brickwall.jpg",&width,&height,&nrChannels,0);
    if(data)
    {
        glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, data);
        glGenerateMipmap(GL_TEXTURE_2D);
    }
    else
    {
         qDebug() << "Failed to load texture" ;
    }
    stbi_image_free(data);

全部代码段:

        提示:在使用stbi_load 函数时候,在qt中不能写相对路径,不然找不到图片。

#ifndef BKQOPENGLW_H
#define BKQOPENGLW_H

#include 
#include 
#include 
class BKQOpenglW : public QOpenGLWidget, QOpenGLFunctions_3_3_Core
{
    Q_OBJECT
public:
    enum Shape{None,Rect,circle,Triangle};
    explicit BKQOpenglW(QWidget *parent = nullptr);
    ~BKQOpenglW();
    void drawShapes(Shape shape);
    void setWireFrame(bool b);
protected:
    virtual void initializeGL();
    virtual void resizeGL(int w, int h);
    virtual void paintGL();

signals:

public slots:

private:
unsigned int VBO, VAO,EBO;
Shape m_Shape;
QOpenGLShaderProgram shaderProgram;
unsigned int texture;
};

#endif // BKQOPENGLW_H

对应cpp:

#include "bkqopenglw.h"
#include
#include 

#define STB_IMAGE_IMPLEMENTATION
#include "stb_image.h"

float vertices[] = {
        // positions          // colors           // texture coords
         0.5f,  0.5f, 0.0f,   1.0f, 0.0f, 0.0f,   1.0f, 1.0f, // top right
         0.5f, -0.5f, 0.0f,   0.0f, 1.0f, 0.0f,   1.0f, 0.0f, // bottom right
        -0.5f, -0.5f, 0.0f,   0.0f, 0.0f, 1.0f,   0.0f, 0.0f, // bottom left
        -0.5f,  0.5f, 0.0f,   1.0f, 1.0f, 0.0f,   0.0f, 1.0f  // top left
    };


unsigned int indices[] = {  // note that we start from 0!
    0, 1, 3,  // first Triangle
    1, 2, 3   // second Triangle
};

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

}

BKQOpenglW::~BKQOpenglW()
{
    makeCurrent();
    glDeleteVertexArrays(1,&VAO);
    glDeleteBuffers(1,&VBO);
    doneCurrent();
}

void BKQOpenglW::drawShapes(BKQOpenglW::Shape shape)
{
    m_Shape = shape;
    update();
}

void BKQOpenglW::setWireFrame(bool b)
{
    makeCurrent();
    if(b)
    {
       glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
    }
    else {
       glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
    }
    update();
    doneCurrent();
}

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

    //    shaderProgram.addShaderFromSourceCode(QOpenGLShader::Vertex,vertexShaderSource);
    //    shaderProgram.addShaderFromSourceCode(QOpenGLShader::Fragment,fragmentShaderSource);
    shaderProgram.addShaderFromSourceFile(QOpenGLShader::Vertex,":/shader/shader.vs");
    shaderProgram.addShaderFromSourceFile(QOpenGLShader::Fragment,":/shader/shader.fs");
    shaderProgram.link();
    glGenVertexArrays(1, &VAO);
    glGenBuffers(1, &VBO);
    // bind the Vertex Array Object first, then bind and set vertex buffer(s), and then configure vertex attributes(s).
    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, 8 * sizeof(float), nullptr);
    glEnableVertexAttribArray(0);

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

    //绑定纹理
    glGenTextures(1, &texture);
    glBindTexture(GL_TEXTURE_2D, texture); // all upcoming GL_TEXTURE_2D operations now have effect on this texture object
    // set the texture wrapping parameters
    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_MIPMAP_LINEAR);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);

    int width, height, nrChannels;
    unsigned char *data  = stbi_load("G:/dataQt/OpenglLearn/chap03/triangleTextures/brickwall.jpg",&width,&height,&nrChannels,0);
    //unsigned char *data  = stbi_load("brickwall.jpg",&width,&height,&nrChannels,0);
    if(data)
    {
        glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, data);
        glGenerateMipmap(GL_TEXTURE_2D);
    }
    else
    {
         qDebug() << "Failed to load texture" ;
    }
    stbi_image_free(data);
    // note that this is allowed, the call to glVertexAttribPointer registered VBO as the vertex attribute's bound vertex buffer object so afterwards we can safely unbind
    glBindBuffer(GL_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);

}

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

void BKQOpenglW::paintGL()
{
    glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
    glClear(GL_COLOR_BUFFER_BIT);

    shaderProgram.bind();
    glBindVertexArray(VAO);
    glBindTexture(GL_TEXTURE_2D, texture);
    switch (m_Shape) {
    case Triangle:
        glDrawArrays(GL_TRIANGLES,0,3);
        break;
    case Rect:
        glDrawElements(GL_TRIANGLES,6,GL_UNSIGNED_INT,0);
        break;
    default:
        break;
    }

}

写在后面的话: 

喜欢我博客的小伙伴们,也同时想在qt上学习opengl的伙伴,可以关注与点赞博客,让我们共同进步吧。

你可能感兴趣的:(Qt之Opengl,qt,opengl,纹理,Textures)