0
\$\begingroup\$

I'm trying to write a map editor for a unity game using openGL. In order to do that, I need to unpack it's resource files to get meshes, textures and other good stuff.

In doing so, I've discovered that unity mesh asset stores vertices, normals, texture data, and any other per-vertex type data in one interleaved array.

I have two choices here. First is to leave the data as is and push it into a single VBO and then use attrib pointer to adjust strides and whatnots to make it work. When I read data from file into memory, I can just read whole array with a single ifstream::read method call.

Second choice is to unravel all data into it's separate channels and have a separate VBO for each data type. I personally prefer it this way, but this means that I need to deinterleave that array. I'm unsure how to do this efficiently. The most obvious way (and very inefficient) is to read it char by char and store each char in appropriate array, depending on channel structure. I could maybe mess with it a bit and set it up to read it channel per channel (meaning 2-4 chars at once) instead of char by char. This still seems very slow to me.

Maybe I could load the whole array into memory and then deinterleave it there, but I'm still unsure of method that would be fast.

The priority is for the program to be fast while drawing, and deinterleaved multiple VBO setup is said to be faster due to lesser amount of cache misses.

To give you a sense of numbers, the game I'm looking at contains about 2630 different mesh assets, with each containing an estimated average of 500 vertices.

How do I deal with this? I will be loading all this data just once on program startup anyway, so it doesn't have to be super fast, but I don't want to force the user to wait for too long even then. Maybe number of vertices altogether is small enough for it to be very fast regardless, but I don't want to commit to either way before I have some idea of what I'm doing.

Bottom line is, should I just leave it interleaved, or is there some efficient way to deinterleave it? Am I jumping the train here, being scared of leaving it interlaved? I know I should probably benchmark both cases, but both cases are drastically different in my case and would require huge code changes, not to mention I'm nowhere close to actually drawing the scene I need to.

\$\endgroup\$
3
\$\begingroup\$

not to mention I'm nowhere close to actually drawing the scene I need to -

So then do you really want to spend extra time on data transformations, when you could be working on getting the scene drawing?

Make it work first. Then you'll know if performance is impacted heavily enough to be worth budgeting time to change the VBO format. Otherwise you might be sinking extra time into data transformation code for no tangible benefit at all.

You already have one data point suggesting the format is OK as-is: your Unity app appears to use it this way with acceptable performance.

\$\endgroup\$
  • \$\begingroup\$ Fair enough. I'll implement it as is and then see how it does. \$\endgroup\$ – Karlovsky120 Jul 9 '18 at 21:13
  • \$\begingroup\$ This answer has good general wisdom. As a minor aside -- deinterleaving the data of about a million vertices in memory would not be very expensive either. \$\endgroup\$ – david van brink Jul 20 '18 at 14:56

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.