了解WebGL状态

时间:2015-02-19 11:07:24

标签: webgl

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

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

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

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

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

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

一个基本问题,但很难找到信息。

2 个答案:

答案 0 :(得分: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);

现在你不必通过这个巨大的清单来找到那些。但是如果你编写一个框架,并想要了解状态,你也可能想要使用所有其他框架。

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)

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)

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

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返回一个缓冲区,因此看起来很相关。缓冲区本身并不比普通的ArrayBuffer更令人兴奋。内容不是javacript,而是远在gpu land,努力工作以支持家里的家庭。

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)

getSupportedExtensions()

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

getVertexAttribOffset(GLuint index, GLenum pname)

(pname必须是VERTEX_ATTRIB_ARRAY_POINTER。)

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

答案 1 :(得分:5)

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_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;
   }
};

其余为全局状态,如清晰颜色,视口,混合设置,模具设置,启用/禁用内容,例如DEPTH_TESTSCISSOR_TEST


只是旁注:如果您启用the extension OES_vertex_array_object,上面示例中的vertexArray会成为您自己的对象,您可以与bindVertexArrayOES绑定。