Part of the Khronos Group
OpenGL.org

The Industry's Foundation for High Performance Graphics

from games to virtual reality, mobile phones to supercomputers

Page 1 of 2 12 LastLast
Results 1 to 10 of 14

Thread: MSAA with maginification's simple question

  1. #1
    Intern Contributor
    Join Date
    Dec 2012
    Posts
    74

    MSAA with maginification's simple question

    This program is only a version of the fbo code example of the the book OpenGL Programming Guide(the red book) fourth edition with a slight modification of multisampling and magnification instead of a copy-and-paste one. Since some fault within it, it runs on neither ATI nor NVIDIA graphics card which turns multisampling on.

    Code cpp:
    //fbo.c
    #include "stdio.h"
    #include "stdlib.h"
    #include "string.h"
    #include <windows.h>
    #include "gl\glew.h"
     
    #define GLUT_DISABLE_ATEXIT_HACK
     
    #include "glut.h"
     
    enum {Color, Depth, NumRenderbuffers};
     
    GLuint framebuffer, renderbuffer[NumRenderbuffers];
     
    void drawTiangle()
    {
        glColor3f(0.0f,1.0f,0.0f);
        glBegin(GL_TRIANGLES);
            glVertex3f(-1.0f,1.0f,0.0f);
            glVertex3f(1.0f,0.0f,0.0f);
            glVertex3f(-1.0f,-1.0f,0.0f);
        glEnd();
    }
     
    void init()
    {
        GLenum status;
        GLint samples;
        GLint bufs;
        GLenum err;
        char ErrorMessage[1024];
        int value;
        glEnable(GL_MULTISAMPLE_EXT);
        //glHint(GL_MULTISAMPLE_FILTER_HINT_NV, GL_NICEST); 
        glGetIntegerv (GL_SAMPLE_BUFFERS, &bufs);
        glGetIntegerv(GL_MAX_SAMPLES_EXT, &samples);
        printf("MSAA: buffers = %d samples = %d\n", bufs, samples);
        glGenFramebuffersEXT(NumRenderbuffers,renderbuffer);
        glBindRenderbufferEXT(GL_RENDERBUFFER_EXT,renderbuffer[Color]);
        //glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT,GL_RGBA8, 256,256);
        glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER_EXT,4,GL_RGBA8, 256,256);
        glBindRenderbufferEXT(GL_RENDERBUFFER_EXT,renderbuffer[Depth]);
        //glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT,GL_DEPTH_COMPONENT, 256,256);
        glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER_EXT,4,GL_DEPTH_COMPONENT24, 256,256);
        glGenFramebuffersEXT(1, & framebuffer);
        glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT,framebuffer);
        glFramebufferRenderbufferEXT(GL_DRAW_FRAMEBUFFER_EXT,GL_COLOR_ATTACHMENT0_EXT,GL_RENDERBUFFER_EXT,renderbuffer[Color]);
        glFramebufferRenderbufferEXT(GL_DRAW_FRAMEBUFFER_EXT,GL_DEPTH_ATTACHMENT_EXT,GL_RENDERBUFFER_EXT,renderbuffer[Depth]);
        status=glCheckFramebufferStatusEXT(GL_DRAW_FRAMEBUFFER_EXT);
        glEnable(GL_DEPTH_TEST);
    }
     
     
    void display()
    {
        GLenum status;
        glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT,framebuffer);
        status=glCheckFramebufferStatusEXT(GL_DRAW_FRAMEBUFFER_EXT);
        glViewport(0,0,256,256);
        //red
        glClearColor(1.0,0.0,0.0,1.0);
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
        glClearDepth(0.0f);
        drawTiangle();
        glViewport(0,0,512,512);
        glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT,framebuffer);
        glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT,0);
        status=glCheckFramebufferStatusEXT(GL_DRAW_FRAMEBUFFER_EXT);
     
        //blue
        //glClearColor(0.0,0.0,1.0,1.0);
        //glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
        //glReadBuffer(GL_COLOR_ATTACHMENT0);
        glBlitFramebufferEXT(0,0,255,255,0,0,511,511,GL_COLOR_BUFFER_BIT,GL_NEAREST);
        status=glCheckFramebufferStatusEXT(GL_DRAW_FRAMEBUFFER_EXT);
        glutSwapBuffers();
    }
     
    int main(int argc, char** argv)
    {
       glutInit(&argc, argv);
       glutInitDisplayMode(GLUT_DOUBLE| GLUT_RGBA | GLUT_DEPTH | GLUT_MULTISAMPLE);
       glutInitWindowSize(512, 512);
       glutInitWindowPosition(100, 100);
       glutCreateWindow("Frame buffer object");
     
       //Initialize the glew library.
       glewInit();
     
       init();
       glutDisplayFunc(display);
       glutMainLoop();
       return 0;
    }
    Last edited by Dark Photon; 12-03-2012 at 06:53 AM.

  2. #2
    Senior Member OpenGL Guru Dark Photon's Avatar
    Join Date
    Oct 2004
    Location
    Druidia
    Posts
    3,123
    Please don't post multiple copies of a single message. Also, use [code]...[/code] or [highlight=cpp]...[/highlight] to mark code blocks to preserve the formatting. Fixed that for you.

    If I hack the Windows-isms out of your #includes as follows:

    Code cpp:
    //fbo.c
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #ifdef WIN32
    # include <windows.h>
    #endif
    #include <GL/glew.h>
     
    #define GLUT_DISABLE_ATEXIT_HACK
     
    #include <GL/glut.h>
    ...


    It builds and runs just fine on NVidia/Linux. Creates a GL window visual 0x31 (4x MSAA), and it successfully creates a renderbuffer FBO with 4 MSAA samples.

    In your display() function though, your glBlitFramebuffer fails with "invalid operation" for this reason:

    Code :
    GL_INVALID_OPERATION is generated if [I]GL_SAMPLE_BUFFERS[/I] for both read and draw 
    buffers greater than zero and the dimensions of the source and destination 
    rectangles is not identical.

    Change the target to 0,0,255,255 and it'll work. You need to check for GL errors:

    * glGetError

    Chances are you don't want GLUT to create a MSAA system framebuffer. So remove GLUT_MULTISAMPLE.
    Last edited by Dark Photon; 12-04-2012 at 06:15 AM.

  3. #3
    Intern Contributor
    Join Date
    Dec 2012
    Posts
    74
    Quote Originally Posted by Dark Photon View Post
    Please don't post multiple copies of a single message. Also, use [code]...[/code] or [highlight=cpp]...[/highlight] to mark code blocks to preserve the formatting. Fixed that for you.

    If I hack the Windows-isms out of your #includes as follows:

    Code cpp:
    //fbo.c
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #ifdef WIN32
    # include <windows.h>
    #endif
    #include <GL/glew.h>
     
    #define GLUT_DISABLE_ATEXIT_HACK
     
    #include <GL/glut.h>
    ...


    It builds and runs just fine on NVidia/Linux. Creates a GL window visual 0x31 (4x MSAA), and it successfully creates a renderbuffer FBO with 4 MSAA samples.

    In your display() function though, your glBlitFramebuffer fails with "invalid operation" for this reason:

    Code :
    GL_INVALID_OPERATION is generated if [I]GL_SAMPLE_BUFFERS[/I] for both read and draw 
    buffers greater than zero and the dimensions of the source and destination 
    rectangles is not identical.

    Change the test to 0,0,255,255 and it'll work. You need to check for GL errors:

    * glGetError

    Chances are you don't want GLUT to create a MSAA system framebuffer. So remove GLUT_MULTISAMPLE.

    The error caused is because the dimensions of the source and destination rectangles is not identical. But the target of this program is first creating a image by using multisamping then mapped to the screen with magnification as a static one.
    So can you provide a solution how this can be done as fast as possible?

    Thanks in advance and god bless you!

  4. #4
    Senior Member OpenGL Guru Dark Photon's Avatar
    Join Date
    Oct 2004
    Location
    Druidia
    Posts
    3,123
    Quote Originally Posted by newbiecow View Post
    The error caused is because the dimensions of the source and destination rectangles is not identical. But the target of this program is first creating a image by using multisamping then mapped to the screen with magnification as a static one.
    So can you provide a solution how this can be done as fast as possible?
    You can't resize a multisample buffer (with glBlitFramebuffer). Downsample first. Then resize. (two blit calls)

    If you write your own shader for this, you could of course downsample and resize all-in-one-go.
    Last edited by Dark Photon; 12-04-2012 at 06:34 AM.

  5. #5
    Intern Contributor
    Join Date
    Dec 2012
    Posts
    74
    Quote Originally Posted by Dark Photon View Post
    You can't resize a multisample buffer (with glBlitFramebuffer). Downsample first. Then resize. (two blit calls)

    If you write your own shader for this, you could of course downsample and resize all-in-one-go.
    So can you please paste this two blit calls here?

  6. #6
    Senior Member OpenGL Guru Dark Photon's Avatar
    Join Date
    Oct 2004
    Location
    Druidia
    Posts
    3,123
    They're both glBlitFramebuffer. In the first, call it to blit between an MSAA target and a single sample target (same resolution) -- this does the downsample. In the second, call it to blit between the single-sample target and another single-sample target (different resolutions) -- this does the resize.

  7. #7
    Intern Contributor
    Join Date
    Dec 2012
    Posts
    74
    Quote Originally Posted by Dark Photon View Post
    They're both glBlitFramebuffer. In the first, call it to blit between an MSAA target and a single sample target (same resolution) -- this does the downsample. In the second, call it to blit between the single-sample target and another single-sample target (different resolutions) -- this does the resize.
    Thanks a lot! I have done such operations. But after my trial, the most important thing should be noticed is between the two glBlitFramebuffer calls, a
    glDisable(GL_MULTISAMPLE);
    should be called. Otherwise a GL_INVALID_OPERATION error will be reported because the samples of read and draw buffer are not the same.

    Thanks for all your help, Dark Photon!

    Best Regards,

    newbiecow

  8. #8
    Senior Member OpenGL Guru Dark Photon's Avatar
    Join Date
    Oct 2004
    Location
    Druidia
    Posts
    3,123
    Actually, whether the buffer has multisample rasterization enabled or not is a separate issue. The problem comes when you try to blit between two different MSAA buffers which have different number of samples per pixel.

  9. #9
    Intern Contributor
    Join Date
    Dec 2012
    Posts
    74
    Quote Originally Posted by Dark Photon View Post
    You can't resize a multisample buffer (with glBlitFramebuffer). Downsample first. Then resize. (two blit calls)

    If you write your own shader for this, you could of course downsample and resize all-in-one-go.
    You mean that if I write a shader, I can both downsample and resize. Then can you tell me if I write a shader, can I use it to sample the stencil buffer in my own way?


    Best Regards,

    newbiecow

  10. #10
    Senior Member OpenGL Guru Dark Photon's Avatar
    Join Date
    Oct 2004
    Location
    Druidia
    Posts
    3,123
    Yes, if your GPU/driver supports OpenGL 4.3 and/or ARB_stencil_texturing.

    If not, probably some PBO copy games you can play to "retype" a stencil or depth/stencil texture so you can read it in the shader.

Posting Permissions

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