2
\$\begingroup\$

How do I pass to my vertex shader an array of N elements?

From what I see I can only pass float arrays of 3|4 elements, vectors 2|3d and matrices, but I want to pass a POD array and use it like this:

void ShaderFunction(float* array,int count)
{
    for (int i = 0;i < count;i++) 
    {
        DoJob(array[i]);
    }
}

So far all of my tests fail.

\$\endgroup\$

3 Answers 3

3
\$\begingroup\$

You can define an array in GLSL like so:

uniform float array[size];  

Then passing in depends on what language you're using. For Java (LWJGL):

FloatBuffer floatBuffer = BufferUtils.createFloatBuffer(size);
floatBuffer.put(x);
floatBuffer.put(y);
...
int location = GL20.glGetUniformLocation(shaderProgram, "array");
GL20.glUniform1f(location, floatBuffer);

Or in C++

GLfloat floatArray[size] = {...};
int location = glGetUniformLocation(program, "array");
glUniform1fv(location, size, floatArray);

Then you can use it:

void ShaderFunction(int count)
{
    for (int i = 0;i < count;i++) 
    {
        DoJob(array[i]);
    }
}
\$\endgroup\$
6
  • \$\begingroup\$ Thank you.So is it still needed to send vertices as usual or could i define a buffer with vertex pointer and iterate through it? \$\endgroup\$ Apr 10, 2012 at 22:53
  • 1
    \$\begingroup\$ I'd send the vertices as usual. If you need access to the vertices you can access them as well. See this handy cheat sheet (PDF) to see some common variables and functions. Including vec4 gl_Position; which is your vertex position in the vertex shader. \$\endgroup\$
    – House
    Apr 10, 2012 at 22:57
  • 2
    \$\begingroup\$ Please note that your array size must be defined at compile time. GLSL does not allow variable size arrays. So you must pick a size that you think will work, and have CPU side code that ensures you don't exceed that size. \$\endgroup\$
    – House
    Apr 10, 2012 at 23:00
  • \$\begingroup\$ Thanks alot.I thought that i could drop the CPU load for the rendering part but now i see that its impossible ;) \$\endgroup\$ Apr 10, 2012 at 23:03
  • 1
    \$\begingroup\$ Perhaps the way you were thinking of doing it isn't possible, but I'm sure there are numerous ways to take a load off the CPU for your game. \$\endgroup\$
    – House
    Apr 10, 2012 at 23:08
1
\$\begingroup\$

Short answer: You can't.

Long answer: Need more info what you are trying to do and why.

\$\endgroup\$
2
  • \$\begingroup\$ I want to move my tile map rendering code to the GPU if its possible. (Sorry if its stupid i warned in the OP that i just set up my shader system but it has been edited) \$\endgroup\$ Apr 10, 2012 at 22:39
  • 1
    \$\begingroup\$ Just use texture to hold all data and skip vertices all together. java-gaming.org/topics/rendering-tiles-fast-isometric-too/25292/… \$\endgroup\$
    – kalle_h
    Apr 11, 2012 at 9:44
1
\$\begingroup\$

Another way you might do this is by using a floating point texture - you would create a one-channel FP texture of the required size, upload your data to it, and sample from that in your shader (remember that vertex shaders can also sample from textures).

Where this is going to cause you huge trouble - irrespective of your chosen solution - is in terms of instruction counts. GPUs are not really designed around being used for this kind of programming, and if your count value is sufficiently high and/or if it varies between calls your performance is at risk of falling off the edge of a cliff.

Since you say that you're looking to do this in a vertex shader, it may yet turn out to be more performance-efficient (and even advantageous from a code-cleanliness perspective) to leave it running on the CPU instead.

\$\endgroup\$
1
  • \$\begingroup\$ That sounds like an amazing idea.But im not sure if i can pull that off at the moment though (sounds tough ;D) \$\endgroup\$ Apr 10, 2012 at 23:08

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .