Previously, code such as the following (where MyGLComponent is rendering
using an OpenGLContext) could result in GL errors, as the destruction of
the inner context unbound the array buffer and element array buffer
after use, instead of setting them to the previous values set up by the
outer context.
Additionally, a VAO was only set up in the OpenGLContext, so rendering
into a GL-backed LowLevel graphics context could fail if no VAO was
bound.
void MyGLComponent::paint (juce::Graphics& g)
{
juce::Image image { juce::Image::PixelFormat::ARGB, width, height, false, juce::OpenGLImageType() };
{
juce::Graphics innerContext { image };
// draw into innerContext
}
g.drawImage (image, juce::Rectangle<float> { width, height });
}
The OpenGL renderer uses ColourGradient::createLookupTable to generate
gradient textures. However, the tweening method used was different to
the tweening used by CoreGraphics gradients, and by the software
renderer.
Gradient tweening is now computed using non-premultiplied colours, to
ensure consistency between gradients rendered using OpenGL, and with
other renderers.
- 4.1 and 4.3 contexts can now be requested
- The requested context version is no longer ignored on Linux
- Debugging contexts are now enabled in Debug builds with GL 4.3
- Fixes a bug where glEnable(GL_TEXTURE_2D) was called in core profiles
Previously, it wasn't safe to access Font instances from multiple
threads because there was a chance that they might reference the same
shared internal state. In this case, calling getTypeface() or getAscent from
two threads simultaneously would cause a race on the typeface and ascent
data members, even though the Font instances appeared to be disjoint.
With this change in place, it is now safe to use Font instances from
multiple threads simultaneously.
It is still an error to modify the same Font instance from multiple
threads without synchronization!
// Fine:
Font a;
Font b = a;
auto futureA = std::async (std::launch::async, [&a] { /* do something with a */ });
auto futureB = std::async (std::launch::async, [&b] { /* do something with b */ });
// Bad idea:
Font f;
auto futureA = std::async (std::launch::async, [&f] { /* do something with f */ });
auto futureB = std::async (std::launch::async, [&f] { /* do something with f */ });