Opengl 使用平铺图像渲染四边形?

Opengl 使用平铺图像渲染四边形?,opengl,qt5,Opengl,Qt5,我正在学习如何在OpenGL中对四边形进行纹理处理。这个想法是让图像在整个四边形上重复,但是我将图像拉伸,形成四边形的两个三角形是可见的 我错过了什么?代码如下所示 void GLViewer::initializeGL() { float vertices[] = { -0.5, 0.0, 0.0, 0.5, 0.0, 0.0, 0.5, 0.5, 0.0 }; // Setup viewport g

我正在学习如何在OpenGL中对四边形进行纹理处理。这个想法是让图像在整个四边形上重复,但是我将图像拉伸,形成四边形的两个三角形是可见的

我错过了什么?代码如下所示

void GLViewer::initializeGL()
{
    float vertices[] =
    {
        -0.5, 0.0, 0.0,
         0.5, 0.0, 0.0,
         0.5, 0.5, 0.0
    };

    // Setup viewport
    glViewport(0, 0,this->width(), this->height());

    // OpenGL configuration
    glClearColor(0.0f,0.0f,0.0f,1.0f);

    // Setup shaders
    m_triangleShader.addShaderFromSourceFile(QGLShader::Vertex, ":/vshader.glsl");
    m_triangleShader.addShaderFromSourceFile(QGLShader::Fragment, ":/fshader.glsl");
    m_triangleShader.link();

    glGenVertexArrays(1, &m_VAO);
    glBindVertexArray(m_VAO);

    glPointSize(10);

    glGenBuffers(1, &m_VBO);
    glBindBuffer(GL_ARRAY_BUFFER, m_VBO);
    glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
    glEnableVertexAttribArray(0);
    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0);

    glBindBuffer(GL_ARRAY_BUFFER, 0);
    glBindVertexArray(0);

    float quad[] =
    {
        -1.0, -1.0,
         1.0, -1.0,
        -1.0,  1.0,
         1.0,  1.0
    };

    float uv[] =
    {
        0.0, 0.0,
        1.0, 0.0,
        1.0, 1.0,
        0.0, 1.0
    };

    m_backgroundShader.addShaderFromSourceFile(QGLShader::Vertex, ":/vbackground.glsl");
    m_backgroundShader.addShaderFromSourceFile(QGLShader::Fragment, ":/fbackground.glsl");
    m_backgroundShader.link();
    glGenVertexArrays(1, &m_backgroundVAO);
    glBindVertexArray(m_backgroundVAO);

    glGenBuffers(1, &m_quadVBO);
    glBindBuffer(GL_ARRAY_BUFFER, m_quadVBO);
    glBufferData(GL_ARRAY_BUFFER, sizeof(quad), quad, GL_STATIC_DRAW);
    glEnableVertexAttribArray(0);
    glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, 0);

    glGenBuffers(1, &m_uvVBO);
    glBindBuffer(GL_ARRAY_BUFFER, m_uvVBO);
    glBufferData(GL_ARRAY_BUFFER, sizeof(uv), uv, GL_STATIC_DRAW);
    glEnableVertexAttribArray(1);
    glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 0, 0);

    glGenTextures(1, &m_textureID);
    glBindTexture(GL_TEXTURE_2D, m_textureID);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    QImage image(":/background.png");
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, image.width(), image.height(),
                 0, GL_RGBA, GL_UNSIGNED_BYTE, image.bits());

    glBindTexture(GL_TEXTURE_2D, 0);
    glBindBuffer(GL_ARRAY_BUFFER, 0);
    glBindVertexArray(0);
}

void GLViewer::paintGL()
{
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    glDepthMask(GL_TRUE);
    glEnable(GL_DEPTH_TEST);

    m_backgroundShader.bind();
    glBindVertexArray(m_backgroundVAO);
    glActiveTexture(GL_TEXTURE0);
    glBindTexture(GL_TEXTURE_2D, m_textureID);
    glUniform1i(glGetUniformLocation(m_backgroundShader.programId(),"tex"),0);
    glDrawArrays(GL_TRIANGLE_STRIP,0,4);

    m_triangleShader.bind();
    glBindVertexArray(m_VAO);
    glDrawArrays(GL_TRIANGLES, 0, 3);

    update();
}

为什么你希望你的纹理被你正在使用的代码重复(以及重复多少次)

然而,代码原样与您的观察结果是一致的。您正在使用[0,1]范围内的texcoords,因此如果在对纹理进行采样之前未调整texcoords,则应仅看到拉伸到四边形的图像。可以通过到目前为止尚未粘贴的着色器执行此操作。如果希望纹理沿
u
维度显示
n
-次平铺,沿
v
显示
m
次平铺,则需要分别对
u
范围使用
[0,n]
,对
v
范围使用
[0,m]

第二个问题是texcoords与几何体不匹配。这可能导致了您所描述的“构成四边形的两个三角形可见”。您的两个三角形不会在预期的纹理空间中构建四边形,您应该交换最后两条线:


如果我只让我的
uv
坐标大于范围[0,0]x[1,1],我实际上可以强制平铺而不使用着色器。
float uv[] =
{
    0.0, 0.0,
    1.0, 0.0,
    1.0, 1.0,      /* should be 0.0, 1.0 */
    0.0, 1.0       /* should be 1.0, 1.0 */
};