private ProgramData loadProgram(String vertexShaderFilename, String fragmentShaderFilename) {
    ArrayList<Integer> shaderList = new ArrayList<>();
    shaderList.add(Framework.loadShader(GL_VERTEX_SHADER, vertexShaderFilename));
    shaderList.add(Framework.loadShader(GL_FRAGMENT_SHADER, fragmentShaderFilename));

    ProgramData data = new ProgramData();
    data.theProgram = Framework.createProgram(shaderList);
    data.cameraToClipMatrixUnif = glGetUniformLocation(data.theProgram, "cameraToClipMatrix");

    return data;
  }
  private ProgramData loadProgram(String vertexShaderFilename, String fragmentShaderFilename) {
    ArrayList<Integer> shaderList = new ArrayList<>();
    shaderList.add(Framework.loadShader(GL_VERTEX_SHADER, vertexShaderFilename));
    shaderList.add(Framework.loadShader(GL_FRAGMENT_SHADER, fragmentShaderFilename));

    ProgramData data = new ProgramData();
    data.theProgram = Framework.createProgram(shaderList);
    data.modelToCameraMatrixUnif = glGetUniformLocation(data.theProgram, "modelToCameraMatrix");
    data.normalModelToCameraMatrixUnif =
        glGetUniformLocation(data.theProgram, "normalModelToCameraMatrix");
    data.dirToLightUnif = glGetUniformLocation(data.theProgram, "dirToLight");
    data.lightIntensityUnif = glGetUniformLocation(data.theProgram, "lightIntensity");

    int projectionBlock = glGetUniformBlockIndex(data.theProgram, "Projection");
    glUniformBlockBinding(data.theProgram, projectionBlock, projectionBlockIndex);

    return data;
  }