1
0
Fork 0
mirror of https://github.com/juce-framework/JUCE.git synced 2026-01-15 00:24:19 +00:00

OpenGL renderer optimisations.

This commit is contained in:
jules 2011-11-04 16:09:52 +00:00
parent 2b34a17716
commit 6f71bfdf89

View file

@ -177,6 +177,7 @@ public:
GLuint textureID;
Rectangle<int> area, clip;
private:
struct EdgeTableData
{
EdgeTableData (const EdgeTable& et)
@ -285,10 +286,8 @@ namespace
void fillRectangleList (const RectangleList& list)
{
glEnableClientState (GL_VERTEX_ARRAY);
glDisableClientState (GL_TEXTURE_COORD_ARRAY);
GLfloat vertices [8];
glEnableClientState (GL_VERTEX_ARRAY);
glVertexPointer (2, GL_FLOAT, 0, vertices);
for (RectangleList::Iterator i (list); i.next();)
@ -302,6 +301,24 @@ namespace
}
}
void fillRectangleList (const RectangleList& list, const Rectangle<int>& clip)
{
GLfloat vertices [8];
glEnableClientState (GL_VERTEX_ARRAY);
glVertexPointer (2, GL_FLOAT, 0, vertices);
for (RectangleList::Iterator i (list); i.next();)
{
const Rectangle<int> r (i.getRectangle()->getIntersection (clip));
vertices[0] = vertices[4] = (GLfloat) r.getX();
vertices[1] = vertices[3] = (GLfloat) r.getY();
vertices[2] = vertices[6] = (GLfloat) r.getRight();
vertices[5] = vertices[7] = (GLfloat) r.getBottom();
glDrawArrays (GL_TRIANGLE_STRIP, 0, 4);
}
}
inline void setColour (const float alpha) noexcept
{
glColor4f (alpha, alpha, alpha, alpha);
@ -698,6 +715,123 @@ namespace
mask1, mask2, replaceExistingContents, true);
}
}
//==============================================================================
struct VariableAlphaColour
{
VariableAlphaColour (const Colour& c) noexcept
: r (c.getFloatRed()), g (c.getFloatGreen()), b (c.getFloatBlue()),
alphaScale (c.getFloatAlpha() / 255.0f), lastAlpha (-1)
{}
void setForAlpha (const int alpha) noexcept
{
if (lastAlpha != alpha)
{
lastAlpha = alpha;
const float a = alpha * alphaScale;
glColor4f (r * a, g * a, b * a, a);
}
}
private:
const float r, g, b, alphaScale;
int lastAlpha;
JUCE_DECLARE_NON_COPYABLE (VariableAlphaColour);
};
//==============================================================================
struct EdgeTableRenderer
{
EdgeTableRenderer (const Colour& c) noexcept
: colour (c)
{}
void draw (const EdgeTable& et)
{
glDisableClientState (GL_TEXTURE_COORD_ARRAY);
glEnableClientState (GL_VERTEX_ARRAY);
glVertexPointer (2, GL_FLOAT, 0, vertices);
et.iterate (*this);
}
void setEdgeTableYPos (const int y) noexcept
{
vertices[1] = vertices[5] = (GLfloat) y;
vertices[3] = vertices[7] = (GLfloat) (y + 1);
}
void handleEdgeTablePixel (const int x, const int alphaLevel) noexcept
{
drawHorizontal (x, 1, alphaLevel);
}
void handleEdgeTablePixelFull (const int x) noexcept
{
drawHorizontal (x, 1, 255);
}
void handleEdgeTableLine (const int x, const int width, const int alphaLevel) noexcept
{
drawHorizontal (x, width, alphaLevel);
}
void handleEdgeTableLineFull (const int x, const int width) noexcept
{
drawHorizontal (x, width, 255);
}
private:
GLfloat vertices[8];
VariableAlphaColour colour;
void drawHorizontal (int x, const int w, const int alpha) noexcept
{
vertices[0] = vertices[2] = (GLfloat) x;
vertices[4] = vertices[6] = (GLfloat) (x + w);
colour.setForAlpha (alpha);
glDrawArrays (GL_TRIANGLE_STRIP, 0, 4);
}
JUCE_DECLARE_NON_COPYABLE (EdgeTableRenderer);
};
//==============================================================================
struct FloatRectangleRenderer
{
FloatRectangleRenderer (const Colour& c) noexcept
: colour (c)
{}
void draw (const Rectangle<float>& r)
{
glDisableClientState (GL_TEXTURE_COORD_ARRAY);
glEnableClientState (GL_VERTEX_ARRAY);
glVertexPointer (2, GL_FLOAT, 0, vertices);
RenderingHelpers::FloatRectangleRasterisingInfo (r).iterate (*this);
}
void operator() (const int x, const int y, const int w, const int h, const int alpha)
{
vertices[0] = vertices[2] = (GLfloat) x;
vertices[1] = vertices[5] = (GLfloat) y;
vertices[4] = vertices[6] = (GLfloat) (x + w);
vertices[3] = vertices[7] = (GLfloat) (y + h);
colour.setForAlpha (alpha);
glDrawArrays (GL_TRIANGLE_STRIP, 0, 4);
}
private:
GLfloat vertices[8];
VariableAlphaColour colour;
JUCE_DECLARE_NON_COPYABLE (FloatRectangleRenderer);
};
}
//==============================================================================
@ -722,7 +856,9 @@ public:
virtual Ptr clipToTexture (const PositionedTexture&) = 0;
virtual Rectangle<int> getClipBounds() const = 0;
virtual void fillRect (const OpenGLTarget&, const Rectangle<int>& area, const FillType&, GradientTexture&, bool replaceContents) = 0;
virtual void fillRect (const OpenGLTarget&, const Rectangle<float>& area, const FillType&, GradientTexture&) = 0;
virtual void fillMask (const OpenGLTarget& target, const Rectangle<int>& area, const PositionedTexture&, const FillType&, GradientTexture&) = 0;
virtual void fillEdgeTable (const OpenGLTarget& target, EdgeTable& et, const FillType& fill, GradientTexture& gradientTexture) = 0;
virtual void drawImage (const OpenGLTarget&, const OpenGLTextureFromImage&, const AffineTransform&, float alpha,
const Rectangle<int>& clip, const PositionedTexture* mask) = 0;
@ -888,12 +1024,26 @@ public:
fillRectInternal (target, r, fill, gradientTexture, false);
}
void fillRect (const OpenGLTarget& target, const Rectangle<float>& area, const FillType& fill, GradientTexture& gradientTexture)
{
EdgeTable et (area);
fillEdgeTable (target, et, fill, gradientTexture);
}
void fillMask (const OpenGLTarget& target, const Rectangle<int>& area, const PositionedTexture& texture, const FillType& fill, GradientTexture& gradientTexture)
{
PositionedTexture pt (mask.getTextureID(), Rectangle<int> (maskOrigin.x, maskOrigin.y, mask.getWidth(), mask.getHeight()), area);
fillTexture (target, area, fill, gradientTexture, &texture, &pt, false);
}
void fillEdgeTable (const OpenGLTarget& target, EdgeTable& et, const FillType& fill, GradientTexture& gradientTexture)
{
OpenGLTexture texture;
PositionedTexture pt (texture, et, clip);
fillMask (target, pt.clip, pt, fill, gradientTexture);
}
void fillRectInternal (const OpenGLTarget& target, const Rectangle<int>& area, const FillType& fill, GradientTexture& gradientTexture, bool replaceContents)
{
PositionedTexture pt (mask.getTextureID(), Rectangle<int> (maskOrigin.x, maskOrigin.y, mask.getWidth(), mask.getHeight()), area);
@ -970,18 +1120,54 @@ public:
Ptr clipToRectangleList (const RectangleList& r) { return clip.clipTo (r) ? this : nullptr; }
Ptr excludeClipRectangle (const Rectangle<int>& r) { clip.subtract (r); return clip.isEmpty() ? nullptr : this; }
Ptr clipToTexture (const PositionedTexture& t) { return toMask()->clipToTexture (t); }
Ptr clipToTexture (const PositionedTexture& t) { return toMask()->clipToTexture (t); }
Ptr clipToPath (const Path& p, const AffineTransform& transform) { return toMask()->clipToPath (p, transform); }
Ptr clipToImageAlpha (const OpenGLTextureFromImage& image, const AffineTransform& transform) { return toMask()->clipToImageAlpha (image, transform); }
void fillRect (const OpenGLTarget& target, const Rectangle<int>& area, const FillType& fill, GradientTexture& gradientTexture, bool replaceContents)
{
for (RectangleList::Iterator i (clip); i.next();)
if (fill.isColour())
{
const Rectangle<int> r (i.getRectangle()->getIntersection (area));
disableMultiTexture();
setBlendMode (replaceContents || fill.colour.isOpaque());
setPremultipliedColour (fill.colour);
fillRectangleList (clip, area);
}
else
{
for (RectangleList::Iterator i (clip); i.next();)
{
const Rectangle<int> r (i.getRectangle()->getIntersection (area));
if (! r.isEmpty())
fillTexture (target, r, fill, gradientTexture, nullptr, nullptr, replaceContents);
if (! r.isEmpty())
fillTexture (target, r, fill, gradientTexture, nullptr, nullptr, replaceContents);
}
}
}
void fillRect (const OpenGLTarget& target, const Rectangle<float>& area, const FillType& fill, GradientTexture& gradientTexture)
{
if (fill.isColour())
{
disableMultiTexture();
setPremultipliedBlendingMode();
setPremultipliedColour (fill.colour);
for (RectangleList::Iterator i (clip); i.next();)
{
const Rectangle<float> r (i.getRectangle()->toFloat().getIntersection (area));
if (! r.isEmpty())
{
FloatRectangleRenderer frr (fill.colour);
frr.draw (r);
}
}
}
else
{
EdgeTable et (area);
fillEdgeTable (target, et, fill, gradientTexture);
}
}
@ -997,6 +1183,39 @@ public:
}
}
void fillEdgeTable (const OpenGLTarget& target, EdgeTable& et, const FillType& fill, GradientTexture& gradientTexture)
{
if (fill.isColour())
{
setPremultipliedBlendingMode();
disableMultiTexture (GL_TEXTURE2);
disableMultiTexture (GL_TEXTURE1);
disableMultiTexture (GL_TEXTURE0);
for (RectangleList::Iterator i (clip); i.next();)
{
const Rectangle<int> r (i.getRectangle()->getIntersection (et.getMaximumBounds()));
if (! r.isEmpty())
{
target.scissor (r);
EdgeTableRenderer etr (fill.colour);
etr.draw (et);
}
}
glDisable (GL_SCISSOR_TEST);
}
else
{
OpenGLTexture texture;
PositionedTexture pt (texture, et, clip.getBounds());
fillMask (target, pt.clip, pt, fill, gradientTexture);
}
}
void fillMask (const OpenGLTarget& target, const Rectangle<int>& area, const PositionedTexture& texture, const FillType& fill, GradientTexture& gradientTexture)
{
fillTexture (target, area, fill, gradientTexture, &texture, nullptr, false);
@ -1196,10 +1415,7 @@ public:
.getIntersection (clip->getClipBounds().toFloat()));
if (! c.isEmpty())
{
EdgeTable et (c);
fillEdgeTable (et);
}
clip->fillRect (target, c, getFillType(), gradientTexture);
}
else
{
@ -1332,10 +1548,7 @@ private:
void fillEdgeTable (EdgeTable& et)
{
OpenGLTexture texture;
PositionedTexture pt (texture, et, clip->getClipBounds());
clip->fillMask (target, pt.clip, pt, getFillType(), gradientTexture);
clip->fillEdgeTable (target, et, getFillType(), gradientTexture);
}
class CachedGlyphEdgeTable