Sign in to follow this  

OpenGL mipmaps with texture arrays

This topic is 1107 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hey all,

I've been trying to implement mipmapping with the images in my texture array, but I think I may be going about this wrong and I'm having difficulty tracking down an answer. I'm not receiving an error, but everything in game still looks very pixelated and jagged in the distance.

 

my image loading looks thusly:

void LoadAssets()
{
    //create texture array////
    glGenTextures(1, &TextureArray);
    glBindTexture(GL_TEXTURE_2D_ARRAY, TextureArray);
    glTexStorage3D(GL_TEXTURE_2D_ARRAY,1, GL_RGBA8, 1024, 1024, 9);

    //bind vertex array. Once.////
    glGenVertexArrays(1, &VertexArrayID);
    glBindVertexArray(VertexArrayID);

    //load images////
    //don't change the number on the end, used for texture array placement. don't rearrange. add to end of list.
    //stone image////
    LoadImage("GAMEASSETS/StoneDiffuse.png", 0);
    LoadImage("GAMEASSETS/StoneNormal.png", 1);
    LoadImage("GAMEASSETS/StoneSpecular.png", 2);
    imageIndices.emplace_back(glm::vec3(0,1,2));

    //mountain image////
    LoadImage("GAMEASSETS/mountainDiffuse.png", 3);
    LoadImage("GAMEASSETS/mountainNormal.png", 4);
    LoadImage("GAMEASSETS/mountainSpecular.png", 5);
    imageIndices.emplace_back(glm::vec3(3,4,5));
    
    //tree image////
    LoadImage("GAMEASSETS/TreeDiffuse.png", 6);
    LoadImage("GAMEASSETS/TreeNormal.png", 7);
    LoadImage("GAMEASSETS/TreeSpecular.png", 8);
    imageIndices.emplace_back(glm::vec3(6,7,8));

    //set texture parameters////
    glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_S, GL_REPEAT);
    glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_T, GL_REPEAT);
    glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
    
    glGenerateMipmap(GL_TEXTURE_2D_ARRAY);
}

void LoadImage(const char* imageName, int layerNumber)
{
    if(!image.loadFromFile(imageName))
    {
        std::cout<<imageName<<" failed to load..."<<std::endl;
    }
    
    glTexSubImage3D(GL_TEXTURE_2D_ARRAY, 0, 0, 0, layerNumber, image.getSize().x, image.getSize().y,1, GL_RGBA, GL_UNSIGNED_BYTE, image.getPixelsPtr());
}

So, if I'm doing things incorrectly, what is the proper way in OpenGL 3.3+ to mipmap the images in a texture array? Should I be setting the glTexParameters for every image rather than once at the end? Do I need to be changing the second parameter of glTexSubImage3D? Is the jaggedness in the textures at a distance not a mipmap problem? I do find cranking up the antialiasing helps, but it's not really feasible to keep that at 32 samples :P

 

To clarify though, I'm not receiving any error, but the images definitely don't look mipmapped, and become pixelated in the distance. Hopefully I'm just doing something silly here.

 

Anyhow, I appreciate any input, and cheers! smile.png

Edited by Misantes

Share this post


Link to post
Share on other sites

You are allocating just one mipmap level with the call to glTexStorage3D. Then you fill the base level with the loaded image, and then you ask to generate mipmaps. Because there is no level allocated above the base level (only those will be generated by glGenerateMipmap), nothing happens in the end. So try to increase the level parameter of glTexStorage3D.

Share this post


Link to post
Share on other sites

I thought that may be the case. That's the second parameter, correct? When I try to increase it, everything turns solid black/white or just really....weird (kind of like an old crt monitor). Does it need to be a specific number (such as divisible by 4 or anything)? I've tried various values but all have the same effect.

Edited by Misantes

Share this post


Link to post
Share on other sites

I thought that may be the case. That's the second parameter, correct? When I try to increase it, everything turns solid black/white or just really....weird (kind of like an old crt monitor). Does it need to be a specific number (such as divisible by 4 or anything)? I've tried various values but all have the same effect.

It is the 2nd parameter, yes. Its value must not exceed the hardware limit as can be requested by using GL_TEXTURE_MAX_LEVEL with glGetTexParameteriv, but I doubt that you actually exceed it. It must further be so that the mipmap level with size 1 by 1 is not generated more often than once (the reference says that it must not be greater than log2(max(width,height))+1 which, in your case, computes to 11). Besides that, it may be any positive integer number.

 

EDIT: Oops: glGetTexParameter naturally gives you a set-up parameter, not a hardware limit. 

Edited by haegarr

Share this post


Link to post
Share on other sites

You're calling glGenerateMipMap on an empty texture. At the point you're calling, your texture contains no data - only the memory for the texture has been allocated. If you want mipmaps to be generated for each layer you update, you need to call glGenerateMipMap every time you update the layer. Note this could potentially do unnecessary extra work and regenerate the mipmaps for the other layers as well. Alternatively, you could pre-calculate the mipmaps for the textures you're using and upload them into each mip level manually.

 

EDIT: Didn't notice the LoadImage calls :p What haegarr is correct - you need to allocate storage for all the mip levels.

Edited by Xycaleth

Share this post


Link to post
Share on other sites

Bleh, in my sleepy state (when I said I "thought that was the case") I was referring to and changing the value in glTexSubImage3D instead of glTexStorage3D >.<. Your advice works perfectly. Thanks again as always Haegar, You're always tremendously heflpful. I think I've learned more useful information from you than countless tutorials and books tongue.png

Edited by Misantes

Share this post


Link to post
Share on other sites

This topic is 1107 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this