Qt5.6.0+OpenGL 纹理贴图首战告捷

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Qt5.6.0+OpenGL 纹理贴图首战告捷相关的知识,希望对你有一定的参考价值。

重要的话写在前面~~通过今晚的实验,知道了EBO是不能随便release的~~~一直不要release就可以了,否则vao会失效

 

Display.h

#ifndef DISPLAYWIDGET_H
#define DISPLAYWIDGET_H

#include <QGLWidget>

#include <QOpenGLFunctions>
#include <QOpenGLBuffer>
#include <QOpenGLVertexArrayObject>
#include <QOpenGLShaderProgram>
#include <QOpenGLVertexArrayObject>
#include <QOpenGLTexture>

class DisplayGLWidget:public QGLWidget,protected QOpenGLFunctions
{
    Q_OBJECT
public:
    DisplayGLWidget(QWidget *parent = 0);
    ~DisplayGLWidget();

    void teardownGL();
public slots:
    //void CompileAndLinkVertexShader(const QString& shaderText);
    //void CompileAndLinkFragmentShader(const QString& shaderText);
    
protected:
    
    void initializeGL() ;
    void paintGL() ;
    void resizeGL(int width, int height) ; 


    //void keyPressEvent(QKeyEvent *event) override;
    void mousePressEvent(QMouseEvent *event) override;
    void mouseMoveEvent(QMouseEvent *event) override;

private:
    QOpenGLBuffer m_vbo;
    QOpenGLBuffer m_ebo;
    QOpenGLVertexArrayObject m_vao;
    QOpenGLShaderProgram *m_program;
    QOpenGLTexture *texture;

        

    void printVersionInformation();

    void initTextures();


};


#endif

 

Display.cpp

#include "DisplayGLWidget.h"
#include "Vertex.h"

#include <QDebug>
#include <iostream>

// Create a colored triangle
static const Vertex sg_vertexes[] = {
  Vertex( QVector3D( 0.00f,  0.75f, 1.0f), QVector3D(1.0f, 0.0f, 0.0f) ),
  Vertex( QVector3D( 0.75f, -0.75f, 1.0f), QVector3D(0.0f, 1.0f, 0.0f) ),
  Vertex( QVector3D(-0.75f, -0.75f, 1.0f), QVector3D(0.0f, 0.0f, 1.0f) )
};

static const GLfloat 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
};

static const GLfloat vertices1[] = 
{
-0.5f, 0.5f, 0.0f, // Top Left
-0.5f,0.0f,    0.0f,
0.0f, 0.5f, 0.0f
};


static const GLuint indices[] = { // Note that we start from 0!
0, 1, 3, // First Triangle
1, 2, 3 // Second Triangle
};




DisplayGLWidget::DisplayGLWidget(QWidget* parent)
    :QGLWidget(parent)
    //: QGLWidget(QGLFormat(QGL::SampleBuffers),parent)
    , m_vbo(QOpenGLBuffer::VertexBuffer)
    , m_ebo(QOpenGLBuffer::IndexBuffer)
    
{
    
    int a = 1;
    //timer.start();
}

DisplayGLWidget::~DisplayGLWidget()
{
    makeCurrent();
    teardownGL();
}

void DisplayGLWidget::teardownGL()
{
     // Actually destroy our OpenGL information
    m_vbo.destroy();
    m_ebo.destroy();
    m_vao.destroy();
    delete m_program;
}

void DisplayGLWidget::initializeGL()
{
    //glShadeModel(GL_SMOOTH);        // 启用阴影光滑
    //glClearColor(0.2,0.2,0.2,0);    // 设置清除屏幕的颜色
    //glClearDepth(1.0);                // 设置深度缓存
    //glEnable(GL_DEPTH_TEST);        // 深度测试
    //glDepthFunc(GL_LEQUAL);            // 启用深度测试
    //glHint(GL_PERSPECTIVE_CORRECTION_HINT,GL_NICEST);    // 进行最好的透视修正,可能会影响性能
     initializeOpenGLFunctions();
     printVersionInformation();
     glClearColor(0.3,0.3,0.3,0);    

     // Application-specific initialization

    {
    // Create Shader (Do not release until VAO is created)
    m_program = new QOpenGLShaderProgram();
    m_program->addShaderFromSourceFile(QOpenGLShader::Vertex, "./shaders/simple.vert");
    m_program->addShaderFromSourceFile(QOpenGLShader::Fragment, "./shaders/simple.frag");
    m_program->link();
    m_program->bind();
 
    // Create Vertex Array Object
    m_vao.create();
    m_vao.bind();

    // Create Buffer (Do not release until VAO is created)
    m_vbo.create();
    m_vbo.bind();
    m_vbo.setUsagePattern(QOpenGLBuffer::StaticDraw);
    m_vbo.allocate(vertices, sizeof(vertices));

    m_ebo.create();    
    m_ebo.bind();    
    m_ebo.setUsagePattern(QOpenGLBuffer::StaticDraw);
    m_ebo.allocate(indices,sizeof(indices));
 
   
    m_program->enableAttributeArray(0);    
    m_program->enableAttributeArray(1);
    m_program->enableAttributeArray(2);
    m_program->setAttributeBuffer(0, GL_FLOAT, 0, 3 , 8*sizeof(GLfloat));      // 3表示的是这一个属性里面有几个分量
    m_program->setAttributeBuffer(1, GL_FLOAT, 3*sizeof(GLfloat), 3,  8*sizeof(GLfloat));
    m_program->setAttributeBuffer(2, GL_FLOAT, 6 * sizeof(GLfloat), 2, 8 * sizeof(GLfloat));
    
    initTextures();

    // Release (unbind) all
    
    m_vbo.release();
    m_vao.release();    
    //m_ebo.release();
    m_program->release();    
  }    

}

void DisplayGLWidget::paintGL()
{
    //makeCurrent();

    glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);    // 清除屏幕和深度缓存
    //glLoadIdentity();                                    // 重置当前模型的观察矩阵
     // Render using our shader
    
    m_program->bind();
    {
        
        m_program->setUniformValue("ourTexture", 0);
        texture->bind();
        m_vao.bind();
        glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
        glDrawElements(GL_TRIANGLES,6,GL_UNSIGNED_INT,0);
        //glDrawArrays(GL_TRIANGLES, 0, sizeof(sg_vertexes) / sizeof(sg_vertexes[0]));
        //glDrawArrays(GL_TRIANGLES, 0, 3);
        m_vao.release();
    }
    m_program->release();

    /*m_program1->bind();
    {        
        m_vao1.bind();
        glDrawArrays(GL_TRIANGLES,0,3);
        m_vao1.release();
    }
    m_program1->release();*/
}


void DisplayGLWidget::resizeGL(int width, int height)
{
    if (height == 0)                            // 规定屏幕高度不得低于20
    {
        height = 20;
    }
    glViewport(0,0,(GLint)width,(GLint)height);    // 重置当前的视口
    glMatrixMode(GL_PROJECTION);                // 选择投影矩阵
    glLoadIdentity();                            // 重置投影矩阵
    //gluPerspective(45.0,(GLfloat)width/(GLfloat)height,0.1,100.0); // 建立透视投影矩阵
    glMatrixMode(GL_MODELVIEW); // 选择模型观察矩阵
    glLoadIdentity();            // 重置模型观察矩阵
}

//void DisplayGLWidget::keyPressEvent(QKeyEvent* e)
//{
//    switch (e->key())
//    {
//    default:
//        break;
//    }
//}


void DisplayGLWidget::mouseMoveEvent(QMouseEvent* event)
{
    
}

void DisplayGLWidget::printVersionInformation()
{
    QString glType;
    QString glVersion;
    QString glProfile;
 
    // Get Version Information
    //glType = (context()->isOpenGLES()) ? "OpenGL ES" : "OpenGL";
    glVersion = reinterpret_cast<const char*>(glGetString(GL_VERSION));
 
    // Get Profile Information
#define CASE(c) case QSurfaceFormat::c: glProfile = #c; break
  switch (format().profile())
  {
    CASE(NoProfile);
    CASE(CoreProfile);
    CASE(CompatibilityProfile);
  }
#undef CASE
 
  // qPrintable() will print our QString w/o quotes around it.
  //qDebug() << qPrintable(glType) << qPrintable(glVersion) << "(" << qPrintable(glProfile) << ")";
  qDebug() << qPrintable(glVersion) << "(" << qPrintable(glProfile) << ")";
}

void DisplayGLWidget::initTextures()
{
    texture = new QOpenGLTexture(QImage("./resources/texture/flower.jpg").mirrored());
    texture->setMinificationFilter(QOpenGLTexture::Nearest);
    texture->setMagnificationFilter(QOpenGLTexture::Linear);
    texture->setWrapMode(QOpenGLTexture::Repeat);


}

void DisplayGLWidget::mousePressEvent(QMouseEvent* event)
{
    
}

 

 

结果:

技术分享

 

以上是关于Qt5.6.0+OpenGL 纹理贴图首战告捷的主要内容,如果未能解决你的问题,请参考以下文章

OpenGL入门05.纹理贴图

OpenGL——OpenCV读取图片进行纹理贴图

OpenGL-纹理(下)

OpenGL - 链接两个纹理不起作用

Opengl ES 1.x NDK实例开发之六:纹理贴图

应用纹理贴图