Part of the Khronos Group
OpenGL.org

The Industry's Foundation for High Performance Graphics

from games to virtual reality, mobile phones to supercomputers

Page 1 of 2 12 LastLast
Results 1 to 10 of 11

Thread: glGetUniformLocation() unwantedly returns -1

  1. #1
    Junior Member Newbie
    Join Date
    Sep 2017
    Posts
    7

    glGetUniformLocation() unwantedly returns -1

    Hello,

    I'm in a desperate situation, please help me.

    The past two weeks I've had difficulty using uniform variables in my shader programs. The problem arises as the glGetUniformLocation() function call returns the value -1.
    I've done plenty of research recently on the topic myself and I think I have the right function calls at the right places. I'm also aware that the glsl driver optimizes out certain variables that it sees not affecting the output of the program, but I do not understand why the heck it would do that in my case. The variables for I'm calling the glGetUniformLocation() are put in a good use calculating the result values in my shaders. What is even more incomprehensible to me is the haphazard results I get after I run my program. Same binary, different runtime results each time. It sometimes works perfectly as intended, sometimes it fails getting the uniform locations. I've extracted the problem to a simplified build and loaded it to a github repository. It can be found here https://github.com/Motonen/Uniform. Here is the vertex shader

    Code glsl:
    #version 330 core
    layout (location = 0) in vec4 vPosition;
     
    uniform mat4 projMatrix;
    uniform mat4 modelMatrix;
    uniform mat4 viewMatrix;
     
     
    void main()
    {
        vec4 m = modelMatrix * vPosition;
        vec4 mv = viewMatrix * m;
        vec4 mvp = projMatrix * mv;
        gl_Position = mvp;
    }

    The glsl driver in this case shouldn't optimize out any of those uniform matrices right? It does it nevertheless sometimes.

    Enlighten me about my situation. Thank you guys in advance.
    Last edited by Dark Photon; 09-17-2017 at 12:43 PM.

  2. #2
    Senior Member OpenGL Guru Dark Photon's Avatar
    Join Date
    Oct 2004
    Location
    Druidia
    Posts
    4,123
    Quote Originally Posted by Motonen View Post
    The glsl driver in this case shouldn't optimize out any of those uniform matrices right?
    Nope.

    It does it nevertheless sometimes.
    Hmmm. Let's see the code you're using to compile your shader and link your program. Make sure that you're checking for compile and link failures and printing out the compile and link error strings on failure. Also make sure you are actually adding your shader to your program.

    Also, what GL driver is this? I can tell you on NVidia drivers, it doesn't optimize these away (I tossed this in a small, stand-alone GLUT test program and verified that.)

  3. #3
    Junior Member Newbie
    Join Date
    Sep 2017
    Posts
    7
    Quote Originally Posted by Dark Photon View Post
    Nope.



    Hmmm. Let's see the code you're using to compile your shader and link your program. Make sure that you're checking for compile and link failures and printing out the compile and link error strings on failure. Also make sure you are actually adding your shader to your program.
    Code :
    #include "LoadShaders.h"
     
    std::string readFile(const char *filename)
    {
        std::ifstream inputFile(filename); 
     
        if(!inputFile)
            std::cerr << "Couldn't open file " << filename << '\n';
     
        std::stringstream inputStream;
        inputStream << inputFile.rdbuf();
        inputFile.close();
     
        return inputStream.str();    
    }
     
    GLuint loadFromFile(const char *filename, int type)
    {
     
        GLint status;
        GLchar infoLog[512];
     
     
        const GLchar *shaderCode = readFile(filename).c_str();
        GLuint shaderID = glCreateShader(type);
        glShaderSource(shaderID, 1, &shaderCode, NULL);
        glCompileShader(shaderID);
     
        glGetShaderiv(shaderID, GL_COMPILE_STATUS, &status);
     
        if(!status)
        {
            glGetShaderInfoLog(shaderID, 512, nullptr, infoLog);
            std::cerr << infoLog << "\n" << filename << '\n';
        }
     
        return shaderID;
    }
     
     
     
     
     
    GLuint loadShaders(const char *vertexFile, const char *fragmentFile)
    {
        GLuint vertexID = loadFromFile(vertexFile, GL_VERTEX_SHADER);
        GLuint fragmentID = loadFromFile(fragmentFile, GL_FRAGMENT_SHADER);
     
        GLuint programID = glCreateProgram();
        glAttachShader(programID, vertexID);
        glAttachShader(programID, fragmentID);
     
        glLinkProgram(programID);
        glValidateProgram(programID);
     
        return programID;
    }

    Here is the code for loading the shaders, I don't see anything wrong with it.

    Those functions are being called in the main.

    Code :
     
     
        GLuint program = loadShaders("vertexFile", "fragmentFile");
        GLint viewLoc, projLoc, modelLoc;
     
        const char *viewId = "viewMatrix";
        const char *projId = "projMatrix";
        const char *modelId = "modelMatrix";
     
        glUseProgram(program);
     
        viewLoc = glGetUniformLocation(program, viewId);    
        projLoc = glGetUniformLocation(program, projId);    
        modelLoc = glGetUniformLocation(program, modelId);


    Code :
     
        std::cout << glGetString(GL_VENDOR) << '\n';
        std::cout << glGetString(GL_RENDERER) << '\n';
        std::cout << glGetString(GL_VERSION) << '\n';


    This code provides the output:

    Intel Inc.
    Intel HD Graphics 5000 OpenGL Engine
    4.1 INTEL-10.25.17

  4. #4
    Member Regular Contributor
    Join Date
    Jul 2012
    Posts
    418
    No errors reported after the link and validation of your shader and after the call of glGetUniformLocation ?

  5. #5
    Junior Member Newbie
    Join Date
    Sep 2017
    Posts
    7
    No, the error code is never provoked as I run the program. Only the uniform check I included there notifies me that it fails to get the uniform location for the matrix variables I have. This only happens sometimes.

  6. #6
    Junior Member Newbie
    Join Date
    Sep 2017
    Posts
    7
    Code :
     
     
    bool verify(GLint loc, const char *name)
    {
        if(loc < 0)
            return false;
        return true;
    }
     
    bool initShaders()
    {
        GLuint program = loadShaders("vertexFile", "fragmentFile");
        GLuint viewLoc, projLoc, modelLoc;
     
        const char *viewId = "viewMatrix";
        const char *projId = "projMatrix";
        const char *modelId = "modelMatrix";
     
        glUseProgram(program);
     
        viewLoc = glGetUniformLocation(program, viewId);    
        projLoc = glGetUniformLocation(program, projId);    
        modelLoc = glGetUniformLocation(program, modelId);    
     
        bool result1 = verify(viewLoc, viewId);
        bool result2 = verify(projLoc, projId);
        bool result3 = verify(modelLoc, modelId);
     
        return (result1 && result2 && result3);
    }
     
     
    int main()
    {
        GLuint vao, vbo;
        int vertexCount = 6; 
        Display display;
        int numTries = 0;
        int successes = 0;
        while(1)
        {
            numTries++;
            bool result = initShaders();
            if(result)
                successes++;
            std::cout << "\rTries: " << numTries << "Successes: " << successes << std::flush;
     
        }   
    }

    I wrote this code snippet to see what is the success/failure rate of the initialization of the shader program.
    As I ran the program a few times, it seems that the failure rate is about 9%. So with this build opengl fails 9% of the time to initialize the shaders. 91 % of the time it works smoothly. For other implementations of mine where there are even more uniform variables, I get much worse success/failure ratio.
    I'm completely lost.

  7. #7
    Member Regular Contributor
    Join Date
    Jul 2012
    Posts
    418
    Quote Originally Posted by Motonen View Post
    No, the error code is never provoked as I run the program. Only the uniform check I included there notifies me that it fails to get the uniform location for the matrix variables I have. This only happens sometimes.
    So you mean you are calling glGetError, and you never face any OpenGL errors ?

    And in case it can help other people:
    It seems the OP is on Mac.
    He requests a forward compatible OpenGL 3.3 context.
    And he actually sets all the uniform variables to some values just right after he asks for their locations.

  8. #8
    Junior Member Newbie
    Join Date
    Sep 2017
    Posts
    7
    Ah, I hadn't included the glGetError. I called the function and it returned OpenGL error: 1282, GL_INVALID_OPERATION.
    I get GL_INVALID_OPERATION because I'm calling the getUniformLocation with a uniform variable name that doesn't exist in the shader program, even though it actually does. The variable name gets optimized out 9 % of the time.
    Yeah, I'm using mac and I'm calling the necessary compatibility functions in the constructor of Display.
    Quote Originally Posted by Silence View Post
    And he actually sets all the uniform variables to some values just right after he asks for their locations.
    No, I'm just asking the locations.
    Last edited by Motonen; 09-18-2017 at 02:50 AM.

  9. #9
    Member Regular Contributor
    Join Date
    Jul 2012
    Posts
    418
    Quote Originally Posted by Motonen View Post
    Ah, I hadn't included the glGetError. I called the function and it returned OpenGL error: 1282, GL_INVALID_OPERATION.
    I get GL_INVALID_ERROR because I'm calling the getUniformLocation with a uniform variable name that doesn't exist in the shader program, even though it actually does. The variable name gets optimized out 9 % of the time.
    Yeah, I'm using mac and I'm calling the necessary compatibility functions in the constructor of Display.
    Please, refer to this. It just says whether your program is not a program or it did not linked correctly.
    Please, check the OpenGL errors (with glGetError) when compiling and linking your shader.

    Quote Originally Posted by Motonen View Post
    No, I'm just asking the locations.
    You do:

    From https://github.com/Motonen/Uniform/b...r/src/main.cpp, line 54:
    Code :
    glUniformMatrix4fv(viewLoc, 1, GL_FALSE, glm::value_ptr(m));  
    glUniformMatrix4fv(projLoc, 1, GL_FALSE, glm::value_ptr(m));  
    glUniformMatrix4fv(modelLoc, 1, GL_FALSE, glm::value_ptr(m));

  10. #10
    Junior Member Newbie
    Join Date
    Sep 2017
    Posts
    7
    Alright so I was wrong about the glGetError. The GL_INVALID_OPERATION comes from a failure to compile/link the shaders most likely.
    I called the glGetError in the midst of the compilation process and I received sometimes the flag GL_INVALID_OPERATION. Most of the time it worked fine.
    I think the root of the problem lies on the loadShaders function.

    Thank you Silence.

    However, I still haven't figured out why the loadShaders function produces such randomness.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •