Qt结合GLSL贴出纹理(二、采用QOpenGLShaderProgram和QOpenGLTexture)

鉴于前一篇博客的问题,我又尝试用QOpenGLShaderProgram和QOpenGLTexture来贴纹理。

pro文件:

#-------------------------------------------------
#
# Project created by QtCreator 2018-02-21T16:49:46
#
#-------------------------------------------------

QT       += core gui opengl

greaterThan(QT_MAJOR_VERSION, 4): QT += widgets

TARGET = qshader4
TEMPLATE = app


SOURCES += main.cpp\
        mainwindow.cpp

HEADERS  += mainwindow.h
LIBS += -lopengl32 -lGLU32

h文件:

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QOpenGLWidget>
#include <QOpenGLFunctions>
#include <QOpenGLTexture>
#include <QOpenGLShader>
#include <QOpenGLShaderProgram>

class MainWindow : public QOpenGLWidget, protected QOpenGLFunctions
{
    Q_OBJECT

public:
    MainWindow(QWidget *parent = 0);
    ~MainWindow();

    GLuint                          m_uiVertLoc;
    QOpenGLTexture          *       m_pTextures;
    QOpenGLShaderProgram    *       m_pProgram;
    GLfloat                 *       m_pVertices;
    //unsigned char *     pLoadTex(char * Image, unsigned long & bWidth, unsigned long & bHeight);
protected:
    void        initializeGL();
    void        paintGL();
    void        resizeGL(int w, int h);
};

#endif // MAINWINDOW_H

cpp文件:

#include "mainwindow.h"

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

MainWindow::~MainWindow()
{
    m_pTextures->release();
    delete m_pTextures;
    delete m_pProgram;
    delete [] m_pVertices;

}

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

    m_pVertices = new GLfloat[18];
    //给顶点赋值
    GLfloat arrVertices[18] = {0.0, 1.0, 0.0,
                               0.0, 0.0, 0.0,
                               1.0, 0.0, 0.0,
                               1.0, 0.0, 0.0,
                               1.0, 1.0, 0.0,
                               0.0, 1.0, 0.0};
    m_pVertices = new GLfloat[18];
    memcpy(m_pVertices, arrVertices, 18 * sizeof(GLfloat));

    QOpenGLShader *vshader = new QOpenGLShader(QOpenGLShader::Vertex, this);
    const char *vsrc =
                        "#version 330\n"
                        "in vec3 pos;\n"
                        "out vec2 texCoord;\n"
                        //"uniform mat4 mat4MVP;\n"
                        "void main()\n"
                        "{\n"
                        "    gl_Position = vec4(pos, 1.0);\n"
                        "    texCoord = pos.xy;\n"
                        "}\n";
    vshader->compileSourceCode(vsrc);

    QOpenGLShader *fshader = new QOpenGLShader(QOpenGLShader::Fragment, this);
    const char *fsrc =
                        "#version 330\n"
                        "out mediump vec4 color;\n"
                        "in vec2 texCoord;\n"
                        "uniform sampler2D Tex\n;"
                        "void main()\n"
                        "{\n"
                        "    color = texture(Tex, texCoord);\n"
                        //"      color = vec4(1.0, 0.0, 0.0, 0.0);\n"
                        "}\n";
    fshader->compileSourceCode(fsrc);

    m_pProgram = new QOpenGLShaderProgram;
    m_pProgram->addShader(vshader);
    m_pProgram->addShader(fshader);
    m_pProgram->link();
    m_pProgram->bind();

    m_uiVertLoc = m_pProgram->attributeLocation("pos");
    m_pProgram->enableAttributeArray(m_uiVertLoc);
    m_pProgram->setAttributeArray(m_uiVertLoc, m_pVertices, 3, 0);

    m_pTextures = new QOpenGLTexture(QImage(QString("earth.bmp")).mirrored());
    m_pTextures->setMinificationFilter(QOpenGLTexture::Nearest);
    m_pTextures->setMagnificationFilter(QOpenGLTexture::Linear);
    m_pTextures->setWrapMode(QOpenGLTexture::Repeat);
    m_pProgram->setUniformValue("Tex", 0);//这里的“0”与paintGL函数里的bind(0)不必是0,但是要相等


    glEnable(GL_DEPTH_TEST);
    glClearColor(0,0,0,1);
}

void MainWindow::paintGL()
{
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    m_pTextures->bind(0);//这里的“0”与initializeGL()函数里的setUniformValue("Tex", 0)不必是0, 但是要相等

    glDrawArrays(GL_TRIANGLES, 0, 6);
    m_pTextures->release();
}

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

结果:


注意,纹理文件earth.bmp要放在“build-XXXXXX"文件夹下,否则纹理载入会失败:


展开阅读全文

没有更多推荐了,返回首页