api-independent data

Started by
11 comments, last by Psybr 21 years, 8 months ago
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?
Advertisement
I don''t know much about d3d but if you want to have an engine that supports d3d and ogl then you could use d3d stuctures but it''s probably better that you create your own stuctures.
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
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)
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.
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]
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]
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)?
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
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

Simon O'Connor | Technical Director (Newcastle) Lockwood Publishing | LinkedIn | Personal site

This topic is closed to new replies.

Advertisement