1

I just need pass a huge array (count 1521) of Int to shader for my animation. Firstly, I treat it as a uniform, but it seems too huge as uniform.

Then, I found that Passing a list of values to fragment shader I don't enough reputation for comment, so I have to open another question. I am not familiar with those APIs, I tried all of them

  • 1D Textures: I can't find any API which works.
  • Uniform Buffer Objects: Most examples are clear and understandable, but it's not available on iOS with ES 2.0
  • Buffer Textures: I think it's very close, but glTexBuffer and GL_TEXTURE_BUFFER seems missing on iOS with ES 2.0
  • Shader Storage Buffer Objects: That's something for GL 4.3, it's too new for ES 2.0

Please help me, I just need to access that array in shader.

That's what I am doing:

// i var
GLint *randomArray; 
GLuint _randomArrayTexture;
GLuint _randomArrayUnifrom;

// init texture
randomArray = (GLint*)malloc(1521 * sizeof(GLint)); 
    for (int i=0; i<1521; i++) {
        randomArray[i] = array[i].intValue;
    }

glGenTextures(0, &_randomArrayTexture);
glBindTexture(GL_TEXTURE_2D, _randomArrayTexture);

glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, 1521, 1, 0, GL_ALPHA, GL_INT, randomArray);
glBindTexture(GL_TEXTURE_2D, 0);

_randomArrayUnifrom = glGetUniformLocation(_program, "randomArray"); // after shader compiled

// before draw
glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_2D, _randomArrayTexture);
glUniform1i(_randomArrayUnifrom, 1);
glBindTexture(GL_TEXTURE_2D, 0);

// the thing in shader
uniform sampler2D randomArray;
texture2D(randomArray, vec2(0.1, 0.0)); 
// Could I access the texture with real index (not uniformed) such as vec2(1109, 0)
Community
  • 1
  • 1
iaomw
  • 720
  • 6
  • 21

2 Answers2

1

I suggest you simulate a 1D texture using glTexImage2D with a width of your array count (or the next power of two) and a height of 1.

Rhythmic Fistman
  • 34,352
  • 5
  • 87
  • 159
1

Make sure what you need to do in shader codes using the array. It is the same size as vertices?

  1. 1521 is not huge.
  2. it seems that the best way for this is passing the array as one of vertices arrays
  3. even if you pass a texture buffer, to refer a specific index of the buffer in shader, you should use a vertex buffer.

Plus,

If you use the array as random values, you should use a custom random() based on time or noise in your shader code, however, I think you got wrong. it seems you want to control some animation using the number in the array[1521] but must the array[1521] be read in 1/60 sec?

if no, you can give each value as a uniform1f each 1/60sec (supposed 60FPS)

if yes, it might be 39x39 noise grid or something right?

then you should generate those random values in the Shader. or the better way could be using a texture[1521] with a texture coordinate array as one vertex array to use each value of the array[1521] which is the texture.

Sung
  • 1,036
  • 1
  • 8
  • 22
  • Thanks, just some cooked random number from CPU to control animation process in shader. Should be something like global const. They are huge while I treated it as uniform. I am trying to do it with glTexImage2D now, but it's not accessible in shader. Is that right? glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, 1521, 1, 0, GL_ALPHA, GL_INT, randomArray); – iaomw Nov 14 '15 at 14:21
  • @iaomw to access the value, you should use one vertices as a texture coordinate. Just updated my answer. What kind of animation do you use? if it is a time-based body animation and it is not about any realtime graphic techniques like modifying another textures or noise effects, you don't have to pass whole array into the shader. just give them one by one. – Sung Nov 14 '15 at 19:18
  • The frame is treated as 39*39 squares logically, the animation should perform on each square randomly once. I should make sure each one of them will be done. So I made that array on CPU to make sure it's a new section for each time and will finish as expected. @Sung Woo – iaomw Nov 15 '15 at 14:25
  • Once each section is done, it should stay in finished status. @Sung – iaomw Nov 15 '15 at 14:37
  • @iaomw glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, texture_width,texture_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, imageData); and you can access it using texture coordnate(0.0~1.0,0.0~1.0) that you will pass trough Vertex Shader – Sung Nov 15 '15 at 19:50
  • @iaomw you should know your vertex shader is called for each vertex not for 1/60sec, and FS is called for each fragment(not pixel). I still don't get for what animation, you need the texture because you can't access the texture in Vertex shader which means you can't change any vertex values using the texture. Did you know these? – Sung Nov 15 '15 at 19:56
  • Yes, I know. I am not going to change vertex values, just do all the stuff in fragment shader. – iaomw Nov 17 '15 at 05:11
  • So, I cannot use GL_DEPTH_COMPONENT and GL_ALPHA with glTexImage2D for GL_INT. I don't want to pass it as RGB, since there is only on value. – iaomw Nov 17 '15 at 05:18
  • 1
    @iaomw ok I see but you can't also use GL_INT in opengl es . The following symbolic values are accepted: GL_UNSIGNED_BYTE, GL_UNSIGNED_SHORT_5_6_5, GL_UNSIGNED_SHORT_4_4_4_4, and GL_UNSIGNED_SHORT_5_5_5_1. – Sung Nov 17 '15 at 05:52
  • Yeah, it's done. I miss configurated glTexParameteri, so it never came out. – iaomw Nov 19 '15 at 10:06
  • @iaomw my bad, I should've told you that. Now can you do what you wanted to do? – Sung Nov 19 '15 at 17:55
  • I have made that after proper glTexParameteri configuration, thanks :) – iaomw Nov 21 '15 at 03:58