Pages: 1
  Print  
Author Topic: Perfect low-level game framework  (Read 23833 times)
Offline (Unknown gender) luiscubal
Posted on: July 02, 2010, 01:43:55 pm
Member
Joined: Jun 2009
Posts: 452

View Profile Email
Ok, so there's like ten million APIs for coding games.
However, none of them are good enough.

The reason is this: When coding games, no system is isolated. Integration is essential.
So, I present - my own perfect imaginary low-level game framework:

Some basic principles
1. In modules, so if you don't need Internet access, it wouldn't waste space
2. Although unrelated modules are independent, modules obviously can have dependencies. So, for instance, the Video and Image modules could depend on the Graphics module
3. The API would be object-oriented. It could be written in C, provided that bindings available for object-oriented languages are available.
4. The API must support at least the following file formats: BMP, PNG, WAV, OGG and OGV. Other formats can be supported, such as MIDI, MP3 and WEBM, but are optional.
5. Rendering to window, to control and to image(texture?) must be supported.
6. Cross-platform: WinAPI, WPF, Xlib, GTK+, Qt, Cocoa.
7. The audio API must have optional streaming(but also the option of loading all at once), playing(once or looping), pausing, resuming, stopping, fading in, fading out, mixing, volume control, ability to select only parts of the sound to be played, capacity of detecting how long the sound file is, panning, and - very important - seeking(both in streaming and non-streaming). SDL_Mixer has no streaming support in some cases.
8. The audio API would provide both 2D and 3D audio support.
9. The video API would also provide playing with optional looping, pausing, resuming, stopping, seeking, etc.
10. I haven't used shaders and audio post-effects in the past, but apparently they are important, so the API should provide first-class support for these.
11. Video and animated images should have first class support.
12. The API must be designed for extreme efficiency and speed, and take advantage of hardware acceleration if available.

So, a simple hello world in my perfect API(in C++):
Code: [Select]
#include <awesome-api/all>

using namespace awesome::Core;
using namespace awesome::Graphics;
using namespace awesome::Image;
using namespace awesome::Fonts;

int main(int argc, char* argv[]) {

GameWindow window("Hello World!", 800, 600, 32, false); //Title, Width, Height, Bpp, Fullscreen
WindowGraphicsContext ctx(window);
ctx.EnableDoubleBuffering(true);

Image img("image.png", false); //Second parameter means explicitly disable support for animations(APNG, in this case) even if they are supported

Matrix& projection = ctx.ProjectionMatrix();
projection.ToIdentity();
projection.Multiply(OrthographicMatrix(0.0f, 800, 600, 0.0f, -1.0f, 1.0f));
//To be honest, I mostly copied the two lines above from an SDL+OpenGL tutorial

ctx.TransformMatrix().ToIdentity(); //Reset all transformations

//Here I'll make it similar to OpenGL because not everything in OpenGL sucks
ctx.Begin();
//We could use the long way, but the API would include some utilities to simplify common usages
//An even more simplified version(DrawImageRect) would be provided, taking away the whole "BottomLeft" stuff
//but in this case, this is provided to show the flexibility of the API.
DrawUtils::DrawRect(ctx, img.BottomLeft(), img.BottomRight(), img.TopRight(), img.TopLeft(), Rectangle(Vertex3(0,0,0), Vertex3(800, 600,0)));
ctx.End();
ctx.SwapBuffers();

ctx.Dispose();
window.Dispose();

return 0;

}

At this point, the API is quite conventional.
What makes it different?

1. Contexts: Having many contexts at the same time. Then one'd just apply the functions(begin, end, etc.) to a different context and it'd "just work". OpenGL isn't very context-friendly, since you can only have one active context at any given time.
2. Unification: Using base classes such as Drawable, the same functions could be applied to colors, static images, animated images, text, other graphical contexts and even movies. In OpenGL, this part is notably bad. Even with existent libraries available(such as DevIL). Try rendering a GStreamer movie in an OpenGL cube. Really, I'll be very interested in example code if you can show me.
3. Render to textures: Because of contexts and unification, this is as simple as rendering to the screen.
4. Video as just another resource: Ability to pick a video and just render it to a cube like it was a texture is important.
5. Draw context to context: A variant of render to textures.

This is my imaginary perfect low-level game API. If something like this already exists, I'd be happy to use it. It could be in C++, Java or .NET provided that it had all the simplicity and features I described.
Logged
Offline (Male) Josh @ Dreamland
Reply #1 Posted on: July 02, 2010, 03:31:14 pm

Prince of all Goldfish
Developer
Location: Pittsburgh, PA, USA
Joined: Feb 2008
Posts: 2950

View Profile Email
Our ideals are only slightly off.
"The API would be object-oriented."
By this, I figure you mean
Code: [Select]
Gaming.Engine.Code.Functions.Drawing.Images.SpritesInParticular.Rendering.DrawSprite(
  resources.images.sprites.byIndex(0),
  self.locals.drawing.images.sprite.index,self.locals.position.mouse.x,self.locals.position.mouse.y
);
But I'll be damned if I'd put up like that in anything other than Java*. Yes, now that I see your example code, I've noted that you're content with just DrawUtils::DrawRect. But eh, I vastly prefer draw_rectangle, personally.

"BMP, PNG, WAV, OGG and OGV"
I'd not settle for anything not supporting XM. And MP3 is a major plus.

"Contexts: Having many contexts at the same time. Then one'd just apply the functions(begin, end, etc.) to a different context and it'd "just work". OpenGL isn't very context-friendly, since you can only have one active context at any given time."
Easily implemented, major efficiency damper. Each draw function would have to check that the correct context is bound, and the user would have to specify that context every single time. That's annoying to user and GPU.

I don't know what you've used that you're acting as though video is some magically aloof resource that can't be treated as a texture. Must have been one fucked up little library. Happens when libraries do too much for you, I imagine. I can't think of a reason any respectable video renderer wouldn't have FBO's/contexts usable as textures.
Logged
"That is the single most cryptic piece of code I have ever seen." -Master PobbleWobble
"I disapprove of what you say, but I will defend to the death your right to say it." -Evelyn Beatrice Hall, Friends of Voltaire
Offline (Unknown gender) luiscubal
Reply #2 Posted on: July 02, 2010, 04:38:12 pm
Member
Joined: Jun 2009
Posts: 452

View Profile Email
It's just that, for once, I'd like to be able to pick a library, compile a simple Hello World and have it just work.
Right now, libraries are too much of an effort to interact with each other. That was one of my main complaints about C++ a few posts ago when we were discussing C++ vs other languages. Unfortunately, the situation sucks for all languages.

So far, the best library to accomplish this has been SDL which actually is object-oriented in spite of being plain C(hence making bindings to C++ and other languages pretty easy), with the following problems:
1. SDL_mixer has the problem of chunk vs music, with different features for each.
2. No video library
3. No hardware acceleration
4. No 3D (we can use OpenGL but then we go back to the context problem).

Yes, I am aware that currently my context proposal could be problematic for performance, but I guess it could be optimized. One possible way would be to prevent switching contexts during Begin()/End().
Using some optimizations, this could actually end up being just an if case in the functions. While it would be a bit slower, I don't think it'd be that bad. I mean, in assembly it could be something like

Code: [Select]
MOV EAX, [Address of this+Position of context ID]
CMP EAX, [Address of static variable current context ID]
JE good_context
;Do context switching here
good_context:
Meaning that when the context was correct, it'd be two memory reads and three instructions. Not too bad. And not all functions would need this I guess.
It's only an example, I could adjust it to require even less of these checks.

I am actually more concerned about how to tell it which textures to keep in memory, etc.

Also, this API makes it very easy to handle multiple windows. Think about it. Three separated windows rendering spinning cubes.

Disclaimer: I never actually tried DirectX so I don't know if it's as I describe here. Either way, I'm not sure I like the way Microsoft is going with XACT for sound.
Logged
Offline (Male) Josh @ Dreamland
Reply #3 Posted on: July 02, 2010, 06:18:06 pm

Prince of all Goldfish
Developer
Location: Pittsburgh, PA, USA
Joined: Feb 2008
Posts: 2950

View Profile Email
Sure, it's not detrimental, but it's little things like that which ultimately pile up. I'm just saying that the superior choice, however more or less convenient it would be, is to make the user explicitly switch context. Like surface_set_target in GM.

And yes; I was planning on making some GUI functions in ENIGMA that would potentially allow you to switch the current context to a new window. The only reason I'm making it, though, is for other pieces of ENIGMA to use; it's not really helpful in games. I just figure I may as well offer it up for use.
Logged
"That is the single most cryptic piece of code I have ever seen." -Master PobbleWobble
"I disapprove of what you say, but I will defend to the death your right to say it." -Evelyn Beatrice Hall, Friends of Voltaire
Offline (Unknown gender) luiscubal
Reply #4 Posted on: July 02, 2010, 06:55:46 pm
Member
Joined: Jun 2009
Posts: 452

View Profile Email
One efficient way to implement many contexts would be to use a stack.

Like:

Code: [Select]
create_screen_context();
//Draws here go to screen
create_texture_context();
//Draws here go to texture
dispose_texture_context();
//Draws here go to screen
dispose_screen_context();
Logged
Offline (Male) RetroX
Reply #5 Posted on: July 10, 2010, 09:33:10 pm

Master of all things Linux
Contributor
Location: US
Joined: Apr 2008
Posts: 1055
MSN Messenger - classixretrox@gmail.com
View Profile Email
Your API is SFML.  It allows OpenGL to be directly used into the program, and drawables to be used as textures.

Window.PreserveOpenGLStates(true);
Logged
My Box: Phenom II 3.4GHz X4 | ASUS ATI RadeonHD 5770, 1GB GDDR5 RAM | 1x4GB DDR3 SRAM | Arch Linux, x86_64 (Cube) / Windows 7 x64 (Blob)
Quote from: Fede-lasse
Why do all the pro-Microsoft people have troll avatars? :(
Offline (Unknown gender) luiscubal
Reply #6 Posted on: July 11, 2010, 05:59:13 am
Member
Joined: Jun 2009
Posts: 452

View Profile Email
No, it is not.
SFML lacks several features I mentioned, such as video support.
Logged
Pages: 1
  Print