ios - 当我编译 `GLSL` 代码时,出现错误 'ERROR: 0:15: ' premature EOF' : syntax error syntax error'

标签 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);
}

这让我困惑了很长时间。

最佳答案

我已经解决了这个问题。原因是我无法正确读取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)

关于ios - 当我编译 `GLSL` 代码时,出现错误 'ERROR: 0:15: ' premature EOF' : syntax error syntax error',我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56627835/

相关文章:

ios - 当键盘出现 Swift 时,使用文本字段和按钮向上移动 View

ios - 如何隐藏和取消隐藏 UIAlertView。?

ios - 为什么我不能遍历 NSArray?

ios - 从空 Swift 数组中获取对象类型

Android 动态壁纸 -- OpenGL 与 Canvas

java - Android OpenGL ES - 我无法使 gluLookAt/gluPerspective 工作

ios - 声明 IBOutlet 时使用类型别名

string - Swift nil 可选字符串 = 空字符串

ios - 如何在应用程序未运行时保存 UISwitch 状态(Swift)

android - 将 3d 对象渲染到 Cameraview