1
0
Fork 0
mirror of https://github.com/juce-framework/JUCE.git synced 2026-01-10 23:44:24 +00:00

More openGL: removed problematic gl_FragCoord use; made shaders work in GLES2.

This commit is contained in:
jules 2012-01-10 14:25:21 +00:00
parent 0301e9d1e4
commit 493a78f33d
9 changed files with 187 additions and 164 deletions

View file

@ -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"

View file

@ -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

View file

@ -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<int>& 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 <const GLESContext*> (contextToShareListsWith),
(flags & openGLES2) == 0 ? kEAGLRenderingAPIOpenGLES1
: kEAGLRenderingAPIOpenGLES2);
(flags & openGLES2) != 0);
return nullptr;
}

View file

@ -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<int> (frameBuffer.getWidth(), frameBuffer.getHeight()),
getAlpha());
context->copyTexture (bounds, Rectangle<int> (bounds.getWidth(),
bounds.getHeight()));
glBindTexture (GL_TEXTURE_2D, 0);
}

View file

@ -91,7 +91,7 @@ bool OpenGLPixelFormat::operator== (const OpenGLPixelFormat& other) const noexce
static Array<OpenGLContext*> 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<int>& targetClipArea,
const Rectangle<int>& anchorPosAndTextureSize,
float alpha)
const Rectangle<int>& 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<int>& 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<int>& targetClipArea,
matrix (program, "matrix")
{}
void set (const int targetWidth, const int targetHeight, const Rectangle<float>& anchorPosAndTextureSize) const
void set (const float targetWidth, const float targetHeight, const Rectangle<float>& 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<int>& 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<int>& 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);

View file

@ -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<int>& targetClipArea,
const Rectangle<int>& anchorPosAndTextureSize,
float alpha);
const Rectangle<int>& anchorPosAndTextureSize);
protected:
//==============================================================================
OpenGLContext() noexcept;
private:
double shaderLanguageVersion;
double getShaderLanguageVersion();
mutable int shaderLanguageAvailable;
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (OpenGLContext);
};

View file

@ -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<int>
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<int>
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);

View file

@ -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 <class QuadQueueType>
@ -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<float> p1 (g.point1.transformedBy (t));
const Point<float> p2 (g.point2.transformedBy (t));
const Point<float> p3 (Point<float> (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();

View file

@ -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)