diff --git a/extras/JuceDemo/Builds/MacOSX/Juce Demo.xcodeproj/project.pbxproj b/extras/JuceDemo/Builds/MacOSX/Juce Demo.xcodeproj/project.pbxproj index 84ab0735f3..5bad6798f1 100644 --- a/extras/JuceDemo/Builds/MacOSX/Juce Demo.xcodeproj/project.pbxproj +++ b/extras/JuceDemo/Builds/MacOSX/Juce Demo.xcodeproj/project.pbxproj @@ -384,6 +384,7 @@ 5741A7FD2C785C3F65377A45 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_linux_AudioCDReader.cpp"; path = "../../../../modules/juce_audio_devices/native/juce_linux_AudioCDReader.cpp"; sourceTree = "SOURCE_ROOT"; }; 574BCE46C31D810F694B0651 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_FileChooserDialogBox.cpp"; path = "../../../../modules/juce_gui_basics/filebrowser/juce_FileChooserDialogBox.cpp"; sourceTree = "SOURCE_ROOT"; }; 575587359A2F65312CE97AC4 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = "juce_graphics.mm"; path = "../../../../modules/juce_graphics/juce_graphics.mm"; sourceTree = "SOURCE_ROOT"; }; + 5786364EC4C531CDE41BDCEA = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_OpenGLContext.cpp"; path = "../../../../modules/juce_opengl/opengl/juce_OpenGLContext.cpp"; sourceTree = "SOURCE_ROOT"; }; 579D22DA6ECC930E19B7104A = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = BinaryData.cpp; path = ../../JuceLibraryCode/BinaryData.cpp; sourceTree = "SOURCE_ROOT"; }; 58061ADC1867C814A334D49D = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_FileInputStream.cpp"; path = "../../../../modules/juce_core/files/juce_FileInputStream.cpp"; sourceTree = "SOURCE_ROOT"; }; 58864C3D7F369EBE01E42C5C = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_OpenGLShaderProgram.cpp"; path = "../../../../modules/juce_opengl/opengl/juce_OpenGLShaderProgram.cpp"; sourceTree = "SOURCE_ROOT"; }; @@ -1897,6 +1898,7 @@ 87FB016388B49E97FCCBE69B, 4F802BD98072EA49F7F4FE4A, D6D0F076F54C7D669A9717C9, + 5786364EC4C531CDE41BDCEA, 8878426C7F58CB22969E7133, AC3EFDDC80761A45E8BE0624, 43E4604C39E9A992216F6B98, diff --git a/extras/JuceDemo/Builds/VisualStudio2005/Juce Demo.vcproj b/extras/JuceDemo/Builds/VisualStudio2005/Juce Demo.vcproj index cf63ed12ad..5c631b04fc 100644 --- a/extras/JuceDemo/Builds/VisualStudio2005/Juce Demo.vcproj +++ b/extras/JuceDemo/Builds/VisualStudio2005/Juce Demo.vcproj @@ -4265,6 +4265,16 @@ + + + + + + + + + + + + + + + + true + + true + true diff --git a/extras/JuceDemo/Builds/VisualStudio2010/Juce Demo.vcxproj.filters b/extras/JuceDemo/Builds/VisualStudio2010/Juce Demo.vcxproj.filters index bafb6723d3..87d777de08 100644 --- a/extras/JuceDemo/Builds/VisualStudio2010/Juce Demo.vcxproj.filters +++ b/extras/JuceDemo/Builds/VisualStudio2010/Juce Demo.vcxproj.filters @@ -1498,6 +1498,9 @@ Juce Modules\juce_opengl\opengl + + Juce Modules\juce_opengl\opengl + Juce Modules\juce_opengl\opengl diff --git a/extras/JuceDemo/Builds/iOS/Juce Demo.xcodeproj/project.pbxproj b/extras/JuceDemo/Builds/iOS/Juce Demo.xcodeproj/project.pbxproj index 87942151e1..e014797428 100644 --- a/extras/JuceDemo/Builds/iOS/Juce Demo.xcodeproj/project.pbxproj +++ b/extras/JuceDemo/Builds/iOS/Juce Demo.xcodeproj/project.pbxproj @@ -378,6 +378,7 @@ 5741A7FD2C785C3F65377A45 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_linux_AudioCDReader.cpp"; path = "../../../../modules/juce_audio_devices/native/juce_linux_AudioCDReader.cpp"; sourceTree = "SOURCE_ROOT"; }; 574BCE46C31D810F694B0651 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_FileChooserDialogBox.cpp"; path = "../../../../modules/juce_gui_basics/filebrowser/juce_FileChooserDialogBox.cpp"; sourceTree = "SOURCE_ROOT"; }; 575587359A2F65312CE97AC4 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = "juce_graphics.mm"; path = "../../../../modules/juce_graphics/juce_graphics.mm"; sourceTree = "SOURCE_ROOT"; }; + 5786364EC4C531CDE41BDCEA = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_OpenGLContext.cpp"; path = "../../../../modules/juce_opengl/opengl/juce_OpenGLContext.cpp"; sourceTree = "SOURCE_ROOT"; }; 579D22DA6ECC930E19B7104A = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = BinaryData.cpp; path = ../../JuceLibraryCode/BinaryData.cpp; sourceTree = "SOURCE_ROOT"; }; 58061ADC1867C814A334D49D = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_FileInputStream.cpp"; path = "../../../../modules/juce_core/files/juce_FileInputStream.cpp"; sourceTree = "SOURCE_ROOT"; }; 58864C3D7F369EBE01E42C5C = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_OpenGLShaderProgram.cpp"; path = "../../../../modules/juce_opengl/opengl/juce_OpenGLShaderProgram.cpp"; sourceTree = "SOURCE_ROOT"; }; @@ -1889,6 +1890,7 @@ 87FB016388B49E97FCCBE69B, 4F802BD98072EA49F7F4FE4A, D6D0F076F54C7D669A9717C9, + 5786364EC4C531CDE41BDCEA, 8878426C7F58CB22969E7133, AC3EFDDC80761A45E8BE0624, 43E4604C39E9A992216F6B98, diff --git a/extras/JuceDemo/Source/demos/OpenGLDemo.cpp b/extras/JuceDemo/Source/demos/OpenGLDemo.cpp index de57eba0f1..6656c4ed56 100644 --- a/extras/JuceDemo/Source/demos/OpenGLDemo.cpp +++ b/extras/JuceDemo/Source/demos/OpenGLDemo.cpp @@ -102,6 +102,7 @@ public: glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glEnable (GL_TEXTURE_2D); + #if JUCE_USE_OPENGL_FIXED_FUNCTION OpenGLHelpers::prepareFor2D (getWidth(), getHeight()); OpenGLHelpers::setPerspective (45.0, getWidth() / (double) getHeight(), 0.1, 100.0); @@ -123,6 +124,7 @@ public: tex2->draw3D (-1.0f, 1.0f, -1.0f, -1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, -1.0f, Colours::white); tex2->draw3D ( 1.0f, 1.0f, -1.0f, 1.0f, 1.0f, 1.0f, 1.0f, -1.0f, 1.0f, 1.0f, -1.0f, -1.0f, Colours::white); tex2->draw3D (-1.0f, 1.0f, -1.0f, -1.0f, -1.0f, -1.0f, -1.0f, -1.0f, 1.0f, -1.0f, 1.0f, 1.0f, Colours::white); + #endif } void updateTextureImage() 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 c17ed5f568..5b0a322138 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 @@ -531,6 +531,7 @@ 94B22D21E4DE9259A3F385A3 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_DropShadowEffect.h"; path = "../../../../modules/juce_graphics/effects/juce_DropShadowEffect.h"; sourceTree = "SOURCE_ROOT"; }; 94B986F221A8369B8DE3D986 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_WeakReference.h"; path = "../../../../modules/juce_core/memory/juce_WeakReference.h"; sourceTree = "SOURCE_ROOT"; }; 94D27CA81B1481621186F4D5 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_RenderingHelpers.h"; path = "../../../../modules/juce_graphics/native/juce_RenderingHelpers.h"; sourceTree = "SOURCE_ROOT"; }; + 9512FB5C9D667ED59CFC0FF4 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_OpenGLContext.cpp"; path = "../../../../modules/juce_opengl/opengl/juce_OpenGLContext.cpp"; sourceTree = "SOURCE_ROOT"; }; 956BE0B32D5B1410E43A3C58 = { isa = PBXFileReference; lastKnownFileType = file; name = "juce_module_info"; path = "../../../../modules/juce_data_structures/juce_module_info"; sourceTree = "SOURCE_ROOT"; }; 957428BC0CD90C37ED1EB7E1 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_StringArray.h"; path = "../../../../modules/juce_core/text/juce_StringArray.h"; sourceTree = "SOURCE_ROOT"; }; 9647232A743A0C7BFE819385 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_TextPropertyComponent.h"; path = "../../../../modules/juce_gui_basics/properties/juce_TextPropertyComponent.h"; sourceTree = "SOURCE_ROOT"; }; @@ -1819,6 +1820,7 @@ 483527FCBD7F07A7AF4743CC, CD96180DDD8610A155629CE1, E89669EB797637247F52D30F, + 9512FB5C9D667ED59CFC0FF4, BE0231D93CBB02BBC2704D1D, 43D23C18695F24F9A3DFA7B4, 438CA87567F47F9AF39788D1, diff --git a/extras/audio plugin host/Builds/VisualStudio2005/Plugin Host.vcproj b/extras/audio plugin host/Builds/VisualStudio2005/Plugin Host.vcproj index 06e1b197a5..d8a7c79901 100644 --- a/extras/audio plugin host/Builds/VisualStudio2005/Plugin Host.vcproj +++ b/extras/audio plugin host/Builds/VisualStudio2005/Plugin Host.vcproj @@ -4188,6 +4188,16 @@ + + + + + + + + + + + + + + + + + + + + + + + + true + + true + true diff --git a/extras/static library/Builds/VisualStudio2010/juce.vcxproj.filters b/extras/static library/Builds/VisualStudio2010/juce.vcxproj.filters index a7acb77432..f25d4bb010 100644 --- a/extras/static library/Builds/VisualStudio2010/juce.vcxproj.filters +++ b/extras/static library/Builds/VisualStudio2010/juce.vcxproj.filters @@ -1384,6 +1384,9 @@ Juce Modules\juce_opengl\opengl + + Juce Modules\juce_opengl\opengl + Juce Modules\juce_opengl\opengl diff --git a/modules/juce_core/containers/juce_HashMap.h b/modules/juce_core/containers/juce_HashMap.h index 86beaacc0e..b422a4d00e 100644 --- a/modules/juce_core/containers/juce_HashMap.h +++ b/modules/juce_core/containers/juce_HashMap.h @@ -376,7 +376,7 @@ public: public: //============================================================================== Iterator (const HashMap& hashMapToIterate) - : hashMap (hashMapToIterate), entry (0), index (0) + : hashMap (hashMapToIterate), entry (nullptr), index (0) {} /** Moves to the next item, if one is available. diff --git a/modules/juce_opengl/juce_opengl.cpp b/modules/juce_opengl/juce_opengl.cpp index d1b037fc16..1e7c537700 100644 --- a/modules/juce_opengl/juce_opengl.cpp +++ b/modules/juce_opengl/juce_opengl.cpp @@ -147,6 +147,7 @@ void OpenGLExtensionFunctions::initialise() //============================================================================== // START_AUTOINCLUDE opengl/*.cpp #include "opengl/juce_OpenGLComponent.cpp" +#include "opengl/juce_OpenGLContext.cpp" #include "opengl/juce_OpenGLFrameBuffer.cpp" #include "opengl/juce_OpenGLGraphicsContext.cpp" #include "opengl/juce_OpenGLHelpers.cpp" diff --git a/modules/juce_opengl/juce_opengl.h b/modules/juce_opengl/juce_opengl.h index 9cb74dd96a..39e10ba1ce 100644 --- a/modules/juce_opengl/juce_opengl.h +++ b/modules/juce_opengl/juce_opengl.h @@ -76,7 +76,6 @@ //============================================================================= BEGIN_JUCE_NAMESPACE -#include "opengl/juce_OpenGLRenderingTarget.h" #include "opengl/juce_OpenGLHelpers.h" // START_AUTOINCLUDE opengl diff --git a/modules/juce_opengl/native/juce_ios_OpenGLComponent.mm b/modules/juce_opengl/native/juce_ios_OpenGLComponent.mm index c9209c5f93..e6f3188d3b 100644 --- a/modules/juce_opengl/native/juce_ios_OpenGLComponent.mm +++ b/modules/juce_opengl/native/juce_ios_OpenGLComponent.mm @@ -74,20 +74,16 @@ public: ~GLESContext() { - deleteContext(); + properties.clear(); // to release any stored programs, etc that may be held in properties. + makeInactive(); + [context release]; + context = nil; [view removeFromSuperview]; [view release]; freeGLBuffers(); } - void deleteContext() - { - makeInactive(); - [context release]; - context = nil; - } - bool makeActive() const noexcept { jassert (context != nil); @@ -116,6 +112,9 @@ public: void* getRawContext() const noexcept { return glLayer; } unsigned int getFrameBufferID() const { return (unsigned int) frameBufferHandle; } + int getWidth() const { return lastWidth; } + int getHeight() const { return lastHeight; } + void updateWindowPosition (const Rectangle& bounds) { // For some strange reason, the view seems to fail unless its width is a multiple of 8... diff --git a/modules/juce_opengl/native/juce_linux_OpenGLComponent.cpp b/modules/juce_opengl/native/juce_linux_OpenGLComponent.cpp index 958193f186..a002101d17 100644 --- a/modules/juce_opengl/native/juce_linux_OpenGLComponent.cpp +++ b/modules/juce_opengl/native/juce_linux_OpenGLComponent.cpp @@ -103,14 +103,8 @@ public: ~WindowedGLContext() { ScopedXLock xlock; - deleteContext(); - XUnmapWindow (display, embeddedWindow); - XDestroyWindow (display, embeddedWindow); - } - - void deleteContext() - { + properties.clear(); // to release any stored programs, etc that may be held in properties. makeInactive(); if (renderContext != 0) @@ -119,6 +113,9 @@ public: glXDestroyContext (display, renderContext); renderContext = nullptr; } + + XUnmapWindow (display, embeddedWindow); + XDestroyWindow (display, embeddedWindow); } bool makeActive() const noexcept @@ -142,14 +139,19 @@ public: return glXGetCurrentContext() == renderContext; } - void* getRawContext() const noexcept - { - return renderContext; - } + unsigned int getFrameBufferID() const { return 0; } + void* getRawContext() const noexcept { return renderContext; } + + int getWidth() const { return bounds.getWidth(); } + int getHeight() const { return bounds.getHeight(); } - unsigned int getFrameBufferID() const + void updateWindowPosition (const Rectangle& newBounds) { - return 0; + bounds = newBounds; + + ScopedXLock xlock; + XMoveResizeWindow (display, embeddedWindow, + bounds.getX(), bounds.getY(), jmax (1, bounds.getWidth()), jmax (1, bounds.getHeight())); } void swapBuffers() @@ -183,6 +185,7 @@ public: private: int swapInterval; + Rectangle bounds; JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (WindowedGLContext); }; @@ -201,13 +204,7 @@ void OpenGLComponent::updateEmbeddedPosition (const Rectangle& bounds) const ScopedLock sl (contextLock); if (context != nullptr) - { - Window embeddedWindow = static_cast (context.get())->embeddedWindow; - - ScopedXLock xlock; - XMoveResizeWindow (display, embeddedWindow, - bounds.getX(), bounds.getY(), jmax (1, bounds.getWidth()), jmax (1, bounds.getHeight())); - } + static_cast (context.get())->updateWindowPosition (bounds); } //============================================================================== diff --git a/modules/juce_opengl/native/juce_mac_OpenGLComponent.mm b/modules/juce_opengl/native/juce_mac_OpenGLComponent.mm index 52dd74e342..ebd210a1f8 100644 --- a/modules/juce_opengl/native/juce_mac_OpenGLComponent.mm +++ b/modules/juce_opengl/native/juce_mac_OpenGLComponent.mm @@ -160,11 +160,8 @@ public: ~WindowedGLContext() { - deleteContext(); - } + properties.clear(); // to release any stored programs, etc that may be held in properties. - void deleteContext() - { makeInactive(); [renderContext clearDrawable]; [renderContext setView: nil]; @@ -197,6 +194,9 @@ public: void* getRawContext() const noexcept { return renderContext; } unsigned int getFrameBufferID() const { return 0; } + int getWidth() const { return [view frame].size.width; } + int getHeight() const { return [view frame].size.height; } + void swapBuffers() { [renderContext flushBuffer]; diff --git a/modules/juce_opengl/native/juce_win32_OpenGLComponent.cpp b/modules/juce_opengl/native/juce_win32_OpenGLComponent.cpp index 99ae21dc6c..de01ad5da1 100644 --- a/modules/juce_opengl/native/juce_win32_OpenGLComponent.cpp +++ b/modules/juce_opengl/native/juce_win32_OpenGLComponent.cpp @@ -64,13 +64,7 @@ public: ~WindowedGLContext() { - deleteContext(); - ReleaseDC ((HWND) nativeWindow->getNativeHandle(), dc); - nativeWindow = nullptr; - } - - void deleteContext() - { + properties.clear(); // to release any stored programs, etc that may be held in properties. makeInactive(); if (renderContext != 0) @@ -78,6 +72,9 @@ public: wglDeleteContext (renderContext); renderContext = 0; } + + ReleaseDC ((HWND) nativeWindow->getNativeHandle(), dc); + nativeWindow = nullptr; } bool makeActive() const noexcept @@ -96,15 +93,11 @@ public: return wglGetCurrentContext() == renderContext; } - void* getRawContext() const noexcept - { - return renderContext; - } + void* getRawContext() const noexcept { return renderContext; } + unsigned int getFrameBufferID() const { return 0; } - unsigned int getFrameBufferID() const - { - return 0; - } + int getWidth() const { return component->getWidth(); } + int getHeight() const { return component->getHeight(); } bool setPixelFormat (const OpenGLPixelFormat& pixelFormat) { diff --git a/modules/juce_opengl/opengl/juce_OpenGLComponent.cpp b/modules/juce_opengl/opengl/juce_OpenGLComponent.cpp index 91a8be09ea..c8e5c28fcf 100644 --- a/modules/juce_opengl/opengl/juce_OpenGLComponent.cpp +++ b/modules/juce_opengl/opengl/juce_OpenGLComponent.cpp @@ -23,98 +23,6 @@ ============================================================================== */ -//============================================================================== -OpenGLPixelFormat::OpenGLPixelFormat (const int bitsPerRGBComponent, - const int alphaBits_, - const int depthBufferBits_, - const int stencilBufferBits_) noexcept - : redBits (bitsPerRGBComponent), - greenBits (bitsPerRGBComponent), - blueBits (bitsPerRGBComponent), - alphaBits (alphaBits_), - depthBufferBits (depthBufferBits_), - stencilBufferBits (stencilBufferBits_), - accumulationBufferRedBits (0), - accumulationBufferGreenBits (0), - accumulationBufferBlueBits (0), - accumulationBufferAlphaBits (0), - multisamplingLevel (0) -{ -} - -OpenGLPixelFormat::OpenGLPixelFormat (const OpenGLPixelFormat& other) noexcept - : redBits (other.redBits), - greenBits (other.greenBits), - blueBits (other.blueBits), - alphaBits (other.alphaBits), - depthBufferBits (other.depthBufferBits), - stencilBufferBits (other.stencilBufferBits), - accumulationBufferRedBits (other.accumulationBufferRedBits), - accumulationBufferGreenBits (other.accumulationBufferGreenBits), - accumulationBufferBlueBits (other.accumulationBufferBlueBits), - accumulationBufferAlphaBits (other.accumulationBufferAlphaBits), - multisamplingLevel (other.multisamplingLevel) -{ -} - -OpenGLPixelFormat& OpenGLPixelFormat::operator= (const OpenGLPixelFormat& other) noexcept -{ - redBits = other.redBits; - greenBits = other.greenBits; - blueBits = other.blueBits; - alphaBits = other.alphaBits; - depthBufferBits = other.depthBufferBits; - stencilBufferBits = other.stencilBufferBits; - accumulationBufferRedBits = other.accumulationBufferRedBits; - accumulationBufferGreenBits = other.accumulationBufferGreenBits; - accumulationBufferBlueBits = other.accumulationBufferBlueBits; - accumulationBufferAlphaBits = other.accumulationBufferAlphaBits; - multisamplingLevel = other.multisamplingLevel; - return *this; -} - -bool OpenGLPixelFormat::operator== (const OpenGLPixelFormat& other) const noexcept -{ - return redBits == other.redBits - && greenBits == other.greenBits - && blueBits == other.blueBits - && alphaBits == other.alphaBits - && depthBufferBits == other.depthBufferBits - && stencilBufferBits == other.stencilBufferBits - && accumulationBufferRedBits == other.accumulationBufferRedBits - && accumulationBufferGreenBits == other.accumulationBufferGreenBits - && accumulationBufferBlueBits == other.accumulationBufferBlueBits - && accumulationBufferAlphaBits == other.accumulationBufferAlphaBits - && multisamplingLevel == other.multisamplingLevel; -} - -//============================================================================== -static Array knownContexts; - -OpenGLContext::OpenGLContext() noexcept -{ - knownContexts.add (this); -} - -OpenGLContext::~OpenGLContext() -{ - knownContexts.removeValue (this); -} - -OpenGLContext* OpenGLContext::getCurrentContext() -{ - for (int i = knownContexts.size(); --i >= 0;) - { - OpenGLContext* const oglc = knownContexts.getUnchecked(i); - - if (oglc->isActive()) - return oglc; - } - - return nullptr; -} - -//============================================================================== class OpenGLComponent::OpenGLCachedComponentImage : public CachedComponentImage, public Timer // N.B. using a Timer rather than an AsyncUpdater // to avoid scheduling problems on Windows @@ -122,8 +30,7 @@ class OpenGLComponent::OpenGLCachedComponentImage : public CachedComponentImage public: OpenGLCachedComponentImage (OpenGLComponent& owner_) : owner (owner_) - { - } + {} void paint (Graphics&) { @@ -533,11 +440,15 @@ bool OpenGLComponent::performRender() } } - OpenGLHelpers::prepareFor2D (bounds.getWidth(), bounds.getHeight()); - glBlendFunc (GL_ONE, GL_ONE_MINUS_SRC_ALPHA); - glEnable (GL_BLEND); - glColor4f (1.0f, 1.0f, 1.0f, getAlpha()); - frameBuffer.drawAt (0, (float) (bounds.getHeight() - frameBuffer.getHeight())); + glEnable (GL_TEXTURE_2D); + glActiveTexture (GL_TEXTURE0); + glBindTexture (GL_TEXTURE_2D, frameBuffer.getTextureID()); + + context->copyTexture (getLocalBounds(), + Rectangle (frameBuffer.getWidth(), frameBuffer.getHeight()), + getAlpha()); + + glBindTexture (GL_TEXTURE_2D, 0); } swapBuffers(); diff --git a/modules/juce_opengl/opengl/juce_OpenGLContext.cpp b/modules/juce_opengl/opengl/juce_OpenGLContext.cpp new file mode 100644 index 0000000000..129142c520 --- /dev/null +++ b/modules/juce_opengl/opengl/juce_OpenGLContext.cpp @@ -0,0 +1,256 @@ +/* + ============================================================================== + + 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. + + ============================================================================== +*/ + +OpenGLPixelFormat::OpenGLPixelFormat (const int bitsPerRGBComponent, + const int alphaBits_, + const int depthBufferBits_, + const int stencilBufferBits_) noexcept + : redBits (bitsPerRGBComponent), + greenBits (bitsPerRGBComponent), + blueBits (bitsPerRGBComponent), + alphaBits (alphaBits_), + depthBufferBits (depthBufferBits_), + stencilBufferBits (stencilBufferBits_), + accumulationBufferRedBits (0), + accumulationBufferGreenBits (0), + accumulationBufferBlueBits (0), + accumulationBufferAlphaBits (0), + multisamplingLevel (0) +{ +} + +OpenGLPixelFormat::OpenGLPixelFormat (const OpenGLPixelFormat& other) noexcept + : redBits (other.redBits), + greenBits (other.greenBits), + blueBits (other.blueBits), + alphaBits (other.alphaBits), + depthBufferBits (other.depthBufferBits), + stencilBufferBits (other.stencilBufferBits), + accumulationBufferRedBits (other.accumulationBufferRedBits), + accumulationBufferGreenBits (other.accumulationBufferGreenBits), + accumulationBufferBlueBits (other.accumulationBufferBlueBits), + accumulationBufferAlphaBits (other.accumulationBufferAlphaBits), + multisamplingLevel (other.multisamplingLevel) +{ +} + +OpenGLPixelFormat& OpenGLPixelFormat::operator= (const OpenGLPixelFormat& other) noexcept +{ + redBits = other.redBits; + greenBits = other.greenBits; + blueBits = other.blueBits; + alphaBits = other.alphaBits; + depthBufferBits = other.depthBufferBits; + stencilBufferBits = other.stencilBufferBits; + accumulationBufferRedBits = other.accumulationBufferRedBits; + accumulationBufferGreenBits = other.accumulationBufferGreenBits; + accumulationBufferBlueBits = other.accumulationBufferBlueBits; + accumulationBufferAlphaBits = other.accumulationBufferAlphaBits; + multisamplingLevel = other.multisamplingLevel; + return *this; +} + +bool OpenGLPixelFormat::operator== (const OpenGLPixelFormat& other) const noexcept +{ + return redBits == other.redBits + && greenBits == other.greenBits + && blueBits == other.blueBits + && alphaBits == other.alphaBits + && depthBufferBits == other.depthBufferBits + && stencilBufferBits == other.stencilBufferBits + && accumulationBufferRedBits == other.accumulationBufferRedBits + && accumulationBufferGreenBits == other.accumulationBufferGreenBits + && accumulationBufferBlueBits == other.accumulationBufferBlueBits + && accumulationBufferAlphaBits == other.accumulationBufferAlphaBits + && multisamplingLevel == other.multisamplingLevel; +} + +//============================================================================== +static Array knownContexts; + +OpenGLContext::OpenGLContext() noexcept + : shaderLanguageVersion (0) +{ + knownContexts.add (this); +} + +OpenGLContext::~OpenGLContext() +{ + knownContexts.removeValue (this); +} + +OpenGLContext* OpenGLContext::getCurrentContext() +{ + for (int i = knownContexts.size(); --i >= 0;) + { + OpenGLContext* const oglc = knownContexts.getUnchecked(i); + + if (oglc->isActive()) + return oglc; + } + + return nullptr; +} + +#if JUCE_USE_OPENGL_SHADERS +double OpenGLContext::getShaderLanguageVersion() +{ + if (shaderLanguageVersion == 0) + shaderLanguageVersion = OpenGLShaderProgram::getLanguageVersion(); + + return shaderLanguageVersion; +} +#endif + +void OpenGLContext::copyTexture (const Rectangle& targetClipArea, + const Rectangle& anchorPosAndTextureSize, + float alpha) +{ + glBlendFunc (GL_ONE, GL_ONE_MINUS_SRC_ALPHA); + glEnable (GL_BLEND); + glColor4f (1.0f, 1.0f, 1.0f, alpha); + + const GLshort y = (GLshort) (getHeight() - anchorPosAndTextureSize.getHeight()); + const GLshort width = (GLshort) anchorPosAndTextureSize.getWidth(); + const GLshort bottom = (GLshort) (y + anchorPosAndTextureSize.getHeight()); + const GLshort vertices[] = { 0, y, width, y, 0, bottom, width, bottom }; + + #if JUCE_USE_OPENGL_SHADERS + if (getShaderLanguageVersion() > 1.199) + { + struct OverlayShaderProgram : public ReferenceCountedObject + { + OverlayShaderProgram (OpenGLContext& context) + : program (context), + builder (program), + params (program) + {} + + static const OverlayShaderProgram& select (OpenGLContext& context) + { + static const Identifier programValueID ("juceGLComponentOverlayShader"); + OverlayShaderProgram* program = dynamic_cast (context.properties [programValueID].getObject()); + + if (program == nullptr) + { + program = new OverlayShaderProgram (context); + context.properties.set (programValueID, var (program)); + } + + program->program.use(); + return *program; + } + + struct ProgramBuilder + { + ProgramBuilder (OpenGLShaderProgram& program) + { + program.addShader ("attribute vec2 position;" + "uniform vec2 screenSize;" + "void main()" + "{" + " vec2 scaled = position / (0.5 * screenSize.xy);" + " gl_Position = vec4 (scaled.x - 1.0, 1.0 - scaled.y, 0, 1.0);" + "}", + GL_VERTEX_SHADER); + + program.addShader ("#version 120\n" + "uniform sampler2D imageTexture;" + "uniform float matrix[6];" + "void main()" + "{" + "vec2 texturePos = mat2 (matrix[0], matrix[3], matrix[1], matrix[4]) * gl_FragCoord.xy" + " + vec2 (matrix[2], matrix[5]);" + "gl_FragColor = gl_Color.a * texture2D (imageTexture, vec2 (texturePos.x, 1.0 - texturePos.y));" + "}", + GL_FRAGMENT_SHADER); + program.link(); + } + }; + + struct Params + { + Params (OpenGLShaderProgram& program) + : positionAttribute (program, "position"), + screenSize (program, "screenSize"), + imageTexture (program, "imageTexture"), + matrix (program, "matrix") + {} + + void set (const int targetWidth, const int targetHeight, const Rectangle& anchorPosAndTextureSize) const + { + const AffineTransform t (AffineTransform::translation (-anchorPosAndTextureSize.getX(), + -anchorPosAndTextureSize.getY()) + .followedBy (AffineTransform::verticalFlip (targetHeight)) + .inverted().scaled (1.0f / anchorPosAndTextureSize.getWidth(), + 1.0f / anchorPosAndTextureSize.getHeight())); + + const GLfloat m[] = { t.mat00, t.mat01, t.mat02, t.mat10, t.mat11, t.mat12 }; + matrix.set (m, 6); + imageTexture.set (0); + screenSize.set (targetWidth, targetHeight); + } + + OpenGLShaderProgram::Attribute positionAttribute; + OpenGLShaderProgram::Uniform screenSize, imageTexture, matrix; + }; + + OpenGLShaderProgram program; + ProgramBuilder builder; + Params params; + }; + + const OverlayShaderProgram& program = OverlayShaderProgram::select (*this); + program.params.set (getWidth(), getHeight(), anchorPosAndTextureSize.toFloat()); + + extensions.glVertexAttribPointer (program.params.positionAttribute.attributeID, 2, GL_SHORT, GL_FALSE, 4, vertices); + extensions.glEnableVertexAttribArray (program.params.positionAttribute.attributeID); + + glDrawArrays (GL_TRIANGLE_STRIP, 0, 4); + + extensions.glUseProgram (0); + } + #if JUCE_USE_OPENGL_FIXED_FUNCTION + else + #endif + #endif + + #if JUCE_USE_OPENGL_FIXED_FUNCTION + { + OpenGLHelpers::prepareFor2D (getWidth(), getHeight()); + + glDisableClientState (GL_COLOR_ARRAY); + glDisableClientState (GL_NORMAL_ARRAY); + glEnableClientState (GL_VERTEX_ARRAY); + glEnableClientState (GL_TEXTURE_COORD_ARRAY); + + const GLfloat textureCoords[] = { 0, 0, 1.0f, 0, 0, 1.0f, 1.0f, 1.0f }; + glTexCoordPointer (2, GL_FLOAT, 0, textureCoords); + glVertexPointer (2, GL_SHORT, 0, vertices); + + glDrawArrays (GL_TRIANGLE_STRIP, 0, 4); + } + #endif +} diff --git a/modules/juce_opengl/opengl/juce_OpenGLContext.h b/modules/juce_opengl/opengl/juce_OpenGLContext.h index e83089ac1b..2a7a57b6eb 100644 --- a/modules/juce_opengl/opengl/juce_OpenGLContext.h +++ b/modules/juce_opengl/opengl/juce_OpenGLContext.h @@ -77,15 +77,10 @@ public: */ virtual void* getRawContext() const noexcept = 0; - /** Deletes the context. - - This must only be called on the message thread, or will deadlock. - On background threads, call getCurrentContext()->deleteContext(), but be careful not - to call any other OpenGL function afterwards. - This doesn't touch other resources, such as window handles, etc. - You'll probably never have to call this method directly. - */ - virtual void deleteContext() = 0; + /** Returns the width of this context */ + virtual int getWidth() const = 0; + /** Returns the height of this context */ + virtual int getHeight() const = 0; /** If this context is backed by a frame buffer, this returns its ID number, or 0 if the context has no accessible framebuffer. @@ -108,11 +103,26 @@ public: /** This structure holds a set of dynamically loaded GL functions for use on this context. */ OpenGLExtensionFunctions extensions; + //============================================================================== + /** Draws the currently selected texture into this context at its original size. + @param targetClipArea the target area to draw into (in top-left origin coords) + @param anchorPosAndTextureSize the position of this rectangle is the texture's top-left + anchor position in the target space, and the size must be + the total size of the texture. + */ + void copyTexture (const Rectangle& targetClipArea, + const Rectangle& anchorPosAndTextureSize, + float alpha); + protected: //============================================================================== OpenGLContext() noexcept; private: + double shaderLanguageVersion; + + double getShaderLanguageVersion(); + JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (OpenGLContext); }; diff --git a/modules/juce_opengl/opengl/juce_OpenGLFrameBuffer.cpp b/modules/juce_opengl/opengl/juce_OpenGLFrameBuffer.cpp index d869898e34..fbb9aa817d 100644 --- a/modules/juce_opengl/opengl/juce_OpenGLFrameBuffer.cpp +++ b/modules/juce_opengl/opengl/juce_OpenGLFrameBuffer.cpp @@ -26,7 +26,7 @@ class OpenGLFrameBuffer::Pimpl { public: - Pimpl (const OpenGLContext& context_, const int width_, const int height_, + Pimpl (OpenGLContext& context_, const int width_, const int height_, const bool wantsDepthBuffer, const bool wantsStencilBuffer) : context (context_), width (width_), @@ -106,7 +106,7 @@ public: void bind() { context.extensions.glBindFramebuffer (GL_FRAMEBUFFER, frameBufferHandle); } void unbind() { context.extensions.glBindFramebuffer (GL_FRAMEBUFFER, 0); } - const OpenGLContext& context; + OpenGLContext& context; const int width, height; GLuint textureID, frameBufferHandle, depthOrStencilBuffer; bool hasDepthBuffer, hasStencilBuffer, ok; @@ -134,7 +134,7 @@ public: buffer.readPixels (data, Rectangle (w, h)); } - bool restore (const OpenGLContext& context, OpenGLFrameBuffer& buffer) + bool restore (OpenGLContext& context, OpenGLFrameBuffer& buffer) { if (buffer.initialise (context, width, height)) { @@ -156,7 +156,7 @@ private: OpenGLFrameBuffer::OpenGLFrameBuffer() {} OpenGLFrameBuffer::~OpenGLFrameBuffer() {} -bool OpenGLFrameBuffer::initialise (const OpenGLContext& context, int width, int height) +bool OpenGLFrameBuffer::initialise (OpenGLContext& context, int width, int height) { jassert (context.isActive()); // The context must be active when creating a framebuffer! @@ -169,7 +169,7 @@ bool OpenGLFrameBuffer::initialise (const OpenGLContext& context, int width, int return pimpl != nullptr; } -bool OpenGLFrameBuffer::initialise (const OpenGLContext& context, const Image& image) +bool OpenGLFrameBuffer::initialise (OpenGLContext& context, const Image& image) { if (! image.isARGB()) return initialise (context, image.convertedToFormat (Image::ARGB)); @@ -180,7 +180,7 @@ bool OpenGLFrameBuffer::initialise (const OpenGLContext& context, const Image& i && writePixels ((const PixelARGB*) bitmap.data, image.getBounds()); } -bool OpenGLFrameBuffer::initialise (const OpenGLFrameBuffer& other) +bool OpenGLFrameBuffer::initialise (OpenGLFrameBuffer& other) { const Pimpl* const p = other.pimpl; @@ -190,15 +190,18 @@ bool OpenGLFrameBuffer::initialise (const OpenGLFrameBuffer& other) return true; } - if (initialise (p->context, p->width, p->height)) + const Rectangle area (pimpl->width, pimpl->height); + + if (initialise (p->context, area.getWidth(), area.getHeight())) { pimpl->bind(); - OpenGLHelpers::prepareFor2D (p->width, p->height); - glDisable (GL_BLEND); - glColor4f (1.0f, 1.0f, 1.0f, 1.0f); - other.drawAt (0, 0); - pimpl->unbind(); + glEnable (GL_TEXTURE_2D); + glBindTexture (GL_TEXTURE_2D, p->textureID); + pimpl->context.copyTexture (area, area, 1.0f); + glBindTexture (GL_TEXTURE_2D, 0); + + pimpl->unbind(); return true; } @@ -220,7 +223,7 @@ void OpenGLFrameBuffer::saveAndRelease() } } -bool OpenGLFrameBuffer::reloadSavedCopy (const OpenGLContext& context) +bool OpenGLFrameBuffer::reloadSavedCopy (OpenGLContext& context) { if (savedState != nullptr) { @@ -300,15 +303,14 @@ bool OpenGLFrameBuffer::writePixels (const PixelARGB* data, const Rectangle if (! makeCurrentRenderingTarget()) return false; - OpenGLHelpers::prepareFor2D (pimpl->width, pimpl->height); glDisable (GL_DEPTH_TEST); glDisable (GL_BLEND); OpenGLTexture tex; tex.loadARGBFlipped (data, area.getWidth(), area.getHeight()); - const int texH = tex.getHeight(); #if JUCE_OPENGL_ES + const int texH = tex.getHeight(); tex.bind(); const GLint cropRect[4] = { 0, texH - area.getHeight(), area.getWidth(), area.getHeight() }; glTexParameteriv (GL_TEXTURE_2D, GL_TEXTURE_CROP_RECT_OES, cropRect); @@ -317,28 +319,14 @@ bool OpenGLFrameBuffer::writePixels (const PixelARGB* data, const Rectangle glDrawTexiOES (area.getX(), area.getY(), 1, area.getWidth(), area.getHeight()); glBindTexture (GL_TEXTURE_2D, 0); #else - glTexParameterf (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - glTexParameterf (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - glTexParameterf (GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - glTexParameterf (GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - glColor4f (1.0f, 1.0f, 1.0f, 1.0f); - - const int x = area.getX(); - const int y = area.getY() - (texH - area.getHeight()); - const GLfloat x1 = (GLfloat) x; - const GLfloat y1 = (GLfloat) y; - const GLfloat x2 = (GLfloat) (x + tex.getWidth()); - const GLfloat y2 = (GLfloat) (y + texH); - const GLfloat vertices[] = { x1, y1, x2, y1, x1, y2, x2, y2 }; - const GLfloat textureCoords[] = { 0, 0, 1.0f, 0, 0, 1.0f, 1.0f, 1.0f }; - - OpenGLHelpers::drawTriangleStrip (vertices, textureCoords, 4, tex.getTextureID()); + pimpl->context.copyTexture (area, area, 1.0f); #endif pimpl->context.extensions.glBindFramebuffer (GL_FRAMEBUFFER, 0); return true; } +#if JUCE_USE_OPENGL_FIXED_FUNCTION void OpenGLFrameBuffer::draw2D (float x1, float y1, float x2, float y2, float x3, float y3, @@ -394,3 +382,4 @@ void OpenGLFrameBuffer::drawAt (float x1, float y1) const glBindTexture (GL_TEXTURE_2D, 0); } } +#endif diff --git a/modules/juce_opengl/opengl/juce_OpenGLFrameBuffer.h b/modules/juce_opengl/opengl/juce_OpenGLFrameBuffer.h index 677b74a24d..44b694c9bd 100644 --- a/modules/juce_opengl/opengl/juce_OpenGLFrameBuffer.h +++ b/modules/juce_opengl/opengl/juce_OpenGLFrameBuffer.h @@ -47,17 +47,17 @@ public: Note that a valid openGL context must be selected when you call this method, or it will fail. */ - bool initialise (const OpenGLContext& context, int width, int height); + bool initialise (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 OpenGLContext& context, const Image& content); + bool initialise (OpenGLContext& context, const Image& content); /** Tries to allocate a copy of another framebuffer. */ - bool initialise (const OpenGLFrameBuffer& other); + bool initialise (OpenGLFrameBuffer& other); /** Releases the buffer, if one has been allocated. Any saved state that was created with saveAndRelease() will also be freed by this call. @@ -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 (const OpenGLContext& context); + bool reloadSavedCopy (OpenGLContext& context); //============================================================================== /** Returns true if a valid buffer has been allocated. */ @@ -104,6 +104,7 @@ public: /** Selects the framebuffer as the current target, and clears it to transparent. */ void makeCurrentAndClear(); + #if JUCE_USE_OPENGL_FIXED_FUNCTION /** Draws this framebuffer onto the current context, with the specified corner positions. */ void draw2D (float x1, float y1, float x2, float y2, @@ -120,6 +121,7 @@ public: /** Draws the framebuffer at a given position. */ void drawAt (float x1, float y1) const; + #endif /** 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 diff --git a/modules/juce_opengl/opengl/juce_OpenGLGraphicsContext.cpp b/modules/juce_opengl/opengl/juce_OpenGLGraphicsContext.cpp index a002069859..81150f80ce 100644 --- a/modules/juce_opengl/opengl/juce_OpenGLGraphicsContext.cpp +++ b/modules/juce_opengl/opengl/juce_OpenGLGraphicsContext.cpp @@ -199,7 +199,7 @@ private: class ShaderPrograms : public ReferenceCountedObject { public: - ShaderPrograms (const OpenGLContext& context) + ShaderPrograms (OpenGLContext& context) : solidColourProgram (context), solidColourMasked (context), radialGradient (context), @@ -221,7 +221,7 @@ public: //============================================================================== struct ShaderProgramHolder { - ShaderProgramHolder (const OpenGLContext& context, const char* fragmentShader) + ShaderProgramHolder (OpenGLContext& context, const char* fragmentShader) : program (context) { program.addShader ("attribute vec2 position;" @@ -243,7 +243,7 @@ public: struct ShaderBase : public ShaderProgramHolder { - ShaderBase (const OpenGLContext& context, const char* fragmentShader) + ShaderBase (OpenGLContext& context, const char* fragmentShader) : ShaderProgramHolder (context, fragmentShader), positionAttribute (program, "position"), colourAttribute (program, "colour"), @@ -255,7 +255,7 @@ public: screenBounds.set (bounds.getX(), bounds.getY(), 0.5f * bounds.getWidth(), 0.5f * bounds.getHeight()); } - void bindAttributes (const OpenGLContext& context) + void bindAttributes (OpenGLContext& context) { 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); @@ -271,7 +271,7 @@ public: struct MaskedShaderParams { - MaskedShaderParams (const OpenGLShaderProgram& program) + MaskedShaderParams (OpenGLShaderProgram& program) : maskTexture (program, "maskTexture"), maskBounds (program, "maskBounds") {} @@ -290,7 +290,7 @@ public: //============================================================================== struct SolidColourProgram : public ShaderBase { - SolidColourProgram (const OpenGLContext& context) + SolidColourProgram (OpenGLContext& context) : ShaderBase (context, "void main()" "{" " gl_FragColor = gl_Color;" @@ -307,7 +307,7 @@ public: struct SolidColourMaskedProgram : public ShaderBase { - SolidColourMaskedProgram (const OpenGLContext& context) + SolidColourMaskedProgram (OpenGLContext& context) : ShaderBase (context, JUCE_DECLARE_SHADER_VERSION JUCE_DECLARE_MASK_UNIFORMS "void main()" @@ -323,7 +323,7 @@ public: //============================================================================== struct RadialGradientParams { - RadialGradientParams (const OpenGLShaderProgram& program) + RadialGradientParams (OpenGLShaderProgram& program) : gradientTexture (program, "gradientTexture"), matrix (program, "matrix") {} @@ -342,14 +342,13 @@ public: #define JUCE_DECLARE_MATRIX_UNIFORM "uniform float matrix[6];" #define JUCE_DECLARE_RADIAL_UNIFORMS "uniform sampler2D gradientTexture;" JUCE_DECLARE_MATRIX_UNIFORM - #define JUCE_MATRIX_TIMES_FRAGCOORD "(vec2 (matrix[0], matrix[3]) * gl_FragCoord.x" \ - " + vec2 (matrix[1], matrix[4]) * gl_FragCoord.y " \ + #define JUCE_MATRIX_TIMES_FRAGCOORD "(mat2 (matrix[0], matrix[3], matrix[1], matrix[4]) * gl_FragCoord.xy" \ " + vec2 (matrix[2], matrix[5]))" #define JUCE_GET_TEXTURE_COLOUR "(gl_Color.a * texture2D (gradientTexture, vec2 (gradientPos, 0.5)))" struct RadialGradientProgram : public ShaderBase { - RadialGradientProgram (const OpenGLContext& context) + RadialGradientProgram (OpenGLContext& context) : ShaderBase (context, JUCE_DECLARE_SHADER_VERSION JUCE_DECLARE_RADIAL_UNIFORMS "void main()" @@ -365,7 +364,7 @@ public: struct RadialGradientMaskedProgram : public ShaderBase { - RadialGradientMaskedProgram (const OpenGLContext& context) + RadialGradientMaskedProgram (OpenGLContext& context) : ShaderBase (context, JUCE_DECLARE_SHADER_VERSION JUCE_DECLARE_RADIAL_UNIFORMS JUCE_DECLARE_MASK_UNIFORMS @@ -385,7 +384,7 @@ public: //============================================================================== struct LinearGradientParams { - LinearGradientParams (const OpenGLShaderProgram& program) + LinearGradientParams (OpenGLShaderProgram& program) : gradientTexture (program, "gradientTexture"), gradientInfo (program, "gradientInfo") {} @@ -400,7 +399,7 @@ public: struct LinearGradient1Program : public ShaderBase { - LinearGradient1Program (const OpenGLContext& context) + LinearGradient1Program (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()" @@ -416,7 +415,7 @@ public: struct LinearGradient1MaskedProgram : public ShaderBase { - LinearGradient1MaskedProgram (const OpenGLContext& context) + LinearGradient1MaskedProgram (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 @@ -435,7 +434,7 @@ public: struct LinearGradient2Program : public ShaderBase { - LinearGradient2Program (const OpenGLContext& context) + LinearGradient2Program (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()" @@ -451,7 +450,7 @@ public: struct LinearGradient2MaskedProgram : public ShaderBase { - LinearGradient2MaskedProgram (const OpenGLContext& context) + LinearGradient2MaskedProgram (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 @@ -471,7 +470,7 @@ public: //============================================================================== struct ImageParams { - ImageParams (const OpenGLShaderProgram& program) + ImageParams (OpenGLShaderProgram& program) : imageTexture (program, "imageTexture"), matrix (program, "matrix"), imageRepeatSize (program, "imageRepeatSize") @@ -511,7 +510,7 @@ public: struct ImageProgram : public ShaderBase { - ImageProgram (const OpenGLContext& context) + ImageProgram (OpenGLContext& context) : ShaderBase (context, JUCE_DECLARE_SHADER_VERSION JUCE_DECLARE_IMAGE_UNIFORMS "void main()" @@ -527,7 +526,7 @@ public: struct ImageMaskedProgram : public ShaderBase { - ImageMaskedProgram (const OpenGLContext& context) + ImageMaskedProgram (OpenGLContext& context) : ShaderBase (context, JUCE_DECLARE_SHADER_VERSION JUCE_DECLARE_IMAGE_UNIFORMS JUCE_DECLARE_MASK_UNIFORMS @@ -546,7 +545,7 @@ public: struct TiledImageProgram : public ShaderBase { - TiledImageProgram (const OpenGLContext& context) + TiledImageProgram (OpenGLContext& context) : ShaderBase (context, JUCE_DECLARE_SHADER_VERSION JUCE_DECLARE_IMAGE_UNIFORMS "void main()" @@ -562,7 +561,7 @@ public: struct TiledImageMaskedProgram : public ShaderBase { - TiledImageMaskedProgram (const OpenGLContext& context) + TiledImageMaskedProgram (OpenGLContext& context) : ShaderBase (context, JUCE_DECLARE_SHADER_VERSION JUCE_DECLARE_IMAGE_UNIFORMS JUCE_DECLARE_MASK_UNIFORMS @@ -581,7 +580,7 @@ public: struct CopyTextureProgram : public ShaderBase { - CopyTextureProgram (const OpenGLContext& context) + CopyTextureProgram (OpenGLContext& context) : ShaderBase (context, JUCE_DECLARE_SHADER_VERSION JUCE_DECLARE_IMAGE_UNIFORMS "void main()" @@ -597,7 +596,7 @@ public: struct MaskTextureProgram : public ShaderBase { - MaskTextureProgram (const OpenGLContext& context) + MaskTextureProgram (OpenGLContext& context) : ShaderBase (context, JUCE_DECLARE_SHADER_VERSION JUCE_DECLARE_IMAGE_UNIFORMS "void main()" @@ -1237,7 +1236,7 @@ struct StateHelpers { quadQueue.flush(); activeShader = &(shader.program); - context.extensions.glUseProgram (shader.program.programID); + shader.program.use(); shader.bindAttributes (context); currentBounds = bounds; @@ -1351,6 +1350,10 @@ public: #if JUCE_USE_OPENGL_FIXED_FUNCTION resetMultiTextureModes (true); #endif + + #if JUCE_USE_OPENGL_SHADERS + glDisableClientState (GL_INDEX_ARRAY); + #endif } void flush() diff --git a/modules/juce_opengl/opengl/juce_OpenGLShaderProgram.cpp b/modules/juce_opengl/opengl/juce_OpenGLShaderProgram.cpp index a43d5ed487..89c2711ff3 100644 --- a/modules/juce_opengl/opengl/juce_OpenGLShaderProgram.cpp +++ b/modules/juce_opengl/opengl/juce_OpenGLShaderProgram.cpp @@ -80,6 +80,11 @@ void OpenGLShaderProgram::link() noexcept #endif } +void OpenGLShaderProgram::use() const noexcept +{ + context.extensions.glUseProgram (programID); +} + OpenGLShaderProgram::Uniform::Uniform (const OpenGLShaderProgram& program, const char* const name) : uniformID (program.context.extensions.glGetUniformLocation (program.programID, name)), context (program.context) { diff --git a/modules/juce_opengl/opengl/juce_OpenGLShaderProgram.h b/modules/juce_opengl/opengl/juce_OpenGLShaderProgram.h index dba7873b5d..837739353f 100644 --- a/modules/juce_opengl/opengl/juce_OpenGLShaderProgram.h +++ b/modules/juce_opengl/opengl/juce_OpenGLShaderProgram.h @@ -65,6 +65,9 @@ public: */ void link() noexcept; + /** Selects this program into the current context. */ + void use() const noexcept; + /** Represents an openGL uniform value. After a program has been linked, you can create Uniform objects to let you set the uniforms that your shaders use. diff --git a/modules/juce_opengl/opengl/juce_OpenGLTexture.cpp b/modules/juce_opengl/opengl/juce_OpenGLTexture.cpp index b253a262dc..2af7a758a7 100644 --- a/modules/juce_opengl/opengl/juce_OpenGLTexture.cpp +++ b/modules/juce_opengl/opengl/juce_OpenGLTexture.cpp @@ -154,6 +154,7 @@ void OpenGLTexture::unbind() const glBindTexture (GL_TEXTURE_2D, 0); } +#if JUCE_USE_OPENGL_FIXED_FUNCTION void OpenGLTexture::draw2D (float x1, float y1, float x2, float y2, float x3, float y3, @@ -175,3 +176,4 @@ void OpenGLTexture::draw3D (float x1, float y1, float z1, OpenGLHelpers::drawQuad3D (x1, y1, z1, x2, y2, z2, x3, y3, z3, x4, y4, z4, colour); unbind(); } +#endif diff --git a/modules/juce_opengl/opengl/juce_OpenGLTexture.h b/modules/juce_opengl/opengl/juce_OpenGLTexture.h index 180caa030f..cd04ec3c2d 100644 --- a/modules/juce_opengl/opengl/juce_OpenGLTexture.h +++ b/modules/juce_opengl/opengl/juce_OpenGLTexture.h @@ -80,6 +80,7 @@ public: /** Unbinds the texture to the currently selected openGL context. */ void unbind() const; + #if JUCE_USE_OPENGL_FIXED_FUNCTION /** Draws this texture into the current context, with the specified corner positions. */ void draw2D (float x1, float y1, float x2, float y2, @@ -93,6 +94,7 @@ public: float x3, float y3, float z3, float x4, float y4, float z4, const Colour& colour) const; + #endif /** Returns the GL texture ID number. */ GLuint getTextureID() const noexcept { return textureID; }