2016-10-24 14 views
0

私はRGBA値を持つUint8Arrayと、画像の一部が更新された情報を受け取りました。この生のビットマップ情報をキャンバスに戻す最も簡単な方法は何ですか?私は、アレイと設定された画素情報かかわらず、手動でループに2Dレンダリングコンテキストを使用しているが、これは非常に遅いです:Uint8Arrayをキャンバスにレンダリングする最も速い方法

let imageData = new ImageData(1920, 1080); 
for (var i=0;i < args.frameBuffer.length; i+=4) { 
    imageData.data[i] = args.frameBuffer[i]; 
    imageData.data[i+1] = args.frameBuffer[i+1]; 
    imageData.data[i+2] = args.frameBuffer[i+2]; 
    imageData.data[i+3] = args.frameBuffer[i+3]; 
} 
context.putImageData(imageData, 0, 0, args.dirtyX, args.dirtyY, args.dirtyWidth, args.dirtyHeight); 

これを行うには、より効率的な方法だろうか? WebGLは2Dコンテキストよりも優れていますか?ネイティブまたはThree.jsのようなものを介して?

+0

で繰り返すことができるもちろん

let imageData = new ImageData(args.frameBuffer, args.dirtyWidth, args.dirtyHeight); context.putImageData(imageData, args.dirtyX, args.dirtyY); 

ような何かを行うことができればen-US/docs/Web/API/WebGL_API/Tutorial/Using_textures_in_WebGL)を参照してください。特に、[texImage2D](https://developer.mozilla.org/en/docs/Web/API/WebGLRenderingContext/texImage2D)メソッド。 – mlkn

+1

型付き配列間でデータを移動するには、 'imageDataTo.data.set(imageDataFrom.data)'を使用します。データの一部(rect)をコピーするには、 'set'と' subArray'を使って行を移動します。各行(imageDataはid) 'idTo.data.set(idFrom.data.subArray(yFrom * idFrom.width + xFrom)* 4、width)、(yTo * idTo.width + xTo)* 4)' If 'data32 = new Uint32Array(imageData.data.buffer)'を使って1つの読み書きでピクセルを扱うためにUint32Arrayを作成することができる各ピクセルをチェックする必要があります。little/bigエンディアンが動作するように注意します。またキャンバスはイメージですので、 'context.drawImage(canvasFrom、...'キャンバスからキャンバスにレンダリングすることができます。 – Blindman67

答えて

0

gl.TexSubImage2Dを使用してテクスチャを更新し、テクスチャ全体をブリットすることができます。しかし、TexSubImage2Dは、次のフレームのテクスチャを更新する前に、前のレンダリングを完了するまで待機しなければならないため、パフォーマンス上の問題があります。

より良い方法は、webglにpreserveDrawingBufferビットを使用して、TexImage2Dでラウンドロビン方式で2つのテクスチャを使用することです。ダーティ領域のみをレンダリングするには、ダーティ座標に基づいてDrawArraysの頂点データを設定する必要があります。

WebGLはまだ多くのデータをコピーする必要がありますが、これらのコピーパスはputImageDataよりも最適化されている可能性があります。しかし、ドライバがしばしばテクスチャ画像が静的であり、複数のレンダリングに使用されるユースケースに対して最適化することが多いため、webglが遅くなる可能性がある深刻な危険があります。これにより、レンダリングは高速になりますが、テクスチャデータのアップロードは遅くなります。

高価なテクスチャアップロードの問題を解決するにはOpenGLには複数の拡張機能があり、高速の画像アップロードをサポートしていますが、レンダリングは少し遅くなります。これらの拡張子があまりにも悪いとwebglにとって実用的ではありません。

しかし、あなたは完全にフレームバッファーを受け取っているように見えますが、たびたびに部分的にしか更新されません。

あなたは[テクスチャ](https://developer.mozilla.org/を見てみましょう、あなたの現在のインターフェースが

let imageData = new ImageData(args.frameBuffer, 1920, Math.floor((args.frameBuffer.length + 4*1919)/(4*1920))); 
context.putImageData(imageData, 0,0, args.dirtyX, args.dirtyY, args.dirtyWidth, args.dirtyHeight); 
+0

私はframeBuffer全体を使用していたことを指摘してくれてありがとうございます。 – sqwk

関連する問題