2012年11月29日 星期四

OpenGL - programmable Pipeline, GLSL 學習(2) Switching Shaders

如何在一個程式內使用不同的shader的方法 : 
 http://pouet.net/topic.php?which=6164


簡而言之就是在主程式內創造多個program object,
每個各自有著不同的shader連接於其上,之後要轉換使用各種不同的shader的話就用

glUseProgram(Gluint programID)

依據keyboard input來切換不同的shader



(至於如何連接shader至program obj,我使用tutorial的shader.cpp 的code來講解

/*************************************************************************************************/
//Read the notation first!! It's just a fragment of loading shader, not a full example.
//first load the shader text in, and regard it as c string
    char const * VertexSourcePointer = VertexShaderCode.c_str();

//create shader obj and compile it
    glShaderSource(VertexShaderID, 1, &VertexSourcePointer , NULL);
    glCompileShader(VertexShaderID);

// Check Vertex Shader Compile error
    glGetShaderiv(VertexShaderID, GL_COMPILE_STATUS, &Result);
    glGetShaderiv(VertexShaderID, GL_INFO_LOG_LENGTH, &InfoLogLength);
    std::vector<char> VertexShaderErrorMessage(InfoLogLength);
    glGetShaderInfoLog(VertexShaderID, InfoLogLength, NULL, &VertexShaderErrorMessage[0]);
    fprintf(stdout, "%s\n", &VertexShaderErrorMessage[0]);
//end checking compile error

// Link shader to the program
    fprintf(stdout, "Linking program\n");
    GLuint ProgramID = glCreateProgram();
    glAttachShader(ProgramID, VertexShaderID);
    glAttachShader(ProgramID, FragmentShaderID);
    glLinkProgram(ProgramID);

// Check the program
    glGetProgramiv(ProgramID, GL_LINK_STATUS, &Result);
    glGetProgramiv(ProgramID, GL_INFO_LOG_LENGTH, &InfoLogLength);
    std::vector<char> ProgramErrorMessage( max(InfoLogLength, int(1)) );
    glGetProgramInfoLog(ProgramID, InfoLogLength, NULL, &ProgramErrorMessage[0]);
    fprintf(stdout, "%s\n", &ProgramErrorMessage[0]);
//....後續還有

/*************************************************************************************************



大概就是這樣了吧@@

至於因為有多個program obj存在,記得要在每個program obj linking後

在裡面註冊個Uniform MVP Matrix( Projection*View*Model) 位置,

這樣每個program都可以存取到MVP matrix

之後就可以傳給各自的Shader惹ˊˇˋ


--------------------------------------------------------------------------------------------------------
方法二
Using subroutines to sele shader functionality

glslcookbook P71有寫到,可以在vs,fs裡面再做判斷。

但相對的,所有shading方法就要寫在同一份檔案裡面了

1.在Shader內使用subroutine 前綴關鍵字

2.並在主程式裡面用

GLuint adsIndex = glGetSubroutineIndex( programHandle, GL_VERTEX_SHADER,"phongModel" );
//第三個參數是在Shader 裡面定義的subroutine function name

GLuint diffuseIndex = glGetSubroutineIndex(programHandle, GL_VERTEX_SHADER, "diffuseOnly");

glUniformSubroutinesuiv( GL_VERTEX_SHADER, 1, &adsIndex);
... // Render the first obj
glUniformSubroutinesuiv( GL_VERTEX_SHADER, 1, &diffuseIndex);
... // Render the second

沒有留言:

張貼留言