WebGL 不显示内容

WebGL not displaying content

我主要使用 C++ 进行开发,因此决定将我的一个项目编译为 WebAssembly 并在其上构建一个网站。因为我之前用C++写过一些3D-Engine,所以我决定在网站上使用WebGL。我已经翻译了我的着色器模板 class。我已经把问题简化为二维问题了。


任务

首先,我将描述我正在尝试做的事情。 我将渲染一个 2D FEM 网格,它由 FEM 元素组成,它是任何类型的多边形。这些多边形的节点包含我要显示的值。我已经编写了将多边形分解为三角形的代码。最初我只是试图渲染 二维三角形 并对其 节点值进行插值 .


着色器代码

我在 WebGL 中编写了一些模板着色器 class,它处理着色器的构建和编译,并且已从我的 C++ 3D 引擎中复制。由于代码本身有点长,我不会在这里 post 但最终会显示一个已执行的 OpenGL 命令列表。 我目前用来调试问题的着色器如下:

Vertex-Shader:

precision mediump float;
attribute vec2 position;
            
varying vec2 fragPos;
void main(){
   gl_Position = vec4(position,0,1.0);
   fragPos     = position;
}
            
---------------------------------------------------------------

Fragment-Shader:

precision mediump float;
varying vec2 fragPos;
            
uniform sampler2D elementValues;
uniform int elementValuesDimension;
            
void main(){
    gl_FragColor  = vec4(0.8,0.2,0.0,1.0);
}

如您所见,我不打算在此调试案例中进行任何插值,而只是尝试在我的片段着色器中添加一些偏红的颜色。


执行的命令

我继续使用 webgl-debug.js 来显示所有已完成的操作。对于这种情况,您可以看到顶点和索引与跨越 [0,0.6]x[0,0.6] 的简单四边形相匹配,它应该很好地位于剪辑 space.

这可以分为几个部分:

  1. 启用 uint32 作为索引
gl.getExtension(OES_element_index_uint)
  1. 为顶点坐标和索引创建两个缓冲区
gl.createBuffer()
gl.createBuffer()
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, [object WebGLBuffer])
gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, 0,1,2,0,2,3, gl.STATIC_DRAW)
gl.bindBuffer(gl.ARRAY_BUFFER, [object WebGLBuffer])
gl.bufferData(gl.ARRAY_BUFFER, 0,0,0,0.6000000238418579,0.6000000238418579,0.6000000238418579,0.6000000238418579,0, gl.STATIC_DRAW)
  1. 创建并编译着色器
gl.createShader(gl.VERTEX_SHADER)
gl.shaderSource(vertex_shader_src);
gl.compileShader([object WebGLShader]);
gl.getShaderParameter([object WebGLShader], gl.COMPILE_STATUS);
gl.createShader(gl.FRAGMENT_SHADER);
gl.shaderSource(fragment_shader_src);
gl.compileShader([object WebGLShader]);
gl.getShaderParameter([object WebGLShader], gl.COMPILE_STATUS);

gl.createProgram()

gl.attachShader([object WebGLProgram], [object WebGLShader])
gl.attachShader([object WebGLProgram], [object WebGLShader])
gl.linkProgram([object WebGLProgram])
gl.validateProgram([object WebGLProgram])
  1. 获取制服(未使用)的位置以及属性的位置
gl.getUniformLocation([object WebGLProgram], elementValues)
gl.getUniformLocation([object WebGLProgram], elementValuesDimension)
gl.getAttribLocation([object WebGLProgram], position)
  1. 验证链接是否有效
gl.getProgramParameter([object WebGLProgram], gl.LINK_STATUS)
  1. 主渲染循环。最初清除显示的东西
gl.clearColor(0.5, 0.5, 0.5, 1)
gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT)
gl.disable(gl.CULL_FACE)
gl.viewport(0, 0, 700, 600)
  1. 激活着色器并绑定缓冲区
gl.useProgram([object WebGLProgram])
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, [object WebGLBuffer])
gl.bindBuffer(gl.ARRAY_BUFFER, [object WebGLBuffer])
  1. 将顶点连接到第一个属性
gl.vertexAttribPointer(0, 2, gl.FLOAT, false, 0, 0)
  1. 渲染调用。
gl.drawElements(gl.TRIANGLES, 4, gl.UNSIGNED_INT, 0)

可悲的是,当执行上述命令时,除了灰色屏幕外我什么都看不到:

我很高兴能得到任何帮助!

您好 芬恩

多亏了 teddybeard 和我在这个问题上花费的时间比我希望的多得多,出现了两个问题:

  1. l.bufferData(gl.ELEMENT_ARRAY_BUFFER, 0,1,2,0,2,3, gl.STATIC_DRAW) 包含 6 个顶点,但 drawElements 命令只取了 4 个值。这显然是一个错误,但应该至少渲染了两个三角形之一。
  2. 其次,我忘记在着色器中启用顶点属性。 gl.enableVertexAttribArray(1); 解决了问题。