Sign in to follow this  
rikibee

[.net] Simple question about unserializing an array of floats

Recommended Posts

rikibee    122
I'm doing some experiments with the Tao framework to use OpenGL with C#. Yet my problem is not related directly to OpenGL, it's just that doing OpenGL is one of the situation I came to meet this problem. I have a model file which contains vertex data, index data, texcoords, and so on. Now I made a simple class which reads this file and returns the data that is associated with a particular section of the file. For example, if I ask the FileReader to look for the vertices section, the class returns an array of bytes containing the whole piece of vertex data. Now I got some generic byte[] array. I want to be able to convert that array into the actual data. For vertices, this will be an array of floats. Is there a very casting-like operation I could do in order to get a float[] object from a byte[] object? My guess is that C# is so strongly typed that such operation is not allowed, but I am not sure. I know one solution that would be using the BitConverter class, but will I need to iterate through the byte array and convert them to floats one-by-one? Thanks.

Share this post


Link to post
Share on other sites
rikibee    122
Thanks,

As you suggest, I will try to go straight from the FileStream to get the floats using ReadSingle() of BinaryReader.

However, must I understand that there are no mechanism that exists in .NET that would allow me to read a block of floats in one call from binary data? I would have liked to have a method that does that the same thing as BinaryReader.ReadBytes but for floats.


Share this post


Link to post
Share on other sites
rikibee    122
Quote:
Original post by TheTroll
Why don't you just use the serialize functions built into .Net?


That sounds good, but I don't want to have the file format depend on the way .NET does its serialization on objects.

.NET serialization would be an obvious choice if I had to save a model to a file and load it back within the same class. But I don't have (i.e. don't want to have) control over the file format, I just want to load chunks of data from an already-defined file format.

Thanks for your help.

Share this post


Link to post
Share on other sites
kanato    568
Probably the best option is to just use a BinaryReader.ReadSingle when loading the file format, and just loop over how many you need to read.

If you have a lot of data to read and this is performance-critical code, then you might try reading it into a byte[] and then use Marshal.AllocHGlobal to allocate a temporary block of unmanaged memory, Marshal.Copy to copy data from the byte[] to the unmanaged memory and then back to a float[] (then use Marshal.FreeHGlobal to free the unmanaged memory).

Another option is to use unsafe code to get a pointer to the byte array and use Marshal.Copy to copy it into the float array. That's one less copy, but it involves using unsafe code, which may or may not perform better.

I'd strongly recommend using the first option until you are sure that it's a performance bottleneck (through profiling), then try something more complicated.

Quote:
You do realize you can use the ISerialisable interface and read and write in pretty much any format you want, right?


Implementing ISerializable allows you to control which / how the internal data of a class is serialized, but it's the formatter that really produces the byte stream. For instance, the BinaryFormatter stores a great deal of extra information about types in the file, and its file format allows for multiple reference to a single object, so that when things are deserialized objects aren't unnecessarily duplicated.

If you want to use the .NET serialization to do this, you'd have to write your own Formatter (implementing IFormatter) in addition to implementing ISerializable on the objects that represent the data. If you don't have control over the file format, and especially if you are only deserializing (like if you are reading md2 or bsp files or something), then I'd imagine this route would end up taking a lot more time and coding effort.

Share this post


Link to post
Share on other sites
rikibee    122
I decided to use the ReadSingle in a loop as some of you have suggested.

I appreciated the extra info, kanato. I will follow your advice to make it simple and test if it works for me.

regards

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this