DirectDraw & C++

Started by
16 comments, last by ROSS128 23 years, 7 months ago
quote:Original post by null_pointer


To the original poster:



null_pointer,
Thanks! You have given me some things to think about.

Phillip
Advertisement
Houdini:

If your set/get functions are just setting and getting the variable''s value, why have them? If you aren''t doing any sort of validation like this:


void something::set_x(int x)
{
if( x < 5 && x > 10 ) // check it first
throw "x is not in the right range!";

else this->x = x; // set it
}



Then why bother with the functions? Either add the validation (if you need it), or just make the int protected instead of private.


- null_pointer
Sabre Multimedia
DISCLAIMER! Let me flaunt my ignorance: I have never used DirectX (or any other graphics API other than windows GDI for that matter). It''s on my rather long list of "things to do", but there''s a bit of a resource allocation problem there, if you know what I mean.

My question: I thought DX uses COM, so you get interface classes. Wouldn''t it already be class-based then?

If not (i.e. if the COM interfaces don''t lend to objects well), I can''t believe there''s not a commercial C++ wrapper package out there. EVERYBODY uses DirectX (well, it seems lik eit anyway). Shouldn''t there be an OO package?
Nope, COM doesn''t support classes (at least not that can be directly accessed from outside the DLL). They do this for portability (it can be used in C, C++, VB, VB Script, etc). COM interfaces can basically (and I mean very basically) be thought of as seperate DLLs or modules inside one DLL. One interface has NOTHING to do with the others, they don''t even know about each other.
- Houdini
Stoffel: yea DX is class based... and yes its also COM... its an absolute mess... DX is designed to work for both games and application(like say Bryce or something)... wich means theres alot of crap in there that there doesn''t need to be... its a realy sloppy way of doing things if you ask me... so OO wrappers are written to help clean it up by us.... infact thats what I''m doing now =) rewrapping the whole DX API and packing alot of other stuff in there too =)

ROSS128:ummm go to my webpage... Got Milenko?
under my library section theres a few diffrent DX wrappers... both C and C++... ummmm heh like most of the site isn''t up yet but thats there =)....

Laterz

Great Milenko

Words Of Wisdom:
"Never Stick A Pretzel In Your Butt It Might Break Off In There."


http://www.crosswinds.net/~milenko
http://www.crosswinds.net/~pirotech

The Great Milenko"Don't stick a pretzel up your ass, it might get stuck in there.""Computer Programming is findding the right wrench to hammer in the correct screw."
Yeah, internally it''s probably all class-based (maybe even C++?), but (like everyone else said) to remain compatible with C and other languages they just make structs of function pointers (lpvtbl). I think they have an #ifdef __cplusplus in there to use classes if C++ is defined. Really, there are three major headaches with COM that could be handled quite easily with a wrapper library:

1. COM doesn''t use constructors/destructors per se, it has to be done manually.

2. You can''t create a COM object on the stack (which makes sense because of the linking).

3. COM objects use massive amounts of switch statements/return values instead of C++ exceptions. (ugh...)

So, I think a good start for a wrapper library would be:


class direct_draw
{
public:
direct_draw(/* parameters */) { DirectDrawCreateEx(/* parameters */); }
virtual ~direct_draw() { safe_release(lpdd); }

operator LPDIRECTDRAW7 () { return( lpdd ); }

private:
LPDIRECTDRAW7 lpdd;
};



Because you don''t have to rewrite all of the methods, and people can use the existing API docs (because every call is still made through the LPDIRECTDRAW7 object). It also solves problems #1 and #2 in that it handles destruction automatically. Of course, it doesn''t solve problem #3. The only unsafe call is using the conversion operator to call Release(), which there is never a need to do anyway - if you want control over which objects are released in what order, allocate the wrapper classes on the heap and call delete on them yourself.

(BTW, because you are using the same format for the member and operator for all of the DirectX objects, you might as well create a template class (com_wrapper) which you can just derive from with protected access. Saves typing, and the user knows that any class derived from that template will allow him to cast to his pointer type, etc.)

To write a really nice wrapper library, you''d have to check the return value after every call and decide whether or not to throw an exception (preferrably with your own com_exception class). Of course, this might set performance back a bit... However, writing a library is kind of tricky as people are very hard to please. I tried to write a Win32 API wrapper lib and didn''t like the result too well, so I scrapped it. It''s also very time-consuming!

Here are the problems I ran into:

1. My library didn''t do enough for programmers to justify its use!

2. It used tons of inline functions, friend classes, etc.

3. It took tons of time to write and maintain, and it was just different enough that I would have to write my own copy of the Win32 API documentation ().

The major problem was my lack of design. The library was good, didn''t leave any room for bugs (2- or 3-line functions!), and it was fast too, being mostly inline functions. The Win32 API is a real challenge for which to write wrapper classes. Here was my methodology for doing this:

1. Nearly every resource in Windows uses a handle, so for every handle type there should be a class. The handle is made private, with inline functions calling API functions with the handle. The user is not allowed access to the handle.

2. Instead of massive amounts of #defines and C-style struct definitions, I would use typedefs and enums, which meant renaming all flags (to get rid of WM_, WS_, etc.) to my own style.

3. I would derive my own classes and use overloaded arithmetic operators to them, from geometric classes included with the Win32 APIs.

4. Instead of return values, I''d make an exception class and throw exceptions.

etc.

As you can see, the project simply became too big for me to handle (well, not really... just that I have lots to do these days), and it was really irritating just making tons of inline functions with basically the same names...

On the upside, I learned a lot of the API... YMMV

(BTW, if anyone wants the source (to continue it or just use it for ideas), just email me and I''ll send it, but it''s not really too spectacular...)


- null_pointer
Sabre Multimedia
First ... for what it does I like COM a lot. In fact I think it is about the only good general coding thing MS has ever created. There are some weaknesses, which all have to do with limitations so that COM could be language independent (although its ugly in certain languages), the PRIMARY one being it''s lack of C++/Java style exceptions.

The error reporting mechanism in DirectX is the ONLY reason anyone would want to write a general purpose wrapper (there are plenty of benifits of wrappers for using SUBsets and specific areas of DirectX in specific ways, but the only thing a general purpose C++ library could improve (IMHO) is the error handling / reporting system.

Using COM interfaces (which are usually implemeted in C++ as structs containing pure abstract functions, and inheirits from the IUnknown interface) is all COMPLETELY object oriented. The only aspect of COM which uses stand alone (non member) functions, are the component creation and interface access methods, and these areas are their own Meta programming system which owe many of their ideas to the GOF documented factory methods (if you do not own the book "Design Patterns" you are missing out on many tried and true OO methodologies).

I''d post a more on this topic ... but the ever popular Chinease cuisine has suddenly found itself on my desk, eagerly awaiting my consumption.

I would like to simply say that I do have classes written embodying 2D images (sprites or bitmaps) but they primarily serve the purpose of encapsulating reloading of lost surfaces, and allowing images to animate transparently to the client program. I also use other classes which provide memory management and back-to-front rendering benifits. But I do NOT have any class which acts as a wrapper for a DirectX interface, except where it hides all but 1 or 2 functions.
Well, the COM doesn''t fit my my criteria for OO and encapsulation - it can''t handle it''s own cleanup, which makes it as bad as procedural code in my book. In order to use exceptions with any benefit, you have to wrap the allocation/cleanup of COM interfaces in a class. When I throw an exception in my code, I need to know that all of my resources will be cleaned up, and the program will exit normally.

Besides, the COM isn''t a replacement for C++ - it''s a specification, not a new language. You can''t make all the little classes like this in the COM:

class point;
class rectangle;
class polygon;
// etc.

Internally, yes. However you could not use your own classes like this as part of interface of the COM object because they would not be visible outside the COM object. You could probably use C-style structs, but that''s leagues behind what C++ classes can do, even for small types.

The COM doesn''t support operator overloading (even D3D has to use a header file with C++ code for that!), and it''s just too much overhead for little classes. Do I need three function calls to create and destroy a 4-byte point class? I''m not bashing the COM - like I said, it''s not a new language but a specification of how to use existing languages. It''s designed for larger, more complex interfaces.

So, what benefits does the COM provide for larger, more complex interfaces? Language independence, and also its different execution models (if that''s the right term - you know, in-process, etc.). I think that the latter could have been done in C++ with better results. Language independence with C++ code is tricky, though, so COM gets my respect for that.


- null_pointer
Sabre Multimedia

This topic is closed to new replies.

Advertisement