最終更新: mikk_ni3_92 2010年02月28日(日) 15:16:00履歴
現在地:メニュー >> GLSL >> GLSL編07
INDEX:GLSL編06<< GLSL編07 >>GLSL編08
uniformやvaryingなど変数に色々な修飾子がついたりする。
(使用が使用を推奨されないものもあったりするが、とりあえず整理)
…等々
glDrawArrays関数などの頂点配列使った描画を通して
修飾子のついた変数を実際に使ってみる。
つまり、
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を使用する
次のような頂点シェーダを記述すると仮定。
まず、頂点シェーダ内での名前vertexとCPUとの関連付けをおこなう。
【例】:変数名の関連付け
【描画時】
描画関数はglDrawArraysなどかわらないが、有効化したり、配列データ位置を指定する関数は違う。
【例】
#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()
【例】:変数名の関連付け
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);//無効化 … …
次のようなフラグメントシェーダを記述すると仮定
【例】
名前の関連付けはglBindFragDataLocationEXTを使う。(標準化されたものはglBindFragDataLocation)
【例】:変数名の関連付け
【例】
#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(); }