我在Swift中创建了一个自定义NGOpenGLView,我正在尝试编译一些着色器。我得到着色器编译错误,但glGetShaderInfoLog什么也没有返回......无法调试。 然而,着色器使用OpenGL Shader构建器进行编译,因此我不知道出了什么问题。
这就是我编译着色器并尝试获取信息的方式,
class CustomOpenGLView : NSOpenGLView {
override func awakeFromNib() {
var attributes : [NSOpenGLPixelFormatAttribute] = [
NSOpenGLPixelFormatAttribute(NSOpenGLPFADepthSize),
NSOpenGLPixelFormatAttribute(24),
NSOpenGLPixelFormatAttribute(NSOpenGLPFAOpenGLProfile),
NSOpenGLPixelFormatAttribute(NSOpenGLProfileVersion3_2Core),
NSOpenGLPixelFormatAttribute(0)]
self.pixelFormat = NSOpenGLPixelFormat(attributes: attributes)
initShaders()
}
override func drawRect(dirtyRect: NSRect) {
glClearColor(0, 0, 0, 1)
glClear(GLbitfield(GL_COLOR_BUFFER_BIT))
//drawAnObject()
glFlush()
}
func compileShader(shaderName: NSString, shaderType: GLenum) -> GLuint {
let shaderPath: NSString? = NSBundle.mainBundle().pathForResource(shaderName, ofType: nil)
if shaderPath == nil {
println("Can't find shader \(shaderName)")
return 0
}
var error: NSError? = nil
let shaderString = NSString(contentsOfFile: shaderPath!, encoding: NSUTF8StringEncoding, error: &error)
if shaderString == nil {
println("Failed to set contents shader of shader file!")
return 0
}
var shaderHandle: GLuint = glCreateShader(shaderType)
var shaderStringUTF8 = shaderString!.cStringUsingEncoding(NSUTF8StringEncoding)
var shaderStringLength: GLint = GLint(shaderString!.length)
glShaderSource(shaderHandle, 1, &shaderStringUTF8, &shaderStringLength)
glCompileShader(shaderHandle)
var compileSuccess: GLint = GLint()
glGetShaderiv(shaderHandle, GLenum(GL_COMPILE_STATUS), &compileSuccess)
if (compileSuccess == GL_FALSE) {
println("Failed to compile shader! \(shaderName)")
var value: GLint = 0
glGetShaderiv(shaderHandle, GLenum(GL_INFO_LOG_LENGTH), &value)
var infoLog: [GLchar] = [GLchar](count: Int(value), repeatedValue: 0)
var infoLogLength: GLsizei = 0
glGetShaderInfoLog(shaderHandle, value, &infoLogLength, &infoLog)
var s = NSString(bytes: infoLog, length: Int(infoLogLength), encoding: NSASCIIStringEncoding)
println(s)
return 0
}
return shaderHandle
}
func initShaders() {
// Compile our vertex and fragment shaders.
var vertexShader: GLuint = self.compileShader("geometryColor.vs", shaderType: GLenum(GL_VERTEX_SHADER))
var fragmentShader: GLuint = self.compileShader("color.fs", shaderType: GLenum(GL_FRAGMENT_SHADER))
// ... etc
}
}
vs shader就是这个,
attribute vec3 position;
attribute vec4 color;
uniform mat4 Pmatrix;
uniform mat4 Vmatrix;
uniform mat4 Mmatrix;
varying vec4 vColor;
void main(void) { // pre-built function
gl_Position = Pmatrix * Vmatrix * Mmatrix * vec4(position, 1.);
vColor = color;
}
但我也尝试过更新的语法
in vec3 position;
in vec4 color;
uniform mat4 Pmatrix;
uniform mat4 Vmatrix;
uniform mat4 Mmatrix;
out vec4 vColor;
void main(void) { // pre-built function
gl_Position = Pmatrix * Vmatrix * Mmatrix * vec4(position, 1.);
vColor = color;
}
glClear正在工作,所以视图本身似乎很好。 如何调试这个?
答案 0 :(得分:0)
尝试在创建和编译着色器之前使上下文保持最新状态,我不熟悉swift,但在您发布的代码中似乎没有做任何事情。
我遇到了同样的问题,这个答案还有另一个问题,但我找不到......
答案 1 :(得分:0)
使用桥接文件在objc中实现。这对我有用。 对于桥接标题:
/**
* return 0 on failure
*/
extern GLuint CompileShader(GLenum shaderType, NSString* _Nonnull source);
/***
* get last gl error message
*/
extern NSString* _Nullable GetLastGLErrorMessage();
其实施:
static NSString* ___AM_global_error_message__;
GLuint CompileShader(GLenum shaderType, NSString* _Nonnull source)
{
GLuint shader = glCreateShader(shaderType);
const GLchar* glSource = (GLchar*) source.UTF8String;
glShaderSource(shader, 1, &glSource, 0);
glCompileShader(shader);
GLint compileResult;
glGetShaderiv(shader, GL_COMPILE_STATUS, &compileResult);
if (GL_FALSE == compileResult)
{
GLchar messages[4090];
glGetShaderInfoLog(shader, sizeof(messages), 0, &messages[0]);
NSLog(@"- shader compile error!!! : %s", messages);
___AM_global_error_message__ = [NSString stringWithFormat:@"%s", messages];
return shader;
}
return shader;
}
NSString* GetLastGLErrorMessage()
{
return ___AM_global_error_message__;
}
在swift文件中使用:
private func __createShader(type: GLenum, filename: String) -> GLuint {
let resourcePath = NSBundle.mainBundle().pathForResource(filename, ofType: "shader")
// failed to load the file return 0 indicates error occured.
guard resourcePath != nil else { return 0 }
let fileContent = try! String(contentsOfFile: resourcePath!)
let ret = CompileShader(type, fileContent)
if ret == 0
{
print(GetLastGLErrorMessage())
return 0
}
return ret
}