C++ 为什么总是在我的qt opengl程序中生成4幅图片?

C++ 为什么总是在我的qt opengl程序中生成4幅图片?,c++,qt,opengl,qml,shader,C++,Qt,Opengl,Qml,Shader,这是我的密码: 从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;

这是我的密码: 从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();
}
void squirclerender::init()
{
无符号字符*数据=(无符号字符*)malloc(1200*4);
对于(inti=0;igraphicsApi()==qsgrenderinterface::OpenGL | | rif->graphicsApi()==qsgrenderinterface::OpenGLRhi);
初始化EnglFunctions();
if(texs[0])
{
gldelete纹理(1,texs);
}
玻璃纤维织物(1,texs);
glBindTexture(GL_TEXTURE_2D,texs[0]);
glTexParameteri(GL_纹理2D,GL_纹理MAG_过滤器,GL_最近);
glTexParameteri(GL\u纹理\u 2D,GL\u纹理\u最小\u过滤器,GL\u最近);
GLTEXAGE2D(GL_纹理_2D,0,GL_RGBA,30,40,0,GL_RGBA,GL_无符号_字节,数据);
m_程序=新QOpenGLShaderProgram();
m_程序->addCacheableShaderFromSourceCode(QOpenGLShader::Vertex,
“属性highp vec4顶点;”
“可变高矢量2坐标;”
“void main(){”
“gl_位置=顶点;”
“坐标=顶点.xy;”
"}");
m_程序->addCacheableShaderFromSourceCode(QOpenGLShader::Fragment,
“可变高矢量2坐标;”
“均匀采样2D inputImageTexture;”
“void main(){”
gl_FragColor=texture2D(输入图像纹理,坐标)
"}");
m_程序->bindAttributeLocation(“顶点”,0);
m_程序->链接();
arrUni[0]=m_程序->统一位置(“inputImageTexture”);
}
}
//! [4] //! [5]
void squirclerender::paint()
{
//善用RHI。当scenegraph使用
//直接使用OpenGL。
m_window->beginternalcommands();
m_程序->绑定();
m_program->enableAttributeArray(0);
浮点值[]={
-1, 1,
1, 1,
-1, -1,
1, -1
};
//此示例依赖于顶点的客户端指针(已弃用)
//因此,我们必须确保没有顶点缓冲区被绑定。
glBindBuffer(GL_数组_BUFFER,0);
m_程序->setAttributeArray(0,GL_浮点,值,2);//值两个一读
//m_程序->设置UniformValue(“t”,(float)m_t);

qDebug()纹理在
[0,1]
范围内映射,超出该范围的值以模循环方式返回到该范围内,这会创建一个重复的图案。解释
[-1,1]
范围内的纹理会导致您看到的结果,因为您在两个轴上映射的UV范围正好是UV范围的两倍

有几种方法可以解决此问题。但我个人喜欢这样的完整帧缓冲区过程,即对属性进行规范化,然后将其转换为顶点着色器中剪辑空间坐标的预期
[-1,1]
范围:

float values[] = {
  0.f, 1.f,
  1.f, 1.f,
  0.f, 0.f,
  1.f, 0.f
};

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

谢谢!这很有效,gl\u Position=vertexs*2.0-vec4(1.0,1.0,0.0,1.0);
gl_Position = vertices * 2.0 - vec4(1.0, 1.0,0.0,1.0);