前言:

本文的代码是 LearnOpenGL 中对应代码,这里提供学习,大家喜欢的可去官方网站去看看:

LearnOpenGL-CNhttps://learnopengl-cn.readthedocs.io/zh/latest/本章简单使用不同的环绕方式,来显示不同的纹理方案。

Texture Wrapping

纹理坐标通常的范围是从(0, 0)到(1, 1), 如果我们把纹理坐标设置为范围以外会发生什么?
OpenGL默认的行为是重复这个纹理图像(我们简单地忽略浮点纹理坐标的整数部分), 但
OpenGL提供了更多的选择:

环绕方式 描述
GL_REPEAT 纹理的默认行为, 重复纹理图像
GL_MIRRORED_REPEAT 和 GL_REPEAT 一样, 除了重复的图片是镜像放置的
GL_CLAMP_TO_EDGE 纹理坐标会在0到1之间, 超出的部分会重复纹理坐标的
边缘, 就是边缘被拉伸
GL_CLAMP_TO_BORDER 超出的部分是用户指定的边缘的颜色

对应的图标状况:

前面提到的选项都可以使用 glTexParameter 函数单独设置每个坐标轴 s 、 t (如果是使用3D
纹理那么还有一个 r )它们和 x 、 y ( z )是相等的。

glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_MIRRORED_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_MIRRORED_REPEAT);

如果我们选择 GL_CLAMP_TO_BORDER 选项, 我们还要指定一个边缘的颜色。 这次使
用 glTexParameter 函数的 fv 后缀形式, 加上 GL_TEXTURE_BORDER_COLOR 作为选项, 这个函数需要我们传递一个边缘颜色的float数组作为颜色值:

float borderColor[] = { 1.0f, 1.0f, 0.0f, 1.0f };
glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, borderColor);

例子:

顶点坐标:

float vertices[] = {// positions          // colors           // texture coords0.8f,  0.8f, 0.0f,   1.0f, 0.0f, 0.0f,   2.0f, 2.0f, // top right0.8f, -0.8f, 0.0f,   0.0f, 1.0f, 0.0f,   2.0f, 0.0f, // bottom right-0.8f, -0.8f, 0.0f,   0.0f, 0.0f, 1.0f,   0.0f, 0.0f, // bottom left-0.8f,  0.8f, 0.0f,   1.0f, 1.0f, 0.0f,   0.0f, 2.0f  // top left};unsigned int indices[] = {  // note that we start from 0!0, 1, 3,  // first Triangle1, 2, 3   // second Triangle
};

这里纹理我们不在是1 1, 写出纹理超出部分。

顶点着色器写法:

#version 330 core
layout (location = 0) in vec3 aPos;
layout (location = 1) in vec3 aColor;
layout (location = 2) in vec2 aTexCoord;out vec3 ourColor;
out vec2 TexCoord;void main()
{gl_Position = vec4(aPos, 1.0);ourColor = aColor;TexCoord = vec2(aTexCoord.x, aTexCoord.y);
}

片段着色器

#version 330 core
out vec4 FragColor;in vec3 ourColor;
in vec2 TexCoord;// texture samplers
uniform sampler2D texture1;
uniform sampler2D texture2;void main()
{// linearly interpolate between both textures (80% container, 20% awesomeface)//FragColor = mix(texture(texture1, TexCoord), texture(texture2, TexCoord), 0.2);FragColor =texture(texture2,TexCoord);
}

这里我们使用了纹理2

GL_CLAMP_TO_BORDER:

float borderColor[] = { 1.0f, 1.0f, 0.0f, 1.0f };
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);  // we want to repeat the awesomeface pattern so we kept it at GL_REPEAT
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, borderColor);
glDrawElements(GL_TRIANGLES,6,GL_UNSIGNED_INT,0);

效果:

我们可以看到,超出部分都用黄色代替了。

GL_CLAMP_TO_EDGE

glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); // we want to repeat the awesomeface pattern so we kept it at GL_REPEAT
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);

GL_MIRRORED_REPEAT:

        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S,GL_MIRRORED_REPEAT);    // we want to repeat the awesomeface pattern so we kept it at GL_REPEATglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T,GL_MIRRORED_REPEAT);

效果:

GL_REPEAT:

        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S,GL_REPEAT); // we want to repeat the awesomeface pattern so we kept it at GL_REPEATglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T,GL_REPEAT);

所有代码:

#ifndef BKQOPENGLW_H
#define BKQOPENGLW_H#include <QOpenGLWidget>
#include <QOpenGLFunctions_3_3_Core>
#include <QOpenGLShaderProgram>
#include <QOpenGLTexture>
class BKQOpenglW : public QOpenGLWidget, QOpenGLFunctions_3_3_Core
{Q_OBJECT
public:enum Shape{None,Rect,circle,Triangle};explicit BKQOpenglW(QWidget *parent = nullptr);~BKQOpenglW();void drawShapes(Shape shape);void setWireFrame(bool b);
protected:virtual void initializeGL();virtual void resizeGL(int w, int h);virtual void paintGL();signals:public slots:private:
unsigned int VBO, VAO,EBO;
Shape m_Shape;
QOpenGLShaderProgram shaderProgram;
unsigned int texture;
QOpenGLTexture *pTexture;
QOpenGLTexture *pTexture2;
};#endif // BKQOPENGLW_H

对应cpp:

#include "bkqopenglw.h"
#include<iostream>
#include <QDebug>#define STB_IMAGE_IMPLEMENTATION
#include "stb_image.h"float vertices[] = {// positions          // colors           // texture coords0.8f,  0.8f, 0.0f,   1.0f, 0.0f, 0.0f,   2.0f, 2.0f, // top right0.8f, -0.8f, 0.0f,   0.0f, 1.0f, 0.0f,   2.0f, 0.0f, // bottom right-0.8f, -0.8f, 0.0f,   0.0f, 0.0f, 1.0f,   0.0f, 0.0f, // bottom left-0.8f,  0.8f, 0.0f,   1.0f, 1.0f, 0.0f,   0.0f, 2.0f  // top left};unsigned int indices[] = {  // note that we start from 0!0, 1, 3,  // first Triangle1, 2, 3   // second Triangle
};BKQOpenglW::BKQOpenglW(QWidget *parent) : QOpenGLWidget(parent)
{}BKQOpenglW::~BKQOpenglW()
{makeCurrent();glDeleteVertexArrays(1,&VAO);glDeleteBuffers(1,&VBO);doneCurrent();
}void BKQOpenglW::drawShapes(BKQOpenglW::Shape shape)
{m_Shape = shape;update();
}void BKQOpenglW::setWireFrame(bool b)
{makeCurrent();if(b){glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);}else {glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);}update();doneCurrent();
}void BKQOpenglW::initializeGL()
{initializeOpenGLFunctions();//    shaderProgram.addShaderFromSourceCode(QOpenGLShader::Vertex,vertexShaderSource);//    shaderProgram.addShaderFromSourceCode(QOpenGLShader::Fragment,fragmentShaderSource);shaderProgram.addShaderFromSourceFile(QOpenGLShader::Vertex,":/shader/shader.vs");shaderProgram.addShaderFromSourceFile(QOpenGLShader::Fragment,":/shader/shader.fs");shaderProgram.link();glGenVertexArrays(1, &VAO);glGenBuffers(1, &VBO);// bind the Vertex Array Object first, then bind and set vertex buffer(s), and then configure vertex attributes(s).glBindVertexArray(VAO);glBindBuffer(GL_ARRAY_BUFFER, VBO);glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);//绑定eboglBindBuffer(GL_ELEMENT_ARRAY_BUFFER,EBO);glBufferData(GL_ELEMENT_ARRAY_BUFFER,sizeof(indices),indices,GL_STATIC_DRAW);glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(float), nullptr);glEnableVertexAttribArray(0);glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void*)(3 * sizeof(float)));glEnableVertexAttribArray(1);// texture coord attributeglVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void*)(6 * sizeof(float)));glEnableVertexAttribArray(2);//绑定纹理glEnable(GL_BLEND);glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);pTexture = new QOpenGLTexture(QImage(":/images/images/brickwall.jpg").mirrored());pTexture2 = new QOpenGLTexture(QImage(":/images/images/awesomeface.png").mirrored());shaderProgram.bind();shaderProgram.setUniformValue("texture1",0);shaderProgram.setUniformValue("texture2",1);// note that this is allowed, the call to glVertexAttribPointer registered VBO as the vertex attribute's bound vertex buffer object so afterwards we can safely unbindglBindBuffer(GL_ARRAY_BUFFER, 0);// You can unbind the VAO afterwards so other VAO calls won't accidentally modify this VAO, but this rarely happens. Modifying other// VAOs requires a call to glBindVertexArray anyways so we generally don't unbind VAOs (nor VBOs) when it's not directly necessary.glBindVertexArray(0);}void BKQOpenglW::resizeGL(int w, int h)
{glViewport(0,0,w,h);
}void BKQOpenglW::paintGL()
{glClearColor(0.2f, 0.3f, 0.3f, 1.0f);glClear(GL_COLOR_BUFFER_BIT);float borderColor[] = { 1.0f, 1.0f, 0.0f, 1.0f };shaderProgram.bind();glBindVertexArray(VAO);switch (m_Shape) {case Triangle:glDrawArrays(GL_TRIANGLES,0,3);break;case Rect:pTexture->bind(0);pTexture2->bind(1);//默认为GL_REPEAT 重复 GL_MIRRORED_REPEAT镜像  GL_CLAMP_TO_EDGE 边缘拉伸 GL_CLAMP_TO_BORDER 超出部分使用用户定义glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S,GL_REPEAT);  // we want to repeat the awesomeface pattern so we kept it at GL_REPEATglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T,GL_REPEAT);
//        glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, borderColor);glDrawElements(GL_TRIANGLES,6,GL_UNSIGNED_INT,0);break;default:break;}}

纹理过滤(Texture Filtering)

GL_NEAREST(Nearest Neighbor Filtering, 邻近过滤) 是一种OpenGL默认的纹理过滤方式。 当设置为 GL_NEAREST 的时候, OpenGL选择最接近纹理坐标中心点的那个像素。 下图你
会看到四个像素, 加号代表纹理坐标。 左上角的纹理像素是距离纹理坐标最近的那个, 这样它就会选择这个作为采样颜色:

GL_LINEAR((Bi)linear Filtering, 线性过滤) 它会从纹理坐标的临近纹理像素进行计算, 返
回一个多个纹理像素的近似值。 一个纹理像素距离纹理坐标越近, 那么这个纹理像素对最终
的采样颜色的影响越大。 下面你会看到临近像素返回的混合颜色:

基本区别:

使用方式:

glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);

最后的话:

每天写代码时间不多,上班时间还是比较长,写博客不易,喜欢的朋友,可以关注偶。

QT中学习Opengl---(纹理环绕方式与过滤)相关推荐

  1. 在Qt中使用OpenGL(四)

    前言 在Qt中使用OpenGL(一) 在Qt中使用OpenGL(二) 在Qt中使用OpenGL(三) 在之前的文章中,我们通过一个最简单的例子完成了在Qt中使用OpenGL绘图的全过程,然后又使用了纹 ...

  2. Qt中的OpenGL

    Qt还是本人可移植GUI程序开发的首选,不过Qt开发普通的应用程序是行,但是据说效率太低,以至于像某些人说的那种刷新看得到一条条横线?这点我比较纳闷,就我使用的感觉,虽然Qt不以效率著称,但是事实上有 ...

  3. QT中使用OpenGL绘制图形

    Qt Creator中的3D绘图及动画教程(参照NeHe) 刚刚学习了Qt Creator,发现Qt提供了QtOpenGL模块,对OpenGL做了不错的封装,这使得我们可以很轻松地在Qt程序中使用Op ...

  4. Qt中使用OpenGL进行绘图

    Qt Creator中的3D绘图及动画教程(参照NeHe) 刚刚学习了Qt Creator,发现Qt提供了QtOpenGL模块,对OpenGL做了不错的封装,这使得我们可以很轻松地在Qt程序中使用Op ...

  5. 在Qt中使用OpenGL(三)

    前言 在Qt中使用OpenGL(一) 在Qt中使用OpenGL(二) 在之前的文章中,我们首先了解了在Qt中使用OpenGL的全流程,然后我们使用了一个最简单的例子将这个流程给过了一遍. 那么,在本篇 ...

  6. qt 中 使用 opengl 上下文 (context) 相关的注意事项

    qt 中 使用 opengl 相关的注意事项 本人移植了一个glut到qt的项目,前期没有注意相关的上下文的使用,导致相关的显示混乱. 解决方案 makeCurrent();在每一个类函数中加上这一句 ...

  7. 在Qt中使用OpenGL(二)

    前言 在Qt中使用OpenGL(一) 在上一篇文章中,我们结合了一个实际的例子了解了在Qt中使用OpenGL的全部过程.但是肯定对于初次接触的人来说哪怕知道了整个过程,依旧是两眼一抹黑的搞不懂到底要怎 ...

  8. word默认文字环绕方式是什么_在Word 2010文档中设置图片文字环绕方式

    默认情况下,插入到Word 2010文档中的图片作为字符插入到Word 2010文档中,其位置随着其他字符的改变而改变,用户不能自由移动图片.而通过为图片设置文字环绕方式,则可以自由移动图片的位置,操 ...

  9. 在 Lazarus 中学习 OpenGL

    在 Lazarus 中学习 OpenGL 教学网站 https://learnopengl-cn.github.io/ API 查询 https://docs.gl/ 创建窗口 Lazarus 可以在 ...

最新文章

  1. 解决“错误 D8016 “/ZI”和“/Gy-”命令行选项不兼容 ”问题
  2. Java 8 - 收集器Collectors_分组groupingBy
  3. Java中将CST格式的时间字符串进行格式化
  4. 微信小程序学习笔记(五)
  5. 山海伏妖录java_山海伏妖录攻略大全 剧情结局加点妖兽大全
  6. css 列表相关的属性 列表前的小点点 0302
  7. VB6中给数组赋值的限制
  8. 自动驾驶“老司机”拼车技,MIT的这个比赛已经飙到了时速123公里
  9. 支持python的云虚拟主机_云虚拟主机运行python(能运行python的主机)
  10. i++和++i哪个效率高
  11. 引入的噪声程度:曝光时间,模拟增益,数字增益的不同
  12. 一篇就明白什么是H3C?
  13. 你知道吗?计算机界也有诺贝尔奖!
  14. Android studio设计app登录界面
  15. 第十六届全国大学智能车竞赛华东赛区成绩汇总
  16. 【洛谷】P1008 [NOIP1998 普及组] 三连击
  17. idea导入子工程module
  18. “泰迪杯”挑战赛 -利用非侵入式负荷检测进行高效率数据挖掘(完整数学模型)
  19. 如何进阶Java之道?首先得知道层层递进的四种软件架构
  20. GitBook建立本地Book及导入别人Book

热门文章

  1. python帮助和文档、希腊字母对照表
  2. Android Camera提升帧率的方法
  3. column命令对齐文件内容
  4. Bootstrap(前端开发框架一)
  5. simulink中比scope模块还好用的平替出图工具?
  6. Manjaro 安装 ibus-rime 输入法
  7. 跨域请求的三种解决方案
  8. “中国农技推广信息服务平台”能否满足大众农业技术需求?
  9. 阿里巴巴canal学习笔记
  10. [转] 一级建造师一次通过四科之点滴心得体会