GLSLを使う手順

glsl-setup.png

オーバービュー

頂点シェーダ、フラグメントシェーダそれぞれやるところ

  1. glCreateShader…シェーダオブジェクトを作る
  2. glShaderSource…シェーダソースコードをシェーダオブジェクトに渡す
  3. glCompileShader…各シェーダをコンパイルする
  4. glCreateProgram…プログラムオブジェクトを作る。
  5. glAttachShader…シェーダオブジェクトをアタッチする

これ以降は頂点シェーダ、フラグメントシェーダ、いっしょくたでok

  1. glLinkProgram…programにアタッチされたすべてのシェーダオブジェクトろ処理し、完結したシェーダプログラムを作成する
  2. glGetUniformLocation….ユニフォーム変数の名前とcpp上での変数名を結び付ける
  3. glUseProgram…OpenGLの現在のステートに実行可能なプログラムをインストールする
  4. glUniform…ユニフォーム変数の値を渡す
  5. 図形を描く

glShaderSource(GLuint shader,GLsizei count,GLchar** string,const GLint* length)

  • shader…ソースであるstringと関連付けたいシェーダオブジェクト
  • count….普通は1
  • length…NULLならば、第3引数stringは\0で終わる文字列でなければならない。NULLでない場合は、第2引数stringの文字列の長さを書く

2.Initにて

仮に、エラーチェック何もなしに書いたらこうなる。

//引数にはシェーダのコードである文字列を渡す
    GLuint CreateShaderProgram(const char* pVertexSource, const char* pFragmentSource) {
        // シェーダプログラムをロードする
        GLuint vertexShader = glCreateShader(GL_VERTEX_SHADER);
            glShaderSource(vertexShader, 1, &pVertexSource, NULL);
            glCompileShader(vertexShader);//シェーダをコンパイルする。
            GLuint pixelShader = glCreateShader(GL_FRAGMENT_SHADER);
            glShaderSource(pixelShader, 1, &pFragmentSource, NULL);
            glCompileShader(pixelShader);//シェーダをコンパイルする。
 
        GLuint program = glCreateProgram();
 
        glAttachShader(program, vertexShader);
        glAttachShader(program, pixelShader);
        glLinkProgram(program);
 
        return program;
    }

2.b アトリビュート変数を結びつける

 // 頂点座標の設定
    glBindAttribLocation(gProgram, ATTRIB_VERTEX, "Position");
    checkGlError("glBindAttribLocation");
    // 色座標を設定
    glBindAttribLocation(gProgram, ATTRIB_COLOR, "SourceColor");
    checkGlError("glBindAttribLocation");

2.c 射影行列を渡す

glViewPortとかある場所にて行う

// 透視変換行列の設定
    GLint projectionUniform = glGetUniformLocation(gProgram, "Projection");
    gProj.glFrustum(-ratio,ratio,-2.0,2.0,3,100);
    glUniformMatrix4fv(projectionUniform, 1, 0, gProj.mMatrix);

まとめ

void InitShader() {
    FILE* fp;
    fp=fopen("raycasting.frag","rb");
    if(fp==NULL){
        char buf[200];
        GetCurrentDirectory(200,buf);
        printf("current directory:%s\n",buf);
        assert(!"file could not open!");}
    //ファイルの長さを調べる
    fseek(fp,0,SEEK_END);
    int size= ftell(fp);
    fseek(fp,0,SEEK_SET);//先頭まで移動
    gFragmentShader=new char[size+1];
    fread(gFragmentShader,sizeof(char),size,fp);
    fclose(fp);
    gFragmentShader[size]='\0';//終わりだよ印をつける
    gProgram = miffy::CreateShaderProgram(gVertexShader, gFragmentShader);
    gSimpleProgram = miffy::CreateShaderProgram(gSimpleVertexShader, gSimpleFragmentShader);//boundingboxのために必要。
    projectionUniform = glGetUniformLocation(gProgram, "Projection");
    modelviewUniform = glGetUniformLocation(gProgram, "Modelview");
    gCamUniLoc    =    glGetUniformLocation(gProgram,"camera");
    gTexSamplerLoc= glGetUniformLocation ( gProgram, "voltexture" );
    gTFTexSamplerLoc= glGetUniformLocation ( gProgram, "trans_func" );
    printf("glUni=%d,%d",gTFTexSamplerLoc,gTexSamplerLoc);
 
}

3.display関数にて

gl_ModelViewProjectionMatrixの組み込みユニフォーム変数のあるバージョンなら以下の項目はとばしてもいい。

3.a行列情報を渡す

gModelView.LoadIdentity();
    gModelView.gluLookAt(0,0,gZoom, 0,0,0, 0,1,0);
    gModelView.MultMatrix(&rotation);
    // 表示物の姿勢設定
    int modelviewUniform = glGetUniformLocation(gProgram, "Modelview");
    glUniformMatrix4fv(modelviewUniform, 1, 0, gModelView.mMatrix);

サポートサイト Wikidot.com