2017-02-02 13 views
0

Как и в случае с простым VideoFilter и распознаванием лиц, я хотел бы выделить часть видеоролика GPUImage2 с цветными прямоугольниками. SolidColorGenerator кажется хорошим началом с двумя исключениями. Во-первых, я не уверен, как перенести вывод SolidColorGenerator в нужное место на моем исходном изображении. Во-вторых, я не уверен, как добавить N прямоугольников в исходное изображение. Между тем у меня был успех с LineGenerator, но я думаю, что прямоугольник будет выглядеть лучше.GPUImage2 использует SolidColorGenerator как RectangleGenerator

Бонус: Прямоугольники с закругленными углами и одна граница пикселей.

enter image description here

ответ

0

То, что сработало для меня писал RectangleGenerator. Ключ к новому RectangleGenerator должен был нарисовать GL_TRIANGLES.

glDrawArrays(GLenum(GL_TRIANGLES), 0, GLsizei(positions.count) * 2) 

Одна оптимизация, которую можно было бы сделать было бы использовать GL_Elements и GL_TRIANGLE_STRIP Полоса, хотя я не был в состоянии понять это.

enter image description here

Полное решение должно поддерживать границы, BorderWidth и cornerRadius. На данный момент достаточно простых прямоугольников. Полный код ниже.

let vertex = "attribute vec4 position; void main(){ gl_Position = position; }" 

let fragment = "uniform lowp vec3 fillColor; void main(){ gl_FragColor = vec4(fillColor, 1.0); }" 

public class RectangleGenerator: ImageGenerator { 

let rectangleShader:ShaderProgram 
var uniformSettings = ShaderUniformSettings() 

public var fillColor:Color = Color.green { didSet { uniformSettings["fillColor"] = fillColor } } 

public override init(size:Size) { 
    rectangleShader = crashOnShaderCompileFailure("RectangleGenerator"){try sharedImageProcessingContext.programForVertexShader(vertex, fragmentShader:fragment)} 
    super.init(size:size) 

    ({fillColor = Color.green})() 
} 

public func renderRectangles(_ positions:[Position]) { 
    guard positions.count > 3 else { return } 

    imageFramebuffer.activateFramebufferForRendering() 

    rectangleShader.use() 
    uniformSettings.restoreShaderSettings(rectangleShader) 
    clearFramebufferWithColor(Color.transparent) 

    guard let positionAttribute = rectangleShader.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) 

    glBlendEquation(GLenum(GL_FUNC_ADD)) 
    glBlendFunc(GLenum(GL_ONE), GLenum(GL_ONE)) 
    glEnable(GLenum(GL_BLEND)) 

    glDrawArrays(GLenum(GL_TRIANGLES), 0, GLsizei(positions.count) * 2) 
    glDisable(GLenum(GL_BLEND)) 

    notifyTargets() 
} 
} 

Счастливый Coding