鉴于前一篇博客的问题,我又尝试用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"文件夹下,否则纹理载入会失败: