• 検索結果がありません。

テクスチャ間のデータのコピー

ドキュメント内 _openglcl (ページ 126-130)

1

代入が確認できたから、次にテクスチャ間でデータの単純なコピーを確認する。Cのプ

2

ログラムに表すならば、2次元配列 xzについて

3

z[i][j] = x[i][j];

4

という実行である。

5

GPU内のデータの流れを図4.17のように設定する。まず、ホストプログラムによって

6

フラグメントシェーダープログラム内のテクスチャ x を適当な初期値でセットアップす

7

る。この方法は前章の通りであり、4.1.4節の入出力兼用テクスチャRWTexture2Dでそれ

8

を行う。次に、そのテクスチャの内容を出力テクスチャへ画素毎に格納すればよい。具体

9

的には以下の通りである。

10

4.3.1 ホストプログラムの変更

11

まず、プログラムの構成上、以下の大域変数を追加宣言しておく。

12

RWTexture2D *texXp;

RGBA x[height][width];

void initData() {

Position2D pos[NUM_POINTS];

pos[0].x = -1.0; pos[0].y = -1.0;

pos[1].x = +1.0; pos[1].y = -1.0;

pos[2].x = +1.0; pos[2].y = +1.0;

pos[3].x = -1.0; pos[3].y = +1.0;

ArrayBuffer ab((float*)pos,2,NUM_POINTS);

sp->bindArrayBuffer("position",&ab);

for(int h = height-1; h >= 0; h--){

for(int w = 0; w < width; w++){

x[h][w].r = w+h+0.1; // 設定値は任意でよい。

x[h][w].g = w+h+0.2;

x[h][w].b = w+h+0.3;

x[h][w].a = w+h+0.4;

} }

texXp = new RWTexture2D(1,x,width,height); // 入力用テクスチャ texZp = new RWTexture2D(0,NULL,width,height); // 出力用テクスチャ sp->bindTextureR("tx",texXp); // GPUへデータを転送

sp->bindTextureW(texZp); // テクスチャをフレームバッファと接続 sp->setFloat("width",width); // テクスチャの幅をシェーダーに渡す sp->setFloat("height",height); // テクスチャの高さをシェーダーに渡す

}

図4.18: コピーのためのinitData() これを用いて、図4.18initData()では、

1

1. 配列 xの適当な初期値を代入し、

2

2. 入力用テクスチャオブジェクトを xを用いて生成し、

3

3. このオブジェクトをポインタtexXp に保持する。

4

4. さらにこのオブジェクトをテクスチャunifrom変数 tx に結びつける。

5

また、フラグメントシェーダー内での処理にテクスチャの幅、高さが必要になるため、

6

sp->setFloat("width",width);

7

sp->setFloat("height",height);

8

void showResults()

{

RGBA result[height][width];

texZp->readData(result,width,height);

for(int h = height-1; h >= 0; h--){

for(int w = 0; w < width; w++){

printf("%d %d r : %7.3f %7.3f\n",

w, h, x[h][w].r, result[h][w].r);

printf("%d %d g : %7.3f %7.3f\n",

w, h, x[h][w].g, result[h][w].g);

printf("%d %d b : %7.3f %7.3f\n",

w, h, x[h][w].b, result[h][w].b);

printf("%d %d a : %7.3f %7.3f\n",

w, h, x[h][w].a, result[h][w].a);

} }

}

図4.19: コピー確認のためのshowResults()

で、それらをシェーダー内のunifrom変数 widthheightへ渡しておく。

1

次に、関数showResults()を図4.19のように作り、入力テクスチャの各配列要素の値

2

と出力用テクスチャから得られた各配列要素の値の比較を行うこととする。

3

4.3.2 フラグメントシェーダープログラムの変更

4

フラグメントシェーダープログラムは図4.20のように変更する。ここに、テクスチャ

5

tx にアクセスするときの座標値の計算式が以下であることに注意する。

6

vec2(gl FragCoord.x/width, gl FragCoord.y/height)

7

既に述べたように、gl FragCoordの値の範囲は以下 [0,width]×[0,height]

であり、前章で述べたように、テクスチャ座標の範囲は [0,1]×[0,1]

#version 120

uniform sampler2D tx;

uniform float width;

uniform float height;

void main(void) {

vec2 texCoord = vec2(gl_FragCoord.x/width,gl_FragCoord.y/height);

gl_FragColor = texture2D(tx,texCoord);

}

図 4.20: コピーのためのフラグメントシェーダープログラム

4.3.3 実行結果

1

showResults()の実行結果は以下の通りとなり、コピーは正しく行われていることが分

2

かる。

3

0 6 r : 6.100 6.100

4

0 6 g : 6.200 6.200

5

0 6 b : 6.300 6.300

6

0 6 a : 6.400 6.400

7

1 6 r : 7.100 7.100

8

中略

9

3 0 a : 3.400 3.400

10

4 0 r : 4.100 4.100

11

4 0 g : 4.200 4.200

12

4 0 b : 4.300 4.300

13

4 0 a : 4.400 4.400

14

ホストプログラム

バーテックス シェーダー プログラム

フラグメント シェーダー プログラム

画像出力

CPU

GPU

ラスタ ライザ

テクスチャ : z attribute 変数

フレームバッファ オブジェクト テクスチャ : y テクスチャ : x

float:alpha

図4.21: saxpy計算の経路

ドキュメント内 _openglcl (ページ 126-130)