2013-11-01 94 views
13

如何測試WebGLTexture對象是否「完整」?WebGL - 等待紋理加載

目前,我得到這個消息: [WebGLRenderingContext]RENDER WARNING: texture bound to texture unit 0 is not renderable. It maybe non-power-of-2 and have incompatible texture filtering or is not 'texture complete'

我得到這樣的警告,因爲渲染循環正在嘗試使用紋理的形象完成加載之前,所以如何解決呢?

+1

感謝您提出這個問題,我一直在這些控制檯消息中進行一段時間的實驗。 :-) –

回答

18

來解決這個問題最簡單的方法是使在創建時一個1x1的質感。

var tex = gl.createTexture(); 
gl.bindTexture(gl.TEXTURE_2D, tex); 
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 1, 1, 0, gl.RGBA, gl.UNSIGNED_BYTE, 
       new Uint8Array([255, 0, 0, 255])); // red 

然後,當圖像加載時,您可以用圖像替換1x1像素紋理。沒有標誌需要,你的場景將用你選擇的顏色進行渲染,直到圖像加載完畢。

var img = new Image(); 
img.src = "http://someplace/someimage.jpg"; 
img.onload = function() { 
    gl.bindTexture(gl.TEXTURE_2D, tex); 
    gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, img); 

    // then either generate mips if the image uses power-of-2 dimensions or 
    // set the filtering correctly for non-power-of-2 images. 
    setupTextureFilteringAndMips(img.width, img.height); 
} 

只是爲了救人運行到他們最有可能會碰到下一個問題的麻煩起見,WebGL的需要MIPS或它需要不需要MIPS過濾。最重要的是,它需要尺寸爲2的冪(即1,2,4,8,...,256,512等)的紋理才能使用mips。所以,在加載圖片時,您最有可能需要設置過濾器來正確處理此問題。

function isPowerOf2(value) { 
    return (value & (value - 1)) == 0; 
}; 

function setupTextureFilteringAndMips(width, height) { 
    if (isPowerOf2(width) && isPowerOf2(height) { 
    // the dimensions are power of 2 so generate mips and turn on 
    // tri-linear filtering. 
    gl.generateMipmap(gl.TEXTURE_2D); 
    gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR_MIPMAP_LINEAR); 
    } else { 
    // at least one of the dimensions is not a power of 2 so set the filtering 
    // so WebGL will render it. 
    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.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR); 
    } 
} 
+1

這是一個非常好的技巧,在不添加測試/布爾值的情況下襬脫警告。問題仍然是,如果出於某種原因紋理不被認爲是「完整的」,會發生什麼情況。從texImage2D返回足夠的條件以具有「完整」紋理? –

+0

我不能變紅!紋理總是白色的?看到http://jsfiddle.net/aXcs8/2/ –

+0

我的不好。對於紅色,1像素單像素紋理的值應該是'[255,0,0,255]'。修正它上面。至於紋理完成,我會更新答案 – gman

1

要解決該問題,請使用一些布爾值來判斷圖像是否已加載。

var loaded = false, 
    texture, 
    img = new Image(); 

img.onload = function() { 
    texture = gl.createTexture(); 
    // . . . 
    loaded = true; 
}; 
img.src = "path/myimage.jpg"; 

// render-loop 
function render() { 
    if(loaded) { 
     // use texture 
    } 
    else { 
     // not loaded yet 
    } 
} 
+1

管理我自己的布爾值將告訴我是否已經調用了一組API(如texImage2D)。但它不會告訴它是否成功創建了「完整」紋理?分別追蹤布爾值可能是一種痛苦,所以我修改了這個來存儲WebGL紋理對象中的布爾值 - > texture.isLoaded = false; –

0

我試圖將我的HTML5/JS應用程序部署到使用Cordova的Android手機時遇到此問題。首先,我認爲我的問題是我的spritesheet /紋理圖集太大,無法加載移動GPU。所以我batch shrank all the images using ImageMagick's mogrifymogrify -resize 256x256 *.png),但仍然有問題。這一步仍然是必要的(因爲我的8000x8000 .png是太多的手機)。

然後我用console.log(navigator.userAgent)來檢查我的瀏覽器版本,看到使用的Chromium比我的瀏覽器舊。所以我重新安裝了Crosswalk plugin,一切都很好。

cordova plugin rm cordova-plugin-crosswalk-webview 
cordova plugin add cordova-plugin-crosswalk-webview