On Friday 21 November 2003 13.14, Stephen Anthony wrote:
[...]
> > Machines like the Atari ST and some 8 bit machines that lack
> > sprites and (ab)usable text modes are problematic as the games
> > usually do most rendering in software. You may not even be able
> > to use dirty rects without significant overhead. (You'd have to
> > trap all VRAM accesses the emulated CPU does, or do some brute
> > force test on the frame buffer after each frame.)
> >
> > If you're emulating a character generator + sprite based display,
> > try dropping the software rendering and doing it all in OpenGL.
> > Characters and sprites would be textures and normal rendering
> > would be done using "pure" OpenGL. The textures would become
> > procedural only if the emulated game/application keeps messing
> > with the graphics data.
> >
> > Note that hardware scrolling of "true" graphic planes can be
> > implemented in pretty much the same way as on the real hardware.
> > Make the textures correspond to the VRAM; not the display. That
> > way, you can have the 3D accelerator emulate the plane + sprite
> > combining hardware, instead of emulating the whole thing pixel by
> > pixel in software.
>> I understand (some!) of what you're saying above, but I think
> that's at a lower level than I can go.
Yeah, that goes for most emulators, AFAIK.
> This is a multi-platform
> emulator, and I can't change the core too much. So basically, to
> reiterate my original question, I only have access to a 2D
> framebuffer of pixel values. At this level, there is no concept of
> a sprite or anything like that, its just raw data. What would be
> the fastest way to send that data to OpenGL?
You could try something like microtiles arrays. Use a fixed grid when
checking the emulator buffers, and just mark the tiles that need
updating. Then the hard part: analyze the result and merge contigous
areas inte a minimal set of rectangles.
Note that if it's common to get complex patterns of small changes, it
might be better to update a bigger area than to have more rects. The
number of rects where overhead becomes bigger than the transfer cost
is highly hardware and driver dependent, of course, but I think it
would be possible to come up with tile size and/or "fuzzines factors"
that work ok on most hardware of interest.
> I agree that a pure OpenGL solution at a lower level would rock,
> and that's something I may look into at some point. But it could
> never be integrated back into the core code, since it would mean
> that OpenGL *is required*. This emulator has run on everything
> from a Zaurus to a mainframe, and most of the targets have no
> OpenGL capability.
Actually, what I described doesn't *have* to be implemented in OpenGL.
It would work just fine with any 2D API (such as the ones supported
by SDL), h/w accelerated or not. So, if you can get the core to talk
about surfaces, tiled maps (for character modes), sprites and stuff,
you could move the actual rendering into rendering backends. The s/w
rendering backend that is currently integrated into the core would
just be another backend, possibly used as an intermediate backend for
use with various direct rendering drivers. (Anything that's better of
just blitting full screen, basically.)
The problem is "procedural surfaces". If the emulator exposes internal
graphics data, weird pixel formats may cause major overhead when
running code that does a lot of s/w rendering into sprites,
characters or graphic display buffers. Conversion has to be done
*somewhere*, but if it's done early, it can be hard to avoid a sprite
being changed and converted multiple times per frames and stuff like
that.
//David Olofson - Programmer, Composer, Open Source Advocate
.- Audiality -----------------------------------------------.
| Free/Open Source audio engine for games and multimedia. |
| MIDI, modular synthesis, real time effects, scripting,... |
`-----------------------------------> http://audiality.org -'
--- http://olofson.net --- http://www.reologica.se ---