Part of the Khronos Group
OpenGL.org

The Industry's Foundation for High Performance Graphics

from games to virtual reality, mobile phones to supercomputers

Results 1 to 9 of 9

Thread: How to pass an array to a shader?

  1. #1
    Junior Member Newbie
    Join Date
    Nov 2016
    Posts
    10

    How to pass an array to a shader?

    I try this for 3 days now and spend about 6 hours searching the net for a simplistic and working example:

    How on earth, can I pass an array to my shader by uniform? Can someone give me a brief example of how the syntax in C++ AND GLSL is supposed to look like?

    I only succeed in setting the first element of the Array, but cant set any higher indices.

  2. #2
    Senior Member OpenGL Guru Dark Photon's Avatar
    Join Date
    Oct 2004
    Location
    Druidia
    Posts
    4,121
    See:
    * GLSL_Uniform#Uniform_management
    * GLSL_:_common_mistakes#How_to_use_glUniform

    Note the use of functions which set multiple elements which end with a "v" (e.g. glUniform4fv).

  3. #3
    Senior Member OpenGL Lord
    Join Date
    May 2009
    Posts
    5,904
    Quote Originally Posted by Patsch View Post
    I try this for 3 days now and spend about 6 hours searching the net for a simplistic and working example:

    How on earth, can I pass an array to my shader by uniform? Can someone give me a brief example of how the syntax in C++ AND GLSL is supposed to look like?

    I only succeed in setting the first element of the Array, but cant set any higher indices.
    You've asked this question several times in different locations. Are you sure you're not encountering a driver bug? What hardware are you using?

  4. #4
    Junior Member Newbie
    Join Date
    Nov 2016
    Posts
    10
    Quote Originally Posted by Alfonse Reinheart View Post
    You've asked this question several times in different locations. Are you sure you're not encountering a driver bug? What hardware are you using?
    I asked a somewhat related question on the stack. But the question on the stack was about my specific code, and all suggestions about fixing it did not work. Thats why I wanted to ask for a simple working example, since I didnt find any way of fixing my own code. Since Stack does basically not allow that kind of question, I asked it here. Hope that was okay.
    The problem is most probably not related to my hardware, since I tried it on my GeForce GTX 1050Ti, my Intel Onboard something, and made a friend check for the behaviour with the same unpleasent results on a GeForce GTX 960. I recognized different behaviour with different shader versions (330 made all vertices multiplied by the undefined array entries stuck on the middle of the screen, 220 rendered the whole model in another position and 420 didnt render it at all)

    See:
    * GLSL_Uniform#Uniform_management
    * GLSL_:_common_mistakes#How_to_use_glUniform

    Note the use of functions which set multiple elements which end with a "v" (e.g. glUniform4fv).
    I did read both documents multiple time, yet I cant get it to work.

    If I change the shader to multiple uniforms and asign each uniform a mat4 it works though, giving expected results, so my input code is most probably alright.

  5. #5
    Senior Member OpenGL Guru Dark Photon's Avatar
    Join Date
    Oct 2004
    Location
    Druidia
    Posts
    4,121
    Quote Originally Posted by Patsch View Post
    If I change the shader to multiple uniforms and asign each uniform a mat4 it works though, giving expected results, so my input code is most probably alright.
    ...for the case where you're using non-array uniforms, yes. Probably so.

    However, it doesn't establish that for the array uniform case.

    Post a short, standalone GLUT test program which illustrates your problem here. That'll make it easy for a number of folks to try your code, give you results feedback, and probably tell you how to fix your problem. Here's a shell to copy/paste your code into:

    Code cpp:
    //-----------------------------------------------------------------------
    //  Stand-alone GLUT test program
    //-----------------------------------------------------------------------
     
    #include <stdio.h>
    #include <string.h>
    #include <stdlib.h>
    #include <GL/glew.h>
    #include <GL/glut.h>
     
    //-----------------------------------------------------------------------
     
    void checkGLError( const char hdr[] )
    {
        int err = glGetError();
        if( err )
        {
            fprintf(stderr, "ERROR %s: %s\n", hdr, gluErrorString(err));
            exit(1);
        }
    }
     
    //-----------------------------------------------------------------------
     
    void init()
    {
        //------------------------------------------------------------
        // Put your GL init code here.
        //------------------------------------------------------------
     
        // glGenBuffers( 1, &Vbo_handle );
        //   etc.
     
        checkGLError( "init" );
    }
     
    //-----------------------------------------------------------------------
     
    void reshape( int width, int height )
    {
        glViewport(0, 0, width, height);
    }
     
    //-----------------------------------------------------------------------
     
    void display()
    {
        // Clear screen
        glClearColor( 0.1f, 0.1f, 0.43f, 1.0f );
        glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
     
        //------------------------------------------------------------
        // Put your GL draw code here.
        //------------------------------------------------------------
     
        // Swap
        glutSwapBuffers();
     
        // Cause display() to be called again.
        glutPostRedisplay();
        checkGLError( "End of display()" );
    }
     
    //-----------------------------------------------------------------------
     
    void keyboard( unsigned char key, int x, int y )
    {
        switch (key)
        {
            case 27:         // ESC quits
                exit(0);
                break;
        }
    }
     
    int main( int argc, char** argv )
    {
        // Init GLUT
        glutInit( &argc, argv );
        glutInitDisplayMode(  GLUT_RGBA | GLUT_DEPTH | GLUT_DOUBLE  );
        glutCreateWindow( argv[0] );
     
        glutKeyboardFunc( keyboard );
        glutDisplayFunc( display );
        glutReshapeFunc( reshape );
     
        glutReshapeWindow( 400,400 );
     
        // Init GLEW
        GLenum err = glewInit();
        if ( err != GLEW_OK )
        {
            // Problem: glewInit failed, something is seriously wrong.
            fprintf( stderr, "Error: %s\n", glewGetErrorString(err) );
            exit(1);
        }
     
        printf( "GL_RENDERER = %s\n", glGetString( GL_RENDERER) );
     
        init();
     
        glutMainLoop();
        return 0;
    }
    Last edited by Dark Photon; 08-24-2017 at 05:36 AM.

  6. #6
    Junior Member Newbie
    Join Date
    Nov 2016
    Posts
    10
    Quote Originally Posted by Dark Photon View Post
    ...for the case where you're using non-array uniforms, yes. Probably so.

    However, it doesn't establish that for the array uniform case.

    Post a short, standalone GLUT test program ...

    Thanks a lot for your advice! I actually got the test program up and running with the very same syntax I am using in my other project. Everything works fine, all array slots are set. Yet, the other project still doesnt work, double checked pretty much everything, "cout"ed my matrices, checked again with unique non-array uniforms:

    Code :
    	int jointLoc1 = glGetUniformLocation(shaderID, "jointTransforms1");
    	glUniformMatrix4fv(jointLoc1, 1, GL_FALSE, &finalBoneTransformContainer[0].mat[0][0]);
     
    	int jointLoc2 = glGetUniformLocation(shaderID, "jointTransforms2");
    	glUniformMatrix4fv(jointLoc2, 1, GL_FALSE, &finalBoneTransformContainer[1].mat[0][0]);
    works.


    Code :
    glUniformMatrix4fv(jointLoc, 20, GL_FALSE, &finalBoneTransformContainer[0].mat[0][0]);

    still doesnt, while it does in the test program.


    Is it actually possible, that there is a difference in using GLFW and GLAD (my project which doesnt work), and using GLEW and GLUT? Thats pretty much the last possible difference I can find.

    Edit: Tried to substitute GLAD for GLEW, didnt change anything.
    Last edited by Patsch; 08-24-2017 at 04:50 PM.

  7. #7
    Member Regular Contributor
    Join Date
    May 2016
    Posts
    415
    did you read the article DarkPhoton liked to in his post above ?
    https://www.khronos.org/opengl/wiki/..._use_glUniform

    did you read the function's description (completely) ?
    https://www.khronos.org/registry/Ope...lUniform.xhtml

    did you check for GL errors ? do you get any ?
    what error(s) ? which function throws the error ?

    did you try to create a debug context ? maybe the GL debug callback gives you a hint in case you're doing something wrong ...

  8. #8
    Junior Member Newbie
    Join Date
    Nov 2016
    Posts
    10
    I finally(!!!) solved this enigma
    I realized, that my joint indices were messed up by glVertexAttribPointer(4, 4, GL_INT... expected the GL_INT to define the type, missing the I in the function call. While at the same time using ivec4 as shader input. Changing shader input to vec4 made things work out. Trying to set the VAP to int though.

    Thanks for everyones attempt to give me a hand!

  9. #9
    Senior Member OpenGL Pro
    Join Date
    Jan 2007
    Posts
    1,680
    This is why it's important to say what you're trying to do as well as how you're trying to do it. If your OP had told us this was happening when indexing into an array of bone matrices, you would have probably had the solution within the first 2 replies, because this is actually an extremely common mistake.

Posting Permissions

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