0
votes

Hi I hava jpeg compressed data stored in Uin8Array . I read about texture in Webgl . All Link what i saw initialize texture after loading image ( created by jpeg data , image.src = "some data" image.onload ( load texture ) ) . But this is asynchronus process . This process works fine . But can i use function compressedTexImage2D(target, level, internalFormat, width, height, border, data) internel format should be related to jpeg and data will be in form of compressed jpeg format ( width or height is not in form of pow of 2 ) so that whole process should be synchronous ? Or any other method in webgl that take jpeg compressed data directly without loading an image ?

1

1 Answers

2
votes

So here is the bad news currently as of September 2012 WebGL does not actually support compressedTexImage2D. If you try calling the function it will always return an INVALID_ENUM error. If you are curious here is the section of the specification that explains it.

Now the some what good news is that you can create a texture from a Uint8Array of jpeg data. I'm not sure how to do this synchronously, but maybe this code will help anyways.

Basically we have to convert the original Uint8Array data into a base64 string, so we can create a new image with the base64 string as the image source.

So here is the code:

function createTexture(gl, data) {
    var stringData = String.fromCharCode.apply(null, new Uint16Array(data));
    var encodedData = window.btoa(stringData);
    var dataURI = "data:image/jpeg;base64," + encodedData;

    texture = gl.createTexture();
    texture.image = new Image();

    texture.image.onload = function () {
        gl.bindTexture(gl.TEXTURE_2D, texture);
        gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, true);
        gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, texture.image);
        gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
        gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
        gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
        gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
        gl.bindTexture(gl.TEXTURE_2D, null);
    };

    texture.image.src = dataURI;

    return texture;
}

I have a demo of the function here. To keep the file small I'm only using a 24x24 pixel jpeg. Just in case you are wondering, the function also works for jpeg's with non power of 2 heights/widths.

If you want to see the full source code of the demo look here.