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 |