1
0
Fork 0
mirror of https://github.com/juce-framework/JUCE.git synced 2026-02-03 03:30:06 +00:00

More OpenGL work.

This commit is contained in:
jules 2011-10-26 19:31:45 +01:00
parent 74a727b42f
commit 0422e4ced9
9 changed files with 195 additions and 145 deletions

View file

@ -51,8 +51,6 @@ END_JUCE_NAMESPACE
- (BOOL) resignFirstResponder;
- (BOOL) canBecomeFirstResponder;
- (void) asyncRepaint: (id) rect;
- (BOOL) textView: (UITextView*) textView shouldChangeTextInRange: (NSRange) range replacementText: (NSString*) text;
@end
@ -343,12 +341,6 @@ juce::Point<int> juce_lastMousePos;
return owner != nullptr && owner->canBecomeKeyWindow();
}
- (void) asyncRepaint: (id) rect
{
CGRect* r = (CGRect*) [((NSData*) rect) bytes];
[self setNeedsDisplayInRect: *r];
}
- (BOOL) textView: (UITextView*) textView shouldChangeTextInRange: (NSRange) range replacementText: (NSString*) text
{
return owner->textViewReplaceCharacters (Range<int> (range.location, range.location + range.length),

View file

@ -69,7 +69,7 @@ END_JUCE_NAMESPACE
{
const ScopedLock sl (*contextLock);
if ([self openGLContext] == 0)
if ([self openGLContext] == nil)
return false;
[[self openGLContext] makeCurrentContext];
@ -108,15 +108,8 @@ END_JUCE_NAMESPACE
needsUpdate = true;
}
- (void) rightMouseDown: (NSEvent*) ev
{
[[self superview] rightMouseDown: ev];
}
- (void) rightMouseUp: (NSEvent*) ev
{
[[self superview] rightMouseUp: ev];
}
- (void) rightMouseDown: (NSEvent*) ev { [[self superview] rightMouseDown: ev]; }
- (void) rightMouseUp: (NSEvent*) ev { [[self superview] rightMouseUp: ev]; }
@end
BEGIN_JUCE_NAMESPACE
@ -275,5 +268,5 @@ void OpenGLComponent::updateEmbeddedPosition (const Rectangle<int>&)
//==============================================================================
bool OpenGLHelpers::isContextActive()
{
return [NSOpenGLContext currentContext] != nil;
return CGLGetCurrentContext() != 0;
}

View file

@ -126,7 +126,7 @@ public:
depthOrStencilBuffer (0),
hasDepthBuffer (false),
hasStencilBuffer (false),
ok (false)
ok (true)
{
// 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.
@ -180,8 +180,6 @@ public:
hasStencilBuffer = wantsStencilBuffer;
}
ok = checkStatus();
glBindFramebufferEXT (GL_FRAMEBUFFER_EXT, 0);
}
@ -197,25 +195,14 @@ public:
glDeleteFramebuffersEXT (1, &frameBufferHandle);
}
bool bind() { return bind (frameBufferHandle); }
bool unbind() { return bind (0); }
void bind() { glBindFramebufferEXT (GL_FRAMEBUFFER_EXT, frameBufferHandle); }
void unbind() { glBindFramebufferEXT (GL_FRAMEBUFFER_EXT, 0); }
const int width, height;
GLuint textureID, frameBufferHandle, depthOrStencilBuffer;
bool hasDepthBuffer, hasStencilBuffer, ok;
private:
bool bind (GLuint buffer)
{
if (ok)
{
glBindFramebufferEXT (GL_FRAMEBUFFER_EXT, buffer);
ok = checkStatus();
}
return ok;
}
static bool checkStatus() noexcept
{
const GLenum status = glCheckFramebufferStatusEXT (GL_FRAMEBUFFER_EXT);
@ -347,7 +334,11 @@ bool OpenGLFrameBuffer::makeCurrentRenderingTarget()
// reloadSavedCopy() to put it back into GPU memory before using it..
jassert (savedState == nullptr);
return pimpl != nullptr && pimpl->bind();
if (pimpl == nullptr)
return false;
pimpl->bind();
return true;
}
void OpenGLFrameBuffer::setCurrentFrameBufferTarget (GLuint frameBufferID)
@ -355,6 +346,13 @@ void OpenGLFrameBuffer::setCurrentFrameBufferTarget (GLuint frameBufferID)
glBindFramebufferEXT (GL_FRAMEBUFFER_EXT, frameBufferID);
}
GLuint OpenGLFrameBuffer::getCurrentFrameBufferTarget()
{
GLint fb;
glGetIntegerv (GL_FRAMEBUFFER_BINDING_EXT, &fb);
return (GLuint) fb;
}
void OpenGLFrameBuffer::releaseAsRenderingTarget()
{
setCurrentFrameBufferTarget (0);
@ -397,16 +395,16 @@ bool OpenGLFrameBuffer::writePixels (const PixelARGB* data, const Rectangle<int>
OpenGLHelpers::prepareFor2D (pimpl->width, pimpl->height);
glDisable (GL_DEPTH_TEST);
glDisable (GL_BLEND);
glColor4f (1.0f, 1.0f, 1.0f, 1.0f);
#if JUCE_OPENGL_ES
{
// GLES has no glDrawPixels function, so we have to create a texture and draw it..
glEnable (GL_TEXTURE_2D);
glColor4f (1.0f, 1.0f, 1.0f, 1.0f);
OpenGLTexture temp;
temp.load (data, area.getWidth(), area.getHeight());
temp.bind();
OpenGLTexture tex;
tex.load (data, area.getWidth(), area.getHeight());
tex.bind();
const GLint cropRect[4] = { 0, 0, area.getWidth(), area.getHeight() };
glTexParameteriv (GL_TEXTURE_2D, GL_TEXTURE_CROP_RECT_OES, cropRect);
@ -415,10 +413,12 @@ bool OpenGLFrameBuffer::writePixels (const PixelARGB* data, const Rectangle<int>
glBindTexture (GL_TEXTURE_2D, 0);
}
#else
glRasterPos2i (area.getX(), area.getY());
glBindTexture (GL_TEXTURE_2D, 0);
glPixelStorei (GL_UNPACK_ALIGNMENT, 4);
glDrawPixels (area.getWidth(), area.getHeight(), GL_BGRA_EXT, GL_UNSIGNED_BYTE, data);
{
OpenGLTexture tex;
tex.load (data, area.getWidth(), area.getHeight());
OpenGLHelpers::fillRectWithTexture (area.withSize (tex.getWidth(), tex.getHeight()), tex.getTextureID(), 1.0f);
}
#endif
glBindFramebufferEXT (GL_FRAMEBUFFER_EXT, 0);

View file

@ -103,6 +103,9 @@ public:
*/
static void setCurrentFrameBufferTarget (GLuint frameBufferID);
/** Returns the ID of the currently-bound framebuffer. */
static GLuint getCurrentFrameBufferTarget();
/** Clears the framebuffer with the specified colour. */
void clear (const Colour& colour);

View file

@ -103,67 +103,14 @@ namespace
glColor4f (alpha, alpha, alpha, alpha);
}
void drawTriangleStrip (const GLfloat* const vertices, const GLfloat* const textureCoords, const int numVertices) noexcept
{
glEnable (GL_TEXTURE_2D);
glDisableClientState (GL_COLOR_ARRAY);
glDisableClientState (GL_NORMAL_ARRAY);
glEnableClientState (GL_VERTEX_ARRAY);
glVertexPointer (2, GL_FLOAT, 0, vertices);
glEnableClientState (GL_TEXTURE_COORD_ARRAY);
glTexCoordPointer (2, GL_FLOAT, 0, textureCoords);
glDrawArrays (GL_TRIANGLE_STRIP, 0, numVertices);
}
void drawTriangleStrip (const GLfloat* const vertices, const GLfloat* const textureCoords,
const int numVertices, const GLuint textureID) noexcept
{
jassert (textureID != 0);
glBindTexture (GL_TEXTURE_2D, textureID);
drawTriangleStrip (vertices, textureCoords, numVertices);
glBindTexture (GL_TEXTURE_2D, 0);
}
void drawTextureQuad (GLuint textureID, int x, int y, int w, int h)
{
const GLfloat l = (GLfloat) x;
const GLfloat t = (GLfloat) y;
const GLfloat r = (GLfloat) (x + w);
const GLfloat b = (GLfloat) (y + h);
const GLfloat vertices[] = { l, t, r, t, l, b, r, b };
const GLfloat textureCoords[] = { 0, 1.0f, 1.0f, 1.0f, 0, 0, 1.0f, 0 };
drawTriangleStrip (vertices, textureCoords, 4, textureID);
}
void fillRectWithTexture (const Rectangle<int>& rect, GLuint textureID, const float alpha)
{
glTexParameterf (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameterf (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameterf (GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameterf (GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glColor4f (1.0f, 1.0f, 1.0f, alpha);
drawTextureQuad (textureID, rect.getX(), rect.getY(), rect.getWidth(), rect.getHeight());
}
void clipFrameBuffers (const OpenGLTarget& dest, OpenGLFrameBuffer& source,
const Point<int> sourceOrigin, const bool shouldMaskRGB)
void clipFrameBuffers (const OpenGLTarget& dest, OpenGLFrameBuffer& source, const Point<int> sourceOrigin)
{
dest.makeActiveFor2D();
glEnable (GL_BLEND);
glBlendFunc (GL_ZERO, GL_SRC_ALPHA);
setColour (1.0f);
if (shouldMaskRGB)
glColorMask (GL_FALSE, GL_FALSE, GL_FALSE, GL_TRUE);
drawTextureQuad (source.getTextureID(), sourceOrigin.getX(), sourceOrigin.getY(),
source.getWidth(), source.getHeight());
if (shouldMaskRGB)
glColorMask (GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
OpenGLHelpers::drawTextureQuad (source.getTextureID(), sourceOrigin.getX(), sourceOrigin.getY(),
source.getWidth(), source.getHeight());
}
void renderPath (const Path& path, const AffineTransform& transform, int oversamplingLevel)
@ -177,10 +124,10 @@ namespace
TriangulatedPath (path, transform).draw (oversamplingLevel);
}
void setNormalBlendingMode() noexcept
void setPremultipliedBlendingMode() noexcept
{
glEnable (GL_BLEND);
glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glBlendFunc (GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
}
void setBlendMode (const bool replaceExistingContents) noexcept
@ -188,7 +135,7 @@ namespace
if (replaceExistingContents)
glDisable (GL_BLEND);
else
setNormalBlendingMode();
setPremultipliedBlendingMode();
}
void fillRectWithTiledTexture (const OpenGLTarget& target, int textureWidth, int textureHeight,
@ -295,7 +242,8 @@ namespace
textureTransform.transformPoints (textureCoords[0], textureCoords[1], textureCoords[2], textureCoords[3]);
textureTransform.transformPoints (textureCoords[4], textureCoords[5], textureCoords[6], textureCoords[7]);
drawTriangleStrip (vertices, textureCoords, 4);
setColour (1.0f);
OpenGLHelpers::drawTriangleStrip (vertices, textureCoords, 4);
}
void fillWithRadialGradient (const OpenGLTarget& target, const Rectangle<int>& rect,
@ -442,7 +390,6 @@ public:
virtual Ptr clipToEdgeTable (const EdgeTable&) = 0;
virtual Ptr clipToImageAlpha (const OpenGLTextureFromImage&, const AffineTransform&) = 0;
virtual Ptr clipToMask (ClipRegion_Mask*) = 0;
virtual void translate (const Point<int>& delta) = 0;
virtual const Rectangle<int>& getClipBounds() const = 0;
virtual void fillAll (const OpenGLTarget&, const FillType& fill, bool replaceContents) = 0;
virtual void fillRect (const OpenGLTarget&, const Rectangle<int>& area, const FillType& fill, bool replaceContents) = 0;
@ -489,7 +436,7 @@ public:
maskOrigin (clip.getPosition())
{
initialiseClear();
OpenGLHelpers::fillEdgeTable (e, 0, 0, 0);
OpenGLHelpers::fillEdgeTable (e);
}
ClipRegion_Mask (const Rectangle<int>& bounds, const Path& p, const AffineTransform& transform, int oversamplingLevel)
@ -511,12 +458,6 @@ public:
const Rectangle<int>& getClipBounds() const { return clip; }
Ptr applyClipTo (const Ptr& target) { return target->clipToMask (this); }
void translate (const Point<int>& delta)
{
maskOrigin += delta;
clip += delta;
}
Ptr clipToRectangle (const Rectangle<int>& r)
{
clip = clip.getIntersection (r);
@ -579,7 +520,7 @@ public:
if (clip.isEmpty())
return nullptr;
clipFrameBuffers (OpenGLTarget (mask, maskOrigin), m->mask, m->maskOrigin, true);
clipFrameBuffers (OpenGLTarget (mask, maskOrigin), m->mask, m->maskOrigin);
return this;
}
@ -645,7 +586,7 @@ public:
OpenGLTarget bufferTarget (buffer, bufferArea.getPosition());
bufferTarget.makeActiveFor2D();
glDisable (GL_BLEND);
fillRectWithTexture (targetArea, source.textureID, alpha);
OpenGLHelpers::fillRectWithTexture (targetArea, source.textureID, alpha);
clipAndDraw (target, bufferTarget);
}
@ -703,7 +644,7 @@ private:
const GLfloat b = (GLfloat) (y + h);
const GLfloat vertices[] = { l, t, r, t, l, b, r, b };
glColor4f (1.0f, 1.0f, 1.0f, alpha / 255.0f);
setColour (alpha / 255.0f);
glVertexPointer (2, GL_FLOAT, 0, vertices);
glDrawArrays (GL_TRIANGLE_STRIP, 0, 4);
}
@ -711,7 +652,7 @@ private:
void clipAndDraw (const OpenGLTarget& target, const OpenGLTarget& buffer)
{
clipFrameBuffers (buffer, mask, maskOrigin, false);
clipFrameBuffers (buffer, mask, maskOrigin);
target.makeActiveFor2D();
glEnable (GL_BLEND);
@ -723,8 +664,8 @@ private:
void drawFrameBuffer (const OpenGLFrameBuffer& buffer, const Point<int>& topLeft)
{
drawTextureQuad (buffer.getTextureID(), topLeft.getX(), topLeft.getY(),
buffer.getWidth(), buffer.getHeight());
OpenGLHelpers::drawTextureQuad (buffer.getTextureID(), topLeft.getX(), topLeft.getY(),
buffer.getWidth(), buffer.getHeight());
}
void fillMaskWithSourceImage (const OpenGLTextureFromImage& image, const AffineTransform& transform) const
@ -749,7 +690,12 @@ private:
inv.transformPoints (textureCoords[0], textureCoords[1], textureCoords[2], textureCoords[3]);
inv.transformPoints (textureCoords[4], textureCoords[5], textureCoords[6], textureCoords[7]);
drawTriangleStrip (vertices, textureCoords, 4);
textureCoords[1] = 1.0f - textureCoords[1];
textureCoords[3] = 1.0f - textureCoords[3];
textureCoords[5] = 1.0f - textureCoords[5];
textureCoords[7] = 1.0f - textureCoords[7];
OpenGLHelpers::drawTriangleStrip (vertices, textureCoords, 4);
}
ClipRegion_Mask& operator= (const ClipRegion_Mask&);
@ -767,7 +713,6 @@ public:
Ptr clone() const { return new ClipRegion_Rectangle (clip); }
const Rectangle<int>& getClipBounds() const { return clip; }
Ptr applyClipTo (const Ptr& target) { return target->clipToRectangle (clip); }
void translate (const Point<int>& delta) { clip += delta; }
Ptr clipToRectangle (const Rectangle<int>& r)
{
@ -814,8 +759,8 @@ public:
{
target.makeActiveFor2D();
target.scissor (clip);
setNormalBlendingMode();
fillRectWithTexture (targetArea, source.textureID, alpha);
setPremultipliedBlendingMode();
OpenGLHelpers::fillRectWithTexture (targetArea, source.textureID, alpha);
glDisable (GL_SCISSOR_TEST);
}
@ -977,12 +922,11 @@ public:
OpenGLFrameBufferImage* fbi = new OpenGLFrameBufferImage (clipBounds.getWidth(), clipBounds.getHeight());
fbi->frameBuffer.clear (Colours::transparentBlack);
s->transparencyLayer = Image (fbi);
s->target = OpenGLTarget (fbi->frameBuffer, Point<int>());
s->target = OpenGLTarget (fbi->frameBuffer, clipBounds.getPosition());
s->transparencyLayerAlpha = opacity;
s->transform.moveOriginInDeviceSpace (-clipBounds.getX(), -clipBounds.getY());
s->cloneClipIfMultiplyReferenced();
s->clip->translate (-clipBounds.getPosition());
}
return s;
@ -1048,17 +992,34 @@ public:
{
if (clip != nullptr)
{
const float fontHeight = font.getHeight();
if (transform.isOnlyTranslated && t.isOnlyTranslation())
{
RenderingHelpers::GlyphCache <CachedGlyphEdgeTable, SavedState>::getInstance()
.drawGlyph (*this, font, glyphNumber,
transform.xOffset + t.getTranslationX(),
transform.yOffset + t.getTranslationY());
}
else
{
const float fontHeight = font.getHeight();
const ScopedPointer<EdgeTable> et (font.getTypeface()->getEdgeTableForGlyph
(glyphNumber, transform.getTransformWith (AffineTransform::scale (fontHeight * font.getHorizontalScale(), fontHeight)
.followedBy (t))));
const ScopedPointer<EdgeTable> et (font.getTypeface()->getEdgeTableForGlyph
(glyphNumber, transform.getTransformWith (AffineTransform::scale (fontHeight * font.getHorizontalScale(), fontHeight)
.followedBy (t))));
if (et != nullptr)
fillShape (new ClipRegion_Mask (*et), false);
if (et != nullptr)
fillShape (new ClipRegion_Mask (*et), false);
}
}
}
void fillEdgeTable (const EdgeTable& et, float x, int y)
{
EdgeTable et2 (et);
et2.translate (x, y);
fillShape (new ClipRegion_Mask (et2), false);
}
void drawLine (const Line <float>& line)
{
Path p;
@ -1147,10 +1108,48 @@ private:
return fillType.transformed (transform.getTransform());
}
class CachedGlyphEdgeTable
{
public:
CachedGlyphEdgeTable() : glyph (0), lastAccessCount (0) {}
void draw (OpenGLRenderer::SavedState& state, float x, const float y) const
{
if (snapToIntegerCoordinate)
x = std::floor (x + 0.5f);
if (edgeTable != nullptr)
state.fillEdgeTable (*edgeTable, x, roundToInt (y));
}
void generate (const Font& newFont, const int glyphNumber)
{
font = newFont;
snapToIntegerCoordinate = newFont.getTypeface()->isHinted();
glyph = glyphNumber;
const float fontHeight = font.getHeight();
edgeTable = font.getTypeface()->getEdgeTableForGlyph (glyphNumber,
AffineTransform::scale (fontHeight * font.getHorizontalScale(), fontHeight)
#if JUCE_MAC || JUCE_IOS
.translated (0.0f, -0.5f)
#endif
);
}
Font font;
int glyph, lastAccessCount;
bool snapToIntegerCoordinate;
private:
ScopedPointer <EdgeTable> edgeTable;
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (CachedGlyphEdgeTable);
};
SavedState& operator= (const SavedState&);
};
//==============================================================================
OpenGLRenderer::OpenGLRenderer (OpenGLComponent& target)
: stack (new SavedState (OpenGLTarget (target.getFrameBufferID(), target.getWidth(), target.getHeight())))
@ -1165,6 +1164,13 @@ OpenGLRenderer::OpenGLRenderer (OpenGLFrameBuffer& target)
jassert (OpenGLHelpers::isContextActive());
}
OpenGLRenderer::OpenGLRenderer (unsigned int frameBufferID, int width, int height)
: stack (new SavedState (OpenGLTarget (frameBufferID, width, height)))
{
// This object can only be created and used when the current thread has an active OpenGL context.
jassert (OpenGLHelpers::isContextActive());
}
OpenGLRenderer::~OpenGLRenderer() {}
bool OpenGLRenderer::isVectorDevice() const { return false; }

View file

@ -35,6 +35,7 @@ class JUCE_API OpenGLRenderer : public LowLevelGraphicsContext
public:
explicit OpenGLRenderer (OpenGLComponent& target);
explicit OpenGLRenderer (OpenGLFrameBuffer& target);
OpenGLRenderer (unsigned int frameBufferID, int width, int height);
~OpenGLRenderer();
bool isVectorDevice() const;

View file

@ -213,6 +213,51 @@ void OpenGLHelpers::drawQuad3D (float x1, float y1, float z1,
glDrawArrays (GL_TRIANGLE_STRIP, 0, 4);
}
void OpenGLHelpers::drawTriangleStrip (const GLfloat* const vertices, const GLfloat* const textureCoords, const int numVertices) noexcept
{
glEnable (GL_TEXTURE_2D);
glDisableClientState (GL_COLOR_ARRAY);
glDisableClientState (GL_NORMAL_ARRAY);
glEnableClientState (GL_VERTEX_ARRAY);
glVertexPointer (2, GL_FLOAT, 0, vertices);
glEnableClientState (GL_TEXTURE_COORD_ARRAY);
glTexCoordPointer (2, GL_FLOAT, 0, textureCoords);
glDrawArrays (GL_TRIANGLE_STRIP, 0, numVertices);
}
void OpenGLHelpers::drawTriangleStrip (const GLfloat* const vertices, const GLfloat* const textureCoords,
const int numVertices, const GLuint textureID) noexcept
{
jassert (textureID != 0);
glBindTexture (GL_TEXTURE_2D, textureID);
drawTriangleStrip (vertices, textureCoords, numVertices);
glBindTexture (GL_TEXTURE_2D, 0);
}
void OpenGLHelpers::drawTextureQuad (GLuint textureID, int x, int y, int w, int h)
{
const GLfloat l = (GLfloat) x;
const GLfloat t = (GLfloat) y;
const GLfloat r = (GLfloat) (x + w);
const GLfloat b = (GLfloat) (y + h);
const GLfloat vertices[] = { l, t, r, t, l, b, r, b };
const GLfloat textureCoords[] = { 0, 1.0f, 1.0f, 1.0f, 0, 0, 1.0f, 0 };
drawTriangleStrip (vertices, textureCoords, 4, textureID);
}
void OpenGLHelpers::fillRectWithTexture (const Rectangle<int>& rect, GLuint textureID, const float alpha)
{
glTexParameterf (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameterf (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameterf (GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameterf (GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glColor4f (alpha, alpha, alpha, alpha);
drawTextureQuad (textureID, rect.getX(), rect.getY(), rect.getWidth(), rect.getHeight());
}
//==============================================================================
void OpenGLHelpers::fillRectWithColour (const Rectangle<int>& rect, const Colour& colour)
{
@ -238,8 +283,8 @@ void OpenGLHelpers::fillRect (const Rectangle<int>& rect)
//==============================================================================
struct OpenGLEdgeTableRenderer
{
OpenGLEdgeTableRenderer (float r_, float g_, float b_) noexcept
: r (r_), g (g_), b (b_), lastAlpha (-1)
OpenGLEdgeTableRenderer() noexcept
: lastAlpha (-1)
{
}
@ -280,7 +325,6 @@ struct OpenGLEdgeTableRenderer
private:
GLfloat vertices[8];
const float r, g, b;
int lastAlpha;
void drawHorizontal (int x, const int w, const int alphaLevel) noexcept
@ -291,7 +335,8 @@ private:
if (lastAlpha != alphaLevel)
{
lastAlpha = alphaLevel;
glColor4f (r, g, b, alphaLevel / 255.0f);
const float a = alphaLevel / 255.0f;
glColor4f (a, a, a, a);
}
glDrawArrays (GL_TRIANGLE_STRIP, 0, 4);
@ -300,10 +345,9 @@ private:
JUCE_DECLARE_NON_COPYABLE (OpenGLEdgeTableRenderer);
};
void OpenGLHelpers::fillEdgeTable (const EdgeTable& edgeTable,
float red, float green, float blue)
void OpenGLHelpers::fillEdgeTable (const EdgeTable& edgeTable)
{
OpenGLEdgeTableRenderer etr (red, green, blue);
OpenGLEdgeTableRenderer etr;
etr.draw (edgeTable);
}
@ -597,7 +641,8 @@ TriangulatedPath::~TriangulatedPath() {}
void TriangulatedPath::draw (const int oversamplingLevel) const
{
glColor4f (1.0f, 1.0f, 1.0f, 1.0f / (oversamplingLevel * oversamplingLevel));
const float a = 1.0f / (oversamplingLevel * oversamplingLevel);
glColor4f (a, a, a, a);
glPushMatrix();
glTranslatef (-0.5f, -0.5f, 0.0f);

View file

@ -73,14 +73,23 @@ public:
float x4, float y4, float z4,
const Colour& colour);
static void drawTriangleStrip (const GLfloat* const vertices, const GLfloat* const textureCoords, const int numVertices) noexcept;
static void drawTriangleStrip (const GLfloat* const vertices, const GLfloat* const textureCoords,
const int numVertices, const GLuint textureID) noexcept;
static void drawTextureQuad (GLuint textureID, int x, int y, int w, int h);
static void fillRectWithTexture (const Rectangle<int>& rect, GLuint textureID, const float alpha);
static void fillRect (const Rectangle<int>& rect);
/** Fills a rectangle with the specified colour. */
static void fillRectWithColour (const Rectangle<int>& rect,
const Colour& colour);
/** Renders an edge-table into the current context. */
static void fillEdgeTable (const EdgeTable& edgeTable,
float red, float green, float blue);
static void fillEdgeTable (const EdgeTable& edgeTable);
/** Checks whether the current context supports the specified extension. */
static bool isExtensionSupported (const char* extensionName);

View file

@ -94,13 +94,14 @@ void OpenGLTexture::load (const Image& image)
const int srcLineStride = (srcData.pixelStride * imageW + 3) & ~3;
dataCopy.malloc (textureW * textureH);
data = dataCopy;
const int yOffset = textureH - imageH;
if (srcData.pixelFormat == Image::RGB)
{
for (int y = 0; y < imageH; ++y)
{
const PixelRGB* const src = (const PixelRGB*) addBytesToPointer (srcData.data, srcLineStride * y);
PixelARGB* const dst = (PixelARGB*) (dataCopy + textureW * y);
PixelARGB* const dst = (PixelARGB*) (dataCopy + textureW * (y + yOffset));
for (int x = 0; x < imageW; ++x)
dst[x].set (src[x]);
@ -109,7 +110,7 @@ void OpenGLTexture::load (const Image& image)
else if (srcData.pixelFormat == Image::ARGB)
{
for (int y = 0; y < imageH; ++y)
memcpy (dataCopy + textureW * y, addBytesToPointer (srcData.data, srcLineStride * y), srcLineStride);
memcpy (dataCopy + textureW * (y + yOffset), addBytesToPointer (srcData.data, srcLineStride * y), srcLineStride);
}
}
@ -128,7 +129,7 @@ void OpenGLTexture::load (const PixelARGB* pixels, const int w, const int h)
dataCopy.malloc (textureW * textureH);
for (int y = 0; y < h; ++y)
memcpy (dataCopy + textureW * y, pixels + w * y, w * 4);
memcpy (dataCopy + textureW * (y + textureH - h), pixels + w * y, w * 4);
pixels = dataCopy;
}