BradLarson / GPUImage2

GPUImage 2 is a BSD-licensed Swift framework for GPU-accelerated video and image processing.
BSD 3-Clause "New" or "Revised" License
4.85k stars 605 forks source link

How can i set inputImageTexture2 in a custom filter? #271

Closed killua167 closed 5 years ago

killua167 commented 5 years ago

Hi,brad i had this custom filter:

varying highp vec2 textureCoordinate;

uniform sampler2D inputImageTexture;
uniform sampler2D inputImageTexture_1;

uniform highp float alpha;

lowp vec3 texel;
lowp vec3 color;
highp float blueColor;
highp vec2 quad1;
highp vec2 quad2;
highp vec2 texPos1;
highp vec2 texPos2;
lowp vec4 newColor1;
lowp vec4 newColor2;
void main()
{
    texel=texture2D(inputImageTexture, textureCoordinate).rgb;

    blueColor = texel.b * 15.0;
    quad1.y = floor(floor(blueColor) / 4.0);
    quad1.x = floor(blueColor) - (quad1.y * 4.0);
    quad2.y = floor(ceil(blueColor) / 4.0);
    quad2.x = ceil(blueColor) - (quad2.y * 4.0);
    texPos1.x = (quad1.x * 0.25) + 0.5/64.0 + ((0.25 - 1.0/64.0) * texel.r);
    texPos1.y = (quad1.y * 0.25) + 0.5/64.0 + ((0.25 - 1.0/64.0) * texel.g);
    texPos2.x = (quad2.x * 0.25) + 0.5/64.0 + ((0.25 - 1.0/64.0) * texel.r);
    texPos2.y = (quad2.y * 0.25) + 0.5/64.0 + ((0.25 - 1.0/64.0) * texel.g);
    newColor1 = texture2D(inputImageTexture_1, texPos1);
    newColor2 = texture2D(inputImageTexture_1, texPos2);
    color = mix(newColor1.rgb, newColor2.rgb, fract(blueColor));
    texel = mix(texel, color, alpha);
    gl_FragColor = vec4(texel.rgb, 1.0);
}

it has two inputImageTexture, and the uniform inputImageTexture_1 need to bind a texture from a .png image.

here is the problem:

  1. how can i set uniform inputImageTexture_1 in the class BasicOperation?
  2. can UIImage turn to FrameBuffer? so i can set 'glBindTexture(GLenum(GL_TEXTURE_2D), (frameBuffer.texture));'

in the GPUImage OC version, i can work it out like this:

override init() {
        let folder = Bundle.main.path(forResource: "Charm", ofType: nil)
        let input1URL = NSURL(string: folder!)!.appendingPathComponent("fragment.glsl")
        var  inputStr : String = String()
        do {
            try inputStr = String.init(contentsOfFile: input1URL!.absoluteString, encoding: .utf8)
        } catch  {
            print(error)
        }
        super.init(fragmentShaderFrom: inputStr)
        runSynchronouslyOnVideoProcessingQueue {
            self.bindTexture()
        }
    }

func bindTexture() {
        //uniform
        let filterProgram : GLProgram = self.value(forKey: "filterProgram") as! GLProgram
        let inputImageTextureID = filterProgram.uniformIndex("inputImageTexture_1")

        //load image
        let image = UIImage.init(contentsOfFile: imageURL!.absoluteString)
        let image1 : GPUImagePicture = GPUImagePicture.init(image: image)

        let frameBuffer : GPUImageFramebuffer = image1.framebufferForOutput()
        //lock
        frameBuffer.lock()
        frameBuffer.activate()

        // Texture
        //        int startTextureIndex = 3;
        glActiveTexture(GLenum(GL_TEXTURE0 + 3));
        glBindTexture(GLenum(GL_TEXTURE_2D), (frameBuffer.texture));
        glUniform1i(GLint(inputImageTextureID), 3);

        frameBuffer.unlock()

        self.setFloat(0.5, forUniformName: "alpha")
    }

but in GPUImage2, when i get the imageFramebuffer from a PictureInput, the imageFramebuffer.framebuffer is nil , cause the method activateFramebufferForRendering() crash. Is this a bug or I do wrong?

ljmkimqx commented 3 years ago

Have you found a way?