現在地メニュー >> GLSL >> GLSL編07
INDEX:GLSL編06<< GLSL編07 >>GLSL編08

変数につく修飾子


uniformやvaryingなど変数に色々な修飾子がついたりする。
(使用が使用を推奨されないものもあったりするが、とりあえず整理)
const定数
attribute頂点単位のデータ読み込み用。(頂点シェーダでのみ使用可能)
uniformシェーダが実行されても変化がない値。constとは異なって、コンパイル時にはどんな値か不明
varying頂点シェーダの出力を意味する。フラグメントシェーダでは補間された入力値となっている。
in入力を意味する。
out出力を意味する。
inout入力であり出力であることを意味する。
…等々

頂点配列を使う


glDrawArrays関数などの頂点配列使った描画を通して
修飾子のついた変数を実際に使ってみる。

つまり、
  • 頂点座標の入力を「gl_Vertex」→「in vec4 vertex」にする
  • 出力を「gl_FragColor」→「out vec4 outColor」にする
  • GLSL1.4を使用する
ということをやってみる。

頂点シェーダとの関連付け

次のような頂点シェーダを記述すると仮定。
#version 140 //GLSL1.4を使用する

in vec4 vertex; //GLSL1.3以下はattributeでもOK(1.4以降ではin)

//頂点シェーダ
void main(void)
{
	//投影変換 (モデルビュー * プロジェクション) * 頂点座標
	gl_Position = gl_ModelViewProjectionMatrix * vertex;
	gl_FrontColor = gl_Color;
}

まず、頂点シェーダ内での名前vertexとCPUとの関連付けをおこなう。
  • glGetAttribLocation()
  • glBindAttribLocation()
の2つの方法があるが、ここではglGetAttribLocation()を使う。

【例】:変数名の関連付け
GLint vertLoc;
… …
glLinkProgram(programId);//先にリンクしておく
… …
vertLoc = glGetAttribLocation(programId, "vertex");//現在リンクしているプログラムが対象
▲注意点は、リンク後に使用するという点。

【描画時】
描画関数はglDrawArraysなどかわらないが、有効化したり、配列データ位置を指定する関数は違う。

【例】
GLint vertLoc;
… …
glVertexAttribPointer(vertLoc,3, GL_FLOAT,GL_FALSE, 0, points);//GL_FALSE→データを正規化しない
glEnableVertexAttribArray(vertLoc);//有効化
glDrawArrays(GL_QUADS,0,4);//描画
glDisableVertexAttribArray(vertLoc);//無効化
… …

フラグメントシェーダとの関連付け

次のようなフラグメントシェーダを記述すると仮定
【例】
#version 140 //GLSL1.4を使用する

out vec4 outColor;

//フラグメント
void main(void)
{
	outColor = gl_Color;
}

名前の関連付けはglBindFragDataLocationEXTを使う。(標準化されたものはglBindFragDataLocation)
【例】:変数名の関連付け
glBindFragDataLocationEXT(programId,0,"outColor");
… …
glLinkProgram(programId);//リンクは後
▲注意点は、リンク前に行うという点。

まとめ

まとめると次のようになる

GLuint vShaderId;
GLuint fShaderId;
GLuint programId;
GLint vertLoc;

//GLSLのセットアップ
void setUpGLSL()
{
	//---- 頂点シェーダオブジェクトの作成 ----//
	vShaderId = glCreateShader(GL_VERTEX_SHADER);

	//.vertファイルの中身を全て読み込む
	std::ifstream inputFile1("glsl.vert");
	std::istreambuf_iterator<char> vdataBegin(inputFile1);
	std::istreambuf_iterator<char> vdataEnd;
	std::string fileData1(vdataBegin,vdataEnd);
	const char *vfile = fileData1.c_str();

	//ソースコードをシェーダオブジェクトに変換
	glShaderSource(vShaderId, 1, &vfile,NULL);
	glCompileShader(vShaderId);//コンパイル


	//---- フラグメントシェーダオブジェクトの作成 ----//
	fShaderId = glCreateShader(GL_FRAGMENT_SHADER);

	//.fragファイルの中身を全て読み込む
	std::ifstream inputFile2("glsl.frag");
	std::istreambuf_iterator<char> fdataBegin(inputFile2);
	std::istreambuf_iterator<char> fdataEnd;
	std::string fileData2(fdataBegin,fdataEnd);
	const char *ffile = fileData2.c_str();
	//ソースコードをシェーダオブジェクトに変換
	glShaderSource(fShaderId, 1, &ffile,NULL);
	glCompileShader(fShaderId);//コンパイル

	//プログラムオブジェクトの作成
	programId = glCreateProgram();
	glAttachShader(programId,vShaderId);
	glAttachShader(programId,fShaderId);
	glBindFragDataLocationEXT(programId,0,"outColor");//フラグメントの関連付け

	GLint linked;
	glLinkProgram(programId);
	glGetProgramiv(programId, GL_LINK_STATUS, &linked);
	if(linked == GL_FALSE)
	{
		std::cerr << "Link Err.\n";
	}

	glUseProgram(programId);

	vertLoc = glGetAttribLocation(programId, "vertex");//現在リンクしているプログラムが対象
}
… …
void display()
{
	glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
	glLoadIdentity();
	gluLookAt(3,4,5,0,0,0,0,1,0);
	glColor3f(1,0,1);

	glVertexAttribPointer(vertLoc,3, GL_FLOAT,GL_FALSE, 0, points);
	glEnableVertexAttribArray(vertLoc);
	glDrawArrays(GL_QUADS,0,4);
	glDisableVertexAttribArray(vertLoc);

	glutSwapBuffers();
}

サンプルコード

目次

― その他 ―

Wiki内検索

計測中...(07.10.8〜)

Save The World






▲よろしければ広告のクリックもお願いします


▲ランキングに参加しました

管理人/副管理人のみ編集できます