Qt5+OpenGL学习笔记(新手向):一(2)、OpenGL中Buffer的初步认识



  • 前面的话。。。
    这次简单介绍了下我学习时觉得比较关键的基本知识,是基于OpenGL原生函数的讲解。Qt有一套对OpenGL的封装,就是QOpenGL系列。我打算在写完shader的笔记之后将原生写法和使用Qt所封装的类的写法都介绍下。还有就是红宝书是上来就开始讲shader的概念的,但是我觉得这样不太好理解(是不是我太笨了TvT)。。。

    Buffer Object(缓存对象)
    OpenGL几乎所有的事情都用到了缓存中的数据。
    在上一个笔记中,我渲染了一个简单的三角形。基本步骤
    先给出了顶点数据:
    GLfloat verts[]={
    +0.0f, +1.0f,
    +1.0f, -1.0f,
    -1.0f, -1.0f,
    };
    每两个浮点数一组表示一个顶点的X,Y坐标,这里没有给出Z的坐标(应该是默认为0.0了)。关于Z的坐标在写Shader(着色器)的笔记的时候会详细解释。
    有了顶点数据之后,要将顶点数据放入OpenGL的缓存当中。
    首先,我们要创建一块OpenGL中的缓存。
    void glGenBuffers(GLsizei n,GLuint* buffers);
    返回n个当前未使用的缓存对象名称,并保存到buffers数组中。
    对应的代码:生成了一个缓存对象(BufferObject)的名称,给它赋值给myBufferID。
    GLuint myBufferID;
    glGenBuffers(1,&myBufferID);
    之后,要把缓存对象绑定到指定的的缓存结合点。
    void glBindBuffer(GLenum target,GLuint buffer);
    将名为buffer的缓存对象绑定到target所指定的缓存结合点。
    对应的代码:(将myBufferID绑定到GL_ARRAY_BUFFER上)
    glBindBuffer(GL_ARRAY_BUFFER,myBufferID);
    我们已经生成了一个缓存对象并绑定到了指定的缓存结合点。之后我们要向缓存中输入数据。
    glBufferData(GLenum target,GLsizeiptr size,const GLvoid* data,GLenum usage);
    为绑定到target的缓存对象分配size大小(单位为字节)的存储空间。如果参数data不是NULL,那么将使用data所在的内存区域的内容来初始化整个空间。Usage允许应用程序向OpenGL端发出一个提示,指示缓存中的数据可能具备一定的特殊用途。
    对应的代码:分配相应的缓存空间
    glBufferData(GL_ARRAY_BUFFER,sizeof(verts),verts,GL_STATIC_DRAW);
    至此呢,OpenGL已经在缓存中存储了我们所需要的数据。但是OpenGL不知道这些数据的含义,需要我们为它指明。
    void glEnableVertexAttribArray(GLuint index);
    void glDisableVertexAttribArray(GLuint index);
    设置是否启用与index索引相关联的顶点数组。Index必须是一个介于0到GL_MAX_VERTEX_ATTRIBS-1之间的值。

    void glVertexAttribPointer(GLuint index,GLuint size,GLenum type,GLboolean normalized,GLsizei stride,const GLvoid *pointer);
    设置index(着色器中的属性位置)位置对应的数据值。pointer表示缓存对象中,从开始位置开始计算的数组数据的偏移值(假设起始地址为0),使用基本的系统单位(byte)。size表示每个顶点需要更新的分量数目。type指定了数组中每个元素的数据类型。Normalized设置顶点数据在存储前是否需要归一化。stride是数组中每两个元素的大小偏移值(byte)。如果stride为0,那么数据应该紧密的封装在一起。
    对应的代码:启用索引为0的顶点数组。从头开始读取,每个元素含两个浮点型数据,不采取归一化,每个数据紧密相连。
    glEnableVertexAttribArray(0);
    glVertexAttribPointer(0,2,GL_FLOAT,GL_FALSE,0,0);
    最后在paintGL()中使用绘制指令
    void glDrawArrays(GLenum mode,GLint first,GLsizei count);
    使用数组元素建立连续的几何图元序列,每个启用的数组中的起始位置为first,结束位置为first+count-1。mode为构建图元的类型。
    对应的代码:绘制三角形,其实位置为0,结束位置为2。
    glDrawArrays(GL_TRIANGLES,0,3);

    后面的话:感觉这次写的乱了一点。主要是初学自己也没理解透,可能有表述不清之处Orz。
    附带两个将这方面的传送门:
    讲OpenGL中Buffer的:
    http://www.bubuko.com/infodetail-700038.html
    讲VAO,VBO的:
    http://blog.csdn.net/zhuyingqingfen/article/details/19238651

    Ps:初学时的坐标系简介
    在学习视口变换等内容之前,我们渲染的图形对应的坐标系如下。以绘图窗口的中心为原点,向左为X轴正向,最大值为+1.0。向右为X轴负向,最小值为-1.0。向上为Y轴正向,最大值为+1.0。向下为Y轴负向,最小值为-1.0。垂直XOY平面指向屏幕外为Z轴正向,最大值为+1.0。垂直XOY平面指向屏幕内为Z轴负向,最小值为-1.0。(画了个示意图如下,Z轴没有画出)
    0_1454503571179_upload-3e6509ec-ec5f-44ba-9810-2e02881753df



  • 弱弱问一句,博客发了之后不能修改么。。。



  • @MrXiaoXiao 可以进行修改。只要左边有齿轮的按钮,可以设置。



  • 十分期待后续啊~不能太监啊~



  • 关注一波,opengl大法好



  • @MrXiaoXiao 下文(面)没有了?



  • @qyvlik 我也在期待他的下文,不过这个ID好像好久没来了~


  • 网站研运

    这个博客讲的是OpenGL的概念。
    Qt对此进行了封装。
    比如说顶点以及索引缓存对象为:QOpenGLBuffer,纹理对象为:QOpenGLTexture,FBO对象为QOpenGLFrameBufferObject
    最后推荐看看我的github。里面有一些简单的OpenGL和Qt相关的小例子,大家可以参考一下。

    请点击我



  • 安利一下这个:http://learnopengl.com/, 中文版 https://learnopengl-cn.readthedocs.io

    最近在看这个和彩阳的博客学习Qt3D的框架,捣鼓了一个大炮打蚊子的东西 https://github.com/MidoriYakumo/learnopengl-qt3d


 

最近的回复

  • Qt for Python终于发布了!
    以前的我,可能接触了一点Python,但是都没有坚持下来,现在Python水平还很弱呢。不过我基本语法还是了解一点的。所以我打算借着Qt for Python的东风,来尝试一下Python的开发。

    1、去Python 官网安装Python。地址是:

    https://www.python.org/downloads/mac-osx
    0_1529422911935_1.png
    我下载的版本是3.6.5

    2、双击pkg安装包进行安装,按照提示安装即可,不必做什么设置。
    0_1529422932496_2.png
    3、安装pip。pip是一个类似npm的快速安装器,非常适合python安装。由于Mac的安全策略,这个时候要输入的命令以sudo开始:

    sudo python get-pip.py

    4、需要安装Qt官网提供的python安装包。Qt的Python安装包并没有放入Pypi的地址,因为Qt库本身就偏大。
    但是依然能够通过pip安装。只是安装的命令稍微长:

    sudo pip install --index-url=https://download.qt.io/official_releases/QtForPython/ pyside2

    然后输出的结果是:
    daxiongtekiMacBook-Air:~ jiangcaiyang$ sudo pip install --index-url=https://download.qt.io/official_releases/QtForPython/ pyside2
    Password:
    The directory '/Users/jiangcaiyang/Library/Caches/pip/http' or its parent directory is not owned by the current user and the cache has been disabled. Please check the permissions and owner of that directory. If executing pip with sudo, you may want sudo's -H flag.
    The directory '/Users/jiangcaiyang/Library/Caches/pip' or its parent directory is not owned by the current user and caching wheels has been disabled. check the permissions and owner of that directory. If executing pip with sudo, you may want sudo's -H flag.
    Looking in indexes: https://download.qt.io/official_releases/QtForPython/
    Collecting pyside2
    Downloading https://download.qt.io/official_releases/QtForPython/pyside2/PySide2-5.11.0-5.11.0-cp27-cp27m-macosx_10_11_intel.whl (125.7MB)
    100% |████████████████████████████████| 125.7MB 1.0MB/s
    matplotlib 1.3.1 requires nose, which is not installed.
    matplotlib 1.3.1 requires tornado, which is not installed.
    Installing collected packages: pyside2
    Successfully installed pyside2-5.11.0
    安装成功。

    5、安装成功了,开始写一个测试的程序吧!
    最简单的,当然是Hello Qt for Python啦。很简单,使用Qt Creator,很方便地可以创建这样的Python脚本,使用方法也和C++版本的Qt应用相同:

    #!/usr/bin/env python # -*- coding: utf-8 -*- from PySide2.QtWidgets import QApplication, QLabel app = QApplication( [ ] ) label = QLabel( "您好 Qt for Python!" ) label.show( ) app.exec_( )

    0_1529422962008_4.jpg
    其中第一行表示用/usr/bin/python 来解析,大家可以在命令提示符输入“which python”来看结果:
    第二行则是在Python 3.x下不用写了,设定的是utf-8编码格式。大家最好也是使用这样的格式,因为这样遇到编码的坑最少。
    因为Python没有main()函数的说法,所以直接从上往下运行就可以了。Python是弱语言,所以不用声明类型,这里还有一点不一样,就是
    app.exec_( ),和C++版本不同的是,添加上了一个下划线。可能和Python内置的函数冲突了?我还需要再调查一下。

    接下来我就仿照例子写了一个更加复杂的Python程序,大致是这样的:

    #!/usr/bin/env python # -*- coding: utf-8 -*- import sys import random from PySide2.QtCore import Qt from PySide2.QtWidgets import (QApplication, QWidget, QPushButton, QLabel, QVBoxLayout ) class MyWidget( QWidget ): def __init__( self ): QWidget.__init__( self ) self.hello = [ "Hallo welt!", "Ciao mondo", "Hei maailma", "Hola mundo", "Hei verden!" ] self.button = QPushButton( "Click me!" ) self.text = QLabel( "Hello World" ) self.text.setAlignment( Qt.AlignCenter ) self.layout = QVBoxLayout( ) self.layout.addWidget( self.text ) self.layout.addWidget( self.button ) self.setLayout( self.layout ) self.button.clicked.connect( self.magic ) def magic( self ): self.text.setText( random.choice( self.hello ) ) if __name__ == "__main__": app = QApplication( sys.argv ) widget = MyWidget( ) widget.resize( 640, 480 ) widget.show( ) sys.exit( app.exec_( ) )

    程序运行起来还行吧!
    0_1529422988117_5.png

    阅读更多
  • @jiangcaiyang 如果需要自动化测试,也用的上

    阅读更多
  • @青山白云 这个可能有点用,但是可能更多局限于爬虫领域吧。

    阅读更多
  • https://blog.csdn.net/huilan_same/article/details/51896672

    python制作爬虫时候使用selenium进行自动化
    使用chromedriver时候需要对应版本

    chromedriver版本 支持的Chrome版本 v2.39 v66-68 v2.38 v65-67 v2.37 v64-66 v2.36 v63-65 v2.35 v62-64 v2.34 v61-63 v2.33 v60-62 v2.32 v59-61 v2.31 v58-60 v2.30 v58-60 v2.29 v56-58 v2.28 v55-57 v2.27 v54-56 v2.26 v53-55 v2.25 v53-55 v2.24 v52-54 v2.23 v51-53 v2.22 v49-52 v2.21 v46-50 v2.20 v43-48 v2.19 v43-47 v2.18 v43-46 v2.17 v42-43 v2.13 v42-45 v2.15 v40-43 v2.14 v39-42 v2.13 v38-41 v2.12 v36-40 v2.11 v36-40 v2.10 v33-36 v2.9 v31-34 v2.8 v30-33 v2.7 v30-33 v2.6 v29-32 v2.5 v29-32 v2.4 v29-32 查谷歌浏览器版本

    地址栏输入chrome://settings/help

    0_1528459921154_16bbaf4d-0e8e-42cd-9e52-f8fc43932871-image.png

    所有chromedriver均可在下面链接中下载到:

    http://chromedriver.storage.googleapis.com/index.html

    阅读更多

关注我们

微博
QQ群











召唤伊斯特瓦尔