Skip to content

Commit

Permalink
Fixed the filter masking on iOS. Forgot OpenGL ES 2.0 didn't support …
Browse files Browse the repository at this point in the history
…GL_ALPHA_TEST.
  • Loading branch information
BradLarson committed Apr 20, 2016
1 parent b047667 commit da42bcd
Show file tree
Hide file tree
Showing 7 changed files with 72 additions and 9 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -388,7 +388,12 @@ let filterOperations: Array<FilterOperationInterface> = [
filterOperationType:.Custom(filterSetupFunction:{(camera, filter, outputView) in
let castFilter = filter as! Pixellate
castFilter.fractionalWidthOfAPixel = 0.05
// TODO: Find a way to not hardcode these values
#if os(iOS)
let circleGenerator = CircleGenerator(size:Size(width:480, height:640))
#else
let circleGenerator = CircleGenerator(size:Size(width:1280, height:720))
#endif
castFilter.mask = circleGenerator
circleGenerator.renderCircleOfRadius(0.25, center:Position.Center, circleColor:Color.White, backgroundColor:Color.Transparent)
camera --> castFilter --> outputView
Expand Down
12 changes: 11 additions & 1 deletion framework/Source/Framebuffer.swift
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ public enum FramebufferTimingStyle {
public class Framebuffer {
let texture:GLuint
let framebuffer:GLuint?
let stencilBuffer:GLuint?
let size:GLSize
let orientation:ImageOrientation
let internalFormat:Int32
Expand Down Expand Up @@ -65,12 +66,16 @@ public class Framebuffer {

if (!textureOnly) {
do {
framebuffer = try generateFramebufferForTexture(texture, width:size.width, height:size.height, internalFormat:internalFormat, format:format, type:type, stencil:stencil)
let (createdFrameBuffer, createdStencil) = try generateFramebufferForTexture(texture, width:size.width, height:size.height, internalFormat:internalFormat, format:format, type:type, stencil:stencil)
framebuffer = createdFrameBuffer
stencilBuffer = createdStencil
} catch {
stencilBuffer = nil
framebuffer = nil
throw error
}
} else {
stencilBuffer = nil
framebuffer = nil
}
}
Expand All @@ -86,6 +91,11 @@ public class Framebuffer {
var mutableFramebuffer = framebuffer
glDeleteFramebuffers(1, &mutableFramebuffer)
}

if let stencilBuffer = stencilBuffer {
var mutableStencil = stencilBuffer
glDeleteRenderbuffers(1, &mutableStencil)
}
}

func sizeForTargetOrientation(targetOrientation:ImageOrientation) -> GLSize {
Expand Down
30 changes: 22 additions & 8 deletions framework/Source/OpenGLRendering.swift
Original file line number Diff line number Diff line change
Expand Up @@ -84,24 +84,30 @@ func clearFramebufferWithColor(color:Color) {

func renderStencilMaskFromFramebuffer(framebuffer:Framebuffer) {
let inputTextureProperties = framebuffer.texturePropertiesForOutputRotation(.NoRotation)
glEnable(GLenum(GL_STENCIL_TEST))
glClearStencil(0)
glClear (GLenum(GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT))
glColorMask(GLboolean(GL_FALSE), GLboolean(GL_FALSE), GLboolean(GL_FALSE), GLboolean(GL_FALSE))
glDisable(GLenum(GL_DEPTH_TEST))
glEnable(GLenum(GL_STENCIL_TEST))
glEnable(GLenum(GL_ALPHA_TEST))
glBlendFunc(GLenum(GL_ONE), GLenum(GL_ONE))
glAlphaFunc(GLenum(GL_NOTEQUAL), 0.0)
glStencilFunc(GLenum(GL_ALWAYS), 1, 1)
glStencilOp(GLenum(GL_KEEP), GLenum(GL_KEEP), GLenum(GL_REPLACE))

#if GL
glEnable(GLenum(GL_ALPHA_TEST))
glAlphaFunc(GLenum(GL_NOTEQUAL), 0.0)
renderQuadWithShader(sharedImageProcessingContext.passthroughShader, vertices:standardImageVertices, inputTextures:[inputTextureProperties])
#else
let alphaTestShader = crashOnShaderCompileFailure("Stencil"){return try sharedImageProcessingContext.programForVertexShader(OneInputVertexShader, fragmentShader:AlphaTestFragmentShader)}
renderQuadWithShader(alphaTestShader, vertices:standardImageVertices, inputTextures:[inputTextureProperties])
#endif

glColorMask(GLboolean(GL_TRUE), GLboolean(GL_TRUE), GLboolean(GL_TRUE), GLboolean(GL_TRUE))

glStencilFunc(GLenum(GL_EQUAL), 1, 1)
glStencilOp(GLenum(GL_KEEP), GLenum(GL_KEEP), GLenum(GL_KEEP))

#if GL
glDisable(GLenum(GL_ALPHA_TEST))
#endif
}

func disableStencil() {
Expand Down Expand Up @@ -139,7 +145,7 @@ func generateTexture(minFilter minFilter:Int32, magFilter:Int32, wrapS:Int32, wr
return texture
}

func generateFramebufferForTexture(texture:GLuint, width:GLint, height:GLint, internalFormat:Int32, format:Int32, type:Int32, stencil:Bool) throws -> GLuint {
func generateFramebufferForTexture(texture:GLuint, width:GLint, height:GLint, internalFormat:Int32, format:Int32, type:Int32, stencil:Bool) throws -> (GLuint, GLuint?) {
var framebuffer:GLuint = 0
glActiveTexture(GLenum(GL_TEXTURE1))

Expand All @@ -155,22 +161,30 @@ func generateFramebufferForTexture(texture:GLuint, width:GLint, height:GLint, in
throw FramebufferCreationError(errorCode:status)
}

let stencilBuffer:GLuint?
if stencil {
try attachStencilBuffer(width:width, height:height)
stencilBuffer = try attachStencilBuffer(width:width, height:height)
} else {
stencilBuffer = nil
}

glBindTexture(GLenum(GL_TEXTURE_2D), 0)
glBindFramebuffer(GLenum(GL_FRAMEBUFFER), 0)
return framebuffer
return (framebuffer, stencilBuffer)
}

func attachStencilBuffer(width width:GLint, height:GLint) throws -> GLuint {
var stencilBuffer:GLuint = 0
glGenRenderbuffers(1, &stencilBuffer);
glBindRenderbuffer(GLenum(GL_RENDERBUFFER), stencilBuffer)
glRenderbufferStorage(GLenum(GL_RENDERBUFFER), GLenum(GL_DEPTH24_STENCIL8), width, height) // iOS seems to only support combination depth + stencil, from references
#if os(iOS)
glFramebufferRenderbuffer(GLenum(GL_FRAMEBUFFER), GLenum(GL_DEPTH_ATTACHMENT), GLenum(GL_RENDERBUFFER), stencilBuffer)
#endif
glFramebufferRenderbuffer(GLenum(GL_FRAMEBUFFER), GLenum(GL_STENCIL_ATTACHMENT), GLenum(GL_RENDERBUFFER), stencilBuffer)

glBindRenderbuffer(GLenum(GL_RENDERBUFFER), 0)

let status = glCheckFramebufferStatus(GLenum(GL_FRAMEBUFFER))
if (status != GLenum(GL_FRAMEBUFFER_COMPLETE)) {
throw FramebufferCreationError(errorCode:status)
Expand Down
16 changes: 16 additions & 0 deletions framework/Source/Operations/Shaders/AlphaTest_GL.fsh
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
varying vec2 textureCoordinate;

uniform sampler2D inputImageTexture;

void main()
{
vec4 color = texture2D(inputImageTexture, textureCoordinate);
if (color.a < 0.5)
{
discard;
}
else
{
gl_FragColor = color;
}
}
16 changes: 16 additions & 0 deletions framework/Source/Operations/Shaders/AlphaTest_GLES.fsh
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
varying highp vec2 textureCoordinate;

uniform sampler2D inputImageTexture;

void main()
{
lowp vec4 color = texture2D(inputImageTexture, textureCoordinate);
if (color.a < 0.5)
{
discard;
}
else
{
gl_FragColor = color;
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
public let AdaptiveThresholdFragmentShader = "varying vec2 textureCoordinate;\n varying vec2 textureCoordinate2;\n \n uniform sampler2D inputImageTexture;\n uniform sampler2D inputImageTexture2;\n \n void main()\n {\n float blurredInput = texture2D(inputImageTexture, textureCoordinate).r;\n float localLuminance = texture2D(inputImageTexture2, textureCoordinate2).r;\n float thresholdResult = step(blurredInput - 0.05, localLuminance);\n \n gl_FragColor = vec4(vec3(thresholdResult), 1.0);\n }\n "
public let AddBlendFragmentShader = "varying vec2 textureCoordinate;\n varying vec2 textureCoordinate2;\n \n uniform sampler2D inputImageTexture;\n uniform sampler2D inputImageTexture2;\n \n void main()\n {\n vec4 base = texture2D(inputImageTexture, textureCoordinate);\n vec4 overlay = texture2D(inputImageTexture2, textureCoordinate2);\n \n float r;\n if (overlay.r * base.a + base.r * overlay.a >= overlay.a * base.a) {\n r = overlay.a * base.a + overlay.r * (1.0 - base.a) + base.r * (1.0 - overlay.a);\n } else {\n r = overlay.r + base.r;\n }\n \n float g;\n if (overlay.g * base.a + base.g * overlay.a >= overlay.a * base.a) {\n g = overlay.a * base.a + overlay.g * (1.0 - base.a) + base.g * (1.0 - overlay.a);\n } else {\n g = overlay.g + base.g;\n }\n \n float b;\n if (overlay.b * base.a + base.b * overlay.a >= overlay.a * base.a) {\n b = overlay.a * base.a + overlay.b * (1.0 - base.a) + base.b * (1.0 - overlay.a);\n } else {\n b = overlay.b + base.b;\n }\n \n float a = overlay.a + base.a - overlay.a * base.a;\n \n gl_FragColor = vec4(r, g, b, a);\n }\n "
public let AlphaBlendFragmentShader = "varying vec2 textureCoordinate;\n varying vec2 textureCoordinate2;\n \n uniform sampler2D inputImageTexture;\n uniform sampler2D inputImageTexture2;\n \n uniform float mixturePercent;\n \n void main()\n {\n vec4 textureColor = texture2D(inputImageTexture, textureCoordinate);\n vec4 textureColor2 = texture2D(inputImageTexture2, textureCoordinate2);\n \n gl_FragColor = vec4(mix(textureColor.rgb, textureColor2.rgb, textureColor2.a * mixturePercent), textureColor.a);\n }\n "
public let AlphaTestFragmentShader = "varying vec2 textureCoordinate;\n \n uniform sampler2D inputImageTexture;\n \n void main()\n {\n vec4 color = texture2D(inputImageTexture, textureCoordinate);\n if (color.a < 0.5) \n {\n discard;\n } \n else\n {\n gl_FragColor = color;\n }\n }\n "
public let AverageColorVertexShader = "attribute vec4 position;\n attribute vec4 inputTextureCoordinate;\n \n uniform float texelWidth;\n uniform float texelHeight;\n \n varying vec2 upperLeftInputTextureCoordinate;\n varying vec2 upperRightInputTextureCoordinate;\n varying vec2 lowerLeftInputTextureCoordinate;\n varying vec2 lowerRightInputTextureCoordinate;\n \n void main()\n {\n gl_Position = position;\n \n upperLeftInputTextureCoordinate = inputTextureCoordinate.xy + vec2(-texelWidth, -texelHeight);\n upperRightInputTextureCoordinate = inputTextureCoordinate.xy + vec2(texelWidth, -texelHeight);\n lowerLeftInputTextureCoordinate = inputTextureCoordinate.xy + vec2(-texelWidth, texelHeight);\n lowerRightInputTextureCoordinate = inputTextureCoordinate.xy + vec2(texelWidth, texelHeight);\n }\n "
public let AverageColorFragmentShader = "uniform sampler2D inputImageTexture;\n \n varying vec2 outputTextureCoordinate;\n \n varying vec2 upperLeftInputTextureCoordinate;\n varying vec2 upperRightInputTextureCoordinate;\n varying vec2 lowerLeftInputTextureCoordinate;\n varying vec2 lowerRightInputTextureCoordinate;\n \n void main()\n {\n vec4 upperLeftColor = texture2D(inputImageTexture, upperLeftInputTextureCoordinate);\n vec4 upperRightColor = texture2D(inputImageTexture, upperRightInputTextureCoordinate);\n vec4 lowerLeftColor = texture2D(inputImageTexture, lowerLeftInputTextureCoordinate);\n vec4 lowerRightColor = texture2D(inputImageTexture, lowerRightInputTextureCoordinate);\n \n gl_FragColor = 0.25 * (upperLeftColor + upperRightColor + lowerLeftColor + lowerRightColor);\n }\n "
public let AverageLuminanceFragmentShader = "uniform sampler2D inputImageTexture;\n \n varying vec2 outputTextureCoordinate;\n \n varying vec2 upperLeftInputTextureCoordinate;\n varying vec2 upperRightInputTextureCoordinate;\n varying vec2 lowerLeftInputTextureCoordinate;\n varying vec2 lowerRightInputTextureCoordinate;\n \n void main()\n {\n float upperLeftLuminance = texture2D(inputImageTexture, upperLeftInputTextureCoordinate).r;\n float upperRightLuminance = texture2D(inputImageTexture, upperRightInputTextureCoordinate).r;\n float lowerLeftLuminance = texture2D(inputImageTexture, lowerLeftInputTextureCoordinate).r;\n float lowerRightLuminance = texture2D(inputImageTexture, lowerRightInputTextureCoordinate).r;\n \n float luminosity = 0.25 * (upperLeftLuminance + upperRightLuminance + lowerLeftLuminance + lowerRightLuminance);\n gl_FragColor = vec4(luminosity, luminosity, luminosity, 1.0);\n }\n "
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
public let AdaptiveThresholdFragmentShader = "varying highp vec2 textureCoordinate;\n varying highp vec2 textureCoordinate2;\n \n uniform sampler2D inputImageTexture;\n uniform sampler2D inputImageTexture2; \n \n void main()\n {\n highp float blurredInput = texture2D(inputImageTexture, textureCoordinate).r;\n highp float localLuminance = texture2D(inputImageTexture2, textureCoordinate2).r;\n highp float thresholdResult = step(blurredInput - 0.05, localLuminance);\n \n gl_FragColor = vec4(vec3(thresholdResult), 1.0);\n }\n "
public let AddBlendFragmentShader = "varying highp vec2 textureCoordinate;\n varying highp vec2 textureCoordinate2;\n \n uniform sampler2D inputImageTexture;\n uniform sampler2D inputImageTexture2;\n \n void main()\n {\n lowp vec4 base = texture2D(inputImageTexture, textureCoordinate);\n lowp vec4 overlay = texture2D(inputImageTexture2, textureCoordinate2);\n \n mediump float r;\n if (overlay.r * base.a + base.r * overlay.a >= overlay.a * base.a) {\n r = overlay.a * base.a + overlay.r * (1.0 - base.a) + base.r * (1.0 - overlay.a);\n } else {\n r = overlay.r + base.r;\n }\n \n mediump float g;\n if (overlay.g * base.a + base.g * overlay.a >= overlay.a * base.a) {\n g = overlay.a * base.a + overlay.g * (1.0 - base.a) + base.g * (1.0 - overlay.a);\n } else {\n g = overlay.g + base.g;\n }\n \n mediump float b;\n if (overlay.b * base.a + base.b * overlay.a >= overlay.a * base.a) {\n b = overlay.a * base.a + overlay.b * (1.0 - base.a) + base.b * (1.0 - overlay.a);\n } else {\n b = overlay.b + base.b;\n }\n \n mediump float a = overlay.a + base.a - overlay.a * base.a;\n \n gl_FragColor = vec4(r, g, b, a);\n }\n "
public let AlphaBlendFragmentShader = "varying highp vec2 textureCoordinate;\n varying highp vec2 textureCoordinate2;\n \n uniform sampler2D inputImageTexture;\n uniform sampler2D inputImageTexture2;\n \n uniform lowp float mixturePercent;\n \n void main()\n {\n lowp vec4 textureColor = texture2D(inputImageTexture, textureCoordinate);\n lowp vec4 textureColor2 = texture2D(inputImageTexture2, textureCoordinate2);\n \n gl_FragColor = vec4(mix(textureColor.rgb, textureColor2.rgb, textureColor2.a * mixturePercent), textureColor.a);\n }\n "
public let AlphaTestFragmentShader = "varying highp vec2 textureCoordinate;\n \n uniform sampler2D inputImageTexture;\n \n void main()\n {\n lowp vec4 color = texture2D(inputImageTexture, textureCoordinate);\n if (color.a < 0.5) \n {\n discard;\n } \n else\n {\n gl_FragColor = color;\n }\n }\n "
public let AverageColorVertexShader = "attribute vec4 position;\n attribute vec4 inputTextureCoordinate;\n \n uniform float texelWidth;\n uniform float texelHeight;\n \n varying vec2 upperLeftInputTextureCoordinate;\n varying vec2 upperRightInputTextureCoordinate;\n varying vec2 lowerLeftInputTextureCoordinate;\n varying vec2 lowerRightInputTextureCoordinate;\n \n void main()\n {\n gl_Position = position;\n \n upperLeftInputTextureCoordinate = inputTextureCoordinate.xy + vec2(-texelWidth, -texelHeight);\n upperRightInputTextureCoordinate = inputTextureCoordinate.xy + vec2(texelWidth, -texelHeight);\n lowerLeftInputTextureCoordinate = inputTextureCoordinate.xy + vec2(-texelWidth, texelHeight);\n lowerRightInputTextureCoordinate = inputTextureCoordinate.xy + vec2(texelWidth, texelHeight);\n }\n "
public let AverageColorFragmentShader = "precision highp float;\n \n uniform sampler2D inputImageTexture;\n \n varying highp vec2 outputTextureCoordinate;\n \n varying highp vec2 upperLeftInputTextureCoordinate;\n varying highp vec2 upperRightInputTextureCoordinate;\n varying highp vec2 lowerLeftInputTextureCoordinate;\n varying highp vec2 lowerRightInputTextureCoordinate;\n \n void main()\n {\n highp vec4 upperLeftColor = texture2D(inputImageTexture, upperLeftInputTextureCoordinate);\n highp vec4 upperRightColor = texture2D(inputImageTexture, upperRightInputTextureCoordinate);\n highp vec4 lowerLeftColor = texture2D(inputImageTexture, lowerLeftInputTextureCoordinate);\n highp vec4 lowerRightColor = texture2D(inputImageTexture, lowerRightInputTextureCoordinate);\n \n gl_FragColor = 0.25 * (upperLeftColor + upperRightColor + lowerLeftColor + lowerRightColor);\n }\n "
public let AverageLuminanceFragmentShader = "precision highp float;\n \n uniform sampler2D inputImageTexture;\n \n varying highp vec2 outputTextureCoordinate;\n \n varying highp vec2 upperLeftInputTextureCoordinate;\n varying highp vec2 upperRightInputTextureCoordinate;\n varying highp vec2 lowerLeftInputTextureCoordinate;\n varying highp vec2 lowerRightInputTextureCoordinate;\n \n void main()\n {\n highp float upperLeftLuminance = texture2D(inputImageTexture, upperLeftInputTextureCoordinate).r;\n highp float upperRightLuminance = texture2D(inputImageTexture, upperRightInputTextureCoordinate).r;\n highp float lowerLeftLuminance = texture2D(inputImageTexture, lowerLeftInputTextureCoordinate).r;\n highp float lowerRightLuminance = texture2D(inputImageTexture, lowerRightInputTextureCoordinate).r;\n \n highp float luminosity = 0.25 * (upperLeftLuminance + upperRightLuminance + lowerLeftLuminance + lowerRightLuminance);\n gl_FragColor = vec4(luminosity, luminosity, luminosity, 1.0);\n }\n "
Expand Down

0 comments on commit da42bcd

Please sign in to comment.