| OLD | NEW |
| (Empty) |
| 1 /* | |
| 2 * Copyright 2015 The WebRTC project authors. All Rights Reserved. | |
| 3 * | |
| 4 * Use of this source code is governed by a BSD-style license | |
| 5 * that can be found in the LICENSE file in the root of the source | |
| 6 * tree. An additional intellectual property rights grant can be found | |
| 7 * in the file PATENTS. All contributing project authors may | |
| 8 * be found in the AUTHORS file in the root of the source tree. | |
| 9 */ | |
| 10 | |
| 11 package org.webrtc; | |
| 12 | |
| 13 import android.opengl.GLES20; | |
| 14 | |
| 15 import java.nio.FloatBuffer; | |
| 16 | |
| 17 // Helper class for handling OpenGL shaders and shader programs. | |
| 18 public class GlShader { | |
| 19 private static final String TAG = "GlShader"; | |
| 20 | |
| 21 private static int compileShader(int shaderType, String source) { | |
| 22 final int shader = GLES20.glCreateShader(shaderType); | |
| 23 if (shader == 0) { | |
| 24 throw new RuntimeException("glCreateShader() failed. GLES20 error: " + GLE
S20.glGetError()); | |
| 25 } | |
| 26 GLES20.glShaderSource(shader, source); | |
| 27 GLES20.glCompileShader(shader); | |
| 28 int[] compileStatus = new int[] {GLES20.GL_FALSE}; | |
| 29 GLES20.glGetShaderiv(shader, GLES20.GL_COMPILE_STATUS, compileStatus, 0); | |
| 30 if (compileStatus[0] != GLES20.GL_TRUE) { | |
| 31 Logging.e( | |
| 32 TAG, "Could not compile shader " + shaderType + ":" + GLES20.glGetShad
erInfoLog(shader)); | |
| 33 throw new RuntimeException(GLES20.glGetShaderInfoLog(shader)); | |
| 34 } | |
| 35 GlUtil.checkNoGLES2Error("compileShader"); | |
| 36 return shader; | |
| 37 } | |
| 38 | |
| 39 private int program; | |
| 40 | |
| 41 public GlShader(String vertexSource, String fragmentSource) { | |
| 42 final int vertexShader = compileShader(GLES20.GL_VERTEX_SHADER, vertexSource
); | |
| 43 final int fragmentShader = compileShader(GLES20.GL_FRAGMENT_SHADER, fragment
Source); | |
| 44 program = GLES20.glCreateProgram(); | |
| 45 if (program == 0) { | |
| 46 throw new RuntimeException("glCreateProgram() failed. GLES20 error: " + GL
ES20.glGetError()); | |
| 47 } | |
| 48 GLES20.glAttachShader(program, vertexShader); | |
| 49 GLES20.glAttachShader(program, fragmentShader); | |
| 50 GLES20.glLinkProgram(program); | |
| 51 int[] linkStatus = new int[] {GLES20.GL_FALSE}; | |
| 52 GLES20.glGetProgramiv(program, GLES20.GL_LINK_STATUS, linkStatus, 0); | |
| 53 if (linkStatus[0] != GLES20.GL_TRUE) { | |
| 54 Logging.e(TAG, "Could not link program: " + GLES20.glGetProgramInfoLog(pro
gram)); | |
| 55 throw new RuntimeException(GLES20.glGetProgramInfoLog(program)); | |
| 56 } | |
| 57 // According to the documentation of glLinkProgram(): | |
| 58 // "After the link operation, applications are free to modify attached shade
r objects, compile | |
| 59 // attached shader objects, detach shader objects, delete shader objects, an
d attach additional | |
| 60 // shader objects. None of these operations affects the information log or t
he program that is | |
| 61 // part of the program object." | |
| 62 // But in practice, detaching shaders from the program seems to break some d
evices. Deleting the | |
| 63 // shaders are fine however - it will delete them when they are no longer at
tached to a program. | |
| 64 GLES20.glDeleteShader(vertexShader); | |
| 65 GLES20.glDeleteShader(fragmentShader); | |
| 66 GlUtil.checkNoGLES2Error("Creating GlShader"); | |
| 67 } | |
| 68 | |
| 69 public int getAttribLocation(String label) { | |
| 70 if (program == -1) { | |
| 71 throw new RuntimeException("The program has been released"); | |
| 72 } | |
| 73 int location = GLES20.glGetAttribLocation(program, label); | |
| 74 if (location < 0) { | |
| 75 throw new RuntimeException("Could not locate '" + label + "' in program"); | |
| 76 } | |
| 77 return location; | |
| 78 } | |
| 79 | |
| 80 /** | |
| 81 * Enable and upload a vertex array for attribute |label|. The vertex data is
specified in | |
| 82 * |buffer| with |dimension| number of components per vertex. | |
| 83 */ | |
| 84 public void setVertexAttribArray(String label, int dimension, FloatBuffer buff
er) { | |
| 85 if (program == -1) { | |
| 86 throw new RuntimeException("The program has been released"); | |
| 87 } | |
| 88 int location = getAttribLocation(label); | |
| 89 GLES20.glEnableVertexAttribArray(location); | |
| 90 GLES20.glVertexAttribPointer(location, dimension, GLES20.GL_FLOAT, false, 0,
buffer); | |
| 91 GlUtil.checkNoGLES2Error("setVertexAttribArray"); | |
| 92 } | |
| 93 | |
| 94 public int getUniformLocation(String label) { | |
| 95 if (program == -1) { | |
| 96 throw new RuntimeException("The program has been released"); | |
| 97 } | |
| 98 int location = GLES20.glGetUniformLocation(program, label); | |
| 99 if (location < 0) { | |
| 100 throw new RuntimeException("Could not locate uniform '" + label + "' in pr
ogram"); | |
| 101 } | |
| 102 return location; | |
| 103 } | |
| 104 | |
| 105 public void useProgram() { | |
| 106 if (program == -1) { | |
| 107 throw new RuntimeException("The program has been released"); | |
| 108 } | |
| 109 GLES20.glUseProgram(program); | |
| 110 GlUtil.checkNoGLES2Error("glUseProgram"); | |
| 111 } | |
| 112 | |
| 113 public void release() { | |
| 114 Logging.d(TAG, "Deleting shader."); | |
| 115 // Delete program, automatically detaching any shaders from it. | |
| 116 if (program != -1) { | |
| 117 GLES20.glDeleteProgram(program); | |
| 118 program = -1; | |
| 119 } | |
| 120 } | |
| 121 } | |
| OLD | NEW |