1 /*
2  * Copyright (C) 2019 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 android.gameperformance;
17 
18 import android.annotation.NonNull;
19 import android.content.Context;
20 import android.graphics.BitmapFactory;
21 import android.opengl.GLES20;
22 import android.opengl.GLUtils;
23 import android.util.Log;
24 
25 /**
26  * Helper class for OpenGL.
27  */
28 public class OpenGLUtils {
29     private final static String TAG = "OpenGLUtils";
30 
checkGlError(String glOperation)31     public static void checkGlError(String glOperation) {
32         final int error = GLES20.glGetError();
33         if (error == GLES20.GL_NO_ERROR) {
34             return;
35         }
36         final String errorMessage = glOperation + ": glError " + error;
37         Log.e(TAG, errorMessage);
38     }
39 
loadShader(int type, String shaderCode)40     public static int loadShader(int type, String shaderCode) {
41         final int shader = GLES20.glCreateShader(type);
42         checkGlError("createShader");
43 
44         GLES20.glShaderSource(shader, shaderCode);
45         checkGlError("shaderSource");
46         GLES20.glCompileShader(shader);
47         checkGlError("shaderCompile");
48 
49         return shader;
50     }
51 
createProgram(@onNull String vertexShaderCode, @NonNull String fragmentShaderCode)52     public static int createProgram(@NonNull String vertexShaderCode,
53                                     @NonNull String fragmentShaderCode) {
54         final int vertexShader = loadShader(GLES20.GL_VERTEX_SHADER, vertexShaderCode);
55         final int fragmentShader = loadShader(GLES20.GL_FRAGMENT_SHADER, fragmentShaderCode);
56 
57         final int program = GLES20.glCreateProgram();
58         checkGlError("createProgram");
59         GLES20.glAttachShader(program, vertexShader);
60         checkGlError("attachVertexShader");
61         GLES20.glAttachShader(program, fragmentShader);
62         checkGlError("attachFragmentShader");
63         GLES20.glLinkProgram(program);
64         checkGlError("linkProgram");
65 
66         return program;
67     }
68 
createTexture(@onNull Context context, int resource)69     public static int createTexture(@NonNull Context context, int resource) {
70         final BitmapFactory.Options options = new BitmapFactory.Options();
71         options.inScaled = false;
72 
73         final int[] textureHandle = new int[1];
74         GLES20.glGenTextures(1, textureHandle, 0);
75         OpenGLUtils.checkGlError("GenTextures");
76         final int handle = textureHandle[0];
77 
78         GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, handle);
79         GLES20.glTexParameteri(
80                 GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MIN_FILTER, GLES20.GL_LINEAR);
81         GLES20.glTexParameteri(
82                 GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MAG_FILTER, GLES20.GL_LINEAR);
83         GLUtils.texImage2D(
84                 GLES20.GL_TEXTURE_2D,
85                 0,
86                 BitmapFactory.decodeResource(
87                         context.getResources(), resource, options),
88                 0);
89 
90         return handle;
91     }
92 }