# Compile the shaders, and this program, then link and report any errors
fun compile_and_link
do
# Get an index
var gl_program = glCreateProgram
if not glIsProgram(gl_program) then
self.error = new Error("Program creation failed: {glGetError.to_s}")
return
end
self.gl_program = gl_program
# Vertex shader
var vertex_shader = vertex_shader
vertex_shader.compile
if vertex_shader.error != null then
self.error = vertex_shader.error
return
end
# Fragment shader
var fragment_shader = fragment_shader
fragment_shader.compile
if fragment_shader.error != null then
self.error = fragment_shader.error
return
end
# Attach shaders
glAttachShader(gl_program, vertex_shader.gl_shader)
glAttachShader(gl_program, fragment_shader.gl_shader)
# Catch any errors up to here
var error = gammit_gl_error
if error != null then
self.error = error
return
end
# Link
glLinkProgram gl_program
if not gl_program.is_linked then
self.error = new Error("Linking failed: {glGetProgramInfoLog(gl_program)}")
return
end
# Fill the attribute and uniform lists
var n_attribs = glGetProgramiv(gl_program, gl_ACTIVE_ATTRIBUTES)
for a in [0..n_attribs[ do
var name = gl_program.active_attrib_name(a)
var size = gl_program.active_attrib_size(a)
var typ = gl_program.active_attrib_type(a)
var location = gl_program.attrib_location(name)
# FIXME location may be invalid at this point because
# attrib_location does not work with truncated names,
# as returned by `active_attrib_name`.
var attribute
if typ == gl_FLOAT then
attribute = new AttributeFloat(gl_program, name, location, size)
else if typ == gl_FLOAT_VEC2 then
attribute = new AttributeVec2(gl_program, name, location, size)
else if typ == gl_FLOAT_VEC3 then
attribute = new AttributeVec3(gl_program, name, location, size)
else if typ == gl_FLOAT_VEC4 then
attribute = new AttributeVec4(gl_program, name, location, size)
else
attribute = new Attribute(gl_program, name, location, size)
end
# TODO missing types
attributes[name] = attribute
end
var n_uniforms = glGetProgramiv(gl_program, gl_ACTIVE_UNIFORMS)
for a in [0..n_uniforms[ do
var name = gl_program.active_uniform_name(a)
var size = gl_program.active_uniform_size(a)
var typ = gl_program.active_uniform_type(a)
var location = gl_program.uniform_location(name)
var uniform
if typ == gl_BOOL then
uniform = new UniformBool(gl_program, name, location, size)
else if typ == gl_INT then
uniform = new UniformInt(gl_program, name, location, size)
else if typ == gl_SAMPLER_2D then
uniform = new UniformSampler2D(gl_program, name, location, size)
else if typ == gl_FLOAT then
uniform = new UniformFloat(gl_program, name, location, size)
else if typ == gl_FLOAT_VEC2 then
uniform = new UniformVec2(gl_program, name, location, size)
else if typ == gl_FLOAT_VEC3 then
uniform = new UniformVec3(gl_program, name, location, size)
else if typ == gl_FLOAT_VEC4 then
uniform = new UniformVec4(gl_program, name, location, size)
else if typ == gl_FLOAT_MAT4 then
uniform = new UniformMat4(gl_program, name, location, size)
else
uniform = new Uniform(gl_program, name, location, size)
end
# TODO missing types
uniforms[name] = uniform
end
end
lib/gamnit/programs.nit:336,2--440,4