了解 WebGL 状态
Understanding WebGL State
是否有任何我可以在某处找到的文档记录了 WebGL 调用所需的先决条件?
我已经相当深入地掌握了 WebGL 的基础知识,但现在我正在创建自己的 'framework' 并且需要更深入的理解。
例如,enableVertexAttribArray 调用。此调用是否要求当前着色器位于 'use' 中?它在哪里存储这个 'enabled' 标志?如果我切换着色器程序,以后再次使用它时是否必须重新启用它?
我想要某种图表来解释所有 'stateful' 信息的存储位置,以及何时会脱离上下文。
另一个例子是使用 gl.bindBuffer,ARRAY_BUFFER 和 ELEMENT_ARRAY_BUFFER 的缓冲区是否存储在不同的位置?
考虑到所有这些,是否建议在 JavaScript 中使用并行状态以避免 运行 WebGL 调用?即存储一个 'currentBuffer' 对象以避免在已经绑定的情况下一遍又一遍地绑定相同的缓冲区。我可以想象在一般情况下,这会变成相当多的状态重复,但对于性能来说可能会非常好。
有点基本问题,但很难找到相关信息。
我最近给出了类似的答案,但我只是说有很多并且给了规范 link,没有复制粘贴任何东西。吸取教训,我可以解决这个问题。但只是一个公平的警告,如果人们称 WebGL "stateful" 他们 是认真的 。但是包含 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);
现在您不必通过这个巨大的列表来找到它们。但是如果你写了一个框架,并且想了解状态,你可能也想使用所有其他的。
pname returned type
ACTIVE_TEXTURE GLenum
ALIASED_LINE_WIDTH_RANGE Float32Array (with 2 elements)
ALIASED_POINT_SIZE_RANGE Float32Array (with 2 elements)
ALPHA_BITS GLint
ARRAY_BUFFER_BINDING WebGLBuffer
BLEND GLboolean
BLEND_COLOR Float32Array (with 4 values)
BLEND_DST_ALPHA GLenum
BLEND_DST_RGB GLenum
BLEND_EQUATION_ALPHA GLenum
BLEND_EQUATION_RGB GLenum
BLEND_SRC_ALPHA GLenum
BLEND_SRC_RGB GLenum
BLUE_BITS GLint
COLOR_CLEAR_VALUE Float32Array (with 4 values)
COLOR_WRITEMASK sequence<GLboolean> (with 4 values)
COMPRESSED_TEXTURE_FORMATS Uint32Array
CULL_FACE GLboolean
CULL_FACE_MODE GLenum
CURRENT_PROGRAM WebGLProgram
DEPTH_BITS GLint
DEPTH_CLEAR_VALUE GLfloat
DEPTH_FUNC GLenum
DEPTH_RANGE Float32Array (with 2 elements)
DEPTH_TEST GLboolean
DEPTH_WRITEMASK GLboolean
DITHER GLboolean
ELEMENT_ARRAY_BUFFER_BINDING WebGLBuffer
FRAMEBUFFER_BINDING WebGLFramebuffer
FRONT_FACE GLenum
GENERATE_MIPMAP_HINT GLenum
GREEN_BITS GLint
IMPLEMENTATION_COLOR_READ_FORMAT GLenum
IMPLEMENTATION_COLOR_READ_TYPE GLenum
LINE_WIDTH GLfloat
MAX_COMBINED_TEXTURE_IMAGE_UNITS GLint
MAX_CUBE_MAP_TEXTURE_SIZE GLint
MAX_FRAGMENT_UNIFORM_VECTORS GLint
MAX_RENDERBUFFER_SIZE GLint
MAX_TEXTURE_IMAGE_UNITS GLint
MAX_TEXTURE_SIZE GLint
MAX_VARYING_VECTORS GLint
MAX_VERTEX_ATTRIBS GLint
MAX_VERTEX_TEXTURE_IMAGE_UNITS GLint
MAX_VERTEX_UNIFORM_VECTORS GLint
MAX_VIEWPORT_DIMS Int32Array (with 2 elements)
PACK_ALIGNMENT GLint
POLYGON_OFFSET_FACTOR GLfloat
POLYGON_OFFSET_FILL GLboolean
POLYGON_OFFSET_UNITS GLfloat
RED_BITS GLint
RENDERBUFFER_BINDING WebGLRenderbuffer
RENDERER DOMString
SAMPLE_BUFFERS GLint
SAMPLE_COVERAGE_INVERT GLboolean
SAMPLE_COVERAGE_VALUE GLfloat
SAMPLES GLint
SCISSOR_BOX Int32Array (with 4 elements)
SCISSOR_TEST GLboolean
SHADING_LANGUAGE_VERSION DOMString
STENCIL_BACK_FAIL GLenum
STENCIL_BACK_FUNC GLenum
STENCIL_BACK_PASS_DEPTH_FAIL GLenum
STENCIL_BACK_PASS_DEPTH_PASS GLenum
STENCIL_BACK_REF GLint
STENCIL_BACK_VALUE_MASK GLuint
STENCIL_BACK_WRITEMASK GLuint
STENCIL_BITS GLint
STENCIL_CLEAR_VALUE GLint
STENCIL_FAIL GLenum
STENCIL_FUNC GLenum
STENCIL_PASS_DEPTH_FAIL GLenum
STENCIL_PASS_DEPTH_PASS GLenum
STENCIL_REF GLint
STENCIL_TEST GLboolean
STENCIL_VALUE_MASK GLuint
STENCIL_WRITEMASK GLuint
SUBPIXEL_BITS GLint
TEXTURE_BINDING_2D WebGLTexture
TEXTURE_BINDING_CUBE_MAP WebGLTexture
UNPACK_ALIGNMENT GLint
UNPACK_COLORSPACE_CONVERSION_WEBGL GLenum
UNPACK_FLIP_Y_WEBGL GLboolean
UNPACK_PREMULTIPLY_ALPHA_WEBGL GLboolean
VENDOR DOMString
VERSION DOMString
VIEWPORT Int32Array (with 4 elements)
enableVertexAttribArray
和vertexAttribPointer
是在特定索引处设置顶点属性数组的状态,与程序无关。您还可以通过上述索引查询所有这些状态。
getVertexAttrib (GLuint index, GLenum pname )
pname returned type
VERTEX_ATTRIB_ARRAY_BUFFER_BINDING WebGLBuffer
VERTEX_ATTRIB_ARRAY_ENABLED GLboolean
VERTEX_ATTRIB_ARRAY_SIZE GLint
VERTEX_ATTRIB_ARRAY_STRIDE GLint
VERTEX_ATTRIB_ARRAY_TYPE GLenum
VERTEX_ATTRIB_ARRAY_NORMALIZED GLboolean
CURRENT_VERTEX_ATTRIB Float32Array (with 4 elements)
如果您现在查看程序的状态,就会发现没有太多重叠。甚至可以做实验,亲眼看看状态是如何变化的。
getProgramParameter(WebGLProgram? program, GLenum pname)
pname returned type
DELETE_STATUS GLboolean
LINK_STATUS GLboolean
VALIDATE_STATUS GLboolean
ATTACHED_SHADERS GLint
ACTIVE_ATTRIBUTES GLint
ACTIVE_UNIFORMS GLint
或者您可能想检查着色器的运行情况。仍然看不到真正的重叠。
getShaderParameter(WebGLShader? shader, GLenum pname)
pname returned type
SHADER_TYPE GLenum
DELETE_STATUS GLboolean
COMPILE_STATUS GLboolean
您看到了 getVertexAttrib
returns 一个缓冲区,所以这似乎是相关的。缓冲区本身并不比普通的 ArrayBuffer 更令人兴奋。内容只是不是javacript,而是远在gpu的土地上,辛辛苦苦养家糊口
getBufferParameter(GLenum target, GLenum pname)
pname returned type
BUFFER_SIZE GLint
BUFFER_USAGE GLenum
所以程序和顶点数组可能没有那么多共同点。很难通过猜测来推断,但如果您知道(或抽象掉)所有这些吸气剂,则非常简单。
为了完整性,也为了帮助您理解状态,我也复制了所有其他内容。
getFramebufferAttachmentParameter(GLenum target, GLenum attachment, GLenum pname)
pname returned type
FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE GLenum
FRAMEBUFFER_ATTACHMENT_OBJECT_NAME WebGLRenderbuffer or WebGLTexture
FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL GLint
FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE GLint
getRenderbufferParameter(GLenum target, GLenum pname)
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
getTexParameter(GLenum target, GLenum pname)
pname returned type
TEXTURE_MAG_FILTER GLenum
TEXTURE_MIN_FILTER GLenum
TEXTURE_WRAP_S GLenum
TEXTURE_WRAP_T GLenum
我还没有放弃主持它。所以也许您想检查制服的价值。这有时真的很有用。
getUniform(WebGLProgram? program, WebGLUniformLocation? location)
这里有一些更有用的吸气剂:
getActiveAttrib(WebGLProgram? program, GLuint index)
getActiveUniform(WebGLProgram? program, GLuint index)
当然还有那些人人都爱的人:
getUniformLocation(WebGLProgram? program, DOMString name)
getAttribLocation(WebGLProgram? program, DOMString name)
getProgramInfoLog(WebGLProgram? program)
getShaderInfoLog(WebGLShader? shader)
getShaderSource(WebGLShader? shader)
getShaderPrecisionFormat(GLenum shadertype, GLenum precisiontype)
哦这里居然还有一个属于顶点属性的,差点忘了。由于重要的遗留原因,它是分开的。
getVertexAttribOffset(GLuint index, GLenum pname)
(那个 pname 必须是 VERTEX_ATTRIB_ARRAY_POINTER
。)
除非我忘记了什么,否则这基本上就是 WebGL 状态的全部。看起来可能很多,但我个人发现所有这些都对理解事物的运作方式非常有帮助。如果没有这些,你基本上会被蒙住双眼,只能一直猜测,并按照教程告诉你调用函数的确切顺序,这在 WebGL 中效果不佳——因为有太多东西,但也有错误你可以的。
Screenius 的回答非常完整。
精简版本为:
在 WebGL 1.0 中,制服是按程序进行的,纹理过滤和包装是按纹理进行的。其他一切都是全球性的。这包括所有属性和所有纹理单元。
从以前的一些回答中粘贴过来
你可以这样想属性和纹理单元
gl = {
arrayBuffer: someBuffer,
vertexArray: {
elementArrayBuffer: someOtherBuffer,
attributes: [],
},
};
当您调用 gl.bindBuffer
时,您只是在 gl 状态中设置了 2 个全局变量之一。
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
时,它会将 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_2D
和一个 TEXTURE_CUBEMAP
所以 gl.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;
}
};
其余的是全局状态,如透明颜色、视口、混合设置、模板设置、enable/disable 东西,如 DEPTH_TEST
、SCISSOR_TEST
附带说明:如果您启用 the extension OES_vertex_array_object,则上例中的 vertexArray
将成为您可以与 bindVertexArrayOES
绑定的对象。
是否有任何我可以在某处找到的文档记录了 WebGL 调用所需的先决条件?
我已经相当深入地掌握了 WebGL 的基础知识,但现在我正在创建自己的 'framework' 并且需要更深入的理解。
例如,enableVertexAttribArray 调用。此调用是否要求当前着色器位于 'use' 中?它在哪里存储这个 'enabled' 标志?如果我切换着色器程序,以后再次使用它时是否必须重新启用它?
我想要某种图表来解释所有 'stateful' 信息的存储位置,以及何时会脱离上下文。
另一个例子是使用 gl.bindBuffer,ARRAY_BUFFER 和 ELEMENT_ARRAY_BUFFER 的缓冲区是否存储在不同的位置?
考虑到所有这些,是否建议在 JavaScript 中使用并行状态以避免 运行 WebGL 调用?即存储一个 'currentBuffer' 对象以避免在已经绑定的情况下一遍又一遍地绑定相同的缓冲区。我可以想象在一般情况下,这会变成相当多的状态重复,但对于性能来说可能会非常好。
有点基本问题,但很难找到相关信息。
我最近给出了类似的答案,但我只是说有很多并且给了规范 link,没有复制粘贴任何东西。吸取教训,我可以解决这个问题。但只是一个公平的警告,如果人们称 WebGL "stateful" 他们 是认真的 。但是包含 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);
现在您不必通过这个巨大的列表来找到它们。但是如果你写了一个框架,并且想了解状态,你可能也想使用所有其他的。
pname returned type
ACTIVE_TEXTURE GLenum
ALIASED_LINE_WIDTH_RANGE Float32Array (with 2 elements)
ALIASED_POINT_SIZE_RANGE Float32Array (with 2 elements)
ALPHA_BITS GLint
ARRAY_BUFFER_BINDING WebGLBuffer
BLEND GLboolean
BLEND_COLOR Float32Array (with 4 values)
BLEND_DST_ALPHA GLenum
BLEND_DST_RGB GLenum
BLEND_EQUATION_ALPHA GLenum
BLEND_EQUATION_RGB GLenum
BLEND_SRC_ALPHA GLenum
BLEND_SRC_RGB GLenum
BLUE_BITS GLint
COLOR_CLEAR_VALUE Float32Array (with 4 values)
COLOR_WRITEMASK sequence<GLboolean> (with 4 values)
COMPRESSED_TEXTURE_FORMATS Uint32Array
CULL_FACE GLboolean
CULL_FACE_MODE GLenum
CURRENT_PROGRAM WebGLProgram
DEPTH_BITS GLint
DEPTH_CLEAR_VALUE GLfloat
DEPTH_FUNC GLenum
DEPTH_RANGE Float32Array (with 2 elements)
DEPTH_TEST GLboolean
DEPTH_WRITEMASK GLboolean
DITHER GLboolean
ELEMENT_ARRAY_BUFFER_BINDING WebGLBuffer
FRAMEBUFFER_BINDING WebGLFramebuffer
FRONT_FACE GLenum
GENERATE_MIPMAP_HINT GLenum
GREEN_BITS GLint
IMPLEMENTATION_COLOR_READ_FORMAT GLenum
IMPLEMENTATION_COLOR_READ_TYPE GLenum
LINE_WIDTH GLfloat
MAX_COMBINED_TEXTURE_IMAGE_UNITS GLint
MAX_CUBE_MAP_TEXTURE_SIZE GLint
MAX_FRAGMENT_UNIFORM_VECTORS GLint
MAX_RENDERBUFFER_SIZE GLint
MAX_TEXTURE_IMAGE_UNITS GLint
MAX_TEXTURE_SIZE GLint
MAX_VARYING_VECTORS GLint
MAX_VERTEX_ATTRIBS GLint
MAX_VERTEX_TEXTURE_IMAGE_UNITS GLint
MAX_VERTEX_UNIFORM_VECTORS GLint
MAX_VIEWPORT_DIMS Int32Array (with 2 elements)
PACK_ALIGNMENT GLint
POLYGON_OFFSET_FACTOR GLfloat
POLYGON_OFFSET_FILL GLboolean
POLYGON_OFFSET_UNITS GLfloat
RED_BITS GLint
RENDERBUFFER_BINDING WebGLRenderbuffer
RENDERER DOMString
SAMPLE_BUFFERS GLint
SAMPLE_COVERAGE_INVERT GLboolean
SAMPLE_COVERAGE_VALUE GLfloat
SAMPLES GLint
SCISSOR_BOX Int32Array (with 4 elements)
SCISSOR_TEST GLboolean
SHADING_LANGUAGE_VERSION DOMString
STENCIL_BACK_FAIL GLenum
STENCIL_BACK_FUNC GLenum
STENCIL_BACK_PASS_DEPTH_FAIL GLenum
STENCIL_BACK_PASS_DEPTH_PASS GLenum
STENCIL_BACK_REF GLint
STENCIL_BACK_VALUE_MASK GLuint
STENCIL_BACK_WRITEMASK GLuint
STENCIL_BITS GLint
STENCIL_CLEAR_VALUE GLint
STENCIL_FAIL GLenum
STENCIL_FUNC GLenum
STENCIL_PASS_DEPTH_FAIL GLenum
STENCIL_PASS_DEPTH_PASS GLenum
STENCIL_REF GLint
STENCIL_TEST GLboolean
STENCIL_VALUE_MASK GLuint
STENCIL_WRITEMASK GLuint
SUBPIXEL_BITS GLint
TEXTURE_BINDING_2D WebGLTexture
TEXTURE_BINDING_CUBE_MAP WebGLTexture
UNPACK_ALIGNMENT GLint
UNPACK_COLORSPACE_CONVERSION_WEBGL GLenum
UNPACK_FLIP_Y_WEBGL GLboolean
UNPACK_PREMULTIPLY_ALPHA_WEBGL GLboolean
VENDOR DOMString
VERSION DOMString
VIEWPORT Int32Array (with 4 elements)
enableVertexAttribArray
和vertexAttribPointer
是在特定索引处设置顶点属性数组的状态,与程序无关。您还可以通过上述索引查询所有这些状态。
getVertexAttrib (GLuint index, GLenum pname )
pname returned type
VERTEX_ATTRIB_ARRAY_BUFFER_BINDING WebGLBuffer
VERTEX_ATTRIB_ARRAY_ENABLED GLboolean
VERTEX_ATTRIB_ARRAY_SIZE GLint
VERTEX_ATTRIB_ARRAY_STRIDE GLint
VERTEX_ATTRIB_ARRAY_TYPE GLenum
VERTEX_ATTRIB_ARRAY_NORMALIZED GLboolean
CURRENT_VERTEX_ATTRIB Float32Array (with 4 elements)
如果您现在查看程序的状态,就会发现没有太多重叠。甚至可以做实验,亲眼看看状态是如何变化的。
getProgramParameter(WebGLProgram? program, GLenum pname)
pname returned type
DELETE_STATUS GLboolean
LINK_STATUS GLboolean
VALIDATE_STATUS GLboolean
ATTACHED_SHADERS GLint
ACTIVE_ATTRIBUTES GLint
ACTIVE_UNIFORMS GLint
或者您可能想检查着色器的运行情况。仍然看不到真正的重叠。
getShaderParameter(WebGLShader? shader, GLenum pname)
pname returned type
SHADER_TYPE GLenum
DELETE_STATUS GLboolean
COMPILE_STATUS GLboolean
您看到了 getVertexAttrib
returns 一个缓冲区,所以这似乎是相关的。缓冲区本身并不比普通的 ArrayBuffer 更令人兴奋。内容只是不是javacript,而是远在gpu的土地上,辛辛苦苦养家糊口
getBufferParameter(GLenum target, GLenum pname)
pname returned type
BUFFER_SIZE GLint
BUFFER_USAGE GLenum
所以程序和顶点数组可能没有那么多共同点。很难通过猜测来推断,但如果您知道(或抽象掉)所有这些吸气剂,则非常简单。
为了完整性,也为了帮助您理解状态,我也复制了所有其他内容。
getFramebufferAttachmentParameter(GLenum target, GLenum attachment, GLenum pname)
pname returned type
FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE GLenum
FRAMEBUFFER_ATTACHMENT_OBJECT_NAME WebGLRenderbuffer or WebGLTexture
FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL GLint
FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE GLint
getRenderbufferParameter(GLenum target, GLenum pname)
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
getTexParameter(GLenum target, GLenum pname)
pname returned type
TEXTURE_MAG_FILTER GLenum
TEXTURE_MIN_FILTER GLenum
TEXTURE_WRAP_S GLenum
TEXTURE_WRAP_T GLenum
我还没有放弃主持它。所以也许您想检查制服的价值。这有时真的很有用。
getUniform(WebGLProgram? program, WebGLUniformLocation? location)
这里有一些更有用的吸气剂:
getActiveAttrib(WebGLProgram? program, GLuint index)
getActiveUniform(WebGLProgram? program, GLuint index)
当然还有那些人人都爱的人:
getUniformLocation(WebGLProgram? program, DOMString name)
getAttribLocation(WebGLProgram? program, DOMString name)
getProgramInfoLog(WebGLProgram? program)
getShaderInfoLog(WebGLShader? shader)
getShaderSource(WebGLShader? shader)
getShaderPrecisionFormat(GLenum shadertype, GLenum precisiontype)
哦这里居然还有一个属于顶点属性的,差点忘了。由于重要的遗留原因,它是分开的。
getVertexAttribOffset(GLuint index, GLenum pname)
(那个 pname 必须是 VERTEX_ATTRIB_ARRAY_POINTER
。)
除非我忘记了什么,否则这基本上就是 WebGL 状态的全部。看起来可能很多,但我个人发现所有这些都对理解事物的运作方式非常有帮助。如果没有这些,你基本上会被蒙住双眼,只能一直猜测,并按照教程告诉你调用函数的确切顺序,这在 WebGL 中效果不佳——因为有太多东西,但也有错误你可以的。
Screenius 的回答非常完整。
精简版本为:
在 WebGL 1.0 中,制服是按程序进行的,纹理过滤和包装是按纹理进行的。其他一切都是全球性的。这包括所有属性和所有纹理单元。
从以前的一些回答中粘贴过来
你可以这样想属性和纹理单元
gl = {
arrayBuffer: someBuffer,
vertexArray: {
elementArrayBuffer: someOtherBuffer,
attributes: [],
},
};
当您调用 gl.bindBuffer
时,您只是在 gl 状态中设置了 2 个全局变量之一。
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
时,它会将 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_2D
和一个 TEXTURE_CUBEMAP
所以 gl.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;
}
};
其余的是全局状态,如透明颜色、视口、混合设置、模板设置、enable/disable 东西,如 DEPTH_TEST
、SCISSOR_TEST
附带说明:如果您启用 the extension OES_vertex_array_object,则上例中的 vertexArray
将成为您可以与 bindVertexArrayOES
绑定的对象。