C++ mit OpenGL (Speziell: GLSL): Shader linking-problem



  • Hallo,

    und erneut habe ich ein Problem mit meinem Code. Zunächst wollte ich ihn wie unten reinkopiert abändern, jedoch funktioniert dies nicht. Ich habe den Verdacht, dass die Compilefunktion mehrmals den selben Code compiliert, was die Fehler (unten) erklären würde, jedoch kann ich mir nicht vorstellen wo mein Fehler liegt (Ich bin mir sicher, dass der Fehler in meiner neuen Methode die Shader zu compilierenn liegt, denn setzt man die Alte wieder ein und passt die darauf Folgende an, tut alles wieder tun)!

    Neue compile() Funktion + grober Umriss meines Codes:

    namespace Shader {
            int maxAttribs;
            int shaderProgram;
            int maxShadersSupported;
            int usedShaderSlots = 0;
            GLuint* compiledShaders;
            string* ShaderCode;
            string* ShaderFileType;
    
            void init(int maxShadersSupportedValue) {
                //....
                ShaderFileType = new string[maxShadersSupported];
                ShaderCode = new string[maxShadersSupported];
                compiledShaders = new GLuint[maxShadersSupported];
            }
    
            void add(string shaderPath) {
                //....
            }
    
            void compile() {
                for (int i = 0; i < usedShaderSlots; i++) {
                    if (ShaderFileType[i] == "VERTEX") {
                        Core::LOG_Msg(4, "Type of shader: Vertex");
                        compiledShaders[i] = glCreateShader(GL_VERTEX_SHADER);
                    } else {
                        if (ShaderFileType[i] == "FRAGMENT") {
                            Core::LOG_Msg(4, "Type of shader: Fragment");
                            compiledShaders[i] = glCreateShader(GL_VERTEX_SHADER);
                        } else {
                            if (ShaderFileType[i] == "ERROR") {
                                Core::LOG_Msg(4, "Type of shader: Fuck");
                                Core::LOG_Msg(1, "Error. Shader-array corrupted.");
                            }
                        }
                    }
    
                    const GLchar* Source = ShaderCode[i].c_str();
                    glShaderSource(compiledShaders[i], 1, &Source, NULL);                           <-- Hier glaube ich ist der Fehler
                    glCompileShader(compiledShaders[i]);                                            <-- Oder hier...
    
                    // check for shader compile errors
                    int success;
                    char infoLog[512];
                    glGetShaderiv(compiledShaders[i], GL_COMPILE_STATUS, &success);
                    if (!success) {
                        glGetShaderInfoLog(compiledShaders[i], 512, NULL, infoLog);
                        Core::LOG_Msg(1, "A SHADER COMPILING FAILED:");
                        cerr << infoLog << endl;
                        Core::LOG_Msg(1, "Shader type:", i);
                    }
                    Core::LOG_Msg(4, "Compiled a shader successfully: ", i);
                }
    
                int success;
                char infoLog[512];
    
                // link shaders
                shaderProgram = glCreateProgram();
                for (int i = 0; i < usedShaderSlots; i++) {
                    glAttachShader(shaderProgram, compiledShaders[i]);
                    Core::LOG_Msg(4, "Added a shader for linking: ", i);
                }
    
                glLinkProgram(shaderProgram); //Now link the program
    
                // check for linking errors
                glGetProgramiv(shaderProgram, GL_LINK_STATUS, &success);
                if (!success) {
                    glGetProgramInfoLog(shaderProgram, 512, NULL, infoLog);
                    Core::LOG_Msg(1, "SHADER LINKING FAILED:");
                    cerr << infoLog << endl;
                    exit(1);
                }
    
                glUseProgram(shaderProgram);
                Core::LOG_Msg(4, "Shaderprogram successfully compiled and selected.");
    
                for (int i = 0; i < usedShaderSlots; i++) {
                    glDeleteShader(compiledShaders[i]);
                }
            }
        }
    }
    

    Und hier mein Vorläufer der nun fehlerhaften Funktion:

    int vertexShader = glCreateShader(GL_VERTEX_SHADER);
                const GLchar* Source = ShaderCode[0].c_str();
                glShaderSource(vertexShader, 1, &Source, NULL);
                glCompileShader(vertexShader);
    
                // check for shader compile errors
                int success;
                char infoLog[512];
                glGetShaderiv(vertexShader, GL_COMPILE_STATUS, &success);
                if (!success) {
                    glGetShaderInfoLog(vertexShader, 512, NULL, infoLog);
                    Core::LOG_Msg(1, "VERTEX SHADER COMPILATION FAILED:");
                    cerr << infoLog << endl;
                }
    
                // fragment shader
                int fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
                Source = ShaderCode[1].c_str();
                glShaderSource(fragmentShader, 1, &Source, NULL);
                glCompileShader(fragmentShader);
    
                // check for shader compile errors
                glGetShaderiv(fragmentShader, GL_COMPILE_STATUS, &success);
                if (!success) {
                    glGetShaderInfoLog(fragmentShader, 512, NULL, infoLog);
                    Core::LOG_Msg(1, "FRAGMENT SHADER COMPILATION FAILED:");
                    cerr << infoLog << endl;
                }
    
                // link shaders
                // Hier habe ich (hoffentlich) nichts Relevantes abgeändert.
    

    Hier der Aufruf meiner Funktionen (kurz):

    Shader::init(2);
       Shader::add("assets/shaders/default.vsh");
       Shader::add("assets/shaders/default.fsh");
       Shader::compile();
    

    ...Und hier der Fehler + Protokoll auf der Konsole:

    //.....
    DEBUG: Type of loaded shader: Vertex
    DEBUG: -> Used shader slots: 1
    DEBUG: Type of loaded shader: Fragment
    DEBUG: -> Used shader slots: 2
    DEBUG: Type of shader: Vertex
    DEBUG: Compiled a shader successfully:
    DEBUG: Type of shader: Fragment
    DEBUG: Compiled a shader successfully: 1
    DEBUG: Added a shader for linking:
    DEBUG: Added a shader for linking: 1
    ERROR: SHADER LINKING FAILED:
    Vertex info
    -----------
    0(8) : error C1038: declaration of "color" conflicts with previous declaration at 0(3)
    0(10) : error C1013: function "main" is already defined at 0(11)

    Ich wäre über jede Hilfe wie immer äußerst dankbar! Und sorry, für die "Wall of Code".

    Einen guten Abend noch,

    Simon

    EDIT:
    Hier noch die (UNFERTIGEN) Shader (die sonst (fast)) funktionieren:

    default.fsh schrieb:

    #version 330 core
    in vec3 ourColor;
    in vec2 TexCoord;

    //uniform vec4 vertexColor; //LEAGCY for Colors by vertex
    uniform sampler2D ourTexture;

    out vec4 color;

    void main() {
    //color = vertexColor; //LEAGCY for Colors by vertex
    color = texture(ourTexture, TexCoord) * vec4(ourColor, 1.0f);
    }

    default.vsh schrieb:

    #version 330 core
    layout (location = 0) in vec3 position;
    layout (location = 1) in vec3 color;
    layout (location = 2) in vec2 texCoord;

    uniform vec3 offset;

    out vec3 ourColor;
    out vec2 TexCoord;

    void main() {
    gl_Position = vec4(position, 1.0);
    //gl_Position.y = gl_Position.y * -1; //UP SITE DOWN - YEAH!
    gl_Position.x = gl_Position.x + offset.x;
    gl_Position.y = gl_Position.y + offset.y;
    gl_Position.z = gl_Position.z + offset.z;

    ourColor = color;
    TexCoord = texCoord;
    }



  • Hi,

    mir ist gerade eingefallen, dass ich ja theoretisch ein und den selben Pointer auf den selben Sourcecode bei "glShaderSource" übergebe - der GLSL compiler hat also vielleicht kein Problem damit, dass ich ihm richtigen Code gebe sondern, dass dessen Interpreter bei der Prüfung des reinen Quelltextes Ärger macht 😕 -> Man müsste ein lokal definiertes Array für compile() machen welches den Datentyp const GLchar hat, damit könnte man sich bei mir z.B. "const GLchar* Source = ShaderCode[i].c_str();" sparen. Hätte Jemand dazu eine Idee (ich kriege die nachträgliche Initialisierung eines solchen Arrays nicht mehr hin, nachdem ich es am Anfang von compile() deklariert habe...)?

    Bis dann,

    Simon



  • glCreateShader(GL_VERTEX_SHADER) für einen Fragmentshader?

    Wo ist dein C++ Problem?

    Jedem, der public init-Funktionen schreibt, sollen die Hände abfaulen.



  • Hallo manni66,

    möge ich in der Hölle schmoren, das mir dieser verdammte Copy-Paste-Fehler trotz mehrmaligem Durchlesens gestern Abend nicht mehr aufgefallen ist. Kurz korrigiert und voilá alles in Ordnung! Das C++ Problem hat sich somit auch erledigt (hätte ich den Beitrag in der Kathegorie Spieleentwicklung erstellen sollen?). Ebenfalls hatte ich vor daraus noch ein Objekt zu basteln, aber das werde ich dann wieder Abseits dieses Forums tun (Nur so als Rechtfertigung für die public init()).

    VIELEN DANK!

    Simon, der zu blöd ist seinen Code zu lesen 😉


Log in to reply