1 /* 2 * Copyright (C) 2016 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 package com.android.cts.verifier.sensors.sixdof.Renderer.RenderUtils; 17 18 import android.opengl.GLES20; 19 import android.util.Log; 20 21 /** 22 * Contains shader code and helper functions for compiling them. 23 */ 24 public class ShaderHelper { 25 private static final String TAG = "ShaderHelper"; 26 27 public static String getCameraPreviewFragmentShader() { 28 return "#extension GL_OES_EGL_image_external : require\n" + 29 "precision mediump float;\n" + 30 "uniform samplerExternalOES u_Texture;\n" + 31 "\n" + 32 "varying vec3 v_Position;\n" + 33 "varying vec2 v_TexCoordinate;\n" + 34 "\n" + 35 "void main()\n" + 36 "{\n" + 37 " gl_FragColor = texture2D(u_Texture, v_TexCoordinate);\n" + 38 "}"; 39 } 40 41 public static String getCameraPreviewVertexShader() { 42 return "uniform mat4 u_MVPMatrix;\n" + 43 "uniform mat4 u_MVMatrix;\n" + 44 "attribute vec4 a_Position;\n" + 45 "attribute vec2 a_TexCoordinate;\n" + 46 "\n" + 47 "varying vec3 v_Position;\n" + 48 "varying vec2 v_TexCoordinate;\n" + 49 "\n" + 50 "void main()\n" + 51 "{\n" + 52 " v_Position = vec3(u_MVMatrix * a_Position);\n" + 53 "\n" + 54 " v_TexCoordinate = a_TexCoordinate;\n" + 55 "\n" + 56 " gl_Position = u_MVPMatrix * a_Position;\n" + 57 "}"; 58 } 59 60 public static String getRectangleFragmentShader() { 61 return "precision mediump float;" + 62 "varying vec4 v_Color;" + 63 "varying vec3 v_Position;" + 64 "void main() {" + 65 " gl_FragColor = v_Color;" + 66 "}"; 67 68 } 69 70 public static String getRectangleVertexShader() { 71 return "uniform mat4 u_MVPMatrix;" + 72 "uniform mat4 u_MVMatrix;" + 73 "varying vec3 v_Position;" + 74 "varying vec4 v_Color;" + 75 "attribute vec4 a_Position;" + 76 "attribute vec4 a_Color;" + 77 "void main() {" + 78 " v_Position = vec3(u_MVMatrix * a_Position);" + 79 " v_Color = a_Color;" + 80 " gl_Position = u_MVPMatrix * a_Position;" + 81 "}"; 82 } 83 84 /** 85 * Contains lighting information for shadows that enhance AR effect. 86 * 87 * @return the vertex shader. 88 */ 89 public static String getAugmentedRealityVertexShader() { 90 return "uniform mat4 u_MVPMatrix;\n" 91 + "uniform mat4 u_MVMatrix;\n" 92 93 + "attribute vec4 a_Position;\n" 94 + "attribute vec4 a_Color;\n" 95 + "attribute vec3 a_Normal;\n" 96 97 + "varying vec3 v_Position;\n" 98 + "varying vec4 v_Color;\n" 99 + "varying vec3 v_Normal;\n" 100 101 + "void main()\n" 102 + "{\n" 103 + " v_Position = vec3(u_MVMatrix * a_Position);\n" 104 + " v_Color = a_Color;\n" 105 + " v_Normal = vec3(u_MVMatrix * vec4(a_Normal, 0.0));\n" 106 + " gl_Position = u_MVPMatrix * a_Position;\n" 107 + "}\n"; 108 } 109 110 /** 111 * Contains lighting information for shadows that enhance AR effect. 112 * 113 * @return the fragment shader. 114 */ 115 public static String getAugmentedRealityFragmentShader() { 116 return "precision mediump float;\n" 117 + "uniform vec3 u_LightPos;\n" 118 + "uniform float u_LightStrength;\n" 119 + "varying vec3 v_Position;\n" 120 + "varying vec4 v_Color;\n" 121 + "varying vec3 v_Normal;\n" 122 123 + "void main()\n" 124 + "{\n" 125 + " float distance = length(u_LightPos - v_Position);\n" 126 + " vec3 lightVector = normalize(u_LightPos - v_Position);\n" 127 + " float diffuse = max(dot(v_Normal, lightVector), 0.25);\n" 128 + " diffuse = diffuse * (u_LightStrength / (1.0 + (0.25 * distance * distance)));\n" 129 + " gl_FragColor = v_Color * diffuse;\n" 130 + "}"; 131 } 132 133 /** 134 * Helper function to compile a shader. 135 * 136 * @param shaderType The shader type. 137 * @param shaderSource The shader source code. 138 * @return An OpenGL handle to the shader. 139 */ 140 public static int compileShader(final int shaderType, final String shaderSource) { 141 int shaderHandle = GLES20.glCreateShader(shaderType); 142 143 if (shaderHandle != 0) { 144 // Pass in the shader source. 145 GLES20.glShaderSource(shaderHandle, shaderSource); 146 147 // Compile the shader. 148 GLES20.glCompileShader(shaderHandle); 149 150 // Get the compilation status. 151 final int[] compileStatus = new int[1]; 152 GLES20.glGetShaderiv(shaderHandle, GLES20.GL_COMPILE_STATUS, compileStatus, 0); 153 154 // If the compilation failed, delete the shader. 155 if (compileStatus[0] == 0) { 156 Log.e(TAG, "Error compiling shader: " + GLES20.glGetShaderInfoLog(shaderHandle)); 157 GLES20.glDeleteShader(shaderHandle); 158 shaderHandle = 0; 159 } 160 } 161 162 if (shaderHandle == 0) { 163 throw new RuntimeException("Error creating shader."); 164 } 165 166 return shaderHandle; 167 } 168 169 /** 170 * Helper function to compile and link a program. 171 * 172 * @param vertexShaderHandle An OpenGL handle to an already-compiled vertex shader. 173 * @param fragmentShaderHandle An OpenGL handle to an already-compiled fragment shader. 174 * @param attributes Attributes that need to be bound to the program. 175 * @return An OpenGL handle to the program. 176 */ 177 public static int createAndLinkProgram(final int vertexShaderHandle, final int fragmentShaderHandle, final String[] attributes) { 178 int programHandle = GLES20.glCreateProgram(); 179 180 if (programHandle != 0) { 181 // Bind the vertex shader to the program. 182 GLES20.glAttachShader(programHandle, vertexShaderHandle); 183 184 // Bind the fragment shader to the program. 185 GLES20.glAttachShader(programHandle, fragmentShaderHandle); 186 187 // Bind attributes 188 if (attributes != null) { 189 final int size = attributes.length; 190 for (int i = 0; i < size; i++) { 191 GLES20.glBindAttribLocation(programHandle, i, attributes[i]); 192 } 193 } 194 195 // Link the two shaders together into a program. 196 GLES20.glLinkProgram(programHandle); 197 198 // Get the link status. 199 final int[] linkStatus = new int[1]; 200 GLES20.glGetProgramiv(programHandle, GLES20.GL_LINK_STATUS, linkStatus, 0); 201 202 // If the link failed, delete the program. 203 if (linkStatus[0] == 0) { 204 Log.e(TAG, "Error compiling program: " + GLES20.glGetProgramInfoLog(programHandle)); 205 GLES20.glDeleteProgram(programHandle); 206 programHandle = 0; 207 } 208 } 209 210 if (programHandle == 0) { 211 throw new RuntimeException("Error creating program."); 212 } 213 214 return programHandle; 215 } 216 } 217