如何使用texSubImage2D在webgl中显示精灵?

时间:2011-03-15 15:49:44

标签: textures webgl sprite-sheet

我可以通过调用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不是做精灵表的正确方法吗?

1 个答案:

答案 0 :(得分:11)

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

  1. texSubImage2D不会将image的子集复制到GL纹理中。它在给定偏移量的GL纹理顶部复制image的整体。
  2. texSubImage2D只能修改现有的纹理数据,除非为GL纹理首先调用texImage2D,否则会搞乱。
  3. 您用于texSubImage2D的调用样式需要一个像素数组,而不是HTMLImageElement
  4. 这些方法有四种可能的签名:

    // 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);