Browse Source

More OpenGL work.

tags/2021-05-28
jules 13 years ago
parent
commit
f31dca5f2f
30 changed files with 561 additions and 100 deletions
  1. +2
    -0
      extras/JuceDemo/Builds/MacOSX/Juce Demo.xcodeproj/project.pbxproj
  2. +1
    -0
      extras/JuceDemo/Builds/VisualStudio2005/Juce Demo.vcproj
  3. +1
    -0
      extras/JuceDemo/Builds/VisualStudio2008/Juce Demo.vcproj
  4. +1
    -0
      extras/JuceDemo/Builds/VisualStudio2010/Juce Demo.vcxproj
  5. +3
    -0
      extras/JuceDemo/Builds/VisualStudio2010/Juce Demo.vcxproj.filters
  6. +2
    -0
      extras/JuceDemo/Builds/iOS/Juce Demo.xcodeproj/project.pbxproj
  7. +2
    -0
      extras/audio plugin host/Builds/MacOSX/Plugin Host.xcodeproj/project.pbxproj
  8. +1
    -0
      extras/audio plugin host/Builds/VisualStudio2005/Plugin Host.vcproj
  9. +1
    -0
      extras/audio plugin host/Builds/VisualStudio2008/Plugin Host.vcproj
  10. +2
    -0
      extras/static library/Builds/MacOSX/juce.xcodeproj/project.pbxproj
  11. +1
    -0
      extras/static library/Builds/VisualStudio2008/juce.vcproj
  12. +1
    -0
      extras/static library/Builds/VisualStudio2010/juce.vcxproj
  13. +3
    -0
      extras/static library/Builds/VisualStudio2010/juce.vcxproj.filters
  14. +9
    -0
      modules/juce_core/maths/juce_MathsFunctions.h
  15. +7
    -2
      modules/juce_graphics/geometry/juce_AffineTransform.cpp
  16. +5
    -0
      modules/juce_graphics/geometry/juce_AffineTransform.h
  17. +10
    -1
      modules/juce_graphics/images/juce_Image.cpp
  18. +3
    -4
      modules/juce_graphics/native/juce_mac_CoreGraphicsContext.mm
  19. +4
    -0
      modules/juce_opengl/juce_opengl.h
  20. +3
    -10
      modules/juce_opengl/opengl/juce_OpenGLComponent.cpp
  21. +10
    -19
      modules/juce_opengl/opengl/juce_OpenGLComponent.h
  22. +1
    -1
      modules/juce_opengl/opengl/juce_OpenGLContext.h
  23. +69
    -31
      modules/juce_opengl/opengl/juce_OpenGLFrameBuffer.cpp
  24. +18
    -8
      modules/juce_opengl/opengl/juce_OpenGLFrameBuffer.h
  25. +272
    -11
      modules/juce_opengl/opengl/juce_OpenGLHelpers.cpp
  26. +34
    -1
      modules/juce_opengl/opengl/juce_OpenGLHelpers.h
  27. +2
    -2
      modules/juce_opengl/opengl/juce_OpenGLImage.cpp
  28. +62
    -0
      modules/juce_opengl/opengl/juce_OpenGLRenderingTarget.h
  29. +20
    -9
      modules/juce_opengl/opengl/juce_OpenGLTexture.cpp
  30. +11
    -1
      modules/juce_opengl/opengl/juce_OpenGLTexture.h

+ 2
- 0
extras/JuceDemo/Builds/MacOSX/Juce Demo.xcodeproj/project.pbxproj View File

@@ -558,6 +558,7 @@
936C6419223D7B28CE16A72B = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_BufferedInputStream.cpp"; path = "../../../../modules/juce_core/streams/juce_BufferedInputStream.cpp"; sourceTree = "SOURCE_ROOT"; };
9398049BFCAC42B8FD1E16C5 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_DirectXPluginFormat.h"; path = "../../../../modules/juce_audio_processors/format_types/juce_DirectXPluginFormat.h"; sourceTree = "SOURCE_ROOT"; };
93C594ECD5CEA7878114149A = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_win32_WebBrowserComponent.cpp"; path = "../../../../modules/juce_gui_extra/native/juce_win32_WebBrowserComponent.cpp"; sourceTree = "SOURCE_ROOT"; };
942191F317B1B2B1CFBB7C60 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_OpenGLRenderingTarget.h"; path = "../../../../modules/juce_opengl/opengl/juce_OpenGLRenderingTarget.h"; sourceTree = "SOURCE_ROOT"; };
94A9A7DF00C64509E9B5A337 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = QuickTimeDemo.cpp; path = ../../Source/demos/QuickTimeDemo.cpp; sourceTree = "SOURCE_ROOT"; };
94EB4630C360BA31195FA13D = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_AudioIODeviceType.cpp"; path = "../../../../modules/juce_audio_devices/audio_io/juce_AudioIODeviceType.cpp"; sourceTree = "SOURCE_ROOT"; };
95305C4003CD4784CA20D1D1 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_TextEditorKeyMapper.h"; path = "../../../../modules/juce_gui_basics/keyboard/juce_TextEditorKeyMapper.h"; sourceTree = "SOURCE_ROOT"; };
@@ -1871,6 +1872,7 @@
E46977801F19277F4D3B324B,
17422D876DAAF091ED089B8D,
B81FA2ED22BCC03D124031ED,
942191F317B1B2B1CFBB7C60,
FE9A5898294228EB7F439951,
4CFB262AA9778621B8B33A7D ); name = opengl; sourceTree = "<group>"; };
C92FEA88254DAAE793DB3CF7 = { isa = PBXGroup; children = (


+ 1
- 0
extras/JuceDemo/Builds/VisualStudio2005/Juce Demo.vcproj View File

@@ -4242,6 +4242,7 @@
</File>
<File RelativePath="..\..\..\..\modules\juce_opengl\opengl\juce_OpenGLImage.h"/>
<File RelativePath="..\..\..\..\modules\juce_opengl\opengl\juce_OpenGLPixelFormat.h"/>
<File RelativePath="..\..\..\..\modules\juce_opengl\opengl\juce_OpenGLRenderingTarget.h"/>
<File RelativePath="..\..\..\..\modules\juce_opengl\opengl\juce_OpenGLTexture.cpp">
<FileConfiguration Name="Debug|Win32"
ExcludedFromBuild="true">


+ 1
- 0
extras/JuceDemo/Builds/VisualStudio2008/Juce Demo.vcproj View File

@@ -4242,6 +4242,7 @@
</File>
<File RelativePath="..\..\..\..\modules\juce_opengl\opengl\juce_OpenGLImage.h"/>
<File RelativePath="..\..\..\..\modules\juce_opengl\opengl\juce_OpenGLPixelFormat.h"/>
<File RelativePath="..\..\..\..\modules\juce_opengl\opengl\juce_OpenGLRenderingTarget.h"/>
<File RelativePath="..\..\..\..\modules\juce_opengl\opengl\juce_OpenGLTexture.cpp">
<FileConfiguration Name="Debug|Win32"
ExcludedFromBuild="true">


+ 1
- 0
extras/JuceDemo/Builds/VisualStudio2010/Juce Demo.vcxproj View File

@@ -1580,6 +1580,7 @@
<ClInclude Include="..\..\..\..\modules\juce_opengl\opengl\juce_OpenGLHelpers.h"/>
<ClInclude Include="..\..\..\..\modules\juce_opengl\opengl\juce_OpenGLImage.h"/>
<ClInclude Include="..\..\..\..\modules\juce_opengl\opengl\juce_OpenGLPixelFormat.h"/>
<ClInclude Include="..\..\..\..\modules\juce_opengl\opengl\juce_OpenGLRenderingTarget.h"/>
<ClInclude Include="..\..\..\..\modules\juce_opengl\opengl\juce_OpenGLTexture.h"/>
<ClInclude Include="..\..\..\..\modules\juce_opengl\juce_opengl.h"/>
<ClInclude Include="..\..\..\..\modules\juce_video\playback\juce_DirectShowComponent.h"/>


+ 3
- 0
extras/JuceDemo/Builds/VisualStudio2010/Juce Demo.vcxproj.filters View File

@@ -2781,6 +2781,9 @@
<ClInclude Include="..\..\..\..\modules\juce_opengl\opengl\juce_OpenGLPixelFormat.h">
<Filter>Juce Modules\juce_opengl\opengl</Filter>
</ClInclude>
<ClInclude Include="..\..\..\..\modules\juce_opengl\opengl\juce_OpenGLRenderingTarget.h">
<Filter>Juce Modules\juce_opengl\opengl</Filter>
</ClInclude>
<ClInclude Include="..\..\..\..\modules\juce_opengl\opengl\juce_OpenGLTexture.h">
<Filter>Juce Modules\juce_opengl\opengl</Filter>
</ClInclude>


+ 2
- 0
extras/JuceDemo/Builds/iOS/Juce Demo.xcodeproj/project.pbxproj View File

@@ -550,6 +550,7 @@
936C6419223D7B28CE16A72B = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_BufferedInputStream.cpp"; path = "../../../../modules/juce_core/streams/juce_BufferedInputStream.cpp"; sourceTree = "SOURCE_ROOT"; };
9398049BFCAC42B8FD1E16C5 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_DirectXPluginFormat.h"; path = "../../../../modules/juce_audio_processors/format_types/juce_DirectXPluginFormat.h"; sourceTree = "SOURCE_ROOT"; };
93C594ECD5CEA7878114149A = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_win32_WebBrowserComponent.cpp"; path = "../../../../modules/juce_gui_extra/native/juce_win32_WebBrowserComponent.cpp"; sourceTree = "SOURCE_ROOT"; };
942191F317B1B2B1CFBB7C60 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_OpenGLRenderingTarget.h"; path = "../../../../modules/juce_opengl/opengl/juce_OpenGLRenderingTarget.h"; sourceTree = "SOURCE_ROOT"; };
94A9A7DF00C64509E9B5A337 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = QuickTimeDemo.cpp; path = ../../Source/demos/QuickTimeDemo.cpp; sourceTree = "SOURCE_ROOT"; };
94EB4630C360BA31195FA13D = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_AudioIODeviceType.cpp"; path = "../../../../modules/juce_audio_devices/audio_io/juce_AudioIODeviceType.cpp"; sourceTree = "SOURCE_ROOT"; };
95305C4003CD4784CA20D1D1 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_TextEditorKeyMapper.h"; path = "../../../../modules/juce_gui_basics/keyboard/juce_TextEditorKeyMapper.h"; sourceTree = "SOURCE_ROOT"; };
@@ -1861,6 +1862,7 @@
E46977801F19277F4D3B324B,
17422D876DAAF091ED089B8D,
B81FA2ED22BCC03D124031ED,
942191F317B1B2B1CFBB7C60,
FE9A5898294228EB7F439951,
4CFB262AA9778621B8B33A7D ); name = opengl; sourceTree = "<group>"; };
C92FEA88254DAAE793DB3CF7 = { isa = PBXGroup; children = (


+ 2
- 0
extras/audio plugin host/Builds/MacOSX/Plugin Host.xcodeproj/project.pbxproj View File

@@ -341,6 +341,7 @@
582D00AF5D2B03D99D395C5D = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_LowLevelGraphicsSoftwareRenderer.h"; path = "../../../../modules/juce_graphics/contexts/juce_LowLevelGraphicsSoftwareRenderer.h"; sourceTree = "SOURCE_ROOT"; };
5855BA9AD11D9A3AE9FAF972 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_Result.h"; path = "../../../../modules/juce_core/misc/juce_Result.h"; sourceTree = "SOURCE_ROOT"; };
589769409FB8620A45B85335 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_LowLevelGraphicsPostScriptRenderer.h"; path = "../../../../modules/juce_graphics/contexts/juce_LowLevelGraphicsPostScriptRenderer.h"; sourceTree = "SOURCE_ROOT"; };
597D5688E23397FE09F53BA3 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_OpenGLRenderingTarget.h"; path = "../../../../modules/juce_opengl/opengl/juce_OpenGLRenderingTarget.h"; sourceTree = "SOURCE_ROOT"; };
599F30CF78998EA6657D56A0 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_MixerAudioSource.cpp"; path = "../../../../modules/juce_audio_basics/sources/juce_MixerAudioSource.cpp"; sourceTree = "SOURCE_ROOT"; };
5A835BB9C7C51847701951A1 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_OutputStream.h"; path = "../../../../modules/juce_core/streams/juce_OutputStream.h"; sourceTree = "SOURCE_ROOT"; };
5AA6D24CBDEC48447451F46A = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = "juce_gui_extra.mm"; path = "../../../../modules/juce_gui_extra/juce_gui_extra.mm"; sourceTree = "SOURCE_ROOT"; };
@@ -1793,6 +1794,7 @@
C0EECABDA5446EAD76E2578F,
4CE76ABC51CC5E019AED3C2B,
8BA1AF085755958342C9213A,
597D5688E23397FE09F53BA3,
651055751E902F40B83EFD55,
09089786B542AEB678DDE38F ); name = opengl; sourceTree = "<group>"; };
E8C88E6E3FEC2E7A4373205B = { isa = PBXGroup; children = (


+ 1
- 0
extras/audio plugin host/Builds/VisualStudio2005/Plugin Host.vcproj View File

@@ -4165,6 +4165,7 @@
</File>
<File RelativePath="..\..\..\..\modules\juce_opengl\opengl\juce_OpenGLImage.h"/>
<File RelativePath="..\..\..\..\modules\juce_opengl\opengl\juce_OpenGLPixelFormat.h"/>
<File RelativePath="..\..\..\..\modules\juce_opengl\opengl\juce_OpenGLRenderingTarget.h"/>
<File RelativePath="..\..\..\..\modules\juce_opengl\opengl\juce_OpenGLTexture.cpp">
<FileConfiguration Name="Debug|Win32"
ExcludedFromBuild="true">


+ 1
- 0
extras/audio plugin host/Builds/VisualStudio2008/Plugin Host.vcproj View File

@@ -4165,6 +4165,7 @@
</File>
<File RelativePath="..\..\..\..\modules\juce_opengl\opengl\juce_OpenGLImage.h"/>
<File RelativePath="..\..\..\..\modules\juce_opengl\opengl\juce_OpenGLPixelFormat.h"/>
<File RelativePath="..\..\..\..\modules\juce_opengl\opengl\juce_OpenGLRenderingTarget.h"/>
<File RelativePath="..\..\..\..\modules\juce_opengl\opengl\juce_OpenGLTexture.cpp">
<FileConfiguration Name="Debug|Win32"
ExcludedFromBuild="true">


+ 2
- 0
extras/static library/Builds/MacOSX/juce.xcodeproj/project.pbxproj View File

@@ -498,6 +498,7 @@
9D4FC9BEE122256B2557D088 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_OpenGLFrameBuffer.h"; path = "../../../../modules/juce_opengl/opengl/juce_OpenGLFrameBuffer.h"; sourceTree = "SOURCE_ROOT"; };
9D7F83D461E62DDA82C74EA8 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_PropertyPanel.cpp"; path = "../../../../modules/juce_gui_basics/properties/juce_PropertyPanel.cpp"; sourceTree = "SOURCE_ROOT"; };
9D9D7797A0B32F28838D8FC7 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_GZIPCompressorOutputStream.h"; path = "../../../../modules/juce_core/zip/juce_GZIPCompressorOutputStream.h"; sourceTree = "SOURCE_ROOT"; };
9E067C6101B6E2D11365EBDC = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_OpenGLRenderingTarget.h"; path = "../../../../modules/juce_opengl/opengl/juce_OpenGLRenderingTarget.h"; sourceTree = "SOURCE_ROOT"; };
9E7E5C859FFDA600253B3379 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ScopedPointer.h"; path = "../../../../modules/juce_core/memory/juce_ScopedPointer.h"; sourceTree = "SOURCE_ROOT"; };
9E80E6825A34DD1E15D0F61C = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_HeapBlock.h"; path = "../../../../modules/juce_core/memory/juce_HeapBlock.h"; sourceTree = "SOURCE_ROOT"; };
9EAEFA0E956265487E7A3919 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_ios_Audio.cpp"; path = "../../../../modules/juce_audio_devices/native/juce_ios_Audio.cpp"; sourceTree = "SOURCE_ROOT"; };
@@ -1712,6 +1713,7 @@
6DCD8800E380DB691DC9D467,
7251827C30AC1C4F55C3DB69,
6D95302F8D68BA3F0538214F,
9E067C6101B6E2D11365EBDC,
A0D54F01BC8018CC41FA34E9,
53B9B6090EDB9B6E0FA8577F ); name = opengl; sourceTree = "<group>"; };
637D3A9082C214CA0E067538 = { isa = PBXGroup; children = (


+ 1
- 0
extras/static library/Builds/VisualStudio2008/juce.vcproj View File

@@ -4056,6 +4056,7 @@
</File>
<File RelativePath="..\..\..\..\modules\juce_opengl\opengl\juce_OpenGLImage.h"/>
<File RelativePath="..\..\..\..\modules\juce_opengl\opengl\juce_OpenGLPixelFormat.h"/>
<File RelativePath="..\..\..\..\modules\juce_opengl\opengl\juce_OpenGLRenderingTarget.h"/>
<File RelativePath="..\..\..\..\modules\juce_opengl\opengl\juce_OpenGLTexture.cpp">
<FileConfiguration Name="Debug|Win32"
ExcludedFromBuild="true">


+ 1
- 0
extras/static library/Builds/VisualStudio2010/juce.vcxproj View File

@@ -1526,6 +1526,7 @@
<ClInclude Include="..\..\..\..\modules\juce_opengl\opengl\juce_OpenGLHelpers.h"/>
<ClInclude Include="..\..\..\..\modules\juce_opengl\opengl\juce_OpenGLImage.h"/>
<ClInclude Include="..\..\..\..\modules\juce_opengl\opengl\juce_OpenGLPixelFormat.h"/>
<ClInclude Include="..\..\..\..\modules\juce_opengl\opengl\juce_OpenGLRenderingTarget.h"/>
<ClInclude Include="..\..\..\..\modules\juce_opengl\opengl\juce_OpenGLTexture.h"/>
<ClInclude Include="..\..\..\..\modules\juce_opengl\juce_opengl.h"/>
<ClInclude Include="..\..\..\..\modules\juce_video\playback\juce_DirectShowComponent.h"/>


+ 3
- 0
extras/static library/Builds/VisualStudio2010/juce.vcxproj.filters View File

@@ -2616,6 +2616,9 @@
<ClInclude Include="..\..\..\..\modules\juce_opengl\opengl\juce_OpenGLPixelFormat.h">
<Filter>Juce Modules\juce_opengl\opengl</Filter>
</ClInclude>
<ClInclude Include="..\..\..\..\modules\juce_opengl\opengl\juce_OpenGLRenderingTarget.h">
<Filter>Juce Modules\juce_opengl\opengl</Filter>
</ClInclude>
<ClInclude Include="..\..\..\..\modules\juce_opengl\opengl\juce_OpenGLTexture.h">
<Filter>Juce Modules\juce_opengl\opengl</Filter>
</ClInclude>


+ 9
- 0
modules/juce_core/maths/juce_MathsFunctions.h View File

@@ -415,6 +415,15 @@ inline int roundFloatToInt (const float value) noexcept
return roundToInt (value);
}
//==============================================================================
/** Returns true if the specified integer is a power-of-two.
*/
template <typename IntegerType>
bool isPowerOfTwo (IntegerType value)
{
return (value & (value - 1)) == 0;
}
//==============================================================================
#if (JUCE_INTEL && JUCE_32BIT) || defined (DOXYGEN)
/** This macro can be applied to a float variable to check whether it contains a denormalised


+ 7
- 2
modules/juce_graphics/geometry/juce_AffineTransform.cpp View File

@@ -157,14 +157,14 @@ AffineTransform AffineTransform::scale (const float factorX, const float factorY
}
AffineTransform AffineTransform::scaled (const float factorX, const float factorY,
const float pivotX, const float pivotY) const noexcept
const float pivotX, const float pivotY) const noexcept
{
return AffineTransform (factorX * mat00, factorX * mat01, factorX * mat02 + pivotX * (1.0f - factorX),
factorY * mat10, factorY * mat11, factorY * mat12 + pivotY * (1.0f - factorY));
}
AffineTransform AffineTransform::scale (const float factorX, const float factorY,
const float pivotX, const float pivotY) noexcept
const float pivotX, const float pivotY) noexcept
{
return AffineTransform (factorX, 0, pivotX * (1.0f - factorX),
0, factorY, pivotY * (1.0f - factorY));
@@ -186,6 +186,11 @@ AffineTransform AffineTransform::sheared (const float shearX, const float shearY
shearY * mat02 + mat12);
}
AffineTransform AffineTransform::verticalFlip (const float height) noexcept
{
return AffineTransform (1.0f, 0, 0, 0, -1.0f, height);
}
AffineTransform AffineTransform::inverted() const noexcept
{
double determinant = (mat00 * mat11 - mat10 * mat01);


+ 5
- 0
modules/juce_graphics/geometry/juce_AffineTransform.h View File

@@ -185,6 +185,11 @@ public:
/** Returns a shear transform, centred around the origin (0, 0). */
static AffineTransform shear (float shearX, float shearY) noexcept;
/** Returns a transform that will flip co-ordinates vertically within a window of the given height.
This is handy for converting between upside-down coordinate systems such as OpenGL or CoreGraphics.
*/
static AffineTransform verticalFlip (float height) noexcept;
/** Returns a matrix which is the inverse operation of this one.
Some matrices don't have an inverse - in this case, the method will just return


+ 10
- 1
modules/juce_graphics/images/juce_Image.cpp View File

@@ -116,7 +116,16 @@ public:
Image::SharedImage* clone()
{
return new SubsectionSharedImage (image->clone(), area);
Image newImage (format, area.getWidth(), area.getHeight(),
format != Image::RGB, image->getType());
{
Graphics g (newImage);
g.drawImageAt (Image (this), 0, 0);
}
newImage.getSharedImage()->incReferenceCount();
return newImage.getSharedImage();
}
private:


+ 3
- 4
modules/juce_graphics/native/juce_mac_CoreGraphicsContext.mm View File

@@ -169,8 +169,7 @@ void CoreGraphicsContext::setOrigin (int x, int y)
void CoreGraphicsContext::addTransform (const AffineTransform& transform)
{
applyTransform (AffineTransform::scale (1.0f, -1.0f)
.translated (0, flipHeight)
applyTransform (AffineTransform::verticalFlip (flipHeight)
.followedBy (transform)
.translated (0, -flipHeight)
.scaled (1.0f, -1.0f));
@@ -253,7 +252,7 @@ void CoreGraphicsContext::clipToImageAlpha (const Image& sourceImage, const Affi
CGImageRef image = CoreGraphicsImage::createImage (singleChannelImage, true, greyColourSpace, true);
flip();
AffineTransform t (AffineTransform::scale (1.0f, -1.0f).translated (0, sourceImage.getHeight()).followedBy (transform));
AffineTransform t (AffineTransform::verticalFlip (sourceImage.getHeight()).followedBy (transform));
applyTransform (t);
CGRect r = CGRectMake (0, 0, sourceImage.getWidth(), sourceImage.getHeight());
@@ -447,7 +446,7 @@ void CoreGraphicsContext::drawImage (const Image& sourceImage, const AffineTrans
CGContextSetAlpha (context, state->fillType.getOpacity());
flip();
applyTransform (AffineTransform::scale (1.0f, -1.0f).translated (0, ih).followedBy (transform));
applyTransform (AffineTransform::verticalFlip (ih).followedBy (transform));
CGRect imageRect = CGRectMake (0, 0, iw, ih);
if (fillEntireClipAsTiles)


+ 4
- 0
modules/juce_opengl/juce_opengl.h View File

@@ -81,6 +81,7 @@
//=============================================================================
BEGIN_JUCE_NAMESPACE
#include "opengl/juce_OpenGLRenderingTarget.h"
// START_AUTOINCLUDE opengl
#ifndef __JUCE_OPENGLCOMPONENT_JUCEHEADER__
@@ -101,6 +102,9 @@ BEGIN_JUCE_NAMESPACE
#ifndef __JUCE_OPENGLPIXELFORMAT_JUCEHEADER__
#include "opengl/juce_OpenGLPixelFormat.h"
#endif
#ifndef __JUCE_OPENGLRENDERINGTARGET_JUCEHEADER__
#include "opengl/juce_OpenGLRenderingTarget.h"
#endif
#ifndef __JUCE_OPENGLTEXTURE_JUCEHEADER__
#include "opengl/juce_OpenGLTexture.h"
#endif


+ 3
- 10
modules/juce_opengl/opengl/juce_OpenGLComponent.cpp View File

@@ -121,7 +121,6 @@ OpenGLContext* OpenGLContext::getCurrentContext()
class OpenGLComponent::OpenGLComponentWatcher : public ComponentMovementWatcher
{
public:
//==============================================================================
OpenGLComponentWatcher (OpenGLComponent* const owner_)
: ComponentMovementWatcher (owner_),
owner (owner_)
@@ -145,7 +144,6 @@ public:
owner->stopBackgroundThread();
}
//==============================================================================
private:
OpenGLComponent* const owner;
@@ -276,22 +274,17 @@ void OpenGLComponent::recreateContextAsync()
repaint();
}
bool OpenGLComponent::makeCurrentContextActive()
bool OpenGLComponent::makeCurrentRenderingTarget()
{
return context != nullptr && context->makeActive();
}
void OpenGLComponent::makeCurrentContextInactive()
void OpenGLComponent::releaseAsRenderingTarget()
{
if (context != nullptr)
context->makeInactive();
}
bool OpenGLComponent::isActiveContext() const noexcept
{
return context != nullptr && context->isActive();
}
void OpenGLComponent::swapBuffers()
{
if (context != nullptr)
@@ -416,7 +409,7 @@ bool OpenGLComponent::renderAndSwapBuffers()
if (context != nullptr)
{
if (! makeCurrentContextActive())
if (! makeCurrentRenderingTarget())
return false;
if (needToUpdateViewport)


+ 10
- 19
modules/juce_opengl/opengl/juce_OpenGLComponent.h View File

@@ -42,7 +42,8 @@
method to draw its contents.
*/
class JUCE_API OpenGLComponent : public OpenGLBaseType
class JUCE_API OpenGLComponent : public OpenGLBaseType,
public OpenGLRenderingTarget
{
public:
//==============================================================================
@@ -160,10 +161,7 @@ public:
*/
OpenGLContext* getCurrentContext() const noexcept { return context; }
/** Makes this component the current openGL context.
You might want to use this in things like your resize() method, before calling
GL commands.
/** Makes this component the currently active openGL context.
If this returns false, then the context isn't active, so you should avoid
making any calls.
@@ -172,25 +170,18 @@ public:
it does this, it will also synchronously call the newOpenGLContextCreated()
method to let you initialise it as necessary.
@see OpenGLContext::makeActive
@see releaseAsRenderingTarget
*/
bool makeCurrentContextActive();
bool makeCurrentRenderingTarget();
/** Stops the current component being the active OpenGL context.
This is the opposite of makeCurrentContextActive()
@see OpenGLContext::makeInactive
*/
void makeCurrentContextInactive();
/** Returns true if this component's context is the active openGL context for the
current thread.
@see OpenGLContext::isActive
This is the opposite of makeCurrentRenderingTarget()
@see makeCurrentRenderingTarget
*/
bool isActiveContext() const noexcept;
void releaseAsRenderingTarget();
int getRenderingTargetWidth() const { return getWidth(); }
int getRenderingTargetHeight() const { return getHeight(); }
//==============================================================================
/** Calls the rendering callback, and swaps the buffers afterwards.


+ 1
- 1
modules/juce_opengl/opengl/juce_OpenGLContext.h View File

@@ -85,7 +85,7 @@ public:
/** Returns an OS-dependent handle to the raw GL context.
On win32, this will be a HGLRC; on the Mac, an AGLContext; on Linux,
On win32, this will be a HGLRC; on the Mac, an NSOpenGLContext; on Linux,
a GLXContext.
*/
virtual void* getRawContext() const noexcept = 0;


+ 69
- 31
modules/juce_opengl/opengl/juce_OpenGLFrameBuffer.cpp View File

@@ -258,14 +258,14 @@ public:
: width (w), height (h),
data (w * h)
{
buffer.readPixels (data, 0, Rectangle<int> (0, 0, w, h));
buffer.readPixels (data, Rectangle<int> (0, 0, w, h));
}
bool restore (OpenGLFrameBuffer& buffer)
{
if (buffer.initialise (width, height))
{
buffer.writePixels (data, 0, 4, Rectangle<int> (0, 0, width, height));
buffer.writePixels (data, 4, Rectangle<int> (0, 0, width, height));
return true;
}
@@ -294,13 +294,18 @@ bool OpenGLFrameBuffer::initialise (int width, int height)
return pimpl != nullptr;
}
bool OpenGLFrameBuffer::initialise (const Image& content)
bool OpenGLFrameBuffer::initialise (const Image& image)
{
if (initialise (content.getWidth(), content.getHeight()))
if (initialise (image.getWidth(), image.getHeight()))
{
Image::BitmapData bitmap (content, Image::BitmapData::readOnly);
return writePixels (bitmap.data, bitmap.lineStride / bitmap.pixelStride,
bitmap.pixelStride, content.getBounds());
{
Image::BitmapData bitmap (image, Image::BitmapData::readOnly);
if (bitmap.lineStride == image.getWidth() * bitmap.pixelStride)
return writePixels (bitmap.data, bitmap.pixelStride, image.getBounds());
}
return initialise (Image (image.getSharedImage()->clone()));
}
return false;
@@ -340,7 +345,7 @@ int OpenGLFrameBuffer::getWidth() const noexcept { return pimpl != nu
int OpenGLFrameBuffer::getHeight() const noexcept { return pimpl != nullptr ? pimpl->height : 0; }
GLuint OpenGLFrameBuffer::getTextureID() const noexcept { return pimpl != nullptr ? pimpl->textureID : 0; }
bool OpenGLFrameBuffer::makeCurrentTarget()
bool OpenGLFrameBuffer::makeCurrentRenderingTarget()
{
// trying to use a framebuffer after saving it with saveAndRelease()! Be sure to call
// reloadSavedCopy() to put it back into GPU memory before using it..
@@ -349,7 +354,7 @@ bool OpenGLFrameBuffer::makeCurrentTarget()
return pimpl != nullptr && pimpl->bind();
}
void OpenGLFrameBuffer::releaseCurrentTarget()
void OpenGLFrameBuffer::releaseAsRenderingTarget()
{
if (pimpl != nullptr)
pimpl->unbind();
@@ -357,22 +362,28 @@ void OpenGLFrameBuffer::releaseCurrentTarget()
void OpenGLFrameBuffer::clear (const Colour& colour)
{
if (makeCurrentTarget())
if (makeCurrentRenderingTarget())
{
OpenGLHelpers::clear (colour);
releaseCurrentTarget();
releaseAsRenderingTarget();
}
}
bool OpenGLFrameBuffer::readPixels (void* target, int lineStride, const Rectangle<int>& area)
void OpenGLFrameBuffer::makeCurrentAndClear()
{
if (! makeCurrentTarget())
return false;
if (makeCurrentRenderingTarget())
{
glClearColor (0, 0, 0, 0);
glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
}
}
OpenGLHelpers::prepareFor2D (pimpl->width, pimpl->height);
bool OpenGLFrameBuffer::readPixels (void* target, const Rectangle<int>& area)
{
if (! makeCurrentRenderingTarget())
return false;
glPixelStorei (GL_PACK_ALIGNMENT, 4);
glPixelStorei (GL_PACK_ROW_LENGTH, lineStride);
glReadPixels (area.getX(), area.getY(), area.getWidth(), area.getHeight(), GL_RGBA, GL_UNSIGNED_BYTE, target);
glBindFramebufferEXT (GL_FRAMEBUFFER_EXT, 0);
@@ -380,16 +391,16 @@ bool OpenGLFrameBuffer::readPixels (void* target, int lineStride, const Rectangl
return true;
}
bool OpenGLFrameBuffer::writePixels (const void* data, int lineStride, int pixelStride, const Rectangle<int>& area)
bool OpenGLFrameBuffer::writePixels (const void* data, int pixelStride, const Rectangle<int>& area)
{
if (! makeCurrentTarget())
if (! makeCurrentRenderingTarget())
return false;
OpenGLHelpers::prepareFor2D (pimpl->width, pimpl->height);
jassert (pixelStride == 3 || pixelStride == 4); // can only handle RGB or ARGB
const int format = pixelStride == 3 ? GL_RGB : GL_BGRA_EXT;
const int invertedY = pimpl->height - area.getBottom();
OpenGLHelpers::prepareFor2D (pimpl->width, pimpl->height);
glDisable (GL_DEPTH_TEST);
glDisable (GL_BLEND);
@@ -405,7 +416,6 @@ bool OpenGLFrameBuffer::writePixels (const void* data, int lineStride, int pixel
glBindTexture (GL_TEXTURE_2D, temporaryTexture);
glPixelStorei (GL_UNPACK_ALIGNMENT, pixelStride);
glPixelStorei (GL_UNPACK_ROW_LENGTH, lineStride);
glTexImage2D (GL_TEXTURE_2D, 0, GL_RGBA, area.getWidth(), area.getHeight(), 0,
format, GL_UNSIGNED_BYTE, data);
@@ -415,19 +425,19 @@ bool OpenGLFrameBuffer::writePixels (const void* data, int lineStride, int pixel
const int cropRect[4] = { 0, 0, area.getWidth(), area.getHeight() };
glTexParameteriv (GL_TEXTURE_2D, GL_TEXTURE_CROP_RECT_OES, cropRect);
glDrawTexiOES (area.getX(), area.getY(), 1, area.getWidth(), area.getHeight());
glDrawTexiOES (area.getX(), invertedY, 1, area.getWidth(), area.getHeight());
glBindTexture (GL_TEXTURE_2D, 0);
glDeleteTextures (1, &temporaryTexture);
}
#else
glRasterPos2i (area.getX(), area.getY());
glRasterPos2i (area.getX(), invertedY);
glBindTexture (GL_TEXTURE_2D, 0);
glPixelStorei (GL_UNPACK_ALIGNMENT, pixelStride);
glPixelStorei (GL_UNPACK_ROW_LENGTH, lineStride);
glPixelStorei (GL_UNPACK_ROW_LENGTH, 0);
glDrawPixels (area.getWidth(), area.getHeight(), format, GL_UNSIGNED_BYTE, data);
#endif
#endif
glBindFramebufferEXT (GL_FRAMEBUFFER_EXT, 0);
@@ -462,10 +472,39 @@ void OpenGLFrameBuffer::draw3D (float x1, float y1, float z1,
}
}
void OpenGLFrameBuffer::drawAt (float x1, float y1) const
{
if (pimpl != nullptr)
{
glEnable (GL_TEXTURE_2D);
glBindTexture (GL_TEXTURE_2D, pimpl->textureID);
glDisableClientState (GL_COLOR_ARRAY);
glDisableClientState (GL_NORMAL_ARRAY);
const GLfloat vertices[] = { x1, y1,
x1 + pimpl->width, y1,
x1, y1 + pimpl->height,
x1 + pimpl->width, y1 + pimpl->height };
const GLfloat textureCoords[] = { 0, 0, 1.0f, 0, 0, 1.0f, 1.0f, 1.0f };
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, 4);
glBindTexture (GL_TEXTURE_2D, 0);
}
}
//==============================================================================
void OpenGLFrameBuffer::createAlphaChannelFromPath (const Path& path, const int oversamplingLevel)
void OpenGLFrameBuffer::createAlphaChannelFromPath (const Path& path, const AffineTransform& transform,
const int oversamplingLevel)
{
makeCurrentTarget();
makeCurrentRenderingTarget();
glEnableClientState (GL_VERTEX_ARRAY);
glEnableClientState (GL_TEXTURE_COORD_ARRAY);
@@ -473,13 +512,12 @@ void OpenGLFrameBuffer::createAlphaChannelFromPath (const Path& path, const int
glDisableClientState (GL_NORMAL_ARRAY);
glDisable (GL_TEXTURE_2D);
glDisable (GL_DEPTH_TEST);
glColorMask (GL_FALSE, GL_FALSE, GL_FALSE, GL_TRUE);
glColorMask (GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
glEnable (GL_BLEND);
glBlendFunc (GL_ONE, GL_ONE);
OpenGLHelpers::prepareFor2D (getWidth(), getHeight());
TriangulatedPath (path).draw (oversamplingLevel);
prepareFor2D();
TriangulatedPath (path, transform).draw (oversamplingLevel);
}
END_JUCE_NAMESPACE

+ 18
- 8
modules/juce_opengl/opengl/juce_OpenGLFrameBuffer.h View File

@@ -31,7 +31,7 @@
/**
Creates an openGL frame buffer.
*/
class JUCE_API OpenGLFrameBuffer
class JUCE_API OpenGLFrameBuffer : public OpenGLRenderingTarget
{
public:
/** Creates an uninitialised buffer.
@@ -81,19 +81,25 @@ public:
/** Returns the height of the buffer. */
int getHeight() const noexcept;
int getRenderingTargetWidth() const { return getWidth(); }
int getRenderingTargetHeight() const { return getHeight(); }
/** Returns the texture ID number for using this buffer as a texture. */
unsigned int getTextureID() const noexcept;
GLuint getTextureID() const noexcept;
//==============================================================================
/** Selects this buffer as the current OpenGL rendering target. */
bool makeCurrentTarget();
bool makeCurrentRenderingTarget();
/** Deselects this buffer as the current OpenGL rendering target. */
void releaseCurrentTarget();
void releaseAsRenderingTarget();
/** Clears the framebuffer with the specified colour. */
void clear (const Colour& colour);
/** Selects the framebuffer as the current target, and clears it to transparent. */
void makeCurrentAndClear();
/** Draws this framebuffer onto the current context, with the specified corner positions. */
void draw2D (float x1, float y1,
float x2, float y2,
@@ -108,18 +114,20 @@ public:
float x4, float y4, float z4,
const Colour& colour) const;
/** Draws the framebuffer at a given position. */
void drawAt (float x1, float y1) const;
/** Reads an area of pixels from the framebuffer into a 32-bit ARGB pixel array.
The lineStride is measured as a number of pixels, not bytes - pass a stride
of 0 to indicate a packed array.
*/
bool readPixels (void* targetData, int lineStride, const Rectangle<int>& sourceArea);
bool readPixels (void* targetData, const Rectangle<int>& sourceArea);
/** Writes an area of pixels into the framebuffer from a specified pixel array.
The lineStride is measured as a number of pixels, not bytes - pass a stride
of 0 to indicate a packed array.
*/
bool writePixels (const void* srcData,
int srcLineStride, int srcPixelStride,
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.
@@ -131,7 +139,9 @@ public:
Calling this will make changes to a lot of openGL state, including colour masks, blend
functions, etc
*/
void createAlphaChannelFromPath (const Path& path, int oversamplingLevel = 4);
void createAlphaChannelFromPath (const Path& path,
const AffineTransform& transform,
int oversamplingLevel = 4);
private:
class Pimpl;


+ 272
- 11
modules/juce_opengl/opengl/juce_OpenGLHelpers.cpp View File

@@ -25,6 +25,7 @@
BEGIN_JUCE_NAMESPACE
//==============================================================================
void OpenGLHelpers::resetErrorState()
{
while (glGetError() != GL_NO_ERROR) {}
@@ -44,7 +45,7 @@ void OpenGLHelpers::setColour (const Colour& colour)
colour.getFloatBlue(), colour.getFloatAlpha());
}
void OpenGLHelpers::prepareFor2D (int width, int height)
void OpenGLHelpers::prepareFor2D (const int width, const int height)
{
glMatrixMode (GL_PROJECTION);
glLoadIdentity();
@@ -75,6 +76,15 @@ void OpenGLHelpers::setPerspective (double fovy, double aspect, double zNear, do
#endif
}
void OpenGLHelpers::applyTransform (const AffineTransform& t)
{
const GLfloat m[] = { t.mat00, t.mat10, 0, 0,
t.mat01, t.mat11, 0, 0,
0, 0, 1, 0,
t.mat02, t.mat12, 0, 1 };
glMultMatrixf (m);
}
void OpenGLHelpers::drawQuad2D (float x1, float y1,
float x2, float y2,
float x3, float y3,
@@ -126,6 +136,8 @@ 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);
glDisableClientState (GL_COLOR_ARRAY);
@@ -243,11 +255,6 @@ void OpenGLHelpers::fillRectWithColourGradient (const Rectangle<int>& rect,
texture.load (lookup, textureSize, 1);
texture.bind();
if (gradient.isOpaque())
glDisable (GL_BLEND);
else
glEnable (GL_BLEND);
if (gradient.point1 == gradient.point2)
{
fillRectWithColour (rect, gradient.getColourAtPosition (1.0));
@@ -267,13 +274,17 @@ void OpenGLHelpers::fillRectWithColour (const Rectangle<int>& rect, const Colour
glDisableClientState (GL_TEXTURE_COORD_ARRAY);
glDisableClientState (GL_COLOR_ARRAY);
glDisableClientState (GL_NORMAL_ARRAY);
setColour (colour);
fillRect (rect);
}
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() };
setColour (colour);
glVertexPointer (2, GL_FLOAT, 0, vertices);
glDrawArrays (GL_TRIANGLE_STRIP, 0, 4);
}
@@ -283,11 +294,11 @@ void OpenGLHelpers::fillRectWithColour (const Rectangle<int>& rect, const Colour
class TriangulatedPath::TrapezoidedPath
{
public:
TrapezoidedPath (const Path& p)
TrapezoidedPath (const Path& p, const AffineTransform& transform)
: firstSlice (nullptr),
windingMask (p.isUsingNonZeroWinding() ? -1 : 1)
{
for (PathFlatteningIterator iter (p); iter.next();)
for (PathFlatteningIterator iter (p, transform); iter.next();)
addLine (floatToInt (iter.x1), floatToInt (iter.y1),
floatToInt (iter.x2), floatToInt (iter.y2));
}
@@ -558,10 +569,10 @@ struct TriangulatedPath::TriangleBlock
HeapBlock<GLfloat> triangles;
};
TriangulatedPath::TriangulatedPath (const Path& path)
TriangulatedPath::TriangulatedPath (const Path& path, const AffineTransform& transform)
{
startNewBlock();
TrapezoidedPath (path).iterate (*this);
TrapezoidedPath (path, transform).iterate (*this);
}
void TriangulatedPath::draw (const int oversamplingLevel) const
@@ -619,4 +630,254 @@ void TriangulatedPath::addTrapezoid (GLfloat y1, GLfloat y2, GLfloat x1, GLfloat
currentBlock->numVertices += 12;
}
//==============================================================================
OpenGLTextureFromImage::OpenGLTextureFromImage (const Image& image)
: width (image.getWidth()),
height (image.getHeight())
{
OpenGLFrameBufferImage* glImage = dynamic_cast <OpenGLFrameBufferImage*> (image.getSharedImage());
if (glImage != nullptr)
{
textureID = glImage->frameBuffer.getTextureID();
}
else
{
if (OpenGLTexture::isValidSize (width, height))
{
texture = new OpenGLTexture();
texture->load (image);
textureID = texture->getTextureID();
}
else
{
frameBuffer = new OpenGLFrameBuffer();
frameBuffer->initialise (image);
textureID = frameBuffer->getTextureID();
}
}
}
OpenGLTextureFromImage::~OpenGLTextureFromImage() {}
//==============================================================================
OpenGLRenderingTarget::OpenGLRenderingTarget() {}
OpenGLRenderingTarget::~OpenGLRenderingTarget() {}
void OpenGLRenderingTarget::prepareFor2D()
{
OpenGLHelpers::prepareFor2D (getRenderingTargetWidth(),
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

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

@@ -26,6 +26,10 @@
#ifndef __JUCE_OPENGLHELPERS_JUCEHEADER__
#define __JUCE_OPENGLHELPERS_JUCEHEADER__
class OpenGLTexture;
class OpenGLFrameBuffer;
//==============================================================================
/**
A set of miscellaneous openGL helper functions.
@@ -48,6 +52,8 @@ public:
/** This does the same job as gluPerspective(). */
static void setPerspective (double fovy, double aspect, double zNear, double zFar);
static void applyTransform (const AffineTransform& t);
/** Draws a 2D quad with the specified corner points. */
static void drawQuad2D (float x1, float y1,
float x2, float y2,
@@ -62,6 +68,8 @@ public:
float x4, float y4, float z4,
const Colour& colour);
static void fillRect (const Rectangle<int>& rect);
/** Fills a rectangle with the specified colour. */
static void fillRectWithColour (const Rectangle<int>& rect,
const Colour& colour);
@@ -78,7 +86,7 @@ public:
class JUCE_API TriangulatedPath
{
public:
TriangulatedPath (const Path& path);
TriangulatedPath (const Path& path, const AffineTransform& transform);
/** Renders the path, using a jittered oversampling method.
The oversampling level is the square root of the number of times it
@@ -106,4 +114,29 @@ private:
};
//==============================================================================
/**
Used as a local object while rendering, this will create a temporary texture ID
from an image in the quickest way possible.
If the image is backed by an OpenGL framebuffer, it will use that directly; otherwise,
this object will create a temporary texture or framebuffer and copy the image.
*/
class JUCE_API OpenGLTextureFromImage
{
public:
OpenGLTextureFromImage (const Image& image);
~OpenGLTextureFromImage();
GLuint textureID;
const int width, height;
private:
ScopedPointer<OpenGLTexture> texture;
ScopedPointer<OpenGLFrameBuffer> frameBuffer;
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (OpenGLTextureFromImage);
};
#endif // __JUCE_OPENGLHELPERS_JUCEHEADER__

+ 2
- 2
modules/juce_opengl/opengl/juce_OpenGLImage.cpp View File

@@ -74,7 +74,7 @@ namespace OpenGLImageHelpers
{
static void read (OpenGLFrameBuffer& frameBuffer, Image::BitmapData& bitmapData, int x, int y)
{
frameBuffer.readPixels (bitmapData.data, 0, Rectangle<int> (x, y, bitmapData.width, bitmapData.height));
frameBuffer.readPixels (bitmapData.data, Rectangle<int> (x, y, bitmapData.width, bitmapData.height));
}
};
@@ -86,7 +86,7 @@ namespace OpenGLImageHelpers
void write (const void* const data) const noexcept
{
frameBuffer.writePixels (data, 0, 4, area);
frameBuffer.writePixels (data, 4, area);
}
OpenGLFrameBuffer& frameBuffer;


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

@@ -0,0 +1,62 @@
/*
==============================================================================
This file is part of the JUCE library - "Jules' Utility Class Extensions"
Copyright 2004-11 by Raw Material Software Ltd.
------------------------------------------------------------------------------
JUCE can be redistributed and/or modified under the terms of the GNU General
Public License (Version 2), as published by the Free Software Foundation.
A copy of the license is included in the JUCE distribution, or can be found
online at www.gnu.org/licenses.
JUCE is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
------------------------------------------------------------------------------
To release a closed-source product which uses JUCE, commercial licenses are
available: visit www.rawmaterialsoftware.com/juce for more information.
==============================================================================
*/
#ifndef __JUCE_OPENGLRENDERINGTARGET_JUCEHEADER__
#define __JUCE_OPENGLRENDERINGTARGET_JUCEHEADER__
//==============================================================================
/**
Base class for OpenGL objects which can be selected as a rendering target.
*/
class JUCE_API OpenGLRenderingTarget
{
public:
OpenGLRenderingTarget();
virtual ~OpenGLRenderingTarget();
/** Activates this object as the current OpenGL target. */
virtual bool makeCurrentRenderingTarget() = 0;
/** Deactivates this object as the current OpenGL target. */
virtual void releaseAsRenderingTarget() = 0;
/** Returns the width in pixels of this target. */
virtual int getRenderingTargetWidth() const = 0;
/** Returns the height in pixels of this target. */
virtual int getRenderingTargetHeight() const = 0;
/** Sets the current matrix for 2D rendering into this object.
@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);
};
#endif // __JUCE_OPENGLRENDERINGTARGET_JUCEHEADER__

+ 20
- 9
modules/juce_opengl/opengl/juce_OpenGLTexture.cpp View File

@@ -42,16 +42,20 @@ OpenGLTexture::~OpenGLTexture()
release();
}
bool OpenGLTexture::isValidSize (int width, int height)
{
return isPowerOfTwo (width) && isPowerOfTwo (height);
}
void OpenGLTexture::create (const int w, const int h)
{
jassert (isValidSize (w, h)); // Perhaps these dimensions must be a power-of-two?
release();
width = w;
height = h;
jassert (BitArray (width).countNumberOfSetBits() == 1); // these dimensions must be a power-of-two
jassert (BitArray (height).countNumberOfSetBits() == 1);
glGenTextures (1, &textureID);
glBindTexture (GL_TEXTURE_2D, textureID);
@@ -67,14 +71,21 @@ void OpenGLTexture::load (const Image& image)
{
create (image.getWidth(), image.getHeight());
Image::BitmapData srcData (image, Image::BitmapData::readOnly);
{
Image::BitmapData srcData (image, Image::BitmapData::readOnly);
glPixelStorei (GL_UNPACK_ALIGNMENT, srcData.pixelFormat);
glPixelStorei (GL_UNPACK_ALIGNMENT, srcData.pixelFormat);
glPixelStorei (GL_UNPACK_ROW_LENGTH, srcData.lineStride);
if (srcData.lineStride == image.getWidth() * srcData.pixelStride)
{
glTexImage2D (GL_TEXTURE_2D, 0, internalGLTextureFormat, width, height, 0,
srcData.pixelFormat == Image::RGB ? GL_RGB : GL_BGRA_EXT,
GL_UNSIGNED_BYTE, srcData.data);
return;
}
}
glTexImage2D (GL_TEXTURE_2D, 0, internalGLTextureFormat, width, height, 0,
srcData.pixelFormat == Image::RGB ? GL_RGB : GL_BGRA_EXT,
GL_UNSIGNED_BYTE, srcData.data);
load (Image (image.getSharedImage()->clone()));
}
void OpenGLTexture::load (const PixelARGB* const pixels, const int w, const int h)


+ 11
- 1
modules/juce_opengl/opengl/juce_OpenGLTexture.h View File

@@ -26,6 +26,7 @@
#ifndef __JUCE_OPENGLTEXTURE_JUCEHEADER__
#define __JUCE_OPENGLTEXTURE_JUCEHEADER__
//==============================================================================
/**
Creates an openGL texture from an Image.
*/
@@ -66,8 +67,16 @@ public:
float x4, float y4, float z4,
const Colour& colour) const;
/** Returns the GL texture ID number. */
GLuint getTextureID() const noexcept { return textureID; }
/** Returns true if a texture can be created with the given size.
Some systems may require that the sizes are powers-of-two.
*/
static bool isValidSize (int width, int height);
private:
unsigned int textureID;
GLuint textureID;
int width, height;
void create (int w, int h);
@@ -75,4 +84,5 @@ private:
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (OpenGLTexture);
};
#endif // __JUCE_OPENGLTEXTURE_JUCEHEADER__

Loading…
Cancel
Save