簡體   English   中英

Unity:CopyTexture到外部texture2D

[英]Unity: CopyTexture to External texture2D

我需要將 Unity 紋理/Rendertexture 公開給某些本機插件,這需要紋理上的“D3D11_RESOURCE_MISC_SHARED”標志。

unity 創建的紋理沒有這個標志,所以,我從插件端創建它,然后使用 CreateExternalTexture 在 unity 中創建一個參考紋理,並使用 Graphics.CopyTexture 將內容復制到這個原生紋理。

2 個紋理具有相同的維度、相同的大小、相同的格式和相同的 mipCount(0)

問題是,當我統一顯示它時(出於調試目的),我什么也看不到,也沒有發生錯誤。

順便說一句,如果我通過 ReadPixel 復制,則會發生錯誤:

ReadPixels 在未定義的圖像 0 上調用(有效值為 0 - -1

如果我使用 unity api 創建紋理,CopyTexture 成功並且可以看到結果。 但是后來,我丟失了“D3D11_RESOURCE_MISC_SHARED”標志。

所以,也許我創建的紋理無效? 我的代碼:

    D3D11_TEXTURE2D_DESC desc = { 0 };
desc.Width = width;
desc.Height = height;
desc.MipLevels = 0;
desc.ArraySize = 1;
desc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;//這里,格式能不能調整?比如,A8是需要的嗎?
desc.SampleDesc.Count = 1;
desc.Usage = D3D11_USAGE_DEFAULT;
desc.BindFlags = D3D11_BIND_SHADER_RESOURCE;//普通資源
//desc.CPUAccessFlags = D3D11_CPU_ACCESS_READ;//應該不需要cpu訪問的,不是read也不是write
desc.MiscFlags = D3D11_RESOURCE_MISC_SHARED;//for "OpenSharedHandle" d3d11 api

HRESULT hr = E_FAIL;
if (FAILED(hr = pDevice->CreateTexture2D(&desc, nullptr, &g_unityEquirectTexture)))
{
    Log(" Create Shared Texture Failed!");
    return NULL;
}
Log("CreateSharedTexture success");
//return g_unityEquirectTexture;

Unity CopyTexture 代碼:

        if (output == null)
    {
        Debug.Log($"limit = {QualitySettings.masterTextureLimit}");
        //output = new Texture2D(equirect.width, equirect.height, TextureFormat.RGBA32,false);//uncomment this line and then copyTexture below succeeds
        IntPtr externalTextureData = CGDKInterOp.cgdk_c_CreateExternalTexture(equirectLeft.GetNativeTexturePtr(), equirectLeft.width * 2, equirectLeft.height);
        if (externalTextureData != IntPtr.Zero)
        {
            output = Texture2D.CreateExternalTexture(equirectLeft.width * 2, equirectLeft.height, TextureFormat.RGBA32, false, true, externalTextureData);
        }
    }
    if (output == null)
    {
        Debug.LogError("create texture from external failed!");
        return;
    }

    //RenderTexture.active = equirect;
    //output.ReadPixels(new Rect(0, 0, equirect.width, equirect.height), 0, 0);
    //RenderTexture.active = null;
    Graphics.CopyTexture(equirect, output);

好的,自己解決了。

問題是:Miplevel == 0。這會導致 d3d11 創建一個分配了 0B memory的紋理! 將 Miplevel 更改為 1 解決了問題

注意:在unity inspector中,我們可以看到紋理分配的memory。 我發現我的紋理有來自檢查員的 0B memory 然后,我使用這個線索搜索並找到了解決方案

可能有更好的解決方案,但上次我需要將紋理數據從本機端復制到托管 (Unity) 時,我是通過數據編組來完成的。

您基本上只需要在本機插件中公開一個方法,將紋理數據作為數組傳遞給您,然后在 C# 代碼中有一個方法來獲取它的數據(通過調用該方法),釋放指向本機 memory 的指針。重做。 您可以在 Microsoft 的文檔中找到有關編組和互操作的信息(例如https://learn.microsoft.com/en-us/do.net/framework/interop/marshalling-different-types-of-arrays )。 如果您的紋理始終保證具有相同的大小和格式,那么它會更容易 - 但如果您需要了解一些額外的參數以便您知道紋理應該如何在托管土地中表示,您可以隨時將額外的數據傳遞給自己通過同樣的方法。

暫無
暫無

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

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