【OpenGL纹理】纹理贴图基础知识(01/4)

文章目录

  • 一、说明
  • 二、贴图的初始化处理
    • 2.1 贴图中的几种纹理
    • 2.2 原始数据处理 - 贴图的规格化
  • 三、纹理对象生成和绑定(选中)
    • 3.1 生成纹理矩阵
    • 3.2 glGenTextures 函数明细
    • 3.2 glBindTexture函数明细
  • 四、glTexParameteri函数
    • 4.1 贴放放法参数确定
    • 4.2 放大缩小插值方法参数确定
  • 五、一段参考代码
    • 5.1 顶点着色器
    • 5.2 片段着色器
    • 5.3 OpenGL代码
  • 六、glTexImage2D函数
    • 6.1 函数描述
    • 6.2 参数解释
    • 6.3 其它限制
    • 6.4 补充描述
  • 七、纹理对象调用过程总结
    • 7.1 顶点着色器作用
    • 7.2 片元着色器作用
    • 7.3 OpenGL的作用
  • 八、后记

一、说明

关于贴图问题,是OpenGL最复杂的系统了,本系列文挡将在整个流程上叙述纹理贴图的过程。在本文中,将涉及最一般朴素的若干操作,基本覆盖从读入图片,到生成纹理图像的过程。在整个过程的若干操作函数都给出一般常识性解释。

常见函数:
glActiveTexture,
glCopyTexImage1D,
glCopyTexImage2D,
glCopyTexSubImage1D,
glCopyTexSubImage2D,
glCopyTexSubImage3D,
glPixelStore,
glTexImage1D,
glTexImage3D,
glTexSubImage1D,
glTexSubImage2D,
glTexSubImage3D,
glTexParameter

二、贴图的初始化处理

2.1 贴图中的几种纹理

纹理有两种:

  • GL_TEXTURE_1D_ARRAY 表明是一维纹理
  • GL_TEXTURE_2D_ARRAY 表明是二维纹理

2.2 原始数据处理 - 贴图的规格化

1)将三通道图像转化成4通道图像

  • 读入Image图像,此为RGB格式的数据结构,要追加 α \alpha α通道形成四通道图像:
from PIL import Image
image = Image.open("textures/cat.png")
image = image.transpose(Image.FLIP_TOP_BOTTOM)
img_data = image.convert("RGBA").tobytes()

2)PIL.image.convert有九种不同模式:

convert参数意义
1:1位像素,黑白,每字节一个像素存储
L:8位像素,黑白
P:8位像素,使用调色板映射到任何其他模式
RGB:3x8位像素,真彩色
RGBA:4x8位像素,带透明度掩模的真彩色
CMYK:4x8位像素,分色
YCbCr:3x8位像素,彩色视频格式
I:32位有符号整数像素
F:32位浮点像素

示例:将彩色转成黑白:

image_1 = image.convert('1')
image_1.show()

三、纹理对象生成和绑定(选中)

3.1 生成纹理矩阵

通过纹理数组,可以将几个2D图像加载到一个单独的纹理对象中,然后在着色器中对它们进行检索,这样就大大增加了着色器可用的纹理数据数量;
对于2D纹理数组来说,和其正常创建和绑定纹理相似只是改变了target参数;

GLuint Texture;
glGenTextures(1,&Texture);
glBindTexture(GL_TEXTURE_2D_ARRAY,Texture);

3.2 glGenTextures 函数明细

glGenTextures 返回纹理中的 n 个纹理名称。不能保证名称形成一组连续的整数;但是,可以保证在调用 glGenTextures 之前没有立即使用返回的名称。

  • 生成的纹理没有维度;它们假定它们首先绑定到的纹理目标的维度(参见 glBindTexture)。
  • 后续调用不会返回调用 glGenTextures 返回的纹理名称,除非首先使用 glDeleteTextures 删除它们。
GLuint Texture;
glGenTextures(10,&Texture);

Signature

  • c++ 程序:void glGenTextures( GLsizei ( n ) , GLuint * ( textures ) )
  • python程序:textures=glGenTextures( n )

参数描述
n : 要生成纹理对象的个数.
textures : 生成的纹理句柄

3.2 glBindTexture函数明细

  • 该函数选中纹理之一,作为当前使用纹理
    glBindTexture 允许您创建或使用命名纹理。调用 glBindTexture 并将目标设置为 GL_TEXTURE_1D 、 GL_TEXTURE_2D 、 GL_TEXTURE_3D 、 GL_TEXTURE_1D_ARRAY 、 GL_TEXTURE_2D_ARRAY 、 GL_TEXTURE_RECTANGLE 、 GL_TEXTURE_CUBE_MAP 、 GL_TEXTURE_CUBE_MAP_ARRAY 、 GL_TEXTURE_BUFFER 、 TEXTURE_2D_MULTISAMPLE 或 GL_TEXTURE_2D_MULTISAMPLE_ARRAY 和设置为新纹理名称的纹理会将纹理名称绑定到目标。当纹理绑定到目标时,该目标的先前绑定将自动中断。
    纹理名称是无符号整数。保留值零来表示每个纹理目标的默认纹理。纹理名称和对应的纹理内容是当前GL渲染上下文的共享对象空间本地的;仅当两个渲染上下文通过适当的 GL windows 接口函数显式启用上下文之间的共享时,它们才共享纹理名称。
  • 您必须使用 glGenTextures 生成一组新的纹理名称。
    当纹理第一次绑定时,它假定指定的目标:首先绑定到 GL_TEXTURE_1D 的纹理成为一维纹理,首先绑定到 GL_TEXTURE_2D 的纹理成为二维纹理,首先绑定到 GL_TEXTURE_3D 的纹理成为三维纹理,首先绑定到 GL_TEXTURE_1D_ARRAY 的纹理成为一维数组纹理,首先绑定到 GL_TEXTURE_2D_ARRAY 的纹理成为二维数组纹理,首先绑定到 GL_TEXTURE_RECTANGLE 的纹理成为矩形纹理,首先绑定到 GL_TEXTURE_CUBE_MAP 的纹理成为立方体映射纹理,首先绑定到 GL_TEXTURE_CUBE_MAP_ARRAY 的纹理将成为立方体映射数组纹理,首先绑定到GL_TEXTURE_BUFFER 的纹理将成为缓冲区纹理,首先绑定到 GL_TEXTURE_2D_MULTISAMPLE 的纹理将成为二维多重采样纹理,并且首先绑定到 GL_TEXTURE_2D_MULTISAMPLE_ARRAY 的纹理将成为二维多重采样纹理数组纹理。一维纹理在第一次绑定后的状态相当于 GL 初始化时默认 GL_TEXTURE_1D 的状态,对于其他纹理类型也是如此。
    函数规格:
    C++函数格式:
  • glBindTexture( GLenum ( target ) , GLuint ( texture ) )-> void
    python函数格式:
  • glBindTexture( target , texture )
  • glBindTextures( first , count , textures )

当纹理被绑定时,对其绑定的目标的 GL 操作会影响绑定的纹理,并且对其绑定的目标的查询会从绑定的纹理返回状态。实际上,纹理目标成为当前绑定到它们的纹理的别名,纹理名称零指的是在初始化时绑定到它们的默认纹理。
使用 glBindTexture 创建的纹理绑定保持活动状态,直到将不同的纹理绑定到同一目标,或者直到使用 glDeleteTextures 删除绑定的纹理。
创建后,命名纹理可以根据需要经常重新绑定到其相同的原始目标。使用 glBindTexture 将现有命名纹理绑定到纹理目标之一通常比使用 glTexImage1D 、 glTexImage2D 、 glTexImage3D 或其他类似函数重新加载纹理图像要快得多。

四、glTexParameteri函数

设置纹理包裹参数,什么意思?
部分参数功能说明如下:

4.1 贴放放法参数确定

glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
GL_TEXTURE_2D: 操作2D纹理.
GL_TEXTURE_WRAP_S: S方向上的贴图模式.
GL_CLAMP: 将纹理坐标限制在0.0,1.0的范围之内.如果超出了会如何呢.不会错误,只是会边缘拉伸填充.
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
这里同上,只是它是T方向

4.2 放大缩小插值方法参数确定

glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); 这是纹理过滤
GL_TEXTURE_MAG_FILTER: 放大过滤
GL_LINEAR: 线性过滤, 使用距离当前渲染像素中心最近的4个纹素加权平均值.

glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST);
GL_TEXTURE_MIN_FILTER: 缩小过滤
GL_LINEAR_MIPMAP_NEAREST: 使用GL_NEAREST对最接近当前多边形的解析度的两个层级贴图进行采样,然后用这两个值进行线性插值.

void glTexParameterfv(GLenum target​, GLenum pname​, const GLfloat * params​);
void glTexParameteriv(GLenum target​, GLenum pname​, const GLint * params​);
void glTexParameterIiv(GLenum target​, GLenum pname​, const GLint * params​);
void glTexParameterIuiv(GLenum target​, GLenum pname​, const GLuint * params​);

  • target
  • 规定纹理格式,必须是下列之一:
    GL_TEXTURE_1D,
    GL_TEXTURE_2D,
    GL_TEXTURE_3D,
    GL_TEXTURE_1D_ARRAY,
    GL_TEXTURE_2D_ARRAY,
    GL_TEXTURE_RECTANGLE,
    GL_TEXTURE_CUBE_MAP.
  • pname
  • 指定纹理参数的符号名称。 pname​可以是以下之一。
    GL_DEPTH_STENCIL_TEXTURE_MODE,
    GL_TEXTURE_BASE_LEVEL,
    GL_TEXTURE_BORDER_COLOR,
    GL_TEXTURE_COMPARE_FUNC,
    GL_TEXTURE_COMPARE_MODE,
    GL_TEXTURE_LOD_BIAS,
    GL_TEXTURE_MIN_FILTER,
    GL_TEXTURE_MAG_FILTER,
    GL_TEXTURE_MIN_LOD,
    GL_TEXTURE_MAX_LOD,
    GL_TEXTURE_MAX_LEVEL,
    GL_TEXTURE_SWIZZLE_R,
    GL_TEXTURE_SWIZZLE_G,
    GL_TEXTURE_SWIZZLE_B,
    GL_TEXTURE_SWIZZLE_A,
    GL_TEXTURE_SWIZZLE_RGBA,
    GL_TEXTURE_WRAP_S,
    GL_TEXTURE_WRAP_T,
    GL_TEXTURE_WRAP_R.
    params
    Specifies a pointer to an array where the value or values of pname​ are stored.

params​ 提供了一个用于缩小纹理的函数,如下所示:

参数意义
GL_NEAREST返回最接近(以曼哈顿距离)正在纹理化的像素中心的纹理元素的值。
GL_LINEAR返回最接近纹理像素中心的四个纹理元素的加权平均值。这些可以包括边框纹理元素,具体取决于 GL_TEXTURE_WRAP_S 和 GL_TEXTURE_WRAP_T 的值以及确切的映射。
GL_NEAREST_MIPMAP_NEAREST选择与纹理像素大小最匹配的 mipmap,并使用 GL_NEAREST 标准(最接近像素中心的纹理元素)来生成纹理值。
GL_LINEAR_MIPMAP_NEAREST选择与纹理像素大小最匹配的 mipmap,并使用 GL_LINEAR 标准(最接近像素中心的四个纹理元素的加权平均值)来生成纹理值。
GL_NEAREST_MIPMAP_LINEAR选择与纹理像素大小最匹配的两个 mipmap,并使用 GL_NEAREST 标准(最接近像素中心的纹理元素)从每个 mipmap 生成纹理值。最终纹理值是这两个值的加权平均值。
GL_LINEAR_MIPMAP_LINEAR选择与纹理像素大小最匹配的两个 mipmap,并使用 GL_LINEAR 标准(最接近像素中心的四个纹理元素的加权平均值)从每个 mipmap 生成纹理值。最终纹理值是这两个值的加权平均值。

五、一段参考代码

下面代码演示生成一个2d纹理贴图的过程:

5.1 顶点着色器

#version 330 core

layout (location=0) in vec3 vertexPos;
layout (location=1) in vec3 vertexColor;
layout (location=2) in vec2 vertexTexCoord;

out vec3 fragmentColor;
out vec2 fragmentTexCoord;

void main()
{
    gl_Position = vec4(vertexPos, 1.0);
    fragmentColor = vertexColor;
    fragmentTexCoord = vertexTexCoord;
}

5.2 片段着色器

#version 330 core

in vec3 fragmentColor;
in vec2 fragmentTexCoord;

out vec4 color;

uniform sampler2D imageTexture;

void main()
{
    color = 0.4*vec4(fragmentColor, 1.0) + 0.6*texture(imageTexture, fragmentTexCoord);
}

5.3 OpenGL代码

GLuint Texture;
texture = glGenTextures(1)
glBindTexture(GL_TEXTURE_2D, texture)

# Set the texture wrapping parameters
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT)
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT)
# Set texture filtering parameters
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR)
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR)

# load image
image = Image.open("textures/cat.png")
image = image.transpose(Image.FLIP_TOP_BOTTOM)
img_data = image.convert("RGBA").tobytes()
# img_data = np.array(image.getdata(), np.uint8) # second way of getting the raw image data
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, image.width, image.height, 0, GL_RGBA, GL_UNSIGNED_BYTE, img_data)

glUseProgram(shader)
glClearColor(0, 0.1, 0.1, 1)
glEnable(GL_DEPTH_TEST)
glEnable(GL_BLEND)
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)

六、glTexImage2D函数

void glTexImage2D( GLenum target,
GLint level,
GLint internalformat,
GLsizei width,
GLsizei height,
GLint border,
GLenum format,
GLenum type,
const void * data);
此函数按照图像格式,以及给出的种种条件,生成纹理图像。此纹理允许着色器读取图像数组的元素。

要定义纹理图像,请调用 glTexImage2D。这些参数描述了纹理图像的参数,例如高度、宽度、边框宽度、细节级别编号(请参阅 glTexParameter)以及提供的颜色分量的数量。最后三个参数描述了图像在内存中的表示方式。
纹理允许着色器读取图像数组的元素。也就是片段着色器的像素坐标与图片的重叠部分。

6.1 函数描述

要定义纹理图像,请调用 glTexImage2D。这些参数描述了纹理图像的参数,例如高度、宽度、边框宽度、细节级别编号(请参阅 glTexParameter)以及提供的颜色分量的数量。最后三个参数描述了图像在内存中的表示方式。

void glTexImage2D( GLenum target,
GLint level,
GLint internalformat,
GLsizei width,
GLsizei height,
GLint border,
GLenum format,
GLenum type,
const void * data);

6.2 参数解释

参数描述

  • target
    指定目标纹理。必须是: GL_TEXTURE_2D, GL_PROXY_TEXTURE_2D, GL_TEXTURE_1D_ARRAY, GL_PROXY_TEXTURE_1D_ARRAY, GL_TEXTURE_RECTANGLE, GL_PROXY_TEXTURE_RECTANGLE, GL_TEXTURE_CUBE_MAP_POSITIVE_X, GL_TEXTURE_CUBE_MAP_NEGATIVE_X, GL_TEXTURE_CUBE_MAP_POSITIVE_Y, GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, GL_TEXTURE_CUBE_MAP_POSITIVE_Z, GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, or GL_PROXY_TEXTURE_CUBE_MAP.

  • level
    指定详细级别编号。级别 0 是基础图像级别。 n 级是第 n 个 mipmap 缩小图像。如果目标纹理是 GL_TEXTURE_RECTANGLE
    GL_PROXY_TEXTURE_RECTANGLE,

level 必须是 0.

  • internalformat
    指定纹理中颜色分量的数量。必须是表 1 中给出的基本内部格式之一、表 2 中给出的大小内部格式之一或下表 3 中给出的压缩内部格式之一。
internalformat参数意义
GL_RED每个元素都是一个红色组件。 GL 将其转换为浮点,并通过为绿色和蓝色附加 0、为 Alpha 附加 1 将其组装成 RGBA 元素。每个分量都被限制在 [0,1] 范围内。
GL_RG每个元素都是红/绿双色。 GL 将其转换为浮点型,并通过附加 0(表示蓝色)和 1(表示 alpha)将其组装成 RGBA 元素。每个分量都被限制在 [0,1] 范围内。
GL_RGB, GL_BGR每个元素都是一个 RGB 三元组。 GL 将其转换为浮点,并通过为 alpha 附加 1 将其组装成 RGBA 元素。每个分量都被限制在 [0,1] 范围内。
GL_RGBA, GL_BGRA每个元素包含所有四个组件。每个分量都被限制在 [0,1] 范围内。
GL_DEPTH_COMPONENT每个元素都是一个深度值。 GL 将其转换为浮点数并限制在 [0,1] 范围内。
GL_DEPTH_STENCIL每个元素都是一对深度和模板值。该对的深度分量被解释为 GL_DEPTH_COMPONENT。模板组件根据指定的深度+模板内部格式进行解释。
  • width
    指定纹理图像的宽度。所有实现都支持至少 1024 纹理像素宽的纹理图像。

  • height
    在 GL_TEXTURE_1D_ARRAY 和 GL_PROXY_TEXTURE_1D_ARRAY 目标的情况下,指定纹理图像的高度或纹理数组中的层数。所有实现都支持至少 1024 纹理像素高的 2D 纹理图像以及至少 256 层深的纹理数组。

  • border
    必须是 0.

  • format
    指定像素数据的格式。接受以下符号值: GL_RED, GL_RG, GL_RGB, GL_BGR, GL_RGBA, GL_BGRA, GL_RED_INTEGER, GL_RG_INTEGER, GL_RGB_INTEGER, GL_BGR_INTEGER, GL_RGBA_INTEGER, GL_BGRA_INTEGER, GL_STENCIL_INDEX, GL_DEPTH_COMPONENT, GL_DEPTH_STENCIL.

  • type
    指定像素数据的数据类型。接受以下符号值:GL_UNSIGNED_BYTE, GL_BYTE, GL_UNSIGNED_SHORT, GL_SHORT, GL_UNSIGNED_INT, GL_INT, GL_HALF_FLOAT, GL_FLOAT, GL_UNSIGNED_BYTE_3_3_2, GL_UNSIGNED_BYTE_2_3_3_REV, GL_UNSIGNED_SHORT_5_6_5, GL_UNSIGNED_SHORT_5_6_5_REV, GL_UNSIGNED_SHORT_4_4_4_4, GL_UNSIGNED_SHORT_4_4_4_4_REV, GL_UNSIGNED_SHORT_5_5_5_1, GL_UNSIGNED_SHORT_1_5_5_5_REV, GL_UNSIGNED_INT_8_8_8_8, GL_UNSIGNED_INT_8_8_8_8_REV, GL_UNSIGNED_INT_10_10_10_2, and GL_UNSIGNED_INT_2_10_10_10_REV.

  • data
    内存中图像的指针.

6.3 其它限制

  • 如果目标是 GL_PROXY_TEXTURE_2D、GL_PROXY_TEXTURE_1D_ARRAY、GL_PROXY_TEXTURE_CUBE_MAP 或 GL_PROXY_TEXTURE_RECTANGLE,则不会从数据中读取任何数据,但会重新计算所有纹理图像状态,检查一致性,并根据实现的功能进行检查。如果实现无法处理所请求纹理大小的纹理,则会将所有图像状态设置为 0,但不会生成错误(请参阅 glGetError)。要查询整个 mipmap 数组,请使用大于或等于 1 的图像数组级别。

  • 如果目标是 GL_TEXTURE_2D、GL_TEXTURE_RECTANGLE 或 GL_TEXTURE_CUBE_MAP 目标之一,则从 data 中读取数据作为有符号或无符号字节、短整型或长整型或单精度浮点值的序列,具体取决于类型。根据格式,这些值被分组为一个、两个、三个或四个值的集合,以形成元素。每个数据字节被视为八个 1 位元素,位顺序由 GL_UNPACK_LSB_FIRST 确定(请参阅 glPixelStore)。

  • 如果目标是GL_TEXTURE_1D_ARRAY,则数据被解释为一维图像的数组。

  • 如果在指定纹理图像时将非零命名缓冲区对象绑定到 GL_PIXEL_UNPACK_BUFFER 目标(请参阅 glBindBuffer),则数据将被视为缓冲区对象数据存储中的字节偏移量。

  • 第一个元素对应于纹理图像的左下角。后续元素从左到右穿过纹理图像最低行中的剩余纹理像素,然后依次进入纹理图像的较高行中。最后一个元素对应于纹理图像的右上角。

6.4 补充描述

  • 1 如果目标是 GL_PROXY_TEXTURE_2D、GL_PROXY_TEXTURE_1D_ARRAY、GL_PROXY_TEXTURE_CUBE_MAP 或 GL_PROXY_TEXTURE_RECTANGLE,则不会从数据中读取任何数据,但会重新计算所有纹理图像状态,检查一致性,并根据实现的功能进行检查。如果实现无法处理所请求纹理大小的纹理,则会将所有图像状态设置为 0,但不会生成错误(请参阅 glGetError)。要查询整个 mipmap 数组,请使用大于或等于 1 的图像数组级别。

  • 2 如果目标是 GL_TEXTURE_2D、GL_TEXTURE_RECTANGLE 或 GL_TEXTURE_CUBE_MAP 目标之一,则从 data 中读取数据作为有符号或无符号字节、短整型或长整型或单精度浮点值的序列,具体取决于类型。根据格式,这些值被分组为一个、两个、三个或四个值的集合,以形成元素。每个数据字节被视为八个 1 位元素,位顺序由 GL_UNPACK_LSB_FIRST 确定(请参阅 glPixelStore)。

  • 3 如果目标是GL_TEXTURE_1D_ARRAY,则数据被解释为一维图像的数组。

  • 4 如果在指定纹理图像时将非零命名缓冲区对象绑定到 GL_PIXEL_UNPACK_BUFFER 目标(请参阅 glBindBuffer),则数据将被视为缓冲区对象数据存储中的字节偏移量。

  • 5 纹理图像的第一个元素,对应于纹理图像的左下角。后续元素从左到右穿过纹理图像最低行中的剩余纹理像素,然后依次进入纹理图像的较高行中。最后一个元素对应于纹理图像的右上角。

format:格式决定了数据中每个元素的组成。它可以采用以下符号值之一:
GL_RED
Each element is a single red component. The GL converts it to floating point and assembles it into an RGBA element by attaching 0 for green and blue, and 1 for alpha. Each component is clamped to the range [0,1].

GL_RG
Each element is a red/green double. The GL converts it to floating point and assembles it into an RGBA element by attaching 0 for blue, and 1 for alpha. Each component is clamped to the range [0,1].

GL_RGB, GL_BGR
Each element is an RGB triple. The GL converts it to floating point and assembles it into an RGBA element by attaching 1 for alpha. Each component is clamped to the range [0,1].

GL_RGBA, GL_BGRA
Each element contains all four components. Each component is clamped to the range [0,1].

GL_DEPTH_COMPONENT
Each element is a single depth value. The GL converts it to floating point and clamps to the range [0,1].

GL_DEPTH_STENCIL
Each element is a pair of depth and stencil values. The depth component of the pair is interpreted as in GL_DEPTH_COMPONENT. The stencil component is interpreted based on specified the depth + stencil internal format.

internalformat:

Base Internal FormatRGBA, Depth and Stencil ValuesInternal Components
GL_DEPTH_COMPONENTDepthD
GL_DEPTH_STENCILDepth, StencilD, S
GL_REDRedR
GL_RGRed, GreenR, G
GL_RGBRed, Green, BlueR, G, B
GL_RGBARed, Green, Blue, AlphaR, G, B, A

至此,纹理图像生成了。

七、纹理对象调用过程总结

总之,贴图的步骤共有三个:
1)OpenGL准备外部图片,并转化成GPU纹理对象。
2)顶点着色器引进纹理坐标,并传递给片元着色器。
3)片元着色器将上述元数据解构成像素颜色。

下面用代码实际解释。

7.1 顶点着色器作用

顶点着色器明确地规定,该顶点对应贴图的哪个位置,下面以三角形图元为例:

  • 顶点着色器提供ST坐标,纹理坐标

在这里插入图片描述

7.2 片元着色器作用

片元着色器是一个像素生成环节,它是一个加工厂,原料:

  • 顶点着色器提供ST坐标,纹理坐标。
  • 来自客户端的纹理对象。
    在这里插入图片描述
    上图表示,假如一个图元是个三角形,片段着色器将取出与这个两个区域的交集:
    区域1:三角形图元区域
    区域2: glTexImage2D生成的区域。

7.3 OpenGL的作用

用于生成片元可调用的纹理图:
1)通过 glTexImage2D生成的区域,提供给片元着色器的uniform sampler2D变量
2)uniform sampler2D的调用可以默认,因此无显式调用过程。
3)如果有放大缩小纹理,可调用glGenerateMipmap(GL_TEXTURE_2D)
4)如果纹理很多,可用 glActiveTexture(GL_TEXTURE0)切换。
在这里插入图片描述

八、后记

本文前半部分来自手册理解,后半部分解释一个调用实例,试图解释OpenGL的纹理使用过程,只是一个粗略理解,如果有新的知识,本文将系列地给出解释。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/637561.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

字符串的周期:每一期都有那么几位

【题目描述】 如果一个字符串可以由某个长度为k的字符串重复多次得到,则称该串以k为周期。例 如,abcabcabcabc以3为周期(注意,它也以6和12为周期)。 输入一个长度不超过80的字符串(不含空格),输出其最小周期。 输入第一行表示有T组数据,后续是T行字符串。输出的每组…

【Qt 学习笔记】Qt窗口 | 浮动窗口 | QDockWidget的使用及说明

博客主页:Duck Bro 博客主页系列专栏:Qt 专栏关注博主,后期持续更新系列文章如果有错误感谢请大家批评指出,及时修改感谢大家点赞👍收藏⭐评论✍ Qt窗口 | 浮动窗口 | QDockWidget的使用及说明 文章编号:Q…

Vue 3 组件基础与模板语法详解

title: Vue 3 组件基础与模板语法详解 date: 2024/5/24 16:31:13 updated: 2024/5/24 16:31:13 categories: 前端开发 tags: Vue3特性CompositionAPITeleportSuspenseVue3安装组件基础模板语法 Vue 3 简介 1. Vue 3 的新特性 Vue 3引入了许多新的特性,以提高框…

路由引入实验(华为)

思科设备参考:路由引入实验(思科) 技术简介 路由引入技术在网络通信中起着重要的作用,能够实现不同路由协议之间的路由传递,并在路由引入时部署路由控制,实现路径或策略的控制 实验目的 不同的路由协议之…

【全网最全】2024电工杯数学建模A题21页初步参考论文+py代码+保奖思路等(后续会更新)

您的点赞收藏是我继续更新的最大动力! 一定要点击如下的卡片链接,那是获取资料的入口! 【全网最全】2024电工杯数学建模A题21页初步参考论文py代码保奖思路等(后续会更新成品论文)「首先来看看目前已有的资料&#x…

yolov8seg 瑞芯微RKNN、地平线Horizon芯片部署、TensorRT部署,部署工程难度小、模型推理速度快

之前写过yolov8seg部署,但在实际项目中没有真正的用,最近在项目尝试使用yolov8seg,把之前的yolov8目标检测的优化给同步到yolov8seg中。 特别说明:如有侵权告知删除,谢谢。 模型和完整仿真测试代码,放在git…

一套车间生产管理和调度执行MES系统源码,采用springboot + vue-element+uniapp+mysql技术开发,适合二次开发项目使用。

MES系统源码,车间生产管理系统源码,商业源码,适合上项目 MES系统是制造企业中用于管理和监控生产过程的关键系统,它的核心功能包括生产调度、数据管理、计划排产管理、库存管理、质量管理、设备管理、采购管理、成本管理、项目看板…

《异常检测——从经典算法到深度学习》28 UNRAVEL ANOMALIES:基于周期与趋势分解的时间序列异常检测端到端方法

《异常检测——从经典算法到深度学习》 0 概论1 基于隔离森林的异常检测算法 2 基于LOF的异常检测算法3 基于One-Class SVM的异常检测算法4 基于高斯概率密度异常检测算法5 Opprentice——异常检测经典算法最终篇6 基于重构概率的 VAE 异常检测7 基于条件VAE异常检测8 Donut: …

TypeScript(持续更新中...)

1.TypeScript是什么? TypeScript是javaScript的超集。 2.使用TypeScript 1)全局安装nodejs 2)安装TypeScript编译器 npm i -g typescript 3.编译ts文件 //注意:需要在ts文件同级目录执行此命令,否则会报找不到…

Go语言(Golang)的开发框架

在Go语言(Golang)的开发中,有多种开发框架可供选择,它们各自具有不同的特点和优势。以下是一些流行的Go语言开发框架,选择Go语言的开发框架时,需要考虑项目需求、团队熟悉度、社区支持、框架性能和可维护性…

Java时间工具类(Date和LocalDateTime)

Date package com.qiangesoft.utils.date;import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.Calendar; import java.util.Date;/*** 日期工具类** author lq* date 2024-05-23*/ public class DateUtil {public static final String[] C…

vue从入门到精通(四):MVVM模型

一,MVVM MVVM(Model–view–viewmodel)是一种软件架构模式。MVVM有助于将图形用户界面的开发与业务逻辑或后端逻辑(数据模型)的开发分离开来。详见MVVM 二,Vue中的MVVM Vue虽然没有完全遵循 MVVM 模型,但是 Vue 的设…

nacos-opera(k8s)安装问题解决

整理一些关于k8s部署nacos出现的一些恶心的问题 网上说其他说的更改数据库连接都未解决。 在用nacos-opera想安装高可用nacos时连接mysql数据库报错: 报错具体项: No DataSource set 具体就是说没找到数据源。 第一个 检查一下nacos连接数据库配置 : 第二个 检查一下数据库…

2024 电工杯高校数学建模竞赛(B题)| 平衡膳食食谱 |建模秘籍文章代码思路大全

铛铛!小秘籍来咯! 小秘籍团队独辟蹊径,运用负载均衡,多目标规划等强大工具,构建了这一题的详细解答哦! 为大家量身打造创新解决方案。小秘籍团队,始终引领着建模问题求解的风潮。 抓紧小秘籍&am…

【MySQL数据库】CRUD 增 删 改 查 超详解,有这一篇就够了!

​ ​ 🔥个人主页: 中草药 🔥专栏:【MySQL】探秘:数据库世界的瑞士军刀 目录 ⚗️一.CRUD 🧪二.新增(Create) 🧫1.基本操作 🧬2.使用SELECT插入 &#x…

169. Majority Element

文章目录 题目描述(简单难度)解法一解法二 位运算摩尔投票法参考文献 题目描述(简单难度) 给一个数组,存在一个数字超过了半数,找出这个数。 解法一 这种计数问题,直接就会想到 HashMap,遍历过程中统计每个数字出现的个数即可。…

Python入门全系列教程(更新中……)

最近辞职了,有点时间,打算写一套Python入门的全系列教程,需要的人欢迎关注蹲守!!! 【Python基础篇】:入门基础知识—轻松踏上编程巅峰!" 【Python基础篇】—基本语句详解 【Py…

jenkins插件之xunit

分析测试工具执行的结果,并图形化,比如phpunit,phpstan,可分析junit格式的结果 安装jenkins插件 搜索xunit并安装 项目配置 配置 - Build Steps 您的项目 - 配置 - Build Steps, 新增 Run with timeout 超时时间根据实际情况配置 Build…

unidbg入门笔记

一、unidbg 介绍 unidbg 是凯神 在 2019 年初开源的一个轻量级模拟器,一个基于Java的跨平台解密引擎,专门用于动态分析和逆向工程应用程序。它可以模拟不同CPU架构、操作系统和指令集,从而使用户能够在一个统一的环境中分析各种不同类型的二…

Mac下QT开发环境搭建详细教程

QT Qt是一个跨平台的C应用程序框架,用于开发具有图形用户界面(GUI)的应用程序,同时也可用于开发非GUI程序,比如控制台工具和服务器。Qt是设计成通用、可移植和高效的,它广泛应用于全球的企业和开发者社区中…