0
105 Jul 12, 2011 at 09:05

Hi everybody, i am having hard times converting some code into opengl shaders since i am about to convert a big bulk of previous code into glsl.
My problem is the following:
when i pass the matrices ( sp?? ) in the vertex shader and do the computation like this :

gl_Position = (ProjectionMatrix * ViewMatrix * ModelMatrix) * in_Position ;

everything works fine

so my idea is to move the matrix calculation away from the vertex shader and perform the computation entirely on the cpu since the matrix doesn’ changes trhough all the vertices sent to the graphics card

so i do something like this :

gl_Position = (ProjViewModelMatrix) * in_Position ;

the ProjViewModelMatrix is computed entirely on the CPU and i pass it trhough an uniform , the problem is that i get a blank screen if i use the simplest matrix possibile like this :

float s=1.0f

p[ 0]=s; p[ 1]=0; p[ 2]=0; p[ 3]=0;
p[ 4]=0; p[ 5]=s; p[ 6]=0; p[ 7]=0;
p[ 8]=0; p[ 9]=0; p[10]=s; p[11]=0;
p[12]=0; p[13]=0; p[14]=0; p[15]=1;

the model is drawn correctly but without a projection of course, but let’s
perform a simple translation, this means that p[12]=x, p[13]=y,p[14]= z;
now, if i put a value different from 1 in the p[14] entry i get a blank screen
since the model is drawn away from the observer
how can i solve this problem ?
But better yet, how can i correctly perform computation to match the built in glsl matrix computations ?
i have looked around for tutorial but they always use the built in glsl matrix computations , i haven’t seen anyone doing the computation on the cpu , at least not in a public forum or site.
Thanks for any suggestion i am driving nuts.

11 Replies

Please log in or register to post a reply.

0
101 Jul 12, 2011 at 11:02

@v71

Hi everybody, i am having hard times converting some code into opengl shaders since i am about to convert a big bulk of previous code into glsl.
My problem is the following:
when i pass the matrices ( sp?? ) in the vertex shader and do the computation like this :

gl_Position = (ProjectionMatrix * ViewMatrix * ModelMatrix) * in_Position ;

everything works fine

so my idea is to move the matrix calculation away from the vertex shader and perform the computation entirely on the cpu since the matrix doesn’ changes trhough all the vertices sent to the graphics card

so i do something like this :

gl_Position = (ProjViewModelMatrix) * in_Position ;

the ProjViewModelMatrix is computed entirely on the CPU and i pass it trhough an uniform , the problem is that i get a blank screen if i use the simplest matrix possibile like this :

float s=1.0f

p[ 0]=s; p[ 1]=0; p[ 2]=0; p[ 3]=0;
p[ 4]=0; p[ 5]=s; p[ 6]=0; p[ 7]=0;
p[ 8]=0; p[ 9]=0; p[10]=s; p[11]=0;
p[12]=0; p[13]=0; p[14]=0; p[15]=1;

the model is drawn correctly but without a projection of course, but let’s
perform a simple translation, this means that p[12]=x, p[13]=y,p[14]= z;
now, if i put a value different from 1 in the p[14] entry i get a blank screen
since the model is drawn away from the observer
how can i solve this problem ?
But better yet, how can i correctly perform computation to match the built in glsl matrix computations ?
i have looked around for tutorial but they always use the built in glsl matrix computations , i haven’t seen anyone doing the computation on the cpu , at least not in a public forum or site.
Thanks for any suggestion i am driving nuts.

Remember that opengl is based on a right handed coordinates system, therefore if you specify positive z (and you expect to see things to go deep into the screen) that means everything will go on the back of you.
Try negative values for p[14], like -2 and so on…
Also consider that matrices are column major, therefore watch out the matrix order of multiplication as well …
Can happen dodgy things because of all of these small details.

0
105 Jul 12, 2011 at 11:17

I have tried using negative values, but i get no triangel rendered , the matrix i use is an identity ,matrix with only the translation componet set to a value negative or positive, but still i got nothing.
i can’t pin point the problem.

0
101 Jul 12, 2011 at 11:50

@v71

I have tried using negative values, but i get no triangel rendered , the matrix i use is an identity ,matrix with only the translation componet set to a value negative or positive, but still i got nothing.
i can’t pin point the problem.

some code would help …

0
102 Jul 12, 2011 at 13:17

If you perform the same multiplication on CPU there should be no problem. Make sure the order of multiplication of the matrices is the same as on the GPU. Could be also that OpenGL transposes matrices it passes to the shaders. I haven’t used GL internal matrices but I just pass the local->projection matrix to vertex shader uniform and it works fine. Here is an example how I calculate & pass the matrix to a GLSL vertex shader (line 177) and here is function (transform_static_pos_l2p in line 63) using the uniform in a shader.

Cheers, Jarkko

0
105 Jul 12, 2011 at 22:01

Solved, opengl shaders does matrix computation with the transposed matrices and reverse order of operation
for example in a shader you write

gl_position = proj * view * Model * in_Position;

Proj, View , Model are column major

while what happens is

gl_position = Model* view * Proj * in_Position

Model, View, Proj are row major

now begins the nightmare for normal matrix computation

0
175 Jul 12, 2011 at 22:30

Hehe, the ol matrix order strikes again. OGL doesn’t transpose matrices magically, it assumes you’re passing in column major matrices. The way you setup your matrix is in row-major format (the way DX likes it), so in essence you’re passing a transposed matrix to OGL. It is as you discovered, simply reverse the order of multiplication and you have an instant fix.

0
105 Jul 13, 2011 at 08:24

I thought initially that was an order problem, but something deeper is going on, all the tutorials and the old code i had worked for opengl .
When i had to use shaders i noticed that the code didn’t work.
So i think that the ‘old’ opengl convention is column major, but inside the shader the preferred way is row convention.
I tried to transpose the order of matrices and reverse the multiplication to have a tangible proof, with no effect.
It doesn’t seems the problem is referred anywhere and all the tutorial i have seen use the form
gl_position = P * v * m *in_position;

now i have also read that being p,v,m uniforms, the shader should cache results and use the matrix product for all incoming vertices (sp??).
I haven’t read this in the official documentation and i don’t trhust internet claims.
So i decided to perform all matrix computation on a cpu level and let the gpu do the rest.
By the way does someone have a good idea how to compute the normal matrix to cope with this problem ?
thanks to jarkoll for having pointed me to the correct hint, he calls the uniform mvp that was a good clue.

0
101 Jul 13, 2011 at 21:36

Normal matrix is transpose of inverse of upper left 3x3 model-view matrix - see here (glsl specs): http://www.opengl.org/registry/doc/GLSLangSpec.4.10.6.clean.pdf

7.4.1. Compatibility Profile State uniform mat3 gl_NormalMatrix; // transpose of the inverse of the
// upper leftmost 3x3 of gl_ModelViewMatrix

Not that you can optimize calculation of inverse away, if you don’t have scaling in your model-view transform matrix. Then normal matrix is simply upper left 3x3 matrix of your model-view transform:

mat3 normal_matrix = mat3(Model* view);

0
105 Jul 13, 2011 at 22:19

So i just pick up the 3x3 submatrix , invert and transpose ? i will try tomorrow
today i worked on my smld ( simple mesh language descriptor ), by the way if i am not wrong the rotation matrix is
formed by orthogonal vectors so inverting is equal to transpose the matrix, tranposing the matrix two times
give the same matrix back , so i shoul djust pick the 3x3 submatrix , am i correct on this ?

0
165 Jul 13, 2011 at 22:51

Like he said:
@martinsm

Not that you can optimize calculation of inverse away, if you don’t have scaling in your model-view transform matrix. Then normal matrix is simply upper left 3x3 matrix of your model-view transform:

0
105 Jul 14, 2011 at 08:31

OOpss… :-/