API agnostic systems without massive dynamic casts - possible?

Started by
12 comments, last by Narf the Mouse 11 years, 9 months ago

I was basically going to say the same thing as above.

The last game I played that supported OpenGL and DirectX within the same executable was Unreal Tournament 2003, and that was almost 10 years ago.

And it basically makes sense.

  1. Dynamic cast is something you never need to use within your entire career. I still to this day have never actually used that type of cast in code.
  2. Dynamic casts are not an optimization anyway. There is a lot of overhead associated with this type of cast, and it is generally regarded as a “never use” situation.
  3. Even if any specific user wanted to the option to run OpenGL or DirectX within the same executable, that user is only going to make that choice once. It is not like a users is going to suddenly decide in the middle of a game that he or she wants to switch from OpenGL to DirectX. That basically means all those virtual functions have no meaning. 10 months later you just called the same virtual functions over and over and basically just wasted time. Virtual functions make sense when the type of object might change during run-time, but, in a game, the change from DirectX to OpenGL or vice-versa is only going to happen at most once a year. Meanwhile, every frame of every day of every month of every year you are taking the hit from the same virtual function. It doesn’t make sense. Just compile a second executable as all games these days do.

And if you do decide to compile a second .EXE for each API as you should, you may find this article helpful. Trust me when I say you definitely do need a strategy to avoid spaghetti when you start compiling multiple versions of the same executable.


L. Spiro

How do you handle the user switching between APIs? The simplest method which would also allow end-user API switching would seem to be to just have the launcher swap around API.dlls - Copy the relevant API.dll from the DirectX/OpenGL/Whatever folder into the dlls folder when the user clicks "Ok".
Advertisement
Did this a couple of years back (no shaders back then, so the code below is just an example).

What I did was create an API-Factory object that had a generic interface, but generated and operated on API specific objects.

something like this:

[source ]class API_Factory{
virtual void AbstractShader createShader(...)=0;
}

class AbstractShader{
virtual void Apply()=0;
}


class DX11_Factory:API_Factory{
AbstractShader createShader(...){return new DX11_Shader(this.DX11Context);}
}

class DX11_Shader:AbstractShader{
void Apply(){DX11Context.ActivateShader(this.blabla);};
}[/source]

My Oculus Rift Game: RaiderV

My Android VR games: Time-Rider& Dozer Driver

My browser game: Vitrage - A game of stained glass

My android games : Enemies of the Crown & Killer Bees


[quote name='L. Spiro' timestamp='1341498173' post='4955985']
I was basically going to say the same thing as above.

The last game I played that supported OpenGL and DirectX within the same executable was Unreal Tournament 2003, and that was almost 10 years ago.

And it basically makes sense.

  1. Dynamic cast is something you never need to use within your entire career. I still to this day have never actually used that type of cast in code.
  2. Dynamic casts are not an optimization anyway. There is a lot of overhead associated with this type of cast, and it is generally regarded as a “never use” situation.
  3. Even if any specific user wanted to the option to run OpenGL or DirectX within the same executable, that user is only going to make that choice once. It is not like a users is going to suddenly decide in the middle of a game that he or she wants to switch from OpenGL to DirectX. That basically means all those virtual functions have no meaning. 10 months later you just called the same virtual functions over and over and basically just wasted time. Virtual functions make sense when the type of object might change during run-time, but, in a game, the change from DirectX to OpenGL or vice-versa is only going to happen at most once a year. Meanwhile, every frame of every day of every month of every year you are taking the hit from the same virtual function. It doesn’t make sense. Just compile a second executable as all games these days do.

And if you do decide to compile a second .EXE for each API as you should, you may find this article helpful. Trust me when I say you definitely do need a strategy to avoid spaghetti when you start compiling multiple versions of the same executable.


L. Spiro

How do you handle the user switching between APIs? The simplest method which would also allow end-user API switching would seem to be to just have the launcher swap around API.dlls - Copy the relevant API.dll from the DirectX/OpenGL/Whatever folder into the dlls folder when the user clicks "Ok".
[/quote]
The appropriate DLL’s would be copied to the install directory at install time.
You then have a launcher which allows the user to select one version or another and executes it.

Or the user can select only one version at install time and only that is installed (with some ability to change that later).

Or the launcher remembers the last choice and automatically launches it (with some way to change that in the future).

There are many ways to go about it.


L. Spiro

I restore Nintendo 64 video-game OST’s into HD! https://www.youtube.com/channel/UCCtX_wedtZ5BoyQBXEhnVZw/playlists?view=1&sort=lad&flow=grid


[quote name='Narf the Mouse' timestamp='1341521763' post='4956099']
[quote name='L. Spiro' timestamp='1341498173' post='4955985']
I was basically going to say the same thing as above.

The last game I played that supported OpenGL and DirectX within the same executable was Unreal Tournament 2003, and that was almost 10 years ago.

And it basically makes sense.

  1. Dynamic cast is something you never need to use within your entire career. I still to this day have never actually used that type of cast in code.
  2. Dynamic casts are not an optimization anyway. There is a lot of overhead associated with this type of cast, and it is generally regarded as a “never use” situation.
  3. Even if any specific user wanted to the option to run OpenGL or DirectX within the same executable, that user is only going to make that choice once. It is not like a users is going to suddenly decide in the middle of a game that he or she wants to switch from OpenGL to DirectX. That basically means all those virtual functions have no meaning. 10 months later you just called the same virtual functions over and over and basically just wasted time. Virtual functions make sense when the type of object might change during run-time, but, in a game, the change from DirectX to OpenGL or vice-versa is only going to happen at most once a year. Meanwhile, every frame of every day of every month of every year you are taking the hit from the same virtual function. It doesn’t make sense. Just compile a second executable as all games these days do.

And if you do decide to compile a second .EXE for each API as you should, you may find this article helpful. Trust me when I say you definitely do need a strategy to avoid spaghetti when you start compiling multiple versions of the same executable.


L. Spiro

How do you handle the user switching between APIs? The simplest method which would also allow end-user API switching would seem to be to just have the launcher swap around API.dlls - Copy the relevant API.dll from the DirectX/OpenGL/Whatever folder into the dlls folder when the user clicks "Ok".
[/quote]
The appropriate DLL’s would be copied to the install directory at install time.
You then have a launcher which allows the user to select one version or another and executes it.

Or the user can select only one version at install time and only that is installed (with some ability to change that later).

Or the launcher remembers the last choice and automatically launches it (with some way to change that in the future).

There are many ways to go about it.


L. Spiro
[/quote]
Thanks, sounds about what I was thinking.

*Makes a refactoring note*

This topic is closed to new replies.

Advertisement