【问题标题】:How do I use texSubImage2D to show sprites in webgl?如何使用 texSubImage2D 在 webgl 中显示精灵?
【发布时间】:2011-07-15 22:02:08
【问题描述】:

我可以通过调用 gl.texImage2D 成功显示我的整个精灵 (32x512):

gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, image);

它像我预期的那样被水平挤压,但至少呈现在屏幕上。我试图只显示工作表中的第一个 32x32 精灵,我假设我可以简单地使用 gl.texSubImage2D 来实现这种效果。我尝试用 texSubImage2D (修改参数)简单地替换 texImage2D,但我只是在屏幕上看到一个黑框。这是我正在使用的代码:

gl.texSubImage2D(gl.TEXTURE_2D, 0, 0, 0, 32, 32, gl.RGBA, gl.UNSIGNED_BYTE, image);

我是否遗漏了有关 texSubImage2D 实施的一些信息?我还有其他步骤吗?或者 texSubImage2D 不是制作精灵表的正确方法?

【问题讨论】:

    标签: textures webgl sprite-sheet


    【解决方案1】:

    texSubImage2D 不是您想要的功能。您遇到了三个问题:

    1. texSubImage2D 不会将image 的子集复制到 GL 纹理中。它在给定偏移处将整个image 复制到GL 纹理之上。
    2. texSubImage2D 只能修改现有的纹理数据,除非首先为 GL 纹理调用 texImage2D,否则会搞砸。
    3. 您对texSubImage2D 使用的调用样式需要一个像素数组,而不是HTMLImageElement

    这些方法有四种可能的签名:

    // These two accept the normal HTMLImageElement, etc. for the last param.
    
    texImage2D(enum target, int level,  enum internalformat, enum format,
      enum type, Object object);
    texSubImage2D(enum target, int level, int xoffset, int yoffset,
      enum format, enum type, Object object);
    
    // These two accept a Uint8Array[] of pixels as the last parameter, despite
    // being documented as wanting an ImageData object. The only reason these
    // have a width/height param is *because* they take a pixel array, and GL
    // doesn't know how large the image is.
    
    texImage2D(enum target, int level, enum internalformat, long width,
      long height, int border, enum format, enum type, Object pixels);
    texSubImage2D(enum target, int level, int xoffset, int yoffset,
      long width, long height, enum format, enum type, Object pixels);
    

    要使用图像的前 32x32 像素创建纹理,请改为执行以下操作:

    var spriteCanvas = document.createElement('canvas');
    spriteCanvas.width = 32;
    spriteCanvas.height = 32;
    
    var spriteContext = spriteCanvas.getContext('2d');
    spriteContext.drawImage(image, 0, 0);
    
    gl.bindTexture(gl.TEXTURE_2D, texture);
    gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, spriteCanvas);
    

    【讨论】:

    • 注意:我说那些需要Uint8Array[]。这并不完全正确:它们采用类型化数组,但类型取决于调用的 type 参数的值。
    • 完美运行,谢谢。我认为我必须在 GL 本身中执行此操作,但使用标准 HTML 元素对我来说更容易。
    • texSubImage2D 应该是正确的函数,但是 webgl1 在 glTexSubImage2D 周围有一个尴尬的 API。幸运的是,它已在 webgl2 中修复。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-03-26
    • 2015-02-08
    • 1970-01-01
    相关资源
    最近更新 更多