Applying vertical flip to an FBO?

219 views
Skip to first unread message

Brian Madden

unread,
Apr 15, 2016, 5:16:48 AM4/15/16
to Kivy users support
Hi Everyone,

I have an FBO that I'm using to drive an external RGB LED dot matrix display. That display has pixel (0,0) in the upper left corner, so I need to vertically flip the results I get back with glReadPixel().

The best technique I came up with is to use an EffectWidget(). So I follow the code examples that have been posted here before about creating a Texture and FBO, be instance of adding my widget's canvas to the FBO, I add the widget I need to display to an EffectWidget and then I add my widget to that widget. (And I add the EffectWidget's canvas to the FBO temporarily when I need to read the pixel data.

This is all working fine, but as I am not an OpenGL programmer, I wonder if the following makes sense? Here's the EffectWidgetBase code I'm using. Does this look right?

class FlipVertical(EffectBase):
   
"""GLSL effect to veritically flip a texture"""

   
def __init__(self):
       
super().__init__()

       
self.glsl = '''

        vec4 effect(vec4 color, sampler2D texture, vec2 tex_coords, vec2 coords)

        {{
        return texture2D(texture, vec2(tex_coords.x, .32 - tex_coords.y));
        }}
        '''



Again, this code works, but I wonder if anyone can take a look at it and let me know if this is the best way to do this?

By the way, I don't completely understand the range of the tex_coords here. My display is 128x32. I realized that to flip the y-axis, I need to use a value of 0.32 - tex_coords.y. I don't know if the fact I have a height of 32 and the starting point for my calculation is 0.32 is related or just a coincidence? I would have that that my value I subtract the tex_coords.y from in the GLSL code should either be the height of the widget or 1.0. I'm kind of surprised that 0.32 works (which I found via trial and error).

Anyway, does using an EffectWidget() like this make the most sense here? And what's the deal with the tex_coords needing to be 0.32 versus 32 or 1.0?

Thanks!
Brian


Alexander Taylor

unread,
Apr 15, 2016, 6:51:38 AM4/15/16
to Kivy users support
You can probably do this more efficiently using e.g. a Rotate instruction (rotating by 180 degrees about the centre of the screen), or a Scale instruction with a negative scaling. This is simpler than a whole new shader, and probably more performant both because it doesn't need the shader and because EffectWidget actually has a major performance problem and may be using a lot more cpu time than it should.

I'm not sure about the .32 thing. Are you sure this is the exact value you need?

Brian Madden

unread,
Apr 15, 2016, 11:39:34 AM4/15/16
to Kivy users support
Ok thanks. I'll take a look at those. I did notice quite a CPU hit with this shader, so that's good news. (Interesting though as I also display this widget on screen and apply several EffectWidgets to give it a "dot" look, and those seem fine, but this flipping one definitely slows things down.

And yeah, the .32 thing was exact. Took a bunch of fine tuning to get to that number, and .30 is too small and .35 is too much. It's weird. But if I don't use a shader, then oh well, I won't worry about it. :)

Thanks!

Brian Madden

unread,
Apr 15, 2016, 11:54:36 AM4/15/16
to Kivy users support
As a follow up, is there a way to adjust colors of a widget (and everything under it) not using a GL shader? In our app, we also have an option to represent a monocrhome (16 shades) dot matrix display on the screen. (Like the display in a pinball machine.) I'm using a series of Effects widgets to convert the RGB display to grayscale (with a luminance calculation), then to clamp it down from 256 to 16 shades, then to turn it orange. Then on top of that I have another shader to give it the "dot" look (make it a grid of dots).

The dot look would be easy to do not in OpenGL as I could just put a dot screen image with transparent "holes" in it. But for the conversion to grayscale, limiting the number of shades, and then turning it a color again. Is there a way to do that not using EffectsWidgets?

Again, thanks!
Brian

Alexander Taylor

unread,
Apr 15, 2016, 8:07:26 PM4/15/16
to kivy-...@googlegroups.com
I think a manual shader is the best way to accomplish this colour
manipulation. EffectWidget is a crude and not very performant wrapper
around Fbos though, you can achieve greater efficiency if necessary by
managing the Fbo stuff yourself.
> --
> You received this message because you are subscribed to a topic in the
> Google Groups "Kivy users support" group.
> To unsubscribe from this topic, visit
> https://groups.google.com/d/topic/kivy-users/0kA1ZnBImuU/unsubscribe.
> To unsubscribe from this group and all its topics, send an email to
> kivy-users+...@googlegroups.com
> <mailto:kivy-users+...@googlegroups.com>.
> For more options, visit https://groups.google.com/d/optout.


signature.asc

Brian Madden

unread,
Apr 15, 2016, 8:20:55 PM4/15/16
to Kivy users support
Awesome, thanks!

Sorry to be a total noob, but I've been googling and reading the group archive for the past three days. Are there any examples of how to "manage the Fbo stuff myself" anywhere? Or how to apply shaders, etc? I was able to figure out the GLSL for the EffectWidget on my own based on the existing ones, so if anyone has a starting point, that would be great!

Thanks again!
Brian

Alexander Taylor

unread,
Apr 16, 2016, 7:41:14 PM4/16/16
to Kivy users support
The best resources for the Fbo stuff are the source of EffectWidget itself (it doesn't do anything that complicated - actually its problem is probably that it does a little too much, and it's inefficient to stack Fbos the way it does), and the 'shader' folder of kivy's examples. The core points are to instantiate the Fbo, to set the texture of something visible (normally a Rectangle) to the Fbo texture, and to make sure it updates regularly (accomplished by adding the Fbo to a canvas or manually calling an update function regularly). This shouldn't be hard to follow from the code, and these examples are actually the main resources I used when I learned this stuff in the first place.
Reply all
Reply to author
Forward
0 new messages