如何使用C ++将2D RGB数组转换为dds文件?

问题描述 投票:-1回答:1

我有一个RGB值的2D数组,它们表示一个平面的绘制顶点。我想将平面的最终顶点颜色存储在.dds文件中,以便稍后可以将.dds文件作为纹理加载。

我该如何处理?

c++ directx
1个回答
1
投票

感谢Chuck的评论,我发现此解决方案对我来说很有效。有可能需要改进。该方法可以分为几个步骤。

第一步是捕获用于渲染的设备上下文和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值填充缓冲区。缓冲区大小必须等于存储所需的字节总数,即每个浮点数四个字节,每个顶点四个浮点数以及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;
}

我在实施时使用的一些资源:

© www.soinside.com 2019 - 2024. All rights reserved.