【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 corelayout (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 corein 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的纹理使用过程,只是一个粗略理解,如果有新的知识,本文将系列地给出解释。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

科研——ICONIP论文修改和提交

文章目录 Springer Nature Code of Conduct and Book Publishing Policies行为准则和出版的道德规范文章的准备Structing Your paperLengths of Paper文章长度FontsPage Numbering and Running HeadsFigures and TablesFormulaeFootnotesCitation by Number Additional Informa…

使用Flask Swagger自动生成API文档

文章目录 安装Flask Swagger使用Flask Swagger生成API文档总结1. 自动化文档生成2. 交互式文档展示3. 规范化API设计4. 提升协作效率5. 支持多种格式 Flask Swagger是一种用于管理Flask API文档的工具。它基于OpenAPI规范,可以自动生成API的交互式文档。使用Flask S…

【前端】从手动部署到自动部署:前端项目进化之路

从手动部署到自动部署:前端项目进化之路 在前端开发的领域内,部署是一个不可忽视的环节。随着项目复杂度的增加和线上更新频率的提升,手动部署逐渐暴露出它的弊端。本文将带你从手动部署过渡到自动部署,完成前端项目进化的重要一…

【笔记】软件架构师要点记录(1)

【笔记】软件架构师要点记录 20240517 20240517 连续性:恢复能力;可用性:保持稳定态的时长 增量开发模式:在增量开发中,每个增量都有明确的范围和功能,并按照特定的功能顺序完成。增量之间的范围划分在开发…

【C++】牛客——OR64 求和

✨题目链接: OR64 求和 ✨题目描述 输入两个整数 n 和 m,从数列1,2,3.......n 中随意取几个数,使其和等于 m ,要求将其中所有的可能组合列出来 ✨输入描述: 每个测试输入包含2个整数,n和m ✨输出描述: 按每个组合的字典序排列…

作业-day-240523

思维导图 知识点问答 1、IO多路复用的原理 1、创建一个检测文件描述符的容器 fd_set fds; 2、将需要检测的文件描述符放入容器中 FD_SET(文件描述符,&fds); 3、通过一个阻塞函数阻塞等待容器中是否有事件产生,如果有一个或多个事件产生&#xff0c…

由于找不到mfc140u.dll怎么办,介绍5种靠谱有效的解决方法

当您的电脑显示“mfc140u.dll丢失”的错误时,通常是因为系统中缺少了某个必要的动态链接库文件。这个问题可能会导致某些应用程序无法正常运行,给用户带来困扰。下面我将详细介绍解决该问题的五种方法。 一,关于mfc140u.dll文件的概述 mfc14…

OneAPI接入本地大模型+FastGPT调用本地大模型

将Ollama下载的本地大模型配置到OneAPI中,并通过FastGPT调用本地大模型完成对话。 OneAPI配置 新建令牌 新建渠道 FastGPT配置 配置docker-compose 配置令牌和OneAPI部署地址 配置config.json 配置调用的渠道名称和大模型名称 {"systemEnv": {&qu…

一文带你了解所有常用排序算法

目录 快速排序 堆排序 桶排序 归并排序 拓扑排序 本文主要介绍那些我在刷题过程中常用到的排序算法: 快速排序,堆排序,桶排序,归并排序,拓扑排序 其余算法例如冒泡,插入这种效率特别低的算法就不介绍了,用的可能性极小 每一个算法都将采用例题加解释的方式进行介绍 快速…

行业首发 | MS08067-SecGPT(送邀请码)

一、简介 MS08067-SecGPT基于LLM大模型技术专门为网络安全领域设计的智能助手,集问答、分析、工具为一体的对话式安全专家,支持可以创建多会话问答。目的是辅助用户完成网络安全相关的工作,学员通过问答方式体验到SecGPT所具备的威胁情报分…

flume使用实例

1、监听端口a1.sources.r1.type netcat 配置文件nc-flume-console.conf # Name the components on this agent a1 表示jvm进程名 a1.sources r1 a1.sinks k1 a1.channels c1 # Describe/configure the source a1.sources.r1.type netcat a1.sources.r1.bind node…

VERY DEEP CONVOLUTIONAL NETWORKS FOR LARGE-SCALE IMAGE RECOGNITION--论文笔记

论文笔记 论文来源 Very Deep Convolutional Networks for Large-Scale Image Recognition 代码来源 还没上传 数据集 这里采用的是猫狗数据集 还没上传 1论文摘要的翻译 在这项工作中,我们研究了卷积网络深度对其在大规模图像识别设置中的准确性的影响。我…

防火墙技术基础篇:解析入侵检测与预防系统(IDPS)功能

防火墙技术基础篇:解析入侵检测与预防系统(IDPS)功能 入侵检测与预防系统(Intrusion Detection and Prevention Systems, IDPS)作为防火墙技术的核心组成部分,扮演着保护网络安全的关键角色。本文将全面讲…

OSPF状态机及网络接口类型

、OSPF 状态机 Down一旦接收到hello 包进人下一个状态机 Init 初始化接收到的hello 包中,若存在本地的 RID,进入下一状态 2way 双向通讯--邻居关系建立的标志 条件匹配:点到点网络直接进入下一个状态机 MA 网络将进行 DR/BDR 选举(40S) 非 DR…

哪个网盘最适合个人文件长期储存?用派盘最好

派盘是一款面向个人和企业的本地云存储解决方案,专为长期文件存储而设计。这种存储方式利用了本地硬盘的存储容量,通过“云化”的方式,可以将本地硬盘变成云存储空间。它具有强大的数据保护功能,确保了数据的私密性和安全性。 派盘的主要特点 高效的存取速度:由于使用本地…

这种电脑原来这么耗电……震惊了粉丝小姐姐

前言 在今年1月份的时候,一位来自重庆的小姐姐加了小白,咨询电脑的问题: 哦豁,这个电脑看着确实闪闪发光,是真的很漂亮~(嗯,小姐姐也很漂亮) 电脑无法开机,按…

什么是流量削峰?如何解决秒杀等业务的削峰场景

文章推荐 1 作为程序员,开发用过最好用的AI工具有哪些? 2 Github Copilot正版的激活成功,终于可以chat了 3 idea,pycharm等的ai assistant已成功激活 4 新手如何拿捏 Github Copilot AI助手,帮助你提高写代码效率 5 Jetbrains的a…

数字驱动,教育先行——低代码揭秘教育机构管理数字化转型

数字化时代为教育带来了许多变革和挑战,同时也为教育创新提供了无限可能。数字化转型可以帮助教育机构应对这些变革和挑战,提高教育效率和质量,满足学生个性化需求,优化教育管理和服务,并提高教育机构的竞争力。 并且…

docker 安装 yapi

文章目录 docker 安装 yapi一、拉取镜像二、创建目录三、添加配置文件四、初始化数据库表五、启动 yapi六、测试以及修改默认密码 没有 MongDB 的可以先看这个教程:MongDB安装教程 docker 安装 yapi 版本: 1.9.5 一、拉取镜像 docker pull yapipro/y…

以及Spring中为什么会出现IOC容器?@Autowired和@Resource注解?

以及Spring中为什么会出现IOC容器?Autowired和Resource注解? IOC容器发展史 没有IOC容器之前 首先说一下在Spring之前,我们的程序里面是没有IOC容器的,这个时候我们如果想要得到一个事先已经定义的对象该怎么得到呢?…