纹理坐标不依赖于分辨率,opengl需要知道如何将纹理像素映射到纹理坐标。
 纹理像素和纹理坐标的区别:
 纹理像素是有限的。
 纹理坐标的精度是无限的,可以是任意的浮点值。
 一个像素需要一个颜色。
 因此,所谓采样就是通过纹理坐标获取纹理像素的颜色值。
 
 
 gl_nearest:左图,贴大图时,取最近的颜色值。
 gl_linear: 右图,贴大图时,根据距离及权重线性返回颜色结果。
 坐标数据:
 float vertices[] = {
 // positions // colors // texture coords
 0.9f, 0.9f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, // top right
 0.9f, -0.9f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, // bottom right
 -0.9f, -0.9f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, // bottom left
 -0.9f, 0.9f, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f // top left
 };
 unsigned int indices[] = { // note that we start from 0!
 0, 1, 3, // first triangle
 1, 2, 3 // second triangle
 };
 initializeGL()函数:
	initializeOpenGLFunctions();
    //创建VBO和VAO对象,并赋予ID
    glGenVertexArrays(1, &VAO);
    glGenBuffers(1, &VBO);
    //绑定VBO和VAO对象
    glBindVertexArray(VAO);
    glBindBuffer(GL_ARRAY_BUFFER, VBO);
    //为当前绑定到target的缓冲区对象创建一个新的数据存储。
    //如果data不是NULL,则使用来自此指针的数据初始化数据存储
    glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
    //告知显卡如何解析缓冲里的属性值
    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void*)0);
    //开启VAO管理的第一个属性值
    glEnableVertexAttribArray(0);
    glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void*)(3 * sizeof(float)));
    glEnableVertexAttribArray(1);
    glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void*)(6 * sizeof(float)));
    glEnableVertexAttribArray(2);
    glBindBuffer(GL_ARRAY_BUFFER, 0);
    bool success;
    shaderProgram.addShaderFromSourceFile(QOpenGLShader::Vertex, "shaders/shapes.vert");
    shaderProgram.addShaderFromSourceFile(QOpenGLShader::Fragment, "shaders/shapes.frag");
    success = shaderProgram.link();
    if (!success)
        qDebug() << "ERR:" << shaderProgram.log();
    glGenBuffers(1, &EBO);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);
    textureSmall = new QOpenGLTexture(QImage("images/small.png").mirrored());
    shaderProgram.bind();
    shaderProgram.setUniformValue("textureSmall", 0);
    glBindVertexArray(0);
    textureSmall->bind(0);
    /*  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_MIRRORED_REPEAT);
      glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_MIRRORED_REPEAT);*/
    float borderColor[] = { 0.25f, 0.88f, 0.82f, 1.0f };
    glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, borderColor);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
 
paintGL()函数:
	glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
    glClear(GL_COLOR_BUFFER_BIT);
    shaderProgram.bind();
    glBindVertexArray(VAO);
    textureSmall->bind(0);
    glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, NULL);
 
GL_NEAREST 结果图像:
 
 GL_LINEAR 结果图像:
 



















