antirez / load81

SDL based Lua programming environment for kids similar to Codea
BSD 2-Clause "Simplified" License
599 stars 62 forks source link

Alpha parameter is Float, all else is Integer #16

Closed seclorum closed 12 years ago

seclorum commented 12 years ago

As reported by an early adopter (pmprog) of LOAD81 in the Open Pandora forum here:

http://boards.openpandora.org/index.php?/topic/7405-here-is-a-pnd-for-load81/

"One thing I've just noticed that looks a little weird - in the "fill" command, RGB are 0-255, but alpha seems to be floating point. Am I reading that right? Seems a little bizarre to mix up the parameters."

Perhaps this is a hold-over from Codea compatibility?

antirez commented 12 years ago

Sorry this is Codea heritage, and probably it's too late to change it?

Cheers, Salvatore

seclorum commented 12 years ago

Its up to you and the strategy for supporting float on ARM, which traditionally has poor support for hardware floating point.

antirez commented 12 years ago

@seclorum it's just a matter of API actually, the ARM poor support for floating point is not an issue from the point of view of argument passing to fill(), it's too little work even for the slowest of the floating point maths ;) But it may be misleading that everything is 0-255 except alpha.

seclorum commented 12 years ago

Well for the sake of consistency I would say change the API. This has the benefit of making it easier to use bit-shifting for adjusting alpha values in a game .. ;)

antirez commented 12 years ago

Ok. If we need to do that, better to do that ASAP actually... and I think it's a good idea. Doing it right now.

seclorum commented 12 years ago

Maybe do a quick scan for other such opportunies ..

antirez commented 12 years ago

Sorry I changed my mind, reverted to 0 - 1.0, it's pretty standard in computer graphic and I don't feel like changing it now. Thanks for sharing your point of view.

Btw there is a much bigger problem with alpha blending, the implementation of SLD_gfx is very bad and just "adds" components apparently in some broken way. Try the "paint.lua" example now and before SDL_gfx. Probably we'll need to go back to our drawing functions if I can't find a solution :(

seclorum commented 12 years ago

Yikes! If you don't want to change it, I'll do it .. it will bite us later when someone makes a program that does a lot of fills, and we'll see a big performance change.

And, I'm not seeing the problem you're describing with paint.lua.

seclorum commented 12 years ago

Oh, now I see it. filledEllipseRGBA() -> Alpha is Uint8, but you're passing int. Gotta watch that! In fact, I'm noticing an almost catastrophic mixing of types throughout load81, now I look for them ..

antirez commented 12 years ago

Strange that you don't see the same behavior. Example:

http://antirez.com/misc/sdlgfxalpha.png

Try this to reproduce: paint some blue, then press mouse button to switch to red and do a lot of filling staying both inside and outside the blu circles, and you'll see that the red is not able to overwrite the blue in the background no matter how many times you pass over it. This is not the expected behavior IMHO.

antirez commented 12 years ago

@seclorum I'm passing an int in the range 0-255, so it is unrelated. It is a matter of the bad algorithm used in the implementation. This algorithm is faster but does not work as expected I think.

ghost commented 12 years ago

I see what antirez sees too. But, isn't this because when the mouse stops we keep filling over top of the same x,y position? After a while, it should become solid.

antirez commented 12 years ago

Yes but eventually the component of the circle you are drawing should become dominant, if the algorithm is R = (R1*alpha)+(R2*(1-alpha)) (the same for G and B). Here there is some speedup going on that is not mathematically equivalent unfortunately. Also even stranger the blue circles are instead able to completely cover the red ones...

The good thing is that if we revert to our own drawing primitives I'll do the setPixel variant to write in the 8, 16, 24, and 32 BPP variants so that we don't have to change the kind of SDL surface needed. This should make our code almost as fast as gfx with some luck (but not as fast as we need to do the full math for alpha blending to avoid this problem).

seclorum commented 12 years ago

Have a look here:

http://www.ferzkopp.net/Software/SDL_gfx-2.0/Docs/Screenshots/SDL_gfxPrimitives.jpg

http://www.ferzkopp.net/Software/SDL_gfx-2.0/Docs/html/index.html

http://www.ferzkopp.net/Software/SDL_gfx-2.0/Docs/html/_s_d_l__gfx_primitives_8c.html#a33595ad996dd0dcccde3abbcef540eec

I think this is expected behaviour.

ghost commented 12 years ago

I thought you were talking about the solid circle, but you are talking about the magenta area. I don't see that problem.

antirez commented 12 years ago

Checking on a Linux system...

seclorum commented 12 years ago

Yeah, I think to get the behavior you are expecting, you should be using filledEllipseColor() with the RGBA component set for the Alpha .. you want Alpha (transparency) with no blending, I guess, but gfx is doing blending.

ghost commented 12 years ago

I'm on Ubuntu 11.10 BTW. Here is an capture from my system.

http://i.imgur.com/Csx1J.jpg

antirez commented 12 years ago

not sure what I'm doing wrong here, but this does not work:

filledEllipseColor(fb->screen, xc, fb->height-1-yc, radx, rady, SDL_MapRGBA(fb->screen->format,r,g,b,alpha));
antirez commented 12 years ago

It was not a matter of API call, in Linux it works as expected so it is a bug in the SDL_gfx I've in osx I guess...

antirez commented 12 years ago

Ok, now I understand what's happening and why in Linux it works: with 32 BPP mode it's broken, while with 24 BPP it works. Even on OSX forcing the 24BBP mode in the SDL initialization will make it working right.

@seclorum apparently it is broken in the 16BBP mode as well? Thanks.

antirez commented 12 years ago

The problem was already reported by another user

http://sourceforge.net/tracker/?func=detail&aid=3479727&group_id=294774&atid=1244910

No reply. What to do? Maybe for now we can simply force 24 BBP mode in SDL initialization? How much this makes it slower on the OpenPandora? Cheers.

seclorum commented 12 years ago

There is a proposed fix at that link:

http://sourceforge.net/tracker/download.php?group_id=294774&atid=1244910&file_id=434017&aid=3479727

Maybe the solution, for now, is to force 24bpp .. I don't think it will be that drastic performance difference on Open Pandora.

seclorum commented 12 years ago

Maybe for now the solution is to add a "-bpp <16,24,32>" cmd-line argument so that we can easily select the desired bitdepth at start-time, and for OSX and Linux-openpandora just use whatever works best?

antirez commented 12 years ago

+1 for --bpp with default to 24.

seclorum commented 12 years ago

Okay, I did some testing using asteroids.lua as the test program, and here's the FPS results for Open Pandora:

32bpp: 30fps 24bpp: 22fps 16bpp: 30fps 8bpp: 30fps

So yeah, we take a hit if we force it to 24fps (since the OP driver is doing conversion) but we may be able to get around this by linking with the HW-accelerated version of SDL that is floating around for the OP. Its not optimal, but also you could consider just giving us a cmd-line argument to force the bpp, and then we can use whatever fits best for the platform.

seclorum commented 12 years ago

Also, please re-consider the float/int Alpha API change, use of floats on ARM is really an issue and may bite us in the a\ later on other platforms..

antirez commented 12 years ago

@seclorum I can guarantee that the API does not influence performances, for the following reasons:

So there is absolutely no difference in performances between float or integer api for alpha in fill().

seclorum commented 12 years ago

Ah, okay .. you win. ;) I guess this is closed then. Its just gonna be the first introduction to float vs. ints for some new programmers ..

antirez commented 12 years ago

@seclorum NP at all ;) Maybe you already know it but while we are at it, Lua is a very strange language from this point of view because it has a single type of numbers that defaults to floats, but you can compile it using integers if you want (but then no way to do float math!).

For the same reason Lua does not provide, by default, bit-wise operators that are less than trivial to implement against a float type. Shameless plug: this "single type" is one of the few things I don't like about Lua.

ghost commented 12 years ago

there is the lnum patch which provides some help for this. but, the patch is a bit out of date but is easy to get working of 5.1.4.

http://luaforge.net/projects/lnum/

antirez commented 12 years ago

IMHO it's better to accept standard Lua with its issues (and its many strengths) than going nonstandard, but thx for the hint.

ghost commented 12 years ago

Yes. On some embedded systems there is no choice. There's also LuaJIT.

seclorum commented 12 years ago

Just wanted to let you know that I've rolled out the --bpp setting for Pandora, with "--bpp 16" - for some reason with your new changes, "--bpp 32" no longer works on Open Pandora, or at least setting this results in Alpha not working. So for now I've set it to "--bpp 16", which provides the best of all worlds, working Alpha and 30FPS.