Welcome, Guest. Please login or register. Did you miss your activation email?

Author Topic: How to give a shader an array of values?  (Read 4648 times)

0 Members and 1 Guest are viewing this topic.

Azaral

  • Full Member
  • ***
  • Posts: 110
    • View Profile
How to give a shader an array of values?
« on: February 18, 2014, 06:40:32 am »
A friend of mine and I are making a program for fun, and it has fallen to me to write a shader to display the results. The shader is a fragment shader. In order to do what it needs to do, I need to get two arrays of float values. How can I use an array inside a shader and how can I pass this array from the c++ program into the shader program?

I've been looking, but the results haven't been helping me much. They are also in the context of just opengl and glsl, and I'm not sure how that would apply to the SFML context.

Nexus

  • SFML Team
  • Hero Member
  • *****
  • Posts: 6287
  • Thor Developer
    • View Profile
    • Bromeon
Re: How to give a shader an array of values?
« Reply #1 on: February 18, 2014, 10:22:55 am »
Use textures to store collections of values. Textures are the arrays of the graphics card. Depending on what you exactly want to do, the API that SFML provides might not be enough, and you would have to use raw OpenGL.

What do you need the arrays for?
Zloxx II: action platformer
Thor Library: particle systems, animations, dot products, ...
SFML Game Development:

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32498
    • View Profile
    • SFML's website
    • Email
Re: How to give a shader an array of values?
« Reply #2 on: February 18, 2014, 11:27:10 am »
You can declare an array in your shader, the same way you would declare one in your C++ code. SFML doesn't allow to set all its values in one call, but I as far as I remember, you should be able to set them individually like this:

shader.setParameter("my_array[1]", value);
Laurent Gomila - SFML developer

Grimshaw

  • Hero Member
  • *****
  • Posts: 631
  • Nephilim SDK
    • View Profile
Re: How to give a shader an array of values?
« Reply #3 on: February 18, 2014, 01:14:53 pm »
While Laurent's approach might work, I'd really recommend going Nexus' way. If you declare arrays of uniforms like that, first you quickly run out of uniform memory space, and second you re stuck with a fixed amount of elements in your array.

With textures you can have a lot more data, dynamically sized and without need to map client's memory to the gpu every frame (depending on what you re doing).

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32498
    • View Profile
    • SFML's website
    • Email
Re: How to give a shader an array of values?
« Reply #4 on: February 18, 2014, 01:31:42 pm »
Quote
I'd really recommend going Nexus' way
I don't think it's a good approach. Textures and arrays have their own use cases, which are totally different.

It's not uncommon to use an array with a small/fixed size in a shader (for example: a shader that can handle 8 light sources, or that needs 16 coefficients for a formula); it would be tedious to use a texture for that. Don't forget that with textures, you're limited to 32 bits integers on SFML side, and floats on GLSL side; with arrays you can use whatever type you want (even custom structures). Textures also require more care: you must disable filtering, etc. if you don't want your values to be altered.

Of course textures are also great for a variety of other use cases... but not all ;)
« Last Edit: February 18, 2014, 01:36:00 pm by Laurent »
Laurent Gomila - SFML developer

Azaral

  • Full Member
  • ***
  • Posts: 110
    • View Profile
Re: How to give a shader an array of values?
« Reply #5 on: February 18, 2014, 02:19:30 pm »
Use textures to store collections of values. Textures are the arrays of the graphics card. Depending on what you exactly want to do, the API that SFML provides might not be enough, and you would have to use raw OpenGL.

What do you need the arrays for?

The pixels are going to be shaded according to twp values, each of which will have different places on the screen, and the number can change as well. I think I could do it without passing the arrays into the shader and work on each separately by having a loop that goes through each point and the two values in the main program. Each iteration would run the shader and draw it unto a render texture, then draw the render texture to the window, but I think doing it all on the shader in one go would be a lot faster.

The number of elements in the array would be changing too.

I appreciate the help very much. I'm extremely new to this stuff.