zoukankan      html  css  js  c++  java
  • Qt551.OpenGL.ZC简单例子

    1、主要 模仿代码:OpenGL的教程 第3课 "tutorial03_matrices"的代码(E:OpenGL_somethingogl-master)

    2、参考代码:Qt5中的例子源码:

      (1)C:QtQt5.3.2ExamplesQt-5.3opengl            (E:Project_Qt532Official_Examples)

      (2)C:QtQt5.3.2ExamplesQt-5.3openglcube

      (3)C:QtQt5.5.1ExamplesQt-5.5opengl            (E:Project_Qt551Official_Examples)

      (4)C:QtQt5.5.1ExamplesQt-5.5openglhellogl2

    3、代码:

     (1)main.cpp

     1 #include "mainwindow.h"
     2 #include <QApplication>
     3 
     4 #include "test01.h"
     5 
     6 int main(int argc, char *argv[])
     7 {
     8     QApplication a(argc, argv);
     9 //    MainWindow w;
    10     test01 w;
    11     w.show();
    12 
    13     return a.exec();
    14 }

     (2)test01.h

     1 #ifndef __TEST_01_H__
     2 #define __TEST_01_H__
     3 
     4 #include <iostream>
     5 #include <string>
     6 using namespace std;
     7 
     8 //openGL窗口相关文件
     9 #include <QOpenGLWidget>
    10 #include <QOpenGLFunctions_3_3_Core>
    11 
    12 #include <QMatrix4x4>
    13 
    14 class test01 :public QOpenGLWidget, public QOpenGLFunctions_3_3_Core
    15 {
    16     Q_OBJECT
    17 public:
    18     explicit test01(QWidget *parent = 0);
    19     ~test01();
    20 
    21 public:
    22     virtual void initializeGL();
    23     virtual void resizeGL(int w, int h);// ZC: 不处理窗口大小变化
    24     virtual void paintGL();
    25 
    26 private:
    27     unsigned int FuiProgramID;
    28     GLuint Fvbo;
    29 
    30 
    31 public:
    32     GLuint FuiMVP;
    33     QMatrix4x4 Fmodel;
    34     QMatrix4x4 Fview;
    35     QMatrix4x4 Fprojection;
    36     QMatrix4x4 Fmvp;
    37 
    38 public:
    39     int ShaderLoad_Z(
    40             const QString &_strFullFileName_ShaderVertex,
    41             const QString &_strFullFileName_ShaderFregment);
    42     bool CheckCompileErrors(unsigned int _shader, const std::string &_strType);
    43 };
    44 
    45 #endif // __TEST_01_H__

     (3)test01.cpp

      ZC:注意 资源文件的路径问题:":/test01/shaders/test01/ShaderVertex.glsl",前一部分"/test01"是前缀,后一部分"shaders/test01/ShaderVertex.glsl"是文件所在地址,两部分用"/"相连,最后再在最前面加上冒号":" 

      1 #include "test01.h"
      2 
      3 #include <QFile>
      4 #include <QTextStream>
      5 
      6 #include <iostream>
      7 using namespace std;
      8 
      9 test01::test01(QWidget *parent): QOpenGLWidget(parent)
     10 {
     11     //设置OpenGL的版本信息
     12     QSurfaceFormat format;
     13     format.setRenderableType(QSurfaceFormat::OpenGL);
     14     format.setProfile(QSurfaceFormat::CoreProfile);
     15     format.setVersion(3,3);
     16 //    format.setVersion(2,0);
     17     setFormat(format);
     18 
     19   // *** *** ***
     20     FuiProgramID = 0;
     21 }
     22 
     23 test01::~test01()
     24 {}
     25 
     26 void test01::initializeGL()
     27 {
     28     // Initialize OpenGL Backend
     29     initializeOpenGLFunctions();
     30 
     31     // ZC: 刷背景色
     32     // Set global information
     33     glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
     34 
     35     // ZC: 在类test01的构造函数中,如果指明使用3.x版本的OpenGL的话,下面3句代码是必须的(至少Qt中是这样的,C++的使用glfw时 我暂时不知道 如何指定使用哪个版本的OpenGL)
     36     unsigned int VAO;
     37     glGenVertexArrays(1, &VAO);
     38     glBindVertexArray(VAO);
     39 
     40     // 创建着色器对象
     41     ShaderLoad_Z(":/test01/shaders/test01/ShaderVertex.glsl", ":/test01/shaders/test01/ShaderFragment.glsl");
     42 
     43   // *** *** ***
     44 
     45     FuiMVP = glGetUniformLocation(FuiProgramID, "MVP");
     46 
     47     // ZC: MVP设置:(3步骤)
     48     {
     49         // ZC: (1)MVP中的 P
     50         // ZC:  投射矩阵的设置在 resizeGL(...)中
     51         // ZC: (2)MVP中的 V
     52         Fview.lookAt(
     53                     QVector3D(0, 0, 10),// Camera is at (4,3,3), in World Space
     54                     QVector3D(0, 0, 0), // and looks at the origin
     55                     QVector3D(0, 1, 0)  // Head is up (set to 0,-1,0 to look upside-down)
     56                     );
     57         // ZC: (3)MVP中的 M
     58         Fmodel.setToIdentity();
     59 //        model.translate();
     60 //        model.rotate();
     61     }
     62 
     63   // *** *** ***
     64 
     65 //    static const GLfloat g_vertex_buffer_data[] = {
     66 //        -0.8f, -0.8f, -10.0f,
     67 //        0.8f, -0.8f, -10.0f,
     68 //        0.0f,  0.8f, -10.0f,
     69 //    };
     70     static const GLfloat g_vertex_buffer_data[] = {
     71         -1.0f, -1.0f, 0.0f,
     72         1.0f, -1.0f, 0.0f,
     73         0.0f,  1.0f, 0.0f,
     74     };
     75 
     76     glGenBuffers(1, &Fvbo);
     77     glBindBuffer(GL_ARRAY_BUFFER, Fvbo);
     78     glBufferData(GL_ARRAY_BUFFER, sizeof(g_vertex_buffer_data), g_vertex_buffer_data, GL_STATIC_DRAW);
     79 
     80   // ***
     81     glEnable(GL_DEPTH_TEST);
     82     glPointSize(10);
     83 //    cout << "test01::initializeGL() out" << endl;
     84 }
     85 
     86 void test01::resizeGL(int w, int h)
     87 {
     88     qDebug() << "MainWidget::resizeGL(...)";
     89 
     90     // Set OpenGL viewport to cover whole widget
     91     glViewport(0, 0, w, h);
     92 
     93     // ZC: 下面是 投射矩阵相关
     94     {
     95             // Calculate aspect ratio
     96             qreal aspect = qreal(w) / qreal(h ? h : 1);
     97 
     98             // Set near plane to 3.0, far plane to 7.0, field of view 45 degrees
     99         //    const qreal zNear = 3.0, zFar = 7.0, fov = 45.0;
    100             const qreal zNear = 0.1, zFar = 100.0, fov = 45.0;
    101 
    102             // Reset projection
    103             Fprojection.setToIdentity();
    104 
    105             // Set perspective projection
    106             Fprojection.perspective(fov, aspect, zNear, zFar);
    107     }
    108 
    109     Fmvp = Fprojection * Fview * Fmodel;
    110 }
    111 
    112 void test01::paintGL()
    113 {
    114 //    cout << "test01::paintGL()" << endl;
    115 
    116     //每次绘图前清理屏幕,否则会有残影
    117     //glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
    118     glClearColor(0.0f, 0.0f, 1.0f, 1.0f);
    119     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    120 
    121 // ***
    122     glUseProgram( FuiProgramID );
    123 
    124     glUniformMatrix4fv(FuiMVP, 1, GL_FALSE, Fmvp.data());
    125 
    126     // ZC: 这下面的参数"0"应该是对应顶点着色器的layout的location序号(我记得在哪里看到有函数可以通过变量名取到这个序号的)
    127     glEnableVertexAttribArray(0);
    128         glBindBuffer(GL_ARRAY_BUFFER, Fvbo);
    129         glVertexAttribPointer(
    130             0,                  // attribute. No particular reason for 0, but must match the layout in the shader.
    131             3,                  // size
    132             GL_FLOAT,           // type
    133             GL_FALSE,           // normalized?
    134             0,                  // stride
    135             (void*)0            // array buffer offset
    136             );
    137         glDrawArrays(GL_TRIANGLES, 0, 3); // 3 indices starting at 0 -> 1 triangle
    138     glDisableVertexAttribArray(0);
    139 
    140 
    141 }
    142 
    143 int test01::ShaderLoad_Z(const QString &_strFullFileName_ShaderVertex, const QString &_strFullFileName_ShaderFregment)
    144 {
    145     // ZC: 着色器文件-->着色器字符串
    146     QFile file1( _strFullFileName_ShaderVertex );
    147     file1.open(QIODevice::ReadOnly);
    148     QTextStream in1(&file1);
    149     // 将文本流读取到字符串中:
    150     string strShaderVertex = in1.readAll().toStdString();
    151     file1.close();
    152 
    153     QFile file2( _strFullFileName_ShaderFregment );
    154     file2.open(QIODevice::ReadOnly);
    155     QTextStream in2(&file2);
    156     // 将文本流读取到字符串中:
    157     string strShaderFregment = in2.readAll().toStdString();
    158     file2.close();
    159 
    160 //    cout << "strShaderVertex : " << strShaderVertex << endl;
    161 //    cout << "strShaderFregment : " << strShaderFregment << endl;
    162 
    163 // *** *** *** ***
    164 
    165     const char* pcShaderVertex  = strShaderVertex.c_str();
    166     const char* pcShaderFregment= strShaderFregment.c_str();
    167 
    168     // 编辑编译着色器
    169     unsigned int shaderVertex;// vertex, fragment;
    170     unsigned int shaderFregment;
    171 
    172     // 顶点着色器
    173     shaderVertex = glCreateShader(GL_VERTEX_SHADER);
    174     glShaderSource(shaderVertex, 1, &pcShaderVertex, NULL);
    175     glCompileShader(shaderVertex);
    176 
    177     // 检查着色器编译错误
    178     CheckCompileErrors(shaderVertex, "VERTEX");
    179 
    180     // ***
    181 
    182     // 片段着色器
    183     shaderFregment = glCreateShader(GL_FRAGMENT_SHADER);
    184     glShaderSource(shaderFregment, 1, &pcShaderFregment, NULL);
    185     glCompileShader(shaderFregment);
    186 
    187     // 检查着色器编译错误
    188     CheckCompileErrors(shaderFregment, "FRAGMENT");
    189 
    190     // ***
    191 
    192     // 链接着色器程序
    193     FuiProgramID = glCreateProgram();
    194     glAttachShader(FuiProgramID, shaderVertex);
    195     glAttachShader(FuiProgramID, shaderFregment);
    196     glLinkProgram(FuiProgramID);
    197 
    198     // 检查链接错误
    199     CheckCompileErrors(FuiProgramID, "PROGRAM");
    200 
    201     glDetachShader(FuiProgramID, shaderVertex);
    202     glDetachShader(FuiProgramID, shaderFregment);
    203 
    204     // 删除着色器
    205     glDeleteShader(shaderVertex);
    206     glDeleteShader(shaderFregment);
    207 
    208 
    209     return 0;//uiProgramID;
    210 }
    211 
    212 bool test01::CheckCompileErrors(unsigned int _shader, const string& _strType)
    213 {
    214     int success;
    215     char infoLog[512];
    216     if (_strType != "PROGRAM"){
    217         glGetShaderiv(_shader, GL_COMPILE_STATUS, &success);
    218         if (!success){
    219             glGetShaderInfoLog(_shader, 512, NULL, infoLog);
    220             cout << "ERROR::SHADER_COMPILATION_ERROR of type: " << _strType << "---" << infoLog  << endl;
    221             return false;
    222         }
    223     }else{
    224         glGetProgramiv(_shader, GL_LINK_STATUS, &success);
    225         if (!success){
    226             glGetProgramInfoLog(_shader, 512, NULL, infoLog);
    227             cout << "ERROR::PROGRAM_LINKING_ERROR of type: " << _strType << "---" << infoLog << endl;
    228             return false;
    229         }
    230     }
    231     return true;
    232 }

    4、

      

    5、上面代码中的 关于 "glEnableVertexAttribArray(0); glDisableVertexAttribArray(0);" 的我的注释,

     5.1、现在 找到貌似是 在 "C:QtQt5.3.2ExamplesQt-5.3openglcube"里面的,暂时不知道 是不是准确

      drawCubeGeometry() --> int vertexLocation = program->attributeLocation("a_position");  program->enableAttributeArray(vertexLocation);  --> 看源码是 调用的 glGetAttribLocation(...) 和 glEnableVertexAttribArray(...)

      ZC:这个 貌似是 适用于 版本"version 330 core"之前的GLSL(可能是 2.x的版本)。

      ZC:个人理解:版本"version 330 core"之前的GLSL 使用 "attribute vec4 a_position;"的方式 传递顶点数组数据;3.3之后的 使用类似 "layout(location = 0) in vec3 vertexPosition_modelspace;" 的方式 传递 顶点数组数据

    6、

    7、

    8、

    9、

    10、

  • 相关阅读:
    获取随机数
    性能测试工具
    Oracle 级联删除
    一些shell用法
    英文
    主题:【元宵赏灯】蛇年杭州元宵赏灯攻略(上城区、滨江区、下城区)
    CListCtrl 列表选中项非焦点时也是藍色
    ASCII码表
    杭州市公积金提取及相关知识
    ListBox设置水平滚动条
  • 原文地址:https://www.cnblogs.com/cppskill/p/10686899.html
Copyright © 2011-2022 走看看