Можете ли вы писать на текстуру Unity из плагина iOS C "на месте"? - PullRequest
0 голосов
/ 15 января 2019

Скажем, у вас есть низкоуровневый плагин Unity для iOS,

Так что в с #

using System.Runtime.InteropServices;
using AOT;

public class Teste: MonoBehaviour {

    [DllImport("__Internal")] private static extern
       void set_texture_from_unity(System.IntPtr texture, int w, int h);

иметь текстуру, .Apply() ее, а затем отправить указатель на родной плагин iOS:

public void ClickPassTexture() {

    tex = new Texture2D(256, 256, TextureFormat.ARGB32, false);
    tex.filterMode = FilterMode.Point;

    tex.Apply(); // ACTUALLY UPLOAD TO GPU

    someMaterial.mainTexture = tex;

    set_texture_from_unity(
       tex.GetNativeTexturePtr(), tex.width, tex.height);
}

enter image description here

Теперь код С.

Создайте текстуру из нескольких цветных линий и запишите ее в текстуру Unity.

#include <OpenGLES/ES2/gl.h>
...
void set_texture_from_unity(void *g_TextureHandle,  int w, int h)) {

    // make a texture with a few gray rows
    unsigned char* data = malloc( g_TextureWidth * 4 * g_TextureHeight );
    for (int i = 0; i < 1000; ++i) { data[i] = 100; }

    // now, write that to the texture pointer given to us from Unity
    GLuint gltex = (GLuint)(size_t)(g_TextureHandle);
    glBindTexture(GL_TEXTURE_2D, gltex);
    glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0,
      g_TextureWidth, g_TextureHeight, GL_RGBA, GL_UNSIGNED_BYTE, data);

    free(data);

Итак, в коде C мы, казалось бы, успешно изменили текстуру tex.

Тем не менее.

Не отображается на экране.

enter image description here Изображение показывает полную невозможность чего-либо достичь вообще.

Прекрасное Unity doco docs.unity3d.com / Руководство / NativePluginInterface.html

дает пример, где изменение текстуры C вызывается обратным вызовом в цепочке рендеринга Unity .

Тем не менее.

Можем ли мы просто заставить Unity взять новую текстуру "сейчас"?

Когда мы хотим?

Я думал, что это может просто сработать:

    set_texture_from_unity( tex.GetNativeTexturePtr(),
          tex.width, tex.height);
    // the plugin has changed the texture...
    // perhaps an Apply will change it on screen?!
    tex.Apply();

Но нет! (Не имеет значения, если вы подождете несколько кадров до .Apply.)

Можно подумать, .Apply снова отправит текстуру в графический процессор, но, похоже, она не работает.

Короче, что делать с представленным кодом, чтобы он показывал новую текстуру "тут и тогда", после запуска плагина C ??

Когда вы знаете, что текстура была изменена плагином C, это на iOS, как заставить Unity отображать изменения ???

Ответы [ 2 ]

0 голосов
/ 11 апреля 2019

Решение в «новом» Unity

(легендарный) Кейдзиро Такахаши из Unity Japan опубликовал, пожалуй, самую важную вещь, когда-либо опубликованную Unity:

https://github.com/keijiro/TextureUpdateExample

Фактический пример ( new ) обновления текстур в рамочном стиле из плагина.

И ЭТО РАБОТАЕТ С IOS

Опять же, все, что можно сказать, это в значительной степени самая ценная вещь, когда-либо испущенная Единством! Уф!


Что касается поставленного вопроса, то я действительно никогда не находил решения.

0 голосов
/ 15 января 2019

Вам необходимо вызвать UpdateExternalTexture метод.

Обновляет текстуру Unity для использования другого нативного объекта текстуры.

Эта функция в основном полезна для плагинов собственного кода, которые создают специфичные для платформы объекты текстуры вне Unity, и должны использовать эти текстуры в сценах единства. Для текстуры, созданной с CreateExternalTexture, эта функция переключается на другой базовый объект текстуры, если / когда он изменяется.

...