SDL_OPENGLBLIT: why use GL_LINEAR, and other things

  • Correct me if I’m mistaken, but in the case of SDL_OPENGLBLIT-using code,
    when SDL_GL_UpdateRects() is called, no scaling is happening, right?
    If that is true, then why not use GL_NEAREST filter modes in SDL_GL_Lock()
    so that software renderers don’t choke?

  • For Win32 at least, the 16-bit OPENGLBLIT shadow surface allocation
    should be
    commented out using #ifdef GL_UNSIGNED_SHORT_5_6_5 (or whatever it is);
    you can see that it causes testgl to mess up the little face, since the Windows
    OpenGL headers are 1.1 only. Some sort of run-time OpenGL version check
    might be worthwhile.

  • SDL_FillRect() is pretty useless as-is with OPENGLBLIT, since it draws pixels
    which will be transparent upon GL blit. I have worked around this.

  • SDL_BlitSurface() also seems to have some trouble with the final alpha
    values;
    this is probably due to hardware (or assembler) acceleration. I have
    worked around this,
    but if it’s a problem in a software blitter, it would be drastically better
    to change the blitter.

– Mike

  • Correct me if I’m mistaken, but in the case of SDL_OPENGLBLIT-using code,
    when SDL_GL_UpdateRects() is called, no scaling is happening, right?
    If that is true, then why not use GL_NEAREST filter modes in SDL_GL_Lock()
    so that software renderers don’t choke?

It wasn’t meant for use with software rendering. And if you want you can
simply call SDL_GL_Lock yourself, change the filtering to whatever you
like and then call SDL_UpdateRects.

  • For Win32 at least, the 16-bit OPENGLBLIT shadow surface allocation
    should be
    commented out using #ifdef GL_UNSIGNED_SHORT_5_6_5 (or whatever it is);
    you can see that it causes testgl to mess up the little face, since the Windows
    OpenGL headers are 1.1 only. Some sort of run-time OpenGL version check
    might be worthwhile.

The #ifdef GL_… is broken and cannot be used - e.g. Mesa uses enums and
no #ifdefs. Maybe we should check for GL_VERSION being defined but the standard
doesn’t say it has to be there… BTW, you should update your OpenGL
headers - OpenGL 1.1 is very old.

  • SDL_FillRect() is pretty useless as-is with OPENGLBLIT, since it draws pixels
    which will be transparent upon GL blit. I have worked around this.

That won’t happen in 16 bit mode :wink:

  • SDL_BlitSurface() also seems to have some trouble with the final alpha
    values;
    this is probably due to hardware (or assembler) acceleration. I have
    worked around this,
    but if it’s a problem in a software blitter, it would be drastically better
    to change the blitter.

I guess it is a blitter problem. Usually you want to use the 16 bit
surface and won’t hit those problems.On Fri, Jul 21, 2000 at 04:48:55PM -0400, Michael Chen wrote:


Daniel Vogel
Programmer
Loki Entertainment Software

Well, forgot to mention that you are right and it should use GL_NEAREST
;-)On Fri, Jul 21, 2000 at 02:19:00PM -0700, Daniel Vogel wrote:

On Fri, Jul 21, 2000 at 04:48:55PM -0400, Michael Chen wrote:

  • Correct me if I’m mistaken, but in the case of SDL_OPENGLBLIT-using code,
    when SDL_GL_UpdateRects() is called, no scaling is happening, right?
    If that is true, then why not use GL_NEAREST filter modes in SDL_GL_Lock()
    so that software renderers don’t choke?

It wasn’t meant for use with software rendering. And if you want you can
simply call SDL_GL_Lock yourself, change the filtering to whatever you
like and then call SDL_UpdateRects.


Daniel Vogel
Programmer
Loki Entertainment Software

  • Correct me if I’m mistaken, but in the case of SDL_OPENGLBLIT-using code,
    when SDL_GL_UpdateRects() is called, no scaling is happening, right?
    If that is true, then why not use GL_NEAREST filter modes in SDL_GL_Lock()
    so that software renderers don’t choke?

It wasn’t meant for use with software rendering. And if you want you can
simply call SDL_GL_Lock yourself, change the filtering to whatever you
like and then call SDL_UpdateRects.

Okay, saw the other reply to this :slight_smile:
Is there a way to submit changes like this via CVS?

  • For Win32 at least, the 16-bit OPENGLBLIT shadow surface allocation
    should be
    commented out using #ifdef GL_UNSIGNED_SHORT_5_6_5 (or whatever it is);
    you can see that it causes testgl to mess up the little face, since the
    Windows
    OpenGL headers are 1.1 only. Some sort of run-time OpenGL version check
    might be worthwhile.

The #ifdef GL_… is broken and cannot be used - e.g. Mesa uses enums and
no #ifdefs. Maybe we should check for GL_VERSION being defined but the
standard
doesn’t say it has to be there… BTW, you should update your OpenGL
headers - OpenGL 1.1 is very old.

Right, I agree that the #ifdef stuff is suspect, but since it was being
used that way elsewhere, I figured that was the current method.

I also agree that OpenGL 1.1 is very old, but that happens to be the
version that the Microsoft software renderer implements for Win9x. I
don’t even think the SGI Win32 version is 1.2 (although it does support
565 textures), and that requires dynamically loading
Choose/Descrribe/SetPixelFormat, which SDL currently doesn’t do. Mesa is
for all intents and purposes 1.2, but finding a Win32 version with the MMX
optimizations (or building it) is a nontrivial undertaking.

  • SDL_FillRect() is pretty useless as-is with OPENGLBLIT, since it
    draws pixels
    which will be transparent upon GL blit. I have worked around this.

That won’t happen in 16 bit mode :wink:

Um, correct me if I’m wrong, but I think it will unless the texture
surface is 16-bit, which won’t happen on Win32 since the software renderer
is version 1.1 and doesn’t support 565 textures blah blah blah :slight_smile:

Sorry to keep whining about Winblows, but since it is the majority platform
right now, it seems prudent to keep the Win32 stuff working.

Anyway, the workaround is to do the following:
replace SDL_FillRect(surface,&rect,SDL_MapRGB(surface->format,r,g,b));
with SDL_FillRect(surface,&rect,SDL_MapRGB(surface->format,r,g,b) |
surface->format->Amask);
which, if proper, could be added to the SDL_MapRGB code.
I’ve never really been sure what the destination alpha blending behavior is
supposed to be for SDL.

  • SDL_BlitSurface() also seems to have some trouble with the final alpha
    values;
    this is probably due to hardware (or assembler) acceleration. I have
    worked around this,
    but if it’s a problem in a software blitter, it would be drastically
    better
    to change the blitter.

I guess it is a blitter problem. Usually you want to use the 16 bit
surface and won’t hit those problems.

Unless you’re using the SDL surface as a way to do HUD-like display, and
therefore you actually want to be able to specify transparent
regions. Which would be rather desirable.

FWIW, my current workaround is to force the alpha values of the affected
pixels to opaque,
which is arguably bad behavior, and also very sub-optimal. Maybe blitters
with another blend mode?

– Mike>On Fri, Jul 21, 2000 at 04:48:55PM -0400, Michael Chen wrote:

Okay, saw the other reply to this :slight_smile:
Is there a way to submit changes like this via CVS?

You can send patches to Sam. The GL_NEAREST stuff is already in CVS
though :slight_smile:

Right, I agree that the #ifdef stuff is suspect, but since it was being
used that way elsewhere, I figured that was the current method.

SDL CVS was broken for some time.

That won’t happen in 16 bit mode :wink:

Um, correct me if I’m wrong, but I think it will unless the texture
surface is 16-bit, which won’t happen on Win32 since the software renderer
is version 1.1 and doesn’t support 565 textures blah blah blah :slight_smile:

Well, update your OpenGL headers. I think you maybe can use the Mesa
headers with NVIDIA binaries eg. I could be totally wrong though - I don’t
know much about Windows development.

Sorry to keep whining about Winblows, but since it is the majority platform
right now, it seems prudent to keep the Win32 stuff working.

Agreed, but you can get OpenGL 1.2 headers for Windows, don’t know
where though :wink:

Unless you’re using the SDL surface as a way to do HUD-like display, and
therefore you actually want to be able to specify transparent
regions. Which would be rather desirable.

For a HUD you better use a different approach. You want to create one
texture (or many) and keep them resident. The current SDL_OPENGLBLIT
impl. has to upload the whole texture when you blit (which is okay as it
is SDL_UpdateRect and it is safe to assume the data to be changed when
you call it ;-)). It doesn’t make sense to draw a HUD with SDL_OPENGLBLIT
at the moment.On Mon, Jul 24, 2000 at 11:59:37PM -0400, Michael Chen wrote:


Daniel Vogel
Programmer
Loki Entertainment Software

Right, I agree that the #ifdef stuff is suspect, but since it was being
used that way elsewhere, I figured that was the current method.

SDL CVS was broken for some time.

But should be fixed now.

Agreed, but you can get OpenGL 1.2 headers for Windows, don’t know
where though :wink:

I’m not sure the default Windows OpenGL implementation is OpenGL 1.2.

Anyway, the current CVS snapshot should work correctly even on OpenGL
1.1 implementations.

For a HUD you better use a different approach. You want to create one
texture (or many) and keep them resident. The current SDL_OPENGLBLIT
impl. has to upload the whole texture when you blit (which is okay as it
is SDL_UpdateRect and it is safe to assume the data to be changed when
you call it ;-)). It doesn’t make sense to draw a HUD with SDL_OPENGLBLIT
at the moment.

And probably never will. SDL_OPENGLBLIT is a hack for programs that
heavily mix 2D and 3D. The best way to do overlays and such is to
manage them yourself with GL.

See ya!
-Sam Lantinga, Lead Programmer, Loki Entertainment Software

  • SDL_FillRect() is pretty useless as-is with OPENGLBLIT, since it draws pixels
    which will be transparent upon GL blit. I have worked around this.

Yes, it should probably be fixed to respect destination alpha.
I’m not sure the best way to manipulate alpha on the screen surface.
Suggestions?

  • SDL_BlitSurface() also seems to have some trouble with the final alpha
    values;
    this is probably due to hardware (or assembler) acceleration. I have
    worked around this,
    but if it’s a problem in a software blitter, it would be drastically better
    to change the blitter.

Indeed. Some of the blitters have been fixed, and some are still broken.
If you could give more information about which blitter is being used, that
would be great.

Thanks!
-Sam Lantinga, Lead Programmer, Loki Entertainment Software

  • SDL_FillRect() is pretty useless as-is with OPENGLBLIT, since it
    draws pixels
    which will be transparent upon GL blit. I have worked around this.

Yes, it should probably be fixed to respect destination alpha. I’m not
sure the best way to manipulate alpha on the screen surface. Suggestions?

For SDL_FillRect, it would probably be fine to just make the destination
rectangle opaque.
This can be done by doing the following:
SDL_FillRect(surface,&rect,SDL_MapRGB(surface->format,r,g,b));
becomes
SDL_FillRect(surface,&rect,SDL_MapRGB(surface->format,r,g,b) |
surface->format->Amask);
Maybe there could be a function like SDL_MapRGBA() for this purpose, though
I’m not sure where else it would be useful.
But this would let you use SDL_FillRect like glClear.

Now if you wanted some kind of DrawRect with alpha which blended instead of
replacing,
I’m not sure exactly what would be desirable either…
maybe the OpenGL polygon draw suggestion of (GL_SRC_ALPHA_SATURATE,GL_ONE)?

  • SDL_BlitSurface() also seems to have some trouble with the final alpha
    values;
    this is probably due to hardware (or assembler) acceleration. I have
    worked around this,
    but if it’s a problem in a software blitter, it would be drastically
    better
    to change the blitter.

Indeed. Some of the blitters have been fixed, and some are still broken.
If you could give more information about which blitter is being used, that
would be great. Thanks!

I believe I’m using the 32-bit RGBA to RGBA blitter.

– Mike

For a HUD you better use a different approach. You want to create one
texture (or many) and keep them resident. The current SDL_OPENGLBLIT
impl. has to upload the whole texture when you blit (which is okay as it
is SDL_UpdateRect and it is safe to assume the data to be changed when
you call it ;-)). It doesn’t make sense to draw a HUD with SDL_OPENGLBLIT
at the moment.

And probably never will. SDL_OPENGLBLIT is a hack for programs that
heavily mix 2D and 3D. The best way to do overlays and such is to
manage them yourself with GL.

Two questions here…

  • Surely only the rectangle called out by SDL_GL_UpdateRect() is uploaded
    as new texture data on each call?
  • Have I missed overlay support proper in OpenGL, or is it a 1.2 thing?

It would seem that if the HUD actually needs to be updated each frame,
and one properly manages dirty rectangles, it might not be a bad thing.
For static HUD art, SDL_OPENGLBLIT would be a bad idea.

– Mike

Okay, one more question on this topic…

Do you really have to keep calling glFlush() in SDL_GL_UpdateRect() twice
for each tile?
This may kill performance;
shouldn’t the OpenGL implementation keep track of which texture data to use
each time?
Even if that were not the case, it seems that you’d only have to flush once.

– Mike

And probably never will. SDL_OPENGLBLIT is a hack for programs that
heavily mix 2D and 3D. The best way to do overlays and such is to
manage them yourself with GL.

Two questions here…

  • Surely only the rectangle called out by SDL_GL_UpdateRect() is uploaded
    as new texture data on each call?

Yes, the complete area specified by the update rectangle is uploaded -
and only that rectangle.

  • Have I missed overlay support proper in OpenGL, or is it a 1.2 thing?

What do you mean by overlay support? Do you mean mixing GLX and X calls?
Well, I tried this approach and only could get it to work with single
buffering which renders it useless :frowning:

It would seem that if the HUD actually needs to be updated each frame,
and one properly manages dirty rectangles, it might not be a bad thing.
For static HUD art, SDL_OPENGLBLIT would be a bad idea.

Yes. And as Sam already pointed out it was never intendend to be for
static data. Keep in mind that you will most likely overdraw the static
stuff in your scene by dynamic geometry and therefore have to update the
static things every frame too -> use one big texture ;-)On Tue, Jul 25, 2000 at 10:14:46AM -0400, Michael Chen wrote:


Daniel Vogel
Programmer
Loki Entertainment Software

Okay, one more question on this topic…

Do you really have to keep calling glFlush() in SDL_GL_UpdateRect() twice
for each tile?

Yes. Try removing one and use software Mesa e.g.

This may kill performance;
shouldn’t the OpenGL implementation keep track of which texture data to use
each time?

glFlush is in the OpenGL specs for a reason. Although glFinish seems
really strange - “to finish in finite time”.

Even if that were not the case, it seems that you’d only have to flush once.

No, both flushs are needed. It’s in a loop and I have to ensure that
I don’t use the texture while changing it. The problem is that it is a
really tight loop…On Tue, Jul 25, 2000 at 10:53:11AM -0400, Michael Chen wrote:


Daniel Vogel
Programmer
Loki Entertainment Software

Daniel Vogel schrieb am 25 Jul 2000:

Do you really have to keep calling glFlush() in SDL_GL_UpdateRect() twice
for each tile?
Yes. Try removing one and use software Mesa e.g.

You should report this as a bug to the Mesa developers then.
Updating a texture with glTexSubImage2D and the reusing it immediately
afterwards is completely legit.

AFAI undertstand the spec it is not guaranteed to work. That is what
glFlush is there for. FWIW it also barfs with the NVIDIA drivers IIRC.

/me likes abbreviationsOn Tue, Jul 25, 2000 at 09:19:05PM +0200, Andreas Umbach wrote:

Daniel Vogel schrieb am 25 Jul 2000:

Do you really have to keep calling glFlush() in SDL_GL_UpdateRect() twice
for each tile?
Yes. Try removing one and use software Mesa e.g.

You should report this as a bug to the Mesa developers then.
Updating a texture with glTexSubImage2D and the reusing it immediately
afterwards is completely legit.


Daniel Vogel
Programmer
Loki Entertainment Software