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:
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!
@ShahramShobeiri
For me the below works. As an image I used this (put to my Assets/Data/Textures folder).
using Urho; using Urho.Shapes; var app = SimpleApplication.Show(new ApplicationOptions("Data") { Width = 1280, Height = 800 }); app.Viewport.SetClearColor(Color.Black); app.Renderer.MaterialQuality = 15; var sphere = app.RootNode.GetOrCreateComponent<Sphere>(); var i = app.ResourceCache.GetImage("Textures/world.topo.bathy.200401.3x5400x2700.png"); var m = Material.FromImage(i); sphere.SetMaterial(m);
@puneetmahali
Nothing to explain. There are use cases when storing resources (images, textures, etc) is better than manage images dynamically.
But below is an (not optimized) example, how to download the image and use it as texture/material on the fly:
using Urho; using Urho.Resources; using Urho.Shapes; using System.Net; using System.Text; var url = "https://eoimages.gsfc.nasa.gov/images/imagerecords/73000/73580/world.topo.bathy.200401.3x5400x2700.png"; var wc = new WebClient() { Encoding = Encoding.UTF8 }; var app = SimpleApplication.Show(new ApplicationOptions("Data") { Width = 1280, Height = 800 }); app.Viewport.SetClearColor(Color.Black); app.Renderer.MaterialQuality = 15; try { var mb = new MemoryBuffer(wc.DownloadData(url)); var sphere = app.RootNode.GetOrCreateComponent<Sphere>(); var img = new Urho.Resources.Image(app.Context) { Name = "MyImage" }; img.Load(mb); var m = Material.FromImage(img); sphere.SetMaterial(m); } catch (Exception ex) { // do something when an error occurs }
Answers
Hi Shahram,
Can you please send the full project?
Hi @puneetmahali,
Here is the full project:
https://drive.google.com/file/d/1ZdV38I6OEyQ-HD8UA4OCNrGY3OPO4tjL/view?usp=sharing
What about to use Material.FromImage(string) method?
Thanks @laheller
It didn't work either, After Material.FromImage(string) sphere disappears and everything gets black.
@ShahramShobeiri
For me the below works. As an image I used this (put to my Assets/Data/Textures folder).
@laheller
Can you please explain more about (put to my Assets/Data/Textures folder), because if image will be fetch from url then why we need to put the image into the folder also. Because I want to show the multiple images or we can say dynamically.
@laheller
It would be so helpful If you share the working demo project.
@puneetmahali
Nothing to explain. There are use cases when storing resources (images, textures, etc) is better than manage images dynamically.
But below is an (not optimized) example, how to download the image and use it as texture/material on the fly:
@laheller
Thanks for quick reply.
Sounds Cool.
Is the above solution working/executable for both means iOS & Android for you?
Because it's not working and shows the error like failed to add resource path 'Data', check the documentation. I already give the build action BundleResource for iOS & EmbededResource for Droid.
So, It would be so helpful if you can share the executable demo.
Thanks in advance.
@puneetmahali
The app in my example is an instance of Urho.Application or Urho.SimpleApplication.
You have to create your one and use the rest from my example.
It should work on all platforms because of Xamarin
Thank you @laheller, You helped a lot,
My main goal was to create a 360 degree image viewer, I found a NuGet (Swank.FormsPlugin) for this goal but it didn't work for me, So based on Swank.FormsPlugin and @laheller solution, I created a very simple project to show 360 degree images that works!
Here is the project for @laheller
https://drive.google.com/file/d/1W64xybVTo_xzjb94E5AE_EO7eymB3Uwu/view?usp=sharing
@ShahramShobeiri
This is not working on iOS gives the OpenGl error - "Error: Could not create OpenGL context, root cause 'failed to create OpenGL ES drawable".
@puneetmahali
Is my second example working for you?
BTW I never tried any Xamarin.IOS, I develop only for Windows and Android.
Actually I am working on Indoor Maps. I want to load the 2D Indoor Map images into 3D viewer with 360 degree movement. I am using Texture with Sphere shape. But It's not display into the full screen and light shade also come.
Can you please help me to solve this problem.
Here is my example-
@puneetmahali
Are you working on a Windows Forms/WPF application, while you have no fullscreen?
If yes, you have to initialize your app using ApplicationOptions class.
Regarding to the second problem "light shade also come" please run your current app, make a screenshot and post it here, because it is not clear for me, what is the problem.
@laheller


No, I am working on shared forms for iOS & Android only. I already used ApplicationOptions-
public class MapPage : Urho.Application then creting a scene and all.
Now, my texture image loads like Image1 and I want to do display like Image2.
@puneetmahali
I am not familiar with Xamarin.iOS, never used.
I only develop on Xamarin.Android and WinForms platforms.
On Android if you want:
1. Fullscreen app in general, you have to specify a theme without ActionBar for your activity, for example @android:style/Theme.Holo.Light.NoActionBar or your custom style where you disable actionbar.
Then the whole device screen will be available for Activity layout(s) or other view.
2. For UrhoSharp you have to create the UrhoSurface within a fullscreen layout.
BTW I can't see your screenshots here.
Sorry @puneetmahali, I never tried any Xamarin.IOS, but it works on Android without problem.
One more thing, in the sample project, if you want to load image from URL it's better to use
var mb = new MemoryBuffer(wc.DownloadData(new Uri(url)));
because
var mb = new MemoryBuffer(wc.DownloadData(url));
didn't work for me.
@laheller

No, I am working on shared forms for iOS & Android only. I already used ApplicationOptions-
public class MapPage : Urho.Application then creting a scene and all.
Now, my texture image loads like Image1 and I want to do display like Image2.
@puneetmahali
I still cannot see your screenshots.
Upload them somewhere and share the links here.
https://expirebox.com/download/9a5b5b3c159325a5f82a609d6ec22495.html
https://expirebox.com/download/1517db15a4581c884ca2941697656b09.html
@laheller @ShahramShobeiri
We have some Urho shapes(Urho.Shapes) like Box, Sphere, Plane, Cone, Cylinder, Dome.....etc etc.
So I need to create a Static Component and loads the models into the above shape like below-
var plane = baseNode.CreateComponent();
plane.Model = CoreAssets.Models.Box;
That box provides the 3D view but now I want to load the image in a Square like a Simple ImageView through the texture. So, Which shapes will give me that shape also needs to think about Vector3 position who returns the view in the center.
Make it more Simple- I need to load an Image with texture in 2D view like a normal ImageView(square shape) in Xamarin.forms and It should work for both in iOS & Android.
@puneetmahali
Still not sure, what is your goal.
You want to display a Box shape and render different textures on its 6 surfaces?
@laheller
Are you able to download the Images?
No, I want to display the Image in a square shape and render different textures without 6 surfaces.
Please check your personal message also.
@puneetmahali
Then you have to:
Finally you have to transform (Rotate/Translate/Scale) your node to the final orientation/position/size.
@puneetmahali. @ShahramShobeiri. @laheller I have the same problem as you ("Failed to create texture"). Can you tell me how to do it.
Here is my sample.
@TuaNK Here is my working code: