我是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);
}
很长一段时间让我感到困惑。
答案 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)