2016-08-20 107 views
0

首先,我想弄清楚,我是一個絕對的初學者,當談到帆布& three.js所在畫布上繪製的圖像,並返回作爲紋理

我已經採取了現有項目並且正在嘗試做一些小的修改,即將圖像繪製到紋理上而不是僅寫入文本。我希望紋理具有設置的背景顏色,並試圖在其上繪製透明png圖像。

我試圖修改的方法返回一個紋理用於​​另一個函數,該函數目前正在做更多的東西,我可能無法在這裏解釋。

我試過幾種方法,我似乎無法得到我想要的行爲。

方法#1

在這種方法中,我得到的背景顏色,但我沒有得到的圖像顯示

   var ts = calc_texture_size(size + size * 2 * margin) * 2; 
       canvas.width = canvas.height = ts; 
       context.fillStyle = back_color; 
       context.fillRect(0, 0, canvas.width, canvas.height); 
       var img = new Image(); 
       function drawIcon() { 
        context.drawImage(img,0,0); 
       } 
       img.onload = drawIcon(); 
       img.src = "img/test.png"; 

       var texture = new THREE.Texture(canvas); 
       texture.needsUpdate = true; 
       return texture; 

方法2

做一些後研究,似乎我應該使用TextureLoader,但我無法弄清楚如何在畫布上繪製顏色/形狀。在這種情況下,圖像獨立顯示,沒有任何背景顏色。

var imgTex = new new THREE.TextureLoader().load("img/test.png",function(t){ 
        texture.map = imgTex; 
       }); 
       texture.needsUpdate = true; 
       return texture; 

我怎樣才能成功地繪製在彩色背景上的圖像,並返回它作爲其他功能使用紋理?

+1

[HERE](https://jsfiddle.net/2pha/e6rbt3r4/)是在畫布上合併2個圖像並將其應用爲紋理的示例 – 2pha

回答

1

您的問題與JavaScript事件處理有很大關係,就像我昨天回答的問題:How to make a Json model auto-rotates in the scene?。你永遠不可能有一個「onload」,然後期待爲你返回變量 - 變量只是在執行回調之前才被定義。相反,您需要將工作推遲到回調,或者在其他地方繼續輪詢變量,直到定義爲止。

更具體到你的問題,但:

有了辦法#1,您所發送的質地回填到GPU,再呈現更多的內容,但沒有更新這是後發送到GPU紋理該圖像已加載。將texture.needsUpdate = true;移至您的drawIcon()可能會在此解決。未經測試的例子:

var ts = calc_texture_size(size + size * 2 * margin) * 2; 
var img = new Image(); 
var texture = new THREE.Texture(canvas); 

canvas.width = canvas.height = ts; 
context.fillStyle = back_color; 
context.fillRect(0, 0, canvas.width, canvas.height); 
img.onload = function() { 
    context.drawImage(img,0,0); 
    texture.needsUpdate = true; 
}; 
img.src = "img/test.png"; 
return texture; 

注意:您應該始終在JavaScript中的範圍,讓事情更清晰的開始定義var變量... drawIcon()有權訪問texture變量,雖然它看起來並不喜歡,因爲它似乎它從你的示例代碼後它被定義,但是這不是JavaScript的是如何工作的:var變量始終是全局的,以他們在規定的範圍內

隨着做法#2,您需要在紋理上繪製一些額外的工作,將紋理轉回到畫布並將生成的畫布發送到GPU。 ImageLoaderTexture文檔結合提示您需要如何繪製從TextureLoader獲得的圖像。

兩種方法結合起來,應該是這樣的(也完全未經測試):

var ts = calc_texture_size(size + size * 2 * margin) * 2; 
canvas.width = canvas.height = ts; 
context.fillStyle = back_color; 
context.fillRect(0, 0, canvas.width, canvas.height); 

var textureLoader = new THREE.TextureLoader().load(
    "img/test.png", 
    function(texture) { 
     var image = texture.image; 
     context.drawImage(texture.image, 0, 0 0); 
     var texture = new THREE.Texture(canvas); 
     texture.needsUpdate = true; 
     // Now do something with texture, like assigning it 
     // to your material 
    } 
); 

注意:不要忘記使用數據的URL,如果你需要畫的圖像較小,則這可以作爲一個「data:」URL包含在你的代碼中,這樣可以避免去服務器並等待它加載到事件處理程序中。例如在MDN