2015-03-24 73 views
0

以不同方式多次詢問此問題。我的問題是特定於OpenGL 2.0/GLSL 1.10及更高版本以及與OpenGL ES 2.0及其支持的GLSL版本的潛在兼容性:OpenGL/ES 2.0及更高版本:如何將多個着色器文件編譯在一起

推薦使用哪種C/C++ API將多個文件合併爲一個着色器源以進入glShaderSource

舉例來說,如果我有3個文件A.frag,B.frag,C.frag具有以下內容:

/* A.frag */ 
struct A 
{ 
    vec3 val; 
}; 

/* B.frag */ 
struct B 
{ 
    vec3 val; 
}; 

/* C.frag */ 
void main() { 
    struct A a; 
    a.val = vec3(1.0, 1.0, 1.0); 

    struct B b; 
    b.val = vec3(1.0, 1.0, 1.0); 

    float f = dot(a.val, b.val); 
} 

什麼已有的工具,可以讓我所有的三個文件的內容組合成一個源,所以它可以編譯?考慮到每個着色器源可能更加複雜。

+0

你可能想看看http://stackoverflow.com/questions/10754437/how-to-using-the-include-in-glsl-support-arb-shading-language-include – user3256930 2015-03-24 23:06:33

回答

0

如果你看一下功能規格glShaderSource

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

你看到第三個參數是字符串(字符)的數組的數組。

我寫了一個C++類來實現你正在嘗試做的事情。我發現的最佳方法是單獨加載文件,然後將不同的着色器源代碼放入雙指針,然後將其傳遞給函數glShaderSource。

例如:

GLchar**  fragment_code; // This must be initialized 
GLint*   fragment_char_count; 

void LoadFragment() 
{ 
    //assuming fragment_filepath a vector<string> containing different shader filepaths 
    for (size_t i = 0; i < fragment_filepath.size(); i++) 
    { 
     Load(fragment_filepath[i], fragment_code[i], fragment_char_count[i]); 
    } 
} 

// source_path is the shader file path in the filesystem 
// output will contain the source code of the shader being loaded 
// fragment_char_count will contain the number of char for the shader being loaded 
static void Load(string source_path, GLchar*& output,GLint& fragment_char_count) 
{ 
    string return_code; 
    try 
    { 
     // Open files 
     ifstream vShaderFile(source_path); 
     stringstream vShaderStream; 
     // Read file's buffer contents into streams 
     vShaderStream << vShaderFile.rdbuf(); 
     // close file handlers 
     vShaderFile.close(); 
     // Convert stream into GLchar array 
     return_code = vShaderStream.str(); 
    } 
    catch(exception e) 
    { 
     cout << "ERROR::SHADER::FILE_NOT_SUCCESFULLY_READ: " << source_path << endl; 
    } 

    fragment_char_count = return_code.length() ; 
    output = new GLchar[count + 1]; 
    std::size_t length = return_code.copy(output,fragment_char_count,0); 
    output[length]= '\0'; 
} 

// eventually when you compile you pass to glShaderSource the fragment_id, the number of shader program you are loading (fragment_filepath.size()), the double pointer of char containing the different source codes (fragment_code) and an array representing the char count for each source (fragment_char_count) 
void CompileFragment() 
{ 
    glShaderSource(fragment_shader_id, fragment_filepath.size(), fragment_code, fragment_char_count); 
    glCompileShader(d_vertex_shader); 
} 

這不是很直接,很不幸的OpenGL仍然寫在普通的C.但是Here你可以找到實現全班一個要點。通過這樣做,您可以編譯並鏈接幾個着色器(只要它們都是相同類型的課程)。

希望它有幫助。

+0

我要去東西的東西類似的,但我的開發人員告訴我必須有一個已經存在的API來爲你做這件事。 – 2015-03-25 02:53:07

相關問題