Page 5 of 6

Re: How to use Framebuffer:renderTo() properly

Posted: Sun Jul 10, 2011 8:17 pm
by Robin
Yes and no. They do support full alpha transparency (at least for me), but they somehow assume transparency over black. So

Code: Select all

fb = love.graphics.newFramebuffer()
love.graphics.setBackgroundColor(255, 255, 255)
fb:renderTo(function()
	love.graphics.setColor(255, 255, 255, 128)
	love.graphics.rectangle('fill', 100, 100, 600, 400)
	love.graphics.setColor(255, 255, 255)
end)

function love.draw()
	love.graphics.draw(fb, 0, 0)
end
This renders to a grey rectangle.

EDIT: let me rephrase: when alpha is not 255 or 0, it forgets red, green and blue and just uses 0, 0, 0, alpha.

Re: How to use Framebuffer:renderTo() properly

Posted: Sun Jul 10, 2011 8:29 pm
by Jasoco
Robin wrote:Yes and no. They do support full alpha transparency (at least for me), but they somehow assume transparency over black. So

Code: Select all

fb = love.graphics.newFramebuffer()
love.graphics.setBackgroundColor(255, 255, 255)
fb:renderTo(function()
	love.graphics.setColor(255, 255, 255, 128)
	love.graphics.rectangle('fill', 100, 100, 600, 400)
	love.graphics.setColor(255, 255, 255)
end)

function love.draw()
	love.graphics.draw(fb, 0, 0)
end
This renders to a grey rectangle.

EDIT: let me rephrase: when alpha is not 255 or 0, it forgets red, green and blue and just uses 0, 0, 0, alpha.
You know what, that's what I meant. Slipped my mind. It mattes the partially transparent colors with a background and keeps the 0 alpha ones invisible. So if I draw a partially transparent white box like you do I get a grey box. This is not what I had expected when I discovered them.

I was hoping for it to be more like PhotoShop layers where I have a transparent canvas to draw on and could just draw layers and it would just look like one image to the user. But the weird handling of alpha just makes it work weird and not like you would expect.

I still wish I could apply Quads to a FrameBuffer. It would be SOOOOOOOO useful for doing some really cool effects and transitions.

Imagine rendering the scene to a FB then chopping it up into squares or lines and then rendering them at offsets or rotations or scales. Is this a limitation? Can OpenGL not allow a FB to be chopped into quads?

Re: How to use Framebuffer:renderTo() properly

Posted: Sun Jul 10, 2011 8:30 pm
by Robin
Wow. I was wrong. It turns out to be even weirder. I can't find a rule or something that correctly describes what happens. :shock:

EDIT: not completely wrong, what Jasoco says still seems reasonable, but it... it's just weird.

EDIT 2:
Jasoco wrote:Imagine rendering the scene to a FB then chopping it up into squares or lines and then rendering them at offsets or rotations or scales. Is this a limitation? Can OpenGL not allow a FB to be chopped into quads?
I think you can have the same effect with love.graphics.setScissor when drawing a Framebuffer. Although rotation and scaling might be tricky then.

Re: How to use Framebuffer:renderTo() properly

Posted: Sun Jul 10, 2011 8:42 pm
by Jasoco
Robin wrote:EDIT 2:
Jasoco wrote:Imagine rendering the scene to a FB then chopping it up into squares or lines and then rendering them at offsets or rotations or scales. Is this a limitation? Can OpenGL not allow a FB to be chopped into quads?
I think you can have the same effect with love.graphics.setScissor when drawing a Framebuffer. Although rotation and scaling might be tricky then.
No, I gotta have full control over framebuffer quads or nothing at all. I hope someone in charge can look into it for the future because it would be so useful.

Alternatively, an easier way to copy the contents from a framebuffer into some image container that CAN be used with quads would be a good alternative.

Also the ability to warp an image/quad (Combined with the above would be amazingly useful) into non square/parallelogram shapes. i.e. trapezoidal shapes and others. i.e. the ability to move the top left, top right, bottom left and bottom right corners anywhere to stretch and skew the image would be useful for pretty much anything. Especially if we could also warp other points along the edge of the image border.

This stuff would be great for games.

Oh, and the ability to tint an image a certain color, by changing its Hue, Saturation and Luminocity/Brightness would be convenient too. Especially if it could be applied to the FrameBuffers too.

Re: How to use Framebuffer:renderTo() properly

Posted: Sun Jul 10, 2011 8:50 pm
by slime
Jasoco wrote: Also the ability to warp an image/quad (Combined with the above would be amazingly useful) into non square/parallelogram shapes. i.e. trapezoidal shapes and others. i.e. the ability to move the top left, top right, bottom left and bottom right corners anywhere to stretch and skew the image would be useful for pretty much anything. Especially if we could also warp other points along the edge of the image border.

This stuff would be great for games.

Oh, and the ability to tint an image a certain color, by changing its Hue, Saturation and Luminocity/Brightness would be convenient too. Especially if it could be applied to the FrameBuffers too.
*cough* shaders *cough*. :P
(see the experimental löve-glsl build for fragment/pixel shaders).

Re: How to use Framebuffer:renderTo() properly

Posted: Sun Jul 10, 2011 8:54 pm
by TechnoCat
Jasoco wrote: Alternatively, an easier way to copy the contents from a framebuffer into some image container that CAN be used with quads would be a good alternative.
Framebuffer:getImageData
Jasoco wrote: Also the ability to warp an image/quad (Combined with the above would be amazingly useful) into non square/parallelogram shapes. i.e. trapezoidal shapes and others. i.e. the ability to move the top left, top right, bottom left and bottom right corners anywhere to stretch and skew the image would be useful for pretty much anything. Especially if we could also warp other points along the edge of the image border.
https://bitbucket.org/rude/love/issue/152/image-skewing
Jasoco wrote: Oh, and the ability to tint an image a certain color, by changing its Hue, Saturation and Luminocity/Brightness would be convenient too. Especially if it could be applied to the FrameBuffers too.
http://love2d.org/forums/viewtopic.php?f=5&t=1111 (a small lib i wrote for very basic image manipulation a while ago)
However, it isn't HSL, but I love HSL stuff.

Re: How to use Framebuffer:renderTo() properly

Posted: Sun Jul 10, 2011 9:03 pm
by Ensayia
TechnoCat wrote:I love HSL stuff.
Taehl actually wrote a function that lets you use HSL in LOVE. You input HSL values and it will return RGB values.It can be found here.

Re: How to use Framebuffer:renderTo() properly

Posted: Sun Jul 10, 2011 9:41 pm
by benloran
Jasoco wrote:What color is the background? As I've mentioned before and have had a discussion about the inability for Löve to do it, but this would not be a problem if FrameBuffers could support alpha transparency. The edges around those circles are because FB's can't do alpha. Only solid or transparent like a GIF. Not alpha like a PNG. Sucks. But I'm more a 16-bit homage person so none of my graphics really have alpha edges.
I guess the background color is black, it's not being set anywhere in the example code.

I didn't realize that FrameBuffers only support 0% or 100% transparency, that's good to know.

Re: How to use Framebuffer:renderTo() properly

Posted: Sun Jul 10, 2011 9:50 pm
by Jasoco
slime wrote:
Jasoco wrote: Also the ability to warp an image/quad (Combined with the above would be amazingly useful) into non square/parallelogram shapes. i.e. trapezoidal shapes and others. i.e. the ability to move the top left, top right, bottom left and bottom right corners anywhere to stretch and skew the image would be useful for pretty much anything. Especially if we could also warp other points along the edge of the image border.

This stuff would be great for games.

Oh, and the ability to tint an image a certain color, by changing its Hue, Saturation and Luminocity/Brightness would be convenient too. Especially if it could be applied to the FrameBuffers too.
*cough* shaders *cough*. :P
(see the experimental löve-glsl build for fragment/pixel shaders).
Let me know when that stuff makes it into Löve proper.
TechnoCat wrote:
Jasoco wrote: Alternatively, an easier way to copy the contents from a framebuffer into some image container that CAN be used with quads would be a good alternative.
Framebuffer:getImageData
I'll look into that. I hope it's fast. I assume I'd:
Take the data from the FB
Place it into image data
Create the quads after the image data is set

Right?
Jasoco wrote: Also the ability to warp an image/quad (Combined with the above would be amazingly useful) into non square/parallelogram shapes. i.e. trapezoidal shapes and others. i.e. the ability to move the top left, top right, bottom left and bottom right corners anywhere to stretch and skew the image would be useful for pretty much anything. Especially if we could also warp other points along the edge of the image border.
https://bitbucket.org/rude/love/issue/152/image-skewing
Skewing isn't Warping. Skewing just pushes a side offset. It doesn't move the points themselves arbitrarily like it would in order to make 3D effects or other cool special stuff.

Re: How to use Framebuffer:renderTo() properly

Posted: Sun Jul 10, 2011 9:51 pm
by Boolsheet
No no, the framebuffers do fully support alpha (if there's such a thing).

The alpha on the circle edge is lower than expected because that's how LÖVE's alpha blend mode works if you blend something (translucent) twice. In this case from an image to a framebuffer and the framebuffer to the screen.

It comes down how the pixels are added together with the blend equation.
Let's say we have the already existing pixel A on the screen, the to be drawn pixel B from the image and the pixel C, which will be the result of A and B blended together. They all have the members r, g, b, and a for the color and alpha values and can reach from 0 to 1 as floating point (instead of 0 to 255).
The alpha blend mode does now the following to calculate the result:

Code: Select all

C.r = (A.r * (1 - B.a)) + (B.r * B.a)
C.g = (A.g * (1 - B.a)) + (B.g * B.a)
C.b = (A.b * (1 - B.a)) + (B.b * B.a)
C.a = (A.a * (1 - B.a)) + (B.a * B.a)
A transparent pixel A does have an effect on a translucent pixel B. This is why the circles have those rough edges once they're drawn to the screen.
We need a new blend mode that blends an already blended source with the destination without affecting the alpha of the source.

There's already a ticket in the issue tracker by cadahl that proposes such a blend mode. He also linked to this blog that explains premultiplied blending.
The premultiplied equation looks like this:

Code: Select all

C.r = (A.r * (1 - B.a)) + B.r
C.g = (A.g * (1 - B.a)) + B.g
C.b = (A.b * (1 - B.a)) + B.b
C.a = (A.a * (1 - B.a)) + B.a
Drawing the framebuffer to the screen with this mode gives us the image that we want.
Let the developers know that you want that mode and post a message on the issue. ;)

(I don't actually know what I'm talking about. Anyone, please correct me if I'm talking nonsense)