LMatrix3f - cgGLSetMatrixParameterfc

If I have an LMatrix3f m(row0->1,2,3,row1->4,5,6,row2->7,8,9) and I pass it to a shader as a float3x3 in this way:

float * data = m.get_data() -> data = (1,2,3,4,5,6,7,8,9)
cgGLSetMatrixParameterfc(param,data)

my float3x3 in the shader is going to be m->transpose().

So what’s going at line 545 of glShaderContext_src.cxx

          case Shader::SMP_whole: cgGLSetMatrixParameterfc(p, data); continue;
          case Shader::SMP_transpose: cgGLSetMatrixParameterfr(p, data); continue;

It’s sending an array of floating-points, in column-order. If the mode is set to SMP_whole, it is passed to cgGLSetMatrixParameterfc, which passes it normally. In the case of SMP_transpose, it is sent to cgGLSetMatrixParameterfr (note the “r” at the end) which sends it transposed.

For the record, it is probably more useful to be able to send 4x4 matrices to the shader.

I wasn’t clear, my point is:

if a pass to the shader the data through

cgGLSetMatrixParameterfc(param,data)

in the shader I get the transpose.

that’s why lines 545/46 are confusing me…

For the 4x4 matrix, your are definitely right, it was just an example. Anyway I think the idea would be to implement all the possible CG inputs.

At this point I have a good idea of how the shader system works, and I could get them done in 2/3 days, but I don’t know what to do with with the LMatrix class that handle only square matrices, and possible inputs includes 1x4,2x4,1x4,etc…

I could just implement something like:

nodepath->set_shader_input(float*) but I am not sure this is a good idea…

And this is the pastebin with all the possible inputs.

pastebin.com/m1c889a8

Any comments? I think most of them are completely unuseful i.e. fixed/half/bool float1x1 etc…

It may be possible that Panda stores the values in row-order rather than column-order. I think you can just fix this by transposing the matrix you are passing to the shader.

I think we only need to support square floating-point matrices, possibly even limited to float4x4 matrices. After all, if you need to pass a matrix to a shader, it will usually be float4x4 (sometimes float3x3).

NodePath->set_shader_input(float*) is not really a good idea, as this won’t work from Python code.

This may be helpful:
panda3d.org/manual/index.php/M … esentation

What about NodePath->set_shader_input(float*,int size)?
In case your answer is no, I am ready with another question:

How do you give to a shader an array of matrices?

No, Interrogate doesn’t support passing arrays that way.

drwr, do you perhaps have an idea what would be the best interface for a shaderinput that contains an array?

How about a CPTA_float?

David

Hm, but it’s also supposed to work for vectors, matrices and textures.

Hmm, well, arrays of vectors and matrices can be stuffed (somewhat clumsily) into a CPTA_float. Arrays of textures are more problematic, and perhaps we need a special construct for that.

How is it handled internally? Do the CG interface and OpenGL interface receive just a float * and size, or do they have something more sophisticated? How do arrays of textures work internally? Is it different from just assigning a set of textures via the normal scene graph attributes?

David

In the case of a matrix array, you just pass a 16 * size array of floats, and the size. In the case of a texture array, you pass the texture indices in an array again (with int pointer and size).
These texture indices can’t be resolved right away, because they are only known the moment that the ShaderContext starts passing the inputs.

For arrays the Cg Runtime function is like:

void cgGLSetParameterArray2f(CGparameter parameter,
       long startIndex, long numberOfElements,
       const float* array);

About PTA(type):

In the documentation at express/pointerToArray.h I found:

but there is no matching function for

PointerToArray<int>::PointerToArray(int);

Any idea on how can I get an int[10]?

That comment is out-of-date. The correct way to initialize a fixed-length array is:

PTA_int array = PTA_int::empty_array(10);

David

Perfect.

Thanks a lot.

I do think there needs to be an interface to pass an array of textures rather than an array of indices, and an array of matrices rather than an array of floats.

Maybe a way to construct ShaderInput and calling addElement or so?

Note that the CG Runtime takes always a ptr* as input, and it doesn’t care if it is a 1D array, a matrix or an array of matrices. So it could be pretty efficient if shaderInput would take a PTA() and memcopy() it into a 1D array that goes directly in the shader.

My idea would be create a new type of input ptr_something really similar to k_anything that is set only with PTA() and gives access to 90% of the current CG 2.0 shader inputs more efficiently (but with less error checking…).

Yes, except as rdb pointed out above, the application programmer has no way to determine the integers that correspond to the textures in the array. So you couldn’t build up a PTA() of integers for your texture array.

How about a TextureCollection as a high-level interface to the texture array?

We could also expose PTA(LVecBase4f) and PTA(LMatrix4f), I suppose, in the same way that we currently expose PTA_float. Would this be superior to ShaderInput.addElement?

David

Hm… that sounds like that should work.

Just wondering, would it be possible to add functionality to interrogate to automatically coerce lists into a ©PTA_type, if all members of the list are of that type? Or wouldn’t it make too much sense?

Hmm, it does sound appealing, but maybe a little challenging. Let me investigate.

David