Juce's not quite ready OpenGL Renderer


#1

Hey Jules, I know i’m being overly eager, but i’m curious as to whether you’ll think we’ll be able to mix juce Graphics calls and open gl calls in the components’ paint method? Or will the LowLevelGraphicsContext remain opaque?

Really looking forward to it!


#2

Still ironing out the bumps, but have got most of the hard bits done!

I think what’ll happen is that you’ll be able to put a window into openGL mode, and then any paint() callback in its subcomponents will be able to contain GL commands. Haven’t figured out the exact details yet though…


#3

Awesome… One other useful thing in the OpenGLTexture would be the ability to draw a bordered quad. Its basically the same but with an inset rect defined. That way when the quad is expanded the distortion is kept to a minimum. (Take for instance the iOS back button, if it resized the whole texture to fit text then the arrow left would distort, by defining the “text area” inside the image that is what gets resized.). There’s a ton of other uses for it as well…(component backgrounds with rendered drop shadows)

Make sense? I’m probably not explaining very well. I have code that does this I can send you if you want, (it uses quads though so probably best to move over to triangles!)… But in my code its drawing the top left corner area[1], the top border(stretched horizontally [2]), the top right corner[3], the left border(stretches vertically only[4]), the center area(which is the bit that resizes/stretches x and y[5]), right border(stretch vertically[6]), bottom left corner[7], bottom border(stretch horizontally[8]), and finally the bottom right corner[9]…

ASCII ART!!!

--------------------------------------------------------
| 1 |                       2                      | 3 |
--------------------------------------------------------
| 4 |                       5                      | 6 |
|   |                                              |   |
|   |                                              |   |
|   |                                              |   |
|   |                                              |   |
--------------------------------------------------------
| 7 |                      8                       | 9 |
--------------------------------------------------------

So the inset rect is [5]


#4

Well, that has nothing to do with openGL… You could easily do it with the normal Graphics class.


#5

True, but it’d be nice to do it all in one batch pass. (And saving a lot of glBindTexture calls!)


#6

Congratulations Jules! The rotation parameter on the Demo page with the OpenGL renderer rocks! I know its still early, but quite an accomplishment!


#7

Eh? I’ve not done anything new on the openGL demo page yet - that demo’s been there for years! The OpenGLRenderer class is where the action is going to happen.


#8

I meant the rotation Widget page with OpenGL as the renderer… that aspect is quite faster than the CoreGraphics renderer


#9

Ah, you figured out how to enable the secret GL rendering engine! I hadn’t made it public yet, but yes, feel free to have a play! Lots more work still to be done though!


#10

interesting! would an OpenGL renderer speed up rendering on IOS as well?

currently, on an ipad1, the default renderer renders the widgets demo at approx 25ms per iteration. A bit too slow for fast moving UIs I’m afraid…
However, on my trusty old 1.6Ghz mac mini it’s as low as 4ms, which is very usable. Any chance of approaching that kind of speed on an ipad1 you think?

On a related note: on the mac mini, the software renderer is twice as fast as coregraphics. Is this expected? And if so, is this software renderer maybe usable on IOS as well?


#11

Your Mac Mini has a better CPU than GPU. Your iPad has a better GPU than CPU.

I’m hoping for some improvements with the OpenGL renderer, but only with rendering being in a thread, to be honest.

As for 25 MHz - that’s plenty fast enough for a GUI, it means you’d hit 30 fps with a bit of time over for processing. The problem more is that on a constrained platform, you don’t get that whole amount to use - the system designer has assumed you’ll be using the GPU, so the CPU doesn’t have the oomph to do graphics and normal processing.

Bruce


#12

makes sense! thanks

the reason I joined the conversation is that I am currently struggling with a port of an existing juce audio app which needs to do a lot of real-time UI updates and which gets the ipad on its knees rather quickly.

so if anyone needs a volunteer for trying out experimental hw-accelerated renderers on an ipad1, I’d be happy to give it a shot!


#13

I’ve rewritten the renderer (again…) and updated the demo to show off some 2D stuff - would be interested to hear how you guys find it.

It’s been very frustrating in terms of performance, I can’t seem get it to go anywhere near as fast as the CPU or CoreGraphics renderers, even though my Mac has a decent graphics card.

Of course, it’ll be hugely faster for some things (e.g. drawing a big transformed image when that image is already stored in a GL framebuffer will be almost instantaneous). But just for the day-to-day 2D rendering, it just seems to hit mysterious bottlenecks, and some things are 100x slower than using the software renderer. Would be interested to hear opinions or advice from any GL gurus!


#14

hi Jules, would your new renderer work on an ipad as well? Can test it for you there with juce demo & my own app if you like
can also test on a mac mini with a (modest!) GMA 950 GPU


#15

It works in the simulator - would like to hear if it also works on a real device, as I’ve not tried that.


#16

OK, did some testing
pulled your latest changes from the modules branch and got the opengl renderer to work on OSX for the Juce demo by adding this to AppConfig.h : #define JUCE_OSX_OPENGL_RENDERER 1
This results in a new menu item for the OpenGL renderer below Look&Feel

however, the new menu item does not show up on ipad (simulated nor hardware one). Actually there is no choice of renderer at all on the ipad, that is, no menu items for Coregraphics or Software renderer either
Am I doing something wrong?

Also, on OSX when I choose the OpenGL renderer, the displayed render times seem to be too optimistic given how the UI feels. CoreGraphics renders at 3.4 ms and OpenGl at 3.6, but visually/subjectively the OpenGL version feels a lot slower (I’d say five times slower if not more). Could it be there is some additional processing going on outside the measured rendering operations in the OpenGL case?


#17

The JUCE_OSX_OPENGL_RENDERER stuff is definitely not finished, please ignore it for now!

What I’d be interested in hearing about at the moment is how you get on at mixing 2D and 3D rendering, like I’ve done on the new GL demo page.

And BTW the render times in the demo are only measured for drawing the actual shape that’s being animated, not the entire repaint time. I’ve not written the stuff to handle dirty repaint regions yet, so in OpenGL mode, the demo is continually redrawing the entire window, which is the main reason it’s sluggish (apart from the fact that it’s just slow!)


#18

ah, sorry for my confusion - wasn’t aware of the new OpenGL demo

ran test again this time with OpenGL demo. Result:
-on the ipad1 it’s quite slow, you can easily see every frame update - I estimate about 3 fps
-on the mac mini, with the default juce demo window size, it’s quite smooth and nice looking
however, when I maximize the window to 1920x1200 it becomes slower and a bit jerky, estimate 10 fps or so

would be interesting to have an fps counter or something in the demo so I can give you more accurate stats


#19

some more tests

modified an existing custom component having a quite dynamic ui that does all of its drawing in the Component::paint() override,
as follows :
[list][]removed paint(Graphics& g) override and renamed to paintOld(Graphics& g)[/]
[]derived component from OpenGLComponent instead of from Component[/]
[]added override of OpenGLComponent::renderOpenGL() which calls the paintOld() method with an OpenGLRenderer-provided Graphics object :[/][/list]

void MyComponent:renderOpenGL()
{
  OpenGLHelpers::clear (Colours::darkgrey.withAlpha (1.0f));
  OpenGLRenderer glRenderer(*this); 
  Graphics g(&glRenderer); 
  paintOld(g);
}

(I hope this is the way it’s intended to be used)

issues found:
[list][]Drawing is a lot (order of magnitude at least) slower than using regular Component + paint()
(note the clipping boundaries are equal in both cases (max area of the component) so that probably does not explain the difference)[/
]
[]There is a problem with clipping when the OpenGLComponent is a child of a Viewport and the viewport needs to show scrollbars: in that case the OpenGLComponent draws outside the boundaries of the allotted viewport space[/][/list]

tested using the tip of the modules branch, and so far tested only on Windows7, will test on OSX/IOS soon
hope this helps


#20

Yeah, the performance is annoying - some things are very very fast (e.g. large coloured areas, drawing images, vertical/horizontal lines), but edge tables and paths aren’t so good, due to the way I’ve had to do the anti-aliasing. Any suggestions by experienced openGLers as to ways I could optimise it would be appreciated!

…well yeah, of course. The GL component is a window that’s slapped on top of everything, not a normal juce component. In the future it should be possible to avoid that though, if the whole window is using GL.