Problem, matrix elements not in the right order in my SSBO

Hi!
I use a compute shader to draw triangles so I declare this structure in the c++ source code :

struct Triangle {
            sf::Vector3f positions[3];
            math::Vec3f colours[3];
            sf::Vector2f texCoords[3];
            sf::Vector3f normal;
            unsigned int textureIndex;
            unsigned int refractReflect;
            float ratio;
            odfaeg::math::Matrix4f transform;
            odfaeg::math::Matrix4f textureMatrix;
        };

I’ve an std::vector of triangles I fill when I load objects on my render.

Then, I pass every datas to an SSBO like this :

glCheck(glBindBuffer(GL_SHADER_STORAGE_BUFFER, trianglesSSBO));

                glCheck(glBufferData(GL_SHADER_STORAGE_BUFFER, triangles.size() * 248, NULL, GL_DYNAMIC_DRAW));
                GLvoid* p = nullptr;
                glCheck(p = glMapBuffer(GL_SHADER_STORAGE_BUFFER, GL_WRITE_ONLY));
                memcpy(p, &triangles[0], triangles.size() * 248);
                glCheck(glUnmapBuffer(GL_SHADER_STORAGE_BUFFER));

248 is the size of the struct “Triangle”.

The problem is that every values are null in the compute shader, transform matrices, triangles positions, etc…

vec4 t = projMatrix * viewMatrix * triangles[i].transform * vec4(triangles[i].position[j], 1);
if (pixel_coords.x == 0 && pixel_coords.y == 0 && i == 0) {
drawNumber(ivec2(0, resolution.y-1), 1, vec4(1, 0, 0, 1), triangles[i].position[j].z);
}

Why opengl doesn’t fill my SSBO ?

Because you used vec3.

Ok so we cannot use vec3 with SSBO, I changed the type to vec4 then :

struct Triangle {
                                                      vec4 position[3];
                                                      vec4 color[3];
                                                      vec2 texCoords[3];
                                                      vec4 normal;
                                                      uint textureIndex;
                                                      uint refractReflect;
                                                      float ratio;
                                                      mat4 transform;
                                                      mat4 textureMatrix;
                                                  };

But it crash and sometimes it display the numbers but the values are not correct and then it crash.

I suspect that you need two words of padding before normal and one before transform. C++ implementations will typically align a vec* type to the alignment of a single float, whereas GLSL aligns them to a multiple of their size (or, for vec3, to a multiple of the size of a vec4).

You can use glGetProgramResource to query the offsets. Also, the GLSL definition needs an explicit layout(std430) qualification to get a deterministic layout.

std140 would work as well, though with a slightly different (and less like C++) layout.

I printed the values of the transformation matrix, they are correct but not in the right order in the compute shader.

here is the function when I print the matrix values on cpu side :

ostream& operator<< (ostream &out, const Matrix4f &mat4) {
        out<<mat4.m11<<" "<<mat4.m12<<" "<<mat4.m13<<" "<<mat4.m14<<std::endl;
        out<<mat4.m21<<" "<<mat4.m22<<" "<<mat4.m23<<" "<<mat4.m24<<std::endl;
        out<<mat4.m31<<" "<<mat4.m32<<" "<<mat4.m33<<" "<<mat4.m34<<std::endl;
        out<<mat4.m41<<" "<<mat4.m42<<" "<<mat4.m43<<" "<<mat4.m44<<std::endl;
        return out;
    }

I declare the variables like this :

float m11, m12, m13, m14; /** < the elements of the first row matrix.*/
        float m21, m22, m23, m24; /** < the elements of the second row matrix.*/
        float m31, m32, m33, m34; /** < the elements of the thirst row matrix.*/
        float m41, m42, m43, m44; /** < the elements of the fourth row matrix.*/

I’ve this output :

1 0 0 -450
0 1 0 -500
0 0 1 0
0 0 0 1

But when I print the matrix values in the shader here :

ivec2 print (ivec2 position, int nbPixels, vec4 color, mat4 matrix) {
                                                      int numberSpacing = 10;
                                                      for (uint i = 0; i < 4; i++) {
                                                         for (uint j = 0; j < 4; j++) {
                                                            position = print(position, nbPixels, color, matrix[i][j]);
                                                            position.x += numberSpacing;
                                                         }
                                                      }
                                                      return position;
                                                  }

I got this :

0 0 1 0
0 0 0 1
0 -450 -500 0
1 0 0 0

Which is a different matrix, why ?

Your matrix is transposed. This is because your C++ type is row-major, but C++ expects column major. You can fix that in the shader by setting the matrices to be row_major.

Also, you need to align the members of your structure in accord with whatever layout you specified in your SSBO.

Your matrix is transposed. This is because your C++ type is row-major, but C++ expects column major. You can fix that in the shader by setting the matrices to be row_major .

How to do that ?

Before sending the matrix to the SSBO I transpose it because in my c++ code this is row-major but in the shader this is column-major, but that doesn’t seems to work.

Also, you need to align the members of your structure in accord with whatever layout you specified in your SSBO.

I don’t understand what you mean, where is the layout of the SSBO ?

I changed my structure to solve alignement problem :

struct Triangle {
                                                      mat4 transform;
                                                      mat4 textureMatrix;
                                                      vec4 position[3];
                                                      vec4 color[3];
                                                      vec4 texCoords[3];
                                                      vec4 normal;
                                                      uint textureIndex;
                                                      uint refractReflect;
                                                      float ratio;
                                                  };

And now it’s working, SOLVED.