Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/qt/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ OpenGL故障;抗锯齿MSAA 8x后白线中的黑色像素_C++_Qt_Opengl_Antialiasing_Msaa - Fatal编程技术网

C++ OpenGL故障;抗锯齿MSAA 8x后白线中的黑色像素

C++ OpenGL故障;抗锯齿MSAA 8x后白线中的黑色像素,c++,qt,opengl,antialiasing,msaa,C++,Qt,Opengl,Antialiasing,Msaa,当我使用抗锯齿MSAA 8x时,我的Qt/OpenGL应用程序出现了一个小故障。这是一个有小问题的屏幕截图:黑线像素。它的纹理看起来很糟糕,但我不知道如何修复它 这是屏幕截图: 代码如下: 背景图片.h: class BackgroundImage { public: explicit BackgroundImage(QOpenGLFunctions * GL); virtual ~BackgroundImage(); void save(int w, int h);

当我使用抗锯齿MSAA 8x时,我的Qt/OpenGL应用程序出现了一个小故障。这是一个有小问题的屏幕截图:黑线像素。它的纹理看起来很糟糕,但我不知道如何修复它

这是屏幕截图:

代码如下:

背景图片.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);
}

错误在Render::RenderImage(…)中

此代码

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);
必须用此代码替换

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);

使用纹理四边形时,MSAA没有帮助。它只处理/平滑多边形的边,而不是纹理中的边。好的,这是一个临时代码。最好使用FBO/RBO以blit渲染到屏幕的FBO