OpenGL/ES 2.0和更高版本:如何一起编译多个着色器文件 [英] OpenGL/ES 2.0 and Higher: How to Compile Multiple Shader Files Together

查看:121
本文介绍了OpenGL/ES 2.0和更高版本:如何一起编译多个着色器文件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

已多次以不同方式询问此问题.我的问题仅针对OpenGL 2.0/GLSL 1.10及更高版本,以及与OpenGL ES 2.0及其受支持版本GLSL的潜在兼容性:

This question has been asked multiple times in different ways. My question is specific to OpenGL 2.0 / GLSL 1.10 and higher and potential compatibility with OpenGL ES 2.0 and its supported version of GLSL:

推荐使用哪些C/C ++ API将多个文件组合成一个着色器源,以传递到 glShaderSource .

What are recommended C/C++ APIs used to combine multiple files into one shader source to pass into glShaderSource.

例如,如果我有3个文件A.frag,B.frag,C.frag,它们具有以下内容:

For example, if I have 3 files A.frag, B.frag, C.frag that have the following contents:

/* 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);
}

哪些现有工具可以让我将所有三个文件的内容合并为一个源,以便可以对其进行编译?考虑到每个着色器源可能要复杂得多.

What already existing tools would allow me to combine all three file's contents into one source so it could be compiled? Take into consideration that each shader source could be far more complex.

推荐答案

如果您查看函数规范glShaderSource:

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

您看到第三个参数是一个由字符串(字符)组成的数组.

You see that the third parameter is an array of array of string (chars).

我写了一个c ++类来实现您想要做的事情.我发现最好的方法是分别加载文件,然后将不同的着色器源代码放入双指针中,然后将其最终传递给函数glShaderSource.

I wrote a c++ class to achieve what you are trying to do. The best approach I found is to load the files separately and then put in a double pointer the different shader source codes and then finally pass it to the function 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语言编写的.但是这里找到一个全班实施的要点.这样,您可以将多个着色器全部编译并链接在一起(只要它们都是同一类型).

It's not very straightforward, unfortunately OpenGL is still written in plain C. However Here you can find a gist with the whole class implemented. By doing so you can compile and link several shaders all together (as long as they are all of the same type of course).

希望有帮助.

这篇关于OpenGL/ES 2.0和更高版本:如何一起编译多个着色器文件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆