2017-03-12 2 views
0

私がしようとしていることの要件のために、私はピクセル用に独自のカスタムクラスを用意する必要があります。私が持っている各画素について:高速カスタムピクセルフォーマットを作成するには

byte red 
byte green 
byte blue 
int brightness 
int X 
int Y 

Iは、座標を必要とするので、私は私が描画する必要の画素からのみ成るアレイを作ることができます。たとえば、私は斜めに移動する線を持っている場合、私は描画する必要があるピクセルの1次元配列を持っているだけです。私は残りのピクセルをスキャンする必要はないので、不必要なスキャンを避けることができます。私の現在のケースでは、ポリゴンがたくさんあります。ポリゴンは特定の順序で特定の方法で画像に適用する必要があります。これはゲームエンジン用ですので、私はピクセルをスキャンすることを避けなければなりません。とにかく使用されません。

しかし、そのようなピクセルクラスのデータを持つと、処理が遅くなります。本当に遅い。おそらく、ビットマップが作成されるデフォルトのピクセル形式よりも数百倍遅いでしょう。それに加えて、ピクセルを変更すること自体が非常に遅いです。

各ピクセルの色、明るさ、座標に関するすべての情報を保存しながら、ピクセルの作成と操作を高速化するにはどうすればよいですか? サイド質問:System.Drawingのピクセル形式がどのように機能するのか説明されていますか?

答えて

0

ストライドパターンでアクセスする多くのクラスインスタンスの代わりに、[]をオーバーロードしてシングルトンの内部配列にアクセスできます。したがってpixels[n].Xは、 "pixels"オブジェクトの内部配列または構造体の配列にアクセスし、その中からXを速く取得します。

構造体のすべてのピクセル属性を持ちます。その構造体にアクセスするには、ピクセルクラスからのインデックスを使用します。その構造体を構造体配列に配置します。

structLayoutAttributeを使用すると、構造体を適切なサイズ(および配置)でパックして、アクセスパフォーマンスを向上させることができます。

構造体のフィールドを並べ替えると、すべてのデータを(おそらく)少ないメモリ操作で読み込むことができます。

関数内のすべての属性を使用すると便利です。


代わりの構造体の配列は、すべての画素について(あなたのゲームエンジンのアロケータによって与えられる)アンマネージメモリ領域を使用し、移行のオーバーヘッドをelliminateする大きな塊で読むことができます。(ちょうど1で全体の構造体を読み取ることができますまたは2つの固有のロード命令)。ポインタと安全でないコンテキストを使用して、より大きなチャンクで更新する(または一時的な結果を蓄積する)

int X 
int Y 
int brightness 
byte red 
byte green 
byte blue 
byte alpha 

は、16バイトの構造体境界に収まる必要があります。


あなたが使用しようとしている場合は、色とは別に座標、またはいくつかの属性は、常に使用されません、それは次の画素のために反復する一つ少なくストライド要素になりますので、あなたはそれを切り離し、プリミティブの配列として使用する必要があります。 XとYを色ではなくいくつかの空間検索アルゴリズムで使うつもりならば、XとYを持つ構造体の別の配列(クラスではない)にXとYを再グループ化して、色属性が得られないようにすることができますパフォーマンスの面であなたの方法で


あなたがXにアクセスする、あなたの代わりにpixels.X[i]を試してみて、(配列またはアンマネージメモリで)最高速度を有することができるので、セッターゲッターが50%の性能をコストとしても

public class MyPixel{ 
    public float X{ 
       get{ /* access an array or 
         array of structs or 
         unmanaged memory */} 
       set{ /* same */} 
    } 

    // for unrolled loops 
    public static void BatchUpdateXY(float[] source,int pixelStart,int pixelEnd) 
    { /* copy from source */} 
} 

純粋なC++配列を上位ソリューションに追加すると、新しいピクセルを追加するのが難しくなります。そのため、C++側でベクターなどのコンテナが必要な場合があります。

0

これは、実際に描画関数が最適化された方法(ハードウェアアクセラレーション)で行っていることです。独自の描画関数が必要な理由(つまり、各ピクセルを計算して対角線またはポリゴンを作成する)が不明な場合

各ピクセルを計算して保存する代わりに、接続が必要な点だけを保存してから、作業を行うために描画関数を呼び出すことができますか?

実際にこれを行う必要がある場合は、処理するほうがはるかに高速になる32ビットRGBA整数のサイズ幅*高さの配列またはベクトルを作成するのが最善の方法でしょう。

そして実際はビットマップなので、メモリにビットマップを作成し、標準の描画関数を使ってそのビットマップ(RGBAポイントを持つ配列)に線を描画します。最後にすべてのピクセルを一度移動すると、1D配列でこれを行うよりもはるかに高速になります。これは、検索したり、ソートしたり、成長させたりする必要があります。

「0以外の」ピクセルをすべて一度に移動するには、TransparentBlt()を使用することもできます。

関連する問題