Skip to content

Instantly share code, notes, and snippets.

@ErikHellman
Last active August 29, 2015 14:05
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ErikHellman/d4c04005ec4401e3213a to your computer and use it in GitHub Desktop.
Save ErikHellman/d4c04005ec4401e3213a to your computer and use it in GitHub Desktop.
Simple renderer for a pixel shader on Android
public class VisualizationRenderer implements GLSurfaceView.Renderer {
private static final int FLOAT_SIZE_BYTES = Float.SIZE / Byte.SIZE;
private final FloatBuffer mRectData;
private final Context mContext;
private String mVertexShader;
private String mFragmentShader;
public VisualizationRenderer(Context context) {
mContext = context;
float[] rectData = new float[]{
-1f, -1f,
-1f, 1f,
1f, -1f,
1f, 1f,
};
mRectData = ByteBuffer.allocateDirect(rectData.length * FLOAT_SIZE_BYTES)
.order(ByteOrder.nativeOrder()).asFloatBuffer();
mRectData.put(rectData).position(0);
mVertexShader = readShader(R.raw.vertex_shader, context);
mFragmentShader = readShader(R.raw.fragment_shader, context);
}
@Override
public void onSurfaceCreated(GL10 gl, EGLConfig config) {
int program = createProgram(mVertexShader, mFragmentShader);
if (program == 0) {
Log.e(TAG, "createProgram failed!");
return;
}
int maPositionHandle = GLES20.glGetAttribLocation(program, "aPosition");
checkGlError("glGetAttribLocation aPosition");
if (maPositionHandle == -1) {
throw new RuntimeException("Could not get attrib location for aPosition");
}
GLES20.glUseProgram(program);
checkGlError("glUseProgram mProgram");
GLES20.glEnableVertexAttribArray(maPositionHandle);
checkGlError("glEnableVertexAttribArray maPositionHandle");
mRectData.position(0);
GLES20.glVertexAttribPointer(maPositionHandle, 2, GLES20.GL_FLOAT, false, 0, mRectData);
checkGlError("glVertexAttribPointer maPosition");
}
@Override
public void onSurfaceChanged(GL10 gl, int width, int height) {
GLES20.glViewport(0, 0, width, height);
checkGlError("glViewPort");
}
@Override
public void onDrawFrame(GL10 gl) {
GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT);
checkGlError("glClear");
GLES20.glClearColor(1.0f, 0.0f, 0.0f, 1.0f);
checkGlError("glClearColor");
GLES20.glDrawArrays(GLES20.GL_TRIANGLE_STRIP, 0, 4);
checkGlError("glDrawArrays");
}
private int loadShader(int shaderType, String source) {
int shader = GLES20.glCreateShader(shaderType);
if (shader != 0) {
GLES20.glShaderSource(shader, source);
GLES20.glCompileShader(shader);
int[] compiled = new int[1];
GLES20.glGetShaderiv(shader, GLES20.GL_COMPILE_STATUS, compiled, 0);
if (compiled[0] == 0) {
Log.e(TAG, "Could not compile shader " + shaderType + ":");
Log.e(TAG, GLES20.glGetShaderInfoLog(shader));
GLES20.glDeleteShader(shader);
shader = 0;
}
}
return shader;
}
private 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) {
Log.e(TAG, "Could not link program: ");
Log.e(TAG, GLES20.glGetProgramInfoLog(program));
GLES20.glDeleteProgram(program);
program = 0;
}
}
return program;
}
private static String readShader(int resource, Context context) {
Resources resources = context.getResources();
InputStream inputStream = resources.openRawResource(resource);
InputStreamReader inputStreamReader = new InputStreamReader(inputStream);
BufferedReader bufferedReader = new BufferedReader(inputStreamReader);
char[] buffer = new char[32];
int charsRead;
StringBuilder stringBuilder = new StringBuilder();
try {
while ((charsRead = bufferedReader.read(buffer)) != -1) {
stringBuilder.append(buffer, 0, charsRead);
}
} catch (IOException e) {
Log.e(TAG, "Error reading resource " + resource, e);
}
return stringBuilder.toString();
}
private void checkGlError(String op) {
int error;
boolean hasError = false;
while ((error = GLES20.glGetError()) != GLES20.GL_NO_ERROR) {
Log.e(TAG, op + ": glError " + error);
hasError = true;
}
if (hasError) {
throw new RuntimeException(op + ": glError " + error);
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment