Browse Source

ImageButton fix. OpenGL refactoring.

tags/2021-05-28
jules 14 years ago
parent
commit
b23e5c4515
14 changed files with 136 additions and 300 deletions
  1. +1
    -1
      modules/juce_core/native/juce_posix_SharedCode.h
  2. +2
    -2
      modules/juce_graphics/native/juce_RenderingHelpers.h
  3. +8
    -6
      modules/juce_gui_basics/buttons/juce_ImageButton.cpp
  4. +5
    -0
      modules/juce_opengl/native/juce_android_OpenGLComponent.cpp
  5. +6
    -0
      modules/juce_opengl/native/juce_ios_OpenGLComponent.mm
  6. +7
    -0
      modules/juce_opengl/native/juce_linux_OpenGLComponent.cpp
  7. +6
    -0
      modules/juce_opengl/native/juce_mac_OpenGLComponent.mm
  8. +6
    -0
      modules/juce_opengl/native/juce_win32_OpenGLComponent.cpp
  9. +25
    -48
      modules/juce_opengl/opengl/juce_OpenGLFrameBuffer.cpp
  10. +0
    -13
      modules/juce_opengl/opengl/juce_OpenGLFrameBuffer.h
  11. +54
    -224
      modules/juce_opengl/opengl/juce_OpenGLHelpers.cpp
  12. +12
    -1
      modules/juce_opengl/opengl/juce_OpenGLHelpers.h
  13. +0
    -5
      modules/juce_opengl/opengl/juce_OpenGLRenderingTarget.h
  14. +4
    -0
      modules/juce_opengl/opengl/juce_OpenGLTexture.cpp

+ 1
- 1
modules/juce_core/native/juce_posix_SharedCode.h View File

@@ -771,7 +771,7 @@ void InterProcessLock::exit()
//==============================================================================
void JUCE_API juce_threadEntryPoint (void*);
void* threadEntryProc (void* userData)
extern "C" void* threadEntryProc (void* userData)
{
JUCE_AUTORELEASEPOOL


+ 2
- 2
modules/juce_graphics/native/juce_RenderingHelpers.h View File

@@ -77,7 +77,7 @@ public:
{
if (isOnlyTranslated
&& t.isOnlyTranslation()
&& isIntegerTranlation (t))
&& isIntegerTranslation (t))
{
xOffset += (int) t.getTranslationX();
yOffset += (int) t.getTranslationY();
@@ -126,7 +126,7 @@ public:
bool isOnlyTranslated;
private:
static inline bool isIntegerTranlation (const AffineTransform& t) noexcept
static inline bool isIntegerTranslation (const AffineTransform& t) noexcept
{
const int tx = (int) (t.getTranslationX() * 256.0f);
const int ty = (int) (t.getTranslationY() * 256.0f);


+ 8
- 6
modules/juce_gui_basics/buttons/juce_ImageButton.cpp View File

@@ -129,16 +129,16 @@ void ImageButton::paintButton (Graphics& g,
const int ih = im.getHeight();
imageW = getWidth();
imageH = getHeight();
imageX = (imageW - iw) >> 1;
imageY = (imageH - ih) >> 1;
imageX = (imageW - iw) / 2;
imageY = (imageH - ih) / 2;
if (scaleImageToFit)
{
if (preserveProportions)
{
int newW, newH;
const float imRatio = ih / (float)iw;
const float destRatio = imageH / (float)imageW;
const float imRatio = ih / (float) iw;
const float destRatio = imageH / (float) imageW;
if (imRatio > destRatio)
{
@@ -169,11 +169,13 @@ void ImageButton::paintButton (Graphics& g,
imageH = ih;
}
const bool useDownImage = isButtonDown || getToggleState();
getLookAndFeel().drawImageButton (g, &im, imageX, imageY, imageW, imageH,
isButtonDown ? downOverlay
useDownImage ? downOverlay
: (isMouseOverButton ? overOverlay
: normalOverlay),
isButtonDown ? downOpacity
useDownImage ? downOpacity
: (isMouseOverButton ? overOpacity
: normalOpacity),
*this);


+ 5
- 0
modules/juce_opengl/native/juce_android_OpenGLComponent.cpp View File

@@ -39,3 +39,8 @@ void OpenGLPixelFormat::getAvailablePixelFormats (Component* component,
{
}
bool OpenGLHelpers::isContextActive()
{
return false;
}

+ 6
- 0
modules/juce_opengl/native/juce_ios_OpenGLComponent.mm View File

@@ -234,3 +234,9 @@ void OpenGLPixelFormat::getAvailablePixelFormats (Component* /*component*/,
OwnedArray <OpenGLPixelFormat>& /*results*/)
{
}
//==============================================================================
bool OpenGLHelpers::isContextActive()
{
return [EAGLContext currentContext] != nil;
}

+ 7
- 0
modules/juce_opengl/native/juce_linux_OpenGLComponent.cpp View File

@@ -200,3 +200,10 @@ void OpenGLPixelFormat::getAvailablePixelFormats (Component* component, OwnedArr
{
results.add (new OpenGLPixelFormat()); // xxx
}
//==============================================================================
bool OpenGLHelpers::isContextActive()
{
ScopedXLock xlock;
return glXGetCurrentContext() != 0;
}

+ 6
- 0
modules/juce_opengl/native/juce_mac_OpenGLComponent.mm View File

@@ -312,3 +312,9 @@ void OpenGLPixelFormat::getAvailablePixelFormats (Component* /*component*/,
results.add (pf);
}
}
//==============================================================================
bool OpenGLHelpers::isContextActive()
{
return [NSOpenGLContext currentContext] != nil;
}

+ 6
- 0
modules/juce_opengl/native/juce_win32_OpenGLComponent.cpp View File

@@ -509,3 +509,9 @@ void OpenGLPixelFormat::getAvailablePixelFormats (Component* component,
wc.findAlternativeOpenGLPixelFormats (results);
}
}
//==============================================================================
bool OpenGLHelpers::isContextActive()
{
return wglGetCurrentContext() != 0;
}

+ 25
- 48
modules/juce_opengl/opengl/juce_OpenGLFrameBuffer.cpp View File

@@ -145,6 +145,10 @@ public:
hasStencilBuffer (false),
ok (false)
{
// Framebuffer objects can only be created when the current thread has an active OpenGL
// context. You'll need to make an OpenGLComponent active before calling this.
jassert (OpenGLHelpers::isContextActive());
#if JUCE_WINDOWS || JUCE_LINUX
initialiseFrameBufferFunctions();
@@ -155,17 +159,13 @@ public:
OpenGLHelpers::resetErrorState();
glGenFramebuffersEXT (1, &frameBufferHandle);
glBindFramebufferEXT (GL_FRAMEBUFFER_EXT, frameBufferHandle);
glGenTextures (1, &textureID);
glBindTexture (textureType, textureID);
glTexImage2D (textureType, 0, GL_RGBA8, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
glTexParameterf (textureType, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameterf (textureType, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameterf (textureType, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameterf (textureType, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glFramebufferTexture2DEXT (GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, textureType, textureID, 0);
if (wantsDepthBuffer || wantsStencilBuffer)
@@ -174,37 +174,33 @@ public:
glBindRenderbufferEXT (GL_RENDERBUFFER_EXT, depthOrStencilBuffer);
jassert (glIsRenderbufferEXT (depthOrStencilBuffer));
if (wantsDepthBuffer && wantsStencilBuffer)
{
glRenderbufferStorageEXT (GL_RENDERBUFFER_EXT, GL_DEPTH24_STENCIL8_EXT, width, height);
glRenderbufferStorageEXT (GL_RENDERBUFFER_EXT,
(wantsDepthBuffer && wantsStencilBuffer) ? GL_DEPTH24_STENCIL8_EXT
#if JUCE_OPENGL_ES
: GL_DEPTH_COMPONENT16,
#else
: GL_DEPTH_COMPONENT,
#endif
width, height);
GLint params = 0;
glGetRenderbufferParameterivEXT (GL_RENDERBUFFER_EXT, GL_RENDERBUFFER_DEPTH_SIZE_EXT, &params);
GLint params = 0;
glGetRenderbufferParameterivEXT (GL_RENDERBUFFER_EXT, GL_RENDERBUFFER_DEPTH_SIZE_EXT, &params);
glFramebufferRenderbufferEXT (GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, depthOrStencilBuffer);
glFramebufferRenderbufferEXT (GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, depthOrStencilBuffer);
if (wantsStencilBuffer)
glFramebufferRenderbufferEXT (GL_FRAMEBUFFER_EXT, GL_STENCIL_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, depthOrStencilBuffer);
hasDepthBuffer = true;
hasStencilBuffer = true;
}
else
{
#if JUCE_OPENGL_ES
glRenderbufferStorageEXT (GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT16, width, height);
#else
glRenderbufferStorageEXT (GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT, width, height);
#endif
GLint params = 0;
glGetRenderbufferParameterivEXT (GL_RENDERBUFFER_EXT, GL_RENDERBUFFER_DEPTH_SIZE_EXT, &params);
glFramebufferRenderbufferEXT (GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, depthOrStencilBuffer);
hasDepthBuffer = true;
}
hasDepthBuffer = wantsDepthBuffer;
hasStencilBuffer = wantsStencilBuffer;
}
ok = checkStatus();
glTexParameterf (textureType, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameterf (textureType, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameterf (textureType, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameterf (textureType, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glBindFramebufferEXT (GL_FRAMEBUFFER_EXT, 0);
}
@@ -438,7 +434,7 @@ bool OpenGLFrameBuffer::writePixels (const void* data, int pixelStride, const Re
glBindTexture (GL_TEXTURE_2D, temporaryTexture);
glPixelStorei (GL_UNPACK_ALIGNMENT, pixelStride);
glTexImage2D (GL_TEXTURE_2D, 0, GL_RGBA, area.getWidth(), area.getHeight(), 0,
glTexImage2D (GL_TEXTURE_2D, 0, GL_RGBA8, area.getWidth(), area.getHeight(), 0,
format, GL_UNSIGNED_BYTE, data);
glTexParameterf (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
@@ -522,24 +518,5 @@ void OpenGLFrameBuffer::drawAt (float x1, float y1) const
}
}
//==============================================================================
void OpenGLFrameBuffer::createAlphaChannelFromPath (const Path& path, const AffineTransform& transform,
const int oversamplingLevel)
{
makeCurrentRenderingTarget();
glEnableClientState (GL_VERTEX_ARRAY);
glEnableClientState (GL_TEXTURE_COORD_ARRAY);
glDisableClientState (GL_COLOR_ARRAY);
glDisableClientState (GL_NORMAL_ARRAY);
glDisable (GL_TEXTURE_2D);
glDisable (GL_DEPTH_TEST);
glColorMask (GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
glEnable (GL_BLEND);
glBlendFunc (GL_ONE, GL_ONE);
prepareFor2D();
TriangulatedPath (path, transform).draw (oversamplingLevel);
}
END_JUCE_NAMESPACE

+ 0
- 13
modules/juce_opengl/opengl/juce_OpenGLFrameBuffer.h View File

@@ -134,19 +134,6 @@ public:
bool writePixels (const void* srcData, int srcPixelStride,
const Rectangle<int>& targetArea);
/** This will render an anti-aliased path into just the alpha channel of this framebuffer.
The idea here is that you can clear a framebuffer, use this to set its alpha channel, then
fill the RGB channels with some kind of fill-pattern, and then copy the whole thing onto
a target, to produce a filled path with some kind of texture.
Calling this will make changes to a lot of openGL state, including colour masks, blend
functions, etc
*/
void createAlphaChannelFromPath (const Path& path,
const AffineTransform& transform,
int oversamplingLevel = 4);
private:
class Pimpl;
friend class ScopedPointer<Pimpl>;


+ 54
- 224
modules/juce_opengl/opengl/juce_OpenGLHelpers.cpp View File

@@ -51,7 +51,7 @@ void OpenGLHelpers::prepareFor2D (const int width, const int height)
glLoadIdentity();
#if JUCE_OPENGL_ES
glOrthof (0.0f, (float) width, 0.0f, (float) height, 0.0f, 1.0f);
glOrthof (0.0f, (GLfloat) width, 0.0f, (GLfloat) height, 0.0f, 1.0f);
#else
glOrtho (0.0, width, 0.0, height, 0, 1);
#endif
@@ -64,10 +64,10 @@ void OpenGLHelpers::setPerspective (double fovy, double aspect, double zNear, do
glLoadIdentity();
#if JUCE_OPENGL_ES
const float ymax = (float) (zNear * tan (fovy * double_Pi / 360.0));
const float ymin = -ymax;
const GLfloat ymax = (GLfloat) (zNear * tan (fovy * double_Pi / 360.0));
const GLfloat ymin = -ymax;
glFrustumf (ymin * (float) aspect, ymax * (float) aspect, ymin, ymax, (float) zNear, (float) zFar);
glFrustumf (ymin * (GLfloat) aspect, ymax * (GLfloat) aspect, ymin, ymax, (GLfloat) zNear, (GLfloat) zFar);
#else
const double ymax = zNear * tan (fovy * double_Pi / 360.0);
const double ymin = -ymax;
@@ -136,7 +136,6 @@ namespace OpenGLGradientHelpers
{
void drawTriangles (GLenum mode, const GLfloat* vertices, const GLfloat* textureCoords, const int numElements)
{
glEnable (GL_BLEND);
glEnable (GL_TEXTURE_2D);
glEnableClientState (GL_VERTEX_ARRAY);
glEnableClientState (GL_TEXTURE_COORD_ARRAY);
@@ -164,10 +163,10 @@ namespace OpenGLGradientHelpers
p2.getX(), p2.getY(), 1.0f, 0.0f,
p3.getX(), p3.getY(), 0.0f, 1.0f));
const float l = (float) rect.getX();
const float r = (float) rect.getRight();
const float t = (float) rect.getY();
const float b = (float) rect.getBottom();
const GLfloat l = (GLfloat) rect.getX();
const GLfloat r = (GLfloat) rect.getRight();
const GLfloat t = (GLfloat) rect.getY();
const GLfloat b = (GLfloat) rect.getBottom();
const GLfloat vertices[] = { l, t, r, t, l, b, r, b };
GLfloat textureCoords[] = { l, t, r, t, l, b, r, b };
@@ -202,8 +201,7 @@ namespace OpenGLGradientHelpers
*t++ = 0.0f;
*t++ = 0.0f;
const float originalRadius = grad.point1.getDistanceFrom (grad.point2);
const float texturePos = sourceRadius / originalRadius;
const GLfloat texturePos = sourceRadius / grad.point1.getDistanceFrom (grad.point2);
for (int i = numDivisions + 1; --i >= 0;)
{
@@ -280,15 +278,54 @@ void OpenGLHelpers::fillRectWithColour (const Rectangle<int>& rect, const Colour
void OpenGLHelpers::fillRect (const Rectangle<int>& rect)
{
const GLfloat vertices[] = { (float) rect.getX(), (float) rect.getY(),
(float) rect.getRight(), (float) rect.getY(),
(float) rect.getX(), (float) rect.getBottom(),
(float) rect.getRight(), (float) rect.getBottom() };
const GLfloat vertices[] = { (GLfloat) rect.getX(), (GLfloat) rect.getY(),
(GLfloat) rect.getRight(), (GLfloat) rect.getY(),
(GLfloat) rect.getX(), (GLfloat) rect.getBottom(),
(GLfloat) rect.getRight(), (GLfloat) rect.getBottom() };
glVertexPointer (2, GL_FLOAT, 0, vertices);
glDrawArrays (GL_TRIANGLE_STRIP, 0, 4);
}
void OpenGLHelpers::fillRectWithTiledTexture (int textureWidth, int textureHeight,
const Rectangle<int>& clip,
const AffineTransform& transform,
float alpha)
{
glEnable (GL_TEXTURE_2D);
glTexParameterf (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameterf (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glEnableClientState (GL_VERTEX_ARRAY);
glEnableClientState (GL_TEXTURE_COORD_ARRAY);
glDisableClientState (GL_COLOR_ARRAY);
glDisableClientState (GL_NORMAL_ARRAY);
glColor4f (1.0f, 1.0f, 1.0f, alpha);
glTexParameterf (GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameterf (GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
const GLfloat clipX = (GLfloat) clip.getX();
const GLfloat clipY = (GLfloat) clip.getY();
const GLfloat clipR = (GLfloat) clip.getRight();
const GLfloat clipB = (GLfloat) clip.getBottom();
const GLfloat vertices[] = { clipX, clipY, clipR, clipY, clipX, clipB, clipR, clipB };
GLfloat textureCoords[] = { clipX, clipY, clipR, clipY, clipX, clipB, clipR, clipB };
{
const AffineTransform t (transform.inverted().scaled (1.0f / textureWidth,
1.0f / textureHeight));
t.transformPoints (textureCoords[0], textureCoords[1], textureCoords[2], textureCoords[3]);
t.transformPoints (textureCoords[4], textureCoords[5], textureCoords[6], textureCoords[7]);
}
glVertexPointer (2, GL_FLOAT, 0, vertices);
glTexCoordPointer (2, GL_FLOAT, 0, textureCoords);
glDrawArrays (GL_TRIANGLE_STRIP, 0, 4);
}
//==============================================================================
// This breaks down a path into a series of horizontal strips of trapezoids..
class TriangulatedPath::TrapezoidedPath
@@ -575,6 +612,8 @@ TriangulatedPath::TriangulatedPath (const Path& path, const AffineTransform& tra
TrapezoidedPath (path, transform).iterate (*this);
}
TriangulatedPath::~TriangulatedPath() {}
void TriangulatedPath::draw (const int oversamplingLevel) const
{
glColor4f (1.0f, 1.0f, 1.0f, 1.0f / (oversamplingLevel * oversamplingLevel));
@@ -670,214 +709,5 @@ void OpenGLRenderingTarget::prepareFor2D()
getRenderingTargetHeight());
}
namespace GLPathRendering
{
void clipToPath (OpenGLRenderingTarget& target,
const Path& path, const AffineTransform& transform)
{
const int w = target.getRenderingTargetWidth();
const int h = target.getRenderingTargetHeight();
OpenGLFrameBuffer fb;
fb.initialise (w, h);
fb.makeCurrentAndClear();
fb.createAlphaChannelFromPath (path, transform);
target.makeCurrentRenderingTarget();
target.prepareFor2D();
glColorMask (GL_FALSE, GL_FALSE, GL_FALSE, GL_TRUE);
glBlendFunc (GL_DST_ALPHA, GL_ZERO);
glColor4f (1.0f, 1.0f, 1.0f, 1.0f);
fb.drawAt (0, 0);
}
void fillPathWithColour (OpenGLRenderingTarget& target,
const Rectangle<int>& clip, const Path& path,
const AffineTransform& pathTransform,
const Colour& colour)
{
OpenGLFrameBuffer f;
f.initialise (clip.getWidth(), clip.getHeight());
f.makeCurrentAndClear();
f.createAlphaChannelFromPath (path, pathTransform.translated ((float) -clip.getX(), (float) -clip.getY())
.followedBy (AffineTransform::verticalFlip ((float) clip.getHeight())));
f.releaseAsRenderingTarget();
target.makeCurrentRenderingTarget();
glColorMask (GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
OpenGLHelpers::setColour (colour);
target.prepareFor2D();
f.drawAt ((float) clip.getX(), (float) (target.getRenderingTargetHeight() - clip.getBottom()));
}
void fillPathWithGradient (OpenGLRenderingTarget& target,
const Rectangle<int>& clip, const Path& path,
const AffineTransform& pathTransform,
const ColourGradient& grad,
const AffineTransform& gradientTransform,
const GLfloat alpha)
{
const int targetHeight = target.getRenderingTargetHeight();
OpenGLFrameBuffer f;
f.initialise (clip.getWidth(), clip.getHeight());
f.makeCurrentAndClear();
const AffineTransform correction (AffineTransform::translation ((float) -clip.getX(), (float) -clip.getY())
.followedBy (AffineTransform::verticalFlip ((float) clip.getHeight())));
f.createAlphaChannelFromPath (path, pathTransform.followedBy (correction));
f.makeCurrentRenderingTarget();
f.prepareFor2D();
glColorMask (GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
glBlendFunc (GL_DST_ALPHA, GL_ZERO);
OpenGLHelpers::fillRectWithColourGradient (Rectangle<int> (0, 0, clip.getWidth(), clip.getHeight()),
grad, gradientTransform.followedBy (correction));
f.releaseAsRenderingTarget();
target.makeCurrentRenderingTarget();
glColorMask (GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
glBlendFunc (GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
glColor4f (alpha, alpha, alpha, alpha);
target.prepareFor2D();
f.drawAt ((float) clip.getX(), (float) (targetHeight - clip.getBottom()));
}
void fillPathWithImage (OpenGLRenderingTarget& target,
const Rectangle<int>& clip, const Path& path,
const AffineTransform& transform,
GLuint textureID, GLfloat textureWidth, GLfloat textureHeight,
const AffineTransform& textureTransform,
const bool tiled,
const GLfloat alpha)
{
const int targetHeight = target.getRenderingTargetHeight();
OpenGLFrameBuffer f;
f.initialise (clip.getWidth(), clip.getHeight());
f.makeCurrentRenderingTarget();
f.prepareFor2D();
glDisable (GL_BLEND);
glColorMask (GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
glColor4f (1.0f, 1.0f, 1.0f, 1.0f);
const GLfloat clipX = (GLfloat) clip.getX();
const GLfloat clipY = (GLfloat) clip.getY();
const GLfloat clipH = (GLfloat) clip.getHeight();
const GLfloat clipB = (GLfloat) clip.getBottom();
const AffineTransform correction (AffineTransform::translation (-clipX, -clipY)
.followedBy (AffineTransform::verticalFlip (clipH)));
glBindTexture (GL_TEXTURE_2D, textureID);
glTexParameterf (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameterf (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glEnableClientState (GL_VERTEX_ARRAY);
glEnableClientState (GL_TEXTURE_COORD_ARRAY);
glDisableClientState (GL_COLOR_ARRAY);
glDisableClientState (GL_NORMAL_ARRAY);
glColor4f (1.0f, 1.0f, 1.0f, 1.0f);
if (tiled)
{
glTexParameterf (GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameterf (GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
const GLfloat clipW = (GLfloat) clip.getWidth();
const GLfloat clipR = (GLfloat) clip.getRight();
const GLfloat vertices[] = { 0, clipH, clipW, clipH, 0, 0, clipW, 0 };
GLfloat textureCoords[] = { clipX, clipY, clipR, clipY, clipX, clipB, clipR, clipB };
{
const AffineTransform t (textureTransform.inverted().scaled (1.0f / textureWidth,
1.0f / textureHeight));
t.transformPoints (textureCoords[0], textureCoords[1], textureCoords[2], textureCoords[3]);
t.transformPoints (textureCoords[4], textureCoords[5], textureCoords[6], textureCoords[7]);
}
glVertexPointer (2, GL_FLOAT, 0, vertices);
glTexCoordPointer (2, GL_FLOAT, 0, textureCoords);
glDrawArrays (GL_TRIANGLE_STRIP, 0, 4);
}
else
{
glClearColor (0, 0, 0, 0);
glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
glTexParameterf (GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameterf (GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
GLfloat vertices[] = { 0, 0, textureWidth, 0, 0, textureHeight, textureWidth, textureHeight };
const GLfloat textureCoords[] = { 0, 0, 1.0f, 0, 0, 1.0f, 1.0f, 1.0f };
{
const AffineTransform t (textureTransform.followedBy (correction));
t.transformPoints (vertices[0], vertices[1], vertices[2], vertices[3]);
t.transformPoints (vertices[4], vertices[5], vertices[6], vertices[7]);
}
glVertexPointer (2, GL_FLOAT, 0, vertices);
glTexCoordPointer (2, GL_FLOAT, 0, textureCoords);
glDrawArrays (GL_TRIANGLE_STRIP, 0, 4);
}
glBindTexture (GL_TEXTURE_2D, 0);
clipToPath (f, path, transform.followedBy (correction));
f.releaseAsRenderingTarget();
target.makeCurrentRenderingTarget();
glColorMask (GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glColor4f (1.0f, 1.0f, 1.0f, alpha);
target.prepareFor2D();
f.drawAt (clipX, targetHeight - clipB);
}
}
void OpenGLRenderingTarget::fillPath (const Rectangle<int>& clip,
const Path& path, const AffineTransform& transform,
const FillType& fill)
{
if (! fill.isInvisible())
{
if (fill.isColour())
{
GLPathRendering::fillPathWithColour (*this, clip, path, transform, fill.colour);
}
else if (fill.isGradient())
{
GLPathRendering::fillPathWithGradient (*this, clip, path, transform,
*(fill.gradient), fill.transform,
fill.colour.getFloatAlpha());
}
else if (fill.isTiledImage())
{
OpenGLTextureFromImage t (fill.image);
GLPathRendering::fillPathWithImage (*this, clip, path, transform,
t.textureID, (GLfloat) t.width, (GLfloat) t.height,
fill.transform, true,
fill.colour.getFloatAlpha());
}
}
}
END_JUCE_NAMESPACE

+ 12
- 1
modules/juce_opengl/opengl/juce_OpenGLHelpers.h View File

@@ -40,6 +40,9 @@ public:
/** Clears the GL error state. */
static void resetErrorState();
/** Returns true if the current thread has an active OpenGL context. */
static bool isContextActive();
/** Clears the current context using the given colour. */
static void clear (const Colour& colour);
@@ -78,6 +81,11 @@ public:
static void fillRectWithColourGradient (const Rectangle<int>& rect,
const ColourGradient& gradient,
const AffineTransform& transform);
static void fillRectWithTiledTexture (int textureWidth, int textureHeight,
const Rectangle<int>& targetArea,
const AffineTransform& transform,
float alpha);
};
//==============================================================================
@@ -88,6 +96,9 @@ class JUCE_API TriangulatedPath
public:
TriangulatedPath (const Path& path, const AffineTransform& transform);
/** Destructor. */
~TriangulatedPath();
/** Renders the path, using a jittered oversampling method.
The oversampling level is the square root of the number of times it
should be oversampled, so 3 or 4 might be reasonable.
@@ -102,7 +113,7 @@ private:
friend class TrapezoidedPath;
void startNewBlock();
void addTriangle (GLfloat x1, GLfloat y1, GLfloat x2, GLfloat y2, GLfloat x3, GLfloat y3);
void addTriangle (GLfloat x1, GLfloat y1, GLfloat x2, GLfloat y2, GLfloat x3, GLfloat y3);
void addTrapezoid (GLfloat y1, GLfloat y2, GLfloat x1, GLfloat x2, GLfloat x3, GLfloat x4);
struct TriangleBlock;


+ 0
- 5
modules/juce_opengl/opengl/juce_OpenGLRenderingTarget.h View File

@@ -51,11 +51,6 @@ public:
@see OpenGLHelpers::prepareFor2D
*/
void prepareFor2D();
/** Fills a path with a custom FillType. */
void fillPath (const Rectangle<int>& clipArea,
const Path& path, const AffineTransform& pathTransform,
const FillType& fill);
};


+ 4
- 0
modules/juce_opengl/opengl/juce_OpenGLTexture.cpp View File

@@ -49,6 +49,10 @@ bool OpenGLTexture::isValidSize (int width, int height)
void OpenGLTexture::create (const int w, const int h)
{
// Texture objects can only be created when the current thread has an active OpenGL
// context. You'll need to make an OpenGLComponent active before calling this.
jassert (OpenGLHelpers::isContextActive());
jassert (isValidSize (w, h)); // Perhaps these dimensions must be a power-of-two?
release();


Loading…
Cancel
Save