区块链技术博客
www.b2bchain.cn

创建和采样纹理求职学习资料

本文介绍了创建和采样纹理求职学习资料,有助于帮助完成毕业设计以及求职,是一篇很好的资料。

对技术面试,学习经验等有一些体会,在此分享。

Creating and Sampling Textures | Apple Developer Documentation

将图像数据加载到纹理中,并将其应用到四边形中。

详细介绍了Metal中的纹理使用原理,并通过一个简单示例进行展示。

翻译术语表

概述

你可以使用纹理在Metal中绘制和处理图像。纹理是一个结构化的纹理元素(通常被称为纹素(texels)或像素(pixels))集合。纹素的确切配置取决于纹理的类型。该示例使用了一个二维数组结构的纹理,每个元素都包含颜色数据,以表达一个图像。纹理是通过称为纹理映射(texture mapping)的过程绘制到几何图元上的。片元函数通过对纹理进行采样,为每个片元生成颜色。

纹理由MTLTexture对象管理。MTLTexture对象定义了纹理的格式,包括纹素的大小和布局、纹素数量以及纹素组织方式。一旦创建,纹理的格式和组织方式就不会改变。然而,你可以改变纹理的内容,无论是通过渲染它,亦或者是给它复制数据。

Metal框架没有提供一个API来直接从文件中加载图像数据到纹理中。Metal本身只是分配纹理对象资源,并提供将数据复制到纹理对象和从纹理对象复制数据的方法。Metal程序靠其他框架来处理图像文件,如MetalKit、Image I/O、UIKit或AppKit。例如,你可以使用MTKTextureLoader来执行简单的纹理加载。本示例展示了如何编写一个自定义的纹理加载器。

注意

Xcode项目包含了在macOS、iOS或tvOS设备上运行本示例的方案(scheme)。默认方案是macOS,它将按Mac上的方式运行示例。

加载和格式化图像数据

你可以手动创建一个纹理或更新它的内容,这个过程将在接下来的几个章节中介绍。你可能出于以下原因需要手动创建或更新一个问题:

  • 以自定义格式存储的图像数据。
  • 需要在运行时生成内容的纹理。
  • 从服务器流式传输的纹理数据,或者需要动态更新纹理内容。

在本示例中,AAPLImage类从TGA文件加载和解析图像数据。该类把TGA文件加载和解析图像数据。该类将TGA文件中的像素数据转换为Metal可以理解的像素格式。该示例使用图像的元数据来创建一个新的Metal纹理,并将像素数据复制到纹理中。

注意

AAPLImage类并不是该示例的重点,所以没有详细阐述。该类演示了基本的图像加载操作,但并没有使用或依赖Metal框架。它但唯一目的是方便加载图像数据并将其转换为Metal像素格式。如果需要加载一个自定格式的图像,你可以创建一个类似的类。

Metal要求所有的纹理都要用特定的MTLPixelFormat值进行格式化。像素格式描述类纹理中像素数据的布局。本示例使用的是MTLPixelFormatBGRA8Unorm像素格式,每个像素32位,按蓝色、绿色、红色和alpha顺序排列,每个分量占8位:

创建和采样纹理

在你填充Metal纹理之前,必须要把图像的像素数据格式化为纹理的像素格式。TGA文件可以以每像素32位,或每像素24位的格式提供像素数据。如果使用每像素32位的TGA文件,文件已经以MTLPixelFormatBGRA8Unorm这种格式排列了,所以只需要复制像素数据。如果使用每像素24位的BGR图像,需要进行转换,复制红、绿、蓝通道,并将alpha通道设置为255,表示完全不透明的像素:

// Initialize a source pointer with the source image data that's in BGR form uint8_t *srcImageData = ((uint8_t*)fileData.bytes +                          sizeof(TGAHeader) +                          tgaInfo->IDSize);  // Initialize a destination pointer to which you'll store the converted BGRA // image data uint8_t *dstImageData = mutableData.mutableBytes;  // For every row of the image for(NSUInteger y = 0; y < _height; y++) {     // If bit 5 of the descriptor is not set, flip vertically     // to transform the data to Metal's top-left texture origin     NSUInteger srcRow = (tgaInfo->topOrigin) ? y : _height - 1 - y;      // For every column of the current row     for(NSUInteger x = 0; x < _width; x++)     {         // If bit 4 of the descriptor is set, flip horizontally         // to transform the data to Metal's top-left texture origin         NSUInteger srcColumn = (tgaInfo->rightOrigin) ? _width - 1 - x : x;          // Calculate the index for the first byte of the pixel you're         // converting in both the source and destination images         NSUInteger srcPixelIndex = srcBytesPerPixel * (srcRow * _width + srcColumn);         NSUInteger dstPixelIndex = 4 * (y * _width + x);          // Copy BGR channels from the source to the destination         // Set the alpha channel of the destination pixel to 255         dstImageData[dstPixelIndex + 0] = srcImageData[srcPixelIndex + 0];         dstImageData[dstPixelIndex + 1] = srcImageData[srcPixelIndex + 1];         dstImageData[dstPixelIndex + 2] = srcImageData[srcPixelIndex + 2];          if(tgaInfo->bitsPerPixel == 32)         {             dstImageData[dstPixelIndex + 3] =  srcImageData[srcPixelIndex + 3];         }         else         {             dstImageData[dstPixelIndex + 3] = 255;         }     } } _data = mutableData;

从纹理描述符创建纹理

使用MTLTextureDescriptor对象为MTLTexture对象配置纹理尺寸和像素格式等格式。然后调用newTextureWithDescriptor:方法创建一个纹理。

MTLTextureDescriptor *textureDescriptor = [[MTLTextureDescriptor alloc] init];  // Indicate that each pixel has a blue, green, red, and alpha channel, where each channel is // an 8-bit unsigned normalized value (i.e. 0 maps to 0.0 and 255 maps to 1.0) textureDescriptor.pixelFormat = MTLPixelFormatBGRA8Unorm;  // Set the pixel dimensions of the texture textureDescriptor.width = image.width; textureDescriptor.height = image.height;  // Create the texture from the device by using the descriptor id<MTLTexture> texture = [_device newTextureWithDescriptor:textureDescriptor];

Metal创建了一个MTLTexture对象并为纹理分配内存。当创建纹理对象时,其内存是未初始化的,所以下一步是将数据复制到纹理中。

复制图像数据到纹理中

Metal管理这纹理的内存,并且不提供直接访问它的权限。所以,当要复制像素数据,你不能在内存中获得一个指向纹理数据的指针,然后填充数据。取而代之的是,调用MTLTexture对象的方法,从内存中复制数据到纹理中,反之亦然。

在本示例中,AAPLImage对象为图像数据分配了内存,所以要告诉纹理对象复制这些数据。

使用MTLRegion结构体来确定要更新纹理的区域。本示例用图像数据填充整个纹理,所以要创建一个覆盖整个纹理的区域。

“`

Creating and Sampling Textures | Apple Developer Documentation

将图像数据加载到纹理中,并将其应用到四边形中。

详细介绍了Metal中的纹理使用原理,并通过一个简单示例进行展示。

翻译术语表

概述

你可以使用纹理在Metal中绘制和处理图像。纹理是一个结构化的纹理元素(通常被称为纹素(texels)或像素(pixels))集合。纹素的确切配置取决于纹理的类型。该示例使用了一个二维数组结构的纹理,每个元素都包含颜色数据,以表达一个图像。纹理是通过称为纹理映射(texture mapping)的过程绘制到几何图元上的。片元函数通过对纹理进行采样,为每个片元生成颜色。

纹理由MTLTexture对象管理。MTLTexture对象定义了纹理的格式,包括纹素的大小和布局、纹素数量以及纹素组织方式。一旦创建,纹理的格式和组织方式就不会改变。然而,你可以改变纹理的内容,无论是通过渲染它,亦或者是给它复制数据。

Metal框架没有提供一个API来直接从文件中加载图像数据到纹理中。Metal本身只是分配纹理对象资源,并提供将数据复制到纹理对象和从纹理对象复制数据的方法。Metal程序靠其他框架来处理图像文件,如MetalKit、Image I/O、UIKit或AppKit。例如,你可以使用MTKTextureLoader来执行简单的纹理加载。本示例展示了如何编写一个自定义的纹理加载器。

注意

Xcode项目包含了在macOS、iOS或tvOS设备上运行本示例的方案(scheme)。默认方案是macOS,它将按Mac上的方式运行示例。

加载和格式化图像数据

你可以手动创建一个纹理或更新它的内容,这个过程将在接下来的几个章节中介绍。你可能出于以下原因需要手动创建或更新一个问题:

  • 以自定义格式存储的图像数据。
  • 需要在运行时生成内容的纹理。
  • 从服务器流式传输的纹理数据,或者需要动态更新纹理内容。

在本示例中,AAPLImage类从TGA文件加载和解析图像数据。该类把TGA文件加载和解析图像数据。该类将TGA文件中的像素数据转换为Metal可以理解的像素格式。该示例使用图像的元数据来创建一个新的Metal纹理,并将像素数据复制到纹理中。

注意

AAPLImage类并不是该示例的重点,所以没有详细阐述。该类演示了基本的图像加载操作,但并没有使用或依赖Metal框架。它但唯一目的是方便加载图像数据并将其转换为Metal像素格式。如果需要加载一个自定格式的图像,你可以创建一个类似的类。

Metal要求所有的纹理都要用特定的MTLPixelFormat值进行格式化。像素格式描述类纹理中像素数据的布局。本示例使用的是MTLPixelFormatBGRA8Unorm像素格式,每个像素32位,按蓝色、绿色、红色和alpha顺序排列,每个分量占8位:

创建和采样纹理

在你填充Metal纹理之前,必须要把图像的像素数据格式化为纹理的像素格式。TGA文件可以以每像素32位,或每像素24位的格式提供像素数据。如果使用每像素32位的TGA文件,文件已经以MTLPixelFormatBGRA8Unorm这种格式排列了,所以只需要复制像素数据。如果使用每像素24位的BGR图像,需要进行转换,复制红、绿、蓝通道,并将alpha通道设置为255,表示完全不透明的像素:

// Initialize a source pointer with the source image data that's in BGR form uint8_t *srcImageData = ((uint8_t*)fileData.bytes +                          sizeof(TGAHeader) +                          tgaInfo->IDSize);  // Initialize a destination pointer to which you'll store the converted BGRA // image data uint8_t *dstImageData = mutableData.mutableBytes;  // For every row of the image for(NSUInteger y = 0; y < _height; y++) {     // If bit 5 of the descriptor is not set, flip vertically     // to transform the data to Metal's top-left texture origin     NSUInteger srcRow = (tgaInfo->topOrigin) ? y : _height - 1 - y;      // For every column of the current row     for(NSUInteger x = 0; x < _width; x++)     {         // If bit 4 of the descriptor is set, flip horizontally         // to transform the data to Metal's top-left texture origin         NSUInteger srcColumn = (tgaInfo->rightOrigin) ? _width - 1 - x : x;          // Calculate the index for the first byte of the pixel you're         // converting in both the source and destination images         NSUInteger srcPixelIndex = srcBytesPerPixel * (srcRow * _width + srcColumn);         NSUInteger dstPixelIndex = 4 * (y * _width + x);          // Copy BGR channels from the source to the destination         // Set the alpha channel of the destination pixel to 255         dstImageData[dstPixelIndex + 0] = srcImageData[srcPixelIndex + 0];         dstImageData[dstPixelIndex + 1] = srcImageData[srcPixelIndex + 1];         dstImageData[dstPixelIndex + 2] = srcImageData[srcPixelIndex + 2];          if(tgaInfo->bitsPerPixel == 32)         {             dstImageData[dstPixelIndex + 3] =  srcImageData[srcPixelIndex + 3];         }         else         {             dstImageData[dstPixelIndex + 3] = 255;         }     } } _data = mutableData;

从纹理描述符创建纹理

使用MTLTextureDescriptor对象为MTLTexture对象配置纹理尺寸和像素格式等格式。然后调用newTextureWithDescriptor:方法创建一个纹理。

MTLTextureDescriptor *textureDescriptor = [[MTLTextureDescriptor alloc] init];  // Indicate that each pixel has a blue, green, red, and alpha channel, where each channel is // an 8-bit unsigned normalized value (i.e. 0 maps to 0.0 and 255 maps to 1.0) textureDescriptor.pixelFormat = MTLPixelFormatBGRA8Unorm;  // Set the pixel dimensions of the texture textureDescriptor.width = image.width; textureDescriptor.height = image.height;  // Create the texture from the device by using the descriptor id<MTLTexture> texture = [_device newTextureWithDescriptor:textureDescriptor];

Metal创建了一个MTLTexture对象并为纹理分配内存。当创建纹理对象时,其内存是未初始化的,所以下一步是将数据复制到纹理中。

复制图像数据到纹理中

Metal管理这纹理的内存,并且不提供直接访问它的权限。所以,当要复制像素数据,你不能在内存中获得一个指向纹理数据的指针,然后填充数据。取而代之的是,调用MTLTexture对象的方法,从内存中复制数据到纹理中,反之亦然。

在本示例中,AAPLImage对象为图像数据分配了内存,所以要告诉纹理对象复制这些数据。

使用MTLRegion结构体来确定要更新纹理的区域。本示例用图像数据填充整个纹理,所以要创建一个覆盖整个纹理的区域。

“`

Creating and Sampling Textures | Apple Developer Documentation

将图像数据加载到纹理中,并将其应用到四边形中。

详细介绍了Metal中的纹理使用原理,并通过一个简单示例进行展示。

翻译术语表

概述

你可以使用纹理在Metal中绘制和处理图像。纹理是一个结构化的纹理元素(通常被称为纹素(texels)或像素(pixels))集合。纹素的确切配置取决于纹理的类型。该示例使用了一个二维数组结构的纹理,每个元素都包含颜色数据,以表达一个图像。纹理是通过称为纹理映射(texture mapping)的过程绘制到几何图元上的。片元函数通过对纹理进行采样,为每个片元生成颜色。

纹理由MTLTexture对象管理。MTLTexture对象定义了纹理的格式,包括纹素的大小和布局、纹素数量以及纹素组织方式。一旦创建,纹理的格式和组织方式就不会改变。然而,你可以改变纹理的内容,无论是通过渲染它,亦或者是给它复制数据。

Metal框架没有提供一个API来直接从文件中加载图像数据到纹理中。Metal本身只是分配纹理对象资源,并提供将数据复制到纹理对象和从纹理对象复制数据的方法。Metal程序靠其他框架来处理图像文件,如MetalKit、Image I/O、UIKit或AppKit。例如,你可以使用MTKTextureLoader来执行简单的纹理加载。本示例展示了如何编写一个自定义的纹理加载器。

注意

Xcode项目包含了在macOS、iOS或tvOS设备上运行本示例的方案(scheme)。默认方案是macOS,它将按Mac上的方式运行示例。

加载和格式化图像数据

你可以手动创建一个纹理或更新它的内容,这个过程将在接下来的几个章节中介绍。你可能出于以下原因需要手动创建或更新一个问题:

  • 以自定义格式存储的图像数据。
  • 需要在运行时生成内容的纹理。
  • 从服务器流式传输的纹理数据,或者需要动态更新纹理内容。

在本示例中,AAPLImage类从TGA文件加载和解析图像数据。该类把TGA文件加载和解析图像数据。该类将TGA文件中的像素数据转换为Metal可以理解的像素格式。该示例使用图像的元数据来创建一个新的Metal纹理,并将像素数据复制到纹理中。

注意

AAPLImage类并不是该示例的重点,所以没有详细阐述。该类演示了基本的图像加载操作,但并没有使用或依赖Metal框架。它但唯一目的是方便加载图像数据并将其转换为Metal像素格式。如果需要加载一个自定格式的图像,你可以创建一个类似的类。

Metal要求所有的纹理都要用特定的MTLPixelFormat值进行格式化。像素格式描述类纹理中像素数据的布局。本示例使用的是MTLPixelFormatBGRA8Unorm像素格式,每个像素32位,按蓝色、绿色、红色和alpha顺序排列,每个分量占8位:

创建和采样纹理

在你填充Metal纹理之前,必须要把图像的像素数据格式化为纹理的像素格式。TGA文件可以以每像素32位,或每像素24位的格式提供像素数据。如果使用每像素32位的TGA文件,文件已经以MTLPixelFormatBGRA8Unorm这种格式排列了,所以只需要复制像素数据。如果使用每像素24位的BGR图像,需要进行转换,复制红、绿、蓝通道,并将alpha通道设置为255,表示完全不透明的像素:

// Initialize a source pointer with the source image data that's in BGR form uint8_t *srcImageData = ((uint8_t*)fileData.bytes +                          sizeof(TGAHeader) +                          tgaInfo->IDSize);  // Initialize a destination pointer to which you'll store the converted BGRA // image data uint8_t *dstImageData = mutableData.mutableBytes;  // For every row of the image for(NSUInteger y = 0; y < _height; y++) {     // If bit 5 of the descriptor is not set, flip vertically     // to transform the data to Metal's top-left texture origin     NSUInteger srcRow = (tgaInfo->topOrigin) ? y : _height - 1 - y;      // For every column of the current row     for(NSUInteger x = 0; x < _width; x++)     {         // If bit 4 of the descriptor is set, flip horizontally         // to transform the data to Metal's top-left texture origin         NSUInteger srcColumn = (tgaInfo->rightOrigin) ? _width - 1 - x : x;          // Calculate the index for the first byte of the pixel you're         // converting in both the source and destination images         NSUInteger srcPixelIndex = srcBytesPerPixel * (srcRow * _width + srcColumn);         NSUInteger dstPixelIndex = 4 * (y * _width + x);          // Copy BGR channels from the source to the destination         // Set the alpha channel of the destination pixel to 255         dstImageData[dstPixelIndex + 0] = srcImageData[srcPixelIndex + 0];         dstImageData[dstPixelIndex + 1] = srcImageData[srcPixelIndex + 1];         dstImageData[dstPixelIndex + 2] = srcImageData[srcPixelIndex + 2];          if(tgaInfo->bitsPerPixel == 32)         {             dstImageData[dstPixelIndex + 3] =  srcImageData[srcPixelIndex + 3];         }         else         {             dstImageData[dstPixelIndex + 3] = 255;         }     } } _data = mutableData;

从纹理描述符创建纹理

使用MTLTextureDescriptor对象为MTLTexture对象配置纹理尺寸和像素格式等格式。然后调用newTextureWithDescriptor:方法创建一个纹理。

MTLTextureDescriptor *textureDescriptor = [[MTLTextureDescriptor alloc] init];  // Indicate that each pixel has a blue, green, red, and alpha channel, where each channel is // an 8-bit unsigned normalized value (i.e. 0 maps to 0.0 and 255 maps to 1.0) textureDescriptor.pixelFormat = MTLPixelFormatBGRA8Unorm;  // Set the pixel dimensions of the texture textureDescriptor.width = image.width; textureDescriptor.height = image.height;  // Create the texture from the device by using the descriptor id<MTLTexture> texture = [_device newTextureWithDescriptor:textureDescriptor];

Metal创建了一个MTLTexture对象并为纹理分配内存。当创建纹理对象时,其内存是未初始化的,所以下一步是将数据复制到纹理中。

复制图像数据到纹理中

Metal管理这纹理的内存,并且不提供直接访问它的权限。所以,当要复制像素数据,你不能在内存中获得一个指向纹理数据的指针,然后填充数据。取而代之的是,调用MTLTexture对象的方法,从内存中复制数据到纹理中,反之亦然。

在本示例中,AAPLImage对象为图像数据分配了内存,所以要告诉纹理对象复制这些数据。

使用MTLRegion结构体来确定要更新纹理的区域。本示例用图像数据填充整个纹理,所以要创建一个覆盖整个纹理的区域。

“`

部分转自互联网,侵权删除联系

赞(0) 打赏
部分文章转自网络,侵权联系删除b2bchain区块链学习技术社区 » 创建和采样纹理求职学习资料
分享到: 更多 (0)

评论 抢沙发

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址

b2b链

联系我们联系我们