GLSL绘制流程的粗浅理解

这几天在一个open.gl的网站学习了一下openGL,感觉只是粗浅的理解了一下。

本人是小菜所以有什么不对的地方请大家见谅。

新一代OpenGL开始用GLSL写程序了。用GLSL的好处就是一些流程可以用shader来完成,就不用再程序中再写代码了,也便于了管理。

先说一下这几天我学的一些东西吧。

1.OpenGL绘制流程

  a.首先有一个VAO,所谓VAO就是在显存中存储了我们所要绘制的所有信息的一块区域。例如顶点坐标,顶点颜色等

  b.然后在这个VAO上去声明一系列的VBO,VBO就是一块显存的区域,存储顶点信息,顶点的信息可以都放在这个VBO中,也可以分别放在不同的VBO中。(绘制时只用激活一        下我们绘制的是哪个VAO,用这个VAO里面的信息就可以了)

  c.指明好VAO然后去绘制就可以了。

2.纹理

  1)如果要使用纹理可以在1.中的vao上去声明一个纹理缓存,glGenTextures()用来声明一个,然后往这个纹理缓存中去装入我们要指定的纹理的内容,可以用glTexImage2D(),接        着再指明一下纹理的一些属性就可以了。或者还可以建立一下mipMap。

   2)多重纹理

      openGL中有多个GL_TEXTUREi,即纹理单元,(貌似最低有48个?),在激活纹理(glBindTexture())之前,我们可以指明这个纹理缓存绑定到哪个纹理单元中 (glActiveTexture(GL_TEXTUREi)),如果有多个纹理缓存就可以分别绑定到不同的纹理单元中。

      绑定好纹理单元之后,我们要在GLSL中使用时,就要用到sampler2D类型的变量,这个变量默认值是0,如果这个值是k,表示他要采样的第k个纹理单元。比如有个

uniform sampler2D m,那么在GLSL中使用 texture(m, textureCoord)来获得纹理单元m在坐标textureCoord上的颜色值[这个值的获取也跟1)中我们所指明的纹理属性有 关]。

       在GLSL中用mix(samper2D m1, samper2D m2, k)可以获得一个混合两个纹理之后的颜色,计算结果是(1-k) * m1 + k * m2

3.深度缓存与模板缓存

    模板缓存理解了好久,其实大致意思就是在一个2D上指明一块区域的区域码,然后我们可以利用一些比较规则,可以在这个区域绘制或者不绘制。主要的函数时glStencilFcn(),glStencilOp。还有一个glDepthMask(bool) ,为true时表示可以向深度缓存中写,为false时表示不可以想深度缓存中写。(注意要先开始深度测试)。

    模板缓存是在深度缓存之前进行的。

     可以利用模板缓存实现镜面反射的效果,以及透过玻璃看汽车外面风景的效果。

4.frame buffer object

    很重要的一个概念,可以实现离屏渲染,例如实现汽车后视镜,摄像头等等效果。

    fbo也是显存中的一块区域,保存了深度信息,模板信息,颜色信息等等,一个fbo的结构由多个GL_COLOR_ATTATCHMENTi以及一些render buffer组成,一个GL_COLOR_ATTATCHMENTi对应了一个纹理缓存。一个render buffer 对应了深度与模板的信息。

   一个framebuffer使用的流程。

    //render 3D to my framebuffer object
glGenFramebuffers(1, &myFbo);
glBindFramebuffer(GL_FRAMEBUFFER, myFbo);


//generate my fbo's texture buffer
glGenTextures(1, &myFboColorbuffer);
glBindTexture(GL_TEXTURE_2D, myFboColorbuffer);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, winWidth, winHeight, 0, GL_RGB, GL_UNSIGNED_BYTE, NULL);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);


//bind empty texture image to my fbo
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,GL_TEXTURE_2D,myFboColorbuffer,0);

//generate my fbo's depth and stecil render buffer
glGenRenderbuffers(1, &myFborenderbuffer_dep_stenci);
glBindRenderbuffer(GL_RENDERBUFFER, myFborenderbuffer_dep_stenci);


//the render buffer's storage
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, winWidth, winHeight);


//bind empty render buffer to my fbo
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER, myFborenderbuffer_dep_stenci);


//back to default fbo

glBindFramebuffer(GL_FRAMEBUFFER, 0);


5.geometry shader

    可以由vertex shader中传过来的数据生成新的图元。

    需要注意的是layout(type) in, 由type指明了vertex shader一次向geometry shader 传入几个顶点。

    比如在vertex shader 中有一个变量out float k;那么在geometry shader 中就要声明一个in float[] k,而对应的上述type是什么,这个k数组的大小就是多少。

    还有一个结构体,

  1. Vertex  
  2. {  
  3.     vec4  gl_Position;  
  4.     float gl_PointSize;  
  5.     float gl_ClipDistance[];  
  6. }; gl_in[]

       这个gl_in[]数组对应的是vertex中的gl_Position,同理,由上述type定义了这个gl_in[]数组里面有几个顶点的位置信息。


6. transform feedback

    可以实现粒子系统。

    大意就是说可以对vertex shader 或者有geometry shader的,可以获得他们那里的out 类型的变量的数据。

    流程:在glLinkProgram()之前先指明要feedback的变量的个数以及他们在shader中的名字。然后声明一个或多个vbo并指明这个vbo是用来储存feedback数据的。这样就可以开始glBeginTransformFeedback()。

    还有一个2-pass的概念可以参考http://www.zwqxin.com/archives/opengl/talk-about-transform-feedback.html


     记录下自己的点点滴滴...........

你可能感兴趣的:(GLSL绘制流程的粗浅理解)