Archived

This topic is now archived and is closed to further replies.

Psybr

api-independent data

Recommended Posts

I have an engine that currently runs on Direct3D, but I would like it to be able to support OpenGL also. Early on in the porting process, I realized that most of the structures I used were Direct3D-specific (e.g. D3DVECTOR). I don''t know much about OpenGL, right now all I can do is initialize it ;-). Can I keep the data structures, or would I have to change them. For instance, use a wrapper class, write my own class, or leave them as-is?

Share this post


Link to post
Share on other sites
OpenGL is rather flexible when it comes to vertex structure definitions. You should be able to get it working on pretty much any imaginable vertex memory layout, if you respect some simple guidelines about the underlying datatypes. You should perhaps investigate a bit further in OpenGL''s vertex array mechanisms at this point, if you''ll eventually port your engine to OGL at a later point.

But keep in mind, that mixing D3D and OGL is generally a bad idea, even if it''s only about some type definitions. It''s possible (and some people actually use eg. D3DX and OGL), but I wouldn''t recommend it. Use D3D datatypes for D3D apps, OpenGL datatypes for OGL apps, and your own types/structures for a portable engine. Using D3D types with OGL will seriously limit portability, one of the main advantages of using OpenGL in the first place...

/ Yann

Share this post


Link to post
Share on other sites
I was talking about creating a portable engine. Sorry if that wasn''t clear.

Would you happen to have information on creating personalized data structures? (e.g. a web page that outlines what''s needed, or source code)

Share this post


Link to post
Share on other sites
Your data structures should have what you need. A basic vertex structure, matrix structure, etc. You can mimick a lot of the existing D3D or OGL data structures for starters, if you really have no idea where to start.

Share this post


Link to post
Share on other sites
If you're creating a portable engine why not just use ogl. Saves you having to right the same routines in two different api's.

Oh and check this libary out SDL It as a very portable libary if you use this and ogl right you could compile your code on say linux and windows with no changes. Oh and it supports a lot of other platforms as well. It's also very easy.

[edited by - Monder on July 27, 2002 7:58:26 AM]

Share this post


Link to post
Share on other sites
quote:

Would you happen to have information on creating personalized data structures?


Hmm, well, put in what you need

For example, a simple vertex structure could look like this:

      
typedef struct {
float x, y, z;
} MyVector;

typedef struct {
float s, t;
} MyTexCoord;

typedef struct {
char r, g, b, a;
} MyColour;


typedef struct {
MyVector position; // the vertex 3D position

MyTexCoord texture_coords[4]; // texture coordinates for 4 units

MyColour colour; // vertex colour


// add optional data as needed, eg. for vertex/pixelshaders:

char fog_coord; // fog coordinate

MyVector refractive_displace; // ;)

// etc, whatever else you need...

} MyVertex;



This structure is a simple, but very wasteful one (in terms of memory). In a real-world engine, you would use the smallest datatypes that still work, simply because they save memory (esp. precious AGP/Vidmem). Now, I'm not very much into D3D, so I don't know if that type of structure will work there. It definitely will work in OpenGL, though.

Another point to consider, when talking about portability: how far does it need to go ? The above structure will almost certainly fail, if you try to compile it on a machine, where eg. the float type is 64bit. Or if you want to compile your structures on eg. a Mac, then you'll have to take endianness into account (which can be a real pain in the ass, btw). Let's state it like this: simple custom datastructures will be portable to any OS, but be more or less restricted to the x86 platform.

Besides that, I strongly suggest reading some OpenGL basics up first (eg. the redbook). You don't need to know everything yet, but it'll give you an idea on what type of data OpenGL expects/accepts. That way, you'll be able to create structures that will satisfy OpenGL as well as D3D.

Example would be matrices: although both OGL and D3D accept a matrix as 16 floating-point values, the representations are transposed. Simply means, that D3D matrices will not work in OpenGL and vice-versa. You'll have to transpose them manually, or let an OpenGL extension do that. So, there are some small differences here and there, nothing really problematic, but very important, esp. if you want to save yourself some headaches and lots of hours in the debugger...

/ Yann

[edited by - Yann L on July 27, 2002 8:48:10 AM]

Share this post


Link to post
Share on other sites
quote:

What kind of data types would you suggest using instead of floats? Wouldn''t you be sacrificing speed for mem usage if you used another data type(well with OGL anyway)?


Depends. Using smaller datatypes does not negatively impact speed, in fact it will most likely increase performance. Data conversion isn''t done by OpenGL, it''s done by dedicated hardware on the 3D board.

I would suggest using shorts for texture coordinates (in some special cases, you can even use chars), or shorts for vertex coordinates.

/ Yann

Share this post


Link to post
Share on other sites
Yann wrote:

quote:

Now, I''m not very much into D3D, so I don''t know if that type of structure will work there. It definitely will work in OpenGL, though.




With D3D vertex shaders, the vertex format you post would be just fine (since the programmer gets to decide how the stream input data is formatted). However, with the D3D fixed function pipe , there are a few things which would cause issues:

1. Texture coordinates always come at the end of the vertex with FFP

2. D3D colours in current D3D versions are ARGB rather than RGBA with FFP.

3. Hanging extra data off the vertices isn''t generally so good because fixed function vertices map directly to whatever the hardware supports per vertex, the API won''t do any stripping (unless you use strided vertices which are hideous to performance).



The method which is commonly used for cross platform (PS2<->NGC<->PC<->Xbox) stuff in the games world is to keep the outward engine API the same across all platforms, but pre-format the *data* for each platform. The preformatting does things like texture conversion and swizzling, vertex conversion etc
This would work in most cases for D3D/OpenGL too. The pre-formatting is usually done as an offline process (export time etc), but can easily be done at load time if space is an issue.

The key to pre-formatting is to assume that the client application using the data never assumes "raw ownership" of that data, instead, it gets say a handle back which it uses to refer to a specific bunch of vertices, but never a direct pointer. If a client app needs to fiddle with vertices in realtime, it has to do so via some form of locking which either converts to a platform independent form or pulls up a cached platform independent form.

--
Simon O''Connor
Creative Asylum Ltd
www.creative-asylum.com

Share this post


Link to post
Share on other sites
Wow, thanks! I didn''t know about the Direct3D/OpenGL matrix difference, which might have taken me a while to figure out. As far as going cross-platform, I just expected to have code that is API independent, so that it ports easily between Windows and say Mac.

Share this post


Link to post
Share on other sites
quote:

With D3D vertex shaders, the vertex format you post would be just fine


Good to know

quote:

The method which is commonly used for cross platform (PS2<->NGC<->PC<->Xbox) stuff in the games world is to keep the outward engine API the same across all platforms, but pre-format the *data* for each platform. The preformatting does things like texture conversion and swizzling, vertex conversion etc


Hmm, yes, I know that this is rather common. Doesn't change the fact that I don't like it

While it's OK on static geometry, it's problematic on dynamic geometry: it creates an additional abstraction layer between your dynamic vertex feed and the 3D card. On higher level structures (eg. matrices), that's no problem. But on a lowlevel vertex structure, which is one of the most important keypoints to good performance, it is unacceptable IMO.

Imagine a vertex animation system running on the CPU (skinning, cloth simulation, water NSE, etc). For best performance, you'd need direct access to the vertex structure. Two possibilities:

1) Use a compatibility layer, doing needed data conversions on the fly. Lethal for performance.

2) Code a seperate animation module for every vertex format used. Ouch. Especially, since mesh animation code is normally not part of the api-dependent render core, but more of the api-independent physics/animation engine...

I still think, that a unified vertex format is the best option.

/ Yann

[edited by - Yann L on July 27, 2002 1:25:13 PM]

Share this post


Link to post
Share on other sites
Do you think that Microsoft''s FVF is a good idea? And would it be feasible to write something similar for my engine, or should I just stick to a unified vertex format?

Share this post


Link to post
Share on other sites