簡體   English   中英

如何使用 C++ 將 2D RGB 數組轉換為 dds 文件?

[英]How can I convert a 2D RGB array into a dds file using C++?

我有一個 RGB 值的二維數組,代表平面的繪制頂點。 我想將平面的最終頂點顏色存儲在 a.dds 文件中,以便以后可以將 .dds 文件作為紋理加載。

我該如何處理?

感謝評論中的 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 的單獨浮點值。 這樣,在每個頂點 position 處,您可以推回所需的 16 個字節值(如上所述,每個浮點數中的 4 個)。

    // 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(bytes) x 4(floats) x 10(width) x 10(height) = 1600 bytes 用於存儲每個頂點的 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 允許將紋理資源保存到 external.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;
}

我在實施時使用的一些資源:

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM