1

Are there certain format restrictions that textures need to adhere too?

I am loading TGA files and drawing them with the following fragment shader:

varying vec2      v_texCoord;
uniform sampler2D s_texture;
uniform vec4      vColor4;

void main()
{
  vec4 tmpColor = texture2D( s_texture, v_texCoord );

  tmpColor.r = vColor4.r;
  tmpColor.g = vColor4.g;
  tmpColor.b = vColor4.b;

  gl_FragColor = tmpColor;
}

I find that 16x16 images display OK. 64x16 display OK. 72x16, 80x16 and 96x16 doesn't work.

I will provide more information including the TGA files if needed.

Nicol Bolas
  • 449,505
  • 63
  • 781
  • 982
SparkyNZ
  • 6,266
  • 7
  • 39
  • 80
  • 2
    Are you using OpenGL, or OpenGL ES? There used to be restrictions on textures that they needed to be a power-of-two in both dimensions. However, that restriction was removed from OpenGL after version 2.0. With OpenGL ES and WebGL, that restriction may still be there (unless your implementation supports an extension removing the restriction). – radical7 Apr 08 '16 at 01:54
  • @radical7 I'm using OpenGL ES2.0. That would make sense what you are saying. So after 64x16 it would have to be 128x16 and 256x16 etc? – SparkyNZ Apr 08 '16 at 02:09
  • just go with 2^n like 2 4 8 16 32 64 128 256 512 1024.. It is obvious. – Sung Apr 08 '16 at 02:12
  • If you do not require texture filtering, a lot of really ancient (and embedded) hardware supports non-power-of-two textures through texture rectangles. It's unclear what you are trying to do here. – Andon M. Coleman Apr 08 '16 at 02:34
  • @AndonM.Coleman I have accepted your answer but just to clarify, I have a bitmap font strip that I created in 2011 (ie. ASCII glyphs that I want to extract and paint on a 2D screen). Moving my code from OpenGL ES1.1 to ES2.0 (immediate mode to shaders) I'm trying to get things working again. – SparkyNZ Apr 08 '16 at 02:38
  • 1
    Oh. I almost want to say texture rectangles would be appropriate here then. Filtering bitmap fonts to accomplish scaling rarely produces favorable results. You usually wind up requiring nearest-neighbor sampling using various different resolution fonts, and that's actually a perfect use-case for texture rectangles. – Andon M. Coleman Apr 08 '16 at 02:41
  • 1
    This should be completely supported in ES 2.0 so long as the min/mag filter is nearest and the S and T wrap behavior is clamp to edge (neither of which are the default texture state). – Andon M. Coleman Apr 08 '16 at 02:47

1 Answers1

0

72, 80 and 96 are not powers-of-two; this requirement has little to do with data format in OpenGL ES. This requirement is actually pervasive even in modern desktop GL, where it may depend on the data format used.

Uncompressed texture data in (desktop) OpenGL 2.0 or greater can have non-power-of-two dimensions.

However, compressed texture data continues to require block sizes that are multiples of 4, pixel transfer functions continue to assume 4-byte data alignment for each row in an image, floating-point textures, if supported may also require powers of two, and so on.

Many image libraries designed for GL will actually rescale stuff to a power-of-two, which can solve every one of the problems discussed above. It's not always the most appropriate way (it can be extremely wasteful) to fix dimension problems but it can be applied universally to just about any common dimension problem.

Andon M. Coleman
  • 42,359
  • 2
  • 81
  • 106
  • Yes, all of the textures I'm using are compressed. – SparkyNZ Apr 08 '16 at 02:38
  • "*Uncompressed texture data in (desktop) OpenGL 2.0 or greater can have non-power-of-two dimensions.*" No, ***all*** textures in desktop OpenGL 2.0+ can have non-power-of-2 dimensions, whether compressed or not. Block sizes have nothing to do with the size of the texture as well, since partial blocks are not forbidden by the OpenGL specification. The specification makes it clear how block compressed formats work for textures who's sizes are not divisible by the block size. So your answer only applies to OpenGL. – Nicol Bolas Apr 08 '16 at 04:47
  • That comment is thoroughly confusing and verifiably wrong. DXTn textures as a simple example will generate `GL_INVALID_OPERATION` if you try to allocate a datastore with non-block aligned dimensions. Other compressed formats have their own rules discussed in their respective extension specifications. And of course it only applies to OpenGL, I try to keep my answers relevant to the APIs under discussion. If you want to discuss Vulkan, Direct3D or some other API, be my guest but I don't see what value it will add to the question. – Andon M. Coleman Apr 08 '16 at 05:29
  • It appears I will never get an answer. Oh well, do not let the misleading statements in the comment prior confuse you. Alignment and texture width are inseparably related. An 8-bit per-component RGB image with arbitrary width may not end each row on 4-byte boundaries, while the same 8-bit RGB format with a power-of-two (>= 4) width always will. However, just because this satisfies certain alignment requirements, the whole point of the answer was to give you a couple of examples that at first glance might be problems related to non-power-of-two texture sampling but are not. – Andon M. Coleman Apr 10 '16 at 01:16