如何使用 C++将 2D RGB 数组转换为 dds 文件?
How can I convert a 2D RGB array into a dds file using C++?
我有一个 RGB 值的 2D 数组,表示平面的绘制顶点。我想将平面的最终顶点颜色存储在.dds文件中,以便以后可以将.dds文件作为纹理加载。
我该如何解决这个问题?
感谢评论中的查克,我发现这个解决方案对我有用。可能需要进行改进。该方法可以分为几个步骤。
第一步是捕获用于渲染的设备上下文和 D3D 设备,并设置在使用 SaveDDSTextureToFile (ScreenGrab( 创建要捕获的纹理时使用的正确纹理描述。当每个浮点数包含每种颜色和 alpha 值的四个字节值时,以下描述有效。
void DisplayChunk::SaveVertexColours(std::shared_ptr<DX::DeviceResources> DevResources)
{
// Setup D3DDeviceContext and D3DDevice
auto devicecontext = DevResources->GetD3DDeviceContext();
auto device = DevResources->GetD3DDevice();
// Create Texture2D and Texture2D Description
ID3D11Texture2D* terrain_texture;
D3D11_TEXTURE2D_DESC texture_desc;
// Set up a texture description
texture_desc.Width = TERRAINRESOLUTION;
texture_desc.Height = TERRAINRESOLUTION;
texture_desc.MipLevels = texture_desc.ArraySize = 1;
texture_desc.Format = DXGI_FORMAT_R32G32B32A32_FLOAT;
texture_desc.SampleDesc.Count = 1;
texture_desc.SampleDesc.Quality = 0;
texture_desc.Usage = D3D11_USAGE_DYNAMIC;
texture_desc.BindFlags = D3D11_BIND_SHADER_RESOURCE;
texture_desc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
texture_desc.MiscFlags = 0;
第二步是创建一个浮点向量,并用相关的 RGBA 值填充它。我使用向量的原因是为了方便每次迭代推送 R、G、B 和 A 的单独浮点值。这样,在每个顶点位置,您可以推回所需的 16 个字节值(如上所述,每个浮点值四个(。
// Create vertex colour vector
std::vector<float> colour_vector;
for (int i = 0; i < TERRAINRESOLUTION; i++) {
for (int j = 0; j < TERRAINRESOLUTION; j++) {
colour_vector.push_back((float)m_terrainGeometry[i][j].color.x);
colour_vector.push_back((float)m_terrainGeometry[i][j].color.y);
colour_vector.push_back((float)m_terrainGeometry[i][j].color.z);
colour_vector.push_back((float)m_terrainGeometry[i][j].color.w);
}
}
第三步是用顶点 RGBA 值填充缓冲区。缓冲区大小必须等于存储所需的总字节数,即每个浮点数 4 个字节,每个顶点 4 个浮点数,以及 TERRAINTRESOLUTION * TERRAINTRESOLUTION 顶点。10 x 10 地形示例:4(字节(x 4(浮点数(x 10(宽度(x 10(高度(= 1600 字节,用于存储每个顶点的 RGBA。
// Initialise buffer parameters
const int components = 4;
const int length = components * TERRAINRESOLUTION * TERRAINRESOLUTION;
// Fill buffer with vertex colours
float* buffer = new float[length * sizeof(float)];
for (int i = 0; i < length; i++)
buffer[i] = colour_vector[i];
最后一步是使用上面创建的缓冲区的内容创建纹理数据。 pSysMem 需要一个指向缓冲区的指针,用作初始化数据。SysMemPitch 必须设置为一行的大小。使用 CreateTexture2D,可以使用存储的字节值创建新纹理。SaveDDSTextureToFile允许将纹理资源保存到外部.dds文件中。使用后不要忘记删除缓冲区。
// Set the texture data using the buffer contents
D3D11_SUBRESOURCE_DATA texture_data;
texture_data.pSysMem = (void*)buffer;
texture_data.SysMemPitch = TERRAINRESOLUTION * components * sizeof(float);
// Create the texture using the terrain colour data
device->CreateTexture2D(&texture_desc, &texture_data, &terrain_texture);
// Save the texture to a .dds file
HRESULT hr = SaveDDSTextureToFile(devicecontext, terrain_texture, L"terrain_output.dds");
// Delete the buffer
delete[] buffer;
}
我在实现时使用的一些资源:
- (DDS指南(
- (截屏来源(
- (截屏示例(
- (在 DirectX 中创建纹理( (
- 寻址方案示例(正确导航缓冲区/数组((
- 防止主数据类型C++的隐式转换
- 模板参数替换失败,并且未完成隐式转换
- 努力将整数转换为链表。不知道我在这里做错了什么
- HEX值到wchar_t字符(UTF-8)的转换
- lambda参数转换为constexpr技巧,然后获取带链接的数组
- 将 Qvector<uint8_t> 转换为 QString
- 如何在cuSparse中使用cusparseXcoo2csr从coo转换为csc
- 有关插入适配器的错误。[错误]请求从 'back_insert_iterator<vector<>>' 类型转换为非标量类型
- 在c++中使用nlohmann从类到json的转换
- 从"int*"强制转换为"unsigned int"会丢失精度错误
- 将Integer转换为4字节的unsined字符矢量(按大端字节顺序)
- 处理小于cpu数据总线的数据类型.(c++转换为机器代码)
- 如何使用OpenCV将RBG图像转换为HSV,并将H、S和V值保存为C++中的3个独立图像
- 复制列表初始化的隐式转换的等级是多少
- 正在将指针转换为范围
- 如何防止 c++ 在从浮点型转换为双精度型(不适用于 IO)时添加额外的小数?
- 将"打开的CV图像"中的"颜色"转换为整数格式
- 是否可以从int转换为enum类类型
- 了解 GLM- openGL 中的相机转换
- 如何使用 C++将 2D RGB 数组转换为 dds 文件?