92922
### 質問内容

GLSLシェーダーをコンパイルしてそのバイナリファイルを実行側で読み込んでシェーダーを実行したいのですが以下のエラーになります。これは何が原因なのでしょうか？何が無効なのでしょうか？

### 確認したこと

  1. コンパイルしたバイナリファイルはサイズが8.4kbです。
  2. コンパイルエラー、プログラムリンクエラー等のエラーを取得しています。出てないので問題ありません
  3. glGetError()にて0x501が出ています。
  4. コンパイル側と利用側でOpengl 4.5を使っています
  5. その場でコンパイルして実行する場合は問題なく実行できています

### 参考サイト

エラー： <https://qiita.com/ydah/items/da56763e94ba58af3d91>  
バイナリ化と読み込み： <https://puarts.com/?pid=1298>  
glProgramBinary: <https://registry.khronos.org/OpenGL-
Refpages/gl4/html/glProgramBinary.xhtml>

### エラー

0x501: 呼んだ関数の引数の値が無効な値もしくは範囲外の場合

```

    $ ./program
    formats: 1
    binaryFormats: 0x55bd29693fe0
    Error 0
    setBindAttribLocation(): -1
    setBindAttribLocation(): -1
    
        glGetError(): 0x501
    program: src/Shader.cpp:826: void FrameWork::Shader::setUniformSampler2D(const char*, GLuint, GLuint): Assertion `0' failed.
    中止 (コアダンプ)
    
```

### シェーダーバイナリを利用側

```

    /*############################################################################################
    # ロード
    ############################################################################################*/
    void FrameWork::Shader::Load(const char* vert,const char* frag)
    {
        GLuint program = glCreateProgram(); 
        
        FILE* fp = fopen(vert, "rb");
        if(fp == NULL)
        {
            std::cout<<"ファイルがありません。"<<std::endl;
        }
        fseek(fp, 0, SEEK_END);
        GLint len = (GLint)ftell(fp);
        unsigned char* binary = new unsigned char[len];
        fseek(fp, 0, SEEK_SET);
        fread(binary, len, 1, fp);
        fclose(fp);
        GLint formats = 0;
        glGetIntegerv(GL_NUM_PROGRAM_BINARY_FORMATS, &formats);
        GLint *binaryFormats = new GLint[formats];
        glGetIntegerv(GL_PROGRAM_BINARY_FORMATS, binaryFormats);
        std::cout<<"formats: "<<formats<<std::endl;
        std::cout<<"binaryFormats: "<<binaryFormats<<std::endl;
    
        glProgramBinary(program, *binaryFormats, binary, len);
        glLinkProgram(program);     //リンクプログラム
    
        delete [] binary;
    
    
    
    
        
        //リンク時のログを表示
        if(ProgramInfoLog(program) == false)
        {
            std::cerr<<"プログラムリンク失敗"<<std::endl;
            assert(0);
        }
    
    
        GLint success;
        glGetProgramiv(program, GL_LINK_STATUS, &success);
        if (!success)
        {
            std::cout<<"Error "<<success<<std::endl;
        // Loading failed...
        }
    
    
    
    
    
    
        //Delete(); //現在のシェーダーを削除
    
    //  program = CreateProgram(LoadShader(vert)->data(),LoadShader(frag)->data());
    
        if (program == 0)
        {
            std::cerr << "シェーダープログラム作成エラー" << std::endl;
            assert(0);
        }   
    }
    
```

### シェーダーコンパイル側

```

    /*############################################################################################
    # 初期化
    ############################################################################################*/
    bool Init()
    {
        GLboolean e = glfwInit();
        if (e == GL_FALSE)
        {
            std::cerr<<"Error: glfwInit() -1"<<std::endl;
            return false;
        }
    
        GLFWwindow* window = glfwCreateWindow(100,100,"test",NULL,NULL);    //ウインドウ生成
    
        if(window == NULL)
        {
            std::cerr<<"Error: glfwCreateWindow() NULL"<<std::endl;
            return false;
        }
    
        glfwMakeContextCurrent(window);
    
        glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4);
        glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 5);
        glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);
        glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
    
    
        GLenum err = glewInit();
        if( err != GLEW_OK)
        {
            std::cerr<<"Error: glewInit() "<<err<<std::endl;
            return false;
        }
    
        return true;    
    }
    
    /*############################################################################################
    # コンパイル
    ############################################################################################*/
    bool Compile(const GLint &program,const GLchar file[],const GLint shaderType)
    {
        //頂点シェーダー
        GLuint shader = glCreateShader(shaderType);
        glShaderSource(shader,1,&file,NULL);
        glCompileShader(shader);  
        GLboolean succ = CompileInfoLog(shader,shaderType); //エラー
        if(succ == GL_TRUE)
        {
            glAttachShader(program,shader);
    
            return true;
        }
    
        glDeleteShader(shader);
    
        return false;
    }
    
    /*############################################################################################
    # バイナリ生成
    ############################################################################################*/
    bool GenBinary(const GLint &program,const char* fileName)
    {
    
        glLinkProgram(program);
        bool succ = ProgramInfoLog(program);    //エラー
        if(succ == true)
        {
            glUseProgram(program);
            
    
            int size = 0;
            GLint formats = 0;
            glGetProgramiv(program, GL_PROGRAM_BINARY_LENGTH, &size);
            glGetIntegerv(GL_NUM_PROGRAM_BINARY_FORMATS, &formats);
            GLint *binaryFormats = new GLint[formats];
            glGetIntegerv(GL_PROGRAM_BINARY_FORMATS, binaryFormats);
    
            unsigned char* binary = new unsigned char[size];
            glGetProgramBinary(program, size, NULL, (GLenum*)binaryFormats, binary);
            glUseProgram(0);
    
            FILE* fp = fopen(fileName,"wb");
            fwrite(binary, size, 1, fp);
            fclose(fp);
    
            delete[] binary;
        }
    
        return false;
    }
    
```

### GLSL vertex

```

    #version 420
    
    
    layout (location = 0) in vec3 vertexPosition;
    layout (location = 1) in vec2 vertexUV;
    
    layout (location = 2) out vec2 vUV;
    
    void main()
    {
        vUV = vertexUV;
    
        gl_Position = vec4(vertexPosition.x, -vertexPosition.y,vertexPosition.z, 1.0); 
    }  
    
```

### GLSL fragment

```

    #version 420
    
    out vec4 fragment;
    
      
    layout (location = 2) in vec2 UV;
    
    uniform sampler2D uImage;
    
    void main()
    { 
        
        fragment = texture(uImage, UV);
        //fragment = vec4(1.0,0.0,0.0,1.0);
    }
    
```
CC BY-SA 4.0
2022-12-20T11:19:37.887
92920
2023-01-07T07:25:23.740
2023-01-07T07:25:23.740
3060
55177
question
c++ opengl
GLSLバイナリをglProgramBinary()で実行すると0x501エラーが出る原因が知りたい。
OpenGLは触ったことないですが、`glGetProgramBinary()` 呼び出し後に第4引数に書き込まれた `GLenum` の値を
`glProgramBinary()` の第2引数に指定する必要があるように読めます。

<https://registry.khronos.org/OpenGL-
Refpages/gl4/html/glGetProgramBinary.xhtml>

> The binary produced by the GL may subsequently be returned to the GL by
> calling `glProgramBinary`, with `binaryFormat` and `length` set to the
> values returned by `glGetProgramBinary`, and passing the returned binary
> data in the `binary` parameter.
CC BY-SA 4.0
2022-12-20T14:13:39.757
92922
2022-12-20T14:13:39.757
3475
92920
answer