2D mode in OpenGL (probably asked before)

I’m thinking about adding an OpenGL target to an SDL version of an
emulator I’m working on, and I’d like some tips on how to proceed.

Specifically, I’ll be using OpenGL to blit the final framebuffer only. I
won’t have access to the individual sprites or objects that make up the
display. Basically I get a 160x300 pixel buffer that has to be sent to
the screen (with the width doubled). There are two framebuffers
available, front and back.

The following is (roughly) how I do it in software mode:

  • Each update analyzes the differences between front and back buffers
    (combination of FillRect and Update_Rects). Comparisons are not done
    per-pixel, but per 4 pixel widths. This works since normally, not every
    pixel changes (its a compromise between full dirty update and
    efficiency).

  • When a word (4 pixel wide area) has changed, an SDL_Rect is created
    with twice the horizontal width, and the contents of the 4 pixels are
    copied into the SDL_Rect with each pixel copied twice (horizontal
    doubling). This is going to change very soon, and the framebuffer will
    be created at 320x300 internally, making the doubling unnecessary.

  • The framebuffer stores palette information (unsigned 8-bit values)
    representing a color for that pixel. This is also going to change very
    soon, as we plan to add 32-bit mode (so that each pixel in the
    framebuffer is a 32-bit true-color value).

  • It is possible to ‘zoom’ the image by a user-defined amount. So (for
    example), if ‘zoom’ is set to 3, then in addition to above horizontal
    doubling, the width and height are tripled. The created SDL_Rect has a
    size 3x width and height, and is filled accordingly.

What I’d like to know is how easy it will be to create an OpenGL target to
do the same thing. If possible, I’d like to see sample code on how to
set up SDL GL in 2D mode (something to do with orthographic mode?).

Also, when using OpenGL, would it be faster to simply create a texture
from the 320x300 framebuffer and send that directly to the video card
(and ignore the back framebuffer), or to stay with using two framebuffers
and update a texture somehow? And how would that be accomplished?

The emulator runs at 60 fps. What kind of performance hit can I expect by
creating a new texture of 320x300 pixels (and sending it to the card) 60
times a second?

I assume that I can get the ‘zoom’ for free with OpenGL. I wouldn’t have
to diddle with the pixels at all, just tell OpenGL to scale it. And
related to that, when I tell it to scale a full image, will it become
blurry? And is there a way to have a normal scale vs. a filtered scale?

Other than the ortho stuff, I’m not looking for any code at this point.
But I’d appreciate if someone could point me in the right direction
concerning what OpenGL functions (or methodology) should be used.

Thanks,
Steve

#Other than the ortho stuff, I’m not looking for any code at this point.

glOrtho(leftside,rightside,bottom,top,near,far)

is the general parameter scheme, ie. this tells OpenGL what the
different edges of the ‘viewport’ (=the output window/screen) should
mean. For example, I often use

glOrtho(0,WIDTH,HEIGHT,0,-1,1); //WIDTH/HEIGHT 640/480 for example

in my 2d-projects, since this is what I am used to from other
gfx-libraries (top-left corner of screen is (0,0), bottom right corner
is (WIDTH-1,HEIGHT-1)). The near/far values sign is relevant, not
their size. I guess you want pixel-level details on the subject, try
to find the OpenGL Red Book (programmers guide) or Blue Book
(reference) on google or something (or buy) for those details.

The other performance issues I am not so sure about; I guess others in
this list have some answers…

Hope I helped some,

/Olof

-----Oorspronkelijk bericht-----
Van: stephena [mailto:stephena at roadrunner.nf.net]
Verzonden: woensdag 1 oktober 2003 15:04
Aan: sdl
Onderwerp: [SDL] 2D mode in OpenGL (probably asked before) …

Hello Steve,

I’m thinking about adding an OpenGL target to an SDL version of an
emulator I’m working on, and I’d like some tips on how to proceed.

I don’t know if it will help you, but you might want to check the
Virtual Jaguar project (http://www.icculus.org/virtualjaguar) which
has OpenGL support.

It uses a backbuffer (SDL_Display) which has all the pixeldata and
it’s “copied” to the OpenGL displaybuffer every frame.

– SNIP –

What I’d like to know is how easy it will be to create an
OpenGL target to
do the same thing. If possible, I’d like to see sample code
on how to
set up SDL GL in 2D mode (something to do with orthographic mode?).

You should check out the Virtual Jaguar CVS (see website) and look
at the sdlemu_opengl.[c|h] files. It’s rather easy to do. I’ve used
it for many SDL related emulation projects.

Also, when using OpenGL, would it be faster to simply create
a texture
from the 320x300 framebuffer and send that directly to the video card
(and ignore the back framebuffer), or to stay with using two
framebuffers
and update a texture somehow? And how would that be accomplished?

I found out by using your backbuffer, where the changes to the display
are being updated, and then blit it to the OpenGL displaybuffer is
much faster. Since OpenGL can do automatic resizing (at least in our
code) it just displays the pixels unrecarding the size of the OpenGL
window.

The emulator runs at 60 fps. What kind of performance hit
can I expect by
creating a new texture of 320x300 pixels (and sending it to
the card) 60
times a second?

I can’t say anything about this. I found out that just plain SDL
rendering was faster then OpenGL rendering. Only when you’re going
to scale OpenGL doesn’t have a performance hit (in our situation).

But I should warn you not to update every frame (ie : frameskip 0)
since it really hurts performance (SDL or OpenGL). I use a frameskip of
1 to archieve very good speeds and people won’t notice the 1 frameskip
difference anyway :slight_smile:

I assume that I can get the ‘zoom’ for free with OpenGL. I
wouldn’t have
to diddle with the pixels at all, just tell OpenGL to scale it. And
related to that, when I tell it to scale a full image, will it become
blurry? And is there a way to have a normal scale vs. a
filtered scale?

You can have several “image-filters” in OpenGL to be used with resizing.
Using GL_LINEAR produces a blurry but better looking scaled image.
GL_NEAREST looks like a pixel by pixel enlargement with a scaled image.

Other than the ortho stuff, I’m not looking for any code at
this point.
But I’d appreciate if someone could point me in the right direction
concerning what OpenGL functions (or methodology) should be used.

I think that most of the stuff you need is in the sdlemu_opengl.c
and it can be used without problems with your project. It’s GPL so
you’re free to use it :wink: Just check the link and the CVS for how we
used it.

Thanks,
Steve

Regards,

Niels Wagenaar