diff --git a/modules/juce_opengl/juce_opengl.cpp b/modules/juce_opengl/juce_opengl.cpp index 1e7c537700..6659423a09 100644 --- a/modules/juce_opengl/juce_opengl.cpp +++ b/modules/juce_opengl/juce_opengl.cpp @@ -144,6 +144,16 @@ void OpenGLExtensionFunctions::initialise() #undef JUCE_GL_EXTENSION_FUNCTIONS +#if JUCE_OPENGL_ES + #define JUCE_LOWP "lowp" + #define JUCE_MEDIUMP "mediump" + #define JUCE_HIGHP "highp" +#else + #define JUCE_LOWP + #define JUCE_MEDIUMP + #define JUCE_HIGHP +#endif + //============================================================================== // START_AUTOINCLUDE opengl/*.cpp #include "opengl/juce_OpenGLComponent.cpp" diff --git a/modules/juce_opengl/native/juce_OpenGLExtensions.h b/modules/juce_opengl/native/juce_OpenGLExtensions.h index da66e897ec..89c5931109 100644 --- a/modules/juce_opengl/native/juce_OpenGLExtensions.h +++ b/modules/juce_opengl/native/juce_OpenGLExtensions.h @@ -32,7 +32,6 @@ */ #define JUCE_GL_BASIC_EXTENSION_FUNCTIONS(USE_FUNCTION) \ USE_FUNCTION (glActiveTexture, void, (GLenum p1), (p1))\ - USE_FUNCTION (glClientActiveTexture, void, (GLenum 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))\ @@ -54,7 +53,7 @@ USE_FUNCTION (glGetFramebufferAttachmentParameteriv, void, (GLenum p1, GLenum p2, GLenum p3, GLint* p4), (p1, p2, p3, p4)) #if JUCE_USE_OPENGL_SHADERS - #define JUCE_GL_EXTENSION_FUNCTIONS(USE_FUNCTION) JUCE_GL_BASIC_EXTENSION_FUNCTIONS(USE_FUNCTION) \ + #define JUCE_GL_EXTENSION_FUNCTIONS1(USE_FUNCTION) JUCE_GL_BASIC_EXTENSION_FUNCTIONS(USE_FUNCTION) \ USE_FUNCTION (glCreateProgram, GLuint, (), ())\ USE_FUNCTION (glDeleteProgram, void, (GLuint p1), (p1))\ USE_FUNCTION (glCreateShader, GLuint, (GLenum p1), (p1))\ @@ -79,7 +78,14 @@ 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)) #else - #define JUCE_GL_EXTENSION_FUNCTIONS(USE_FUNCTION) JUCE_GL_BASIC_EXTENSION_FUNCTIONS(USE_FUNCTION) + #define JUCE_GL_EXTENSION_FUNCTIONS1(USE_FUNCTION) JUCE_GL_BASIC_EXTENSION_FUNCTIONS(USE_FUNCTION) +#endif + +#if JUCE_USE_OPENGL_FIXED_FUNCTION + #define JUCE_GL_EXTENSION_FUNCTIONS(USE_FUNCTION) JUCE_GL_EXTENSION_FUNCTIONS1(USE_FUNCTION) \ + USE_FUNCTION (glClientActiveTexture, void, (GLenum p1), (p1)) +#else + #define JUCE_GL_EXTENSION_FUNCTIONS(USE_FUNCTION) JUCE_GL_EXTENSION_FUNCTIONS1(USE_FUNCTION) #endif /** This class contains a generated list of OpenGL extension functions, which are either dynamically loaded diff --git a/modules/juce_opengl/native/juce_ios_OpenGLComponent.mm b/modules/juce_opengl/native/juce_ios_OpenGLComponent.mm index e6f3188d3b..47089af298 100644 --- a/modules/juce_opengl/native/juce_ios_OpenGLComponent.mm +++ b/modules/juce_opengl/native/juce_ios_OpenGLComponent.mm @@ -48,9 +48,9 @@ public: Component* const component_, const OpenGLPixelFormat& pixelFormat, const GLESContext* const sharedContext, - NSUInteger apiType) + const bool isGLES2_) : component (component_), glLayer (nil), context (nil), - useDepthBuffer (pixelFormat.depthBufferBits > 0), + useDepthBuffer (pixelFormat.depthBufferBits > 0), isGLES2 (isGLES2_), frameBufferHandle (0), colorBufferHandle (0), depthBufferHandle (0), lastWidth (0), lastHeight (0) { @@ -63,6 +63,9 @@ public: glLayer = (CAEAGLLayer*) [view layer]; [parentView addSubview: view]; + NSUInteger apiType = isGLES2_ ? kEAGLRenderingAPIOpenGLES2 + : kEAGLRenderingAPIOpenGLES1; + if (sharedContext != nullptr) context = [[EAGLContext alloc] initWithAPI: apiType sharegroup: [sharedContext->context sharegroup]]; @@ -89,14 +92,14 @@ public: jassert (context != nil); [EAGLContext setCurrentContext: context]; - glBindFramebufferOES (GL_FRAMEBUFFER_OES, frameBufferHandle); + glBindFramebuffer (GL_FRAMEBUFFER, frameBufferHandle); return true; } void swapBuffers() { - glBindRenderbufferOES (GL_RENDERBUFFER_OES, colorBufferHandle); - [context presentRenderbuffer: GL_RENDERBUFFER_OES]; + glBindRenderbuffer (GL_RENDERBUFFER, colorBufferHandle); + [context presentRenderbuffer: GL_RENDERBUFFER]; } bool makeInactive() const noexcept @@ -104,10 +107,7 @@ public: return [EAGLContext setCurrentContext: nil]; } - bool isActive() const noexcept - { - return [EAGLContext currentContext] == context; - } + bool isActive() const noexcept { return [EAGLContext currentContext] == context; } void* getRawContext() const noexcept { return glLayer; } unsigned int getFrameBufferID() const { return (unsigned int) frameBufferHandle; } @@ -115,6 +115,8 @@ public: int getWidth() const { return lastWidth; } int getHeight() const { return lastHeight; } + bool areShadersAvailable() const { return isGLES2; } + void updateWindowPosition (const Rectangle& bounds) { // For some strange reason, the view seems to fail unless its width is a multiple of 8... @@ -147,54 +149,54 @@ public: { makeActive(); - glGenFramebuffersOES (1, &frameBufferHandle); - glGenRenderbuffersOES (1, &colorBufferHandle); - glGenRenderbuffersOES (1, &depthBufferHandle); + glGenFramebuffers (1, &frameBufferHandle); + glGenRenderbuffers (1, &colorBufferHandle); + glGenRenderbuffers (1, &depthBufferHandle); - glBindRenderbufferOES (GL_RENDERBUFFER_OES, colorBufferHandle); - bool ok = [context renderbufferStorage: GL_RENDERBUFFER_OES fromDrawable: glLayer]; + glBindRenderbuffer (GL_RENDERBUFFER, colorBufferHandle); + bool ok = [context renderbufferStorage: GL_RENDERBUFFER fromDrawable: glLayer]; jassert (ok); (void) ok; GLint width, height; - glGetRenderbufferParameterivOES (GL_RENDERBUFFER_OES, GL_RENDERBUFFER_WIDTH_OES, &width); - glGetRenderbufferParameterivOES (GL_RENDERBUFFER_OES, GL_RENDERBUFFER_HEIGHT_OES, &height); + glGetRenderbufferParameteriv (GL_RENDERBUFFER, GL_RENDERBUFFER_WIDTH, &width); + glGetRenderbufferParameteriv (GL_RENDERBUFFER, GL_RENDERBUFFER_HEIGHT, &height); if (useDepthBuffer) { - glBindRenderbufferOES (GL_RENDERBUFFER_OES, depthBufferHandle); - glRenderbufferStorageOES (GL_RENDERBUFFER_OES, GL_DEPTH_COMPONENT16_OES, width, height); + glBindRenderbuffer (GL_RENDERBUFFER, depthBufferHandle); + glRenderbufferStorage (GL_RENDERBUFFER, GL_DEPTH_COMPONENT16, width, height); } - glBindRenderbufferOES (GL_RENDERBUFFER_OES, colorBufferHandle); + glBindRenderbuffer (GL_RENDERBUFFER, colorBufferHandle); - glBindFramebufferOES (GL_FRAMEBUFFER_OES, frameBufferHandle); - glFramebufferRenderbufferOES (GL_FRAMEBUFFER_OES, GL_COLOR_ATTACHMENT0_OES, GL_RENDERBUFFER_OES, colorBufferHandle); + glBindFramebuffer (GL_FRAMEBUFFER, frameBufferHandle); + glFramebufferRenderbuffer (GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, colorBufferHandle); if (useDepthBuffer) - glFramebufferRenderbufferOES (GL_FRAMEBUFFER_OES, GL_DEPTH_ATTACHMENT_OES, GL_RENDERBUFFER_OES, depthBufferHandle); + glFramebufferRenderbuffer (GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, depthBufferHandle); - jassert (glCheckFramebufferStatusOES (GL_FRAMEBUFFER_OES) == GL_FRAMEBUFFER_COMPLETE_OES); + jassert (glCheckFramebufferStatus (GL_FRAMEBUFFER) == GL_FRAMEBUFFER_COMPLETE); } void freeGLBuffers() { - [context renderbufferStorage: GL_RENDERBUFFER_OES fromDrawable: nil]; + [context renderbufferStorage: GL_RENDERBUFFER fromDrawable: nil]; if (frameBufferHandle != 0) { - glDeleteFramebuffersOES (1, &frameBufferHandle); + glDeleteFramebuffers (1, &frameBufferHandle); frameBufferHandle = 0; } if (colorBufferHandle != 0) { - glDeleteRenderbuffersOES (1, &colorBufferHandle); + glDeleteRenderbuffers (1, &colorBufferHandle); colorBufferHandle = 0; } if (depthBufferHandle != 0) { - glDeleteRenderbuffersOES (1, &depthBufferHandle); + glDeleteRenderbuffers (1, &depthBufferHandle); depthBufferHandle = 0; } } @@ -204,7 +206,7 @@ private: JuceGLView* view; CAEAGLLayer* glLayer; EAGLContext* context; - bool useDepthBuffer; + bool useDepthBuffer, isGLES2; GLuint frameBufferHandle, colorBufferHandle, depthBufferHandle; int numFrames; int lastWidth, lastHeight; @@ -221,8 +223,7 @@ OpenGLContext* OpenGLComponent::createContext() if (peer != nullptr) return new GLESContext ((UIView*) peer->getNativeHandle(), this, preferredPixelFormat, dynamic_cast (contextToShareListsWith), - (flags & openGLES2) == 0 ? kEAGLRenderingAPIOpenGLES1 - : kEAGLRenderingAPIOpenGLES2); + (flags & openGLES2) != 0); return nullptr; } diff --git a/modules/juce_opengl/opengl/juce_OpenGLComponent.cpp b/modules/juce_opengl/opengl/juce_OpenGLComponent.cpp index c8e5c28fcf..5c567f9804 100644 --- a/modules/juce_opengl/opengl/juce_OpenGLComponent.cpp +++ b/modules/juce_opengl/opengl/juce_OpenGLComponent.cpp @@ -103,11 +103,7 @@ public: const int fbW = frameBuffer.getWidth(); const int fbH = frameBuffer.getHeight(); - if (fbW < width - || fbH < height - || fbW > width + 128 - || fbH > height + 128 - || ! frameBuffer.isValid()) + if (fbW != width || fbH != height || ! frameBuffer.isValid()) { jassert (owner.getCurrentContext() != nullptr); frameBuffer.initialise (*owner.getCurrentContext(), width, height); @@ -427,27 +423,27 @@ bool OpenGLComponent::performRender() { jassert (getCurrentContext() != nullptr); - OpenGLGraphicsContext g (*getCurrentContext(), frameBuffer); - g.clipToRectangleList (invalid); + { + OpenGLGraphicsContext g (*getCurrentContext(), frameBuffer); + g.clipToRectangleList (invalid); - g.setFill (Colours::transparentBlack); - g.fillRect (bounds, true); - g.setFill (Colours::black); + g.setFill (Colours::transparentBlack); + g.fillRect (bounds, true); + g.setFill (Colours::black); - paintSelf (g); + paintSelf (g); + } makeCurrentRenderingTarget(); } } glEnable (GL_TEXTURE_2D); - glActiveTexture (GL_TEXTURE0); + context->extensions.glActiveTexture (GL_TEXTURE0); glBindTexture (GL_TEXTURE_2D, frameBuffer.getTextureID()); - context->copyTexture (getLocalBounds(), - Rectangle (frameBuffer.getWidth(), frameBuffer.getHeight()), - getAlpha()); - + context->copyTexture (bounds, Rectangle (bounds.getWidth(), + bounds.getHeight())); glBindTexture (GL_TEXTURE_2D, 0); } diff --git a/modules/juce_opengl/opengl/juce_OpenGLContext.cpp b/modules/juce_opengl/opengl/juce_OpenGLContext.cpp index 129142c520..01b9197aef 100644 --- a/modules/juce_opengl/opengl/juce_OpenGLContext.cpp +++ b/modules/juce_opengl/opengl/juce_OpenGLContext.cpp @@ -91,7 +91,7 @@ bool OpenGLPixelFormat::operator== (const OpenGLPixelFormat& other) const noexce static Array knownContexts; OpenGLContext::OpenGLContext() noexcept - : shaderLanguageVersion (0) + : shaderLanguageAvailable (0) { knownContexts.add (this); } @@ -114,31 +114,26 @@ OpenGLContext* OpenGLContext::getCurrentContext() return nullptr; } -#if JUCE_USE_OPENGL_SHADERS -double OpenGLContext::getShaderLanguageVersion() +bool OpenGLContext::areShadersAvailable() const { - if (shaderLanguageVersion == 0) - shaderLanguageVersion = OpenGLShaderProgram::getLanguageVersion(); + #if JUCE_USE_OPENGL_SHADERS + if (shaderLanguageAvailable == 0) + shaderLanguageAvailable = (OpenGLShaderProgram::getLanguageVersion() > 0) ? 1 : -1; - return shaderLanguageVersion; + return shaderLanguageAvailable > 0; + #else + return false; + #endif } -#endif void OpenGLContext::copyTexture (const Rectangle& targetClipArea, - const Rectangle& anchorPosAndTextureSize, - float alpha) + const Rectangle& anchorPosAndTextureSize) { 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) + if (areShadersAvailable()) { struct OverlayShaderProgram : public ReferenceCountedObject { @@ -167,23 +162,25 @@ void OpenGLContext::copyTexture (const Rectangle& targetClipArea, { ProgramBuilder (OpenGLShaderProgram& program) { - program.addShader ("attribute vec2 position;" - "uniform vec2 screenSize;" + program.addShader ("attribute " JUCE_HIGHP " vec2 position;" + "uniform " JUCE_HIGHP " vec2 screenSize;" + "varying " JUCE_HIGHP " vec2 pixelPos;" "void main()" "{" - " vec2 scaled = position / (0.5 * screenSize.xy);" - " gl_Position = vec4 (scaled.x - 1.0, 1.0 - scaled.y, 0, 1.0);" + "pixelPos = position;" + JUCE_HIGHP " 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];" + program.addShader ("uniform sampler2D imageTexture;" + "uniform " JUCE_HIGHP " float matrix[6];" + "varying " JUCE_HIGHP " vec2 pixelPos;" "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));" + JUCE_HIGHP " vec2 texturePos = mat2 (matrix[0], matrix[3], matrix[1], matrix[4]) * pixelPos" + " + vec2 (matrix[2], matrix[5]);" + "gl_FragColor = texture2D (imageTexture, vec2 (texturePos.x, 1.0 - texturePos.y));" "}", GL_FRAGMENT_SHADER); program.link(); @@ -199,11 +196,10 @@ void OpenGLContext::copyTexture (const Rectangle& targetClipArea, matrix (program, "matrix") {} - void set (const int targetWidth, const int targetHeight, const Rectangle& anchorPosAndTextureSize) const + void set (const float targetWidth, const float targetHeight, const Rectangle& anchorPosAndTextureSize) const { - const AffineTransform t (AffineTransform::translation (-anchorPosAndTextureSize.getX(), - -anchorPosAndTextureSize.getY()) - .followedBy (AffineTransform::verticalFlip (targetHeight)) + const AffineTransform t (AffineTransform::translation (anchorPosAndTextureSize.getX(), + anchorPosAndTextureSize.getY()) .inverted().scaled (1.0f / anchorPosAndTextureSize.getWidth(), 1.0f / anchorPosAndTextureSize.getHeight())); @@ -222,8 +218,14 @@ void OpenGLContext::copyTexture (const Rectangle& targetClipArea, Params params; }; + const GLshort left = (GLshort) targetClipArea.getX(); + const GLshort top = (GLshort) targetClipArea.getY(); + const GLshort right = (GLshort) targetClipArea.getRight(); + const GLshort bottom = (GLshort) targetClipArea.getBottom(); + const GLshort vertices[] = { left, bottom, right, bottom, left, top, right, top }; + const OverlayShaderProgram& program = OverlayShaderProgram::select (*this); - program.params.set (getWidth(), getHeight(), anchorPosAndTextureSize.toFloat()); + program.params.set ((float) getWidth(), (float) getHeight(), anchorPosAndTextureSize.toFloat()); extensions.glVertexAttribPointer (program.params.positionAttribute.attributeID, 2, GL_SHORT, GL_FALSE, 4, vertices); extensions.glEnableVertexAttribArray (program.params.positionAttribute.attributeID); @@ -239,8 +241,16 @@ void OpenGLContext::copyTexture (const Rectangle& targetClipArea, #if JUCE_USE_OPENGL_FIXED_FUNCTION { + (void) anchorPosAndTextureSize; // xxx need to scissor + const GLshort left = (GLshort) targetClipArea.getX(); + const GLshort right = (GLshort) targetClipArea.getRight(); + const GLshort top = (GLshort) (getHeight() - targetClipArea.getY()); + const GLshort bottom = (GLshort) (getHeight() - targetClipArea.getBottom()); + const GLshort vertices[] = { left, bottom, right, bottom, left, top, right, top }; + OpenGLHelpers::prepareFor2D (getWidth(), getHeight()); + glColor4f (1.0f, 1.0f, 1.0f, 1.0f); glDisableClientState (GL_COLOR_ARRAY); glDisableClientState (GL_NORMAL_ARRAY); glEnableClientState (GL_VERTEX_ARRAY); diff --git a/modules/juce_opengl/opengl/juce_OpenGLContext.h b/modules/juce_opengl/opengl/juce_OpenGLContext.h index 2a7a57b6eb..501c581ec3 100644 --- a/modules/juce_opengl/opengl/juce_OpenGLContext.h +++ b/modules/juce_opengl/opengl/juce_OpenGLContext.h @@ -90,6 +90,9 @@ public: /** Checks whether the current context supports the specified extension. */ bool isExtensionSupported (const char* const extensionName); + /** Returns true if shaders can be used in this context. */ + virtual bool areShadersAvailable() const; + //============================================================================== /** Returns the context that's currently in active use by the calling thread. @@ -111,17 +114,14 @@ public: the total size of the texture. */ void copyTexture (const Rectangle& targetClipArea, - const Rectangle& anchorPosAndTextureSize, - float alpha); + const Rectangle& anchorPosAndTextureSize); protected: //============================================================================== OpenGLContext() noexcept; private: - double shaderLanguageVersion; - - double getShaderLanguageVersion(); + mutable int shaderLanguageAvailable; 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 fbb9aa817d..ebfe1f81f9 100644 --- a/modules/juce_opengl/opengl/juce_OpenGLFrameBuffer.cpp +++ b/modules/juce_opengl/opengl/juce_OpenGLFrameBuffer.cpp @@ -198,7 +198,7 @@ bool OpenGLFrameBuffer::initialise (OpenGLFrameBuffer& other) glEnable (GL_TEXTURE_2D); glBindTexture (GL_TEXTURE_2D, p->textureID); - pimpl->context.copyTexture (area, area, 1.0f); + pimpl->context.copyTexture (area, area); glBindTexture (GL_TEXTURE_2D, 0); pimpl->unbind(); @@ -309,7 +309,7 @@ bool OpenGLFrameBuffer::writePixels (const PixelARGB* data, const Rectangle OpenGLTexture tex; tex.loadARGBFlipped (data, area.getWidth(), area.getHeight()); - #if JUCE_OPENGL_ES + #if JUCE_OPENGL_ES && JUCE_USE_OPENGL_FIXED_FUNCTION const int texH = tex.getHeight(); tex.bind(); const GLint cropRect[4] = { 0, texH - area.getHeight(), area.getWidth(), area.getHeight() }; @@ -319,7 +319,7 @@ bool OpenGLFrameBuffer::writePixels (const PixelARGB* data, const Rectangle glDrawTexiOES (area.getX(), area.getY(), 1, area.getWidth(), area.getHeight()); glBindTexture (GL_TEXTURE_2D, 0); #else - pimpl->context.copyTexture (area, area, 1.0f); + pimpl->context.copyTexture (area, area); #endif pimpl->context.extensions.glBindFramebuffer (GL_FRAMEBUFFER, 0); diff --git a/modules/juce_opengl/opengl/juce_OpenGLGraphicsContext.cpp b/modules/juce_opengl/opengl/juce_OpenGLGraphicsContext.cpp index 81150f80ce..90d41b8255 100644 --- a/modules/juce_opengl/opengl/juce_OpenGLGraphicsContext.cpp +++ b/modules/juce_opengl/opengl/juce_OpenGLGraphicsContext.cpp @@ -227,11 +227,15 @@ public: program.addShader ("attribute vec2 position;" "attribute vec4 colour;" "uniform vec4 screenBounds;" + "varying " JUCE_LOWP " vec4 frontColour;" + "varying " JUCE_HIGHP " vec2 pixelPos;" "void main()" "{" - " gl_FrontColor = colour;" - " vec2 scaled = (position - screenBounds.xy) / screenBounds.zw;" - " gl_Position = vec4 (scaled.x - 1.0, 1.0 - scaled.y, 0, 1.0);" + " frontColour = colour;" + " vec2 adjustedPos = position - screenBounds.xy;" + " pixelPos = adjustedPos;" + " vec2 scaledPos = adjustedPos / screenBounds.zw;" + " gl_Position = vec4 (scaledPos.x - 1.0, 1.0 - scaledPos.y, 0, 1.0);" "}", GL_VERTEX_SHADER); program.addShader (fragmentShader, GL_FRAGMENT_SHADER); @@ -280,7 +284,7 @@ public: { maskTexture.set (textureIndex); maskBounds.set (area.getX() - target.bounds.getX(), - target.bounds.getHeight() - (area.getBottom() - target.bounds.getY()), + area.getY() - target.bounds.getY(), area.getWidth(), area.getHeight()); } @@ -288,31 +292,34 @@ public: }; //============================================================================== + #define JUCE_DECLARE_VARYING_COLOUR "varying " JUCE_LOWP " vec4 frontColour;" + #define JUCE_DECLARE_VARYING_PIXELPOS "varying " JUCE_HIGHP " vec2 pixelPos;" + struct SolidColourProgram : public ShaderBase { SolidColourProgram (OpenGLContext& context) - : ShaderBase (context, "void main()" + : ShaderBase (context, JUCE_DECLARE_VARYING_COLOUR + "void main()" "{" - " gl_FragColor = gl_Color;" + " gl_FragColor = frontColour;" "}") {} }; - #define JUCE_DECLARE_SHADER_VERSION "#version 120\n" #define JUCE_DECLARE_MASK_UNIFORMS "uniform sampler2D maskTexture;" \ "uniform ivec4 maskBounds;" - #define JUCE_FRAGCOORD_TO_MASK_POS "vec2 ((gl_FragCoord.x - maskBounds.x) / maskBounds.z," \ - "(gl_FragCoord.y - maskBounds.y) / maskBounds.w)" + #define JUCE_FRAGCOORD_TO_MASK_POS "vec2 ((pixelPos.x - float (maskBounds.x)) / float (maskBounds.z)," \ + "1.0 - (pixelPos.y - float (maskBounds.y)) / float (maskBounds.w))" #define JUCE_GET_MASK_ALPHA "texture2D (maskTexture, " JUCE_FRAGCOORD_TO_MASK_POS ").a" struct SolidColourMaskedProgram : public ShaderBase { SolidColourMaskedProgram (OpenGLContext& context) - : ShaderBase (context, JUCE_DECLARE_SHADER_VERSION - JUCE_DECLARE_MASK_UNIFORMS + : ShaderBase (context, + JUCE_DECLARE_MASK_UNIFORMS JUCE_DECLARE_VARYING_COLOUR JUCE_DECLARE_VARYING_PIXELPOS "void main()" "{" - "gl_FragColor = gl_Color * " JUCE_GET_MASK_ALPHA ";" + "gl_FragColor = frontColour * " JUCE_GET_MASK_ALPHA ";" "}"), maskParams (program) {} @@ -340,20 +347,20 @@ public: OpenGLShaderProgram::Uniform gradientTexture, matrix; }; - #define JUCE_DECLARE_MATRIX_UNIFORM "uniform float matrix[6];" + #define JUCE_DECLARE_MATRIX_UNIFORM "uniform " JUCE_HIGHP " float matrix[6];" #define JUCE_DECLARE_RADIAL_UNIFORMS "uniform sampler2D gradientTexture;" JUCE_DECLARE_MATRIX_UNIFORM - #define JUCE_MATRIX_TIMES_FRAGCOORD "(mat2 (matrix[0], matrix[3], matrix[1], matrix[4]) * gl_FragCoord.xy" \ + #define JUCE_MATRIX_TIMES_FRAGCOORD "(mat2 (matrix[0], matrix[3], matrix[1], matrix[4]) * pixelPos" \ " + vec2 (matrix[2], matrix[5]))" - #define JUCE_GET_TEXTURE_COLOUR "(gl_Color.a * texture2D (gradientTexture, vec2 (gradientPos, 0.5)))" + #define JUCE_GET_TEXTURE_COLOUR "(frontColour.a * texture2D (gradientTexture, vec2 (gradientPos, 0.5)))" struct RadialGradientProgram : public ShaderBase { RadialGradientProgram (OpenGLContext& context) - : ShaderBase (context, JUCE_DECLARE_SHADER_VERSION - JUCE_DECLARE_RADIAL_UNIFORMS + : ShaderBase (context, JUCE_DECLARE_VARYING_PIXELPOS + JUCE_DECLARE_RADIAL_UNIFORMS JUCE_DECLARE_VARYING_COLOUR "void main()" "{" - "float gradientPos = length (" JUCE_MATRIX_TIMES_FRAGCOORD ");" + JUCE_MEDIUMP " float gradientPos = length (" JUCE_MATRIX_TIMES_FRAGCOORD ");" "gl_FragColor = " JUCE_GET_TEXTURE_COLOUR ";" "}"), gradientParams (program) @@ -365,12 +372,12 @@ public: struct RadialGradientMaskedProgram : public ShaderBase { RadialGradientMaskedProgram (OpenGLContext& context) - : ShaderBase (context, JUCE_DECLARE_SHADER_VERSION - JUCE_DECLARE_RADIAL_UNIFORMS + : ShaderBase (context, JUCE_DECLARE_VARYING_PIXELPOS + JUCE_DECLARE_RADIAL_UNIFORMS JUCE_DECLARE_VARYING_COLOUR JUCE_DECLARE_MASK_UNIFORMS "void main()" "{" - "float gradientPos = length (" JUCE_MATRIX_TIMES_FRAGCOORD ");" + JUCE_MEDIUMP " float gradientPos = length (" JUCE_MATRIX_TIMES_FRAGCOORD ");" "gl_FragColor = " JUCE_GET_TEXTURE_COLOUR " * " JUCE_GET_MASK_ALPHA ";" "}"), gradientParams (program), @@ -393,15 +400,14 @@ public: }; #define JUCE_DECLARE_LINEAR_UNIFORMS "uniform sampler2D gradientTexture;" \ - "uniform vec4 gradientInfo;" - #define JUCE_CALC_LINEAR_GRAD_POS1 "float gradientPos = (gl_FragCoord.y - (gradientInfo.y + (gradientInfo.z * (gl_FragCoord.x - gradientInfo.x)))) / gradientInfo.w;" - #define JUCE_CALC_LINEAR_GRAD_POS2 "float gradientPos = (gl_FragCoord.x - (gradientInfo.x + (gradientInfo.z * (gl_FragCoord.y - gradientInfo.y)))) / gradientInfo.w;" + "uniform " JUCE_MEDIUMP " vec4 gradientInfo;" JUCE_DECLARE_VARYING_COLOUR JUCE_DECLARE_VARYING_PIXELPOS + #define JUCE_CALC_LINEAR_GRAD_POS1 JUCE_MEDIUMP " float gradientPos = (pixelPos.y - (gradientInfo.y + (gradientInfo.z * (pixelPos.x - gradientInfo.x)))) / gradientInfo.w;" + #define JUCE_CALC_LINEAR_GRAD_POS2 JUCE_MEDIUMP " float gradientPos = (pixelPos.x - (gradientInfo.x + (gradientInfo.z * (pixelPos.y - gradientInfo.y)))) / gradientInfo.w;" struct LinearGradient1Program : public ShaderBase { 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 + : ShaderBase (context, JUCE_DECLARE_LINEAR_UNIFORMS // gradientInfo: x = x1, y = y1, z = (y2 - y1) / (x2 - x1), w = length "void main()" "{" JUCE_CALC_LINEAR_GRAD_POS1 @@ -416,8 +422,7 @@ public: struct LinearGradient1MaskedProgram : public ShaderBase { 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 + : ShaderBase (context, JUCE_DECLARE_LINEAR_UNIFORMS // gradientInfo: x = x1, y = y1, z = (y2 - y1) / (x2 - x1), w = length JUCE_DECLARE_MASK_UNIFORMS "void main()" "{" @@ -435,8 +440,7 @@ public: struct LinearGradient2Program : public ShaderBase { 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 + : ShaderBase (context, JUCE_DECLARE_LINEAR_UNIFORMS // gradientInfo: x = x1, y = y1, z = (x2 - x1) / (y2 - y1), y = y1, w = length "void main()" "{" JUCE_CALC_LINEAR_GRAD_POS2 @@ -451,8 +455,7 @@ public: struct LinearGradient2MaskedProgram : public ShaderBase { 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 + : ShaderBase (context, JUCE_DECLARE_LINEAR_UNIFORMS // gradientInfo: x = x1, y = y1, z = (x2 - x1) / (y2 - y1), y = y1, w = length JUCE_DECLARE_MASK_UNIFORMS "void main()" "{" @@ -479,10 +482,9 @@ public: void setMatrix (const AffineTransform& trans, const int imageWidth, const int imageHeight, const float fullWidthProportion, const float fullHeightProportion, - const float targetX, const float targetY, const float targetHeight) const + const float targetX, const float targetY) const { const AffineTransform t (trans.translated (-targetX, -targetY) - .followedBy (AffineTransform::verticalFlip (targetHeight)) .inverted().scaled (fullWidthProportion / imageWidth, fullHeightProportion / imageHeight)); @@ -493,30 +495,30 @@ public: } void setMatrix (const AffineTransform& trans, const OpenGLTextureFromImage& image, - const float targetX, const float targetY, const float targetHeight) const + const float targetX, const float targetY) const { setMatrix (trans, image.imageWidth, image.imageHeight, image.fullWidthProportion, image.fullHeightProportion, - targetX, targetY, targetHeight); + targetX, targetY); } OpenGLShaderProgram::Uniform imageTexture, matrix, imageRepeatSize; }; #define JUCE_DECLARE_IMAGE_UNIFORMS "uniform sampler2D imageTexture;" \ - "uniform vec2 imageRepeatSize;" JUCE_DECLARE_MATRIX_UNIFORM + "uniform " JUCE_MEDIUMP " vec2 imageRepeatSize;" \ + JUCE_DECLARE_MATRIX_UNIFORM JUCE_DECLARE_VARYING_COLOUR JUCE_DECLARE_VARYING_PIXELPOS #define JUCE_GET_IMAGE_PIXEL "texture2D (imageTexture, vec2 (texturePos.x, 1.0 - texturePos.y))" struct ImageProgram : public ShaderBase { ImageProgram (OpenGLContext& context) - : ShaderBase (context, JUCE_DECLARE_SHADER_VERSION - JUCE_DECLARE_IMAGE_UNIFORMS + : ShaderBase (context, JUCE_DECLARE_IMAGE_UNIFORMS "void main()" "{" - "vec2 texturePos = clamp (" JUCE_MATRIX_TIMES_FRAGCOORD ", vec2 (0, 0), imageRepeatSize);" - "gl_FragColor = gl_Color.a * " JUCE_GET_IMAGE_PIXEL ";" + JUCE_HIGHP " vec2 texturePos = clamp (" JUCE_MATRIX_TIMES_FRAGCOORD ", vec2 (0, 0), imageRepeatSize);" + "gl_FragColor = frontColour.a * " JUCE_GET_IMAGE_PIXEL ";" "}"), imageParams (program) {} @@ -527,13 +529,11 @@ public: struct ImageMaskedProgram : public ShaderBase { ImageMaskedProgram (OpenGLContext& context) - : ShaderBase (context, JUCE_DECLARE_SHADER_VERSION - JUCE_DECLARE_IMAGE_UNIFORMS - JUCE_DECLARE_MASK_UNIFORMS + : ShaderBase (context, JUCE_DECLARE_IMAGE_UNIFORMS JUCE_DECLARE_MASK_UNIFORMS "void main()" "{" - "vec2 texturePos = clamp (" JUCE_MATRIX_TIMES_FRAGCOORD ", vec2 (0, 0), imageRepeatSize);" - "gl_FragColor = gl_Color.a * " JUCE_GET_IMAGE_PIXEL " * " JUCE_GET_MASK_ALPHA ";" + JUCE_HIGHP " vec2 texturePos = clamp (" JUCE_MATRIX_TIMES_FRAGCOORD ", vec2 (0, 0), imageRepeatSize);" + "gl_FragColor = frontColour.a * " JUCE_GET_IMAGE_PIXEL " * " JUCE_GET_MASK_ALPHA ";" "}"), imageParams (program), maskParams (program) @@ -546,12 +546,11 @@ public: struct TiledImageProgram : public ShaderBase { TiledImageProgram (OpenGLContext& context) - : ShaderBase (context, JUCE_DECLARE_SHADER_VERSION - JUCE_DECLARE_IMAGE_UNIFORMS + : ShaderBase (context, JUCE_DECLARE_IMAGE_UNIFORMS "void main()" "{" - "vec2 texturePos = mod (" JUCE_MATRIX_TIMES_FRAGCOORD ", imageRepeatSize);" - "gl_FragColor = gl_Color.a * " JUCE_GET_IMAGE_PIXEL ";" + JUCE_HIGHP " vec2 texturePos = mod (" JUCE_MATRIX_TIMES_FRAGCOORD ", imageRepeatSize);" + "gl_FragColor = frontColour.a * " JUCE_GET_IMAGE_PIXEL ";" "}"), imageParams (program) {} @@ -562,13 +561,11 @@ public: struct TiledImageMaskedProgram : public ShaderBase { TiledImageMaskedProgram (OpenGLContext& context) - : ShaderBase (context, JUCE_DECLARE_SHADER_VERSION - JUCE_DECLARE_IMAGE_UNIFORMS - JUCE_DECLARE_MASK_UNIFORMS + : ShaderBase (context, JUCE_DECLARE_IMAGE_UNIFORMS JUCE_DECLARE_MASK_UNIFORMS "void main()" "{" - "vec2 texturePos = mod (" JUCE_MATRIX_TIMES_FRAGCOORD ", imageRepeatSize);" - "gl_FragColor = gl_Color.a * " JUCE_GET_IMAGE_PIXEL " * " JUCE_GET_MASK_ALPHA ";" + JUCE_HIGHP " vec2 texturePos = mod (" JUCE_MATRIX_TIMES_FRAGCOORD ", imageRepeatSize);" + "gl_FragColor = frontColour.a * " JUCE_GET_IMAGE_PIXEL " * " JUCE_GET_MASK_ALPHA ";" "}"), imageParams (program), maskParams (program) @@ -581,12 +578,11 @@ public: struct CopyTextureProgram : public ShaderBase { CopyTextureProgram (OpenGLContext& context) - : ShaderBase (context, JUCE_DECLARE_SHADER_VERSION - JUCE_DECLARE_IMAGE_UNIFORMS + : ShaderBase (context, JUCE_DECLARE_IMAGE_UNIFORMS "void main()" "{" - "vec2 texturePos = mod (" JUCE_MATRIX_TIMES_FRAGCOORD ", imageRepeatSize);" - "gl_FragColor = gl_Color.a * " JUCE_GET_IMAGE_PIXEL ";" + JUCE_HIGHP " vec2 texturePos = mod (" JUCE_MATRIX_TIMES_FRAGCOORD ", imageRepeatSize);" + "gl_FragColor = frontColour.a * " JUCE_GET_IMAGE_PIXEL ";" "}"), imageParams (program) {} @@ -597,13 +593,12 @@ public: struct MaskTextureProgram : public ShaderBase { MaskTextureProgram (OpenGLContext& context) - : ShaderBase (context, JUCE_DECLARE_SHADER_VERSION - JUCE_DECLARE_IMAGE_UNIFORMS + : ShaderBase (context, JUCE_DECLARE_IMAGE_UNIFORMS "void main()" "{" - "vec2 texturePos = " JUCE_MATRIX_TIMES_FRAGCOORD ";" - "if (texturePos.x >= 0 && texturePos.y >= 0 && texturePos.x < imageRepeatSize.x && texturePos.y < imageRepeatSize.y)" - "gl_FragColor = gl_Color * " JUCE_GET_IMAGE_PIXEL ".a;" + JUCE_HIGHP " vec2 texturePos = " JUCE_MATRIX_TIMES_FRAGCOORD ";" + "if (texturePos.x >= 0.0 && texturePos.y >= 0.0 && texturePos.x < imageRepeatSize.x && texturePos.y < imageRepeatSize.y)" + "gl_FragColor = frontColour * " JUCE_GET_IMAGE_PIXEL ".a;" "else " "gl_FragColor = vec4 (0, 0, 0, 0);" "}"), @@ -700,9 +695,9 @@ struct StateHelpers }; //============================================================================== + #if JUCE_USE_OPENGL_FIXED_FUNCTION struct CurrentColour { - #if JUCE_USE_OPENGL_FIXED_FUNCTION CurrentColour() noexcept : currentColour (0xffffffff) {} @@ -745,8 +740,8 @@ struct StateHelpers private: PixelARGB currentColour; - #endif }; + #endif //============================================================================== template @@ -1217,7 +1212,7 @@ struct StateHelpers { CurrentShader (OpenGLContext& context_) noexcept : context (context_), - canUseShaders (OpenGLShaderProgram::getLanguageVersion() >= 1.199), + canUseShaders (context.areShadersAvailable()), activeShader (nullptr) { const Identifier programValueID ("GraphicsContextPrograms"); @@ -1351,7 +1346,7 @@ public: resetMultiTextureModes (true); #endif - #if JUCE_USE_OPENGL_SHADERS + #if JUCE_USE_OPENGL_SHADERS && defined (GL_INDEX_ARRAY) glDisableClientState (GL_INDEX_ARRAY); #endif } @@ -1663,8 +1658,7 @@ public: textureCache.bindTextureForGradient (activeTextures, g); } - const AffineTransform t (transform.translated ((float) -target.bounds.getX(), (float) -target.bounds.getY()) - .followedBy (AffineTransform::verticalFlip ((float) target.bounds.getHeight()))); + const AffineTransform t (transform.translated ((float) -target.bounds.getX(), (float) -target.bounds.getY())); Point p1 (g.point1.transformedBy (t)); const Point p2 (g.point2.transformedBy (t)); const Point p3 (Point (g.point1.x + (g.point2.y - g.point1.y), @@ -1784,8 +1778,7 @@ public: } } - imageParams->setMatrix (transform, image, (float) target.bounds.getX(), - (float) target.bounds.getY(), (float) target.bounds.getHeight()); + imageParams->setMatrix (transform, image, (float) target.bounds.getX(), (float) target.bounds.getY()); if (maskParams != nullptr) maskParams->setBounds (*maskArea, target, 1); @@ -1794,12 +1787,12 @@ public: OpenGLTarget target; - StateHelpers::CurrentColour currentColour; StateHelpers::BlendingMode blendMode; StateHelpers::ActiveTextures activeTextures; StateHelpers::TextureCache textureCache; #if JUCE_USE_OPENGL_FIXED_FUNCTION + StateHelpers::CurrentColour currentColour; StateHelpers::QuadQueue quadQueue; #endif @@ -2446,6 +2439,7 @@ public: state.activeTextures.setSingleTextureMode (state.shaderQuadQueue); state.activeTextures.clear(); mask.initialise (state.target.context, maskArea.getWidth(), maskArea.getHeight()); + maskArea.setSize (mask.getWidth(), mask.getHeight()); makeActive(); state.blendMode.disableBlend (state.shaderQuadQueue); @@ -2457,7 +2451,7 @@ public: state.currentShader.programs->copyTexture.imageParams .setMatrix (AffineTransform::translation ((float) other.maskArea.getX(), (float) other.maskArea.getY()), other.maskArea.getWidth(), other.maskArea.getHeight(), 1.0f, 1.0f, - (float) maskArea.getX(), (float) maskArea.getY(), (float) maskArea.getHeight()); + (float) maskArea.getX(), (float) maskArea.getY()); state.shaderQuadQueue.add (clip, PixelARGB (0xffffffff)); state.shaderQuadQueue.flush(); @@ -2473,6 +2467,7 @@ public: state.shaderQuadQueue.flush(); state.activeTextures.clear(); mask.initialise (state.target.context, maskArea.getWidth(), maskArea.getHeight()); + maskArea.setSize (mask.getWidth(), mask.getHeight()); mask.makeCurrentAndClear(); makeActive(); state.blendMode.setBlendMode (state.shaderQuadQueue, true); @@ -2565,7 +2560,7 @@ public: state.currentShader.programs->maskTexture.imageParams .setMatrix (AffineTransform::translation ((float) pt.area.getX(), (float) pt.area.getY()), pt.area.getWidth(), pt.area.getHeight(), 1.0f, 1.0f, - (float) maskArea.getX(), (float) maskArea.getY(), (float) maskArea.getHeight()); + (float) maskArea.getX(), (float) maskArea.getY()); state.blendMode.setBlendFunc (state.shaderQuadQueue, GL_ZERO, GL_SRC_ALPHA); state.shaderQuadQueue.add (clip, PixelARGB (0xffffffff)); @@ -2583,7 +2578,7 @@ public: state.currentShader.setShader (maskArea, state.shaderQuadQueue, state.currentShader.programs->maskTexture); state.currentShader.programs->maskTexture.imageParams.imageTexture.set (0); state.currentShader.programs->maskTexture.imageParams - .setMatrix (transform, image, (float) maskArea.getX(), (float) maskArea.getY(), (float) maskArea.getHeight()); + .setMatrix (transform, image, (float) maskArea.getX(), (float) maskArea.getY()); state.shaderQuadQueue.add (clip, PixelARGB (0xffffffff)); state.shaderQuadQueue.flush(); diff --git a/modules/juce_opengl/opengl/juce_OpenGLShaderProgram.cpp b/modules/juce_opengl/opengl/juce_OpenGLShaderProgram.cpp index 89c2711ff3..47ca11e899 100644 --- a/modules/juce_opengl/opengl/juce_OpenGLShaderProgram.cpp +++ b/modules/juce_opengl/opengl/juce_OpenGLShaderProgram.cpp @@ -41,8 +41,13 @@ OpenGLShaderProgram::~OpenGLShaderProgram() noexcept double OpenGLShaderProgram::getLanguageVersion() { + #if JUCE_OPENGL_ES + jassertfalse; // doesn't work in ES + return 0; + #else return String ((const char*) glGetString (GL_SHADING_LANGUAGE_VERSION)) .upToFirstOccurrenceOf (" ", false, false).getDoubleValue(); + #endif } void OpenGLShaderProgram::addShader (const char* const code, GLenum type)