protected void linkProgram(List<VertexAttrib> attribLocations) throws LWJGLException {
		if (!valid())
			throw new LWJGLException("trying to link an invalid (i.e. released) program");

		uniforms.clear();

		// bind user-defined attribute locations
		if (attribLocations != null) {
			for (VertexAttrib a : attribLocations) {
				if (a != null)
					glBindAttribLocation(program, a.location, a.name);
			}
		}

		attachShaders();
		glLinkProgram(program);
		int comp = glGetProgrami(program, GL_LINK_STATUS);
		int len = glGetProgrami(program, GL_INFO_LOG_LENGTH);
		String err = glGetProgramInfoLog(program, len);
		if (err != null && err.length() != 0)
			log = err + "\n" + log;
		if (log != null)
			log = log.trim();
		if (comp == GL11.GL_FALSE)
			throw new LWJGLException(log.length()!=0 ? log : "Could not link program");

		fetchUniforms();
		fetchAttributes();
	}