Part of the Khronos Group
OpenGL.org

The Industry's Foundation for High Performance Graphics

from games to virtual reality, mobile phones to supercomputers

Results 1 to 10 of 10

Thread: Framebuffer outputs black on resize

Hybrid View

Previous Post Previous Post   Next Post Next Post
  1. #1
    Junior Member Newbie
    Join Date
    Aug 2017
    Posts
    9

    Framebuffer outputs black on resize

    Hi, I`m trying to resize my framebuffer which uses Multisample Textures with 4 samples.
    When I call my resize method, the framebuffer just outputs a black color.

    Here is my resize method:

    Code :
        GL.DeleteFramebuffer(id);
        foreach (GLXTexture texture in colorAttachments)
        {
            texture.Resize(width, height, 0);
         }
         if (depthAttachment != null)
         {
              depthAttachment.Resize(width, height, 0);
         }
         if (stencilAttachment != null)
         {
              stencilAttachment.Resize(width, height, 0);
         }
         id = GL.GenFramebuffer();
         Create(colorAttachments, depthAttachment, stencilAttachment);

    You can see a "Create" method at the bottom. I can include the source code but it is working fine, because if I dont use "Resize" on a Texture, the framebuffer renders ok. It then renders to a texture, which is not the same size and, because of this, distorted.

    The interesting stuff happens in the Textures "Resize" method. If I use any openGL texture operations like "GL.BindTexture" and "GL.TexImage2DMultisample" in my case, the output is turns black. No error is generated.

    Here is the code (INFO: IsMutable is true, which means that I`m using GL.TexImage2DMultisample):
    Code :
            public override void Resize(int width, int height, int depth)
            {
                if (!IsReserved)
                {
                    throw new NotSupportedException("This texture has to be created before resizing!");
                }
                if (width == 0 || height == 0)
                {
                    throw new NotSupportedException("You can`t resize this image to 0 width or height!");
                }
                this.width = width;
                this.height = height;
                if (!IsMutable) // If the texture is not mutable it has to be destroyed completely
                {
                    Destroy();
                    ReserveTextureID();
                }
                GL.BindTexture(TextureTarget.Texture2DMultisample, id);
                if (IsMutable)
                {
                    // TexTarget is GL_TEXTURE_2D_MULTISAMPLE in this class
                    GL.TexImage2DMultisample((TextureTargetMultisample)TexTarget, samples, internalFormat, width, height, fixedSampleLocations);
                }
                else
                {
                    GL.TexStorage2DMultisample((TextureTargetMultisample2d)TexTarget, samples, (SizedInternalFormat)internalFormat, width, height, fixedSampleLocations);
                }
                //ApplyOptions(IsMutable); Dont apply any options to a 2D Multisample Texture
                GetError(false); // Print errors 
                GL.BindTexture(TextureTarget.Texture2DMultisample, 0);
            }

    Here is the desired output, which I get if I dont resize the screen. (Only these Gray blocks)
    Click image for larger version. 

Name:	des.jpg 
Views:	28 
Size:	12.0 KB 
ID:	2468

    After window resize:
    Click image for larger version. 

Name:	des.jpg 
Views:	27 
Size:	6.2 KB 
ID:	2466

    And here I have removed the GL.BindTexture and GL.TexImage2DMultisample lines and then resized the window:
    Click image for larger version. 

Name:	des.jpg 
Views:	28 
Size:	9.8 KB 
ID:	2467


    I tried this with Multisampled 2D Textures and only 2D Textures, both have the same effect.

    Additional informations:
    - The openGL context which created the textures and framebuffer is bound properly in the resize method.
    - I`m using multiple draw buffers from GL_COLOR_ATTACHMENT0 to 3 which are bound using glDrawBuffers
    - There is no Framebuffer error generated
    - This PC has Intel(R) HD Graphics | Driver Version 9.17.10.2884

  2. #2
    Senior Member OpenGL Guru Dark Photon's Avatar
    Join Date
    Oct 2004
    Location
    Druidia
    Posts
    4,167
    Are you checking for GL errors? Do you see any?

    You don't actually show many of the GL calls you're making here. Showing a bit about how you're doing the downsample might help.

    When I first saw your problem, I suspected you might be trying to downsample and resize your MSAA render target with one glBlitFramebuffer call (which you can't do; you have to use two). However, you didn't show this code so you might check that.

  3. #3
    Junior Member Newbie
    Join Date
    Aug 2017
    Posts
    9
    Quote Originally Posted by Dark Photon View Post
    Are you checking for GL errors? Do you see any?
    No errors =/

    Quote Originally Posted by Dark Photon View Post
    You don't actually show many of the GL calls you're making here. Showing a bit about how you're doing the downsample might help.
    I`m doing downsampling using a shader.
    Code :
        void main(){
             vec4 color = vec4(0.0);
             ivec2 coords = ivec2(texCoords.x * samplerResolution.x, samplerResolution.y - texCoords.y * samplerResolution.y);
             for(int i = 0; i < 4; i++)
             color += texelFetch(finalImage, coords, i);
             fragColor = color / samples;
         }

    But this should`nt be the problem, because it works before I resize.

    Here is the complete resizing procedure captured by GLIntercept:

    Code :
    //Begin Resize (width = 710, height = 307)
    glIsFramebuffer(1)=true 
    glDeleteFramebuffers(1,108FF014)
     
    // For each Texture: Resize(710, 307, 0); // 0 is ignored
    glBindTexture(GL_TEXTURE_2D_MULTISAMPLE,4)
    glTexImage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE,4,34837,710,307,true)
    glGetError()=GL_NO_ERROR 
    glBindTexture(GL_TEXTURE_2D_MULTISAMPLE,0)
     
    glBindTexture(GL_TEXTURE_2D_MULTISAMPLE,5)
    glTexImage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE,4,33323,710,307,true)
    glGetError()=GL_NO_ERROR 
    glBindTexture(GL_TEXTURE_2D_MULTISAMPLE,0)
     
    glBindTexture(GL_TEXTURE_2D_MULTISAMPLE,3)
    glTexImage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE,4,32856,710,307,true)
    glGetError()=GL_NO_ERROR 
    glBindTexture(GL_TEXTURE_2D_MULTISAMPLE,0)
     
    glBindTexture(GL_TEXTURE_2D_MULTISAMPLE,6)
    glTexImage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE,4,34843,710,307,true)
    glGetError()=GL_NO_ERROR 
    glBindTexture(GL_TEXTURE_2D_MULTISAMPLE,0)
     
    glBindTexture(GL_TEXTURE_2D_MULTISAMPLE,7)
    glTexImage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE,4,35056,710,307,true)
    glGetError()=GL_NO_ERROR 
    glBindTexture(GL_TEXTURE_2D_MULTISAMPLE,0)
     
    // Continue with the framebuffer creation
    glGenFramebuffers(1,108FF014)
    glBindFramebuffer(GL_FRAMEBUFFER,1)
    glFramebufferTexture2D(GL_FRAMEBUFFER,GL_COLOR_ATTACHMENT0,GL_TEXTURE_2D_MULTISAMPLE,4,0)
    glFramebufferTexture2D(GL_FRAMEBUFFER,GL_COLOR_ATTACHMENT1,GL_TEXTURE_2D_MULTISAMPLE,5,0)
    glFramebufferTexture2D(GL_FRAMEBUFFER,GL_COLOR_ATTACHMENT2,GL_TEXTURE_2D_MULTISAMPLE,3,0)
    glFramebufferTexture2D(GL_FRAMEBUFFER,GL_COLOR_ATTACHMENT3,GL_TEXTURE_2D_MULTISAMPLE,6,0)
    glFramebufferTexture2D(GL_FRAMEBUFFER,GL_DEPTH_STENCIL_ATTACHMENT,GL_TEXTURE_2D_MULTISAMPLE,7,0)
    glDrawBuffers(4,02A150A8)
    glCheckFramebufferStatus(GL_FRAMEBUFFER)=GL_FRAMEBUFFER_COMPLETE

    Thanks in advance for any hint!

  4. #4
    Senior Member OpenGL Guru Dark Photon's Avatar
    Join Date
    Oct 2004
    Location
    Druidia
    Posts
    4,167
    As a test, try setting the GL_TEXTURE_MIN_FILTER on all of your textures to GL_NEAREST.

  5. #5
    Junior Member Newbie
    Join Date
    Aug 2017
    Posts
    9
    Quote Originally Posted by Dark Photon View Post
    As a test, try setting the GL_TEXTURE_MIN_FILTER on all of your textures to GL_NEAREST.
    This generates the error: 1280-'InvalidEnum'
    I`m using GL_TEXTURE_2D_MULTISAMPLE as Target.

    I found this on the khronos`OpenGL documentation(https://www.khronos.org/registry/Ope...tisample.txt):

    (2) What commands may be used on multisample textures?

    RESOLVED: Multisample textures can be bound for rendering and texturing,
    but they cannot be loaded/read with SubImage commands (TexSubImage,
    CopyTexSubImage, GetTexImage), they don't support compressed formats,
    and they don't need TexParameters since they can only be fetched with
    texelFetchMultisample.

    The screen is still black after resizing =/ Nothing changed even with the generated error.

    #EDIT

    I also tried to detach the textures from the framebuffer using:
    Code :
    GL.FramebufferTexture2D(FramebufferTarget.Framebuffer, FramebufferAttachment.ColorAttachment0 + i, texture.TexTarget, 0, 0);

    But still the same error.
    Also, what may be interesting: if I delete the framebuffer after resizing any textures, It causes an AccessViolationException. This means that I`m writing to protected memory.
    Is this normal behavior? I have to delete the framebuffer before resizing textures to avoid the exception.

    Thanks in advance!
    Last edited by McStones; 08-31-2017 at 02:14 AM.

  6. #6
    Senior Member OpenGL Guru Dark Photon's Avatar
    Join Date
    Oct 2004
    Location
    Druidia
    Posts
    4,167
    Quote Originally Posted by McStones View Post
    This generates the error: 1280-'InvalidEnum'
    I`m using GL_TEXTURE_2D_MULTISAMPLE as Target.
    Sorry about that. That error makes sense. I guess I was remembering having issues when using 2D textures with render-to-texture, not 2D MSAA textures, and needing to reset the MIN_FILTER so that it wouldn't try to access MIPmap levels that didn't exist. That's not an issue for MSAA textures.

    Also, what may be interesting: if I delete the framebuffer after resizing any textures, It causes an AccessViolationException. This means that I`m writing to protected memory.
    Is this normal behavior? I have to delete the framebuffer before resizing textures to avoid the exception.
    No, it's not normal. That indicates either 1) a bug in your code, and/or 2) a bug in your GL drivers.

    At this point, I'd suggest you post a short, stand-alone GLUT text program that illustrates your problem. With that, folks here can build/run it, skim it, and give you feedback both on what you're doing as well as if/how it works on various GPUs and drivers.

    Here's a shell to copy/paste your code into:

    Code cpp:
    #include <stdio.h>
    #include <string.h>
    #include <stdlib.h>
    #include <GL/glew.h>
    #include <GL/glut.h>
     
    void checkGLError( const char hdr[] )
    {
      int err = glGetError();
      if( err )
      {
        fprintf(stderr, "ERROR %s: %s\n", hdr, gluErrorString(err));
        exit(1);
      }
    }
     
    void reshape(GLsizei w, GLsizei h)
    {
      glViewport(0, 0, w, h);
      glutPostRedisplay();
    }
     
    void keyboard( unsigned char key, int x, int y )
    {
      // Key Bindings
      switch( key )
      {
        case 27 : exit(0);                    break;
      }
    }
     
    void display()
    {
      glClearColor( 0,0,1,1 );
      glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
      glutSwapBuffers();
      checkGLError( "display() end" );
    }
     
    main( int argc, char *argv[] )
    {
      glutInit( &argc, argv );
      glutInitDisplayMode( GLUT_DOUBLE | GLUT_DEPTH | GLUT_RGB ); 
      glutCreateWindow( "window title" );
      checkGLError( "Create window" );
     
      glutReshapeFunc ( reshape  );
      glutDisplayFunc ( display  );
      glutKeyboardFunc( keyboard );
     
      glutPostRedisplay();
      glutMainLoop();
    }
    Last edited by Dark Photon; 08-31-2017 at 06:23 AM.

Tags for this Thread

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •