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

 #include "mainwindow.h"
#include <QApplication> #include "test01.h" int main(int argc, char *argv[])
{
QApplication a(argc, argv);
// MainWindow w;
test01 w;
w.show(); return a.exec();
}

 (2)test01.h

 #ifndef __TEST_01_H__
#define __TEST_01_H__ #include <iostream>
#include <string>
using namespace std; //openGL窗口相关文件
#include <QOpenGLWidget>
#include <QOpenGLFunctions_3_3_Core> #include <QMatrix4x4> class test01 :public QOpenGLWidget, public QOpenGLFunctions_3_3_Core
{
Q_OBJECT
public:
explicit test01(QWidget *parent = );
~test01(); public:
virtual void initializeGL();
virtual void resizeGL(int w, int h);// ZC: 不处理窗口大小变化
virtual void paintGL(); private:
unsigned int FuiProgramID;
GLuint Fvbo; public:
GLuint FuiMVP;
QMatrix4x4 Fmodel;
QMatrix4x4 Fview;
QMatrix4x4 Fprojection;
QMatrix4x4 Fmvp; public:
int ShaderLoad_Z(
const QString &_strFullFileName_ShaderVertex,
const QString &_strFullFileName_ShaderFregment);
bool CheckCompileErrors(unsigned int _shader, const std::string &_strType);
}; #endif // __TEST_01_H__

 (3)test01.cpp

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

 #include "test01.h"

 #include <QFile>
#include <QTextStream> #include <iostream>
using namespace std; test01::test01(QWidget *parent): QOpenGLWidget(parent)
{
//设置OpenGL的版本信息
QSurfaceFormat format;
format.setRenderableType(QSurfaceFormat::OpenGL);
format.setProfile(QSurfaceFormat::CoreProfile);
format.setVersion(,);
// format.setVersion(2,0);
setFormat(format); // *** *** ***
FuiProgramID = ;
} test01::~test01()
{} void test01::initializeGL()
{
// Initialize OpenGL Backend
initializeOpenGLFunctions(); // ZC: 刷背景色
// Set global information
glClearColor(0.0f, 0.0f, 0.0f, 1.0f); // ZC: 在类test01的构造函数中,如果指明使用3.x版本的OpenGL的话,下面3句代码是必须的(至少Qt中是这样的,C++的使用glfw时 我暂时不知道 如何指定使用哪个版本的OpenGL)
unsigned int VAO;
glGenVertexArrays(, &VAO);
glBindVertexArray(VAO); // 创建着色器对象
ShaderLoad_Z(":/test01/shaders/test01/ShaderVertex.glsl", ":/test01/shaders/test01/ShaderFragment.glsl"); // *** *** *** FuiMVP = glGetUniformLocation(FuiProgramID, "MVP"); // ZC: MVP设置:(3步骤)
{
// ZC: (1)MVP中的 P
// ZC: 投射矩阵的设置在 resizeGL(...)中
// ZC: (2)MVP中的 V
Fview.lookAt(
QVector3D(, , ),// Camera is at (4,3,3), in World Space
QVector3D(, , ), // and looks at the origin
QVector3D(, , ) // Head is up (set to 0,-1,0 to look upside-down)
);
// ZC: (3)MVP中的 M
Fmodel.setToIdentity();
// model.translate();
// model.rotate();
} // *** *** *** // static const GLfloat g_vertex_buffer_data[] = {
// -0.8f, -0.8f, -10.0f,
// 0.8f, -0.8f, -10.0f,
// 0.0f, 0.8f, -10.0f,
// };
static const GLfloat g_vertex_buffer_data[] = {
-1.0f, -1.0f, 0.0f,
1.0f, -1.0f, 0.0f,
0.0f, 1.0f, 0.0f,
}; glGenBuffers(, &Fvbo);
glBindBuffer(GL_ARRAY_BUFFER, Fvbo);
glBufferData(GL_ARRAY_BUFFER, sizeof(g_vertex_buffer_data), g_vertex_buffer_data, GL_STATIC_DRAW); // ***
glEnable(GL_DEPTH_TEST);
glPointSize();
// cout << "test01::initializeGL() out" << endl;
} void test01::resizeGL(int w, int h)
{
qDebug() << "MainWidget::resizeGL(...)"; // Set OpenGL viewport to cover whole widget
glViewport(, , w, h); // ZC: 下面是 投射矩阵相关
{
// Calculate aspect ratio
qreal aspect = qreal(w) / qreal(h ? h : ); // Set near plane to 3.0, far plane to 7.0, field of view 45 degrees
// const qreal zNear = 3.0, zFar = 7.0, fov = 45.0;
const qreal zNear = 0.1, zFar = 100.0, fov = 45.0; // Reset projection
Fprojection.setToIdentity(); // Set perspective projection
Fprojection.perspective(fov, aspect, zNear, zFar);
} Fmvp = Fprojection * Fview * Fmodel;
} void test01::paintGL()
{
// cout << "test01::paintGL()" << endl; //每次绘图前清理屏幕,否则会有残影
//glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
glClearColor(0.0f, 0.0f, 1.0f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // ***
glUseProgram( FuiProgramID ); glUniformMatrix4fv(FuiMVP, , GL_FALSE, Fmvp.data()); // ZC: 这下面的参数"0"应该是对应顶点着色器的layout的location序号(我记得在哪里看到有函数可以通过变量名取到这个序号的)
glEnableVertexAttribArray();
glBindBuffer(GL_ARRAY_BUFFER, Fvbo);
glVertexAttribPointer(
, // attribute. No particular reason for 0, but must match the layout in the shader.
, // size
GL_FLOAT, // type
GL_FALSE, // normalized?
, // stride
(void*) // array buffer offset
);
glDrawArrays(GL_TRIANGLES, , ); // 3 indices starting at 0 -> 1 triangle
glDisableVertexAttribArray(); } int test01::ShaderLoad_Z(const QString &_strFullFileName_ShaderVertex, const QString &_strFullFileName_ShaderFregment)
{
// ZC: 着色器文件-->着色器字符串
QFile file1( _strFullFileName_ShaderVertex );
file1.open(QIODevice::ReadOnly);
QTextStream in1(&file1);
// 将文本流读取到字符串中:
string strShaderVertex = in1.readAll().toStdString();
file1.close(); QFile file2( _strFullFileName_ShaderFregment );
file2.open(QIODevice::ReadOnly);
QTextStream in2(&file2);
// 将文本流读取到字符串中:
string strShaderFregment = in2.readAll().toStdString();
file2.close(); // cout << "strShaderVertex : " << strShaderVertex << endl;
// cout << "strShaderFregment : " << strShaderFregment << endl; // *** *** *** *** const char* pcShaderVertex = strShaderVertex.c_str();
const char* pcShaderFregment= strShaderFregment.c_str(); // 编辑编译着色器
unsigned int shaderVertex;// vertex, fragment;
unsigned int shaderFregment; // 顶点着色器
shaderVertex = glCreateShader(GL_VERTEX_SHADER);
glShaderSource(shaderVertex, , &pcShaderVertex, NULL);
glCompileShader(shaderVertex); // 检查着色器编译错误
CheckCompileErrors(shaderVertex, "VERTEX"); // *** // 片段着色器
shaderFregment = glCreateShader(GL_FRAGMENT_SHADER);
glShaderSource(shaderFregment, , &pcShaderFregment, NULL);
glCompileShader(shaderFregment); // 检查着色器编译错误
CheckCompileErrors(shaderFregment, "FRAGMENT"); // *** // 链接着色器程序
FuiProgramID = glCreateProgram();
glAttachShader(FuiProgramID, shaderVertex);
glAttachShader(FuiProgramID, shaderFregment);
glLinkProgram(FuiProgramID); // 检查链接错误
CheckCompileErrors(FuiProgramID, "PROGRAM"); glDetachShader(FuiProgramID, shaderVertex);
glDetachShader(FuiProgramID, shaderFregment); // 删除着色器
glDeleteShader(shaderVertex);
glDeleteShader(shaderFregment); return ;//uiProgramID;
} bool test01::CheckCompileErrors(unsigned int _shader, const string& _strType)
{
int success;
char infoLog[];
if (_strType != "PROGRAM"){
glGetShaderiv(_shader, GL_COMPILE_STATUS, &success);
if (!success){
glGetShaderInfoLog(_shader, , NULL, infoLog);
cout << "ERROR::SHADER_COMPILATION_ERROR of type: " << _strType << "---" << infoLog << endl;
return false;
}
}else{
glGetProgramiv(_shader, GL_LINK_STATUS, &success);
if (!success){
glGetProgramInfoLog(_shader, , NULL, infoLog);
cout << "ERROR::PROGRAM_LINKING_ERROR of type: " << _strType << "---" << infoLog << endl;
return false;
}
}
return true;
}

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、

Qt551.OpenGL.ZC简单例子的更多相关文章

  1. Hibernate4.2.4入门(一)——环境搭建和简单例子

    一.前言 发下牢骚,这段时间要做项目,又要学框架,搞得都没时间写笔记,但是觉得这知识学过还是要记录下.进入主题了 1.1.Hibernate简介 什么是Hibernate?Hibernate有什么用? ...

  2. AgileEAS.NET SOA 中间件平台.Net Socket通信框架-简单例子-实现简单的服务端客户端消息应答

    一.AgileEAS.NET SOA中间件Socket/Tcp框架介绍 在文章AgileEAS.NET SOA 中间件平台Socket/Tcp通信框架介绍一文之中我们对AgileEAS.NET SOA ...

  3. spring mvc(注解)上传文件的简单例子

    spring mvc(注解)上传文件的简单例子,这有几个需要注意的地方1.form的enctype=”multipart/form-data” 这个是上传文件必须的2.applicationConte ...

  4. ko 简单例子

    Knockout是在下面三个核心功能是建立起来的: 监控属性(Observables)和依赖跟踪(Dependency tracking) 声明式绑定(Declarative bindings) 模板 ...

  5. mysql定时任务简单例子

    mysql定时任务简单例子 ? 1 2 3 4 5 6 7 8 9     如果要每30秒执行以下语句:   [sql] update userinfo set endtime = now() WHE ...

  6. java socket编程开发简单例子 与 nio非阻塞通道

    基本socket编程 1.以下只是简单例子,没有用多线程处理,只能一发一收(由于scan.nextLine()线程会进入等待状态),使用时可以根据具体项目功能进行优化处理 2.以下代码使用了1.8新特 ...

  7. 一个简单例子:贫血模型or领域模型

    转:一个简单例子:贫血模型or领域模型 贫血模型 我们首先用贫血模型来实现.所谓贫血模型就是模型对象之间存在完整的关联(可能存在多余的关联),但是对象除了get和set方外外几乎就没有其它的方法,整个 ...

  8. [转] 3个学习Socket编程的简单例子:TCP Server/Client, Select

    以前都是采用ACE的编写网络应用,最近由于工作需要,需要直接只用socket接口编写CS的代码,重新学习这方面的知识,给出自己所用到的3个简单例子,都是拷贝别人的程序.如果你能完全理解这3个例子,估计 ...

  9. jsonp的简单例子

    jsonp的简单例子 index.html <!DOCTYPE html> <html> <head> <meta charset="UTF-8&q ...

随机推荐

  1. JS全选反选功能

    总选框:<input type="checkbox" class="all" name="all"> 子选框: <inpu ...

  2. selenium处理元素定位到了点击无效问题

    在WEB自动化测试过程中,经常会遇到这样的问题: 元素定位到了,但是点击无效?有人可能会问了,怎么判断元素定位到了,这个问题很好判断 1.给元素加高亮显示 self.driver.execute_sc ...

  3. JAVA常用加密解密算法Encryption and decryption

    加密,是以某种特殊的算法改变原有的信息数据,使得未授权的用户即使获得了已加密的信息,但因不知解密的方法,仍然无法了解信息的内容.大体上分为双向加密和单向加密,而双向加密又分为对称加密和非对称加密(有些 ...

  4. 虚拟机——虚拟机VMware Workstation 的.vmdk格式与VirtualBox 的.vdi格式相互转换

    啦啦啦~~~ 由于现在Vmware Workstation的越来越普及,让很多小伙伴不知道怎么把以前用的VirtualBox虚拟机vdi格式转换成vmdk格式,下面我们就来转换一下吧... 第一步:找 ...

  5. 福州大学软件工程1916|W班 第2次作业成绩排名

    作业链接: 结对第一次-原型设计(文献摘要热词统计) 评分准则: 本次作业评分分为两部分,一部分是博客分数(满分25分),另一部分是工程能力分数(满分30分). 博客分数评分标准: 1.在随笔开头请加 ...

  6. python:sys.exit() os._exit() exit() quit()

    1>sys.exit() >>> import sys>>> help(sys.exit)Help on built-in function exit in ...

  7. JavaFX-Stage

    1.Stage类继承自Window类,继承了Window类的show()方法,Stage的close()方法实际上是调用了继承自Window类的hide()方法.另外还有Window的setOpaci ...

  8. centos7安装git

    1.安装git依赖包 yum install curl-devel expat-devel gettext-devel openssl-devel zlib-devel gcc perl-ExtUti ...

  9. Linux常用命令大全(非常全!!!)(转)

    最近都在和Linux打交道,感觉还不错.我觉得Linux相比windows比较麻烦的就是很多东西都要用命令来控制,当然,这也是很多人喜欢linux的原因,比较短小但却功能强大.我将我了解到的命令列举一 ...

  10. 向 Nginx 主进程发送 USR1 信号

    [1]Nginx重新打开日志文件 向 Nginx 主进程发送 USR1 信号.USR1 信号是重新打开日志文件: 方式一: kill -USR1 $(cat /usr/local/lib/ubcsrv ...