1 /*
2  * Copyright (C) 2018 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  */
17 
18 #include "shader.h"
19 #include "common.h"
20 #include <cstdlib>
21 #include <android/log.h>
22 
23 namespace android {
24 namespace gamecore {
25 
26 namespace {
27 
loadShader(GLenum shaderType,const char * pSource)28 GLuint loadShader(GLenum shaderType, const char* pSource) {
29 
30     GLuint shader = glCreateShader(shaderType);
31     if (shader) {
32         glShaderSource(shader, 1, &pSource, NULL);
33         glCompileShader(shader);
34         GLint compiled = 0;
35         glGetShaderiv(shader, GL_COMPILE_STATUS, &compiled);
36         if (!compiled) {
37             GLint infoLen = 0;
38             glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &infoLen);
39             if (infoLen) {
40                 char* buf = (char*) malloc(infoLen);
41                 if (buf) {
42                     glGetShaderInfoLog(shader, infoLen, NULL, buf);
43                     LOGE("Could not compile shader %d:\n%s\n",
44                          shaderType, buf);
45                     free(buf);
46                 }
47                 glDeleteShader(shader);
48                 shader = 0;
49             }
50         }
51     }
52     return shader;
53 }
54 
55 } // end of anonymous namespace
56 
createProgram(const char * pVertexSource,const char * pFragmentSource)57 GLuint createProgram(const char* pVertexSource, const char* pFragmentSource) {
58     GLuint vertexShader = loadShader(GL_VERTEX_SHADER, pVertexSource);
59     if (!vertexShader) {
60         return 0;
61     }
62 
63     GLuint pixelShader = loadShader(GL_FRAGMENT_SHADER, pFragmentSource);
64     if (!pixelShader) {
65         return 0;
66     }
67 
68     GLuint program = glCreateProgram();
69     if (program) {
70         glAttachShader(program, vertexShader);
71         checkGlError("glAttachShader");
72         glAttachShader(program, pixelShader);
73         checkGlError("glAttachShader");
74         glLinkProgram(program);
75         GLint linkStatus = GL_FALSE;
76         glGetProgramiv(program, GL_LINK_STATUS, &linkStatus);
77         if (linkStatus != GL_TRUE) {
78             GLint bufLength = 0;
79             glGetProgramiv(program, GL_INFO_LOG_LENGTH, &bufLength);
80             if (bufLength) {
81                 char* buf = (char*) malloc(bufLength);
82                 if (buf) {
83                     glGetProgramInfoLog(program, bufLength, NULL, buf);
84                     LOGE("Could not link program:\n%s\n", buf);
85                     free(buf);
86                 }
87             }
88             glDeleteProgram(program);
89             program = 0;
90         }
91     }
92     return program;
93 }
94 
95 } // end of namespace gamecore
96 } // end of namespace android
97