Skip to content

Files

Latest commit

author
fangshufeng
May 23, 2019
31984bc · May 23, 2019

History

History
159 lines (83 loc) · 7.11 KB

03.Texture.md

File metadata and controls

159 lines (83 loc) · 7.11 KB

纹理

先自行阅读:

  1. 着色器
  2. 纹理

获取当前工程的路径

由于后面会用到本地的一些资源,要获取路径,这里通过Cmake的环境变量来获取,我们需要修改CMakeLists.txt文件使用configure_file,修改如下图

image

root_directory.h.in文件内容如下

const char * logl_root = "${CMAKE_SOURCE_DIR}/Glitter/";

cmake执行以后CMAKE_SOURCE_DIR这个就会被替换,然后会生成在目录~/Desktop/thirdPart/LearnOpenGL/Build/Glitter/configuration就会生成root_directory.h文件

const char * logl_root = "~/Desktop/thirdPart/LearnOpenGL/Glitter/";

关于对象的抽象和封装是一个程序与的必备技能,这里不做任何赘述了

上面2篇文章已经完整讲述了纹理这个东西了,这里将通俗的理解下讲的内容:

一、对于纹理这个东西我们不要狭隘的理解为一张图片,应该理解为记录着数据的一个载体,它可以是颜色值,还有后面会讲到的深度值等等;

对于这个的理解可以类似的计算机汇编代码,它可以是指令,也可以是数据,完全取决于你如何理解

二、纹理的坐标系是[0,1],(0,0)是纹理的左下角,(1,1)是纹理的右上角

既然纹理是以坐标来布局的范围在[0,0]~[1,1]之间的话那么就有以下2个问题

  1. 纹理坐标不在[0,0]~[1,1]范围如何处理;
  2. 纹理的分辨率小于场景如何处理;

2.1 纹理坐标不在[0,0]~[1,1]范围如何处理?

写个demo测试一下,为了便于演示把图片换成texture_wrapping.png

修改顶点数据为

float vertices[] = {
   // positions          // colors           // texture coords
   0.5f,  0.5f, 0.0f,   1.0f, 0.0f, 0.0f,   2.0f, 2.0f, // top right
   0.5f, -0.5f, 0.0f,   0.0f, 1.0f, 0.0f,   2.0f, 0.0f, // bottom right
   -0.5f, -0.5f, 0.0f,   0.0f, 0.0f, 1.0f,   0.0f, 0.0f, // bottom left
   -0.5f,  0.5f, 0.0f,   1.0f, 1.0f, 0.0f,   0.0f, 2.0f  // top left
};

2.1.1 GL_REPEAT:对纹理的默认行为。重复纹理图像。

 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);    // set texture wrapping to GL_REPEAT (default wrapping method)
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
    

image

2.1.2 GL_MIRRORED_REPEAT:镜像重复

image

2.1.3 GL_CLAMP_TO_EDGE :纹理坐标会被约束在0到1之间,超出的部分会重复纹理坐标的边缘,产生一种边缘被拉伸的效果。

image

2.1.14 GL_CLAMP_TO_EDGE :超出的坐标为用户指定的边缘颜色。

 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);    // set texture wrapping to GL_REPEAT (default wrapping method)
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
    
    float borderColor[] = { 1.0f, 1.0f, 0.0f, 1.0f };
    glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, borderColor);

image

读者可以试试修改顶点数据让这个图片位于中间

2.2 纹理的分辨率小于场景如何处理?

想象一个场景,当你的纹理图片很小,但是你需要粘贴的物体很大时,那么你的图片势必要被拉伸,就像下面这个样子

是不是感觉到很明显的颗粒感?

纹理过滤就是来告诉OpenGL如何来处理的,它提供了GL_NEARESTGL_LINEAR2种处理方式,纹理文章中已经详细讲了,上面那张就是GL_NEAREST

glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);

告诉放大的时候取中心点最靠近坐标点的像素颜色,把它改成GL_LINEAR会是下面这个样子

上面说的是放大的时候的处理,缩小也是和放大一样有2中模式,不做演示了,对于缩小OpenGL还有个优化的地方,叫做多级渐远纹理(Mipmap)

想象一下,假设我们有一个包含着上千物体的大房间,每个物体上都有纹理。有些物体会很远,但其纹理会拥> 有与近处物体同样高的分辨率。由于远处的物体可能只产生很少的片段,OpenGL从高分辨率纹理中为这些片> 段获取正确的颜色值就很困难,因为它需r要对一个跨过纹理很大部分的片段只拾取一个纹理颜色。在小物体上> 这会产生不真实的感觉,更不用说对它们使用高分辨率纹理浪费内存的问题了。

要注意的是这个多级渐远纹理是针对缩小的场景的,对于放大是无效的,不要用错了,一般常规用法是如下

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