【OpenGL蓝宝书】Chapter 7. Vertex Processing and Drawing Commands

编程入门 行业动态 更新时间:2024-10-13 14:22:09

【OpenGL蓝<a href=https://www.elefans.com/category/jswz/34/1688550.html style=宝书】Chapter 7. Vertex Processing and Drawing Commands"/>

【OpenGL蓝宝书】Chapter 7. Vertex Processing and Drawing Commands

一、VAO再谈

OpenGL 3.x时代,一般使用

glGenVertexArrays(1, &vao);
glBindVertexAttay(vao);
glVertexAttribPointer(attribIndex, ...);
glEnableVertexAttribArray(attribIndex)glBindBuffer(..., buffer);

所有data都放在一个buffer。

 

OpenGL 4.3引入了另一种写法,其好处是可将不同的data通过不同buffer灌进去。

glGenVertexArrays(1, &vao);
glBindVertexArray(vao);glVertexAttribFormat(attribIndex, ...);
glBindVertexBuffer(bufferBindingpoint, buffer, ...);
glVertexAttribBinding(attribIndex, bufferBindingpoint);
glEnableVertexAttribArray(attribIndex);

以上两种都需要使用glGenVertexArrays()之后,立即使用glBindVertexArray(),还记得之前说过的吗?Gen()只是生成名字,需要Bind之后才会生成object。

 

OpenGL 4.5引入了Create(),它在造名字的同时就生成了object。这就不需要先Bind()。相对应的,VAO这里也引入了直接对名字进行设置,就像Namedbuffer的设置一样。

glCreateVertexArrays(1, &vao);glVertexArrayAttribFormat(vao, attribIndex, ...);
glVertexArrayVertexBuffer(vao, bufferBindingpoint, buffer, ...);
glVertexArrayAttribBinding(vao, attribIndex, bufferBindingpoint);
glEnableVertexArrayAttrib(vao, attribIndex);glBindVertexArray(vao);    // bind可放最后

二、Drawing Commands

1 indexed drawing command

1.1 glDrawElementsBaseVertex():将EBO中的index取出之后,加上basevertex,再用加完了的index去vertex buffer中取点。

glDrawElements();glDrawElementsBaseVertex(..., basevertex);

 

1.2 GL_TRIANGLE_STRIP, GL_TRIANGLE_FAN, GL_LINE_STRIP, GL_LINE_LOOP中间断点,重新绘制。(必须使用glDrawElements(),否则glPrimitiveRestartIndex会被无视)。

glEnable(GL_PRIMITIVE_RESTART);
glPrimitiveRestartIndex(index);

2 Instancing

有些数据我希望每一个instance更新一次,而不是每一个顶点更新一次,这时候就可以使用:

glVertexAttribDivisor(index, divisor);

设置vao的index号attribute每divisor次更新一次。

2.1 若每种attribute想各自跳过前n个,则使用

glDraw...InstancedBaseInstance(..., baseinstance)

对于DrawElement,还可以

glDrawElementsInstancedBaseVertex()
glDrawElementsInstancedBaseVertexBaseInstance()

BaseVertex之功能如1.1所述。

3. Indirect

与instancing类似,只是把除了mode之外的参数整合到一个struct中。

glDrawArraysIndirect(mode, *indirect)
glDrawElementsIndirect(mode, type, *indirect)glMultiDrawArraysIndirect()
glMultiDrawElementsIndirect()

drawArrays和drawElements的indirect结构体去reference查。

引入Indirect draw的目的在于multi draw。可以将不同的draw command 存到一个indirect struct 列表,将该列表存到GL_DRAW_INDIRECT_BUFFER。并且glMultiDrawArraysIndirect(),glMultiDrawElementsIndirect()两个函数调用时的indirect置nullptr。它们就会去GL_DRAW_INDIRECT_BUFFER取command。

三、Transformed Vertices

使用glTransformFeedbackVaryings()指定哪些shader的输出需要存回GL_TRANSFORM_FEEDBACK_BUFFER。

需要在linkProgram()前使用。

P.S. 一共有4个buffer,它们有自己的binding point,分别是

GL_TRANSFORM_FEEDBACK_BUFFER、GL_UNIFORM_BUFFER、GL_ATOMIC_COUNTER_BUFFER、GL_SHADER_STORAGE_BUFFER。

四、用户自定义裁剪

1. gl_ClipDistance[]

在vertex shader中,有个内置变量float数组gl_clipdistance[]。它是per_vertex的。对于一个vertex来说,gl_clipdistance[]数组中,只要有一个为负数,则该点被clip。

为了启用gl_clipdistance[],需要在cpp中显式启用:

glEnable(GL_CLIP_DISTANCEi);

这样就激活了gl_clipdistance[]数组的第i个数据。

顾名思义:clipdistance就是该vertex到裁剪面的距离。距离为正,则没有超过裁剪面;距离为负,则超过裁剪面。

注意:对于一个primitive来说(以三角形举例),一个点被clip,另外两个没被clip,则这个primitive会被部分clip。

2. gl_CullDistance[]

与gl_clipdistance[]一样,只不过只要有一个点被clip,则整个primitive被cull。

不需要显示启用任何东西。

gl_culldistance[]需要glsl4.5以上。

更多推荐

【OpenGL蓝宝书】Chapter 7. Vertex Processing and Drawing Commands

本文发布于:2024-02-12 16:27:29,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1688549.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:宝书   Chapter   OpenGL   Drawing   Commands

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!