Search code examples
c++openglglsl

Passing values of different types to shader


I am using GLEW32 with GLFW and write code on C++. I have encountered some problems passing values to shader. I have successfully passed vec2, uvec3 etc. Now I want to pass multiple values for each vertex:

  1. uvec2 (or vec2 - not very important) - X and Y position;
  2. uvec4 - RGBA color. I can also use int to decode RGBA from int32, but uvec4 would be more convinient :)

But there's another problem: I can set different attributes types using glVertexAttribIPointer() or glVertexAttribPointer():

glVertexAttribIPointer(0, 2, GL_UNSIGNED_SHORT, ...);
glEnableVertexAttribArray(0);
glVertexAttribIPointer(1, 4, GL_UNSIGNED_BYTE, ...);
glEnableVertexAttribArray(1);

But I cannot pass values of different types to glBufferData():

glBufferData(GL_ARRAY_BUFFER, sizeof(array), array, GL_DYNAMIC_DRAW); // Just one array!!!

I tried to do this using uniforms, but the code was tooo bulky and inefficient that I gave it up. Are there any ways to do such a manipulations "properly"?


Solution

  • I found a solution in Kai Burjack's comment. I made a structure to keep data and send it. The code is:

    struct dataToSend
    {
        GLushort x, y;
        GLubyte r, g, b, a;
    }
    ...
    glVertexAttribIPointer(0, 2, GL_UNSIGNED_SHORT, sizeof(dataToSend), (GLvoid *) 0);
    glEnableVertexAttribArray(0);
    glVertexAttribIPointer(1, 4, GL_UNSIGNED_BYTE, sizeof(dataToSend), (GLvoid *) (2 * sizeof(GLushort)));
    glEnableVertexAttribArray(1);
    ...
                // (pixels) x      y       r    g    b    a
    dataToSend data [4] = {{width, height, 255, 255, 0,   255},  // Corner 1 (Up-Right)
                           {width, 0,      255, 0,   255, 255},  // Corner 2 (Down-Right)
                           {0,     0,      0,   255, 0,   0},    // Corner 3 (Down-Left)
                           {0,     height, 0,   255, 255, 255}}; // Corner 4 (Up-Left)
    glBufferData(GL_ARRAY_BUFFER, sizeof(data), (GLvoid *) data, GL_DYNAMIC_DRAW);
    

    That was kinda weird experience to use GLvoid and point to a structure instead of array but this lets one to pass almost any data to shaders. The result image is here: Rendered image