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、