mirror of
https://github.com/juce-framework/JUCE.git
synced 2026-01-10 23:44:24 +00:00
Optimised the GL renderer to avoid splitting large rectangles into horizontal strips unnecessarily
This commit is contained in:
parent
ff0a72da7f
commit
9d56e2990d
7 changed files with 450 additions and 360 deletions
|
|
@ -679,7 +679,7 @@ void EdgeTable::clipEdgeTableLineToRange (int* dest, const int x1, const int x2)
|
|||
|
||||
|
||||
//==============================================================================
|
||||
void EdgeTable::clipToRectangle (const Rectangle<int>& r)
|
||||
void EdgeTable::clipToRectangle (Rectangle<int> r)
|
||||
{
|
||||
auto clipped = r.getIntersection (bounds);
|
||||
|
||||
|
|
@ -718,7 +718,7 @@ void EdgeTable::clipToRectangle (const Rectangle<int>& r)
|
|||
}
|
||||
}
|
||||
|
||||
void EdgeTable::excludeRectangle (const Rectangle<int>& r)
|
||||
void EdgeTable::excludeRectangle (Rectangle<int> r)
|
||||
{
|
||||
auto clipped = r.getIntersection (bounds);
|
||||
|
||||
|
|
|
|||
|
|
@ -72,8 +72,8 @@ public:
|
|||
~EdgeTable();
|
||||
|
||||
//==============================================================================
|
||||
void clipToRectangle (const Rectangle<int>& r);
|
||||
void excludeRectangle (const Rectangle<int>& r);
|
||||
void clipToRectangle (Rectangle<int> r);
|
||||
void excludeRectangle (Rectangle<int> r);
|
||||
void clipToEdgeTable (const EdgeTable&);
|
||||
void clipLineToMask (int x, int y, const uint8* mask, int maskStride, int numPixels);
|
||||
bool isEmpty() noexcept;
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -259,10 +259,9 @@ struct Target
|
|||
};
|
||||
|
||||
//==============================================================================
|
||||
class PositionedTexture
|
||||
struct PositionedTexture
|
||||
{
|
||||
public:
|
||||
PositionedTexture (OpenGLTexture& texture, const EdgeTable& et, const Rectangle<int>& clipRegion)
|
||||
PositionedTexture (OpenGLTexture& texture, const EdgeTable& et, Rectangle<int> clipRegion)
|
||||
: clip (clipRegion.getIntersection (et.getMaximumBounds()))
|
||||
{
|
||||
if (clip.contains (et.getMaximumBounds()))
|
||||
|
|
@ -277,7 +276,7 @@ public:
|
|||
}
|
||||
}
|
||||
|
||||
PositionedTexture (GLuint texture, const Rectangle<int> r, const Rectangle<int> clipRegion) noexcept
|
||||
PositionedTexture (GLuint texture, Rectangle<int> r, Rectangle<int> clipRegion) noexcept
|
||||
: textureID (texture), area (r), clip (clipRegion)
|
||||
{}
|
||||
|
||||
|
|
@ -328,6 +327,24 @@ private:
|
|||
memset (currentLine + x, 255, (size_t) width);
|
||||
}
|
||||
|
||||
void handleEdgeTableRectangle (int x, int y, int width, int height, int alphaLevel) noexcept
|
||||
{
|
||||
while (--height >= 0)
|
||||
{
|
||||
setEdgeTableYPos (y++);
|
||||
handleEdgeTableLine (x, width, alphaLevel);
|
||||
}
|
||||
}
|
||||
|
||||
void handleEdgeTableRectangleFull (int x, int y, int width, int height) noexcept
|
||||
{
|
||||
while (--height >= 0)
|
||||
{
|
||||
setEdgeTableYPos (y++);
|
||||
handleEdgeTableLineFull (x, width);
|
||||
}
|
||||
}
|
||||
|
||||
HeapBlock<uint8> data;
|
||||
const Rectangle<int> area;
|
||||
|
||||
|
|
@ -339,9 +356,8 @@ private:
|
|||
};
|
||||
|
||||
//==============================================================================
|
||||
class ShaderPrograms : public ReferenceCountedObject
|
||||
struct ShaderPrograms : public ReferenceCountedObject
|
||||
{
|
||||
public:
|
||||
ShaderPrograms (OpenGLContext& context)
|
||||
: solidColourProgram (context),
|
||||
solidColourMasked (context),
|
||||
|
|
@ -409,7 +425,7 @@ public:
|
|||
screenBounds (program, "screenBounds")
|
||||
{}
|
||||
|
||||
void set2DBounds (const Rectangle<float>& bounds)
|
||||
void set2DBounds (Rectangle<float> bounds)
|
||||
{
|
||||
screenBounds.set (bounds.getX(), bounds.getY(), 0.5f * bounds.getWidth(), 0.5f * bounds.getHeight());
|
||||
}
|
||||
|
|
@ -441,7 +457,7 @@ public:
|
|||
maskBounds (program, "maskBounds")
|
||||
{}
|
||||
|
||||
void setBounds (const Rectangle<int>& area, const Target& target, const GLint textureIndex) const
|
||||
void setBounds (Rectangle<int> area, const Target& target, GLint textureIndex) const
|
||||
{
|
||||
maskTexture.set (textureIndex);
|
||||
maskBounds.set (area.getX() - target.bounds.getX(),
|
||||
|
|
@ -492,11 +508,11 @@ public:
|
|||
matrix (program, "matrix")
|
||||
{}
|
||||
|
||||
void setMatrix (const Point<float> p1, const Point<float> p2, const Point<float> p3)
|
||||
void setMatrix (Point<float> p1, Point<float> p2, Point<float> p3)
|
||||
{
|
||||
const AffineTransform t (AffineTransform::fromTargetPoints (p1.x, p1.y, 0.0f, 0.0f,
|
||||
p2.x, p2.y, 1.0f, 0.0f,
|
||||
p3.x, p3.y, 0.0f, 1.0f));
|
||||
auto t = AffineTransform::fromTargetPoints (p1.x, p1.y, 0.0f, 0.0f,
|
||||
p2.x, p2.y, 1.0f, 0.0f,
|
||||
p3.x, p3.y, 0.0f, 1.0f);
|
||||
const GLfloat m[] = { t.mat00, t.mat01, t.mat02, t.mat10, t.mat11, t.mat12 };
|
||||
matrix.set (m, 6);
|
||||
}
|
||||
|
|
@ -637,15 +653,13 @@ public:
|
|||
imageLimits (program, "imageLimits")
|
||||
{}
|
||||
|
||||
void setMatrix (const AffineTransform& trans,
|
||||
const int imageWidth, const int imageHeight,
|
||||
void setMatrix (const AffineTransform& trans, int imageWidth, int imageHeight,
|
||||
float fullWidthProportion, float fullHeightProportion,
|
||||
const float targetX, const float targetY,
|
||||
const bool isForTiling) const
|
||||
float targetX, float targetY, bool isForTiling) const
|
||||
{
|
||||
const AffineTransform t (trans.translated (-targetX, -targetY)
|
||||
.inverted().scaled (fullWidthProportion / imageWidth,
|
||||
fullHeightProportion / imageHeight));
|
||||
auto t = trans.translated (-targetX, -targetY)
|
||||
.inverted().scaled (fullWidthProportion / imageWidth,
|
||||
fullHeightProportion / imageHeight);
|
||||
|
||||
const GLfloat m[] = { t.mat00, t.mat01, t.mat02, t.mat10, t.mat11, t.mat12 };
|
||||
matrix.set (m, 6);
|
||||
|
|
@ -660,8 +674,7 @@ public:
|
|||
}
|
||||
|
||||
void setMatrix (const AffineTransform& trans, const TextureInfo& textureInfo,
|
||||
const float targetX, const float targetY,
|
||||
bool isForTiling) const
|
||||
float targetX, float targetY, bool isForTiling) const
|
||||
{
|
||||
setMatrix (trans,
|
||||
textureInfo.imageWidth, textureInfo.imageHeight,
|
||||
|
|
@ -828,13 +841,13 @@ struct StateHelpers
|
|||
srcFunction = dstFunction = 0;
|
||||
}
|
||||
|
||||
template <class QuadQueueType>
|
||||
template <typename QuadQueueType>
|
||||
void setPremultipliedBlendingMode (QuadQueueType& quadQueue) noexcept
|
||||
{
|
||||
setBlendFunc (quadQueue, GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
|
||||
}
|
||||
|
||||
template <class QuadQueueType>
|
||||
template <typename QuadQueueType>
|
||||
void setBlendFunc (QuadQueueType& quadQueue, GLenum src, GLenum dst)
|
||||
{
|
||||
if (! blendingEnabled)
|
||||
|
|
@ -853,7 +866,7 @@ struct StateHelpers
|
|||
}
|
||||
}
|
||||
|
||||
template <class QuadQueueType>
|
||||
template <typename QuadQueueType>
|
||||
void disableBlend (QuadQueueType& quadQueue) noexcept
|
||||
{
|
||||
if (blendingEnabled)
|
||||
|
|
@ -864,8 +877,8 @@ struct StateHelpers
|
|||
}
|
||||
}
|
||||
|
||||
template <class QuadQueueType>
|
||||
void setBlendMode (QuadQueueType& quadQueue, const bool replaceExistingContents) noexcept
|
||||
template <typename QuadQueueType>
|
||||
void setBlendMode (QuadQueueType& quadQueue, bool replaceExistingContents) noexcept
|
||||
{
|
||||
if (replaceExistingContents)
|
||||
disableBlend (quadQueue);
|
||||
|
|
@ -879,42 +892,54 @@ struct StateHelpers
|
|||
};
|
||||
|
||||
//==============================================================================
|
||||
template <class QuadQueueType>
|
||||
template <typename QuadQueueType>
|
||||
struct EdgeTableRenderer
|
||||
{
|
||||
EdgeTableRenderer (QuadQueueType& q, const PixelARGB c) noexcept
|
||||
EdgeTableRenderer (QuadQueueType& q, PixelARGB c) noexcept
|
||||
: quadQueue (q), colour (c)
|
||||
{}
|
||||
|
||||
void setEdgeTableYPos (const int y) noexcept
|
||||
void setEdgeTableYPos (int y) noexcept
|
||||
{
|
||||
currentY = y;
|
||||
}
|
||||
|
||||
void handleEdgeTablePixel (const int x, const int alphaLevel) noexcept
|
||||
void handleEdgeTablePixel (int x, int alphaLevel) noexcept
|
||||
{
|
||||
PixelARGB c (colour);
|
||||
auto c = colour;
|
||||
c.multiplyAlpha (alphaLevel);
|
||||
quadQueue.add (x, currentY, 1, 1, c);
|
||||
}
|
||||
|
||||
void handleEdgeTablePixelFull (const int x) noexcept
|
||||
void handleEdgeTablePixelFull (int x) noexcept
|
||||
{
|
||||
quadQueue.add (x, currentY, 1, 1, colour);
|
||||
}
|
||||
|
||||
void handleEdgeTableLine (const int x, const int width, const int alphaLevel) noexcept
|
||||
void handleEdgeTableLine (int x, int width, int alphaLevel) noexcept
|
||||
{
|
||||
PixelARGB c (colour);
|
||||
auto c = colour;
|
||||
c.multiplyAlpha (alphaLevel);
|
||||
quadQueue.add (x, currentY, width, 1, c);
|
||||
}
|
||||
|
||||
void handleEdgeTableLineFull (const int x, const int width) noexcept
|
||||
void handleEdgeTableLineFull (int x, int width) noexcept
|
||||
{
|
||||
quadQueue.add (x, currentY, width, 1, colour);
|
||||
}
|
||||
|
||||
void handleEdgeTableRectangle (int x, int y, int width, int height, int alphaLevel) noexcept
|
||||
{
|
||||
auto c = colour;
|
||||
c.multiplyAlpha (alphaLevel);
|
||||
quadQueue.add (x, y, width, height, c);
|
||||
}
|
||||
|
||||
void handleEdgeTableRectangleFull (int x, int y, int width, int height) noexcept
|
||||
{
|
||||
quadQueue.add (x, y, width, height, colour);
|
||||
}
|
||||
|
||||
private:
|
||||
QuadQueueType& quadQueue;
|
||||
const PixelARGB colour;
|
||||
|
|
@ -923,14 +948,14 @@ struct StateHelpers
|
|||
JUCE_DECLARE_NON_COPYABLE (EdgeTableRenderer)
|
||||
};
|
||||
|
||||
template <class QuadQueueType>
|
||||
template <typename QuadQueueType>
|
||||
struct FloatRectangleRenderer
|
||||
{
|
||||
FloatRectangleRenderer (QuadQueueType& q, const PixelARGB c) noexcept
|
||||
FloatRectangleRenderer (QuadQueueType& q, PixelARGB c) noexcept
|
||||
: quadQueue (q), colour (c)
|
||||
{}
|
||||
|
||||
void operator() (const int x, const int y, const int w, const int h, const int alpha) noexcept
|
||||
void operator() (int x, int y, int w, int h, int alpha) noexcept
|
||||
{
|
||||
if (w > 0 && h > 0)
|
||||
{
|
||||
|
|
@ -959,8 +984,8 @@ struct StateHelpers
|
|||
zeromem (currentTextureID, sizeof (currentTextureID));
|
||||
}
|
||||
|
||||
template <class QuadQueueType>
|
||||
void setTexturesEnabled (QuadQueueType& quadQueue, const int textureIndexMask) noexcept
|
||||
template <typename QuadQueueType>
|
||||
void setTexturesEnabled (QuadQueueType& quadQueue, int textureIndexMask) noexcept
|
||||
{
|
||||
if (texturesEnabled != textureIndexMask)
|
||||
{
|
||||
|
|
@ -991,20 +1016,20 @@ struct StateHelpers
|
|||
}
|
||||
}
|
||||
|
||||
template <class QuadQueueType>
|
||||
template <typename QuadQueueType>
|
||||
void disableTextures (QuadQueueType& quadQueue) noexcept
|
||||
{
|
||||
setTexturesEnabled (quadQueue, 0);
|
||||
}
|
||||
|
||||
template <class QuadQueueType>
|
||||
template <typename QuadQueueType>
|
||||
void setSingleTextureMode (QuadQueueType& quadQueue) noexcept
|
||||
{
|
||||
setTexturesEnabled (quadQueue, 1);
|
||||
setActiveTexture (0);
|
||||
}
|
||||
|
||||
template <class QuadQueueType>
|
||||
template <typename QuadQueueType>
|
||||
void setTwoTextureMode (QuadQueueType& quadQueue, GLuint texture1, GLuint texture2)
|
||||
{
|
||||
JUCE_CHECK_OPENGL_ERROR
|
||||
|
|
@ -1026,7 +1051,7 @@ struct StateHelpers
|
|||
JUCE_CHECK_OPENGL_ERROR
|
||||
}
|
||||
|
||||
void setActiveTexture (const int index) noexcept
|
||||
void setActiveTexture (int index) noexcept
|
||||
{
|
||||
if (currentActiveTexture != index)
|
||||
{
|
||||
|
|
@ -1036,13 +1061,13 @@ struct StateHelpers
|
|||
}
|
||||
}
|
||||
|
||||
void bindTexture (const GLuint textureID) noexcept
|
||||
void bindTexture (GLuint textureID) noexcept
|
||||
{
|
||||
jassert (currentActiveTexture >= 0);
|
||||
|
||||
if (currentTextureID [currentActiveTexture] != textureID)
|
||||
if (currentTextureID[currentActiveTexture] != textureID)
|
||||
{
|
||||
currentTextureID [currentActiveTexture] = textureID;
|
||||
currentTextureID[currentActiveTexture] = textureID;
|
||||
glBindTexture (GL_TEXTURE_2D, textureID);
|
||||
JUCE_CHECK_OPENGL_ERROR
|
||||
}
|
||||
|
|
@ -1057,7 +1082,7 @@ struct StateHelpers
|
|||
}
|
||||
|
||||
private:
|
||||
GLuint currentTextureID [3];
|
||||
GLuint currentTextureID[3];
|
||||
int texturesEnabled, currentActiveTexture;
|
||||
const OpenGLContext& context;
|
||||
|
||||
|
|
@ -1067,9 +1092,7 @@ struct StateHelpers
|
|||
//==============================================================================
|
||||
struct TextureCache
|
||||
{
|
||||
TextureCache() noexcept
|
||||
: activeGradientIndex (0), gradientNeedsRefresh (true)
|
||||
{}
|
||||
TextureCache() noexcept {}
|
||||
|
||||
OpenGLTexture* getTexture (ActiveTextures& activeTextures, int w, int h)
|
||||
{
|
||||
|
|
@ -1081,7 +1104,8 @@ struct StateHelpers
|
|||
|
||||
for (int i = 0; i < numTexturesToCache - 2; ++i)
|
||||
{
|
||||
const OpenGLTexture* const t = textures.getUnchecked(i);
|
||||
auto* t = textures.getUnchecked(i);
|
||||
|
||||
if (t->getWidth() == w && t->getHeight() == h)
|
||||
return textures.removeAndReturn (i);
|
||||
}
|
||||
|
|
@ -1112,7 +1136,7 @@ struct StateHelpers
|
|||
}
|
||||
|
||||
JUCE_CHECK_OPENGL_ERROR;
|
||||
PixelARGB lookup [gradientTextureSize];
|
||||
PixelARGB lookup[gradientTextureSize];
|
||||
gradient.createLookupTable (lookup, gradientTextureSize);
|
||||
gradientTextures.getUnchecked (activeGradientIndex)->loadARGB (lookup, gradientTextureSize, 1);
|
||||
}
|
||||
|
|
@ -1125,15 +1149,14 @@ struct StateHelpers
|
|||
private:
|
||||
enum { numTexturesToCache = 8, numGradientTexturesToCache = 10 };
|
||||
OwnedArray<OpenGLTexture> textures, gradientTextures;
|
||||
int activeGradientIndex;
|
||||
bool gradientNeedsRefresh;
|
||||
int activeGradientIndex = 0;
|
||||
bool gradientNeedsRefresh = true;
|
||||
};
|
||||
|
||||
//==============================================================================
|
||||
struct ShaderQuadQueue
|
||||
{
|
||||
ShaderQuadQueue (const OpenGLContext& c) noexcept
|
||||
: context (c), numVertices (0)
|
||||
ShaderQuadQueue (const OpenGLContext& c) noexcept : context (c)
|
||||
{}
|
||||
|
||||
~ShaderQuadQueue() noexcept
|
||||
|
|
@ -1147,6 +1170,7 @@ struct StateHelpers
|
|||
void initialise() noexcept
|
||||
{
|
||||
JUCE_CHECK_OPENGL_ERROR
|
||||
|
||||
for (int i = 0, v = 0; i < numQuads * 6; i += 6, v += 4)
|
||||
{
|
||||
indexData[i] = (GLushort) v;
|
||||
|
|
@ -1163,22 +1187,22 @@ struct StateHelpers
|
|||
JUCE_CHECK_OPENGL_ERROR
|
||||
}
|
||||
|
||||
void add (const int x, const int y, const int w, const int h, const PixelARGB colour) noexcept
|
||||
void add (int x, int y, int w, int h, PixelARGB colour) noexcept
|
||||
{
|
||||
jassert (w > 0 && h > 0);
|
||||
|
||||
VertexInfo* const v = vertexData + numVertices;
|
||||
auto* v = vertexData + numVertices;
|
||||
v[0].x = v[2].x = (GLshort) x;
|
||||
v[0].y = v[1].y = (GLshort) y;
|
||||
v[1].x = v[3].x = (GLshort) (x + w);
|
||||
v[2].y = v[3].y = (GLshort) (y + h);
|
||||
|
||||
#if JUCE_BIG_ENDIAN
|
||||
const GLuint rgba = (GLuint) ((colour.getRed() << 24) | (colour.getGreen() << 16)
|
||||
| (colour.getBlue() << 8) | colour.getAlpha());
|
||||
auto rgba = (GLuint) ((colour.getRed() << 24) | (colour.getGreen() << 16)
|
||||
| (colour.getBlue() << 8) | colour.getAlpha());
|
||||
#else
|
||||
const GLuint rgba = (GLuint) ((colour.getAlpha() << 24) | (colour.getBlue() << 16)
|
||||
| (colour.getGreen() << 8) | colour.getRed());
|
||||
auto rgba = (GLuint) ((colour.getAlpha() << 24) | (colour.getBlue() << 16)
|
||||
| (colour.getGreen() << 8) | colour.getRed());
|
||||
#endif
|
||||
|
||||
v[0].colour = rgba;
|
||||
|
|
@ -1192,24 +1216,24 @@ struct StateHelpers
|
|||
draw();
|
||||
}
|
||||
|
||||
void add (const Rectangle<int>& r, const PixelARGB colour) noexcept
|
||||
void add (Rectangle<int> r, PixelARGB colour) noexcept
|
||||
{
|
||||
add (r.getX(), r.getY(), r.getWidth(), r.getHeight(), colour);
|
||||
}
|
||||
|
||||
void add (const Rectangle<float>& r, const PixelARGB colour) noexcept
|
||||
void add (Rectangle<float> r, PixelARGB colour) noexcept
|
||||
{
|
||||
FloatRectangleRenderer<ShaderQuadQueue> frr (*this, colour);
|
||||
RenderingHelpers::FloatRectangleRasterisingInfo (r).iterate (frr);
|
||||
}
|
||||
|
||||
void add (const RectangleList<int>& list, const PixelARGB colour) noexcept
|
||||
void add (const RectangleList<int>& list, PixelARGB colour) noexcept
|
||||
{
|
||||
for (auto& i : list)
|
||||
add (i, colour);
|
||||
}
|
||||
|
||||
void add (const RectangleList<int>& list, const Rectangle<int>& clip, const PixelARGB colour) noexcept
|
||||
void add (const RectangleList<int>& list, Rectangle<int> clip, PixelARGB colour) noexcept
|
||||
{
|
||||
for (auto& i : list)
|
||||
{
|
||||
|
|
@ -1220,8 +1244,8 @@ struct StateHelpers
|
|||
}
|
||||
}
|
||||
|
||||
template <class IteratorType>
|
||||
void add (const IteratorType& et, const PixelARGB colour)
|
||||
template <typename IteratorType>
|
||||
void add (const IteratorType& et, PixelARGB colour)
|
||||
{
|
||||
EdgeTableRenderer<ShaderQuadQueue> etr (*this, colour);
|
||||
et.iterate (etr);
|
||||
|
|
@ -1243,10 +1267,10 @@ struct StateHelpers
|
|||
enum { numQuads = 256 };
|
||||
|
||||
GLuint buffers[2];
|
||||
VertexInfo vertexData [numQuads * 4];
|
||||
GLushort indexData [numQuads * 6];
|
||||
VertexInfo vertexData[numQuads * 4];
|
||||
GLushort indexData[numQuads * 6];
|
||||
const OpenGLContext& context;
|
||||
int numVertices;
|
||||
int numVertices = 0;
|
||||
|
||||
void draw() noexcept
|
||||
{
|
||||
|
|
@ -1264,10 +1288,9 @@ struct StateHelpers
|
|||
//==============================================================================
|
||||
struct CurrentShader
|
||||
{
|
||||
CurrentShader (OpenGLContext& c) noexcept
|
||||
: context (c), activeShader (nullptr)
|
||||
CurrentShader (OpenGLContext& c) noexcept : context (c)
|
||||
{
|
||||
const char programValueID[] = "GraphicsContextPrograms";
|
||||
auto programValueID = "GraphicsContextPrograms";
|
||||
programs = static_cast<ShaderPrograms*> (context.getAssociatedObject (programValueID));
|
||||
|
||||
if (programs == nullptr)
|
||||
|
|
@ -1282,7 +1305,7 @@ struct StateHelpers
|
|||
jassert (activeShader == nullptr);
|
||||
}
|
||||
|
||||
void setShader (const Rectangle<int>& bounds, ShaderQuadQueue& quadQueue, ShaderPrograms::ShaderBase& shader)
|
||||
void setShader (Rectangle<int> bounds, ShaderQuadQueue& quadQueue, ShaderPrograms::ShaderBase& shader)
|
||||
{
|
||||
if (activeShader != &shader)
|
||||
{
|
||||
|
|
@ -1324,7 +1347,7 @@ struct StateHelpers
|
|||
ShaderPrograms::Ptr programs;
|
||||
|
||||
private:
|
||||
ShaderPrograms::ShaderBase* activeShader;
|
||||
ShaderPrograms::ShaderBase* activeShader = nullptr;
|
||||
Rectangle<int> currentBounds;
|
||||
|
||||
CurrentShader& operator= (const CurrentShader&);
|
||||
|
|
@ -1332,9 +1355,8 @@ struct StateHelpers
|
|||
};
|
||||
|
||||
//==============================================================================
|
||||
class GLState
|
||||
struct GLState
|
||||
{
|
||||
public:
|
||||
GLState (const Target& t) noexcept
|
||||
: target (t),
|
||||
activeTextures (t.context),
|
||||
|
|
@ -1375,7 +1397,7 @@ public:
|
|||
}
|
||||
|
||||
void setShaderForGradientFill (const ColourGradient& g, const AffineTransform& transform,
|
||||
const int maskTextureID, const Rectangle<int>* const maskArea)
|
||||
int maskTextureID, const Rectangle<int>* maskArea)
|
||||
{
|
||||
JUCE_CHECK_OPENGL_ERROR
|
||||
activeTextures.disableTextures (shaderQuadQueue);
|
||||
|
|
@ -1396,12 +1418,12 @@ public:
|
|||
textureCache.bindTextureForGradient (activeTextures, g);
|
||||
}
|
||||
|
||||
const AffineTransform t (transform.translated (0.5f - target.bounds.getX(),
|
||||
0.5f - target.bounds.getY()));
|
||||
Point<float> p1 (g.point1.transformedBy (t));
|
||||
const Point<float> p2 (g.point2.transformedBy (t));
|
||||
const Point<float> p3 (Point<float> (g.point1.x + (g.point2.y - g.point1.y),
|
||||
g.point1.y - (g.point2.x - g.point1.x)).transformedBy (t));
|
||||
auto t = transform.translated (0.5f - target.bounds.getX(),
|
||||
0.5f - target.bounds.getY());
|
||||
auto p1 = g.point1.transformedBy (t);
|
||||
auto p2 = g.point2.transformedBy (t);
|
||||
auto p3 = Point<float> (g.point1.x + (g.point2.y - g.point1.y),
|
||||
g.point1.y - (g.point2.x - g.point1.x)).transformedBy (t);
|
||||
|
||||
ShaderPrograms* const programs = currentShader.programs;
|
||||
const ShaderPrograms::MaskedShaderParams* maskParams = nullptr;
|
||||
|
|
@ -1476,7 +1498,7 @@ public:
|
|||
}
|
||||
|
||||
void setShaderForTiledImageFill (const TextureInfo& textureInfo, const AffineTransform& transform,
|
||||
const int maskTextureID, const Rectangle<int>* const maskArea, bool isTiledFill)
|
||||
int maskTextureID, const Rectangle<int>* maskArea, bool isTiledFill)
|
||||
{
|
||||
blendMode.setPremultipliedBlendingMode (shaderQuadQueue);
|
||||
|
||||
|
|
@ -1540,29 +1562,26 @@ private:
|
|||
};
|
||||
|
||||
//==============================================================================
|
||||
class SavedState : public RenderingHelpers::SavedStateBase<SavedState>
|
||||
struct SavedState : public RenderingHelpers::SavedStateBase<SavedState>
|
||||
{
|
||||
typedef RenderingHelpers::SavedStateBase<SavedState> BaseClass;
|
||||
|
||||
public:
|
||||
SavedState (GLState* const s)
|
||||
: BaseClass (s->target.bounds), state (s), isUsingCustomShader (false)
|
||||
SavedState (GLState* s) : BaseClass (s->target.bounds), state (s)
|
||||
{}
|
||||
|
||||
SavedState (const SavedState& other)
|
||||
: BaseClass (other), font (other.font),
|
||||
state (other.state), isUsingCustomShader (false),
|
||||
: BaseClass (other), font (other.font), state (other.state),
|
||||
transparencyLayer (other.transparencyLayer),
|
||||
previousTarget (other.previousTarget.createCopy())
|
||||
{}
|
||||
|
||||
SavedState* beginTransparencyLayer (float opacity)
|
||||
{
|
||||
SavedState* const s = new SavedState (*this);
|
||||
auto* s = new SavedState (*this);
|
||||
|
||||
if (clip != nullptr)
|
||||
{
|
||||
const Rectangle<int> clipBounds (clip->getClipBounds());
|
||||
auto clipBounds = clip->getClipBounds();
|
||||
|
||||
state->flush();
|
||||
s->transparencyLayer = Image (OpenGLImageType().create (Image::ARGB, clipBounds.getWidth(), clipBounds.getHeight(), true));
|
||||
|
|
@ -1588,7 +1607,7 @@ public:
|
|||
finishedLayerState.previousTarget.reset();
|
||||
|
||||
state->target.makeActive();
|
||||
const Rectangle<int> clipBounds (clip->getClipBounds());
|
||||
auto clipBounds = clip->getClipBounds();
|
||||
|
||||
clip->renderImageUntransformed (*this, finishedLayerState.transparencyLayer,
|
||||
(int) (finishedLayerState.transparencyLayerAlpha * 255.0f),
|
||||
|
|
@ -1604,8 +1623,7 @@ public:
|
|||
{
|
||||
if (trans.isOnlyTranslation() && ! transform.isRotated)
|
||||
{
|
||||
GlyphCacheType& cache = GlyphCacheType::getInstance();
|
||||
|
||||
auto& cache = GlyphCacheType::getInstance();
|
||||
Point<float> pos (trans.getTranslationX(), trans.getTranslationY());
|
||||
|
||||
if (transform.isOnlyTranslated)
|
||||
|
|
@ -1619,7 +1637,8 @@ public:
|
|||
Font f (font);
|
||||
f.setHeight (font.getHeight() * transform.complexTransform.mat11);
|
||||
|
||||
const float xScale = transform.complexTransform.mat00 / transform.complexTransform.mat11;
|
||||
auto xScale = transform.complexTransform.mat00 / transform.complexTransform.mat11;
|
||||
|
||||
if (std::abs (xScale - 1.0f) > 0.01f)
|
||||
f.setHorizontalScale (xScale);
|
||||
|
||||
|
|
@ -1628,10 +1647,10 @@ public:
|
|||
}
|
||||
else
|
||||
{
|
||||
const float fontHeight = font.getHeight();
|
||||
auto fontHeight = font.getHeight();
|
||||
|
||||
AffineTransform t (transform.getTransformWith (AffineTransform::scale (fontHeight * font.getHorizontalScale(), fontHeight)
|
||||
.followedBy (trans)));
|
||||
auto t = transform.getTransformWith (AffineTransform::scale (fontHeight * font.getHorizontalScale(), fontHeight)
|
||||
.followedBy (trans));
|
||||
|
||||
const ScopedPointer<EdgeTable> et (font.getTypeface()->getEdgeTableForGlyph (glyphNumber, t, fontHeight));
|
||||
|
||||
|
|
@ -1651,7 +1670,7 @@ public:
|
|||
|
||||
//==============================================================================
|
||||
template <typename IteratorType>
|
||||
void renderImageTransformed (IteratorType& iter, const Image& src, const int alpha,
|
||||
void renderImageTransformed (IteratorType& iter, const Image& src, int alpha,
|
||||
const AffineTransform& trans, Graphics::ResamplingQuality, bool tiledFill) const
|
||||
{
|
||||
state->shaderQuadQueue.flush();
|
||||
|
|
@ -1664,14 +1683,14 @@ public:
|
|||
}
|
||||
|
||||
template <typename IteratorType>
|
||||
void renderImageUntransformed (IteratorType& iter, const Image& src, const int alpha, int x, int y, bool tiledFill) const
|
||||
void renderImageUntransformed (IteratorType& iter, const Image& src, int alpha, int x, int y, bool tiledFill) const
|
||||
{
|
||||
renderImageTransformed (iter, src, alpha, AffineTransform::translation ((float) x, (float) y),
|
||||
Graphics::lowResamplingQuality, tiledFill);
|
||||
}
|
||||
|
||||
template <typename IteratorType>
|
||||
void fillWithSolidColour (IteratorType& iter, const PixelARGB colour, bool replaceContents) const
|
||||
void fillWithSolidColour (IteratorType& iter, PixelARGB colour, bool replaceContents) const
|
||||
{
|
||||
if (! isUsingCustomShader)
|
||||
{
|
||||
|
|
@ -1690,7 +1709,7 @@ public:
|
|||
state->shaderQuadQueue.add (iter, fillType.colour.getPixelARGB());
|
||||
}
|
||||
|
||||
void fillRectWithCustomShader (OpenGLRendering::ShaderPrograms::ShaderBase& shader, const Rectangle<int>& area)
|
||||
void fillRectWithCustomShader (OpenGLRendering::ShaderPrograms::ShaderBase& shader, Rectangle<int> area)
|
||||
{
|
||||
state->setShader (shader);
|
||||
isUsingCustomShader = true;
|
||||
|
|
@ -1704,7 +1723,7 @@ public:
|
|||
//==============================================================================
|
||||
Font font;
|
||||
GLState* state;
|
||||
bool isUsingCustomShader;
|
||||
bool isUsingCustomShader = false;
|
||||
|
||||
private:
|
||||
Image transparencyLayer;
|
||||
|
|
@ -1715,15 +1734,14 @@ private:
|
|||
|
||||
|
||||
//==============================================================================
|
||||
class ShaderContext : public RenderingHelpers::StackBasedLowLevelGraphicsContext<SavedState>
|
||||
struct ShaderContext : public RenderingHelpers::StackBasedLowLevelGraphicsContext<SavedState>
|
||||
{
|
||||
public:
|
||||
ShaderContext (const Target& target) : glState (target)
|
||||
{
|
||||
stack.initialise (new SavedState (&glState));
|
||||
}
|
||||
|
||||
void fillRectWithCustomShader (ShaderPrograms::ShaderBase& shader, const Rectangle<int>& area)
|
||||
void fillRectWithCustomShader (ShaderPrograms::ShaderBase& shader, Rectangle<int> area)
|
||||
{
|
||||
static_cast<SavedState&> (*stack).fillRectWithCustomShader (shader, area);
|
||||
}
|
||||
|
|
@ -1733,9 +1751,8 @@ public:
|
|||
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ShaderContext)
|
||||
};
|
||||
|
||||
class NonShaderContext : public LowLevelGraphicsSoftwareRenderer
|
||||
struct NonShaderContext : public LowLevelGraphicsSoftwareRenderer
|
||||
{
|
||||
public:
|
||||
NonShaderContext (const Target& t, const Image& im)
|
||||
: LowLevelGraphicsSoftwareRenderer (im), target (t), image (im)
|
||||
{}
|
||||
|
|
@ -1743,7 +1760,7 @@ public:
|
|||
~NonShaderContext()
|
||||
{
|
||||
JUCE_CHECK_OPENGL_ERROR
|
||||
const GLuint previousFrameBufferTarget = OpenGLFrameBuffer::getCurrentFrameBufferTarget();
|
||||
auto previousFrameBufferTarget = OpenGLFrameBuffer::getCurrentFrameBufferTarget();
|
||||
|
||||
#if ! JUCE_ANDROID
|
||||
target.context.extensions.glActiveTexture (GL_TEXTURE0);
|
||||
|
|
@ -1803,7 +1820,7 @@ LowLevelGraphicsContext* createOpenGLGraphicsContext (OpenGLContext& context, in
|
|||
|
||||
LowLevelGraphicsContext* createOpenGLGraphicsContext (OpenGLContext& context, OpenGLFrameBuffer& target)
|
||||
{
|
||||
return OpenGLRendering::createOpenGLContext (OpenGLRendering::Target (context, target, Point<int>()));
|
||||
return OpenGLRendering::createOpenGLContext (OpenGLRendering::Target (context, target, {}));
|
||||
}
|
||||
|
||||
LowLevelGraphicsContext* createOpenGLGraphicsContext (OpenGLContext& context, unsigned int frameBufferID, int width, int height)
|
||||
|
|
@ -1822,7 +1839,7 @@ struct CustomProgram : public ReferenceCountedObject,
|
|||
|
||||
static CustomProgram* get (const String& hashName)
|
||||
{
|
||||
if (OpenGLContext* c = OpenGLContext::getCurrentContext())
|
||||
if (auto* c = OpenGLContext::getCurrentContext())
|
||||
return static_cast<CustomProgram*> (c->getAssociatedObject (hashName.toRawUTF8()));
|
||||
|
||||
return nullptr;
|
||||
|
|
@ -1830,13 +1847,12 @@ struct CustomProgram : public ReferenceCountedObject,
|
|||
|
||||
static CustomProgram* getOrCreate (LowLevelGraphicsContext& gc, const String& hashName, const String& code, String& errorMessage)
|
||||
{
|
||||
if (CustomProgram* c = get (hashName))
|
||||
if (auto* c = get (hashName))
|
||||
return c;
|
||||
|
||||
if (OpenGLRendering::ShaderContext* sc = dynamic_cast<OpenGLRendering::ShaderContext*> (&gc))
|
||||
if (auto* sc = dynamic_cast<OpenGLRendering::ShaderContext*> (&gc))
|
||||
{
|
||||
ReferenceCountedObjectPtr<CustomProgram> c (new CustomProgram (*sc, code));
|
||||
|
||||
errorMessage = c->lastError;
|
||||
|
||||
if (errorMessage.isEmpty())
|
||||
|
|
@ -1879,7 +1895,7 @@ OpenGLShaderProgram* OpenGLGraphicsContextCustomShader::getProgram (LowLevelGrap
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
void OpenGLGraphicsContextCustomShader::fillRect (LowLevelGraphicsContext& gc, const Rectangle<int>& area) const
|
||||
void OpenGLGraphicsContextCustomShader::fillRect (LowLevelGraphicsContext& gc, Rectangle<int> area) const
|
||||
{
|
||||
String errorMessage;
|
||||
|
||||
|
|
|
|||
|
|
@ -79,7 +79,7 @@ struct JUCE_API OpenGLGraphicsContextCustomShader
|
|||
OpenGLShaderProgram* getProgram (LowLevelGraphicsContext&) const;
|
||||
|
||||
/** Applies the shader to a rectangle within the graphics context. */
|
||||
void fillRect (LowLevelGraphicsContext&, const Rectangle<int>& area) const;
|
||||
void fillRect (LowLevelGraphicsContext&, Rectangle<int> area) const;
|
||||
|
||||
/** Attempts to compile the program if necessary, and returns an error message if it fails. */
|
||||
Result checkCompilation (LowLevelGraphicsContext&);
|
||||
|
|
|
|||
|
|
@ -76,7 +76,7 @@ void OpenGLHelpers::clear (Colour colour)
|
|||
glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
|
||||
}
|
||||
|
||||
void OpenGLHelpers::enableScissorTest (const Rectangle<int>& clip)
|
||||
void OpenGLHelpers::enableScissorTest (Rectangle<int> clip)
|
||||
{
|
||||
glEnable (GL_SCISSOR_TEST);
|
||||
glScissor (clip.getX(), clip.getY(), clip.getWidth(), clip.getHeight());
|
||||
|
|
|
|||
|
|
@ -43,7 +43,7 @@ public:
|
|||
/** Clears the current context using the given colour. */
|
||||
static void clear (Colour colour);
|
||||
|
||||
static void enableScissorTest (const Rectangle<int>& clip);
|
||||
static void enableScissorTest (Rectangle<int> clip);
|
||||
|
||||
/** Checks whether the current context supports the specified extension. */
|
||||
static bool isExtensionSupported (const char* extensionName);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue