Libgdx how to send arrays to Shader

Sooo, I’m trying to send some light data to libgdx as arrays, but I cannot seem to be able to do anything, because all the values always are 0.

So I have these 2 arrays in my shader, and a vec4 not array to test if it works:


uniform vec4 shaderColor;
uniform vec3[64] lights;
uniform vec3[64] lightColors;

With this code, I can send data to Shader and it works:


		int loc = shader.getUniformLocation("shaderColor");
		shader.setUniform4fv(loc, new float[] { 1f, 1f, 1f, 1f }, 0, 4);

But this just doesn’t work. Values in those array are always 0.


		float[] lights = { 100f, 100f, 1f, 300f, 300f, 1f };

		int loc = shader.getUniformLocation("lights");
		shader.setUniform3fv(loc, lights, 0, lights.length);
		loc = shader.getUniformLocation("lightColors");
		float[] lightColor = { 1f, 1f, 1f };
		shader.setUniform3fv(loc, lightColor, 0, lightColor.length);

Is it even possible to send arrays to Shaders through Libgdx?

It is probably something else, but you may check the GL_MAX_*_UNIFORM_COMPONENTS​ attribute of your graphics card. This attribute tells you how many float uniform you may use in a shader, a vec3 counts as 3 floats of course. Also, AMD cards report the space in bytes so remember to divide by 4.

You need to specify the array index in the location, this is pretty much what i use in my shaders


for(int i = 0; i < totalLights; i++){
int loc = shader.getUniformLocation("shaderColor[" + i + "]");
//setuniform here
}

Isn’t that very slow? Sending an array bit by bit? With lwjgl you can send all the array at once…

I am no expert on shaders its just how I learnt to send an array to a shader, and how many lights will you be sending, i think you will need to be sending literally thousands to notice a difference. (notice a difference at sending data to the shader)

remember if your using a fragment shader, its effect every single pixel that you are rendering, chances are you are rendering to many lights at once without restricting the area that the light modifies.

Ow man… Here I’m back to programming and it seems that libgdx doesn’t even support basic arrays or something… I thought that the “getLocation(“array[1]”);” would work, but when I try setting value of that index, it stays 0. I tried a million things and it just seems that libgdx doesn’t work with arrays. + I cannot find a method that returns shaderprograms program handle. I was going to try to set the values manually through Gdx.gl20 , but I can’t find the handle…

Libgdx is really annoying in some ways…

Not true. You can send full arrays with libgdx api just like you can with lwjgl api. There is no difference. Just look the code if unsure how something works underhood.

You need to use [icode]uniformfv[/icode] calls.

An example of a float array:

GLSL ...
    uniform float a[3];

Java ...
    shader.setUniform1fv("a[0]", new float[] { 1.0f, 0.0f, 0.0f }, 0, 3);

An example of a vec3 array:

GLSL ...
    uniform vec3 a[2];

Java ...
    shader.setUniform3fv("a[0]", new float[] { 1.0f, 0.0f, 0.0f, 1f, 1f, 1f }, 0, 6);

The last parameter, length, is the total number of floats you are passing to GL.

Your method actually worked. I don’t really get libgdx… In lwjgl if you want to send an array, you get the location of that array and send FloatBuffer… Why would you need to get location of array’s specific index to send entire array…

Your first problem is Your attitude. From every post You make regarding LibGDX, it is felt that You are frustrated and that You are forced to work with it. Human mind is a very complex and very conservative, lets say party. If You have a negative attitude, then everything You do reinforces that negativity, until You find a surprise, which, by definition, does not happen regularly. So my first suggestion is to try to be more open minded. Lwjgl and LibGDX are different beasts, although related. Instead of “oh no, why is it so, in the other place it was better” try to be more like “oh wow, something new, interesting”

LibGDX supports “OpenGL for Embedded Systems (OpenGL ES)” version 1.0 and version 2.0. Although it’s still OpenGL, it’s a different beast than regular, desktop GL. This means the differences might come from the stripped down nature of GLES or they might come from the GLES being more strict.