为什么我的qt opengl程序总是生成4张图片?

Why always produce 4 pictures in my qt opengl program?

这是我的代码: 从 qt 示例修改:Examples\Qt-5.14.2\quick\scenegraph\openglunderqml

void SquircleRenderer::init()
{
    unsigned char* data = (unsigned char*)malloc(1200*4);
    for(int i=0;i<600;i++)
    {
        data[i*4] = 0;
        data[i*4+1] = 255;
        data[i*4+2] = 0;
        data[i*4+3] = 255;
    }
    for(int i=600;i<1200;i++)
    {
        data[i*4] = 0;
        data[i*4+1] = 0;
        data[i*4+2] = 255;
        data[i*4+3] = 255;
    }

    if (!m_program) {
        QSGRendererInterface *rif = m_window->rendererInterface();
        Q_ASSERT(rif->graphicsApi() == QSGRendererInterface::OpenGL || rif->graphicsApi() == QSGRendererInterface::OpenGLRhi);

        initializeOpenGLFunctions();
        if (texs[0])
        {
            glDeleteTextures(1, texs);
        }
        glGenTextures(1, texs);

        glBindTexture(GL_TEXTURE_2D, texs[0]);

        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);

        glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 30, 40, 0, GL_RGBA, GL_UNSIGNED_BYTE, data);


        m_program = new QOpenGLShaderProgram();
        m_program->addCacheableShaderFromSourceCode(QOpenGLShader::Vertex,
                                                    "attribute highp vec4 vertices;"
                                                    "varying highp vec2 coords;"
                                                    "void main() {"
                                                    "    gl_Position = vertices;"
                                                    "    coords = vertices.xy;"
                                                    "}");
        m_program->addCacheableShaderFromSourceCode(QOpenGLShader::Fragment,
                                                    "varying highp vec2 coords;"
                                                    "uniform sampler2D inputImageTexture;"
                                                    "void main() {"
                                                    "    gl_FragColor = texture2D(inputImageTexture, coords);"
                                                    "}");

        m_program->bindAttributeLocation("vertices", 0);
        m_program->link();

        arrUni[0] = m_program->uniformLocation("inputImageTexture");
    }
}

//! [4] //! [5]
void SquircleRenderer::paint()
{
    // Play nice with the RHI. Not strictly needed when the scenegraph uses
    // OpenGL directly.
    m_window->beginExternalCommands();

    m_program->bind();

    m_program->enableAttributeArray(0);

    float values[] = {
        -1, 1,
        1, 1,
        -1, -1,
        1, -1
    };

    // This example relies on (deprecated) client-side pointers for the vertex
    // input. Therefore, we have to make sure no vertex buffer is bound.
    glBindBuffer(GL_ARRAY_BUFFER, 0);

    m_program->setAttributeArray(0, GL_FLOAT, values, 2);//values
    //m_program->setUniformValue("t", (float) m_t);

    qDebug()<<m_viewportSize.width()<<m_viewportSize.height()<<"\n";
    glViewport(0, 0, m_viewportSize.width(), m_viewportSize.height());

    glDisable(GL_DEPTH_TEST);

    glEnable(GL_BLEND);
    glBlendFunc(GL_SRC_ALPHA, GL_ONE);

    glActiveTexture(GL_TEXTURE0);
    glBindTexture(GL_TEXTURE_2D, texs[0]);

    glUniform1i(arrUni[0], 0);
    glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);

    m_program->disableAttributeArray(0);
    m_program->release();

    m_window->endExternalCommands();
}

如图所示,它产生了4张相同的图片,你能告诉我如何产生一张图片填满整个window吗?:
试了很多方法都没用,估计是values数组或者glTexImage2D函数有问题

纹理在 [0, 1] 范围内映射,超出该范围的值将以模数循环返回到其中,从而创建重复模式。解释 [-1, 1] 范围内的纹理会导致您所看到的,因为您在两个轴上映射的 UV 范围恰好是两倍。

有几种方法可以解决这个问题。但我个人更喜欢像这样的全帧缓冲区传递是将属性标准化,然后将其转换为顶点着色器中 clip-space 坐标的预期 [-1, 1] 范围:

float values[] = {
  0.f, 1.f,
  1.f, 1.f,
  0.f, 0.f,
  1.f, 0.f
};
gl_Position = vertices * 2.0 - vec4(1.0, 1.0,0.0,1.0);

另一种常用技术是完全取消属性缓冲区,并使用 gl_VertexID 直接生成 UV 和坐标。