2016-09-13 4 views
0

Я пытаюсь нарисовать RenderTexture в Texture2D с целью сохранения его на диск. Этот подход работает в редакторе OSX, а также на Android.iOS зависает при вызове Texture2D.readPixels

Я не вижу каких-либо ошибок в консоли XCode, и мое приложение становится полностью заморожен, когда я звоню Texture2D.ReadPixels()

Вот краткое описание кода:

// declaring variables... 
    RenderTexture outputTexture; 
    RenderTextureFormat RTFormat = RenderTextureFormat.ARGB32; 

    // use an appropriate format for render textures 
    if(SystemInfo.SupportsRenderTextureFormat(RenderTextureFormat.ARGBFloat)){ 
     RTFormat = RenderTextureFormat.ARGBFloat; 
    }else if(SystemInfo.SupportsRenderTextureFormat(RenderTextureFormat.ARGBHalf)){ 
     RTFormat = RenderTextureFormat.ARGBHalf; 
    } 

    // create instance of output texture 
    outputTexture = new RenderTexture (res.x, res.y, 0, RTFormat); 

    // in Update, draw stuff to outputTexture 
    Graphics.Blit (outputTexture, canvasTexture); 
    Graphics.Blit (canvasTexture, outputTexture, material); 

    // later... user wants to save the image 
    // draw rendertexture to a Texture2D so we can write to disk 
    RenderTexture.active = outputTexture; 
    tmpTexture = new Texture2D (outputTexture.width, outputTexture.height, TextureFormat.ARGB32, false); 
    tmpTexture.ReadPixels (new Rect (0, 0, outputTexture.width, outputTexture.height), 0, 0, false); 
    tmpTexture.Apply(); 
    RenderTexture.active = null; 

Я попытался с помощью различных RenderTextureFormat и TextureFormat, но ничего не работает!

+0

Где вы звоните по этому коду? Это внутри пользовательской функции или метода обратного вызова Unity? –

+0

Также, на каком устройстве вы тестируете? Проверьте, нет ли у вас памяти. RenderTexture - дорогой метод. –

ответ

1

Я считаю, что это вызвано вызовом формы текстуры рендера. Что-то подобное случилось раньше.

Этот бит кода присваивает формат текстуры по умолчанию, а затем изменяет формат по умолчанию, если в данный момент выполняет среда поддерживает (мои комментарии будут добавлены)

//set a default render texture of RenderTextureFormat.ARGB32; 
RenderTextureFormat RTFormat = RenderTextureFormat.ARGB32; 

// if my system supports it, switch to either ARGBFloat or ARGBHalf 

// use an appropriate format for render textures 
if(SystemInfo.SupportsRenderTextureFormat(RenderTextureFormat.ARGBFloat)){ 
    RTFormat = RenderTextureFormat.ARGBFloat; 
}else if(SystemInfo.SupportsRenderTextureFormat(RenderTextureFormat.ARGBHalf)){ 
    RTFormat = RenderTextureFormat.ARGBHalf; 
} 

Однако, когда вы на самом деле позже определить вашу временную текстуру заправить readPixels(), вы только определить его в одну сторону (опять же, добавляемые мои комментарии)

//define a new tmpTexture container, ALWAYS with a TextureFormat of ARGB32 
tmpTexture = new Texture2D (outputTexture.width, outputTexture.height, TextureFormat.ARGB32, false); 

Таким образом, на некоторых системах (в зависимости от того поддерживает формат), вы пытаетесь readPixels() из одного формата текстуры в другой. Вероятно, это вызывает вашу проблему.

Вы можете исправить это, также динамически меняя формат текстуры назначения. Таким образом, в первом разделе, вы бы изменить его на:

RenderTextureFormat RTFormat = RenderTextureFormat.ARGB32; 

//add another variable here for the destination Texture format 
var destinationFormat = TextureFormat.ARGB32; 


// use an appropriate format for render textures 
if(SystemInfo.SupportsRenderTextureFormat(RenderTextureFormat.ARGBFloat)){ 
    RTFormat = RenderTextureFormat.ARGBFloat; 

    //also set destination format 
    destinationFormat = TextureFormat.RGBAFloat; 
}else if(SystemInfo.SupportsRenderTextureFormat(RenderTextureFormat.ARGBHalf)){ 
    RTFormat = RenderTextureFormat.ARGBHalf; 

    //also set destination format 
    destinationFormat = TextureFormat.RGBAHalf; 
} 

, а затем, конечно, позже потребляют динамически установленный формат при объявлении объекта назначения:

//define a new tmpTexture container, with a dynamically set destination format that always matches the input texture 
tmpTexture = new Texture2D (outputTexture.width, outputTexture.height, destinationFormat, false); 

Позвольте мне знать, если вы все еще есть вопросы в комментариях.

+0

Ничего себе, спасибо за такой подробный пост. Мой вопрос оказался очень простым, и вы помогли мне это увидеть. Я попробовал установить для параметра назначенияFormat значение TextureFormat.RGFloat! На самом деле я немного озадачен тем, что он работал на Android, несмотря на эту вопиющую ошибку. Я собираюсь отправить редактирование на ваш ответ, для точности и потомства. –

+0

Извините, я упреждающе принял ваш ответ. Я получил его для запуска один раз, но потом восстановление с тем же кодом снова не удалось. –

+0

То же самое, ничего в выходе XCode? И все еще работает на Android? – HBomb

Смежные вопросы