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