2011-11-11 4 views
5

Nei videogiochi viene applicato solo il colore per velocizzare il processo di caricamento. Dopo che le trame sono pronte, sostituiscono i colori correnti. C'è un modo per farlo in WebGL? Tutti i tutorial che ho visto finora mostrano solo come caricare a colori o texture (non uno dopo l'altro).Sostituisci colore con texture in WebGL

Immagino che il buffer per ogni forma debba essere modificato dopo che la sua trama è stata caricata completamente. Assumerei che questo sia digitato tramite una chiamata AJAX che la texture sia disponibile, quindi applicata tramite una sorta di funzione JavaScript. WebGL ha un modo integrato per farlo senza un complicato processo di caricamento delle immagini?

+0

Ok, dopo aver letto la mia domanda qualche mese dopo capisco cosa stavo chiedendo. Per rispondere pienamente alla mia domanda, leggi sotto. Per caricare trame e colori allo stesso tempo sono necessari due set di script x-frammento e x-vertice. Uno per colore e un altro per consistenza. Dal momento che vengono inseriti tramite il DOM, è sufficiente utilizzare l'ID shader corretto durante l'inizializzazione degli oggetti. Può essere a colori o texture Spero che questo aiuti le suole WebGL clueless là fuori come me. –

risposta

5

Nella maggior parte dei giochi che ho visto con il comportamento che descrivi, in genere inizieranno con una colorazione per vertice o con una trama a bassa risoluzione e "si fondono" sulla trama completa quando diventa disponibile. Quel tipo di transizione fluida è complicato, ma se tutto ciò che vuoi è un "pop" veloce da uno all'altro non dovrebbe essere troppo disturbo.

Il percorso di base che dovrei fare è creare un buffer di vertici che contenga sia le informazioni relative alla trama e al colore, sia due ombreggiatori diversi. Uno shader utilizzerà le informazioni sul colore, l'altro lo ignorerà e utilizzerà invece la texture. Dovresti segnalare alla mesh di iniziare a usare quella basata sulla trama non appena la trama è pronta.

Per quanto riguarda la rilevazione del carico di immagini, che non è difficile a tutti e non hanno nemmeno bisogno di AJAX per esso:

var image = new Image(); 
image.addEventListener("load", function() { 
    // Image is done loading, push to texture 
    gl.bindTexture(gl.TEXTURE_2D, texture); 
    gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, image); 
    // Set up any other state needed, such as switching the shader for the mesh 
}, true); 
image.src = src; 

io non sono sicuro di quanto più aiuto che posso dare su questo argomento, senza pubblicare blocchi di codice veramente grandi, ma se stai ancora lottando posso dettagliare alcune delle altre parti.

+0

Molto più semplice di quanto mi aspettassi. Quando dici "due diversi ombreggiatori", stai parlando dello shader iniziale che è impostato? Se è così, immagino che la funzione di disegno debba cambiare marcia e uscire dalla trama ad un certo punto. –

+0

Non sono del tutto sicuro di cosa intendi con lo "shader iniziale". Stai usando un tutorial o un framework specifico? – Toji

+0

Realmente creare da zero il mio motore WebGL, segue molte idee e principi dalle esercitazioni WebGL di Mozilla.Per shader iniziale intendo quello che si usa per afferrare e memorizzare elementi shader dal DOM quando si configura WebGL (se non ricordo male). –

0

In realtà è molto semplice, senza che WebGL abbia alcuna funzione specifica per questo, questo è qualcosa che si ottiene gratuitamente essendo una DOM API. Quando si caricano le immagini, è comunque necessario implementare il loro callback "onload" poiché il caricamento dell'immagine è asincrono. Quindi basta inserire il callback "onload", qualunque codice debba essere eseguito per passare dal colore solido alla texture.

1

L'approccio vorrei prendere è la seguente

loadTexture(url, initialColor) { 

    var tex = gl.createTexture(); 

    // start with a single color. 
    gl.bindTexture(gl.TEXTURE_2D, tex); 
    var pixel = new Uint8Array(initialColor); 
    gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 1, 1, 0, gl.RGBA, pixel); 

    // start loading the image 
    var img = new Image(); 
    img.src = url; 
    img.onLoad = function() { 

    // when the image has loaded update the texture.   
    gl.bindTexture(gl.TEXTURE_2D, tex); 
    gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, img); 
    gl.generateMipmap(gl.TEXTURE_2D); 
    } 
    return tex; 
} 

// Load a tree texture, use brown until the texture loads. 
var treeTexture = loadTexture("tree.png", [255, 200, 0, 255]); 
// Load a water texture, use blue until it loads. 
var waterTexture = loadTexture("water.jpg", [0, 0, 255, 255]); 

Questo è come la maggior parte dei campioni in http://webglsamples.googlecode.com lavoro anche se tutti default texture blu.

Si potrebbe facilmente estendere tale idea per utilizzare un colore a tinta unita, caricare una trama a bassa risoluzione, quindi quando finisce di caricare una trama ad alta risoluzione.

Nota: il codice sopra riportato presuppone che si stiano caricando trame power-of-2. In caso contrario, dovrai configurare correttamente i parametri della trama.