2011-03-15 17 views
7

puedo mostrar todo mi Sprite (32x512) con éxito con este llamado a gl.texImage2D:¿Cómo uso texSubImage2D para mostrar sprites en webgl?

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

Está aplastado horizontalmente, como esperaba, pero hace que en la pantalla por lo menos. Intento mostrar solo el primer sprite de 32x32 en la hoja y asumí que simplemente podría usar gl.texSubImage2D para lograr este efecto. Probé un reemplazo simple de texImage2D con texSubImage2D (con parámetros modificados) pero acabo de obtener un recuadro negro en la pantalla. Aquí está el código que estoy usando:

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

Me estoy perdiendo algo acerca de la implementación de texSubImage2D? ¿Hay algún otro paso que deba hacer? ¿O texSubImage2D no es la forma correcta de hacer hojas de sprites?

Respuesta

10

texSubImage2D no es la función que desea. Que se está ejecutando en tres problemas:

  1. texSubImage2D no copia un subconjunto de image en la textura GL. Copia la totalidad de image encima de la textura GL en un desplazamiento dado.
  2. texSubImage2D solo se pueden modificar los datos de textura existentes, y se estropearán a menos que se haya llamado primero a texImage2D para la textura GL.
  3. El estilo de llamada que está utilizando para texSubImage2D espera una matriz de píxeles en lugar de HTMLImageElement.

Hay cuatro firmas posibles para estos métodos:

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

para crear una textura usando las primeras 32x32 píxeles de la imagen, hacer algo como esto en su lugar:

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); 
+0

Nota: I dijo que esos toman un 'Uint8Array []'. Eso no es del todo correcto: toman una matriz tipada, pero el tipo depende del valor del parámetro 'type' para las llamadas. –

+0

Funciona perfectamente, gracias. Supuse que tendría que hacerlo en GL, pero el uso de elementos HTML estándar es mucho más fácil para mí. – Nick