2013-11-01 26 views
13

Come si verifica se l'oggetto WebGLTexture è "completo"?WebGL - attendere il caricamento della trama

Attualmente ottengo questo messaggio: [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'

ottengo questo avviso perché il render-loop sta cercando di usare la trama prima della sua immagine è terminato il caricamento, così come riparare questo?

+1

Grazie per avermelo chiesto, ho vissuto per un po 'con questi messaggi di console nei miei esperimenti. :-) –

risposta

18

Il modo più semplice per risolvere il problema che è quello di fare una texture 1x1 al momento della creazione.

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 

Quindi, quando l'immagine viene caricata, è possibile sostituire la trama da 1x1 pixel con l'immagine. Nessun flag necessario e la tua scena verrà renderizzata con il colore che hai scelto fino al caricamento dell'immagine.

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

Solo per il gusto di salvare la gente la fatica di correre nel prossimo problema che stanno molto probabilmente andando a correre in, WebGL richiede MIPS o Richiede filtraggio che non necessita di MIPS. Per di più richiede trame con dimensioni che hanno una potenza di 2 (cioè 1, 2, 4, 8, ..., 256, 512, ecc.) Per usare i mips. Quindi, quando si carica un'immagine, è molto probabile che si voglia impostare il filtro per gestirlo correttamente.

+1

Questo è un trucco molto carino, eliminare gli avvisi senza aggiungere un test/booleano. Rimane la domanda che cosa succede se per qualche motivo la trama non è considerata "completa" per qualche motivo. Restituisce da texImage2D una condizione sufficiente per avere una trama 'completa'? –

+0

Non riesco a ottenere il rosso! La trama è sempre bianca? vedi http://jsfiddle.net/aXcs8/2/ –

+0

Il mio male. Il valore della trama di 1 pixel di un pixel dovrebbe essere '[255, 0, 0, 255]' per rosso. Risolto il problema sopra. Per quanto riguarda la texture completa aggiornerò la risposta – gman

1

Per risolvere il problema, utilizzare un valore booleano per indicare se l'immagine è stata caricata.

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

Gestire il mio booleano mi dirà se è stato chiamato il set di API, come texImage2D. Ma non dirà se è riuscito a creare una trama 'completa'? Tracciare separatamente i booleani può essere un problema, quindi ho modificato questo per memorizzare il valore booleano all'interno dell'oggetto trama WebGL -> texture.isLoaded = false; –

0

Ho riscontrato questo problema durante il tentativo di distribuire la mia app HTML5/JS su un telefono Android utilizzando Cordova.

Inizialmente, ho pensato che il mio problema era che il mio atl di spritesheet/texture era troppo grande per essere caricato dalla GPU mobile. Quindi, I (mogrify -resize 256x256 *.png), ma continuavo a riscontrare problemi. Questo passaggio era comunque necessario (come il mio 8000x8000 .png era troppo per i telefoni).

Quindi ho utilizzato console.log(navigator.userAgent) per verificare la versione del mio browser e ho visto che Chromium utilizzato era più vecchio del mio browser. Quindi ho reinstallato lo Crosswalk plugin e tutto sta funzionando bene.

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