Home | History | Annotate | Download | only in RenderUtils
      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