OpenGL and blitting

I have an SDL_Surface I loaded. And the screen SDL_Surface is a double buffered OpenGL window. I want to blit the SDL_Surface to the screen. How do I do this? Can I use SDL_BlitSurface or must I use some OpenGL calls? Some sample code that also has the call to SDL_GL_SwapBuffers would be much appreciated.

I have an SDL_Surface I loaded. And the screen SDL_Surface is a double buffered OpenGL window. I want to blit the SDL_Surface to the screen. How do I do this? Can I use SDL_BlitSurface or must I use some OpenGL calls? Some sample code that also has the call to SDL_GL_SwapBuffers would be much appreciated.

Pass SDL_OPENGLBLIT to SDL_SetVideoMode() instead of SDL_OPENGL,
then use gl calls and SDL calls as you normally would, including
SDL_GL_SwapBuffers() to swap the gl buffers and SDL_Flip/SDL_UpdateRect(s)
to update the 2d stuff you draw with SDL calls.

Jp CalderoneOn Mon, 15 Oct 2001, Joe Tennies wrote:

THANK YOU!
I did the SDL_OPENGLBLIT and SDL_GL_SwapBuffers(), but not the SDL_Flip or
SDL_UpdateRects.

Gracias!

At 12:41 PM 10/15/01 -0400, you wrote:

I have an SDL_Surface I loaded. And the screen SDL_Surface is a double
buffered OpenGL window. I want to blit the SDL_Surface to the screen. How
do I do this? Can I use SDL_BlitSurface or must I use some OpenGL calls?
Some sample code that also has the call to SDL_GL_SwapBuffers would be much
appreciated.>On Mon, 15 Oct 2001, Joe Tennies wrote:

Pass SDL_OPENGLBLIT to SDL_SetVideoMode() instead of SDL_OPENGL,
then use gl calls and SDL calls as you normally would, including
SDL_GL_SwapBuffers() to swap the gl buffers and SDL_Flip/SDL_UpdateRect(s)
to update the 2d stuff you draw with SDL calls.

Jp Calderone


SDL mailing list
SDL at libsdl.org
http://www.libsdl.org/mailman/listinfo/sdl


“It’s kind of fun to do the impossible.”
– Walt Disney

I have an SDL_Surface I loaded. And the screen SDL_Surface is a double
buffered OpenGL window. I want to blit the SDL_Surface to the screen.
How do I do this? Can I use SDL_BlitSurface

You can, but it’s dog slow. (You need to use SDL_OPENGLBLIT, which
gives you a software back buffer that you can blit into, and then render
into the OpenGL framebuffer SDL_UpdateRects().)

or must I use some OpenGL
calls?

Yeah, you’re usually much better of explicitly converting your surface
into a texture, and then rendering it using OpenGL.

Some sample code that also has the call to SDL_GL_SwapBuffers
would be much appreciated.

I’ve been hacking this kind of stuff (an SDL on OpenGL proof-of-concept
hack) this weekend, but unfortunately, I don’t have any code accessible
from here… (It needs some more work, but it runs some SDL test programs
and Kobo Deluxe. ‘testsprite’ with 2000 sprites at 60 fps sounds
interesting? :slight_smile:

//David Olofson — Programmer, Reologica Instruments AB

.- M A I A -------------------------------------------------.
| Multimedia Application Integration Architecture |
| A Free/Open Source Plugin API for Professional Multimedia |
----------------------------> http://www.linuxdj.com/maia -' .- David Olofson -------------------------------------------. | Audio Hacker - Open Source Advocate - Singer - Songwriter |-------------------------------------> http://olofson.net -'On Monday 15 October 2001 17:40, Joe Tennies wrote:

David Olofson wrote:> On Monday 15 October 2001 17:40, Joe Tennies wrote:

I have an SDL_Surface I loaded. And the screen SDL_Surface is a double
buffered OpenGL window. I want to blit the SDL_Surface to the screen.
How do I do this? Can I use SDL_BlitSurface

You can, but it’s dog slow. (You need to use SDL_OPENGLBLIT, which
gives you a software back buffer that you can blit into, and then render
into the OpenGL framebuffer SDL_UpdateRects().)

or must I use some OpenGL
calls?

Yeah, you’re usually much better of explicitly converting your surface
into a texture, and then rendering it using OpenGL.

That’s interesting. Could you give us some insight into “usually”?
Is it because you usually want to blit the same surface repeatedly
or are there cases where this is somehow faster for a one-time
event?

-= Josh

At 19:00 Uhr +0200 15.10.2001, David Olofson wrote:>On Monday 15 October 2001 17:40, Joe Tennies wrote:

I have an SDL_Surface I loaded. And the screen SDL_Surface is a double
buffered OpenGL window. I want to blit the SDL_Surface to the screen.
How do I do this? Can I use SDL_BlitSurface

You can, but it’s dog slow. (You need to use SDL_OPENGLBLIT, which
gives you a software back buffer that you can blit into, and then render
into the OpenGL framebuffer SDL_UpdateRects().)

or must I use some OpenGL
calls?

Yeah, you’re usually much better of explicitly converting your surface
into a texture, and then rendering it using OpenGL.

Some sample code that also has the call to SDL_GL_SwapBuffers
would be much appreciated.

I’ve been hacking this kind of stuff (an SDL on OpenGL proof-of-concept
hack) this weekend, but unfortunately, I don’t have any code accessible
from here… (It needs some more work, but it runs some SDL test programs
and Kobo Deluxe. ‘testsprite’ with 2000 sprites at 60 fps sounds
interesting? :slight_smile:

I still look forward to seeing this. SpriteWorld, a MacOS-only lib,
uses OpenGL accel for its 2D stuff with good success.

Max


Max Horn
Software Developer

email: mailto:Max_Horn
phone: (+49) 6151-494890

David Olofson wrote:

I have an SDL_Surface I loaded. And the screen SDL_Surface is a
double buffered OpenGL window. I want to blit the SDL_Surface to
the screen. How do I do this? Can I use SDL_BlitSurface

You can, but it’s dog slow. (You need to use SDL_OPENGLBLIT, which
gives you a software back buffer that you can blit into, and then
render into the OpenGL framebuffer SDL_UpdateRects().)

or must I use some OpenGL
calls?

Yeah, you’re usually much better of explicitly converting your
surface into a texture, and then rendering it using OpenGL.

That’s interesting. Could you give us some insight into “usually”?
Is it because you usually want to blit the same surface repeatedly

Yes - unless you have a still OpenGL scene, over which you occasionally
want to do a 2D blit, reusing a texture is much faster than the
SDL_OPENGLBLIT method. Of course, it may not matter, and it may not be
worth the effort writing the OpenGL code - but that’s another story.

or are there cases where this is somehow faster for a one-time
event?

Well, SDL_UpdateRects() with SDL_OPENGLBLIT does execute in the range of
30 OpenGL calls prior to actually starting the texture
downloading/rendering loop - some of which may be eliminated if you
integrate it with your OpenGL code. (That’s a good reason not to use
SDL_UpdateRects() more than once per frame, BTW - perhaps the most
extreme example!)

As to the actual texture downloading/rendering loop; no I can’t see how
it could be done much faster than it’s done by SDL. If you really have
to use new texture data for every frame, there’s no way around that step.

//David Olofson — Programmer, Reologica Instruments AB

.- M A I A -------------------------------------------------.
| Multimedia Application Integration Architecture |
| A Free/Open Source Plugin API for Professional Multimedia |
----------------------------> http://www.linuxdj.com/maia -' .- David Olofson -------------------------------------------. | Audio Hacker - Open Source Advocate - Singer - Songwriter |-------------------------------------> http://olofson.net -'On Monday 15 October 2001 19:09, Josh Stern wrote:

On Monday 15 October 2001 17:40, Joe Tennies wrote:

[…]

I’ve been hacking this kind of stuff (an SDL on OpenGL
proof-of-concept hack) this weekend, but unfortunately, I don’t have
any code accessible from here… (It needs some more work, but it
runs some SDL test programs and Kobo Deluxe. ‘testsprite’ with 2000
sprites at 60 fps sounds interesting? :slight_smile:

I still look forward to seeing this. SpriteWorld, a MacOS-only lib,
uses OpenGL accel for its 2D stuff with good success.

Yeah, that shouldn’t be an issue - but making it behave exactly like
SDL 2D blitting is. :slight_smile:

The hack I’m talking about is meant to strictly emulate SDL software
blitting, with no visual enhancements or other compatibility killers -
only faster rendering. (Which it already provides, with only dead simple
"don’t switch to the current texture" style optimizations.)

The biggest problem is applications that want to lock the entire screen,
modify the pixels and then unlock it. Sure, it’s trivial to implement,
but it’ll be dog slow…

Blitting to screen, blitting between surfaces (with automatic
invalidation of textures bound to destination surfaces), SDL_FillRect()
and other “trivial” stuff is done, but not optimized. Blitting from
screen shouldn’t be a problem, although I’m unsure how robust and
generally available the required OpenGL calls are.

Of course, being able to just throw an SDL_GLSDL flag in the
SDL_SetVideoMode() flags argument and then work with SDL surfaces as
usual is a big improvement, even if locking the screen or blitting from
it is slow or even broken.

As to the actual implementation of this hack, there’s one major problem:
It can’t integrate with SDL without “overriding” a bunch of SDL calls,
and then abusing the ‘unused1’ field of SDL_Surface. :-/

Two ways to go:
1) Make it a stand-alone library with new function names,
a surface type of it’s own, and a bunch of SDL<->glSDL
surface blitting functions.

2) Make it a new SDL rendering backend, making the API work
   transparently (as it does now), but without these crappy
   overload and 'unused1' hacks.

Personally, I’m not interested in doing 1) - the result would require
source code changes in applications, and still not deliver anything but
raw speed. I’d rather spend that time on real OpenGL support (with
sub-pixel accurate rendering and filtered scaling for "transparent"
multiple resolution support, most importantly) for the "Spifire Engine"
used in Kobo Deluxe and Project Spitfire - but that’s of no use for
existing SDL applications.

//David Olofson — Programmer, Reologica Instruments AB

.- M A I A -------------------------------------------------.
| Multimedia Application Integration Architecture |
| A Free/Open Source Plugin API for Professional Multimedia |
----------------------------> http://www.linuxdj.com/maia -' .- David Olofson -------------------------------------------. | Audio Hacker - Open Source Advocate - Singer - Songwriter |-------------------------------------> http://olofson.net -'On Monday 15 October 2001 19:15, Max Horn wrote:

For the LAST TIME, this is guaranteed to cut your performance at least
25% on most drivers. Bind a damned textures and do it right!

I’ve seriously started regretting SDL_OPENGLBLIT’s existance because
every couple of weeks someone asks this question and is immediately told
that they should just about guarantee their big bad 3D card falls back
to 2D mode in the final stages of rendering a frame just because it’s
easier than actually uploading the surface as a texture.

I have even within the past month posted a source code for changing
glOrtho at the end of a frame for drawing 2D overlays. Not that anyone
actually uses it. Instead every single time people insist on the worst
possible solution to the problem. SDL_OPENGLBLIT is not the answer to
2D overlays. It is however the start of mediocre to pathetic rendering
performance.On Mon, Oct 15, 2001 at 12:41:42PM -0400, Jp Calderone wrote:

I have an SDL_Surface I loaded. And the screen SDL_Surface is a double buffered OpenGL window. I want to blit the SDL_Surface to the screen. How do I do this? Can I use SDL_BlitSurface or must I use some OpenGL calls? Some sample code that also has the call to SDL_GL_SwapBuffers would be much appreciated.

Pass SDL_OPENGLBLIT to SDL_SetVideoMode() instead of SDL_OPENGL,
then use gl calls and SDL calls as you normally would, including
SDL_GL_SwapBuffers() to swap the gl buffers and SDL_Flip/SDL_UpdateRect(s)
to update the 2d stuff you draw with SDL calls.


Joseph Carter Free software developer

Never underestimate the power of human stupidity.
– Robert A. Heinlein

-------------- next part --------------
A non-text attachment was scrubbed…
Name: not available
Type: application/pgp-signature
Size: 197 bytes
Desc: not available
URL: http://lists.libsdl.org/pipermail/sdl-libsdl.org/attachments/20011015/66e10521/attachment.pgp

The biggest problem is applications that want to lock the entire screen,
modify the pixels and then unlock it. Sure, it’s trivial to implement,
but it’ll be dog slow…

Well, there are two ways to do this IMO, the first and most obvious way is
to use the glpixels or glpoints functions. However from past experiece, this
is a truely slow process. My friend who first implemented something like
this actually found that glpoints was faster than glpixels, and produced the
exact same image providing there were no bugs in the users graphics driver.
(This was done for a fast text output, like in Quake where it mentions who
was killed by who.)

The second way, which is a bit more work but might work better is to keep a
null texture the size of the screen (or bigger rather) or several that
comprise the screen(similar to the current trick used) for when things want
to directly modify the pixels and have this texture as the top most layer.
However IMO this would be just as slow. You can make it faster by using
glSubTexture and updating just the portion (works like SDL’s current
non-blending blit system) that has been modified.

Idealy however games wouldn’t try to lock/unlock the surface and then modify
individual pixels at a time. The project I’m working re-wraps the SDL 2D and
OpenGL “blitting” so they behave exactly the same way, no lock/unlock
feature is available as the SDL 2D mode is forced into software mode all the
time. Which is the only way I could force the 2D api into alpha blending,
you can’t blend on a hardware surface, it replaces.On Monday 15 October 2001 19:15, Max Horn wrote:

Blitting to screen, blitting between surfaces (with automatic
invalidation of textures bound to destination surfaces), SDL_FillRect()
and other “trivial” stuff is done, but not optimized. Blitting from
screen shouldn’t be a problem, although I’m unsure how robust and
generally available the required OpenGL calls are.

The biggest problem is applications that want to lock the entire
screen, modify the pixels and then unlock it. Sure, it’s trivial to
implement, but it’ll be dog slow…

Well, there are two ways to do this IMO, the first and most obvious way
is to use the glpixels or glpoints functions. However from past
experiece, this is a truely slow process.

So is any reading from VRAM on modern computers - and writing, unless
there is busmaster DMA.

My friend who first
implemented something like this actually found that glpoints was faster
than glpixels, and produced the exact same image providing there were
no bugs in the users graphics driver. (This was done for a fast text
output, like in Quake where it mentions who was killed by who.)

The second way, which is a bit more work but might work better is to
keep a null texture the size of the screen (or bigger rather) or
several that comprise the screen(similar to the current trick used) for
when things want to directly modify the pixels and have this texture as
the top most layer.

Like a “true” overlay? That assumes that applications are aware that 1)
the contents of the buffer doesn’t have anything to do with what’s
currently on the screen, and 2) that the screen surface has an alpha
channel, which must be used correctly to produce useful results.

This has very litle in common with what an SDL application expects when
locking the screen surface for some pixel level rendering.

However IMO this would be just as slow.

Depends on what you want to do. For software pixel effects, rendering it
with alpha into textures is the only way.

You can
make it faster by using glSubTexture and updating just the portion
(works like SDL’s current non-blending blit system) that has been
modified.

Yeah, but the big issue is that there’s no way to find out what has
been modified, without adding an API extension and modifying applications.

I can see four ways here:

1) Upon locking the screen surface, copy all of the OpenGL
   frame buffer into the software back surface. Upon
   unlocking, do nothing. Use something like the
   SDL_OPENGLBLIT implementation for blitting all or part
   of the screen back.

   Compatible, but painfully slow.

2) Similar to 1), but instead of actually reading the OpenGL
   framebuffer, maintain the software buffer by doing
   software blits to it, in parallel with the OpenGL
   rendering. (Software blits could be enqueued until the
   screen actually is locked, rather than performed directly.)

   Wow, what a mess...

3) Basically use method 1 or 2, but add an API call that
   allows the application to tell SDL which areas will be
   modified when locking the surface, rather than afterwards.

   Would actually work, but it's not SDL compatible.
   ("Partial surface locking" might still be a good idea,
   but not for SDL 1.2.)

4) As 1 or 2, but instead of reading the OpenGL frambuffer
   at all, just add an alpha channel to the software back
   buffer.

   This is about what SDL_OPENGLBLIT does, and it seems to
   break most normal applications. (Applications that do
   only normal blitting to the screen; no pixel access.)
   It's just not compatible with the way SDL applications
   expect the screen to work.

Idealy however games wouldn’t try to lock/unlock the surface and then
modify individual pixels at a time.

The problem is that that method can actually be a good way of doing
things in many cases…

The project I’m working re-wraps
the SDL 2D and OpenGL “blitting” so they behave exactly the same way,
no lock/unlock feature is available as the SDL 2D mode is forced into
software mode all the time.

I still implement the lock/unlock calls - just in case someone blits to a
surface that is represented by a texture. Unlock invalidates the texture,
so that it gets downloaded again before it’s used in an OpenGL
blit-to-screen the next time. (I’ve also added an Invalidate() call to do
partial texture updates, BTW.)

Which is the only way I could force the 2D
api into alpha blending, you can’t blend on a hardware surface, it
replaces.

You can’t…? Weird thing is that I’ve actually seen Kobo Deluxe do it on
Win2k in single buffer mode - and it was VERY slow, and flickered like
h*ll, of course. :slight_smile:

//David Olofson — Programmer, Reologica Instruments AB

.- M A I A -------------------------------------------------.
| Multimedia Application Integration Architecture |
| A Free/Open Source Plugin API for Professional Multimedia |
----------------------------> http://www.linuxdj.com/maia -' .- David Olofson -------------------------------------------. | Audio Hacker - Open Source Advocate - Singer - Songwriter |-------------------------------------> http://olofson.net -'On Monday 15 October 2001 22:17, Kisai wrote:

On Monday 15 October 2001 19:15, Max Horn wrote: