Hi

I am writing a c matrix 4 library to do my opengl rendering. I created some simple data structures and wanted to make sure that I setup the memory in the correct way so that I do not have to transpose the data when I send it over to the GPU.

Code :
typedef struct mat4
{
    double m[16];
}mat4;
 
mat4* newMat4(const vec3f *c1, const vec3f *c2, const vec3f *c3, const vec3f *c4);
mat4* newMat4identity(void);
 
void newMat4x(mat4* out, const vec3f *c1, const vec3f *c2, const vec3f *c3, const vec3f *c4);
void newMat4xc(mat4* out, const mat4* m4);
void newMat4identityx(mat4* out);
 
 
void mat4add(mat4* out, const mat4* a, const mat4* b);
void mat4sub(mat4* out, const mat4* a, const mat4* b);
void mat4mul(mat4* out, const mat4* a, const mat4* b);
 
void mat4mulvec3(vec3f* out, const vec3f* v, const mat4* a);
 
void mat4trans(mat4* out, const double x, const double y, const double z);
void mat4transv(mat4* out, const vec3f* v);
 
void mat4rotate(mat4* out, const double angle, const double x, const double y, const double z);
void mat4rotatev(mat4* out, const double angle, const vec3f* v);
void mat4xrotate(mat4* out, const double angle, const double x);
void mat4yrotate(mat4* out, const double angle, const double y);
void mat4zrotate(mat4* out, const double angle, const double z);
 
void mat4scale(mat4* out, const double x, const double y, const double z);
void mat4scalev(mat4* out, const vec3f* v);
 
int mat4inverse(mat4* out, const mat4* in);
 
void mat4transpose(mat4* out, const mat4* in);
 
static double iData[] = { 1, 0, 0, 0,
                          0, 1, 0, 0,
                          0, 0, 1, 0,
                          0, 0, 0, 1 };
 
static mat4*copyMatrix(mat4 *out, const double *data)
{
    out->m[0]  = data[0];
    out->m[4]  = data[4];
    out->m[8]  = data[8];
    out->m[12] = data[12];
 
    out->m[1]  = data[1];
    out->m[5]  = data[5];
    out->m[9]  = data[9];
    out->m[13] = data[13];
 
    out->m[2]  = data[2];
    out->m[6]  = data[6];
    out->m[10] = data[10];
    out->m[14] = data[14];
 
    out->m[3]  = data[3];
    out->m[7]  = data[7];
    out->m[11] = data[11];
    out->m[15] = data[15];
    return out;
 
}
 
mat4* newMat4(const vec3f *c1, const vec3f *c2, const vec3f *c3, const vec3f *c4)
{
    double data[] = { c1->p[0], c2->p[0], c3->p[0], c4->p[0],
                      c1->p[1], c2->p[1], c3->p[1], c4->p[1],
                      c1->p[2], c2->p[2], c3->p[2], c4->p[2],
                         0,        0,       0,        1      };
 
    mat4* v = (mat4*)malloc(sizeof(mat4));
    return copyMatrix(v, data);
}
 
mat4* newMat4c(const mat4* m4)
{
    mat4* v = (mat4*)malloc(sizeof(mat4));
    return copyMatrix(v, m4->m);
}
 
mat4* newMat4identity(void)
{
    mat4* v = (mat4*)malloc(sizeof(mat4));
    return copyMatrix(v, iData);
}
 
void newMat4x(mat4* out, const vec3f *c1, const vec3f *c2, const vec3f *c3, const vec3f *c4)
{
    double data[] = { c1->p[0], c2->p[0], c3->p[0], c4->p[0],
                      c1->p[1], c2->p[1], c3->p[1], c4->p[1],
                      c1->p[2], c2->p[2], c3->p[2], c4->p[2],
                      0,        0,       0,        1      };
    copyMatrix(out, data);
}
 
void newMat4xc(mat4* out, const mat4* m4)
{
    copyMatrix(out, m4->m);
}
 
void newMat4identityx(mat4* out)
{
    copyMatrix(out, iData);
}
 
void mat4add(mat4* out, const mat4* a, const mat4* b)
{
    double d[16];
    for(size_t i = 0; i < 16; i++)
    {
        d[i] = a->m[i] + b->m[i];
    }
    copyMatrix(out, d);
}
 
void mat4sub(mat4* out, const mat4* a, const mat4* b)
{
    double d[16];
    for(size_t i = 0; i < 16; i++)
    {
        d[i] = a->m[i] - b->m[i];
    }
    copyMatrix(out, d);
}
 
void mat4mul(mat4* out, const mat4* a, const mat4* b)
{
    out->m[0]  = ( a->m[0]  *  b->m[0]) + (a->m[1]  * b->m[4]) + (a->m[2]  *  b->m[8]) + (a->m[3]  * b->m[12] );
    out->m[4]  = ( a->m[4]  *  b->m[0]) + (a->m[5]  * b->m[4]) + (a->m[6]  *  b->m[8]) + (a->m[7]  * b->m[12] );
    out->m[8]  = ( a->m[8]  *  b->m[0]) + (a->m[9]  * b->m[4]) + (a->m[10] *  b->m[8]) + (a->m[11] * b->m[12] );
    out->m[12] = ( a->m[12] *  b->m[0]) + (a->m[13] * b->m[4]) + (a->m[14] *  b->m[8]) + (a->m[15] * b->m[12] );
 
    out->m[1]  = ( a->m[0]  *  b->m[1]) + (a->m[1]  * b->m[5]) + (a->m[2]  * b->m[9])  + (a->m[3]  * b->m[13] );
    out->m[5]  = ( a->m[4]  *  b->m[1]) + (a->m[5]  * b->m[5]) + (a->m[6]  * b->m[9])  + (a->m[7]  * b->m[13] );
    out->m[9]  = ( a->m[8]  *  b->m[1]) + (a->m[9]  * b->m[5]) + (a->m[10] * b->m[9])  + (a->m[11] * b->m[13] );
    out->m[13] = ( a->m[12] *  b->m[1]) + (a->m[13] * b->m[5]) + (a->m[14] * b->m[9])  + (a->m[15] * b->m[13] );
 
    out->m[2]  = ( a->m[0]  *  b->m[2]) + (a->m[1]  * b->m[6]) + (a->m[2]  * b->m[10]) + (a->m[3]  * b->m[14] );
    out->m[6]  = ( a->m[4]  *  b->m[2]) + (a->m[5]  * b->m[6]) + (a->m[6]  * b->m[10]) + (a->m[7]  * b->m[14] );
    out->m[10] = ( a->m[8]  *  b->m[2]) + (a->m[9]  * b->m[6]) + (a->m[10] * b->m[10]) + (a->m[11] * b->m[14] );
    out->m[14] = ( a->m[12] *  b->m[2]) + (a->m[13] * b->m[6]) + (a->m[14] * b->m[10]) + (a->m[15] * b->m[14] );
 
    out->m[3]  = ( a->m[0]  *  b->m[3]) + (a->m[1]  * b->m[7]) + (a->m[2]  * b->m[11]) + (a->m[3]  * b->m[15] );
    out->m[7]  = ( a->m[4]  *  b->m[3]) + (a->m[5]  * b->m[7]) + (a->m[6]  * b->m[11]) + (a->m[7]  * b->m[15] );
    out->m[11] = ( a->m[8]  *  b->m[3]) + (a->m[9]  * b->m[7]) + (a->m[10] * b->m[11]) + (a->m[11] * b->m[15] );
    out->m[15] = ( a->m[12] *  b->m[3]) + (a->m[13] * b->m[7]) + (a->m[14] * b->m[11]) + (a->m[15] * b->m[15] );
}
 
void mat4mulvec3(vec3f* out, const vec3f* v, const mat4* a)
{
    out->p[0] = a->m[0] * v->p[0] + a->m[1] * v->p[1] + a->m[2]  * v->p[2];
    out->p[1] = a->m[4] * v->p[0] + a->m[5] * v->p[1] + a->m[6]  * v->p[2];
    out->p[2] = a->m[8] * v->p[0] + a->m[9] * v->p[1] + a->m[10] * v->p[2];
}
 
void mat4trans(mat4* out, const double x, const double y, const double z)
{
    out->m[3]  += x;
    out->m[7]  += y;
    out->m[11] += z;
}
 
void mat4transv(mat4* out, const vec3f* v)
{
    out->m[3]  += v->p[0];
    out->m[7]  += v->p[1];
    out->m[11] += v->p[2];
}
 
void mat4rotate(mat4*  out, const double angle, const double x, const double y, const double z)
{
    double mAng = toRadiansr(angle);
    double cosZangle = cos(z);
    double sinZangle = sin(z);
 
    double sinYangle = sin(z);
    double cosYangle = cos(z);
 
    double sinXangle = sin(x);
    double cosXangle = cos(x);
 
    out->m[0]   = cos(mAng) * cos(mAng);
    out->m[4]   = cos(mAng) * sin(mAng);
    out->m[8]   = sin(mAng);
 
    out->m[1]   = ((cos(mAng) * sin(mAng)) + (sin(mAng) * sin(mAng) * cos(mAng)));
    out->m[5]   = ((cos(mAng) * cos(mAng)) - (sin(mAng) * sin(mAng) * sin(mAng)));
    out->m[9]   = -sin(mAng)  * cos(mAng);
 
    out->m[2]   = ((sin(mAng) * sin(mAng)) - (cos(mAng) * sin(mAng) * cos(mAng)));
    out->m[6]   = ((sin(mAng) * sin(mAng)) + (cos(mAng) * sin(mAng) * sin(mAng)));
    out->m[10]  = ((cos(mAng)  * cos(mAng)));
}
 
void mat4rotatev(mat4* out, const double angle, const vec3f* v)
{
    double mAng = toRadiansr(angle);
    double x, y, z;
    x = v->p[0];
    y = v->p[1];
    z = v->p[2];
 
    out->m[0]   = cos(y) * cos(z * mAng);
    out->m[4]   = cos(y) * sin(z * mAng);
    out->m[8]   = sin(y);
 
    out->m[1]   = ((cos(y) * sin(z)) + (sin(x) * sin(y) * cos(z)));
    out->m[5]   = ((cos(y) * cos(z)) - (sin(x) * sin(y) * sin(z)));
    out->m[9]   = -sin(x)  * cos(y);
 
    out->m[2]   = ((sin(x) * sin(z)) - (cos(x) * sin(y) * cos(z)));
    out->m[6]   = ((sin(x) * sin(z)) + (cos(x) * sin(y) * sin(z)));
    out->m[10]  = (cos(x)  * cos(y));
}
 
 
void mat4xrotate(mat4* out, const double angle, const double x)
{
    double mAng = toRadiansr(angle);
    out->m[5]  = cos(mAng);
    out->m[9]  = -sin(mAng);
 
    out->m[6]  = sin(mAng);
    out->m[10] = cos(mAng);
}
 
void mat4yrotate(mat4* out, const double angle, const double y)
{
    double mAng = toRadiansr(angle);
    out->m[0]  = cos(mAng);
    out->m[8]  = sin(mAng);
 
    out->m[2]  = -sin(mAng);
    out->m[10] = cos(mAng);
}
 
void mat4zrotate(mat4* out, const double angle, const double z)
{
    double mAng = toRadiansr(angle);
    out->m[0] = cos(mAng);
    out->m[4] = sin(mAng);
 
    out->m[1] = -sin(mAng);
    out->m[5] = cos(mAng);
}
 
void mat4scale(mat4* out, const double x, const double y, const double z)
{
    out->m[0]   *= x;
    out->m[5]   *= y;
    out->m[10]  *= z;
}
 
void mat4scalev(mat4* out, const vec3f* v)
{
    out->m[0]   *= v->p[0];
    out->m[5]   *= v->p[1];
    out->m[10]  *= v->p[2];
}
 
int mat4inverse(mat4* out, const mat4* in)
{
    double inv[16], det;
    int i;
 
    inv[0] =  in->m[5]  * in->m[10] * in->m[15] -
              in->m[5]  * in->m[11] * in->m[14] -
              in->m[9]  * in->m[6]  * in->m[15] +
              in->m[9]  * in->m[7]  * in->m[14] +
              in->m[13] * in->m[6]  * in->m[11] -
              in->m[13] * in->m[7]  * in->m[10];
 
    inv[4] = -in->m[4]  * in->m[10] * in->m[15] +
              in->m[4]  * in->m[11] * in->m[14] +
              in->m[8]  * in->m[6]  * in->m[15] -
              in->m[8]  * in->m[7]  * in->m[14] -
              in->m[12] * in->m[6]  * in->m[11] +
              in->m[12] * in->m[7]  * in->m[10];
 
    inv[8] =  in->m[4]  * in->m[9]  * in->m[15] -
              in->m[4]  * in->m[11] * in->m[13] -
              in->m[8]  * in->m[5]  * in->m[15] +
              in->m[8]  * in->m[7]  * in->m[13] +
              in->m[12] * in->m[5]  * in->m[11] -
              in->m[12] * in->m[7]  * in->m[9];
 
    inv[12] = -in->m[4]  * in->m[9] * in->m[14] +
               in->m[4]  * in->m[10] * in->m[13] +
               in->m[8]  * in->m[5] * in->m[14] -
               in->m[8]  * in->m[6] * in->m[13] -
               in->m[12] * in->m[5] * in->m[10] +
               in->m[12] * in->m[6] * in->m[9];
 
    inv[1] =  -in->m[1]  * in->m[10] * in->m[15] +
              in->m[1]  * in->m[11] * in->m[14] +
              in->m[9]  * in->m[2] * in->m[15] -
              in->m[9]  * in->m[3] * in->m[14] -
              in->m[13] * in->m[2] * in->m[11] +
              in->m[13] * in->m[3] * in->m[10];
 
    inv[5] =  in->m[0]  * in->m[10] * in->m[15] -
              in->m[0]  * in->m[11] * in->m[14] -
              in->m[8]  * in->m[2] * in->m[15] +
              in->m[8]  * in->m[3] * in->m[14] +
              in->m[12] * in->m[2] * in->m[11] -
              in->m[12] * in->m[3] * in->m[10];
 
    inv[9] =  -in->m[0]  * in->m[9] * in->m[15] +
              in->m[0]  * in->m[11] * in->m[13] +
              in->m[8]  * in->m[1] * in->m[15] -
              in->m[8]  * in->m[3] * in->m[13] -
              in->m[12] * in->m[1] * in->m[11] +
              in->m[12] * in->m[3] * in->m[9];
 
    inv[13] =  in->m[0]  * in->m[9] * in->m[14] -
               in->m[0]  * in->m[10] * in->m[13] -
               in->m[8]  * in->m[1] * in->m[14] +
               in->m[8]  * in->m[2] * in->m[13] +
               in->m[12] * in->m[1] * in->m[10] -
               in->m[12] * in->m[2] * in->m[9];
 
    inv[2] =  in->m[1]  * in->m[6] * in->m[15] -
              in->m[1]  * in->m[7] * in->m[14] -
              in->m[5]  * in->m[2] * in->m[15] +
              in->m[5]  * in->m[3] * in->m[14] +
              in->m[13] * in->m[2] * in->m[7] -
              in->m[13] * in->m[3] * in->m[6];
 
    inv[6] =  -in->m[0]  * in->m[6] * in->m[15] +
              in->m[0]  * in->m[7] * in->m[14] +
              in->m[4]  * in->m[2] * in->m[15] -
              in->m[4]  * in->m[3] * in->m[14] -
              in->m[12] * in->m[2] * in->m[7] +
              in->m[12] * in->m[3] * in->m[6];
 
    inv[10] =  in->m[0]  * in->m[5] * in->m[15] -
               in->m[0]  * in->m[7] * in->m[13] -
               in->m[4]  * in->m[1] * in->m[15] +
               in->m[4]  * in->m[3] * in->m[13] +
               in->m[12] * in->m[1] * in->m[7] -
               in->m[12] * in->m[3] * in->m[5];
 
    inv[14] =  -in->m[0]  * in->m[5] * in->m[14] +
               in->m[0]  * in->m[6] * in->m[13] +
               in->m[4]  * in->m[1] * in->m[14] -
               in->m[4]  * in->m[2] * in->m[13] -
               in->m[12] * in->m[1] * in->m[6] +
               in->m[12] * in->m[2] * in->m[5];
 
    inv[3] =  -in->m[1] * in->m[6] * in->m[11] +
              in->m[1] * in->m[7] * in->m[10] +
              in->m[5] * in->m[2] * in->m[11] -
              in->m[5] * in->m[3] * in->m[10] -
              in->m[9] * in->m[2] * in->m[7] +
              in->m[9] * in->m[3] * in->m[6];
 
    inv[7] =  in->m[0] * in->m[6] * in->m[11] -
              in->m[0] * in->m[7] * in->m[10] -
              in->m[4] * in->m[2] * in->m[11] +
              in->m[4] * in->m[3] * in->m[10] +
              in->m[8] * in->m[2] * in->m[7] -
              in->m[8] * in->m[3] * in->m[6];
 
    inv[11] = -in->m[0] * in->m[5] * in->m[11] +
              in->m[0] * in->m[7] * in->m[9] +
              in->m[4] * in->m[1] * in->m[11] -
              in->m[4] * in->m[3] * in->m[9] -
              in->m[8] * in->m[1] * in->m[7] +
              in->m[8] * in->m[3] * in->m[5];
 
    inv[15] = in->m[0] * in->m[5] * in->m[10] -
              in->m[0] * in->m[6] * in->m[9] -
              in->m[4] * in->m[1] * in->m[10] +
              in->m[4] * in->m[2] * in->m[9] +
              in->m[8] * in->m[1] * in->m[6] -
              in->m[8] * in->m[2] * in->m[5];
 
    det = in->m[0] * inv[0] + in->m[1] * inv[4] + in->m[2] * inv[8] + in->m[3] * inv[12];
 
    if (det == 0)
    {
        printf("oh oh!");
        return -1;
    }
 
    det = 1.0 / det;
 
    for (i = 0; i < 16; i++)
        out->m[i] = inv[i] * det;
 
    return 0;
}
 
void mat4transpose(mat4* out, const mat4* in)
{
    out->m[0]  = in->m[0];
    out->m[1]  = in->m[4];
    out->m[2]  = in->m[8];
    out->m[3]  = in->m[12];
 
    out->m[4]  = in->m[1];
    out->m[5]  = in->m[5];
    out->m[6]  = in->m[9];
    out->m[7]  = in->m[13];
 
    out->m[8]  = in->m[2];
    out->m[9]  = in->m[6];
    out->m[10] = in->m[10];
    out->m[11] = in->m[14];
 
    out->m[12]  = in->m[3];
    out->m[13]  = in->m[7];
    out->m[14] = in->m[11];
    out->m[15] = in->m[15];
}

Is this the proper memory layout to send the data over to opengl without needing to do the transpose?