Qt551.OpenGL.ZC简单例子

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

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

  (1)C:\Qt\Qt5.3.2\Examples\Qt-5.3\opengl            (E:\Project_Qt532\Official_Examples)

  (2)C:\Qt\Qt5.3.2\Examples\Qt-5.3\opengl\cube

  (3)C:\Qt\Qt5.5.1\Examples\Qt-5.5\opengl            (E:\Project_Qt551\Official_Examples)

  (4)C:\Qt\Qt5.5.1\Examples\Qt-5.5\opengl\hellogl2

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:\Qt\Qt5.3.2\Examples\Qt-5.3\opengl\cube"里面的,暂时不知道 是不是准确

  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、

 

posted @ 2019-04-10 23:14  CppSkill  阅读(783)  评论(0编辑  收藏  举报