了解WebGL状态

Bre*_*ble 6 webgl

是否有任何文档可以找到哪些文档记录了WebGL调用所需的前提条件?

我已经对WebGL基础知识有了很强的把握,但现在我正在创建自己的"框架",并且我正在深入了解.

例如,enableVertexAttribArray调用.此调用是否要求当前着色器处于"使用"状态?它在哪里存储这个"启用"标志?如果我切换着色器程序,我再次使用它时是否必须重新启用它?

我喜欢某种图表,解释所有"有状态"信息的存储位置,以及它何时会脱离上下文.

另一个例子是使用gl.bindBuffer,ARRAY_BUFFER和ELEMENT_ARRAY_BUFFER的缓冲区是否存储在不同的位置?

考虑到所有这些,是否建议在JavaScript中使用并行状态以避免运行WebGL调用?即存储'currentBuffer'对象,以避免在已经绑定的情况下反复绑定相同的缓冲区.我可以想象,在一般情况下,这变得相当多的状态重复,但可能对性能非常好.

一点基本问题,但很难找到信息.

Win*_*tro 6

我最近给出了一个类似的答案,但我只是说有很多,并提供了规范的链接,没有复制粘贴任何东西.经验教训,我可以解决这个问题.但只是一个公平的警告,如果人们称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);
Run Code Online (Sandbox Code Playgroud)

现在你不必通过这个庞大的列表来找到它们.但是如果你编写一个框架,并想要了解状态,你也可能想要使用所有其他框架.

getParameter(GLenum pname)

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)
Run Code Online (Sandbox Code Playgroud)

enableVertexAttribArrayvertexAttribPointer在特定索引处设置顶点属性数组的状态,并且与程序无关.您还可以通过上述索引查询所有此状态.

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)
Run Code Online (Sandbox Code Playgroud)

如果您现在查看程序的状态,则没有太多重叠.人们甚至可以进行实验,看看自己的状态如何变化.

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
Run Code Online (Sandbox Code Playgroud)

或者您可能想要检查着色器的工作方式.仍然没有看到真正的重叠.

getShaderParameter(WebGLShader?shader,GLenum pname)

pname                   returned type
SHADER_TYPE             GLenum
DELETE_STATUS           GLboolean
COMPILE_STATUS          GLboolean
Run Code Online (Sandbox Code Playgroud)

你看到getVertexAttrib返回一个缓冲区,所以这似乎是相关的.缓冲区本身并不比普通的ArrayBuffer更令人兴奋.内容不是javacript,而是远在gpu土地上,努力工作以支持家里的家庭.

getBufferParameter(GLenum target,GLenum pname)

pname                       returned type
BUFFER_SIZE                 GLint
BUFFER_USAGE                GLenum
Run Code Online (Sandbox Code Playgroud)

所以程序和顶点数组可能没有那么多共同之处.难以通过猜测来推断,但如果你知道(或抽象地)所有那些吸气剂,那么很容易找到.

为了完整性,并帮助您了解状态,我还复制了所有其他事情.

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
Run Code Online (Sandbox Code Playgroud)

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
Run Code Online (Sandbox Code Playgroud)

getTexParameter(GLenum target,GLenum pname)

pname               returned type
TEXTURE_MAG_FILTER  GLenum
TEXTURE_MIN_FILTER  GLenum
TEXTURE_WRAP_S      GLenum
TEXTURE_WRAP_T      GLenum
Run Code Online (Sandbox Code Playgroud)

我还没有放弃主持它.所以也许你想检查你的制服的价值.这有时非常有用.

getUniform(WebGLProgram?程序,WebGLUniformLocation?位置)

这里有一些非常有用的吸气剂:

getActiveAttrib(WebGLProgram?程序,GLuint索引)

getActiveUniform(WebGLProgram?程序,GLuint索引)

当然,有人喜欢:

getUniformLocation(WebGLProgram?程序,DOMString名称)

getAttribLocation(WebGLProgram?程序,DOMString名称)

getProgramInfoLog(WebGLProgram?程序)

getShaderInfoLog(WebGLShader?着色器)

getShaderSource(WebGLShader?着色器)

getShaderPrecisionFormat(GLenum shadertype,GLenum precisiontype)

getSupportedExtensions()

哦,这里实际上属于顶点属性,差点忘了.由于重要的遗留原因,它是分开的.

getVertexAttribOffset(GLuint索引,GLenum pname)

(pname必须VERTEX_ATTRIB_ARRAY_POINTER在那个.)

除非我忘记了什么,否则基本上都是WebGL的状态.它可能看起来很多,但我个人发现所有这些都非常有助于理解事情是如何运作的.没有那些你基本上被蒙住眼睛,不得不一直猜测,并按照教程告诉你必须调用函数的确切顺序,这对WebGL不起作用 - 只是因为有很多东西,但也有错误你可以做.


gma*_*man 5

Screenius答案非常完整.简洁的版本是

在WebGL 1.0中,统一是每个程序,纹理过滤和包装是每个纹理.其他一切都是全球性的.这包括所有属性和所有纹理单元.

粘贴了之前的一些答案

你可以想到这样的属性和纹理单元

gl = { 
   arrayBuffer: someBuffer, 
   vertexArray: {
     elementArrayBuffer: someOtherBuffer,
     attributes: [], 
   },
};
Run Code Online (Sandbox Code Playgroud)

当你打电话时,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;
   }
};
Run Code Online (Sandbox Code Playgroud)

当您调用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.
};
Run Code Online (Sandbox Code Playgroud)

纹理的工作方式类似

gl = { 
    activeTextureUnit: 0,
    textureUnits: [], 
};
Run Code Online (Sandbox Code Playgroud)

gl.activeTexture 设置你正在处理的纹理单元.

gl.activeTexture = function(unit) {
   this.activeTextureUnit = unit - this.TEXTURE_0;  // make it zero based.
};
Run Code Online (Sandbox Code Playgroud)

每个纹理单元既有TEXTURE_2DTEXTURE_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;
   }
};
Run Code Online (Sandbox Code Playgroud)

其余的是全局状态,如清晰的颜色,视口,混合设置,模板设置,启用/禁用等功能DEPTH_TEST,SCISSOR_TEST


只是一个侧面说明:如果启用扩展OES_vertex_array_objectvertexArray在上面的例子中成为自己的对象,您可以使用绑定bindVertexArrayOES.