diff --git a/extras/JuceDemo/Builds/MacOSX/Juce Demo.xcodeproj/project.pbxproj b/extras/JuceDemo/Builds/MacOSX/Juce Demo.xcodeproj/project.pbxproj index d551b33e8c..2de7febc2c 100644 --- a/extras/JuceDemo/Builds/MacOSX/Juce Demo.xcodeproj/project.pbxproj +++ b/extras/JuceDemo/Builds/MacOSX/Juce Demo.xcodeproj/project.pbxproj @@ -506,6 +506,7 @@ 7D12F1C172F94A735E17ADD4 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ColourGradient.h"; path = "../../../../modules/juce_graphics/colour/juce_ColourGradient.h"; sourceTree = "SOURCE_ROOT"; }; 7DA4BF4F615254D8AFD37BEE = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_Button.h"; path = "../../../../modules/juce_gui_basics/buttons/juce_Button.h"; sourceTree = "SOURCE_ROOT"; }; 7E0006CE91286527B25433FF = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ResamplingAudioSource.h"; path = "../../../../modules/juce_audio_basics/sources/juce_ResamplingAudioSource.h"; sourceTree = "SOURCE_ROOT"; }; + 7E6041874E267458572B93A1 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_MissingGLDefinitions.h"; path = "../../../../modules/juce_opengl/native/juce_MissingGLDefinitions.h"; sourceTree = "SOURCE_ROOT"; }; 7E6AEB024827FD9ACB353BB6 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_MemoryMappedFile.h"; path = "../../../../modules/juce_core/files/juce_MemoryMappedFile.h"; sourceTree = "SOURCE_ROOT"; }; 7EF1F0BC4F4DE2986856DE41 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_Viewport.h"; path = "../../../../modules/juce_gui_basics/layout/juce_Viewport.h"; sourceTree = "SOURCE_ROOT"; }; 7F2A4EF4DE29CE775FF0F5E5 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_ResizableBorderComponent.cpp"; path = "../../../../modules/juce_gui_basics/layout/juce_ResizableBorderComponent.cpp"; sourceTree = "SOURCE_ROOT"; }; @@ -1919,6 +1920,7 @@ ED9FAEA9116C568942BAD000, 6E1CFF5227B2F2E200DD9EC7, AE394742FA0F2C6AA39906DD, + 7E6041874E267458572B93A1, 8565630D87FEE505D50CE2EF, D66048AF1E05FF836B2A813A ); name = native; sourceTree = ""; }; 7CFCB9A92FB574419734C1F5 = { isa = PBXGroup; children = ( diff --git a/extras/JuceDemo/Builds/VisualStudio2005/Juce Demo.vcproj b/extras/JuceDemo/Builds/VisualStudio2005/Juce Demo.vcproj index 7bf90c9dda..8de370ea28 100644 --- a/extras/JuceDemo/Builds/VisualStudio2005/Juce Demo.vcproj +++ b/extras/JuceDemo/Builds/VisualStudio2005/Juce Demo.vcproj @@ -4360,6 +4360,7 @@ + + + diff --git a/extras/JuceDemo/Builds/VisualStudio2010/Juce Demo.vcxproj.filters b/extras/JuceDemo/Builds/VisualStudio2010/Juce Demo.vcxproj.filters index 70deb99274..a306863093 100644 --- a/extras/JuceDemo/Builds/VisualStudio2010/Juce Demo.vcxproj.filters +++ b/extras/JuceDemo/Builds/VisualStudio2010/Juce Demo.vcxproj.filters @@ -2844,6 +2844,9 @@ Juce Modules\juce_opengl\opengl + + Juce Modules\juce_opengl\native + Juce Modules\juce_opengl\native diff --git a/extras/JuceDemo/Builds/iOS/Juce Demo.xcodeproj/project.pbxproj b/extras/JuceDemo/Builds/iOS/Juce Demo.xcodeproj/project.pbxproj index 8a6ab28e1c..be9556f8b8 100644 --- a/extras/JuceDemo/Builds/iOS/Juce Demo.xcodeproj/project.pbxproj +++ b/extras/JuceDemo/Builds/iOS/Juce Demo.xcodeproj/project.pbxproj @@ -499,6 +499,7 @@ 7D12F1C172F94A735E17ADD4 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ColourGradient.h"; path = "../../../../modules/juce_graphics/colour/juce_ColourGradient.h"; sourceTree = "SOURCE_ROOT"; }; 7DA4BF4F615254D8AFD37BEE = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_Button.h"; path = "../../../../modules/juce_gui_basics/buttons/juce_Button.h"; sourceTree = "SOURCE_ROOT"; }; 7E0006CE91286527B25433FF = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ResamplingAudioSource.h"; path = "../../../../modules/juce_audio_basics/sources/juce_ResamplingAudioSource.h"; sourceTree = "SOURCE_ROOT"; }; + 7E6041874E267458572B93A1 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_MissingGLDefinitions.h"; path = "../../../../modules/juce_opengl/native/juce_MissingGLDefinitions.h"; sourceTree = "SOURCE_ROOT"; }; 7E6AEB024827FD9ACB353BB6 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_MemoryMappedFile.h"; path = "../../../../modules/juce_core/files/juce_MemoryMappedFile.h"; sourceTree = "SOURCE_ROOT"; }; 7EF1F0BC4F4DE2986856DE41 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_Viewport.h"; path = "../../../../modules/juce_gui_basics/layout/juce_Viewport.h"; sourceTree = "SOURCE_ROOT"; }; 7F2A4EF4DE29CE775FF0F5E5 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_ResizableBorderComponent.cpp"; path = "../../../../modules/juce_gui_basics/layout/juce_ResizableBorderComponent.cpp"; sourceTree = "SOURCE_ROOT"; }; @@ -1909,6 +1910,7 @@ ED9FAEA9116C568942BAD000, 6E1CFF5227B2F2E200DD9EC7, AE394742FA0F2C6AA39906DD, + 7E6041874E267458572B93A1, 8565630D87FEE505D50CE2EF, D66048AF1E05FF836B2A813A ); name = native; sourceTree = ""; }; 7CFCB9A92FB574419734C1F5 = { isa = PBXGroup; children = ( diff --git a/extras/audio plugin host/Builds/MacOSX/Plugin Host.xcodeproj/project.pbxproj b/extras/audio plugin host/Builds/MacOSX/Plugin Host.xcodeproj/project.pbxproj index 1a4b844f98..141e7bedad 100644 --- a/extras/audio plugin host/Builds/MacOSX/Plugin Host.xcodeproj/project.pbxproj +++ b/extras/audio plugin host/Builds/MacOSX/Plugin Host.xcodeproj/project.pbxproj @@ -620,6 +620,7 @@ B27CEFF5B55B38F2BEB141D1 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_Atomic.h"; path = "../../../../modules/juce_core/memory/juce_Atomic.h"; sourceTree = "SOURCE_ROOT"; }; B2976F6A6BFA0C881FDF4B79 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_RelativePoint.cpp"; path = "../../../../modules/juce_gui_basics/positioning/juce_RelativePoint.cpp"; sourceTree = "SOURCE_ROOT"; }; B3B91E79E9BE863EFB7B2B70 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_ComboBox.cpp"; path = "../../../../modules/juce_gui_basics/widgets/juce_ComboBox.cpp"; sourceTree = "SOURCE_ROOT"; }; + B3E0F684EFAAB3722FC50D6F = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_MissingGLDefinitions.h"; path = "../../../../modules/juce_opengl/native/juce_MissingGLDefinitions.h"; sourceTree = "SOURCE_ROOT"; }; B454943748D0748AAF53A06F = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_Expression.cpp"; path = "../../../../modules/juce_core/maths/juce_Expression.cpp"; sourceTree = "SOURCE_ROOT"; }; B457EE687507BF1DEEA7581F = { isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = WebKit.framework; path = System/Library/Frameworks/WebKit.framework; sourceTree = SDKROOT; }; B49AAED30299568B2E4A864A = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_ResizableBorderComponent.cpp"; path = "../../../../modules/juce_gui_basics/layout/juce_ResizableBorderComponent.cpp"; sourceTree = "SOURCE_ROOT"; }; @@ -1841,6 +1842,7 @@ 6E673B706EA21387275F30FD, D4CC4DE44C44AEE40085ACD7, 1668565234C6F9C31363BBE2, + B3E0F684EFAAB3722FC50D6F, 8BD67EC10CC86AB4DB096E5D, 7916CA65827E16B3775C4952 ); name = native; sourceTree = ""; }; 2C43A64E61A92F2912632BD6 = { isa = PBXGroup; children = ( diff --git a/extras/audio plugin host/Builds/VisualStudio2005/Plugin Host.vcproj b/extras/audio plugin host/Builds/VisualStudio2005/Plugin Host.vcproj index 1d644335e5..802c21ebdc 100644 --- a/extras/audio plugin host/Builds/VisualStudio2005/Plugin Host.vcproj +++ b/extras/audio plugin host/Builds/VisualStudio2005/Plugin Host.vcproj @@ -4283,6 +4283,7 @@ + + + + diff --git a/extras/static library/Builds/VisualStudio2010/juce.vcxproj.filters b/extras/static library/Builds/VisualStudio2010/juce.vcxproj.filters index 2b19021686..ad13819717 100644 --- a/extras/static library/Builds/VisualStudio2010/juce.vcxproj.filters +++ b/extras/static library/Builds/VisualStudio2010/juce.vcxproj.filters @@ -2679,6 +2679,9 @@ Juce Modules\juce_opengl\opengl + + Juce Modules\juce_opengl\native + Juce Modules\juce_opengl\native diff --git a/modules/juce_audio_basics/juce_module_info b/modules/juce_audio_basics/juce_module_info index 560db4e164..96a7fef26c 100644 --- a/modules/juce_audio_basics/juce_module_info +++ b/modules/juce_audio_basics/juce_module_info @@ -1,7 +1,7 @@ { "id": "juce_audio_basics", "name": "JUCE audio and midi data classes", - "version": "2.0.14", + "version": "2.0.15", "description": "Classes for audio buffer manipulation, midi message handling, synthesis, etc", "website": "http://www.juce.com/juce", "license": "GPL/Commercial", diff --git a/modules/juce_audio_devices/juce_module_info b/modules/juce_audio_devices/juce_module_info index 345d6ef3f1..15f7b652e6 100644 --- a/modules/juce_audio_devices/juce_module_info +++ b/modules/juce_audio_devices/juce_module_info @@ -1,7 +1,7 @@ { "id": "juce_audio_devices", "name": "JUCE audio and midi I/O device classes", - "version": "2.0.14", + "version": "2.0.15", "description": "Classes to play and record from audio and midi i/o devices.", "website": "http://www.juce.com/juce", "license": "GPL/Commercial", diff --git a/modules/juce_audio_formats/juce_module_info b/modules/juce_audio_formats/juce_module_info index 149d9f4388..96caa6b4c2 100644 --- a/modules/juce_audio_formats/juce_module_info +++ b/modules/juce_audio_formats/juce_module_info @@ -1,7 +1,7 @@ { "id": "juce_audio_formats", "name": "JUCE audio file format codecs", - "version": "2.0.14", + "version": "2.0.15", "description": "Classes for reading and writing various audio file formats.", "website": "http://www.juce.com/juce", "license": "GPL/Commercial", diff --git a/modules/juce_audio_plugin_client/juce_module_info b/modules/juce_audio_plugin_client/juce_module_info index 9c9f64058f..bfe1adc3ea 100644 --- a/modules/juce_audio_plugin_client/juce_module_info +++ b/modules/juce_audio_plugin_client/juce_module_info @@ -1,7 +1,7 @@ { "id": "juce_audio_plugin_client", "name": "JUCE audio plugin wrapper classes", - "version": "2.0.14", + "version": "2.0.15", "description": "Classes for building VST, RTAS and AU plugins.", "website": "http://www.juce.com/juce", "license": "GPL/Commercial", diff --git a/modules/juce_audio_processors/juce_module_info b/modules/juce_audio_processors/juce_module_info index 4535868f2c..2eb723af8c 100644 --- a/modules/juce_audio_processors/juce_module_info +++ b/modules/juce_audio_processors/juce_module_info @@ -1,7 +1,7 @@ { "id": "juce_audio_processors", "name": "JUCE audio plugin hosting classes", - "version": "2.0.14", + "version": "2.0.15", "description": "Classes for loading and playing VST, AU, or internally-generated audio processors.", "website": "http://www.juce.com/juce", "license": "GPL/Commercial", diff --git a/modules/juce_audio_utils/juce_module_info b/modules/juce_audio_utils/juce_module_info index b799abe443..bcb7d917cf 100644 --- a/modules/juce_audio_utils/juce_module_info +++ b/modules/juce_audio_utils/juce_module_info @@ -1,7 +1,7 @@ { "id": "juce_audio_utils", "name": "JUCE extra audio utility classes", - "version": "2.0.14", + "version": "2.0.15", "description": "Classes for audio-related GUI and miscellaneous tasks.", "website": "http://www.juce.com/juce", "license": "GPL/Commercial", diff --git a/modules/juce_browser_plugin/juce_module_info b/modules/juce_browser_plugin/juce_module_info index 18dddd8cc5..98423c16a8 100644 --- a/modules/juce_browser_plugin/juce_module_info +++ b/modules/juce_browser_plugin/juce_module_info @@ -1,7 +1,7 @@ { "id": "juce_browser_plugin_client", "name": "JUCE browser plugin wrapper classes", - "version": "2.0.14", + "version": "2.0.15", "description": "Classes for building NPAPI and ActiveX browser plugins.", "website": "http://www.juce.com/juce", "license": "GPL/Commercial", diff --git a/modules/juce_core/juce_module_info b/modules/juce_core/juce_module_info index a622eabde1..3186f24b58 100644 --- a/modules/juce_core/juce_module_info +++ b/modules/juce_core/juce_module_info @@ -1,7 +1,7 @@ { "id": "juce_core", "name": "JUCE core classes", - "version": "2.0.14", + "version": "2.0.15", "description": "The essential set of basic JUCE classes, as required by all the other JUCE modules. Includes text, container, memory, threading and i/o functionality.", "website": "http://www.juce.com/juce", "license": "GPL/Commercial", diff --git a/modules/juce_core/system/juce_StandardHeader.h b/modules/juce_core/system/juce_StandardHeader.h index 83495fe20b..a53fb2adc7 100644 --- a/modules/juce_core/system/juce_StandardHeader.h +++ b/modules/juce_core/system/juce_StandardHeader.h @@ -33,7 +33,7 @@ */ #define JUCE_MAJOR_VERSION 2 #define JUCE_MINOR_VERSION 0 -#define JUCE_BUILDNUMBER 14 +#define JUCE_BUILDNUMBER 15 /** Current Juce version number. diff --git a/modules/juce_cryptography/juce_module_info b/modules/juce_cryptography/juce_module_info index e10fa272a3..703f2d2225 100644 --- a/modules/juce_cryptography/juce_module_info +++ b/modules/juce_cryptography/juce_module_info @@ -1,7 +1,7 @@ { "id": "juce_cryptography", "name": "JUCE cryptography classes", - "version": "2.0.14", + "version": "2.0.15", "description": "Classes for various basic cryptography functions, including RSA, Blowfish, MD5, SHA, etc.", "website": "http://www.juce.com/juce", "license": "GPL/Commercial", diff --git a/modules/juce_data_structures/juce_module_info b/modules/juce_data_structures/juce_module_info index 5203465a81..e2ffc28242 100644 --- a/modules/juce_data_structures/juce_module_info +++ b/modules/juce_data_structures/juce_module_info @@ -1,7 +1,7 @@ { "id": "juce_data_structures", "name": "JUCE data model helper classes", - "version": "2.0.14", + "version": "2.0.15", "description": "Classes for undo/redo management, and smart data structures.", "website": "http://www.juce.com/juce", "license": "GPL/Commercial", diff --git a/modules/juce_events/juce_module_info b/modules/juce_events/juce_module_info index 73efff5b5d..f2faaf404d 100644 --- a/modules/juce_events/juce_module_info +++ b/modules/juce_events/juce_module_info @@ -1,7 +1,7 @@ { "id": "juce_events", "name": "JUCE message and event handling classes", - "version": "2.0.14", + "version": "2.0.15", "description": "Classes for running an application's main event loop and sending/receiving messages, timers, etc.", "website": "http://www.juce.com/juce", "license": "GPL/Commercial", diff --git a/modules/juce_graphics/juce_module_info b/modules/juce_graphics/juce_module_info index b244f7558c..a9714317cc 100644 --- a/modules/juce_graphics/juce_module_info +++ b/modules/juce_graphics/juce_module_info @@ -1,7 +1,7 @@ { "id": "juce_graphics", "name": "JUCE graphics classes", - "version": "2.0.14", + "version": "2.0.15", "description": "Classes for 2D vector graphics, image loading/saving, font handling, etc.", "website": "http://www.juce.com/juce", "license": "GPL/Commercial", diff --git a/modules/juce_gui_basics/juce_module_info b/modules/juce_gui_basics/juce_module_info index 3a06f703ab..e50836b9c3 100644 --- a/modules/juce_gui_basics/juce_module_info +++ b/modules/juce_gui_basics/juce_module_info @@ -1,7 +1,7 @@ { "id": "juce_gui_basics", "name": "JUCE GUI core classes", - "version": "2.0.14", + "version": "2.0.15", "description": "Basic user-interface components and related classes.", "website": "http://www.juce.com/juce", "license": "GPL/Commercial", diff --git a/modules/juce_gui_extra/juce_module_info b/modules/juce_gui_extra/juce_module_info index e80d138c56..9a1e268c5d 100644 --- a/modules/juce_gui_extra/juce_module_info +++ b/modules/juce_gui_extra/juce_module_info @@ -1,7 +1,7 @@ { "id": "juce_gui_extra", "name": "JUCE extended GUI classes", - "version": "2.0.14", + "version": "2.0.15", "description": "Miscellaneous GUI classes for specialised tasks.", "website": "http://www.juce.com/juce", "license": "GPL/Commercial", diff --git a/modules/juce_opengl/juce_module_info b/modules/juce_opengl/juce_module_info index a24f6c0f70..952f5f8823 100644 --- a/modules/juce_opengl/juce_module_info +++ b/modules/juce_opengl/juce_module_info @@ -1,7 +1,7 @@ { "id": "juce_opengl", "name": "JUCE OpenGL classes", - "version": "2.0.14", + "version": "2.0.15", "description": "Classes for rendering OpenGL in a JUCE window.", "website": "http://www.juce.com/juce", "license": "GPL/Commercial", diff --git a/modules/juce_opengl/juce_opengl.cpp b/modules/juce_opengl/juce_opengl.cpp index ba01ab3b00..090d551efa 100644 --- a/modules/juce_opengl/juce_opengl.cpp +++ b/modules/juce_opengl/juce_opengl.cpp @@ -122,8 +122,22 @@ #endif BEGIN_JUCE_NAMESPACE + +//============================================================================== +#include "native/juce_MissingGLDefinitions.h" #include "native/juce_OpenGLExtensions.h" +void OpenGLExtensionFunctions::initialise() +{ + #if JUCE_WINDOWS || JUCE_LINUX + #define JUCE_INIT_GL_FUNCTION(name, returnType, params, callparams) name = (type_ ## name) OpenGLHelpers::getExtensionFunction (#name); + JUCE_GL_EXTENSION_FUNCTIONS (JUCE_INIT_GL_FUNCTION) + #undef JUCE_INIT_GL_FUNCTION + #endif +} + +#undef JUCE_GL_EXTENSION_FUNCTIONS + //============================================================================== // START_AUTOINCLUDE opengl/*.cpp #include "opengl/juce_OpenGLComponent.cpp" diff --git a/modules/juce_opengl/native/juce_MissingGLDefinitions.h b/modules/juce_opengl/native/juce_MissingGLDefinitions.h new file mode 100644 index 0000000000..98c8e42384 --- /dev/null +++ b/modules/juce_opengl/native/juce_MissingGLDefinitions.h @@ -0,0 +1,122 @@ +/* + ============================================================================== + + 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. + + ============================================================================== +*/ + +#if JUCE_WINDOWS + #define JUCE_DECLARE_GL_EXTENSION_FUNCTION(name, returnType, params, callparams) \ + typedef returnType (__stdcall *type_ ## name) params; static type_ ## name name = nullptr; +#else + #define JUCE_DECLARE_GL_EXTENSION_FUNCTION(name, returnType, params, callparams) \ + typedef returnType (*type_ ## name) params; static type_ ## name name = nullptr; +#endif + +namespace +{ + #ifndef GL_BGRA_EXT + enum { GL_BGRA_EXT = 0x80e1 }; + #endif + + #ifndef GL_CLAMP_TO_EDGE + enum { GL_CLAMP_TO_EDGE = 0x812f }; + #endif + + #ifndef GL_NUM_EXTENSIONS + enum { GL_NUM_EXTENSIONS = 0x821d }; + #endif + + #ifndef GL_RGBA8 + #define GL_RGBA8 GL_RGBA + #endif + + #ifndef GL_DEPTH24_STENCIL8 + #define GL_DEPTH24_STENCIL8 GL_DEPTH24_STENCIL8_OES + #endif + + #if JUCE_WINDOWS + enum + { + WGL_NUMBER_PIXEL_FORMATS_ARB = 0x2000, + WGL_DRAW_TO_WINDOW_ARB = 0x2001, + WGL_ACCELERATION_ARB = 0x2003, + WGL_SWAP_METHOD_ARB = 0x2007, + WGL_SUPPORT_OPENGL_ARB = 0x2010, + WGL_PIXEL_TYPE_ARB = 0x2013, + WGL_DOUBLE_BUFFER_ARB = 0x2011, + WGL_COLOR_BITS_ARB = 0x2014, + WGL_RED_BITS_ARB = 0x2015, + WGL_GREEN_BITS_ARB = 0x2017, + WGL_BLUE_BITS_ARB = 0x2019, + WGL_ALPHA_BITS_ARB = 0x201B, + WGL_DEPTH_BITS_ARB = 0x2022, + WGL_STENCIL_BITS_ARB = 0x2023, + WGL_FULL_ACCELERATION_ARB = 0x2027, + WGL_ACCUM_RED_BITS_ARB = 0x201E, + WGL_ACCUM_GREEN_BITS_ARB = 0x201F, + WGL_ACCUM_BLUE_BITS_ARB = 0x2020, + WGL_ACCUM_ALPHA_BITS_ARB = 0x2021, + WGL_STEREO_ARB = 0x2012, + WGL_SAMPLE_BUFFERS_ARB = 0x2041, + WGL_SAMPLES_ARB = 0x2042, + WGL_TYPE_RGBA_ARB = 0x202B, + + GL_OPERAND0_RGB = 0x8590, + GL_OPERAND1_RGB = 0x8591, + GL_OPERAND0_ALPHA = 0x8598, + GL_OPERAND1_ALPHA = 0x8599, + GL_SRC0_RGB = 0x8580, + GL_SRC1_RGB = 0x8581, + GL_SRC0_ALPHA = 0x8588, + GL_SRC1_ALPHA = 0x8589, + GL_TEXTURE0 = 0x84C0, + GL_TEXTURE1 = 0x84C1, + GL_TEXTURE2 = 0x84C2, + GL_COMBINE = 0x8570, + GL_COMBINE_RGB = 0x8571, + GL_COMBINE_ALPHA = 0x8572, + GL_PREVIOUS = 0x8578, + GL_COMPILE_STATUS = 0x8B81, + GL_LINK_STATUS = 0x8B82, + GL_SHADING_LANGUAGE_VERSION = 0x8B8C, + GL_FRAGMENT_SHADER = 0x8B30, + GL_VERTEX_SHADER = 0x8B31, + GL_FRAMEBUFFER = 0x8D40, + GL_RENDERBUFFER = 0x8D41, + GL_FRAMEBUFFER_BINDING = 0x8CA6, + GL_COLOR_ATTACHMENT0 = 0x8CE0, + GL_DEPTH_ATTACHMENT = 0x8D00, + GL_STENCIL_ATTACHMENT = 0x8D20, + GL_FRAMEBUFFER_COMPLETE = 0x8CD5, + GL_DEPTH24_STENCIL8 = 0x88F0, + GL_RENDERBUFFER_DEPTH_SIZE = 0x8D54, + GL_ARRAY_BUFFER = 0x8892, + GL_ELEMENT_ARRAY_BUFFER = 0x8893, + GL_STATIC_DRAW = 0x88E4, + GL_DYNAMIC_DRAW = 0x88E8 + }; + + typedef char GLchar; + typedef pointer_sized_int GLsizeiptr; + typedef pointer_sized_int GLintptr; + #endif +} diff --git a/modules/juce_opengl/native/juce_OpenGLExtensions.h b/modules/juce_opengl/native/juce_OpenGLExtensions.h index 3245081079..c0ddc54b47 100644 --- a/modules/juce_opengl/native/juce_OpenGLExtensions.h +++ b/modules/juce_opengl/native/juce_OpenGLExtensions.h @@ -23,180 +23,88 @@ ============================================================================== */ -namespace -{ - -#if JUCE_WINDOWS - #define JUCE_DECLARE_GL_EXTENSION_FUNCTION(name, returnType, params) \ - typedef returnType (__stdcall *type_ ## name) params; static type_ ## name name = nullptr; -#else - #define JUCE_DECLARE_GL_EXTENSION_FUNCTION(name, returnType, params) \ - typedef returnType (*type_ ## name) params; static type_ ## name name = nullptr; -#endif - -#ifndef GL_BGRA_EXT - enum { GL_BGRA_EXT = 0x80e1 }; -#endif - -#ifndef GL_CLAMP_TO_EDGE - enum { GL_CLAMP_TO_EDGE = 0x812f }; -#endif +#ifndef __JUCE_OPENGLEXTENSIONS_JUCEHEADER__ +#define __JUCE_OPENGLEXTENSIONS_JUCEHEADER__ -#ifndef GL_RGBA8 - #define GL_RGBA8 GL_RGBA -#endif -#ifndef GL_DEPTH24_STENCIL8 - #define GL_DEPTH24_STENCIL8 GL_DEPTH24_STENCIL8_OES -#endif - -#if JUCE_WINDOWS - -enum +/** @internal This macro contains a list of GL extension functions that need to be dynamically loaded on Windows/Linux. + @see OpenGLExtensionFunctions +*/ +#define JUCE_GL_EXTENSION_FUNCTIONS(USE_FUNCTION) \ + USE_FUNCTION (glActiveTexture, void, (GLenum p1), (p1))\ + USE_FUNCTION (glClientActiveTexture, void, (GLenum p1), (p1))\ + USE_FUNCTION (glCreateProgram, GLuint, (), ())\ + USE_FUNCTION (glDeleteProgram, void, (GLuint p1), (p1))\ + USE_FUNCTION (glCreateShader, GLuint, (GLenum p1), (p1))\ + USE_FUNCTION (glDeleteShader, void, (GLuint p1), (p1))\ + USE_FUNCTION (glShaderSource, void, (GLuint p1, GLsizei p2, const GLchar** p3, const GLint* p4), (p1, p2, p3, p4))\ + USE_FUNCTION (glCompileShader, void, (GLuint p1), (p1))\ + USE_FUNCTION (glAttachShader, void, (GLuint p1, GLuint p2), (p1, p2))\ + USE_FUNCTION (glLinkProgram, void, (GLuint p1), (p1))\ + USE_FUNCTION (glUseProgram, void, (GLuint p1), (p1))\ + USE_FUNCTION (glGetShaderiv, void, (GLuint p1, GLenum p2, GLint* p3), (p1, p2, p3))\ + USE_FUNCTION (glGetShaderInfoLog, void, (GLuint p1, GLsizei p2, GLsizei* p3, GLchar* p4), (p1, p2, p3, p4))\ + USE_FUNCTION (glGetProgramiv, void, (GLuint p1, GLenum p2, GLint* p3), (p1, p2, p3))\ + USE_FUNCTION (glGetUniformLocation, GLint, (GLuint p1, const GLchar* p2), (p1, p2))\ + USE_FUNCTION (glGetAttribLocation, GLint, (GLuint p1, const GLchar* p2), (p1, p2))\ + USE_FUNCTION (glVertexAttribPointer, void, (GLuint p1, GLint p2, GLenum p3, GLboolean p4, GLsizei p5, const GLvoid* p6), (p1, p2, p3, p4, p5, p6))\ + USE_FUNCTION (glEnableVertexAttribArray, void, (GLuint p1), (p1))\ + USE_FUNCTION (glBindBuffer, void, (GLenum p1, GLuint p2), (p1, p2))\ + USE_FUNCTION (glDeleteBuffers, void, (GLsizei p1, const GLuint* p2), (p1, p2))\ + USE_FUNCTION (glGenBuffers, void, (GLsizei p1, GLuint* p2), (p1, p2))\ + USE_FUNCTION (glBufferData, void, (GLenum p1, GLsizeiptr p2, const GLvoid* p3, GLenum p4), (p1, p2, p3, p4))\ + USE_FUNCTION (glBufferSubData, void, (GLenum p1, GLintptr p2, GLsizeiptr p3, const GLvoid* p4), (p1, p2, p3, p4))\ + USE_FUNCTION (glUniform1f, void, (GLint p1, GLfloat p2), (p1, p2))\ + USE_FUNCTION (glUniform1i, void, (GLint p1, GLint p2), (p1, p2))\ + USE_FUNCTION (glUniform2f, void, (GLint p1, GLfloat p2, GLfloat p3), (p1, p2, p3))\ + USE_FUNCTION (glUniform3f, void, (GLint p1, GLfloat p2, GLfloat p3, GLfloat p4), (p1, p2, p3, p4))\ + USE_FUNCTION (glUniform4f, void, (GLint p1, GLfloat p2, GLfloat p3, GLfloat p4, GLfloat p5), (p1, p2, p3, p4, p5))\ + USE_FUNCTION (glUniform4i, void, (GLint p1, GLint p2, GLint p3, GLint p4, GLint p5), (p1, p2, p3, p4, p5))\ + USE_FUNCTION (glUniform1fv, void, (GLint p1, GLsizei p2, const GLfloat* p3), (p1, p2, p3))\ + USE_FUNCTION (glIsRenderbuffer, GLboolean, (GLuint p1), (p1))\ + USE_FUNCTION (glBindRenderbuffer, void, (GLenum p1, GLuint p2), (p1, p2))\ + USE_FUNCTION (glDeleteRenderbuffers, void, (GLsizei p1, const GLuint* p2), (p1, p2))\ + USE_FUNCTION (glGenRenderbuffers, void, (GLsizei p1, GLuint* p2), (p1, p2))\ + USE_FUNCTION (glRenderbufferStorage, void, (GLenum p1, GLenum p2, GLsizei p3, GLsizei p4), (p1, p2, p3, p4))\ + USE_FUNCTION (glGetRenderbufferParameteriv, void, (GLenum p1, GLenum p2, GLint* p3), (p1, p2, p3))\ + USE_FUNCTION (glIsFramebuffer, GLboolean, (GLuint p1), (p1))\ + USE_FUNCTION (glBindFramebuffer, void, (GLenum p1, GLuint p2), (p1, p2))\ + USE_FUNCTION (glDeleteFramebuffers, void, (GLsizei p1, const GLuint* p2), (p1, p2))\ + USE_FUNCTION (glGenFramebuffers, void, (GLsizei p1, GLuint* p2), (p1, p2))\ + USE_FUNCTION (glCheckFramebufferStatus, GLenum, (GLenum p1), (p1))\ + USE_FUNCTION (glFramebufferTexture1D, void, (GLenum p1, GLenum p2, GLenum p3, GLuint p4, GLint p5), (p1, p2, p3, p4, p5))\ + USE_FUNCTION (glFramebufferTexture2D, void, (GLenum p1, GLenum p2, GLenum p3, GLuint p4, GLint p5), (p1, p2, p3, p4, p5))\ + USE_FUNCTION (glFramebufferTexture3D, void, (GLenum p1, GLenum p2, GLenum p3, GLuint p4, GLint p5, GLint p6), (p1, p2, p3, p4, p5, p6))\ + USE_FUNCTION (glFramebufferRenderbuffer, void, (GLenum p1, GLenum p2, GLenum p3, GLuint p4), (p1, p2, p3, p4))\ + USE_FUNCTION (glGetFramebufferAttachmentParameteriv, void, (GLenum p1, GLenum p2, GLenum p3, GLint* p4), (p1, p2, p3, p4)) + +/** This class contains a generated list of OpenGL extension functions, which are either dynamically loaded + for a specific GL context, or simply call-through to the appropriate OS function where available. +*/ +struct OpenGLExtensionFunctions { - WGL_NUMBER_PIXEL_FORMATS_ARB = 0x2000, - WGL_DRAW_TO_WINDOW_ARB = 0x2001, - WGL_ACCELERATION_ARB = 0x2003, - WGL_SWAP_METHOD_ARB = 0x2007, - WGL_SUPPORT_OPENGL_ARB = 0x2010, - WGL_PIXEL_TYPE_ARB = 0x2013, - WGL_DOUBLE_BUFFER_ARB = 0x2011, - WGL_COLOR_BITS_ARB = 0x2014, - WGL_RED_BITS_ARB = 0x2015, - WGL_GREEN_BITS_ARB = 0x2017, - WGL_BLUE_BITS_ARB = 0x2019, - WGL_ALPHA_BITS_ARB = 0x201B, - WGL_DEPTH_BITS_ARB = 0x2022, - WGL_STENCIL_BITS_ARB = 0x2023, - WGL_FULL_ACCELERATION_ARB = 0x2027, - WGL_ACCUM_RED_BITS_ARB = 0x201E, - WGL_ACCUM_GREEN_BITS_ARB = 0x201F, - WGL_ACCUM_BLUE_BITS_ARB = 0x2020, - WGL_ACCUM_ALPHA_BITS_ARB = 0x2021, - WGL_STEREO_ARB = 0x2012, - WGL_SAMPLE_BUFFERS_ARB = 0x2041, - WGL_SAMPLES_ARB = 0x2042, - WGL_TYPE_RGBA_ARB = 0x202B, - - GL_OPERAND0_RGB = 0x8590, - GL_OPERAND1_RGB = 0x8591, - GL_OPERAND0_ALPHA = 0x8598, - GL_OPERAND1_ALPHA = 0x8599, - GL_SRC0_RGB = 0x8580, - GL_SRC1_RGB = 0x8581, - GL_SRC0_ALPHA = 0x8588, - GL_SRC1_ALPHA = 0x8589, - GL_TEXTURE0 = 0x84C0, - GL_TEXTURE1 = 0x84C1, - GL_TEXTURE2 = 0x84C2, - GL_COMBINE = 0x8570, - GL_COMBINE_RGB = 0x8571, - GL_COMBINE_ALPHA = 0x8572, - GL_PREVIOUS = 0x8578, - GL_COMPILE_STATUS = 0x8B81, - GL_LINK_STATUS = 0x8B82, - GL_SHADING_LANGUAGE_VERSION = 0x8B8C, - GL_FRAGMENT_SHADER = 0x8B30, - GL_VERTEX_SHADER = 0x8B31, - GL_FRAMEBUFFER = 0x8D40, - GL_RENDERBUFFER = 0x8D41, - GL_FRAMEBUFFER_BINDING = 0x8CA6, - GL_COLOR_ATTACHMENT0 = 0x8CE0, - GL_DEPTH_ATTACHMENT = 0x8D00, - GL_STENCIL_ATTACHMENT = 0x8D20, - GL_FRAMEBUFFER_COMPLETE = 0x8CD5, - GL_DEPTH24_STENCIL8 = 0x88F0, - GL_RENDERBUFFER_DEPTH_SIZE = 0x8D54, - GL_ARRAY_BUFFER = 0x8892, - GL_ELEMENT_ARRAY_BUFFER = 0x8893, - GL_STATIC_DRAW = 0x88E4, - GL_DYNAMIC_DRAW = 0x88E8 + void initialise(); + + #if JUCE_WINDOWS && ! DOXYGEN + typedef char GLchar; + typedef pointer_sized_int GLsizeiptr; + typedef pointer_sized_int GLintptr; + #endif + + #if JUCE_WINDOWS || JUCE_LINUX + #if JUCE_WINDOWS + #define JUCE_GL_STDCALL __stdcall + #else + #define JUCE_GL_STDCALL + #endif + + #define JUCE_DECLARE_GL_FUNCTION(name, returnType, params, callparams) typedef returnType (JUCE_GL_STDCALL *type_ ## name) params; type_ ## name name; + #else + #define JUCE_DECLARE_GL_FUNCTION(name, returnType, params, callparams) inline static returnType name params { return ::name callparams; } + #endif + + JUCE_GL_EXTENSION_FUNCTIONS (JUCE_DECLARE_GL_FUNCTION) + #undef JUCE_DECLARE_GL_FUNCTION }; -typedef char GLchar; -typedef pointer_sized_int GLsizeiptr; -typedef pointer_sized_int GLintptr; - -#define WGL_FUNCTION_LIST(USE_FUNCTION) \ - USE_FUNCTION (wglChoosePixelFormatARB, BOOL, (HDC, const int*, const FLOAT*, UINT, int*, UINT*))\ - USE_FUNCTION (wglSwapIntervalEXT, BOOL, (int))\ - USE_FUNCTION (wglGetSwapIntervalEXT, int, ())\ - -WGL_FUNCTION_LIST (JUCE_DECLARE_GL_EXTENSION_FUNCTION) -#endif - -#if JUCE_WINDOWS || JUCE_LINUX - -#define GL_EXTENSIONS_LIST(USE_FUNCTION) \ - USE_FUNCTION (glActiveTexture, void, (GLenum))\ - USE_FUNCTION (glClientActiveTexture, void, (GLenum))\ - USE_FUNCTION (glCreateProgram, GLuint, ())\ - USE_FUNCTION (glDeleteProgram, void, (GLuint))\ - USE_FUNCTION (glCreateShader, GLuint, (GLenum))\ - USE_FUNCTION (glDeleteShader, void, (GLuint))\ - USE_FUNCTION (glShaderSource, void, (GLuint, GLsizei, const GLchar**, const GLint*))\ - USE_FUNCTION (glCompileShader, void, (GLuint))\ - USE_FUNCTION (glAttachShader, void, (GLuint, GLuint))\ - USE_FUNCTION (glLinkProgram, void, (GLuint))\ - USE_FUNCTION (glUseProgram, void, (GLuint))\ - USE_FUNCTION (glGetShaderiv, void, (GLuint, GLenum, GLint*))\ - USE_FUNCTION (glGetShaderInfoLog, void, (GLuint, GLsizei, GLsizei*, GLchar*))\ - USE_FUNCTION (glGetProgramiv, void, (GLuint, GLenum, GLint*))\ - USE_FUNCTION (glGetUniformLocation, GLint, (GLuint, const GLchar*))\ - USE_FUNCTION (glGetAttribLocation, GLint, (GLuint, const GLchar*))\ - USE_FUNCTION (glVertexAttribPointer, void, (GLuint, GLint, GLenum, GLboolean, GLsizei, const GLvoid*))\ - USE_FUNCTION (glEnableVertexAttribArray, void, (GLuint))\ - USE_FUNCTION (glBindBuffer, void, (GLenum, GLuint))\ - USE_FUNCTION (glDeleteBuffers, void, (GLsizei, const GLuint*))\ - USE_FUNCTION (glGenBuffers, void, (GLsizei, GLuint*))\ - USE_FUNCTION (glBufferData, void, (GLenum, GLsizeiptr, const GLvoid*, GLenum))\ - USE_FUNCTION (glBufferSubData, void, (GLenum, GLintptr, GLsizeiptr, const GLvoid*))\ - USE_FUNCTION (glUniform1f, void, (GLint, GLfloat))\ - USE_FUNCTION (glUniform1i, void, (GLint, GLint))\ - USE_FUNCTION (glUniform2f, void, (GLint, GLfloat, GLfloat))\ - USE_FUNCTION (glUniform3f, void, (GLint, GLfloat, GLfloat, GLfloat))\ - USE_FUNCTION (glUniform4f, void, (GLint, GLfloat, GLfloat, GLfloat, GLfloat))\ - USE_FUNCTION (glUniform4i, void, (GLint, GLint, GLint, GLint, GLint))\ - USE_FUNCTION (glUniform1fv, void, (GLint, GLsizei, const GLfloat*))\ - USE_FUNCTION (glIsRenderbuffer, GLboolean, (GLuint))\ - USE_FUNCTION (glBindRenderbuffer, void, (GLenum, GLuint))\ - USE_FUNCTION (glDeleteRenderbuffers, void, (GLsizei, const GLuint*))\ - USE_FUNCTION (glGenRenderbuffers, void, (GLsizei, GLuint*))\ - USE_FUNCTION (glRenderbufferStorage, void, (GLenum, GLenum, GLsizei, GLsizei))\ - USE_FUNCTION (glGetRenderbufferParameteriv, void, (GLenum, GLenum, GLint*))\ - USE_FUNCTION (glIsFramebuffer, GLboolean, (GLuint))\ - USE_FUNCTION (glBindFramebuffer, void, (GLenum, GLuint))\ - USE_FUNCTION (glDeleteFramebuffers, void, (GLsizei, const GLuint*))\ - USE_FUNCTION (glGenFramebuffers, void, (GLsizei, GLuint*))\ - USE_FUNCTION (glCheckFramebufferStatus, GLenum, (GLenum))\ - USE_FUNCTION (glFramebufferTexture1D, void, (GLenum, GLenum, GLenum, GLuint, GLint))\ - USE_FUNCTION (glFramebufferTexture2D, void, (GLenum, GLenum, GLenum, GLuint, GLint))\ - USE_FUNCTION (glFramebufferTexture3D, void, (GLenum, GLenum, GLenum, GLuint, GLint, GLint))\ - USE_FUNCTION (glFramebufferRenderbuffer, void, (GLenum, GLenum, GLenum, GLuint))\ - USE_FUNCTION (glGetFramebufferAttachmentParameteriv, void, (GLenum, GLenum, GLenum, GLint*))\ - -GL_EXTENSIONS_LIST (JUCE_DECLARE_GL_EXTENSION_FUNCTION) - -void initialiseGLExtensions() -{ - if (glActiveTexture == nullptr) - { - #define FIND_FUNCTION(name, returnType, params) name = (type_ ## name) OpenGLHelpers::getExtensionFunction (#name); - - #if JUCE_WINDOWS - WGL_FUNCTION_LIST (FIND_FUNCTION) - #endif - GL_EXTENSIONS_LIST (FIND_FUNCTION) - - #undef FIND_FUNCTION - } -} - -#undef GL_EXTENSIONS_LIST -#undef WGL_FUNCTION_LIST - -#else -void initialiseGLExtensions() {} -#endif - -} +#endif // __JUCE_OPENGLEXTENSIONS_JUCEHEADER__ diff --git a/modules/juce_opengl/native/juce_linux_OpenGLComponent.cpp b/modules/juce_opengl/native/juce_linux_OpenGLComponent.cpp index ee369bd472..958193f186 100644 --- a/modules/juce_opengl/native/juce_linux_OpenGLComponent.cpp +++ b/modules/juce_opengl/native/juce_linux_OpenGLComponent.cpp @@ -37,7 +37,7 @@ public: embeddedWindow (0), swapInterval (0) { - initialiseGLExtensions(); + extensions.initialise(); jassert (component != nullptr); ComponentPeer* const peer = component->getTopLevelComponent()->getPeer(); @@ -94,6 +94,10 @@ public: XFree (bestVisual); XSync (display, False); + + makeActive(); + extensions.initialise(); + makeInactive(); } ~WindowedGLContext() diff --git a/modules/juce_opengl/native/juce_mac_OpenGLComponent.mm b/modules/juce_opengl/native/juce_mac_OpenGLComponent.mm index 118199add4..52dd74e342 100644 --- a/modules/juce_opengl/native/juce_mac_OpenGLComponent.mm +++ b/modules/juce_opengl/native/juce_mac_OpenGLComponent.mm @@ -123,7 +123,7 @@ public: NSOpenGLContext* sharedContext) : renderContext (nil) { - initialiseGLExtensions(); + extensions.initialise(); NSOpenGLPixelFormatAttribute attribs[] = { diff --git a/modules/juce_opengl/native/juce_win32_OpenGLComponent.cpp b/modules/juce_opengl/native/juce_win32_OpenGLComponent.cpp index b7948de617..99ae21dc6c 100644 --- a/modules/juce_opengl/native/juce_win32_OpenGLComponent.cpp +++ b/modules/juce_opengl/native/juce_win32_OpenGLComponent.cpp @@ -38,7 +38,6 @@ public: { initialiseGLExtensions(); jassert (component != nullptr); - createNativeWindow(); PIXELFORMATDESCRIPTOR pfd; @@ -55,6 +54,7 @@ public: { makeActive(); initialiseGLExtensions(); + extensions.initialise(); setPixelFormat (pixelFormat); if (contextToShareWith != 0) @@ -230,6 +230,23 @@ private: Component* const component; HDC dc; + #define JUCE_DECLARE_WGL_EXTENSION_FUNCTION(name, returnType, params) \ + typedef returnType (__stdcall *type_ ## name) params; type_ ## name name; + + JUCE_DECLARE_WGL_EXTENSION_FUNCTION (wglChoosePixelFormatARB, BOOL, (HDC, const int*, const FLOAT*, UINT, int*, UINT*)) + JUCE_DECLARE_WGL_EXTENSION_FUNCTION (wglSwapIntervalEXT, BOOL, (int)) + JUCE_DECLARE_WGL_EXTENSION_FUNCTION (wglGetSwapIntervalEXT, int, ()) + #undef JUCE_DECLARE_WGL_EXTENSION_FUNCTION + + void initialiseGLExtensions() + { + #define JUCE_INIT_WGL_FUNCTION(name) name = (type_ ## name) OpenGLHelpers::getExtensionFunction (#name); + JUCE_INIT_WGL_FUNCTION (wglChoosePixelFormatARB); + JUCE_INIT_WGL_FUNCTION (wglSwapIntervalEXT); + JUCE_INIT_WGL_FUNCTION (wglGetSwapIntervalEXT); + #undef JUCE_INIT_WGL_FUNCTION + } + //============================================================================== void createNativeWindow() { diff --git a/modules/juce_opengl/opengl/juce_OpenGLComponent.cpp b/modules/juce_opengl/opengl/juce_OpenGLComponent.cpp index 974f56a87d..91a8be09ea 100644 --- a/modules/juce_opengl/opengl/juce_OpenGLComponent.cpp +++ b/modules/juce_opengl/opengl/juce_OpenGLComponent.cpp @@ -170,7 +170,9 @@ public: void releaseResources() { + owner.makeCurrentRenderingTarget(); frameBuffer.release(); + owner.releaseAsRenderingTarget(); } void timerCallback() @@ -200,7 +202,8 @@ public: || fbH > height + 128 || ! frameBuffer.isValid()) { - frameBuffer.initialise (width, height); + jassert (owner.getCurrentContext() != nullptr); + frameBuffer.initialise (*owner.getCurrentContext(), width, height); validArea.clear(); } @@ -331,7 +334,11 @@ OpenGLComponent::OpenGLComponent (const int flags_) OpenGLComponent::~OpenGLComponent() { - stopBackgroundThread(); + if (isUsingDedicatedThread()) + stopBackgroundThread(); + else + deleteContext(); + componentWatcher = nullptr; } @@ -416,12 +423,12 @@ void OpenGLComponent::deleteContext() { if (context->makeActive()) { + setCachedComponentImage (nullptr); releaseOpenGLContext(); context->makeInactive(); } context = nullptr; - setCachedComponentImage (nullptr); } needToDeleteContext = false; @@ -511,7 +518,9 @@ bool OpenGLComponent::performRender() if (! invalid.isEmpty()) { - OpenGLGraphicsContext g (frameBuffer); + jassert (getCurrentContext() != nullptr); + + OpenGLGraphicsContext g (*getCurrentContext(), frameBuffer); g.clipToRectangleList (invalid); g.setFill (Colours::transparentBlack); diff --git a/modules/juce_opengl/opengl/juce_OpenGLContext.h b/modules/juce_opengl/opengl/juce_OpenGLContext.h index 33da3e6d7b..e83089ac1b 100644 --- a/modules/juce_opengl/opengl/juce_OpenGLContext.h +++ b/modules/juce_opengl/opengl/juce_OpenGLContext.h @@ -27,6 +27,7 @@ #define __JUCE_OPENGLCONTEXT_JUCEHEADER__ #include "juce_OpenGLPixelFormat.h" +#include "../native/juce_OpenGLExtensions.h" //============================================================================== @@ -91,6 +92,9 @@ public: */ virtual unsigned int getFrameBufferID() const = 0; + /** Checks whether the current context supports the specified extension. */ + bool isExtensionSupported (const char* const extensionName); + //============================================================================== /** Returns the context that's currently in active use by the calling thread. @@ -101,6 +105,9 @@ public: /** This property set allows you to attach persisent values to the context. */ NamedValueSet properties; + /** This structure holds a set of dynamically loaded GL functions for use on this context. */ + OpenGLExtensionFunctions extensions; + protected: //============================================================================== OpenGLContext() noexcept; diff --git a/modules/juce_opengl/opengl/juce_OpenGLFrameBuffer.cpp b/modules/juce_opengl/opengl/juce_OpenGLFrameBuffer.cpp index 978019f31c..d869898e34 100644 --- a/modules/juce_opengl/opengl/juce_OpenGLFrameBuffer.cpp +++ b/modules/juce_opengl/opengl/juce_OpenGLFrameBuffer.cpp @@ -26,9 +26,10 @@ class OpenGLFrameBuffer::Pimpl { public: - Pimpl (const int width_, const int height_, + Pimpl (const OpenGLContext& context_, const int width_, const int height_, const bool wantsDepthBuffer, const bool wantsStencilBuffer) - : width (width_), + : context (context_), + width (width_), height (height_), textureID (0), frameBufferHandle (0), @@ -42,12 +43,12 @@ public: jassert (OpenGLHelpers::isContextActive()); #if JUCE_WINDOWS || JUCE_LINUX - if (glGenFramebuffers == nullptr) + if (context.extensions.glGenFramebuffers == nullptr) return; #endif - glGenFramebuffers (1, &frameBufferHandle); - glBindFramebuffer (GL_FRAMEBUFFER, frameBufferHandle); + context.extensions.glGenFramebuffers (1, &frameBufferHandle); + context.extensions.glBindFramebuffer (GL_FRAMEBUFFER, frameBufferHandle); glGenTextures (1, &textureID); glBindTexture (GL_TEXTURE_2D, textureID); @@ -59,15 +60,15 @@ public: glTexImage2D (GL_TEXTURE_2D, 0, GL_RGBA8, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0); - glFramebufferTexture2D (GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, textureID, 0); + context.extensions.glFramebufferTexture2D (GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, textureID, 0); if (wantsDepthBuffer || wantsStencilBuffer) { - glGenRenderbuffers (1, &depthOrStencilBuffer); - glBindRenderbuffer (GL_RENDERBUFFER, depthOrStencilBuffer); - jassert (glIsRenderbuffer (depthOrStencilBuffer)); + context.extensions.glGenRenderbuffers (1, &depthOrStencilBuffer); + context.extensions.glBindRenderbuffer (GL_RENDERBUFFER, depthOrStencilBuffer); + jassert (context.extensions.glIsRenderbuffer (depthOrStencilBuffer)); - glRenderbufferStorage (GL_RENDERBUFFER, + context.extensions.glRenderbufferStorage (GL_RENDERBUFFER, (wantsDepthBuffer && wantsStencilBuffer) ? GL_DEPTH24_STENCIL8 #if JUCE_OPENGL_ES : GL_DEPTH_COMPONENT16, @@ -77,17 +78,17 @@ public: width, height); GLint params = 0; - glGetRenderbufferParameteriv (GL_RENDERBUFFER, GL_RENDERBUFFER_DEPTH_SIZE, ¶ms); - glFramebufferRenderbuffer (GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, depthOrStencilBuffer); + context.extensions.glGetRenderbufferParameteriv (GL_RENDERBUFFER, GL_RENDERBUFFER_DEPTH_SIZE, ¶ms); + context.extensions.glFramebufferRenderbuffer (GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, depthOrStencilBuffer); if (wantsStencilBuffer) - glFramebufferRenderbuffer (GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, depthOrStencilBuffer); + context.extensions.glFramebufferRenderbuffer (GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, depthOrStencilBuffer); hasDepthBuffer = wantsDepthBuffer; hasStencilBuffer = wantsStencilBuffer; } - glBindFramebuffer (GL_FRAMEBUFFER, 0); + context.extensions.glBindFramebuffer (GL_FRAMEBUFFER, 0); } ~Pimpl() @@ -96,23 +97,24 @@ public: glDeleteTextures (1, &textureID); if (depthOrStencilBuffer != 0) - glDeleteRenderbuffers (1, &depthOrStencilBuffer); + context.extensions.glDeleteRenderbuffers (1, &depthOrStencilBuffer); if (frameBufferHandle != 0) - glDeleteFramebuffers (1, &frameBufferHandle); + context.extensions.glDeleteFramebuffers (1, &frameBufferHandle); } - void bind() { glBindFramebuffer (GL_FRAMEBUFFER, frameBufferHandle); } - void unbind() { glBindFramebuffer (GL_FRAMEBUFFER, 0); } + void bind() { context.extensions.glBindFramebuffer (GL_FRAMEBUFFER, frameBufferHandle); } + void unbind() { context.extensions.glBindFramebuffer (GL_FRAMEBUFFER, 0); } + const OpenGLContext& context; const int width, height; GLuint textureID, frameBufferHandle, depthOrStencilBuffer; bool hasDepthBuffer, hasStencilBuffer, ok; private: - static bool checkStatus() noexcept + bool checkStatus() noexcept { - const GLenum status = glCheckFramebufferStatus (GL_FRAMEBUFFER); + const GLenum status = context.extensions.glCheckFramebufferStatus (GL_FRAMEBUFFER); return status == GL_NO_ERROR || status == GL_FRAMEBUFFER_COMPLETE; @@ -132,9 +134,9 @@ public: buffer.readPixels (data, Rectangle (w, h)); } - bool restore (OpenGLFrameBuffer& buffer) + bool restore (const OpenGLContext& context, OpenGLFrameBuffer& buffer) { - if (buffer.initialise (width, height)) + if (buffer.initialise (context, width, height)) { buffer.writePixels (data, Rectangle (width, height)); return true; @@ -154,10 +156,12 @@ private: OpenGLFrameBuffer::OpenGLFrameBuffer() {} OpenGLFrameBuffer::~OpenGLFrameBuffer() {} -bool OpenGLFrameBuffer::initialise (int width, int height) +bool OpenGLFrameBuffer::initialise (const OpenGLContext& context, int width, int height) { + jassert (context.isActive()); // The context must be active when creating a framebuffer! + pimpl = nullptr; - pimpl = new Pimpl (width, height, false, false); + pimpl = new Pimpl (context, width, height, false, false); if (! pimpl->ok) pimpl = nullptr; @@ -165,14 +169,14 @@ bool OpenGLFrameBuffer::initialise (int width, int height) return pimpl != nullptr; } -bool OpenGLFrameBuffer::initialise (const Image& image) +bool OpenGLFrameBuffer::initialise (const OpenGLContext& context, const Image& image) { if (! image.isARGB()) - return initialise (image.convertedToFormat (Image::ARGB)); + return initialise (context, image.convertedToFormat (Image::ARGB)); Image::BitmapData bitmap (image, Image::BitmapData::readOnly); - return initialise (bitmap.width, bitmap.height) + return initialise (context, bitmap.width, bitmap.height) && writePixels ((const PixelARGB*) bitmap.data, image.getBounds()); } @@ -186,7 +190,7 @@ bool OpenGLFrameBuffer::initialise (const OpenGLFrameBuffer& other) return true; } - if (initialise (p->width, p->height)) + if (initialise (p->context, p->width, p->height)) { pimpl->bind(); OpenGLHelpers::prepareFor2D (p->width, p->height); @@ -216,13 +220,13 @@ void OpenGLFrameBuffer::saveAndRelease() } } -bool OpenGLFrameBuffer::reloadSavedCopy() +bool OpenGLFrameBuffer::reloadSavedCopy (const OpenGLContext& context) { if (savedState != nullptr) { ScopedPointer state (savedState); - if (state->restore (*this)) + if (state->restore (context, *this)) return true; savedState = state; @@ -248,11 +252,6 @@ bool OpenGLFrameBuffer::makeCurrentRenderingTarget() return true; } -void OpenGLFrameBuffer::setCurrentFrameBufferTarget (GLuint frameBufferID) -{ - glBindFramebuffer (GL_FRAMEBUFFER, frameBufferID); -} - GLuint OpenGLFrameBuffer::getCurrentFrameBufferTarget() { GLint fb; @@ -262,7 +261,8 @@ GLuint OpenGLFrameBuffer::getCurrentFrameBufferTarget() void OpenGLFrameBuffer::releaseAsRenderingTarget() { - setCurrentFrameBufferTarget (0); + if (pimpl != nullptr) + pimpl->context.extensions.glBindFramebuffer (GL_FRAMEBUFFER, 0); } void OpenGLFrameBuffer::clear (const Colour& colour) @@ -290,7 +290,7 @@ bool OpenGLFrameBuffer::readPixels (PixelARGB* target, const Rectangle& are glPixelStorei (GL_PACK_ALIGNMENT, 4); glReadPixels (area.getX(), area.getY(), area.getWidth(), area.getHeight(), GL_BGRA_EXT, GL_UNSIGNED_BYTE, target); - glBindFramebuffer (GL_FRAMEBUFFER, 0); + pimpl->context.extensions.glBindFramebuffer (GL_FRAMEBUFFER, 0); glPixelStorei (GL_PACK_ALIGNMENT, 0); return true; } @@ -335,7 +335,7 @@ bool OpenGLFrameBuffer::writePixels (const PixelARGB* data, const Rectangle OpenGLHelpers::drawTriangleStrip (vertices, textureCoords, 4, tex.getTextureID()); #endif - glBindFramebuffer (GL_FRAMEBUFFER, 0); + pimpl->context.extensions.glBindFramebuffer (GL_FRAMEBUFFER, 0); return true; } diff --git a/modules/juce_opengl/opengl/juce_OpenGLFrameBuffer.h b/modules/juce_opengl/opengl/juce_OpenGLFrameBuffer.h index 0fb6030c92..8a9519bbbb 100644 --- a/modules/juce_opengl/opengl/juce_OpenGLFrameBuffer.h +++ b/modules/juce_opengl/opengl/juce_OpenGLFrameBuffer.h @@ -47,13 +47,13 @@ public: Note that a valid openGL context must be selected when you call this method, or it will fail. */ - bool initialise (int width, int height); + bool initialise (const OpenGLContext& context, int width, int height); /** Tries to allocates a buffer containing a copy of a given image. Note that a valid openGL context must be selected when you call this method, or it will fail. */ - bool initialise (const Image& content); + bool initialise (const OpenGLContext& context, const Image& content); /** Tries to allocate a copy of another framebuffer. */ @@ -73,7 +73,7 @@ public: /** Restores the framebuffer content that was previously saved using saveAndRelease(). After saving to main memory, the original state can be restored by calling restoreToGPUMemory(). */ - bool reloadSavedCopy(); + bool reloadSavedCopy (const OpenGLContext& context); //============================================================================== /** Returns true if a valid buffer has been allocated. */ @@ -98,12 +98,7 @@ public: /** Deselects this buffer as the current OpenGL rendering target. */ void releaseAsRenderingTarget(); - /** Selects a framebuffer as the active target, or deselects the current - target buffer if you pass 0. - */ - static void setCurrentFrameBufferTarget (GLuint frameBufferID); - - /** Returns the ID of the currently-bound framebuffer. */ + /** Returns the current frame buffer ID for the current context. */ static GLuint getCurrentFrameBufferTarget(); /** Clears the framebuffer with the specified colour. */ diff --git a/modules/juce_opengl/opengl/juce_OpenGLGraphicsContext.cpp b/modules/juce_opengl/opengl/juce_OpenGLGraphicsContext.cpp index 16852501ae..a002069859 100644 --- a/modules/juce_opengl/opengl/juce_OpenGLGraphicsContext.cpp +++ b/modules/juce_opengl/opengl/juce_OpenGLGraphicsContext.cpp @@ -26,26 +26,34 @@ //============================================================================== struct OpenGLTarget { - OpenGLTarget (GLuint frameBufferID_, int width, int height) noexcept - : frameBuffer (nullptr), frameBufferID (frameBufferID_), bounds (width, height) + OpenGLTarget (OpenGLContext& context_, GLuint frameBufferID_, int width, int height) noexcept + : context (context_), frameBuffer (nullptr), frameBufferID (frameBufferID_), bounds (width, height) {} - OpenGLTarget (OpenGLFrameBuffer& frameBuffer_, const Point& origin) noexcept - : frameBuffer (&frameBuffer_), frameBufferID (0), + OpenGLTarget (OpenGLContext& context_, OpenGLFrameBuffer& frameBuffer_, const Point& origin) noexcept + : context (context_), frameBuffer (&frameBuffer_), frameBufferID (0), bounds (origin.x, origin.y, frameBuffer_.getWidth(), frameBuffer_.getHeight()) {} OpenGLTarget (const OpenGLTarget& other) noexcept - : frameBuffer (other.frameBuffer), frameBufferID (other.frameBufferID), - bounds (other.bounds) + : context (other.context), frameBuffer (other.frameBuffer), + frameBufferID (other.frameBufferID), bounds (other.bounds) {} + OpenGLTarget& operator= (const OpenGLTarget& other) + { + frameBuffer = other.frameBuffer; + frameBufferID = other.frameBufferID; + bounds = other.bounds; + return *this; + } + void makeActiveFor2D() const { if (frameBuffer != nullptr) frameBuffer->makeCurrentRenderingTarget(); else - OpenGLFrameBuffer::setCurrentFrameBufferTarget (frameBufferID); + context.extensions.glBindFramebuffer (GL_FRAMEBUFFER, frameBufferID); #if JUCE_USE_OPENGL_FIXED_FUNCTION applyFlippedMatrix (bounds.getX(), bounds.getY(), bounds.getWidth(), bounds.getHeight()); @@ -77,6 +85,7 @@ struct OpenGLTarget } #endif + OpenGLContext& context; OpenGLFrameBuffer* frameBuffer; GLuint frameBufferID; @@ -190,14 +199,30 @@ private: class ShaderPrograms : public ReferenceCountedObject { public: - ShaderPrograms() {} + ShaderPrograms (const OpenGLContext& context) + : solidColourProgram (context), + solidColourMasked (context), + radialGradient (context), + radialGradientMasked (context), + linearGradient1 (context), + linearGradient1Masked (context), + linearGradient2 (context), + linearGradient2Masked (context), + image (context), + imageMasked (context), + tiledImage (context), + tiledImageMasked (context), + copyTexture (context), + maskTexture (context) + {} typedef ReferenceCountedObjectPtr Ptr; //============================================================================== struct ShaderProgramHolder { - ShaderProgramHolder (const char* fragmentShader) + ShaderProgramHolder (const OpenGLContext& context, const char* fragmentShader) + : program (context) { program.addShader ("attribute vec2 position;" "attribute vec4 colour;" @@ -218,8 +243,8 @@ public: struct ShaderBase : public ShaderProgramHolder { - ShaderBase (const char* fragmentShader) - : ShaderProgramHolder (fragmentShader), + ShaderBase (const OpenGLContext& context, const char* fragmentShader) + : ShaderProgramHolder (context, fragmentShader), positionAttribute (program, "position"), colourAttribute (program, "colour"), screenBounds (program, "screenBounds") @@ -230,12 +255,12 @@ public: screenBounds.set (bounds.getX(), bounds.getY(), 0.5f * bounds.getWidth(), 0.5f * bounds.getHeight()); } - void bindAttributes() + void bindAttributes (const OpenGLContext& context) { - glVertexAttribPointer (positionAttribute.attributeID, 2, GL_SHORT, GL_FALSE, 8, (void*) 0); - glVertexAttribPointer (colourAttribute.attributeID, 4, GL_UNSIGNED_BYTE, GL_TRUE, 8, (void*) 4); - glEnableVertexAttribArray (positionAttribute.attributeID); - glEnableVertexAttribArray (colourAttribute.attributeID); + context.extensions.glVertexAttribPointer (positionAttribute.attributeID, 2, GL_SHORT, GL_FALSE, 8, (void*) 0); + context.extensions.glVertexAttribPointer (colourAttribute.attributeID, 4, GL_UNSIGNED_BYTE, GL_TRUE, 8, (void*) 4); + context.extensions.glEnableVertexAttribArray (positionAttribute.attributeID); + context.extensions.glEnableVertexAttribArray (colourAttribute.attributeID); } OpenGLShaderProgram::Attribute positionAttribute, colourAttribute; @@ -265,11 +290,11 @@ public: //============================================================================== struct SolidColourProgram : public ShaderBase { - SolidColourProgram() - : ShaderBase ("void main()" - "{" - " gl_FragColor = gl_Color;" - "}") + SolidColourProgram (const OpenGLContext& context) + : ShaderBase (context, "void main()" + "{" + " gl_FragColor = gl_Color;" + "}") {} }; @@ -282,8 +307,8 @@ public: struct SolidColourMaskedProgram : public ShaderBase { - SolidColourMaskedProgram() - : ShaderBase (JUCE_DECLARE_SHADER_VERSION + SolidColourMaskedProgram (const OpenGLContext& context) + : ShaderBase (context, JUCE_DECLARE_SHADER_VERSION JUCE_DECLARE_MASK_UNIFORMS "void main()" "{" @@ -324,8 +349,8 @@ public: struct RadialGradientProgram : public ShaderBase { - RadialGradientProgram() - : ShaderBase (JUCE_DECLARE_SHADER_VERSION + RadialGradientProgram (const OpenGLContext& context) + : ShaderBase (context, JUCE_DECLARE_SHADER_VERSION JUCE_DECLARE_RADIAL_UNIFORMS "void main()" "{" @@ -340,8 +365,8 @@ public: struct RadialGradientMaskedProgram : public ShaderBase { - RadialGradientMaskedProgram() - : ShaderBase (JUCE_DECLARE_SHADER_VERSION + RadialGradientMaskedProgram (const OpenGLContext& context) + : ShaderBase (context, JUCE_DECLARE_SHADER_VERSION JUCE_DECLARE_RADIAL_UNIFORMS JUCE_DECLARE_MASK_UNIFORMS "void main()" @@ -375,8 +400,8 @@ public: struct LinearGradient1Program : public ShaderBase { - LinearGradient1Program() - : ShaderBase (JUCE_DECLARE_SHADER_VERSION + LinearGradient1Program (const OpenGLContext& context) + : ShaderBase (context, JUCE_DECLARE_SHADER_VERSION JUCE_DECLARE_LINEAR_UNIFORMS // gradientInfo: x = x1, y = y1, z = (y2 - y1) / (x2 - x1), w = length "void main()" "{" @@ -391,8 +416,8 @@ public: struct LinearGradient1MaskedProgram : public ShaderBase { - LinearGradient1MaskedProgram() - : ShaderBase (JUCE_DECLARE_SHADER_VERSION + LinearGradient1MaskedProgram (const OpenGLContext& context) + : ShaderBase (context, JUCE_DECLARE_SHADER_VERSION JUCE_DECLARE_LINEAR_UNIFORMS // gradientInfo: x = x1, y = y1, z = (y2 - y1) / (x2 - x1), w = length JUCE_DECLARE_MASK_UNIFORMS "void main()" @@ -410,8 +435,8 @@ public: struct LinearGradient2Program : public ShaderBase { - LinearGradient2Program() - : ShaderBase (JUCE_DECLARE_SHADER_VERSION + LinearGradient2Program (const OpenGLContext& context) + : ShaderBase (context, JUCE_DECLARE_SHADER_VERSION JUCE_DECLARE_LINEAR_UNIFORMS // gradientInfo: x = x1, y = y1, z = (x2 - x1) / (y2 - y1), y = y1, w = length "void main()" "{" @@ -426,8 +451,8 @@ public: struct LinearGradient2MaskedProgram : public ShaderBase { - LinearGradient2MaskedProgram() - : ShaderBase (JUCE_DECLARE_SHADER_VERSION + LinearGradient2MaskedProgram (const OpenGLContext& context) + : ShaderBase (context, JUCE_DECLARE_SHADER_VERSION JUCE_DECLARE_LINEAR_UNIFORMS // gradientInfo: x = x1, y = y1, z = (x2 - x1) / (y2 - y1), y = y1, w = length JUCE_DECLARE_MASK_UNIFORMS "void main()" @@ -486,8 +511,8 @@ public: struct ImageProgram : public ShaderBase { - ImageProgram() - : ShaderBase (JUCE_DECLARE_SHADER_VERSION + ImageProgram (const OpenGLContext& context) + : ShaderBase (context, JUCE_DECLARE_SHADER_VERSION JUCE_DECLARE_IMAGE_UNIFORMS "void main()" "{" @@ -502,8 +527,8 @@ public: struct ImageMaskedProgram : public ShaderBase { - ImageMaskedProgram() - : ShaderBase (JUCE_DECLARE_SHADER_VERSION + ImageMaskedProgram (const OpenGLContext& context) + : ShaderBase (context, JUCE_DECLARE_SHADER_VERSION JUCE_DECLARE_IMAGE_UNIFORMS JUCE_DECLARE_MASK_UNIFORMS "void main()" @@ -521,8 +546,8 @@ public: struct TiledImageProgram : public ShaderBase { - TiledImageProgram() - : ShaderBase (JUCE_DECLARE_SHADER_VERSION + TiledImageProgram (const OpenGLContext& context) + : ShaderBase (context, JUCE_DECLARE_SHADER_VERSION JUCE_DECLARE_IMAGE_UNIFORMS "void main()" "{" @@ -537,8 +562,8 @@ public: struct TiledImageMaskedProgram : public ShaderBase { - TiledImageMaskedProgram() - : ShaderBase (JUCE_DECLARE_SHADER_VERSION + TiledImageMaskedProgram (const OpenGLContext& context) + : ShaderBase (context, JUCE_DECLARE_SHADER_VERSION JUCE_DECLARE_IMAGE_UNIFORMS JUCE_DECLARE_MASK_UNIFORMS "void main()" @@ -556,8 +581,8 @@ public: struct CopyTextureProgram : public ShaderBase { - CopyTextureProgram() - : ShaderBase (JUCE_DECLARE_SHADER_VERSION + CopyTextureProgram (const OpenGLContext& context) + : ShaderBase (context, JUCE_DECLARE_SHADER_VERSION JUCE_DECLARE_IMAGE_UNIFORMS "void main()" "{" @@ -572,8 +597,8 @@ public: struct MaskTextureProgram : public ShaderBase { - MaskTextureProgram() - : ShaderBase (JUCE_DECLARE_SHADER_VERSION + MaskTextureProgram (const OpenGLContext& context) + : ShaderBase (context, JUCE_DECLARE_SHADER_VERSION JUCE_DECLARE_IMAGE_UNIFORMS "void main()" "{" @@ -884,8 +909,8 @@ struct StateHelpers //============================================================================== struct ActiveTextures { - ActiveTextures() noexcept - : texturesEnabled (0), currentActiveTexture (0) + ActiveTextures (const OpenGLContext& context_) noexcept + : texturesEnabled (0), currentActiveTexture (0), context (context_) {} void clear() noexcept @@ -964,10 +989,10 @@ struct StateHelpers if (currentActiveTexture != index) { currentActiveTexture = index; - glActiveTexture (GL_TEXTURE0 + index); + context.extensions.glActiveTexture (GL_TEXTURE0 + index); #if JUCE_USE_OPENGL_FIXED_FUNCTION - glClientActiveTexture (GL_TEXTURE0 + index); + context.extensions.glClientActiveTexture (GL_TEXTURE0 + index); #endif } } @@ -992,6 +1017,9 @@ struct StateHelpers private: GLuint currentTextureID [3]; int texturesEnabled, currentActiveTexture; + const OpenGLContext& context; + + ActiveTextures& operator= (const ActiveTextures&); }; //============================================================================== @@ -1068,14 +1096,14 @@ struct StateHelpers //============================================================================== struct ShaderQuadQueue { - ShaderQuadQueue() noexcept - : numVertices (0) + ShaderQuadQueue (const OpenGLContext& context_) noexcept + : context (context_), numVertices (0) {} ~ShaderQuadQueue() noexcept { static_jassert (sizeof (VertexInfo) == 8); - glDeleteBuffers (2, buffers); + context.extensions.glDeleteBuffers (2, buffers); } void initialise() noexcept @@ -1088,10 +1116,10 @@ struct StateHelpers indexData[i + 5] = (GLushort) (v + 3); } - glGenBuffers (2, buffers); - glBindBuffer (GL_ARRAY_BUFFER, buffers[0]); - glBindBuffer (GL_ELEMENT_ARRAY_BUFFER, buffers[1]); - glBufferData (GL_ELEMENT_ARRAY_BUFFER, sizeof (indexData), indexData, GL_STATIC_DRAW); + context.extensions.glGenBuffers (2, buffers); + context.extensions.glBindBuffer (GL_ARRAY_BUFFER, buffers[0]); + context.extensions.glBindBuffer (GL_ELEMENT_ARRAY_BUFFER, buffers[1]); + context.extensions.glBufferData (GL_ELEMENT_ARRAY_BUFFER, sizeof (indexData), indexData, GL_STATIC_DRAW); } void add (const int x, const int y, const int w, const int h, const PixelARGB& colour) noexcept @@ -1172,32 +1200,34 @@ struct StateHelpers GLuint buffers[2]; VertexInfo vertexData [numQuads * 4]; GLushort indexData [numQuads * 6]; + const OpenGLContext& context; int numVertices; void draw() noexcept { - glBufferData (GL_ARRAY_BUFFER, numVertices * 8, vertexData, GL_DYNAMIC_DRAW); - glDrawElements (GL_TRIANGLES, numVertices + numVertices / 2, GL_UNSIGNED_SHORT, 0); + context.extensions.glBufferData (GL_ARRAY_BUFFER, numVertices * sizeof (VertexInfo), vertexData, GL_DYNAMIC_DRAW); + glDrawElements (GL_TRIANGLES, (numVertices * 3) / 2, GL_UNSIGNED_SHORT, 0); numVertices = 0; } + + ShaderQuadQueue& operator= (const ShaderQuadQueue&); }; //============================================================================== struct CurrentShader { - CurrentShader() noexcept - : canUseShaders (OpenGLShaderProgram::getLanguageVersion() >= 1.199), activeShader (nullptr) + CurrentShader (OpenGLContext& context_) noexcept + : context (context_), + canUseShaders (OpenGLShaderProgram::getLanguageVersion() >= 1.199), + activeShader (nullptr) { - OpenGLContext* context = OpenGLContext::getCurrentContext(); - jassert (context != nullptr); // You can only use this class when you have an active GL context! - const Identifier programValueID ("GraphicsContextPrograms"); - programs = dynamic_cast (context->properties [programValueID].getObject()); + programs = dynamic_cast (context.properties [programValueID].getObject()); if (programs == nullptr && canUseShaders) { - programs = new ShaderPrograms(); - context->properties.set (programValueID, var (programs)); + programs = new ShaderPrograms (context); + context.properties.set (programValueID, var (programs)); } } @@ -1207,8 +1237,8 @@ struct StateHelpers { quadQueue.flush(); activeShader = &(shader.program); - glUseProgram (shader.program.programID); - shader.bindAttributes(); + context.extensions.glUseProgram (shader.program.programID); + shader.bindAttributes (context); currentBounds = bounds; shader.set2DBounds (bounds.toFloat()); @@ -1231,16 +1261,19 @@ struct StateHelpers { quadQueue.flush(); activeShader = nullptr; - glUseProgram (0); + context.extensions.glUseProgram (0); } } + OpenGLContext& context; ShaderPrograms::Ptr programs; bool canUseShaders; private: OpenGLShaderProgram* activeShader; Rectangle currentBounds; + + CurrentShader& operator= (const CurrentShader&); }; #endif }; @@ -1251,10 +1284,13 @@ class OpenGLGraphicsContext::GLState public: GLState (const OpenGLTarget& target_) noexcept : target (target_), + activeTextures (target_.context), + #if JUCE_USE_OPENGL_SHADERS + currentShader (target_.context), + shaderQuadQueue (target_.context), + #endif previousFrameBufferTarget (OpenGLFrameBuffer::getCurrentFrameBufferTarget()) { - initialiseGLExtensions(); - // This object can only be created and used when the current thread has an active OpenGL context. jassert (OpenGLHelpers::isContextActive()); @@ -1311,7 +1347,7 @@ public: { flush(); - OpenGLFrameBuffer::setCurrentFrameBufferTarget (previousFrameBufferTarget); + target.context.extensions.glBindFramebuffer (GL_FRAMEBUFFER, previousFrameBufferTarget); #if JUCE_USE_OPENGL_FIXED_FUNCTION resetMultiTextureModes (true); #endif @@ -1986,13 +2022,13 @@ public: clip (other.clip), maskOrigin (other.clip.getPosition()) { - TargetSaver ts; + TargetSaver ts (state.target.context); state.flush(); state.activeTextures.setSingleTextureMode (state.quadQueue); state.activeTextures.clear(); - mask.initialise (clip.getWidth(), clip.getHeight()); + mask.initialise (state.target.context, clip.getWidth(), clip.getHeight()); - OpenGLTarget m (mask, maskOrigin); + OpenGLTarget m (state.target.context, mask, maskOrigin); m.makeActiveFor2D(); state.blendMode.disableBlend (state.quadQueue); state.currentColour.setSolidColour(); @@ -2005,7 +2041,7 @@ public: clip (r.getBounds()), maskOrigin (clip.getPosition()) { - TargetSaver ts; + TargetSaver ts (state.target.context); initialiseClear(); state.blendMode.disableBlend (state.quadQueue); state.fillRectangleList (r, PixelARGB (0xffffffff)); @@ -2034,7 +2070,7 @@ public: if (excluded.getNumRectangles() == 1) return excludeClipRectangle (excluded.getRectangle (0)); - TargetSaver ts; + TargetSaver ts (state.target.context); makeMaskActive(); state.blendMode.disableBlend (state.quadQueue); state.fillRectangleList (excluded, PixelARGB (0)); @@ -2049,7 +2085,7 @@ public: if (r.contains (clip)) return nullptr; - TargetSaver ts; + TargetSaver ts (state.target.context); makeMaskActive(); state.activeTextures.disableTextures (state.quadQueue); state.blendMode.disableBlend (state.quadQueue); @@ -2079,7 +2115,7 @@ public: if (clip.isEmpty()) return nullptr; - TargetSaver ts; + TargetSaver ts (state.target.context); makeMaskActive(); state.blendMode.setBlendFunc (state.quadQueue, GL_ZERO, GL_SRC_ALPHA); state.currentColour.setSolidColour(); @@ -2090,7 +2126,7 @@ public: Ptr clipToImageAlpha (const OpenGLTextureFromImage& image, const AffineTransform& transform) { - TargetSaver ts; + TargetSaver ts (state.target.context); makeMaskActive(); state.blendMode.setBlendFunc (state.quadQueue, GL_ZERO, GL_SRC_ALPHA); state.currentColour.setSolidColour(); @@ -2210,7 +2246,7 @@ protected: jassert (! clip.isEmpty()); state.activeTextures.setSingleTextureMode (state.quadQueue); state.activeTextures.clear(); - mask.initialise (clip.getWidth(), clip.getHeight()); + mask.initialise (state.target.context, clip.getWidth(), clip.getHeight()); mask.makeCurrentAndClear(); state.activeTextures.disableTextures (state.quadQueue); state.blendMode.disableBlend (state.quadQueue); @@ -2219,8 +2255,8 @@ protected: struct TargetSaver { - TargetSaver() - : oldFramebuffer (OpenGLFrameBuffer::getCurrentFrameBufferTarget()) + TargetSaver (const OpenGLContext& context_) + : context (context_), oldFramebuffer (OpenGLFrameBuffer::getCurrentFrameBufferTarget()) { glGetIntegerv (GL_VIEWPORT, oldViewport); glPushMatrix(); @@ -2228,15 +2264,18 @@ protected: ~TargetSaver() { - OpenGLFrameBuffer::setCurrentFrameBufferTarget (oldFramebuffer); + context.extensions.glBindFramebuffer (GL_FRAMEBUFFER, oldFramebuffer); glPopMatrix(); glViewport (oldViewport[0], oldViewport[1], oldViewport[2], oldViewport[3]); } private: + const OpenGLContext& context; GLuint oldFramebuffer; GLint oldViewport[4]; + + TargetSaver& operator= (const TargetSaver&); }; struct FloatRectangleRenderer @@ -2398,12 +2437,12 @@ public: clip (other.clip), maskArea (other.clip) { - TargetSaver ts; + TargetSaver ts (state.target.context); state.currentShader.clearShader (state.shaderQuadQueue); state.shaderQuadQueue.flush(); state.activeTextures.setSingleTextureMode (state.shaderQuadQueue); state.activeTextures.clear(); - mask.initialise (maskArea.getWidth(), maskArea.getHeight()); + mask.initialise (state.target.context, maskArea.getWidth(), maskArea.getHeight()); makeActive(); state.blendMode.disableBlend (state.shaderQuadQueue); @@ -2426,11 +2465,11 @@ public: clip (r.getBounds()), maskArea (clip) { - TargetSaver ts; + TargetSaver ts (state.target.context); state.currentShader.clearShader (state.shaderQuadQueue); state.shaderQuadQueue.flush(); state.activeTextures.clear(); - mask.initialise (maskArea.getWidth(), maskArea.getHeight()); + mask.initialise (state.target.context, maskArea.getWidth(), maskArea.getHeight()); mask.makeCurrentAndClear(); makeActive(); state.blendMode.setBlendMode (state.shaderQuadQueue, true); @@ -2461,7 +2500,7 @@ public: if (excluded.getNumRectangles() == 1) return excludeClipRectangle (excluded.getRectangle (0)); - TargetSaver ts; + TargetSaver ts (state.target.context); makeActive(); state.blendMode.setBlendMode (state.shaderQuadQueue, true); state.currentShader.setShader (maskArea, state.shaderQuadQueue, state.currentShader.programs->solidColourProgram); @@ -2477,7 +2516,7 @@ public: if (r.contains (clip)) return nullptr; - TargetSaver ts; + TargetSaver ts (state.target.context); makeActive(); state.blendMode.setBlendMode (state.shaderQuadQueue, true); state.currentShader.setShader (maskArea, state.shaderQuadQueue, state.currentShader.programs->solidColourProgram); @@ -2492,7 +2531,7 @@ public: if (! et.isEmpty()) { - TargetSaver ts; + TargetSaver ts (state.target.context); state.currentShader.clearShader (state.shaderQuadQueue); state.shaderQuadQueue.flush(); state.activeTextures.clear(); @@ -2512,7 +2551,7 @@ public: if (clip.isEmpty()) return nullptr; - TargetSaver ts; + TargetSaver ts (state.target.context); makeActive(); state.activeTextures.setSingleTextureMode (state.shaderQuadQueue); @@ -2533,7 +2572,7 @@ public: Ptr clipToImageAlpha (const OpenGLTextureFromImage& image, const AffineTransform& transform) { - TargetSaver ts; + TargetSaver ts (state.target.context); makeActive(); state.activeTextures.setSingleTextureMode (state.shaderQuadQueue); state.activeTextures.bindTexture (image.textureID); @@ -2651,21 +2690,24 @@ private: struct TargetSaver { - TargetSaver() - : oldFramebuffer (OpenGLFrameBuffer::getCurrentFrameBufferTarget()) + TargetSaver (const OpenGLContext& context_) + : context (context_), oldFramebuffer (OpenGLFrameBuffer::getCurrentFrameBufferTarget()) { glGetIntegerv (GL_VIEWPORT, oldViewport); } ~TargetSaver() { - OpenGLFrameBuffer::setCurrentFrameBufferTarget (oldFramebuffer); + context.extensions.glBindFramebuffer (GL_FRAMEBUFFER, oldFramebuffer); glViewport (oldViewport[0], oldViewport[1], oldViewport[2], oldViewport[3]); } private: + const OpenGLContext& context; GLuint oldFramebuffer; GLint oldViewport[4]; + + TargetSaver& operator= (const TargetSaver&); }; void makeActive() @@ -2965,7 +3007,7 @@ public: state->flush(); s->transparencyLayer = Image (OpenGLImageType().create (Image::ARGB, clipBounds.getWidth(), clipBounds.getHeight(), true)); s->previousTarget = new OpenGLTarget (state->target); - state->target = OpenGLTarget (*OpenGLImageType::getFrameBufferFrom (s->transparencyLayer), clipBounds.getPosition()); + state->target = OpenGLTarget (state->target.context, *OpenGLImageType::getFrameBufferFrom (s->transparencyLayer), clipBounds.getPosition()); s->transparencyLayerAlpha = opacity; s->cloneClipIfMultiplyReferenced(); @@ -3161,19 +3203,20 @@ private: //============================================================================== OpenGLGraphicsContext::OpenGLGraphicsContext (OpenGLComponent& target) - : glState (new GLState (OpenGLTarget (target.getFrameBufferID(), target.getWidth(), target.getHeight()))), + : glState (new GLState (OpenGLTarget (*target.getCurrentContext(), target.getFrameBufferID(), target.getWidth(), target.getHeight()))), stack (new SavedState (glState)) { + jassert (target.getCurrentContext() != nullptr); // must have a valid context when this is called! } -OpenGLGraphicsContext::OpenGLGraphicsContext (OpenGLFrameBuffer& target) - : glState (new GLState (OpenGLTarget (target, Point()))), +OpenGLGraphicsContext::OpenGLGraphicsContext (OpenGLContext& context, OpenGLFrameBuffer& target) + : glState (new GLState (OpenGLTarget (context, target, Point()))), stack (new SavedState (glState)) { } -OpenGLGraphicsContext::OpenGLGraphicsContext (unsigned int frameBufferID, int width, int height) - : glState (new GLState (OpenGLTarget (frameBufferID, width, height))), +OpenGLGraphicsContext::OpenGLGraphicsContext (OpenGLContext& context, unsigned int frameBufferID, int width, int height) + : glState (new GLState (OpenGLTarget (context, frameBufferID, width, height))), stack (new SavedState (glState)) { } diff --git a/modules/juce_opengl/opengl/juce_OpenGLGraphicsContext.h b/modules/juce_opengl/opengl/juce_OpenGLGraphicsContext.h index 228fb2c121..3868db7379 100644 --- a/modules/juce_opengl/opengl/juce_OpenGLGraphicsContext.h +++ b/modules/juce_opengl/opengl/juce_OpenGLGraphicsContext.h @@ -34,8 +34,8 @@ class JUCE_API OpenGLGraphicsContext : public LowLevelGraphicsContext { public: explicit OpenGLGraphicsContext (OpenGLComponent& target); - explicit OpenGLGraphicsContext (OpenGLFrameBuffer& target); - OpenGLGraphicsContext (unsigned int frameBufferID, int width, int height); + OpenGLGraphicsContext (OpenGLContext& context, OpenGLFrameBuffer& target); + OpenGLGraphicsContext (OpenGLContext& context, unsigned int frameBufferID, int width, int height); ~OpenGLGraphicsContext(); bool isVectorDevice() const; diff --git a/modules/juce_opengl/opengl/juce_OpenGLHelpers.cpp b/modules/juce_opengl/opengl/juce_OpenGLHelpers.cpp index fd8bbf8128..009a6fa0f8 100644 --- a/modules/juce_opengl/opengl/juce_OpenGLHelpers.cpp +++ b/modules/juce_opengl/opengl/juce_OpenGLHelpers.cpp @@ -40,65 +40,25 @@ void* OpenGLHelpers::getExtensionFunction (const char* functionName) #endif } -#if ! JUCE_OPENGL_ES -namespace -{ - bool isExtensionSupportedV3 (const char* extensionName) - { - #ifndef GL_NUM_EXTENSIONS - enum { GL_NUM_EXTENSIONS = 0x821d }; - #endif - - JUCE_DECLARE_GL_EXTENSION_FUNCTION (glGetStringi, const GLubyte*, (GLenum, GLuint)) - - if (glGetStringi == nullptr) - glGetStringi = (type_glGetStringi) OpenGLHelpers::getExtensionFunction ("glGetStringi"); - - if (glGetStringi != nullptr) - { - GLint numExtensions = 0; - glGetIntegerv (GL_NUM_EXTENSIONS, &numExtensions); - - for (int i = 0; i < numExtensions; ++i) - if (strcmp (extensionName, (const char*) glGetStringi (GL_EXTENSIONS, i)) == 0) - return true; - } - - return false; - } -} -#endif - bool OpenGLHelpers::isExtensionSupported (const char* const extensionName) { jassert (extensionName != nullptr); // you must supply a genuine string for this. jassert (isContextActive()); // An OpenGL context will need to be active before calling this. - #if ! JUCE_OPENGL_ES - const GLubyte* version = glGetString (GL_VERSION); + const char* extensions = (const char*) glGetString (GL_EXTENSIONS); + jassert (extensions != nullptr); // Perhaps you didn't activate an OpenGL context before calling this? - if (version != nullptr && version[0] >= '3') - { - return isExtensionSupportedV3 (extensionName); - } - else - #endif + for (;;) { - const char* extensions = (const char*) glGetString (GL_EXTENSIONS); - jassert (extensions != nullptr); // Perhaps you didn't activate an OpenGL context before calling this? - - for (;;) - { - const char* found = strstr (extensions, extensionName); + const char* found = strstr (extensions, extensionName); - if (found == nullptr) - break; + if (found == nullptr) + break; - extensions = found + strlen (extensionName); + extensions = found + strlen (extensionName); - if (extensions[0] == ' ' || extensions[0] == 0) - return true; - } + if (extensions[0] == ' ' || extensions[0] == 0) + return true; } return false; diff --git a/modules/juce_opengl/opengl/juce_OpenGLImage.cpp b/modules/juce_opengl/opengl/juce_OpenGLImage.cpp index 6725a47a3c..8de003d86d 100644 --- a/modules/juce_opengl/opengl/juce_OpenGLImage.cpp +++ b/modules/juce_opengl/opengl/juce_OpenGLImage.cpp @@ -26,25 +26,26 @@ class OpenGLFrameBufferImage : public ImagePixelData { public: - OpenGLFrameBufferImage (int width, int height) + OpenGLFrameBufferImage (OpenGLContext& context_, int width, int height) : ImagePixelData (Image::ARGB, width, height), + context (context_), pixelStride (4), lineStride (width * pixelStride) { - frameBuffer.initialise (width, height); + frameBuffer.initialise (context, width, height); frameBuffer.clear (Colours::transparentBlack); } LowLevelGraphicsContext* createLowLevelContext() { - return new OpenGLGraphicsContext (frameBuffer); + return new OpenGLGraphicsContext (context, frameBuffer); } ImageType* createType() const { return new OpenGLImageType(); } ImagePixelData* clone() { - OpenGLFrameBufferImage* im = new OpenGLFrameBufferImage (width, height); + OpenGLFrameBufferImage* im = new OpenGLFrameBufferImage (context, width, height); im->incReferenceCount(); { @@ -72,6 +73,7 @@ public: } } + OpenGLContext& context; OpenGLFrameBuffer frameBuffer; private: @@ -175,7 +177,10 @@ int OpenGLImageType::getTypeID() const ImagePixelData* OpenGLImageType::create (Image::PixelFormat, int width, int height, bool shouldClearImage) const { - OpenGLFrameBufferImage* im = new OpenGLFrameBufferImage (width, height); + OpenGLContext* currentContext = OpenGLContext::getCurrentContext(); + jassert (currentContext != nullptr); // an OpenGL image can only be created when a valid context is active! + + OpenGLFrameBufferImage* im = new OpenGLFrameBufferImage (*currentContext, width, height); if (shouldClearImage) im->frameBuffer.clear (Colours::transparentBlack); diff --git a/modules/juce_opengl/opengl/juce_OpenGLShaderProgram.cpp b/modules/juce_opengl/opengl/juce_OpenGLShaderProgram.cpp index 84c7f62e93..836fef55b8 100644 --- a/modules/juce_opengl/opengl/juce_OpenGLShaderProgram.cpp +++ b/modules/juce_opengl/opengl/juce_OpenGLShaderProgram.cpp @@ -23,17 +23,18 @@ ============================================================================== */ -OpenGLShaderProgram::OpenGLShaderProgram() noexcept +OpenGLShaderProgram::OpenGLShaderProgram (const OpenGLContext& context_) noexcept + : context (context_) { // This object can only be created and used when the current thread has an active OpenGL context. jassert (OpenGLHelpers::isContextActive()); - programID = glCreateProgram(); + programID = context.extensions.glCreateProgram(); } OpenGLShaderProgram::~OpenGLShaderProgram() noexcept { - glDeleteProgram (programID); + context.extensions.glDeleteProgram (programID); } double OpenGLShaderProgram::getLanguageVersion() @@ -44,55 +45,55 @@ double OpenGLShaderProgram::getLanguageVersion() void OpenGLShaderProgram::addShader (const char* const code, GLenum type) { - GLuint shaderID = glCreateShader (type); - glShaderSource (shaderID, 1, (const GLchar**) &code, nullptr); - glCompileShader (shaderID); + GLuint shaderID = context.extensions.glCreateShader (type); + context.extensions.glShaderSource (shaderID, 1, (const GLchar**) &code, nullptr); + context.extensions.glCompileShader (shaderID); #if JUCE_DEBUG GLint status = 0; - glGetShaderiv (shaderID, GL_COMPILE_STATUS, &status); + context.extensions.glGetShaderiv (shaderID, GL_COMPILE_STATUS, &status); if (status == GL_FALSE) { GLchar infoLog [16384]; GLsizei infologLength = 0; - glGetShaderInfoLog (shaderID, sizeof (infoLog), &infologLength, infoLog); + context.extensions.glGetShaderInfoLog (shaderID, sizeof (infoLog), &infologLength, infoLog); DBG (String (infoLog, infologLength)); jassertfalse; } #endif - glAttachShader (programID, shaderID); - glDeleteShader (shaderID); + context.extensions.glAttachShader (programID, shaderID); + context.extensions.glDeleteShader (shaderID); } void OpenGLShaderProgram::link() noexcept { - glLinkProgram (programID); + context.extensions.glLinkProgram (programID); #if JUCE_DEBUG GLint status = 0; - glGetProgramiv (programID, GL_LINK_STATUS, &status); + context.extensions.glGetProgramiv (programID, GL_LINK_STATUS, &status); jassert (status != GL_FALSE); #endif } OpenGLShaderProgram::Uniform::Uniform (const OpenGLShaderProgram& program, const char* const name) - : uniformID (glGetUniformLocation (program.programID, name)) + : uniformID (program.context.extensions.glGetUniformLocation (program.programID, name)), context (program.context) { jassert (uniformID >= 0); } OpenGLShaderProgram::Attribute::Attribute (const OpenGLShaderProgram& program, const char* name) - : attributeID (glGetAttribLocation (program.programID, name)) + : attributeID (program.context.extensions.glGetAttribLocation (program.programID, name)) { jassert (attributeID >= 0); } -void OpenGLShaderProgram::Uniform::set (GLfloat n1) const noexcept { glUniform1f (uniformID, n1); } -void OpenGLShaderProgram::Uniform::set (GLint n1) const noexcept { glUniform1i (uniformID, n1); } -void OpenGLShaderProgram::Uniform::set (GLfloat n1, GLfloat n2) const noexcept { glUniform2f (uniformID, n1, n2); } -void OpenGLShaderProgram::Uniform::set (GLfloat n1, GLfloat n2, GLfloat n3) const noexcept { glUniform3f (uniformID, n1, n2, n3); } -void OpenGLShaderProgram::Uniform::set (GLfloat n1, GLfloat n2, GLfloat n3, float n4) const noexcept { glUniform4f (uniformID, n1, n2, n3, n4); } -void OpenGLShaderProgram::Uniform::set (GLint n1, GLint n2, GLint n3, GLint n4) const noexcept { glUniform4i (uniformID, n1, n2, n3, n4); } -void OpenGLShaderProgram::Uniform::set (const GLfloat* values, GLsizei numValues) const noexcept { glUniform1fv (uniformID, numValues, values); } +void OpenGLShaderProgram::Uniform::set (GLfloat n1) const noexcept { context.extensions.glUniform1f (uniformID, n1); } +void OpenGLShaderProgram::Uniform::set (GLint n1) const noexcept { context.extensions.glUniform1i (uniformID, n1); } +void OpenGLShaderProgram::Uniform::set (GLfloat n1, GLfloat n2) const noexcept { context.extensions.glUniform2f (uniformID, n1, n2); } +void OpenGLShaderProgram::Uniform::set (GLfloat n1, GLfloat n2, GLfloat n3) const noexcept { context.extensions.glUniform3f (uniformID, n1, n2, n3); } +void OpenGLShaderProgram::Uniform::set (GLfloat n1, GLfloat n2, GLfloat n3, float n4) const noexcept { context.extensions.glUniform4f (uniformID, n1, n2, n3, n4); } +void OpenGLShaderProgram::Uniform::set (GLint n1, GLint n2, GLint n3, GLint n4) const noexcept { context.extensions.glUniform4i (uniformID, n1, n2, n3, n4); } +void OpenGLShaderProgram::Uniform::set (const GLfloat* values, GLsizei numValues) const noexcept { context.extensions.glUniform1fv (uniformID, numValues, values); } diff --git a/modules/juce_opengl/opengl/juce_OpenGLShaderProgram.h b/modules/juce_opengl/opengl/juce_OpenGLShaderProgram.h index ad8591d201..dba7873b5d 100644 --- a/modules/juce_opengl/opengl/juce_OpenGLShaderProgram.h +++ b/modules/juce_opengl/opengl/juce_OpenGLShaderProgram.h @@ -33,7 +33,7 @@ class JUCE_API OpenGLShaderProgram { public: - OpenGLShaderProgram() noexcept; + OpenGLShaderProgram (const OpenGLContext& context) noexcept; ~OpenGLShaderProgram() noexcept; /** Returns the version of GLSL that the current context supports. @@ -99,6 +99,11 @@ public: If the uniform couldn't be found, this value will be < 0. */ GLint uniformID; + + private: + const OpenGLContext& context; + + JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (Uniform); }; /** Represents an openGL vertex attribute value. @@ -123,6 +128,8 @@ public: GLuint programID; private: + const OpenGLContext& context; + JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (OpenGLShaderProgram); }; diff --git a/modules/juce_video/juce_module_info b/modules/juce_video/juce_module_info index 450bea276b..236b471fd9 100644 --- a/modules/juce_video/juce_module_info +++ b/modules/juce_video/juce_module_info @@ -1,7 +1,7 @@ { "id": "juce_video", "name": "JUCE video playback and capture classes", - "version": "2.0.14", + "version": "2.0.15", "description": "Classes for playing video and capturing camera input.", "website": "http://www.juce.com/juce", "license": "GPL/Commercial",