EDIT: hm, looking at F-zero (uses mode 2), I wonder how they did that effect of the layer being laid out to the back
And where does the sky come from???
Â
The projection effect is accomplished by changing the affine transformation step values throughout the frame, up to every scanline. This is usually done with HDMA but you can do it with HIRQs.
Â
I don't know specifically about the sky in F-Zero X right now, but the part above the horizon line is often accomplished by changing the screen mode in the middle of the screen and using a normal text BG for it - that's how Mario Kart does it. It can also be done with sprites, or by changing the affine parameters to point to it (but this is a lot trickier to manage). In mode 1 you can use one of the text BGs on top of the affine one.
Â
Rendering the entire screen at once is going to give you massive compatibility problems. As you can see from from the two examples in this post alone a lot of games change what's on the screen while it's being drawn. Games use it for lots of other things too, like color gradients and wavy scrolling.
Â
That's why emulators of just about every 2D platform use per-line renderers instead of per-frame ones. In fact, in some ways per-frame is slower because you're working with frame sized buffers instead of line sized ones. This applies to priority combining and alpha blending. You'll end up with a lot more L1 misses.
Â
One of the big speed hits from typical line based renderers vs frame based ones is that they will check every sprite every line to see if it should be drawn. You can improve upon this approach by caching which sprites are on which lines are on then only changing this if OAM has been modified before the line. Usually OAM is only modified in vblank so you end up recreating the table once per frame instead of once per line. Even the few games that perform sprite multiplexing only do so a few times per frame.
Â
I've mentioned these things in another thread, but I think that trying to do the layer compositing in OpenGL is just asking for trouble. You're not going to be able to correctly emulate blending so easily (or mosaic, but I think most people don't really care about mosaic anyway). The only way I can think of doing it is with a relatively complex depth peeling approach that would require at least three passes. OBJ windows are also going to be pretty problematic.
Â
Caching the backgrounds into bitmaps (correct me if this is not what you're doing) might also prove a little unpleasant - basically, what is your strategy for dealing with modifications to them? Do you plan to recreate the entire background when any part of the map is modified? Or just a part of it? Unfortunately, in OpenGL modifying textures can be slow, even if it's just a part of it (sometimes especially if it's just a part of it). An even bigger issue is what happens when the tiles themselves are modified, since it can be expensive to track where in a map a tile is being used. You may end up having to re-cache every map any time any tile is modified. Some games modify tiles to animate them, and if you recache the entire maps you'll end up with something that's probably substantially slower than a full software renderer. Oh yeah, forgot about palette modifications, another common per-frame mod. I guess you're basically going to be stuck recaching the whole map a lot no matter what. Layers are at least 256x256, already a decent amount more than the work rendering them to 240x160, but they can be up to 512x512. Affine maps at up to 1024x1024 are quite a bit worse, although there you do save on not having to transform them.
Â
One more comment: if you found the bitmap modes extremely easy then you're probably not emulating them completely. I say this because the bitmaps are affine transformed like the affine layers in modes 1 and 2.