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.
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?