Is there a 3D binary format that matches CUSTOMFVF directly?

Started by
8 comments, last by InvalidPointer 12 years ago
Hello,

Sorry if this is in the wrong category but I'm not sure where it belongs as it spans multiple topics in a way.
I managed to learn direct3D on my own with the tutorials and online forums etc but I have a question that may perhaps save me some time re-inventing the (possibly square) wheel.

So far I can create simple objects, light them, animate them, texture them and what have you. No real problems there.
I realised that .x files, although convenient for a start, aren't the way to go for more professional use so I started to get interested in
how to get mesh information inside my executable without the need to open many external files and/or requiring complex parsers etc.
I already solved the problem for textures loading them as resources and retrieving the pointer.
I only code in C and assembler by the way. (I don't find it harder, I'm allergic to OOP.)

So I mostly use the CUSTOMFVF structure but here is the problem I want to avoid: long lists of comma separated values in my source (or even external includes for that matter) since a structure is really just a fancy array [of floats in this case] and in the exectable it will end up as binary representations of floats i.e. CD CC 4C 40 CD CC 4C 40 ..... (keep in mind little endianness on top of that) and so once I get an export format in this form I'll use resources too. (I'm a big fan of them LOL)

There seems to be export formats that are in binary but... they keep vertices, normals, UV coords separate from each other and I need them grouped by vertex as in the FVF struct format. i.e. {float x, float y, float z, float n0, float n1, float n2, float U, float V};
I could possibly create my own converter although it's a sidestep that would take me some time and I might re-invent the wheel if an exporter has the exact format I describe, which is in fact the actual question: Is there one? (All 3D packages can be considered)

PS: I only tried binary .x, Wavefront OBJ, COLLADA in DeleD. None suited my needs.
Advertisement
I'm not too familiar with the .x file format, but I would have expected that it would have the entire vertex buffer in one chunk, rather than split up into position, colour, UV, etc streams? It's DirectX-specific, so it should surely be in the most optimal format for D3D?
I think I may not have phrased it properly.
What I mean to say is that the .x file (but many other files too) will have the vertex list in one category/chunk i.e. 'Mesh' followed by the vertices. Then another chunk will have (the string) 'normals' followed by the normals then one more chunk with 'textures' followed by UV coordinates. It works automatically with X-related functions which are the very funcs I want to avoid as they are said to be deprecated and slow. (not to mention unprofessional - games don't use them, and I like self-contained exe's rather than have all my assets visible as separate files)
The thing I want is the CUSTOMFVF format, i.e. NO CHUNKS, just a series of rows with vertex coords + normal vects + UV coords intertwined like this, since this is how the fixed pipeline accepts the data. (indices, if used, are needed separately so it's not an issue here)
Maybe another way to phrase it is that I need the rawest binary format possible with he least amount of overhead, headers, checksums, compression, hierarchical trees and what not. (for simple static objects)
In this case it is the best to create your own format based on the needs of your application. Let's say your meshes are in following format:

each vertex:
Vec3 position
Vec3 normal
Vec2 uv

than it is easy to output your mesh from an aplication such as maya/3d studio max, or to convert formats such as obj into your own format outside of your application. What you have to do is to create the vertex buffer and save it as binary.

The final format in binary could look something like this:

int numberOfvertices
int vertexSize (in char)
{vertices}
int numberOfIndices
{indices}

It is as simple as that, I have done it for my meshes, and it speeds up the loading dramatically, as there is no or little parsing done, and vertex data and index data can be sent straight to directx to create buffers.

I hope this helps.

Hello,

Sorry if this is in the wrong category but I'm not sure where it belongs as it spans multiple topics in a way.
I managed to learn direct3D on my own with the tutorials and online forums etc but I have a question that may perhaps save me some time re-inventing the (possibly square) wheel.

So far I can create simple objects, light them, animate them, texture them and what have you. No real problems there.
I realised that .x files, although convenient for a start, aren't the way to go for more professional use so I started to get interested in
how to get mesh information inside my executable without the need to open many external files and/or requiring complex parsers etc.
I already solved the problem for textures loading them as resources and retrieving the pointer.
I only code in C and assembler by the way. (I don't find it harder, I'm allergic to OOP.)

So I mostly use the CUSTOMFVF structure but here is the problem I want to avoid: long lists of comma separated values in my source (or even external includes for that matter) since a structure is really just a fancy array [of floats in this case] and in the exectable it will end up as binary representations of floats i.e. CD CC 4C 40 CD CC 4C 40 ..... (keep in mind little endianness on top of that) and so once I get an export format in this form I'll use resources too. (I'm a big fan of them LOL)

There seems to be export formats that are in binary but... they keep vertices, normals, UV coords separate from each other and I need them grouped by vertex as in the FVF struct format. i.e. {float x, float y, float z, float n0, float n1, float n2, float U, float V};
I could possibly create my own converter although it's a sidestep that would take me some time and I might re-invent the wheel if an exporter has the exact format I describe, which is in fact the actual question: Is there one? (All 3D packages can be considered)

PS: I only tried binary .x, Wavefront OBJ, COLLADA in DeleD. None suited my needs.


You can render (hurp durp) most of your concerns irrelevant in this case if you use the recommended vertex declaration method instead of the rather inexpressive FVF approach. The 'streams' idea works without any modification, but you can also take the 'chunks' approach if it's advantageous for your use case(s).

As a side note-- kick that OOP allergy. You *really* aren't doing yourself any favors. It's possible to do it wrong, yes, but chances are if you find it problematic you just aren't approaching things the right way.

EDIT: Hmm. Upon some closer inspection, I'm not sure if the fixed-function pipeline eats D3DVERTEXELEMENT9s, though I would honestly advocate ditching the FFP anyway if you're interested in speed/expressiveness. It's been emulated by shader hardware since like 2004 and shader support in general is so incredibly widespread compatibility isn't even a concern. Mobile phones now support them(!)
clb: At the end of 2012, the positions of jupiter, saturn, mercury, and deimos are aligned so as to cause a denormalized flush-to-zero bug when computing earth's gravitational force, slinging it to the sun.
The FFP can handle declarations, but I must admit that I've never tried to use one with it that couldn't also be expressed by an FVF code. For the vast majority of use cases that's entirely satisfactory though.

Direct3D has need of instancing, but we do not. We have plenty of glVertexAttrib calls.




The 'streams' idea works without any modification, but you can also take the 'chunks' approach if it's advantageous for your use case(s).

As a side note-- kick that OOP allergy. You *really* aren't doing yourself any favors. It's possible to do it wrong, yes, but chances are if you find it problematic you just aren't approaching things the right way.



Streams! Thanks I think that was what I was looking for if I want to leave them as chunks.
As for OOP yeah it's probably better for productivity once you get it but since I like to understand things deep under the hood I find that it hides everything in a black box. (which I believe is its purpose in the first place)

[quote name='InvalidPointer' timestamp='1332875104' post='4925776']
The 'streams' idea works without any modification, but you can also take the 'chunks' approach if it's advantageous for your use case(s).

As a side note-- kick that OOP allergy. You *really* aren't doing yourself any favors. It's possible to do it wrong, yes, but chances are if you find it problematic you just aren't approaching things the right way.



Streams! Thanks I think that was what I was looking for if I want to leave them as chunks.
As for OOP yeah it's probably better for productivity once you get it but since I like to understand things deep under the hood I find that it hides everything in a black box. (which I believe is its purpose in the first place)
[/quote]

There are a handful of other advantages to using stream-style data mostly involving data locality, and it integrates much, much better with concepts like instancing. Like I said, if you need the array of structures format then go for it, don't make blanket decisions unless you have some hard data.

Re: OOP-- In no particular order, OOP is about gathering functionality into single cohesive wholes for ease of modification, reducing coupling between different areas of a program ('black boxen' is sort of correct, but I don't think it's really the right mindset to enter into) and increasing code reuse, though that last benefit is rather overstated in practice. If you think the ideas behind data-oriented design are neat (I do!) they're very much not incompatible with OOP. Using objects and creating effective designs has little to no bearing on the number of virtual function calls you make during the course of a frame, and in fact many of the best examples of good design don't even involve virtual function calls, see also Andrei Alexandrescu and his excellent work on policy-based design. ;) [size=1](yeah, yeah, it's technically a little closer to to aspect-oriented programming, hush.)
clb: At the end of 2012, the positions of jupiter, saturn, mercury, and deimos are aligned so as to cause a denormalized flush-to-zero bug when computing earth's gravitational force, slinging it to the sun.
Lack of data locality is actually a disadvantage of separate streams if you're talking hardware T&L; it's only advantageous with software T&L. The real advantage of separate streams is to be able to drop unused attributes out if you are using different shaders on the same objects (and even then you should measure streamed vs interleaved to be absolutely certain that it pays off in your own use case).

Direct3D has need of instancing, but we do not. We have plenty of glVertexAttrib calls.


Lack of data locality is actually a disadvantage of separate streams if you're talking hardware T&L; it's only advantageous with software T&L. The real advantage of separate streams is to be able to drop unused attributes out if you are using different shaders on the same objects (and even then you should measure streamed vs interleaved to be absolutely certain that it pays off in your own use case).


Considering that most, if not all GPUs I'm aware of lack fancy high-level caching mechanisms for the input assembler (or I'm just totally dense and missed them) I think this really is a function of the width of your attributes in question-- if you can 'line up' individual elements so that they're wholly fetched with no waste, I'd think that any gap would disappear, no?
clb: At the end of 2012, the positions of jupiter, saturn, mercury, and deimos are aligned so as to cause a denormalized flush-to-zero bug when computing earth's gravitational force, slinging it to the sun.

This topic is closed to new replies.

Advertisement