GPUImage2: passing gl texture to shader

♀尐吖头ヾ 提交于 2019-12-10 17:53:38

问题


I'm trying to modify GPUImage2 Crosshair generator to replace default crosshairs with gl texture made of UIImage, my image is 128x128 png file.

I'm using GPUImage2 PictureInput for converting UIImage to gl texture and it returns the instance of PictureInput without any issues/warnings.

Next I'm modifying CrosshairVertexShader to add support of the new texture:

uniform sampler2D inputImageTexture; 
attribute vec4 position;
varying vec2 centerLocation;
varying float pointSpacing;

void main() {
    gl_Position = vec4(((position.xy * 2.0) - 1.0), 0.0, 1.0);
    gl_PointSize = crosshairWidth + 1.0;
    pointSpacing = 1.0 / crosshairWidth;
    centerLocation = vec2(
        pointSpacing * ceil(crosshairWidth / 2.0),
        pointSpacing * ceil(crosshairWidth / 2.0));
}

then pass it to modified CrosshairFragmentShader and render on screen(?):

uniform sampler2D inputImageTexture;
varying lowp vec3 crosshairColor;
varying highp vec2 centerLocation;
varying highp float pointSpacing;

void main() {
    highp vec4 tex = texture2D(inputImageTexture, centerLocation);
    gl_FragColor = vec4(tex.r, tex.g, tex.b, tex.a);
}

Here is the code of modified CrosshairGenerator:

import UIKit

public class CrosshairGenerator: ImageGenerator {

    public var crosshairWidth:Float = 5.0 { didSet {    uniformSettings["crosshairWidth"] = crosshairWidth } }
    public var crosshairColor:Color = Color.green { didSet { uniformSettings["crosshairColor"] = crosshairColor } }
    public var crosshairImage: PictureInput = PictureInput(imageName:"monohrome.png") {
    didSet {
        uniformSettings["inputImageTexture"] = crosshairImage //Here I pass the texture to shader?
        crosshairImage.processImage()
    }

}

let crosshairShader:ShaderProgram
var uniformSettings = ShaderUniformSettings()

public override init(size:Size) {        
    crosshairShader = crashOnShaderCompileFailure("CrosshairGenerator"){try sharedImageProcessingContext.programForVertexShader(vertexShader, fragmentShader: fragmentShader)}

    super.init(size:size)

    ({crosshairWidth = 5.0})()
    ({crosshairColor = Color.green})()
    ({crosshairImage = PictureInput(imageName:"monohrome.png")})()
}

public func renderCrosshairs(_ positions:[Position]) {
    imageFramebuffer.activateFramebufferForRendering()
    imageFramebuffer.timingStyle = .stillImage 
#if GL
    glEnable(GLenum(GL_POINT_SPRITE))
    glEnable(GLenum(GL_VERTEX_PROGRAM_POINT_SIZE))
#else
    glEnable(GLenum(GL_POINT_SPRITE_OES))
#endif

    crosshairShader.use()
    uniformSettings.restoreShaderSettings(crosshairShader)

    clearFramebufferWithColor(Color.transparent)

    guard let positionAttribute = crosshairShader.attributeIndex("position") else { fatalError("A position attribute was missing from the shader program during rendering.") }

    let convertedPositions = positions.flatMap{$0.toGLArray()}
    glVertexAttribPointer(positionAttribute, 2, GLenum(GL_FLOAT), 0, 0, convertedPositions)

    glDrawArrays(GLenum(GL_POINTS), 0, GLsizei(positions.count))

    notifyTargets()
  }
}

the initialization of corner detector remains the same:

FilterOperation(
    filter:{HarrisCornerDetector()},
    listName:"Harris corner detector",
    titleName:"Harris Corner Detector",
    sliderConfiguration:.enabled(minimumValue:0.01, maximumValue:0.70, initialValue:0.20),
    sliderUpdateCallback: {(filter, sliderValue) in
        filter.threshold = sliderValue
    },
    filterOperationType:.custom(filterSetupFunction:{(camera, filter, outputView) in
        let castFilter = filter as! HarrisCornerDetector
        // TODO: Get this more dynamically sized
#if os(iOS)
        let crosshairGenerator = CrosshairGenerator(size:Size(width:480, height:640))
#else
        let crosshairGenerator = CrosshairGenerator(size:Size(width:1280, height:720))
#endif
        crosshairGenerator.crosshairWidth = 30.0

        castFilter.cornersDetectedCallback = { corners in
            crosshairGenerator.renderCrosshairs(corners)
        }

        camera --> castFilter

        let blendFilter = AlphaBlend()
        camera --> blendFilter --> outputView
        crosshairGenerator --> blendFilter
        return blendFilter
    })
)

The code compiles and works fine, but the texture looks empty (coloured squares) when rendered on screen:

if I comment out this line - uniformSettings["inputImageTexture"] = crosshairImage - the result remains the same which makes me think the texture isn't passed to shader at all.

What I'm missing here?

来源:https://stackoverflow.com/questions/48296781/gpuimage2-passing-gl-texture-to-shader

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!