Java Code Examples for android.opengl.GLES20#glGetProgramInfoLog()

The following examples show how to use android.opengl.GLES20#glGetProgramInfoLog() . You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example 1
Source File: Utils.java    From alynx-live-wallpaper with Apache License 2.0 6 votes vote down vote up
static int linkProgramGLES20(
    final int vertShader,
    final int fragShader
) throws RuntimeException {
    int program = GLES20.glCreateProgram();
    if (program == 0) {
        throw new RuntimeException("Failed to create program");
    }
    GLES20.glAttachShader(program, vertShader);
    GLES20.glAttachShader(program, fragShader);
    GLES20.glLinkProgram(program);
    final int[] status = new int[1];
    GLES20.glGetProgramiv(program, GLES20.GL_LINK_STATUS, status, 0);
    if (status[0] == 0) {
        final String log = GLES20.glGetProgramInfoLog(program);
        GLES20.glDeleteProgram(program);
        throw new RuntimeException(log);
    }
    return program;
}
 
Example 2
Source File: EffectsShader.java    From YCAudioPlayer with Apache License 2.0 6 votes vote down vote up
void setProgram(String vertexSource, String fragmentSource) throws Exception {
	mIdShaderVertex = loadShader(GLES20.GL_VERTEX_SHADER, vertexSource);
	mIdShaderFragment = loadShader(GLES20.GL_FRAGMENT_SHADER, fragmentSource);
	int program = GLES20.glCreateProgram();
	if (program != 0) {
		GLES20.glAttachShader(program, mIdShaderVertex);
		GLES20.glAttachShader(program, mIdShaderFragment);
		GLES20.glLinkProgram(program);
		int[] linkStatus = new int[1];
		GLES20.glGetProgramiv(program, GLES20.GL_LINK_STATUS, linkStatus, 0);
		if (linkStatus[0] != GLES20.GL_TRUE) {
			String error = GLES20.glGetProgramInfoLog(program);
			deleteProgram();
			throw new Exception(error);
		}
	}
	mIdProgram = program;
	mShaderHandleMap.clear();
}
 
Example 3
Source File: RRGLProgram.java    From RedReader with GNU General Public License v3.0 6 votes vote down vote up
private void link() {

		if(mFragmentShaderHandle == null || mVertexShaderHandle == null) throw new RuntimeException();

		GLES20.glLinkProgram(mHandle);

		final int[] linkStatus = new int[1];
		GLES20.glGetProgramiv(mHandle, GLES20.GL_LINK_STATUS, linkStatus, 0);

		if(linkStatus[0] == 0) {
			final String log = GLES20.glGetProgramInfoLog(mHandle);
			GLES20.glDeleteProgram(mHandle);
			throw new RuntimeException(String.format(Locale.US, "Linker error: \"%s\".", log));
		}

		GLES20.glDetachShader(mHandle, mFragmentShaderHandle);
		GLES20.glDetachShader(mHandle, mVertexShaderHandle);

		GLES20.glDeleteShader(mFragmentShaderHandle);
		GLES20.glDeleteShader(mVertexShaderHandle);

		mFragmentShaderHandle = null;
		mVertexShaderHandle = null;
	}
 
Example 4
Source File: GLRenderer.java    From HoloKilo with GNU General Public License v3.0 6 votes vote down vote up
static void printLog(int shader) {

        IntBuffer logLength = IntBuffer.allocate(1);
        if (GLES20.glIsShader(shader)) {
            GLES20.glGetShaderiv(shader, GLES20.GL_INFO_LOG_LENGTH, logLength);
        } else if (GLES20.glIsProgram(shader)) {
            GLES20.glGetProgramiv(shader, GLES20.GL_INFO_LOG_LENGTH, logLength);
        } else {
            Log.e(Config.TAG, "printlog: Not a shader or a program");
            return;
        }

        String result = "";
        if (GLES20.glIsShader(shader))
            result = GLES20.glGetShaderInfoLog(shader);
        else if (GLES20.glIsProgram(shader))
            result = GLES20.glGetProgramInfoLog(shader);

        Log.e(Config.TAG, result);

    }
 
Example 5
Source File: VideoTextureRenderer.java    From AndroidOpenGLVideoDemo with Apache License 2.0 6 votes vote down vote up
private void loadShaders()
{
    int vertexShaderHandle = GLES20.glCreateShader(GLES20.GL_VERTEX_SHADER);
    GLES20.glShaderSource(vertexShaderHandle, VERTEX_SHADER_CODE);
    GLES20.glCompileShader(vertexShaderHandle);
    checkGlError("Vertex shader compile");

    int fragmentShaderHandle = GLES20.glCreateShader(GLES20.GL_FRAGMENT_SHADER);
    GLES20.glShaderSource(fragmentShaderHandle, FRAGMENT_SHADER_CODE);
    GLES20.glCompileShader(fragmentShaderHandle);
    checkGlError("Pixel shader compile");

    shaderProgram = GLES20.glCreateProgram();
    GLES20.glAttachShader(shaderProgram, vertexShaderHandle);
    GLES20.glAttachShader(shaderProgram, fragmentShaderHandle);
    GLES20.glLinkProgram(shaderProgram);
    checkGlError("Shader program compile");

    int[] status = new int[1];
    GLES20.glGetProgramiv(shaderProgram, GLES20.GL_LINK_STATUS, status, 0);
    if (status[0] != GLES20.GL_TRUE) {
        String error = GLES20.glGetProgramInfoLog(shaderProgram);
        Log.e("SurfaceTest", "Error while linking program:\n" + error);
    }

}
 
Example 6
Source File: GLToolbox.java    From android-MediaEffects with Apache License 2.0 5 votes vote down vote up
public static int createProgram(String vertexSource, String fragmentSource) {
    int vertexShader = loadShader(GLES20.GL_VERTEX_SHADER, vertexSource);
    if (vertexShader == 0) {
        return 0;
    }
    int pixelShader = loadShader(GLES20.GL_FRAGMENT_SHADER, fragmentSource);
    if (pixelShader == 0) {
        return 0;
    }

    int program = GLES20.glCreateProgram();
    if (program != 0) {
        GLES20.glAttachShader(program, vertexShader);
        checkGlError("glAttachShader");
        GLES20.glAttachShader(program, pixelShader);
        checkGlError("glAttachShader");
        GLES20.glLinkProgram(program);
        int[] linkStatus = new int[1];
        GLES20.glGetProgramiv(program, GLES20.GL_LINK_STATUS, linkStatus,
                0);
        if (linkStatus[0] != GLES20.GL_TRUE) {
            String info = GLES20.glGetProgramInfoLog(program);
            GLES20.glDeleteProgram(program);
            throw new RuntimeException("Could not link program: " + info);
        }
    }
    return program;
}
 
Example 7
Source File: GlShader.java    From webrtc_android with MIT License 5 votes vote down vote up
public GlShader(String vertexSource, String fragmentSource) {
  final int vertexShader = compileShader(GLES20.GL_VERTEX_SHADER, vertexSource);
  final int fragmentShader = compileShader(GLES20.GL_FRAGMENT_SHADER, fragmentSource);
  program = GLES20.glCreateProgram();
  if (program == 0) {
    throw new RuntimeException("glCreateProgram() failed. GLES20 error: " + GLES20.glGetError());
  }
  GLES20.glAttachShader(program, vertexShader);
  GLES20.glAttachShader(program, fragmentShader);
  GLES20.glLinkProgram(program);
  int[] linkStatus = new int[] {GLES20.GL_FALSE};
  GLES20.glGetProgramiv(program, GLES20.GL_LINK_STATUS, linkStatus, 0);
  if (linkStatus[0] != GLES20.GL_TRUE) {
    Logging.e(TAG, "Could not link program: " + GLES20.glGetProgramInfoLog(program));
    throw new RuntimeException(GLES20.glGetProgramInfoLog(program));
  }
  // According to the documentation of glLinkProgram():
  // "After the link operation, applications are free to modify attached shader objects, compile
  // attached shader objects, detach shader objects, delete shader objects, and attach additional
  // shader objects. None of these operations affects the information log or the program that is
  // part of the program object."
  // But in practice, detaching shaders from the program seems to break some devices. Deleting the
  // shaders are fine however - it will delete them when they are no longer attached to a program.
  GLES20.glDeleteShader(vertexShader);
  GLES20.glDeleteShader(fragmentShader);
  GlUtil.checkNoGLES2Error("Creating GlShader");
}
 
Example 8
Source File: Program.java    From PD-classes with GNU General Public License v3.0 5 votes vote down vote up
public void link() {
	GLES20.glLinkProgram( handle );
	
	int[] status = new int[1];
	GLES20.glGetProgramiv( handle, GLES20.GL_LINK_STATUS, status, 0 );
	if (status[0] == GLES20.GL_FALSE) {
		throw new Error( GLES20.glGetProgramInfoLog( handle ) );
	}
}
 
Example 9
Source File: Program.java    From remixed-dungeon with GNU General Public License v3.0 5 votes vote down vote up
public void link() {
	GLES20.glLinkProgram( handle );
	
	int[] status = new int[1];
	GLES20.glGetProgramiv( handle, GLES20.GL_LINK_STATUS, status, 0 );
	if (status[0] == GLES20.GL_FALSE) {
		throw new Error( GLES20.glGetProgramInfoLog( handle ) );
	}
}
 
Example 10
Source File: ShaderProgram.java    From 30-android-libraries-in-30-days with Apache License 2.0 5 votes vote down vote up
protected void link(final GLState pGLState) throws ShaderProgramLinkException {
	GLES20.glLinkProgram(this.mProgramID);

	GLES20.glGetProgramiv(this.mProgramID, GLES20.GL_LINK_STATUS, ShaderProgram.HARDWAREID_CONTAINER, 0);
	if(ShaderProgram.HARDWAREID_CONTAINER[0] == 0) {
		throw new ShaderProgramLinkException(GLES20.glGetProgramInfoLog(this.mProgramID));
	}

	this.initAttributeLocations();
	this.initUniformLocations();

	this.mCompiled = true;
}
 
Example 11
Source File: ShaderProgram.java    From tilt-game-android with MIT License 5 votes vote down vote up
protected void link(final GLState pGLState) throws ShaderProgramLinkException {
	GLES20.glLinkProgram(this.mProgramID);

	GLES20.glGetProgramiv(this.mProgramID, GLES20.GL_LINK_STATUS, ShaderProgram.HARDWAREID_CONTAINER, 0);
	if (ShaderProgram.HARDWAREID_CONTAINER[0] == 0) {
		throw new ShaderProgramLinkException(GLES20.glGetProgramInfoLog(this.mProgramID));
	}

	this.initAttributeLocations();
	this.initUniformLocations();

	this.mCompiled = true;
}
 
Example 12
Source File: GLToolbox.java    From Rocko-Android-Demos with Apache License 2.0 5 votes vote down vote up
public static int createProgram(String vertexSource,
                                String fragmentSource) {
    int vertexShader = loadShader(GLES20.GL_VERTEX_SHADER, vertexSource);
    if (vertexShader == 0) {
        return 0;
    }
    int pixelShader = loadShader(GLES20.GL_FRAGMENT_SHADER, fragmentSource);
    if (pixelShader == 0) {
        return 0;
    }

    int program = GLES20.glCreateProgram();
    if (program != 0) {
        GLES20.glAttachShader(program, vertexShader);
        checkGlError("glAttachShader");
        GLES20.glAttachShader(program, pixelShader);
        checkGlError("glAttachShader");
        GLES20.glLinkProgram(program);
        int[] linkStatus = new int[1];
        GLES20.glGetProgramiv(program, GLES20.GL_LINK_STATUS, linkStatus,
                0);
        if (linkStatus[0] != GLES20.GL_TRUE) {
            String info = GLES20.glGetProgramInfoLog(program);
            GLES20.glDeleteProgram(program);
            program = 0;
            throw new RuntimeException("Could not link program: " + info);
        }
    }
    return program;
}
 
Example 13
Source File: UWhiteningGPUVideoFilter.java    From UCDLive_Android with MIT License 5 votes vote down vote up
private static int createProgram(String vertexShaderCode, String fragmentShaderCode) {
    if (vertexShaderCode == null || fragmentShaderCode == null) {
        throw new RuntimeException("invalid shader code");
    }
    int vertexShader = GLES20.glCreateShader(GLES20.GL_VERTEX_SHADER);
    int fragmentShader = GLES20.glCreateShader(GLES20.GL_FRAGMENT_SHADER);

    GLES20.glShaderSource(vertexShader, vertexShaderCode);
    GLES20.glShaderSource(fragmentShader, fragmentShaderCode);
    int[] status = new int[1];
    GLES20.glCompileShader(vertexShader);
    GLES20.glGetShaderiv(vertexShader, GLES20.GL_COMPILE_STATUS, status, 0);
    if (GLES20.GL_FALSE == status[0]) {
        throw new RuntimeException("vertext shader compile failed:" + GLES20.glGetShaderInfoLog(vertexShader));
    }
    GLES20.glCompileShader(fragmentShader);
    GLES20.glGetShaderiv(fragmentShader, GLES20.GL_COMPILE_STATUS, status, 0);
    if (GLES20.GL_FALSE == status[0]) {
        throw new RuntimeException("fragment shader compile failed:" + GLES20.glGetShaderInfoLog(fragmentShader));
    }
    int program = GLES20.glCreateProgram();
    GLES20.glAttachShader(program, vertexShader);
    GLES20.glAttachShader(program, fragmentShader);
    GLES20.glLinkProgram(program);
    GLES20.glGetProgramiv(program, GLES20.GL_LINK_STATUS, status, 0);
    if (GLES20.GL_FALSE == status[0]) {
        throw new RuntimeException("link program failed:" + GLES20.glGetProgramInfoLog(program));
    }
    return program;
}
 
Example 14
Source File: GlShader.java    From VideoCRE with MIT License 5 votes vote down vote up
public GlShader(String vertexSource, String fragmentSource) {
  final int vertexShader = compileShader(GLES20.GL_VERTEX_SHADER, vertexSource);
  final int fragmentShader = compileShader(GLES20.GL_FRAGMENT_SHADER, fragmentSource);
  program = GLES20.glCreateProgram();
  if (program == 0) {
    throw new RuntimeException("glCreateProgram() failed. GLES20 error: " + GLES20.glGetError());
  }
  GLES20.glAttachShader(program, vertexShader);
  GLES20.glAttachShader(program, fragmentShader);
  GLES20.glLinkProgram(program);
  int[] linkStatus = new int[] {GLES20.GL_FALSE};
  GLES20.glGetProgramiv(program, GLES20.GL_LINK_STATUS, linkStatus, 0);
  if (linkStatus[0] != GLES20.GL_TRUE) {
    Logging.e(TAG, "Could not link program: " + GLES20.glGetProgramInfoLog(program));
    throw new RuntimeException(GLES20.glGetProgramInfoLog(program));
  }
  // According to the documentation of glLinkProgram():
  // "After the link operation, applications are free to modify attached shader objects, compile
  // attached shader objects, detach shader objects, delete shader objects, and attach additional
  // shader objects. None of these operations affects the information log or the program that is
  // part of the program object."
  // But in practice, detaching shaders from the program seems to break some devices. Deleting the
  // shaders are fine however - it will delete them when they are no longer attached to a program.
  GLES20.glDeleteShader(vertexShader);
  GLES20.glDeleteShader(fragmentShader);
  GlUtil.checkNoGLES2Error("Creating GlShader");
}
 
Example 15
Source File: GlShader.java    From sealrtc-android with MIT License 5 votes vote down vote up
public GlShader(String vertexSource, String fragmentSource) {
    final int vertexShader = compileShader(GLES20.GL_VERTEX_SHADER, vertexSource);
    final int fragmentShader = compileShader(GLES20.GL_FRAGMENT_SHADER, fragmentSource);
    program = GLES20.glCreateProgram();
    if (program == 0) {
        throw new RuntimeException(
                "glCreateProgram() failed. GLES20 error: " + GLES20.glGetError());
    }
    GLES20.glAttachShader(program, vertexShader);
    GLES20.glAttachShader(program, fragmentShader);
    GLES20.glLinkProgram(program);
    int[] linkStatus = new int[] {GLES20.GL_FALSE};
    GLES20.glGetProgramiv(program, GLES20.GL_LINK_STATUS, linkStatus, 0);
    if (linkStatus[0] != GLES20.GL_TRUE) {
        Log.e(TAG, "Could not link program: " + GLES20.glGetProgramInfoLog(program));
        throw new RuntimeException(GLES20.glGetProgramInfoLog(program));
    }
    // According to the documentation of glLinkProgram():
    // "After the link operation, applications are free to modify attached shader objects,
    // compile
    // attached shader objects, detach shader objects, delete shader objects, and attach
    // additional
    // shader objects. None of these operations affects the information log or the program that
    // is
    // part of the program object."
    // But in practice, detaching shaders from the program seems to break some devices. Deleting
    // the
    // shaders are fine however - it will delete them when they are no longer attached to a
    // program.
    GLES20.glDeleteShader(vertexShader);
    GLES20.glDeleteShader(fragmentShader);
    GlUtil.checkNoGLES2Error("Creating GlShader");
}
 
Example 16
Source File: GLToolbox.java    From PhotoEditor with MIT License 5 votes vote down vote up
static int createProgram(String vertexSource, String fragmentSource) {
    int vertexShader = loadShader(GLES20.GL_VERTEX_SHADER, vertexSource);
    if (vertexShader == 0) {
        return 0;
    }
    int pixelShader = loadShader(GLES20.GL_FRAGMENT_SHADER, fragmentSource);
    if (pixelShader == 0) {
        return 0;
    }

    int program = GLES20.glCreateProgram();
    if (program != 0) {
        GLES20.glAttachShader(program, vertexShader);
        checkGlError("glAttachShader");
        GLES20.glAttachShader(program, pixelShader);
        checkGlError("glAttachShader");
        GLES20.glLinkProgram(program);
        int[] linkStatus = new int[1];
        GLES20.glGetProgramiv(program, GLES20.GL_LINK_STATUS, linkStatus,
                0);
        if (linkStatus[0] != GLES20.GL_TRUE) {
            String info = GLES20.glGetProgramInfoLog(program);
            GLES20.glDeleteProgram(program);
            throw new RuntimeException("Could not link program: " + info);
        }
    }
    return program;
}
 
Example 17
Source File: GLToolbox.java    From graphics-samples with Apache License 2.0 5 votes vote down vote up
public static int createProgram(String vertexSource, String fragmentSource) {
    int vertexShader = loadShader(GLES20.GL_VERTEX_SHADER, vertexSource);
    if (vertexShader == 0) {
        return 0;
    }
    int pixelShader = loadShader(GLES20.GL_FRAGMENT_SHADER, fragmentSource);
    if (pixelShader == 0) {
        return 0;
    }

    int program = GLES20.glCreateProgram();
    if (program != 0) {
        GLES20.glAttachShader(program, vertexShader);
        checkGlError("glAttachShader");
        GLES20.glAttachShader(program, pixelShader);
        checkGlError("glAttachShader");
        GLES20.glLinkProgram(program);
        int[] linkStatus = new int[1];
        GLES20.glGetProgramiv(program, GLES20.GL_LINK_STATUS, linkStatus,
                0);
        if (linkStatus[0] != GLES20.GL_TRUE) {
            String info = GLES20.glGetProgramInfoLog(program);
            GLES20.glDeleteProgram(program);
            throw new RuntimeException("Could not link program: " + info);
        }
    }
    return program;
}
 
Example 18
Source File: AndroidGL.java    From trekarta with GNU General Public License v3.0 4 votes vote down vote up
@Override
public String getProgramInfoLog(int program) {
    return GLES20.glGetProgramInfoLog(program);
}
 
Example 19
Source File: OrientationView.java    From PanoramaGL with Apache License 2.0 4 votes vote down vote up
@Override
public final void onSurfaceCreated(GL10 unused, EGLConfig config) {
  // Set up shaders
  int vertexShader = GLES20.glCreateShader(GLES20.GL_VERTEX_SHADER);
  GLES20.glShaderSource(vertexShader, vertexShaderCode);
  GLES20.glCompileShader(vertexShader);

  int fragmentShader = GLES20.glCreateShader(GLES20.GL_FRAGMENT_SHADER);
  GLES20.glShaderSource(fragmentShader, fragmentShaderCode);
  GLES20.glCompileShader(fragmentShader);

  program = GLES20.glCreateProgram();
  GLES20.glAttachShader(program, vertexShader);
  GLES20.glAttachShader(program, fragmentShader);
  GLES20.glLinkProgram(program);

  int[] linkStatus = new int[1];
  GLES20.glGetProgramiv(program, GLES20.GL_LINK_STATUS, linkStatus, 0);
  if (linkStatus[0] != GLES20.GL_TRUE) {
    throw new GLException(linkStatus[0],
        "Unable to create shader program: " + GLES20.glGetProgramInfoLog(program));
  }

  // Set up geometry
  // 16 lines * 2 points * XYZ
  float[] boxVertexData = {
      // X-aligned lines of length 4
      -2, -1, -3,  2, -1, -3,
      -2, -1,  3,  2, -1,  3,
      -2,  1, -3,  2,  1, -3,
      -2,  1,  3,  2,  1,  3,
      // Y-aligned lines of length 2
      -2, -1, -3, -2,  1, -3,
      -2, -1,  3, -2,  1,  3,
       2, -1, -3,  2,  1, -3,
       2, -1,  3,  2,  1,  3,
      // Z-aligned lines of length 6
      -2, -1, -3, -2, -1,  3,
      -2,  1, -3, -2,  1,  3,
       2, -1, -3,  2, -1,  3,
       2,  1, -3,  2,  1,  3,
      // Trackpad diamond
      -1,  1, -1,  0,  1,  0,
       0,  1,  0,  1,  1, -1,
       1,  1, -1,  0,  1, -3,
       0,  1, -3, -1,  1, -1,
  };

  ByteBuffer buffer = ByteBuffer.allocateDirect(boxVertexData.length * 4);
  buffer.order(ByteOrder.nativeOrder());
  boxVertices = buffer.asFloatBuffer();
  boxVertices.put(boxVertexData);
  boxVertices.position(0);

  // The XYZ lines are RGB in the positive direction and black in the negative direction.
  // 16 lines * 2 points * RGBA
  float[] boxColorData = {
      // X-aligned lines
      0, 0, 0, 1, 1, 0, 0, 1,
      0, 0, 0, 1, 1, 0, 0, 1,
      0, 0, 0, 1, 1, 0, 0, 1,
      0, 0, 0, 1, 1, 0, 0, 1,
      // Y-aligned lines
      0, 0, 0, 1, 0, 1, 0, 1,
      0, 0, 0, 1, 0, 1, 0, 1,
      0, 0, 0, 1, 0, 1, 0, 1,
      0, 0, 0, 1, 0, 1, 0, 1,
      // Z-aligned lines
      0, 0, 0, 1, 0, 0, 1, 1,
      0, 0, 0, 1, 0, 0, 1, 1,
      0, 0, 0, 1, 0, 0, 1, 1,
      0, 0, 0, 1, 0, 0, 1, 1,
      // Trackpad
      0, 1, 0, 1, 0, 1, 0, 1,
      0, 1, 0, 1, 0, 1, 0, 1,
      0, 1, 0, 1, 0, 1, 0, 1,
      0, 1, 0, 1, 0, 1, 0, 1,
  };
  buffer = ByteBuffer.allocateDirect(boxColorData.length * 4);
  buffer.order(ByteOrder.nativeOrder());
  boxColors = buffer.asFloatBuffer();
  boxColors.put(boxColorData);
  boxColors.position(0);
}
 
Example 20
Source File: GLES20DrawContext.java    From settlers-remake with MIT License 4 votes vote down vote up
private ShaderProgram(String name) {
	int vertexShader = -1;
	int fragmentShader;

	String vname = name;
	if(name.contains("-")) vname = name.split("-")[0];

	try {
		vertexShader = createShader(vname+".vert", GLES20.GL_VERTEX_SHADER);
		fragmentShader = createShader(name+".frag", GLES20.GL_FRAGMENT_SHADER);
	} catch (IOException e) {
		e.printStackTrace();

		if(vertexShader != -1) GLES20.glDeleteShader(vertexShader);
		throw new Error("could not read shader files", e);
	}

	program = GLES20.glCreateProgram();

	GLES20.glAttachShader(program, vertexShader);
	GLES20.glAttachShader(program, fragmentShader);

	GLES20.glBindAttribLocation(program, 0, "vertex");
	GLES20.glBindAttribLocation(program, 1, "texcoord");
	GLES20.glBindAttribLocation(program, 2, "color");

	GLES20.glLinkProgram(program);
	GLES20.glValidateProgram(program);

	//GLES20.glDetachShader(program, vertexShader);
	//GLES20.glDetachShader(program, fragmentShader);
	GLES20.glDeleteShader(vertexShader);
	GLES20.glDeleteShader(fragmentShader);

	String log = GLES20.glGetProgramInfoLog(program);
	if(!log.isEmpty()) System.out.print("info log of " + name + "=====\n" + log + "==== end\n");

	int[] link_status = new int[1];
	GLES20.glGetProgramiv(program, GLES20.GL_LINK_STATUS, link_status, 0);
	if(link_status[0] == 0) {
		GLES20.glDeleteProgram(program);
		throw new Error("Could not link " + name);
	}

	for(int i = 0;i != ufs.length;i++) {
		int uf = GLES20.glGetUniformLocation(program, uniform_names[i]);
		ufs[i] = uf;
	}
	shaders.add(this);
}