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

シェーダープログラムへのパラメータの受け渡し(その 1 )

ドキュメント内 _openglcl (ページ 57-61)

図 2.57: 画像例(その7、三角形を30度回転させた場合)

ホストプログラム

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

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

画像出力

CPU

GPU

ラスタ ライザ

uniform 変数 attribute 変数

図2.58: attribute変数とuniform変数の関係

uniform変数の具体的な利用法を以下に解説する。

1

2.11.1 Shaderクラスの拡張

2

まず、ホストプログラムからfloatuniform変数に値を代入するためのメンバー関数

3

void setFloat(const char* vname, float val);

4

をShaderクラスに新たに追加する。ここに、第1引数がuniform変数名、第2引数が代

5

入する値である。その実装は図2.59の通りである。関数本体の代入文:

6

GLint p = glGetUniformLocation(program, vname);39

7

は、バーテックスシェーダープログラムおよび(または)フラグメントシェーダープログラ

8

ム中からvnameと同じ変数名のuniform変数を見つけ、その場所(location)を変数p

9

代入する。関数glGetUniformLocation()2.2節に出てきたglGetAttribLocation()

10

に類似の機能であるが、前者はuniform変数の、後者はattribute変数の場所を見つける

11

void Shader::setFloat(const char* vname, float val){

GLint p = glGetUniformLocation(program, vname);

if(p < 0) {

cerr << "uniform name error: " << vname << endl;

exit(1);

}

glUniform1f(p,val);

}

図2.59: Shader::setFloat()の実装

void display(void) {

sp->setFloat("theta",30*M_PI/180.0);

glClear(GL_COLOR_BUFFER_BIT);

sp->run(GL_TRIANGLES,NUM_POINTS);

}

図2.60: uniform変数へ回転角度を代入するdisplay()

関数である。もしpの値が負値ならば、その変数名がバーテックスシェーダープログラム

1

とフラグメントシェーダープログラムのどちらにも宣言されていないことを意味する。そ

2

の場合、図2.59の関数ではエラーメッセージを出力し、プログラム全体を強制終了する。

3

関数呼び出し:

4

glUniform1f(p,val)40

5

はuniform変数の場所に実際にfloat値valを代入する。glUniform1f()と類似した関

6

数として、glUniform2f()41、glUniform3f()42、glUniform4f()43などもある。これら

7

はそれぞれvec2vec3vec4型のuniform変数へ値を代入する関数である。また、別の

8

類似関数 glUniform1i()44 intuniform変数へ値を代入する。

9

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

10

すぐ後に述べるが、図2.61のバーテックスシェーダープログラムに回転角を保持する

11

uniform変数theta(角度θのつもり)を導入する。そこで、図2.60のホストプログラム

12

40void glUniform1f(GLint location, GLfloat v0);

41void glUniform2f(GLint location, GLfloat v0, GLfloat v1);

42void glUniform3f(GLint location, GLfloat v0, GLfloat v1, GLfloat v2);

43void glUniform4f(GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3);

44void glUniform1i(GLint location, GLint v0);

#version 120

attribute vec2 position;

attribute vec3 in_color;

varying vec3 out_color;

uniform float theta; // 追加 void main(void)

{

float x = cos(theta)*position.x-sin(theta)*position.y; // 回転変換 float y = sin(theta)*position.x+cos(theta)*position.y; // 回転変換 gl_Position = vec4(x,y,0.0,1.0);

out_color = in_color;

}

図2.61: 入力座標を回転させるバーテックスシェーダープログラム

の描画関数display()では、そのthetaへ角度30度(ラジアンモードでは= 30·π/180)

1

を代入する関数呼び出し:

2

sp->setFloat("theta",30*M PI/180.0)

3

を実行する。この関数呼び出しはinitData()に追加してもよいが、後節で三角形の回転

4

するCGアニメーションを行うことを想定し、ここではdisplay()に追加しておく。

5

2.11.3 バーテックスシェーダープログラムの変更

6

図2.61がバーテックスシェーダープログラムである。回転角に対応する変数 thetaを

7

uniform宣言している。その変数を用いて、attribute変数として入力された2次元座標

8

positionを回転させ、回転後の座標値を gl Position へ代入している45

9

フラグメントシェーダープログラムは変更しない。

10

2.11.4 実行結果

11

図2.62が実行の様子である。attribute変数として入力された座標値はバーテックスシェー

12

ダーでuniform変数thetaの値だけ回転される。その回転された座標値がラスタライザ

13

V.S.

V.S. ラスタ

ライザ

V.S.

F.S.

F.S.

attribute 変数

uniform 変数 theta

図2.62: 三角形が回転する場合の動作例

へ入力されて、回転された三角形の画素が求められる。

1

ドキュメント内 _openglcl (ページ 57-61)