Troubles with Mipmap

Hi, All!

I try to start working with mipmap.
First of all I try to render depth map to mipmap texture (only 0 level at the first step) instead of simple one.

When I change my working render tools for using mipmap, I have empty result:
[ATTACH=CONFIG]1701[/ATTACH]

mipmap code:


    glBindTexture(GL_TEXTURE_2D, id);

    glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, this.width, this.height, 0, GL_DEPTH_COMPONENT, GL_FLOAT, (ByteBuffer) null);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
    glGenerateMipmap(GL_TEXTURE_2D);

    ....
    glBindFramebuffer(GL_FRAMEBUFFER, depthMapFBO);
    glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, depthMap.getId(), 0);
    if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) {  // Here all is ok - have no errors
      throw new IllegalStateException("Could not create FrameBuffer");
    }
    glBindFramebuffer(GL_FRAMEBUFFER, 0);
    ....

    // rendering of mipmap:
    shaderProgram.bind();

    shaderProgram.setUniform("depthTexture", 0);
    shaderProgram.setUniform("prevFrameInvertedProjViewMatrix", prevFrameInvertedProjViewMatrix);
    shaderProgram.setUniform("currFrameProjViewMatrix", currFrameProjViewMatrix);

    glActiveTexture(GL_TEXTURE0);
    glBindTexture(GL_TEXTURE_2D_ARRAY, depthBuffer.getTexture().getId());

    glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, reprojectedDepthBuffer.getTexture().getId(), 0);
    quadMesh.render();

    shaderProgram.unbind();
    glBindFramebuffer(GL_FRAMEBUFFER, 0);
    ....

    // try to show it on display:
    
    glActiveTexture(GL_TEXTURE0);
    glBindTexture(GL_TEXTURE_2D, reference);

    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0);

    quadMesh.render();
    glBindTexture(type.getGlType(), 0);
    

Who knows where the problem might be? :confused:
Thanks for answer!

Is there some difference between rendering to mipmap and rendering to simple texture?

When I replace mipmap by simple texture rendering is works.
But for mipmap I have empty result.

Where could be problem?

Well, you only bind a specific level of a texture to a framebuffer. If the texture has more than one level, then you need to generate the other levels e.g. with glGenerateMipmap(). If you select a minification filter which uses mipmaps but haven’t generated all of the levels, then texture sampling returns zeros. However, as you appear to be setting the maximum level to zero, this shouldn’t matter.

GClements, you helped me so mauch!

I used glGenerateMipmap next after rendering - it did not get any result.
But when I called it before using mipmap texture, mipmap became - ok.

I wasted a week with other details which didn’t get me any results.
You made me look at glGenerateMipmap more carefully and I gueesed solution at the moment.
But I found out that also I need more learning about using mipmaps.

Thank you!

I have another one problem.

I rendered base level of mipmap (it is redered ok).

And then I render other levels and have result only in last rendered level.
All previous levels (including base level) became empty.
Why it can be?

It’s impossible to say with so little information.

Of course, sorry for that.

I try to implement occlusion culling using hierarchial depth map.
1 - reproject depth map from previous frame (done)
2 - render depth mipmap (i’m here now)
3 - culling with hierarchial depth map (not started yet)



    // reprojection (it is working fine, I can see it on screen):
    .....

    projectionMx.mul(viewMx, currFrameProjViewMatrix);

    glBindFramebuffer(GL_FRAMEBUFFER, reprojectedDepthBuffer.getDepthMapFBO());

    glViewport(0, 0, display.getWidth(), display.getHeight());
    glClear(GL_DEPTH_BUFFER_BIT);

    reprojectionProgram.bind();

    reprojectionProgram.setUniform("depthTexture", 0);
    reprojectionProgram.setUniform("prevFrameInvertedProjViewMatrix", prevFrameInvertedProjViewMatrix);
    reprojectionProgram.setUniform("currFrameProjViewMatrix", currFrameProjViewMatrix);

    depthBuffer.bindForUsage(GL_TEXTURE0);

    reprojectedDepthBuffer.bindAsTarget();

    quadMesh.render();

    reprojectionProgram.unbind();
    glBindFramebuffer(GL_FRAMEBUFFER, 0);
    .....


    // rendering if mipmap (now it not correct, I just try to render reprojection result to all layers of mipmap):
    
    glBindFramebuffer(GL_FRAMEBUFFER, reprojectedDepthBuffer.getDepthMapFBO());
    glClear(GL_DEPTH_BUFFER_BIT);
    testProgramm.bind();
    testProgramm.setUniform("depthTexture", 0);
    testProgramm.setUniform("prevFrameInvertedProjViewMatrix", prevFrameInvertedProjViewMatrix);
    testProgramm.setUniform("currFrameProjViewMatrix", currFrameProjViewMatrix);
    depthBuffer.bindForUsage(GL_TEXTURE0);

    int numLevels = 1 + (int) floor(log(max(display.getWidth(), display.getHeight())) / log(2));
    int currentWidth = display.getWidth();
    int currentHeight = display.getHeight();
    int i = 1;
    for (; i < numLevels; i++) {

      currentWidth /= 2;
      currentHeight /= 2;
      currentWidth = currentWidth > 0 ? currentWidth : 1;
      currentHeight = currentHeight > 0 ? currentHeight : 1;
      glViewport(0, 0, currentWidth, currentHeight);

      glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, reprojectedDepthBuffer.getTexture().getId(), i);
      quadMesh.render();
    }

    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, numLevels - 1);
    glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, reprojectedDepthBuffer.getTexture().getId(), 0);

    testProgramm.unbind();
    glBindFramebuffer(GL_FRAMEBUFFER, 0);


I was wrong, the base level is not erasing with it.
I can render only one level if I use glFramebufferTexture2D with rendering once (without cycle) and not reset index to 0 by glFramebufferTexture2D at the end.
If I set 0 index by glFramebufferTexture2D and use cycle as it must be, then I have only base level, all others is empty.
Automatic generation by glGenerateMipmap(GL_TEXTURE_2D) is working fine.

Thanks for any answer.

I found problem: If I set uniforms every cycle step, then all levels rendered ok.

But new problem appeared:

  • If I render levels of mipmap manually, then I have access to level wich was set at the end of mipmap rendering via call:
    glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, textureId, index);
    I mean: if index = 5, then I see only 5th level of mipmap in the shader.

  • If I generate mipmap via glGenerateMipmap(GL_TEXTURE_2D), then I can see any level of mipmap in the shader.

Where can be problem?