用平铺图像渲染四边形?

时间:2014-12-04 19:07:36

标签: 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
    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();
}

1 个答案:

答案 0 :(得分:0)

为什么您希望您使用的代码重复(以及多少次)纹理?

但是,代码原样与您的观察结果一致。您正在使用[0,1]范围内的texcoords,因此如果您在采样纹理之前没有调整texcoords,您应该只看到图像延伸到四边形。您可能通过目前尚未粘贴的着色器执行此操作。如果您希望纹理显示n - 沿着u维度平铺的时间和m的{​​{1}}次,则需要v用于[0,n]分别为u范围的1}}范围和[0,m]

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

v