xamarinxamarin.formsurhosharp

Add a texture on a sphere by Urhosharp


I'm using Xamarin.Forms + Urhosharp, I've got a problem to set texture from an image on a sphere. The problem is that texture.Load or texture.SetData always returns false. I did try different methods like SetData, Load, resize texture and image (to a power of 2 number) and ... but none of them worked. Here is my code:

    private async void CreateScene()
    {
        Input.SubscribeToTouchEnd(OnTouched);

        _scene = new Scene();
        _octree = _scene.CreateComponent<Octree>();

        _plotNode = _scene.CreateChild();
        var baseNode = _plotNode.CreateChild().CreateChild();
        var plane = baseNode.CreateComponent<StaticModel>();
        plane.Model = CoreAssets.Models.Sphere;

        var cameraNode = _scene.CreateChild();
        _camera = cameraNode.CreateComponent<Camera>();
        cameraNode.Position = new Vector3(10, 15, 10) / 1.75f;
        cameraNode.Rotation = new Quaternion(-0.121f, 0.878f, -0.305f, -0.35f);

        Node lightNode = cameraNode.CreateChild();
        var light = lightNode.CreateComponent<Light>();
        light.LightType = LightType.Point;
        light.Range = 100;
        light.Brightness = 1.3f;

        int size = 3;
        baseNode.Scale = new Vector3(size * 1.5f, 1, size * 1.5f);

        var imageStream = await new HttpClient().GetStreamAsync("some 512 * 512 jpg image");
        var ms = new MemoryStream();
        imageStream.CopyTo(ms);

        var image = new Image();
        var isLoaded = image.Load(new MemoryBuffer(ms));
        if (!isLoaded)
        {
            throw new Exception();
        }

        var texture = new Texture2D();
        //var isTextureLoaded = texture.Load(new MemoryBuffer(ms.ToArray()));
        var isTextureLoaded = texture.SetData(image);
        if (!isTextureLoaded)
        {
            throw new Exception();
        }

        var material = new Material();
        material.SetTexture(TextureUnit.Diffuse, texture);
        material.SetTechnique(0, CoreAssets.Techniques.Diff, 0, 0);
        plane.SetMaterial(material);

        try
        {
            await _plotNode.RunActionsAsync(new EaseBackOut(new RotateBy(2f, 0, 360, 0)));
        }
        catch (OperationCanceledException) { }
    }

Please help!


Solution

  • To Create a material from a 2D Texture, you can use Material.FromImage .

    Refer following documentation for more detail.

    model.SetMaterial(Material.FromImage("earth.jpg"));
    

    https://developer.xamarin.com/api/type/Urho.Material/ https://developer.xamarin.com/api/member/Urho.Material.FromImage/p/System.String/

    private async void CreateScene()
    {
    
    
       _scene = new Scene();
       _octree = _scene.CreateComponent<Octree>();
    
       _plotNode = _scene.CreateChild();
       var baseNode = _plotNode.CreateChild().CreateChild();
    
    
       var plane = _plotNode.CreateComponent<StaticModel>();
       plane.Model = CoreAssets.Models.Sphere;
       plane.SetMaterial(Material.FromImage("earth.jpg"));
    
       var cameraNode = _scene.CreateChild();
       _camera = cameraNode.CreateComponent<Camera>();
       cameraNode.Position = new Vector3(10, 15, 10) / 1.75f;
    
       cameraNode.Rotation = new Quaternion(-0.121f, 0.878f, -0.305f, -0.35f);
    
       Node lightNode = cameraNode.CreateChild();
       var light = lightNode.CreateComponent<Light>();
       light.LightType = LightType.Point;
       light.Range = 100;
       light.Brightness = 1.3f;
    
       int size = 3;
       baseNode.Scale = new Vector3(size * 1.5f, 1, size * 1.5f);
    
       Renderer.SetViewport(0, new Viewport(_scene, _camera, null));
    
       try
       {
           await _plotNode.RunActionsAsync(new EaseBackOut(new RotateBy(2f, 0, 360, 0)));
       }
       catch (OperationCanceledException) { }
    
    }