当我编译`GLSL`代码时,出现错误'ERROR:0:15:'Premature EOF':语法错误语法错误'

时间:2019-06-17 08:49:31

标签: ios swift opengl-es

我是OpenGLES的新朋友。当我编译GLSL代码时,我遇到了麻烦。我的快速代码如下:

import UIKit
import OpenGLES

class DowImageView: UIView {

    private var mEaglLayer: CAEAGLLayer?
    private var mContext: EAGLContext?

    private var mColorRenderBuffer = GLuint()
    private var mColorFrameBuffer = GLuint()
    private var mprograme = GLuint()

    override class var layerClass: AnyClass {
        get {
            return CAEAGLLayer.self
        }
    }

    override func layoutSubviews() {
        setupLayer()
        setupContext()
        deleteRenderAndFrameBuffer()
        setupRenderBuffer()
        setupFrameBuffer()
        renderLayer()
    }

    private func setupLayer() {
        mEaglLayer = self.layer as? CAEAGLLayer
        mEaglLayer?.isOpaque = true
        self.contentScaleFactor = UIScreen.main.scale
        mEaglLayer?.drawableProperties = [kEAGLDrawablePropertyRetainedBacking: false,
                                          kEAGLDrawablePropertyColorFormat: kEAGLColorFormatRGBA8]
    }

    private func setupContext() {
        let context = EAGLContext(api: EAGLRenderingAPI.openGLES3)
        EAGLContext.setCurrent(context)
        mContext = context
    }

    //清空缓存区
    private func deleteRenderAndFrameBuffer() {

        glDeleteBuffers(1, &mColorRenderBuffer)
        mColorRenderBuffer = 0
        glDeleteBuffers(1, &mColorFrameBuffer)
        mColorFrameBuffer = 0
    }

    private func setupRenderBuffer() {

        var buffer = GLuint()
        glGenRenderbuffers(1, &buffer)
        mColorRenderBuffer = buffer

        glBindRenderbuffer(GLenum(GL_RENDERBUFFER), mColorRenderBuffer)
        mContext?.renderbufferStorage(Int(GL_RENDERBUFFER), from: mEaglLayer)
    }

    private func setupFrameBuffer() {
        var buffer = GLuint()
        glGenFramebuffers(1, &buffer)
        mColorFrameBuffer = buffer
        glBindFramebuffer(GLenum(GL_FRAMEBUFFER), mColorFrameBuffer)
        glFramebufferRenderbuffer(GLenum(GL_FRAMEBUFFER), GLenum(GL_COLOR_ATTACHMENT0), GLenum(GL_RENDERBUFFER), mColorRenderBuffer)

    }

    private func renderLayer() {
        glClearColor(0.9, 0.8, 0.5, 1.0)
        glClear(GLbitfield(GL_COLOR_BUFFER_BIT))
        let scale = UIScreen.main.scale
        let frame = self.frame
        glViewport(0, 0, GLsizei(frame.size.width * scale), GLsizei(frame.size.height * scale))


        let verFile = Bundle.main.path(forResource: "shaderv", ofType: "vsh")
        let fragFile = Bundle.main.path(forResource: "shaderf", ofType: "fsh")

        if (mprograme != 0) {
            glDeleteProgram(mprograme)
            mprograme = 0
        }

        attachToProgram(with: verFile, fragFIle: fragFile)


        glLinkProgram(mprograme)

        var linkStatus = GLint()
        glGetProgramiv(mprograme, GLenum(GL_LINK_STATUS), &linkStatus)

        if linkStatus == GL_FALSE {
            var message = [GLchar]()
            glGetProgramInfoLog(mprograme, GLsizei(MemoryLayout<GLchar>.size * 512), nil, &message)
            let errorInfo = String(cString: message, encoding: .utf8)
            print("programErrorInfo" + (errorInfo ?? ""))
            return
        }
        print("?? link success")

    }


    private func attachToProgram(with verFile: String?, fragFIle: String?) {
        guard let verFile = verFile, let fragFIle = fragFIle else { return }
        var verShader = GLuint()
        var fragShader = GLuint()
        let program = glCreateProgram()
        compileshader(with: &verShader, type: GLenum(GL_VERTEX_SHADER), file: verFile)
        compileshader(with: &fragShader, type: GLenum(GL_FRAGMENT_SHADER), file: fragFIle)

        glAttachShader(program, verShader)
        glAttachShader(program, fragShader)

        glDeleteShader(verShader)
        glDeleteShader(fragShader)

        mprograme = program
    }

    private func compileshader(with  shader: inout GLuint,
                               type: GLenum,
                               file: String) {

        let content = try? String(contentsOfFile: file, encoding: String.Encoding.utf8)
        var source = UnsafePointer<GLchar>(content)

        shader = glCreateShader(type)

        glShaderSource(shader, 1,&source, nil)
        glCompileShader(shader)

        var sucess = GLint()
        glGetShaderiv(shader, GLenum(GL_COMPILE_STATUS), &sucess)
        if sucess == GL_FALSE {
            var message = [GLchar]()
            glGetShaderInfoLog(shader, GLsizei(MemoryLayout<GLchar>.size * 512), nil, &message)
            let errorInfo = String(cString: message, encoding: .utf8)
            print("shaderErrorInfo:" + (errorInfo ?? ""))
        }
    }
}


shaderv.vsh代码如下:

attribute vec4 position;
attribute vec4 positionColor;
attribute vec2 textCoordinate;
uniform mat4 projectionMatrix;
uniform mat4 modelViewMatrix;
varying lowp vec2 varyTextCoord;
varying lowp vec4 varyColor;

void main() {
    varyTextCoord = textCoordinate;
    varyColor = positionColor;

    vec4 vPos;
    vPos = projectionMatrix * modelViewMatrix * position;
    gl_Position = vPos;
}

shaderf.fsh代码如下:

precision highp float;

varying lowp vec2 varyTextCoord;
varying lowp vec4 varyColor;
uniform sampler2D colorMap;

void main() {
    vec4 cs = texture2D(colorMap,varyTextCoord);
    vec4 cd = varyColor;
    float s = 0.2;
    float d = 0.5;
    vec4 color = (cs * s) + (cd * d);
    gl_FragColor = color;
}

运行此程序时,我将收到以下错误:

shaderErrorInfo:ERROR: 0:15: 'premature EOF' : syntax error syntax error

shaderErrorInfo:ERROR: 0:13: 'premature EOF' : syntax error syntax error

programErrorInfoERROR: One or more attached shaders not successfully compiled

但是当我更改GLSL代码时,它将成功链接。成功的shaderv.vsh代码如下:

attribute vec4 position;
attribute vec2 textCoordinate;
varying lowp vec2 varyTextCoord;

void main() {
    varyTextCoord = textCoordinate;
    gl_Position = position;
}


shaderf.fsh代码如下:

varying lowp vec2 varyTextCoord;
uniform sampler2D colorMap;

void main() {
    lowp vec2 textCoord = vec2(varyTextCoord.x, 1.0 - varyTextCoord.y);
    gl_FragColor = texture2D(colorMap, textCoord);
}

很长一段时间让我感到困惑。

1 个答案:

答案 0 :(得分:1)

我已经解决了这个问题。原因是我无法正确读取 shader 代码。我错误地使用了以下 func

private func compileshader(with  shader: inout GLuint,
                               type: GLenum,
                               file: String) {
        let content = try? String(contentsOfFile: file, encoding: String.Encoding.utf8)
        var source = UnsafePointer<GLchar>(content)
        ...
}

应将其转换为cString,如下所示:

let content = try? String(contentsOfFile: file, encoding: String.Encoding.utf8)
let contentCString = content?.cString(using: .utf8)
var source = UnsafePointer<GLchar>(contentCString)

或者您可以使用 NSString 方法:

let content = try? NSString(contentsOfFile: file, encoding: String.Encoding.utf8.rawValue)
var contentCString = content?.utf8String
var contentLength: GLint = GLint(Int32(content!.length))
...
glShaderSource(shader, GLsizei(1),&contentCString, &contentLength)