1

I need to pass texture data to a shader program without using OpenGL textures because I'm not using a power of two texture but I get the error with this fragment shader.

varying highp vec2 texcoord;
uniform ivec4 texdata[172800];
void main(){
 int pixel = int(360.0 * texcoord.y + texcoord.x);
 gl_FragColor = vec4(texdata[pixel].x,texdata[pixel].y,texdata[pixel].z,1);
}

How can I pass this data?

genpfault
  • 51,148
  • 11
  • 85
  • 139
Matthew Mitchell
  • 5,293
  • 14
  • 70
  • 122

3 Answers3

4

The OpenGL/ES 2 spec only requires that GLSL integers are at least 17 bits (able to represent the range [-2^16,2^16)), and integers are used for array indexes, so you can't reliably create an array with more than 65535 elements. You might not be able to create one that big in any case, as there are limits on the total amount of uniform data that may be much lower. If you want access to a larger amount of data, you need to use a texture.

This error is probably coming from your integer constant 172800 which is apparently too big for your platform's GLSL implementation.

Chris Dodd
  • 119,907
  • 13
  • 134
  • 226
  • Thank you. I will try the padding idea. It's stupid that you must have power of two textures. The only reason why I found is mipmapping. I'm not even using mipmapping. Thanks to this I have to waste memory. Apple need to fix this (Unless people are missing something?). – Matthew Mitchell Jan 26 '11 at 19:51
2

Actually, the newer iOS models that support OpenGL ES 2.0 have the ability to use non-power-of-two textures because that is provided for in the OpenGL ES 2.0 specification. These devices also allow for non-power-of-two textures to be used in OpenGL ES 1.1 via the GL_APPLE_texture_2D_limited_npot extension, which I describe in more detail in my answer here.

The restrictions Apple places on these non-power-of-two textures is that they must not be mipmapped and they must use GL_CLAMP_TO_EDGE for the wrapping:

glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);

I use such textures in my OpenGL ES 2.0 sample application here.

You shouldn't need to find another way to pass your textures in to your shaders on these devices.

Community
  • 1
  • 1
Brad Larson
  • 170,088
  • 45
  • 397
  • 571
  • Thank you, very much. So I need to set the clamping parameters and it should work? At the moment my app requires iOS 4 or more and a camera. What devices does this extension work for? – Matthew Mitchell Jan 26 '11 at 22:52
  • I need to get something else to work before I'm able to test to see if the texture padding works. I may just use the padding method if it means I can support more devices. – Matthew Mitchell Jan 26 '11 at 22:53
  • I should be able to make it easily choose between using "npot" and "pot" but I will probably only bother if the padding technique is slow or something. At least for when I submit the next version to Apple. – Matthew Mitchell Jan 26 '11 at 22:54
  • @Matthew - Yes, the clamping was the last thing I needed to get going to enable non-power-of-two textures in that sample application. Again, you can check out my sample application to see how this works, because it does color-based object tracking from camera input (I tested it on an iPhone 4, but I believe it also works on the 3G S). It's my understanding that this extension works on all PowerVR SGX hardware, so anything that supports OpenGL ES 2.0. It's not guaranteed to be supported on future hardware, but I see no reason for them dropping support. – Brad Larson Jan 26 '11 at 22:56
  • @Matthew - Actually, now that I read into it, the OpenGL ES 2.0 specification provides for non-power-of-two textures by itself. That extension only applies for OpenGL ES 1.1, so all OpenGL ES 2.0 compatible devices should support non-power-of-two textures. I think the clamping might be a restriction that Apple applies on top of what the specification says. Also, I think Apple still requires mipmapped textures to be power-of-two. – Brad Larson Jan 26 '11 at 23:08
  • Alright. Thanks for that. Odd I found nothing when I search for it. Do you know how much using shaders enhances the performance of image manipulation and rendering from the camera. That's what I'm aiming to do. – Matthew Mitchell Jan 26 '11 at 23:34
  • I've got mine very similar to your example and it just wont work. :( – Matthew Mitchell Jan 27 '11 at 00:48
  • I got it working! I found a mistake. "Height" should have been "Width". Thank you so much. If anyone that answered here would want a promotion code for the paid version of this app when done, let me know. – Matthew Mitchell Jan 27 '11 at 01:03
  • @Matthew - In regards to performance, see the article that I wrote to go along with the sample application: http://www.sunsetlakesoftware.com/2010/10/22/gpu-accelerated-video-processing-mac-and-ios . Using shaders to perform massively parallel operations on the GPU can lead to a 14X-28X speedup in my benchmarks. – Brad Larson Jan 27 '11 at 02:40
0

There are non-power-of-2 texture targets, so no reason to do this. http://www.opengl.org/registry/specs/ARB/texture_rectangle.txt

Or you just pad your non-power-of-2 data into a power-of-2 frame.

datenwolf
  • 159,371
  • 13
  • 185
  • 298
  • 1
    That's a OpenGL extension, and he seems to be using OpenGL ES. – Dr. Snoopy Jan 26 '11 at 19:13
  • I'll have to use padding then? Hmm. I'll have to allocate memory to fit the image into a power of two texture and use memcpy on each row. I'm already copying data into a separate store, so I'll change that part slightly and I'll bring back feedback. Thank you everyone. – Matthew Mitchell Jan 26 '11 at 19:48