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中的用户裁剪和前剪切,记录下gl_ClipDistancegl_CullDiatance的用法。 gl_ClipDiatance:输出的裁剪距离将和图元进行线性插值,插值距离小于0,则图元部分将剪切掉。 gl_CullDiatance:如果图元的所有顶点对于平面都返回了负数的裁减距离值,那么图元需要被裁减。 用OpenGL编程指南中的代码修改测试下: #include <... glDrawElementsBaseVertex — 从数组数据中按元素偏移渲染图元 void glDrawElementsBaseVertex( GLenum mode, GLsizei count, GLenum type, void *indices, GLint basevertex); 指定要渲染的原语类型。接受符号常量GL_POINTS,GL_LINE_... http://github.prideout.net/clip-planes/ http://www.opengl.org/wiki/Built-in_Variable_(GLSL) http://www.opengl.org/wiki/GLSL_Predefined_Variables_By_Version 转载于:https://www.cnblogs.com/lilei911... OpenGL Draw函数族以及渲染优化前言1.最基本的Draw函数1.1 glDrawArrays1.2 glDrawElements2.基本Draw函数的变种2.1 *Instanced2.2 *BaseVertex2.3 *BaseInstance2.4 *BaseInstanceBaseVertex2.5 *Indirect2.6 小结3.多重Draw函数4.无绑定技术(bindless)... 之前那个OpenGL入门教程十二课看完了,现在开始看OpenGL蓝宝书,我要调整学习计划了,现在研二第一期,马上要结束了,从5月接触鱼眼到现在有将近8个月了,简单过了下鱼眼图像校正、图像拼接融合,现在在看OpenGL也就是开始全景漫游的学习了,而我还没有做相机标定,然后前两块学得也不算精通,所以我准备加快OpenGL的学习步伐,只求会用,不会去深究搞懂,因为我学它只是为了全景漫游,也就是一个显示的 距离剔除类型:按Actor距离进行剔除,距离剔除体积。 按Actor距离进行剔除: 关卡中的每个Actor都有自己的绘制距离设置,可以使用“Detail面板”->“LOD”->“Min Draw Distance”和“Desired Max Draw Distance”进行设置。 文章目录openGL系列文章目录前言一、细分曲面着色器1.细分曲面Patch二、使用步骤1.引入库2.读入数据总结 术语Tessellation(镶嵌)是指一大类设计活动,通常是指在平坦的表面上,用各种几何 形状的瓷砖相邻排列以形成图案。它的目的可以是艺术性的或实用性的,很多例子可以追 溯到几千年前[TS16]。 在3D 图形学中,Tessellation 指的是有点不同的东西(曲面细分),但显然是由它的经典 对应物(镶嵌)启发而成的。在这里,曲面细分指的是生成并且操控大量三 GLFrustum::SetOrthographic(GLfloat xMin, GLfloat xMax, GLfloat yMin, GLfloat yMax, GLfloat zMin, GLfloat zMax); GLFrustum::SetPerspective(float fFov, float fAspect, float fNear, float fFar); 对应UnityShader的顶点着色器输入结构体的数据,例如 VERTEX COLOR...