Reputation: 311
I have written a piece of code to compile a shader.
class DFShader {
let ID: GLuint
init(vPath: String, fPath: String) {
ID = glCreateProgram()
let vertex = compile(type: GLenum(GL_VERTEX_SHADER), path: vPath)
let fragment = compile(type: GLenum(GL_FRAGMENT_SHADER), path: fPath)
var success: GLint = 1
glAttachShader(ID, vertex)
glAttachShader(ID, fragment)
glLinkProgram(ID)
glGetProgramiv(ID, GLenum(GL_LINK_STATUS), &success)
if success == GL_FALSE {
let infoLog = UnsafeMutablePointer<GLchar>.allocate(capacity: 512)
glGetProgramInfoLog(ID, 512, nil, infoLog)
print("link program error. \(String.init(cString: infoLog))")
}
glDeleteShader(vertex)
glDeleteShader(fragment)
//log
print("model", glGetUniformLocation(ID, "model")) // print 4
print("projection", glGetUniformLocation(ID, "projection")) // print 0
print(ID.description)
}
private func compile(type: GLenum, path: String) -> GLuint {
let shader = glCreateShader(type)
var success: GLint = 1
do {
let source = try String.init(contentsOfFile: path, encoding: String.Encoding.utf8).cString(using: String.Encoding.utf8)
var castSource = UnsafePointer<GLchar>(source)
glShaderSource(shader, 1, &castSource, nil)
glCompileShader(shader)
glGetShaderiv(shader, GLenum(GL_COMPILE_STATUS), &success)
if success == GL_FALSE {
let infoLog = UnsafeMutablePointer<GLchar>.allocate(capacity: 512)
glGetShaderInfoLog(shader, 512, nil, &infoLog.pointee)
print("compile error. \(String.init(cString: infoLog))")
}
} catch {
print("failed to read from shader source file.")
}
return shader
}
func use() {
glUseProgram(ID)
}
}
//vertex shader code
#version 300 es
layout(location = 0) in vec2 position;
out vec4 VertexColor;
uniform mat4 model;
uniform mat4 projection;
uniform float pointSize;
uniform vec4 color;
void main() {
VertexColor = color;
gl_Position = projection * model * vec4(position, 0.0, 1.0);
gl_PointSize = 10.0f;
}
//fragment shader code
#version 300 es
precision mediump float;
out vec4 FragColor;
in vec4 VertexColor;
void main() {
FragColor = VertexColor;
}
//In the view
...
func setupShaders() {
shader.use()
let projection = GLKMatrix4MakeOrtho(0, Float(width), 0, Float(height), -1, 1)
shader.setMat4(name: "projection", value: projection)
print("projection", glGetUniformLocation(shader.ID, "projection")) // print -1.
...
}
I want to get the right location of all uniform and attribute value.
But the uniform location I get from DFShader instance is -1. And I only get the right location in
init(vPath: String, fPath: String)
, which print 0 and 4 in the code above. However, when I get location in
setupShaders()
it return -1. I get location with shader.ID at any other place, I am also given -1.
Upvotes: 0
Views: 224
Reputation: 473352
Shader objects don't have uniform locations. Only program objects do.
A shader object is nothing more than an intermediary between textual shaders and the final program. They don't actually do much. They don't have state to query.
Upvotes: 1