无法弄清楚为什么WebGL不会绘制三角形

Fly*_*del -2 javascript webgl

我不确定这是否是正确的协议,但我有一个项目位于:

https://github.com/mkarbowski/angry-bears

这是我在WebGL游戏中的尝试.我曾经使用过OpenGL ES 2.0与android,所以我认为WebGL不可能有太大的飞跃.但整个无法调试脚本是杀了我.更不用说缺乏有意义的错误了.

gma*_*man 7

首先,你得到GL错误.找出原因可能会很好.

您可以使用"调试上下文"来查找它们.请参阅WebGL Wiki中的此条目

我添加了包含在那里引用的文件,并将此行添加到engine.js第26行的代码中

gl = WebGLDebugUtils.makeDebugContext(gl, function(err, funcName, args) {
  throw WebGLDebugUtils.glEnumToString(err) + ": " + funcName;
});
Run Code Online (Sandbox Code Playgroud)

在gltexture.js中你有这样的代码

texture = gl.createTexture();
gl.bindTexture(gl.TEXTURE_2D, this.texture);
Run Code Online (Sandbox Code Playgroud)

this.texture没有定义.也许你想在这之前定义它就行了?

this.texture = gl.createTexture();
Run Code Online (Sandbox Code Playgroud)

然后用于加载图像的onload回调使用"this",但在回调的上下文中没有"this".解决这个问题的最简单方法是声明另一个变量"that"或者创建一个属性并使用bind.

that = this;  // define that
image = new Image();
image.onload = function() {
  loaded = true;
  gl.bindTexture(gl.TEXTURE_2D, that.texture);  // using that
  return gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, image);
};
Run Code Online (Sandbox Code Playgroud)

这摆脱了错误

遵循代码.接下来的事情,而不是检查纹理是否加载GLUtils.useTexture我刚刚添加

    gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 1, 1, 0, 
                  gl.RGBA, gl.UNSIGNED_BYTE, 
                  new Uint8Array([255,0,0,255]));
Run Code Online (Sandbox Code Playgroud)

对于GLTexture所以它总是以1像素纹理开始,当真实纹理加载时,它将被替换.

接下来,你的TriangleTest.draw每帧都在创建一个缓冲区.可能不是你想要的.

然后我开始在你的代码周围添加console.log.我将清晰的颜色改为随机

 gl.clearColor(0, 0, Math.random(), 1);
Run Code Online (Sandbox Code Playgroud)

这样我就可以看到该程序正在运行.

我发现你在useCamera中传递的矩阵没有投影矩阵.我将它设置为标识,然后更改顶点,使它们在剪辑空间中,只是为了获得屏幕前的内容.那有一个黑色的三角形.

所以我查看了你的GLUtils.useTexture.在其中,您调用texture.getTexture(),这是一个不存在的函数.把它改成

gl.bindTexture(gl.TEXTURE_2D, texture.texture)
Run Code Online (Sandbox Code Playgroud)

现在它呈现出一些东西.

其他随机评论

  • 使用开发工具(在Chrome或Safari中).在Firefox中使用Ctrl-Shift-J或Cmd-Shift-J或类似工具
  • 有时,WebGL Inspector会很有帮助.
  • console.log和console.error是你的朋友.console.error为您提供堆栈跟踪,至少在Chrome中.
  • 停止使用setTimeout.而是使用requestAnimationFrame.一个优点是,如果你的代码死了,它就会停止.使用setTimeout,浏览器将继续调用和调用,使其难以调试.另一个优点是,当您的页面不是前面的选项卡时,它会显示您不关心用户的系统.
  • 打印和检查所有WebGL调用会很有帮助.按照上面的调试上下文的例子,很容易编写一个包装器,(a)打印每个调用,(b)检查没有未定义的参数.(例如,参见WebGL Wiki)
  • 如果您使用Chrome,请尝试Chrome 20(Chrome Canary).它为WebGL错误提供了一些错误消息.Firefox也是如此.

祝你的项目好运