mak*_*mak 3 opengl opengl-es glsl
打完电话后glVertexAttribPointer(GLuint index, ...)
顶点属性默认情况下禁用的文档说
默认情况下,禁用所有客户端功能,包括所有通用顶点属性数组.
为什么我们必须使用额外功能启用它?有人可以命名一个案例,这有用吗?
在研究时我学到了以下内容:
通过layout(location = x)
在GLSL中使用限定符,glBindAttribLocation
我们可以显式设置位置,而不是让OpenGL生成它.但这不是我的问题.
glEnableVertexAttribArray
不能用于绘制具有多个着色器的一个VAO.当使用程序对象查询属性位置时,可以假设位置是着色器特定的; 然后我们可以预料,我们可以在运行正确的着色器之前启用正确的属性位置.但是,我注意到,在测试时,一个位置值可以在不同的着色器中出现多次; 此外,输出看起来不对.如果您希望查看代码,请询问.
属性位置存储在VAO中.
记住GL已经从一个已有20多年历史的底层API发展而来,为了向后兼容而保留了大量的东西,包括涉及绑定和状态启用的编程风格.
今天的硬件与API的原始硬件完全不同,因此在许多情况下没有明智的"为什么" - 这就是API的工作原理.因此,移动新的Vulkan API会丢弃所有遗留支持,并且具有非常不同的编程模型......
为什么我们必须使用额外功能启用它?
...因为这就是API的工作原理.
有人可以命名一个案例,这有用吗?
...如果你不启用它它不起作用,所以我怀疑这是有用的.
属性位置存储在VAO中.
VAO在原始API中不存在; 他们后来出现了,实际上他们只是为VBO缓存现有的attribarray设置,所以你仍然需要这个API来设置VAO中引用的内容.
如果你用OpenGL问"为什么"很多,你会疯狂 - 从程序员模型的角度来看,它不是一个非常"干净"的API,并且在多次迭代中已经发展,同时在许多情况下保持向后兼容性.有多种做事方式,如果你尝试同时使用两种方式,那么很多事情都没有意义.在大多数情况下,如果没有找到20年前设计原始API时有人在想什么,就不可能准确地回答"为什么".
但是,您可以想象一个理论用例,其中单独的启用是有用的.例如,对渲染具有5个属性数组的模型的情况进行成像,然后对具有4个属性数组的不同模型进行成像.对于第二个模型,硬件对第5个属性有什么作用?天真地,它可能会将其复制到GPU中,因此软件需要告诉硬件不要这样做.您可以使用API编写特殊属性(例如,NULL指针,长度为零),或者您有一个带有启用设置的API,它只是告诉硬件不要读取内容.
鉴于启用可能只是寄存器中的位掩码,那么启用实际上对于驱动程序而言必须比解码特殊情况顶点属性更有效.
这个设置很有意义.启用和禁用它们都有非常有效的用例.
入口点的名称已经给出了强烈的暗示,为什么会这样.注意Array
部分glEnableVertexAttribArray()
.此调用不会"启用该属性".它允许使用数组中的顶点属性值,这意味着:
通过glVertexAttrib[1234]f()
族的调用设置属性的当前值.要在下一次绘制调用中为所有顶点使用相同属性值的用例的典型代码序列是:
glDisableVertexAttribArray(loc);
glVertexAttrib4f(loc, colR, colG, colB, colA);
Run Code Online (Sandbox Code Playgroud)
与每个顶点从数组中获取自己的属性值的情况相比:
glEnableVertexAttribArray(loc);
glVertexAttribPointer(loc, ...);
Run Code Online (Sandbox Code Playgroud)
现在,从数组中获取属性肯定更为常见.因此,你可以争辩说,默认情况下使用现代OpenGL是不幸的.但是设置和改变它的要求肯定仍然非常有用.