理解WebGL状态
我能在哪里找到任何文档记录WebGL调用所需的先决条件吗 我已经对WebGL的基础知识有了相当强的掌握,但现在我正在创建自己的“框架”,我需要更深入的理解 例如,enableVertexAttributeArray调用。此调用是否要求当前着色器处于“使用”状态?它将此“已启用”标志存储在何处?如果我切换着色器程序,我是否必须在以后再次使用它时重新启用它 我想要一些图表来解释所有“有状态”信息存储在哪里,以及何时脱离上下文 另一个例子是使用gl.bindBuffer,数组缓冲区和元素数组缓冲区的缓冲区是否存储在不同的位置 考虑到所有这些,是否建议在JavaScript中使用并行状态以避免运行WebGL调用?i、 e.存储“currentBuffer”对象,以避免在已绑定的情况下反复绑定同一缓冲区。我可以想象,在一般情况下,这会造成相当多的状态复制,但对性能来说可能相当好理解WebGL状态,webgl,Webgl,我能在哪里找到任何文档记录WebGL调用所需的先决条件吗 我已经对WebGL的基础知识有了相当强的掌握,但现在我正在创建自己的“框架”,我需要更深入的理解 例如,enableVertexAttributeArray调用。此调用是否要求当前着色器处于“使用”状态?它将此“已启用”标志存储在何处?如果我切换着色器程序,我是否必须在以后再次使用它时重新启用它 我想要一些图表来解释所有“有状态”信息存储在哪里,以及何时脱离上下文 另一个例子是使用gl.bindBuffer,数组缓冲区和元素数组缓冲区的缓
这是一个基本问题,但很难找到相关信息。我最近给出了一个类似的答案,但我只是说有很多,并提供了规范的链接,没有复制粘贴任何内容。吸取了教训,我可以解决这个问题。但这只是一个合理的警告,如果人们称WebGL为“有状态的”,他们的意思是。但是包含WebGL可以生成的所有错误的文档称为规范。我不会复制所有可能的错误,因为这很容易使它翻倍,如果不是更多的话 首先,因为明确询问了绑定目标,所以这里是查询所有这些目标的方式,不包括扩展:
gl.getParameter( gl.ARRAY_BUFFER_BINDING);
gl.getParameter( gl.ELEMENT_ARRAY_BUFFER_BINDING);
gl.getParameter( gl.FRAMEBUFFER_BINDING);
gl.getParameter( gl.RENDERBUFFER_BINDING);
gl.getParameter( gl.TEXTURE_BINDING_2D);
gl.getParameter( gl.TEXTURE_BINDING_CUBE_MAP);
现在你不必通过这个庞大的列表来找到这些。但是,如果您编写了一个框架,并且希望了解该状态,那么您可能也希望使用所有其他框架
如果你现在看看程序的状态,没有太多的重叠。人们甚至可以做实验,看看状态是如何变化的
或者,您可能想检查着色器的工作情况。仍然看不到真正的重叠
您看到getVertexAttrib
返回一个缓冲区,因此这似乎是相关的。缓冲区本身并不比普通阵列缓冲区更令人兴奋。这些内容不是用JavaScript编写的,而是在遥远的gpu土地上,努力工作以支持家庭
所以程序和顶点数组可能没有那么多共同点。通过猜测很难推断,但如果您知道(或抽象出)所有这些获取者,则很容易发现
为了完整性,并帮助您理解状态,我还复制了所有其他内容
我还没有放弃缓和。所以也许你想检查一下你制服的价值。这有时真的很有用
下面是一些更有用的getter:
当然,每个人都爱的人:
哦,这里这个实际上属于顶点属性,几乎忘记了。由于重要的遗留原因,它是分开的
(pname必须是该节点上的顶点属性数组指针)
除非我忘了什么,这基本上就是WebGL状态的全部。这看起来可能很多,但我个人发现所有这些都对理解事物是如何工作的非常有帮助。如果没有这些,你基本上是被蒙住眼睛,不得不一直猜测,并且按照教程告诉你调用函数的确切顺序,这在WebGL中并不适用——因为有很多事情,但你也可以犯错误。Screenius的答案相当完整 这是一个 简洁的版本是: 在WebGL 1.0中,制服按程序排列,纹理过滤和包装按纹理排列。其他一切都是全球性的。它包括所有属性和所有纹理单元 从以前的一些答案粘贴,涵盖这一点 您可以像这样考虑属性和纹理单元
gl = {
arrayBuffer: someBuffer,
vertexArray: {
elementArrayBuffer: someOtherBuffer,
attributes: [],
},
};
调用gl.bindBuffer
时,您只需在gl状态下设置两个全局变量之一
gl.bindBuffer = function(bindPoint, buffer) {
switch (bindPoint) {
case: this.ARRAY_BUFFER:
this.arrayBuffer = buffer;
break;
case: this.ELEMENT_ARRAY_BUFFER:
this.vertexArray.elementArrayBuffer = buffer;
break;
}
};
调用gl.VertexAttributePointer
时,它会将arrayBuffer
的当前值复制到指定的属性
gl.vertexAttribPointer = function(index, size, type, normalized, stride, offset) {
var attribute = this.vertexArray.attributes[index];
attribute.size = size;
attribute.type = type;
attribute.normalized = normalized;
attribute.stride = stride;
attribute.offset = offset;
attribute.buffer = this.arrayBuffer; // copies the current buffer reference.
};
纹理的工作原理类似
gl = {
activeTextureUnit: 0,
textureUnits: [],
};
gl.activeTexture
设置您正在使用的纹理单元
gl.activeTexture = function(unit) {
this.activeTextureUnit = unit - this.TEXTURE_0; // make it zero based.
};
每个纹理单元都有一个texture\u 2D
和一个texture\u CUBEMAP
sogl。bindTexture(b,t)
是有效的
gl.bindTexture = function(bindPoint, texture) {
var textureUnit = this.textureUnits[this.activeTextureUnit];
switch (bindPoint) {
case this.TEXTURE_2D:
textureUnit.texture2D = texture;
break;
case this.TEXTURE_CUBEMAP:
textureUnit.textureCubeMap = texture;
break;
}
};
其余的是全局状态,如清晰颜色、视口、混合设置、模具设置、启用/禁用内容,如深度测试
,剪刀测试
只是一个旁注:如果你在上面的例子中启用
vertexArray
成为它自己的对象,你可以用bindVertexArrayOES
绑定,那么我承认我花了一段时间才理解这篇文章的含义。我说要理解状态存储在哪里,我应该简单地看看我将如何查询它,这会告诉我,这是正确的吗?e、 g.如果我使用getParameter,它必须是“全局的”,如果我使用getProgramParameter,它必须与程序一起存储?这是有道理的。我想可以查询的任何内容都是独立的,因此存在gl.ARRAY\u BUFFER\u绑定和gl.ELEMENT\u ARRAY\u BUFFER\u绑定这一事实意味着它们是完全独立的绑定。@Brendannable是的,您的思路是正确的!嘿,我知道这已经有一段时间没有得到回答了,但我现在也在挖掘webgl状态的主题。以类似json的方式查看gl={…}
状态非常有用。是否有任何白皮书/规范列出了完整的“webgl状态”?不需要函数
pname returned type
RENDERBUFFER_WIDTH GLint
RENDERBUFFER_HEIGHT GLint
RENDERBUFFER_INTERNAL_FORMAT GLenum
RENDERBUFFER_RED_SIZE GLint
RENDERBUFFER_GREEN_SIZE GLint
RENDERBUFFER_BLUE_SIZE GLint
RENDERBUFFER_ALPHA_SIZE GLint
RENDERBUFFER_DEPTH_SIZE GLint
RENDERBUFFER_STENCIL_SIZE GLint
pname returned type
TEXTURE_MAG_FILTER GLenum
TEXTURE_MIN_FILTER GLenum
TEXTURE_WRAP_S GLenum
TEXTURE_WRAP_T GLenum
gl = {
arrayBuffer: someBuffer,
vertexArray: {
elementArrayBuffer: someOtherBuffer,
attributes: [],
},
};
gl.bindBuffer = function(bindPoint, buffer) {
switch (bindPoint) {
case: this.ARRAY_BUFFER:
this.arrayBuffer = buffer;
break;
case: this.ELEMENT_ARRAY_BUFFER:
this.vertexArray.elementArrayBuffer = buffer;
break;
}
};
gl.vertexAttribPointer = function(index, size, type, normalized, stride, offset) {
var attribute = this.vertexArray.attributes[index];
attribute.size = size;
attribute.type = type;
attribute.normalized = normalized;
attribute.stride = stride;
attribute.offset = offset;
attribute.buffer = this.arrayBuffer; // copies the current buffer reference.
};
gl = {
activeTextureUnit: 0,
textureUnits: [],
};
gl.activeTexture = function(unit) {
this.activeTextureUnit = unit - this.TEXTURE_0; // make it zero based.
};
gl.bindTexture = function(bindPoint, texture) {
var textureUnit = this.textureUnits[this.activeTextureUnit];
switch (bindPoint) {
case this.TEXTURE_2D:
textureUnit.texture2D = texture;
break;
case this.TEXTURE_CUBEMAP:
textureUnit.textureCubeMap = texture;
break;
}
};