1
votes

I have a glitch in my Qt/OpenGL application when I use the Anti-Aliasing MSAA 8x. This is the screenshot with the glitch: black pixels in white lines. It looks a bad strech of the texture but I don't know how to fix it

This is the screenshot:

screenshot

This is the code:

BackgroundImage.h :

class BackgroundImage
{
public:
    explicit BackgroundImage(QOpenGLFunctions * GL);
    virtual ~BackgroundImage();

    void save(int w, int h);
    void restoreToScreen();

private:
    // background consts
    static const int BACKGROUND_SCREEN_WIDTH_MAX = 8 * 1024;
    static const int BACKGROUND_SCREEN_HEIGHT_MAX = 8 * 1024;
    static const int BACKGROUND_BUFFER_SIZE_MAX = sizeof(U16) * BACKGROUND_SCREEN_WIDTH_MAX * BACKGROUND_SCREEN_HEIGHT_MAX;

    // OpenGL Functions
    QOpenGLFunctions * m_gl;

    // rgb members
    int m_width;
    int m_height;
    U32 m_colorTextureId;

    U16 m_depthBuffer[BACKGROUND_BUFFER_SIZE_MAX / sizeof(U16)];
};

BackgroundImage.cpp :

#include "BackgroundImage.h"   
#include "render.h" // glRasterPos   
#include "QDebug"

BackgroundImage::BackgroundImage(QOpenGLFunctions * gl):
    m_gl(gl),
    m_width(0),
    m_height(0),
    m_colorTextureId(0), 
    m_multiSampledFBO(nullptr),
    m_downSampledFBO(nullptr)
{}

BackgroundImage::~BackgroundImage()
{
    m_gl->glDeleteTextures(1, &m_colorTextureId);

    if (m_multiSampledFBO)
    {
        delete m_multiSampledFBO;
    }

    if (m_downSampledFBO)
    {
        delete m_downSampledFBO;
    }
}

void BackgroundImage::beginSave(int w, int h)
{
    if (w!=m_width || h!=m_height) 
    {
        regenerateFBOs(w, h);
        m_width = w;
        m_height = h;    
    }

   m_multiSampledFBO->bind();

   m_gl->glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
}

void BackgroundImage::endSave()
{
    QOpenGLFramebufferObject::blitFramebuffer(m_downSampledFBO, m_multiSampledFBO, GL_COLOR_BUFFER_BIT, GL_LINEAR);

    QOpenGLFramebufferObject::blitFramebuffer(m_downSampledFBO, m_multiSampledFBO, GL_DEPTH_BUFFER_BIT, GL_NEAREST);

    m_downSampledFBO->bind();

    m_gl->glPixelStorei(GL_PACK_ALIGNMENT, 1);

    // Fill background Image + Generate a texture

    m_colorTextureId = m_downSampledFBO->texture();

    m_gl->glPixelStorei(GL_PACK_ALIGNMENT, 2);

    // Read Depth Buffer

    m_gl->glDepthMask(GL_TRUE); // used for enable the zbuffer writing (cf . https://www.khronos.org/registry/OpenGL-Refpages/gl2.1/xhtml/glDepthMask.xml)

    //glRasterPos4f(0, 0, 0, 1);

    m_gl->glReadPixels(0,0, m_width, m_height, GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT, (void*)m_depthBuffer);

    m_multiSampledFBO->bindDefault();
}

void BackgroundImage::restoreToScreen()
{
    m_gl->glEnable(GL_DEPTH_TEST);
    m_gl->glDepthFunc(GL_LESS);
    m_gl->glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
    m_gl->glDepthFunc(GL_ALWAYS);

    // render background
    m_gl->glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);

    Render::RenderImage(m_colorTextureId, 0,0, m_width, m_height);

    m_gl->glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);

    m_gl->glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);

    // Restore Depth Buffer
    m_gl->glDepthMask(GL_TRUE); // used for enable the zbuffer writing (cf . https://www.khronos.org/registry/OpenGL-Refpages/gl2.1/xhtml/glDepthMask.xml)

    m_gl->glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
    m_gl->glDepthFunc(GL_ALWAYS);

    m_gl->glPixelStorei(GL_PACK_ALIGNMENT, 2);

    glDrawPixels(m_width, m_height, GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT, (GLvoid*) m_depthBuffer);

    m_gl->glDepthFunc(GL_LESS);

    m_gl->glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
}

void BackgroundImage::regenerateFBOs(int w, int h)
{
    if (m_multiSampledFBO)
    {
        delete m_multiSampledFBO;
    }

    if (m_downSampledFBO)
    {
        delete m_downSampledFBO;
    }

    //MultiSampling set to 4 now

    QOpenGLFramebufferObjectFormat muliSampleFormat;
    muliSampleFormat.setAttachment(QOpenGLFramebufferObject::Depth);
    muliSampleFormat.setMipmap(true);
    muliSampleFormat.setSamples(8);
    muliSampleFormat.setTextureTarget(GL_TEXTURE_2D);
    muliSampleFormat.setInternalTextureFormat(GL_BGRA_EXT);
    m_multiSampledFBO = new QOpenGLFramebufferObject(w,h, muliSampleFormat);

    QOpenGLFramebufferObjectFormat downSampledFormat;
    downSampledFormat.setAttachment(QOpenGLFramebufferObject::Depth);
    downSampledFormat.setMipmap(true);
    downSampledFormat.setTextureTarget(GL_TEXTURE_2D);
    downSampledFormat.setInternalTextureFormat(GL_BGRA_EXT);
    m_downSampledFBO = new QOpenGLFramebufferObject(w, h, downSampledFormat);
}

Render.cpp :

void Render::RenderImage(U32 tex, int x, int y, int w, int h, float anchorX, float anchorY)
{
    glClear(GL_DEPTH_BUFFER_BIT);

    GLboolean depth = glIsEnabled(GL_DEPTH_TEST);
    if (depth)
        glDisable(GL_DEPTH_TEST);

    glMatrixMode(GL_PROJECTION);
    glPushMatrix();
    glLoadIdentity();
    gluOrtho2D(0, s_width, s_height, 0);

    glMatrixMode(GL_MODELVIEW);
    glPushMatrix();
    glLoadIdentity();

    glColor3ub(255, 255, 255);

    glEnable(GL_TEXTURE_2D);
    glBindTexture(GL_TEXTURE_2D, tex);

    glEnableClientState(GL_VERTEX_ARRAY);
    glEnableClientState(GL_TEXTURE_COORD_ARRAY);
    glDisableClientState(GL_COLOR_ARRAY);

    x -= (int)(anchorX * w);
    y -= (int)(anchorY * h);

    gVertices[0] = VECTOR3F(x, y, 0);
    gVertices[1] = VECTOR3F(x + w - 1, y, 0);
    gVertices[2] = VECTOR3F(x + w - 1, y + h - 1, 0);
    gVertices[3] = VECTOR3F(x, y + h - 1, 0);

    gTexCoords[0] = VECTOR2F(0, 1);
    gTexCoords[1] = VECTOR2F(1, 1);
    gTexCoords[2] = VECTOR2F(1, 0);
    gTexCoords[3] = VECTOR2F(0, 0);

    gIndexes[0] = 2;
    gIndexes[1] = 1;
    gIndexes[2] = 0;

    gIndexes[3] = 0;
    gIndexes[4] = 3;
    gIndexes[5] = 2;

    glVertexPointer(3, GL_FLOAT, 0, gVertices);
    glTexCoordPointer(2, GL_FLOAT, 0, gTexCoords);
    glDrawElements(GL_TRIANGLES, 3 * 2, GL_UNSIGNED_SHORT, gIndexes);

    glDisable(GL_TEXTURE_2D);

    glPopMatrix();

    glMatrixMode(GL_PROJECTION);
    glPopMatrix();
    glMatrixMode(GL_MODELVIEW);

    if (depth)
        glEnable(GL_DEPTH_TEST);
}
1
MSAA doesn't help when working with a textured quad. It only handles/smoothes edges of polygons, not edges in textures.BDL
Ok, it's a temp code. It's better to use a FBO/RBO to render to the screen's FBO with a blitJ. S.

1 Answers

2
votes

The error is in Render::RenderImage(...)

This code ...

gVertices[0] = VECTOR3F(x, y, 0);
gVertices[1] = VECTOR3F(x + w - 1, y, 0);
gVertices[2] = VECTOR3F(x + w - 1, y + h - 1, 0);
gVertices[3] = VECTOR3F(x, y + h - 1, 0);

must be replaced by this code

gVertices[0] = VECTOR3F(x, y, 0);
gVertices[1] = VECTOR3F(x + w, y, 0);
gVertices[2] = VECTOR3F(x + w, y + h, 0);
gVertices[3] = VECTOR3F(x, y + h, 0);