理解 WebGL 状态 [英] Understanding WebGL State
问题描述
是否可以在某处找到任何文档来记录 WebGL 调用所需的先决条件?
Is there any documentation I can find somewhere which documents the preconditions required for WebGL calls?
我对 WebGL 的基础知识有了相当深入的了解,但现在我正在创建自己的框架",并且需要更深入的了解.
I have gotten a fairly strong grasp of the WebGL basics, but now I am creating my own 'framework' and I'm after a deeper understanding.
例如, enableVertexAttribArray 调用.此调用是否要求当前着色器处于使用"状态?它在哪里存储这个启用"标志?如果我切换了着色器程序,当我再次使用它时是否需要重新启用它?
For example, the enableVertexAttribArray call. Does this call required the current shader to be in 'use'? Where does it store this 'enabled' flag? If I switch shader programs, do I have to re-enable it afterwards when I use it again?
我想要某种图表来解释所有有状态"信息的存储位置,以及何时会脱离上下文.
I'd love some kind of diagram explaining where all the 'stateful' information is being stored, and when it will go out of context.
另一个例子是使用 gl.bindBuffer,ARRAY_BUFFER 和 ELEMENT_ARRAY_BUFFER 的缓冲区是否存储在不同的位置?
Another example is using gl.bindBuffer, are the buffers for ARRAY_BUFFER and ELEMENT_ARRAY_BUFFER stored in separate locations?
考虑到所有这些,是否建议在 JavaScript 中使用并行状态以避免运行 WebGL 调用?即存储一个currentBuffer"对象以避免在它已经绑定的情况下一遍又一遍地绑定相同的缓冲区.我可以想象在一般情况下,这会变成相当多的状态重复,但对性能来说可能相当不错.
With all this in mind, is it recommended to have a parallel state in JavaScript to avoid running WebGL calls? i.e. storing a 'currentBuffer' object to avoid binding the same buffer over and over if its already bound. I can imagine in the general case, this becomes quite a bit of state duplication, but could be quite good for performance.
有点基本问题,但很难找到相关信息.
Bit of a fundamental question but hard to find info on.
推荐答案
我最近给出了类似的答案,但我只是说有很多并且给出了规范的链接,没有复制粘贴任何内容.吸取教训,我可以解决这个问题.但只是一个公平的警告,如果人们称 WebGL 为有状态的",他们是认真的.但是包含 WebGL 在这些条件下可能生成的所有错误的文档称为规范.我不会复制所有可能的错误,因为这很容易使错误翻倍,甚至更多.
I recently gave a similar answer, but I just said that there's quite a lot and gave a link to the spec, without copy pasting anything. Lesson learned, I can fix that. But just a fair warning, if people call WebGL "stateful" they mean it. But the document, that contains all the errors WebGL can generate under which conditions is called the spec. I'm not copying over all the possible errors, because that would easily double it, if not more.
首先,因为您明确询问了绑定目标,这里是您查询所有这些的方式,不包括扩展名:
First, because are you explicitly asked about binding targets, here is how you query all of those, not counting extensions:
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);
现在您不必通过这个庞大的列表来找到那些.但是,如果您编写一个框架,并且想了解状态,那么您可能也想使用所有其他框架.
Now you don't have to go through this huge list to find those. But if you write a framework, and want to understand the state, you may want to use all the others, too.
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
是在特定索引处设置顶点属性数组的状态,与程序无关.您还可以通过上述索引查询所有这些状态.
enableVertexAttribArray
and vertexAttribPointer
are setting the state of a vertex attribute array at a specific index, and don't have anything to do with the program. You can also query all this state, by aforementioned index.
getVertexAttrib(GLuint 索引,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)
如果您现在查看程序的状态,就会发现没有太多重叠.人们甚至可以进行实验,看看自己的状态是如何变化的.
If you now look at the state of the program, there isn't much overlap. One could even go as far as make experiments and see yourself how the states change.
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
或者您可能想检查着色器的运行情况.仍然看不到真正的重叠.
Or maybe you want to check how your shader is doing. Still no real overlap in sight.
getShaderParameter(WebGLShader?shader, GLenum pname)
pname returned type
SHADER_TYPE GLenum
DELETE_STATUS GLboolean
COMPILE_STATUS GLboolean
您看到 getVertexAttrib
返回一个缓冲区,所以这似乎很相关.缓冲区本身并不比简单的 ArrayBuffer 更令人兴奋.内容只是不在javacript里,而是在gpu地很远的地方,努力养家糊口.
You saw getVertexAttrib
returns a buffer, so that seems relevant. The buffer itself isn't that much more exciting than say a plain ArrayBuffer. The contents are just not in javacript, but far away in gpu land, doing hard work to support the family at home.
getBufferParameter(GLenum target, GLenum pname)一个>
pname returned type
BUFFER_SIZE GLint
BUFFER_USAGE GLenum
所以程序和顶点数组可能没有那么多共同点.很难通过猜测来推断,但如果你知道(或抽象掉)所有这些 getter,那么很容易找到.
So probably programs and vertex arrays don't have that much in common. Difficult to deduce by guessing, but really simple to find out if you know ( or abstract away ) all those getters.
为了完整起见,并帮助您理解状态,我还复制了所有其他内容.
For completeness, and to help you understand state, I also copy over all the other things.
getFramebufferAttachmentParameter(GLenum 目标,GLenum 附件,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
我还没有放弃对其进行审核.所以也许你想检查一下你制服的价值.这有时真的很有用.
I didn't give up moderating it just yet. So maybe you want to check the value of your uniforms. That's really useful sometimes.
getUniform(WebGLProgram?程序,WebGLUniformLocation?位置)
这里还有一些非常有用的 getter:
Here a few more really useful getters:
getActiveAttrib(WebGLProgram?程序,GLuint 索引)
getActiveUniform(WebGLProgram? program, GLuint index)
当然还有大家喜欢的:
getUniformLocation(WebGLProgram? program, DOMString name)
getAttribLocation(WebGLProgram? program, DOMString name)
getProgramInfoLog(WebGLProgram? 程序)
getShaderInfoLog(WebGLShader?着色器)
getShaderSource(WebGLShader?着色器)
getShaderPrecisionFormat(GLenum shadertype, GLenum precisiontype)
哦这里说的其实是属于顶点属性的,差点忘了.由于重要的遗留原因,它是分开的.
Oh here that one actually belongs to the vertex attributes, almost forgot. It's separate for important legacy reasons.
getVertexAttribOffset(GLuint index, GLenum pname)
(pname 必须是 VERTEX_ATTRIB_ARRAY_POINTER
那个.)
( pname has to be VERTEX_ATTRIB_ARRAY_POINTER
on that one. )
除非我忘记了什么,否则基本上都是 WebGL 状态.它可能看起来很多,但我个人发现所有这些对于理解事物的运作方式非常有帮助.如果没有这些,您基本上会被蒙住眼睛,只能一直猜测,然后按照教程告诉您调用函数的确切顺序,这在 WebGL 中效果不佳 - 只是因为有太多东西,但也有错误你可以.
Unless I forgot something, that's basically all of WebGL state. It may seem like a lot, but I personally found all of it to be really helpful to understand how things work. Without those you are basically blindfolded and have to just guess all the time, and follow tutorials telling you the exact order you have to call functions in, which doesn't work well with WebGL - just because there are so many things, but also mistakes you can do.
这篇关于理解 WebGL 状态的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!