# The Industry's Foundation for High Performance Graphics

1. ## MVP functions

Hi,
I'm very new to OpenGL and for various reasons I'm rolling my own functions to calculate the various parts of my MVP matrix (described here). Anyway the code based off of them doesn't work (naturally...) and i would greatly appreciate if someone with a few minutes could take a look at them and check whether they're at fault, since I can't find a good way to isolate them from the rest of the code, so can't tell where the error is.
Angus
Code :
```void perspective(float fovy, float aspect, float zNear, float zFar, float result[4][4])
{
float f=1/tanf(fovy/2);

result[0][0]=f/aspect;
result[0][1]=0;
result[0][2]=0;
result[0][3]=0;
result[1][0]=0;
result[1][1]=f;
result[1][2]=0;
result[1][3]=0;
result[2][0]=0;
result[2][1]=0;
result[2][2]=(zFar+zNear)/(zNear-zFar);
result[2][3]=(2*zNear*zFar)/(zNear-zFar);
result[3][0]=0;
result[3][1]=0;
result[3][2]=-1;
result[3][3]=0;
}

void crossproduct(float a[4], float b[4], float result[4]);

void lookat(float eyeX, float eyeY, float eyeZ, float centreX, float centreY, float centreZ, float upX, float upY, float upZ, float result[4][4])
{
float f[4] = {centreX-eyeX, centreY-eyeY, centreZ-eyeZ, 1};
float u[4] = {upX, upY, upZ, 1};
float s[4];
float temp[4][4];
float temp2[4][4];
normalise(f);
normalise(u);

crossproduct(f, u, s);
crossproduct(s, f, u);

temp[0][0]=s[0];
temp[0][1]=s[1];
temp[0][2]=s[2];
temp[0][3]=0;
temp[1][0]=u[0];
temp[1][1]=u[1];
temp[1][2]=u[2];
temp[1][3]=0;
temp[2][0]=-f[0];
temp[2][1]=-f[1];
temp[2][2]=-f[2];
temp[2][3]=0;
temp[3][0]=0;
temp[3][1]=0;
temp[3][2]=0;
temp[3][3]=1;

translate(temp2, -eyeX, -eyeY, -eyeZ);
multmatrix(temp, temp2, result);
}

void crossproduct(float a[4], float b[4], float result[4])
{
result[0] = (a[1]*b[2]) - (a[2] * b[1]);
result[1] = (a[2]*b[0]) - (a[0] * b[2]);
result[2] = (a[0]*b[1]) - (a[1] * b[0]);
result[3] = 1;
}

void multmatrix(float a[4][4], float b[4][4], float result[4][4])
{
int i;
int j;
int k;
float total;

for(i=0;i<4;i++)
for(j=0;j<4;j++)
{
total=0;
for(k=0;k<4;k++)
total+=a[i][k]*b[k][j];
result[i][j]=total;
}

}

void translate(float result[4][4], float x, float y, float z)
{
result[0][0]=1;
result[0][1]=0;
result[0][2]=0;
result[0][3]=x;
result[1][0]=0;
result[1][1]=1;
result[1][2]=0;
result[1][3]=y;
result[2][0]=0;
result[2][1]=0;
result[2][2]=1;
result[2][3]=z;
result[3][0]=0;
result[3][1]=0;
result[3][2]=0;
result[3][3]=1;
}```

2. ## Re: MVP functions

I've only looked at your translate.
OpenGL expects matrices stored in float arrays to be column major, i.e. the first index is the column and the second is the row - your translate matrix are transposed.

3. ## Re: MVP functions

Thanks, don't know why I didn't think to check which way matrices should be. Will change that and see if it at all improves things.
Angus

4. ## Re: MVP functions

Yeah, an easy way to deal with this given that C/C++ is row-major order and OpenGL is column-major is: Just do row-major like C/C++ wants, and flip the transform order.

That is, instead of doing "P*V*M * v_obj = v_clip" like OpenGL wants, do this "v_obj * M*V*P = v_clip". In practice this means you use the transposes of the matrices, and you composite them in the opposite order. Then you can blissfully care less that OpenGL uses column major order.

6. ## Re: MVP functions

Tried flipping round the order of the transformations just now which didn't help. I'll do a full proper check of the entire piece of code tomorrow/over the next week, mainly worried about these bits of code as I've no real way to check they're working.
Just as a matter of interest, is there any good reason to keep the C code using row major matrices? I just did it because it seems intuitive and I hadn't checked properly but you seem to imply there's a good reason one might want to do that.

7. ## Re: MVP functions

is there any good reason to keep the C code using row major matrices?
No, not really. It's all purely conventional; just put the columns where you put the rows now. Your matrix multiplication functions will all work exactly the same.

8. ## Re: MVP functions

Originally Posted by Mjiig
is there any good reason to keep the C code using row major matrices?
Yes. Then you never have to do transposes to pass matrices to OpenGL. Further, you end up with matrix translate and basis vectors being in rows of the matrix rather than column which is more efficient to access. And you can just forget the whole column major issue on the C/C++ side.

9. ## Re: MVP functions

Thanks for all the help everyone, changed the matrices to be column major which didn't help at first, then found the real bug which made me feel like a total idiot. My program is filled with code to generate the MVP matrix but was missing the single line of code needed to load it into the shader!
Once I added that in it finally drew something and a couple of tweaks to undo a bit of damage I'd unintentionally done while debugging it finally drew what I wanted it to.
Thanks again
Angus

#### Posting Permissions

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