使用平铺图像渲染四边形



我正在学习如何在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] 范围内的 texcoord,因此,如果您在对纹理进行采样之前没有调整 texcoord,您应该只看到划到四边形的图像。 您可以通过到目前为止尚未粘贴的着色器来执行此操作。如果希望纹理沿u维度平铺显示 n 次平铺,沿v平铺显示 m 次,则需要分别对u范围使用 [0,n],对v范围使用 [0,m]

第二个问题是您的 texcoords 与您的几何图形不匹配。这可能会导致您描述的"形成四边形的两个三角形是可见的"。你的两个三角形不会在你期望的纹理空间中建立四边形,你应该交换最后两行:

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 */
};

相关内容

  • 没有找到相关文章

最新更新