Textures, Pixel Alignment And Texture Mistakes. What Am I Doing Wrong?

Started by
16 comments, last by babaliaris 5 years, 2 months ago
15 minutes ago, CrazyCdn said:

I looked over my texture code for my OpenGL class and I never check for width * channels is a multiple of 4.  All my textures are power of 2 though in both x and y directions.  Some of the textures are 1, 2, 3 or 4 channel textures and I just set glTexImage2D based on the number of channels in the loaded texture.  I didn't have time yesterday to look over your code and I'm heading out to run some errands shortly, but I'll leave this tab up for when I get home later.

If I am correct, I think I read somewhere in OpenGL Recommendations that you should use images that the resolution is a perfect quad and the width and height are multiple of 4 (For example 2x2, 4x4, 1024x1024, 2048x2048 etc..) so what you said make sense. But I would still love to know whats causing my current problem just to be a good graphics programmer and be aware of everything.


void life()
{
  while (!succeed())
    try_again();

  die_happily();
}

 

Advertisement
14 minutes ago, babaliaris said:

If I am correct, I think I read somewhere in OpenGL Recommendations that you should use images that the resolution is a perfect quad and the width and height are multiple of 4 (For example 2x2, 4x4, 1024x1024, 2048x2048 etc..) so what you said make sense. But I would still love to know whats causing my current problem just to be a good graphics programmer and be aware of everything.

But still i checked this out, the resolutions of the images when this problem occurs are in upload order:

2048x2048,  512x512, 948x948,  736x736

And still the problem appears... 


void life()
{
  while (!succeed())
    try_again();

  die_happily();
}

 

38 minutes ago, CrazyCdn said:

I looked over my texture code for my OpenGL class and I never check for width * channels is a multiple of 4.  All my textures are power of 2 though in both x and y directions.

LOL wait. I resized my images so the resolutions will be power of 2 (each direction) and it works!!! So what do you think is the problem in my code?


void life()
{
  while (!succeed())
    try_again();

  die_happily();
}

 

59 minutes ago, babaliaris said:

If I am correct, I think I read somewhere in OpenGL Recommendations that you should use images that the resolution is a perfect quad and the width and height are multiple of 4 (For example 2x2, 4x4, 1024x1024, 2048x2048 etc..) so what you said make sense. But I would still love to know whats causing my current problem just to be a good graphics programmer and be aware of everything.

No, power of two in both directions but they absolutely do not need to be square.  Nearly all modern cards can deal with non-square textures if you set it up correctly but they typically just add padding from my experience.  I have textures that are 1x64 as LUTs and plenty of 256x512, 512x1024, etc textures that all work fine.  I think it might have been your textures, but I'm on my phone and looking over that much code isn't happening while I shop ?.

https://www.khronos.org/opengl/wiki/NPOT_Texture

Also, AMD is known to have rather buggy OpenGL drivers, at least in the past.

Just as a programming tip in general, you put a lot of pointless comments in your code, like "//error string" then the next line is "std::string error;".  Don't waste your time typing things that are completely and totally obvious.  This is why I love using longer descriptive variables names as it helps a lot in self-documenting code.

"Those who would give up essential liberty to purchase a little temporary safety deserve neither liberty nor safety." --Benjamin Franklin

Thank you very much @CrazyCdn!!! You saved me! Now that I know this about power of two, I'll be fine!!!

I bought courses on udemy, watched YouTube videos, even read tutorials and other stuff on the internet, but in this forum I learned how to properly do things.


void life()
{
  while (!succeed())
    try_again();

  die_happily();
}

 

I haven't played with this stuff in a while, but from memory, you'll find that OpenGL typically requires texture rows to be padded to 4 byte divisions. In other words, if you can't divide the number of bytes in a row by 4 evenly (which will happen when you're using 8-24 bit images), you'll hit a few problems. The solution is to set the alignment using glPixelStorei(GL_UNPACK_ALIGNMENT,1) before calling glTexImage2D(…), or pad the rows yourself.

Also, there's been no limitations on texture sizes for a long time. Unless somebody is using hardware that's 10+ years old, you should be fine to use any size textures you want, however, it is recommended to stick to power of two sizes (I'm assuming it's for memory allocation purposes).

https://www.khronos.org/registry/OpenGL-Refpages/es2.0/xhtml/glPixelStorei.xml

https://www.khronos.org/opengl/wiki/Texture says:

Texture sizes have a limit based on the GL implementation. For 1D and 2D textures (and any texture types that use similar dimensionality, like cubemaps) the max size of either dimension is GL_MAX_TEXTURE_SIZE. For array textures, the maximum array length is GL_MAX_ARRAY_TEXTURE_LAYERS. For 3D textures, no dimension can be greater than GL_MAX_3D_TEXTURE_SIZE in size.

Within these limits, the size of a texture can be any value. It is advised however, that you stick to powers-of-two for texture sizes, unless you have a significant need to use arbitrary sizes.

 

3 hours ago, Goraxium said:

I haven't played with this stuff in a while, but from memory, you'll find that OpenGL typically requires texture rows to be padded to 4 byte divisions. In other words, if you can't divide the number of bytes in a row by 4 evenly (which will happen when you're using 8-24 bit images), you'll hit a few problems. The solution is to set the alignment using glPixelStorei(GL_UNPACK_ALIGNMENT,1) before calling glTexImage2D(…), or pad the rows yourself.

Also, there's been no limitations on texture sizes for a long time. Unless somebody is using hardware that's 10+ years old, you should be fine to use any size textures you want, however, it is recommended to stick to power of two sizes (I'm assuming it's for memory allocation purposes).

https://www.khronos.org/registry/OpenGL-Refpages/es2.0/xhtml/glPixelStorei.xml

https://www.khronos.org/opengl/wiki/Texture says:

Texture sizes have a limit based on the GL implementation. For 1D and 2D textures (and any texture types that use similar dimensionality, like cubemaps) the max size of either dimension is GL_MAX_TEXTURE_SIZE. For array textures, the maximum array length is GL_MAX_ARRAY_TEXTURE_LAYERS. For 3D textures, no dimension can be greater than GL_MAX_3D_TEXTURE_SIZE in size.

Within these limits, the size of a texture can be any value. It is advised however, that you stick to powers-of-two for texture sizes, unless you have a significant need to use arbitrary sizes.

 

Well if you read my post you will see that I check about memory alignment, and for the max texture size. These weren't the problem. Anyway problem solved.


void life()
{
  while (!succeed())
    try_again();

  die_happily();
}

 

This topic is closed to new replies.

Advertisement