1 /***************************************************************************
2 *
3 * Copyright 2010,2011 BMW Car IT GmbH
4 *
5 *
6 * Licensed under the Apache License, Version 2.0 (the "License");
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
9 *
10 * http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
17 *
18 ****************************************************************************/
19 #include "ShaderBase.h"
20 #include <GLES2/gl2.h>
21 #include <stdlib.h>
22 #include <iostream>
23 using std::cout;
24
ShaderBase(string vertexCode,string fragmentCode,float * projectionMatrix)25 ShaderBase::ShaderBase(string vertexCode, string fragmentCode, float* projectionMatrix)
26 : m_vertexCode()
27 , m_fragmentCode(fragmentCode)
28 , m_projectionMatrix(projectionMatrix)
29 {
30 m_vertexCode = "uniform mediump mat4 u_projectionMatrix;\n";
31 m_vertexCode += vertexCode;
32 initShader();
33 }
34
~ShaderBase()35 ShaderBase::~ShaderBase()
36 {
37 destroyShader();
38 }
39
initShader()40 bool ShaderBase::initShader()
41 {
42 GLint glResult = GL_FALSE;
43
44 // Create the fragment shader object
45 fragmentShaderId = glCreateShader(GL_FRAGMENT_SHADER);
46
47 // Load Fragment Source
48 const char* fragmentShaderCode = m_fragmentCode.c_str();
49 glShaderSource(fragmentShaderId, 1, &fragmentShaderCode, NULL);
50
51 // Compile the source code of fragment shader
52 glCompileShader(fragmentShaderId);
53
54 glGetShaderiv(fragmentShaderId, GL_COMPILE_STATUS, &glResult);
55
56 if (glResult == GL_FALSE)
57 {
58 int infoLength, numberChars;
59 glGetShaderiv(fragmentShaderId, GL_INFO_LOG_LENGTH, &infoLength);
60
61 // Allocate Log Space
62 char* info = (char*) malloc(sizeof(char) * infoLength);
63 glGetShaderInfoLog(fragmentShaderId, infoLength, &numberChars, info);
64
65 // Print the error
66 cout << "Failed to compile fragment shader: " << info << "\n";
67 free(info);
68 return false;
69 }
70
71 // Create the fragment shader object
72 vertexShaderId = glCreateShader(GL_VERTEX_SHADER);
73
74 // Load Fragment Source
75 const char* vertexShaderCode = m_vertexCode.c_str();
76 glShaderSource(vertexShaderId, 1, &vertexShaderCode, NULL);
77
78 // Compile the source code of fragment shader
79 glCompileShader(vertexShaderId);
80
81 glGetShaderiv(vertexShaderId, GL_COMPILE_STATUS, &glResult);
82
83 if (glResult == GL_FALSE)
84 {
85 int infoLength, numberChars;
86 glGetShaderiv(vertexShaderId, GL_INFO_LOG_LENGTH, &infoLength);
87
88 // Allocate Log Space
89 char* info = (char*) malloc(sizeof(char) * infoLength);
90 glGetShaderInfoLog(vertexShaderId, infoLength, &numberChars, info);
91
92 // Print the error
93 cout << "Failed to compile vertex shader: " << info << "\n";
94 free(info);
95 return false;
96 }
97
98 shaderProgramId = glCreateProgram();
99
100 glAttachShader(shaderProgramId, fragmentShaderId);
101 glAttachShader(shaderProgramId, vertexShaderId);
102
103 glBindAttribLocation(shaderProgramId, 0, "a_vertex");
104
105 glLinkProgram(shaderProgramId);
106
107 glGetProgramiv(shaderProgramId, GL_LINK_STATUS, &glResult);
108
109 if (glResult == GL_FALSE)
110 {
111 int infoLength, numberChars;
112 glGetShaderiv(shaderProgramId, GL_INFO_LOG_LENGTH, &infoLength);
113
114 // Allocate Log Space
115 char* info = (char*) malloc(sizeof(char) * infoLength);
116 glGetShaderInfoLog(shaderProgramId, infoLength, &numberChars,
117 info);
118
119 // Print the error
120 cout << "Failed to link program: " << info << "\n";
121 free(info);
122 return false;
123 }
124
125 #if 1 /* ADIT */
126 glValidateProgram(shaderProgramId);
127
128 glGetProgramiv(shaderProgramId, GL_VALIDATE_STATUS, &glResult);
129
130 if (glResult == GL_FALSE)
131 {
132 int infoLength, numberChars;
133 glGetShaderiv(shaderProgramId, GL_INFO_LOG_LENGTH, &infoLength);
134
135 // Allocate Log Space
136 char* info = (char*) malloc(sizeof(char) * infoLength);
137 glGetShaderInfoLog(shaderProgramId, infoLength, &numberChars,
138 info);
139
140 // Print the error
141 cout << "Failed to validate program: " << info << "\n";
142 free(info);
143 return false;
144 }
145
146 #endif /* ADIT */
147
148 glUseProgram(shaderProgramId);
149
150 m_uniformProjectionMatrix = glGetUniformLocation(shaderProgramId, "u_projectionMatrix");
151
152 cout << "Shader setup complete.\n";
153
154 return true;
155 }
156
destroyShader()157 bool ShaderBase::destroyShader()
158 {
159 bool result = true;
160 glDeleteProgram(shaderProgramId);
161 glDeleteShader(fragmentShaderId);
162 glDeleteShader(vertexShaderId);
163 return result;
164 }
165
use(vec3f * position,vec4f * color)166 void ShaderBase::use(vec3f* position, vec4f* color)
167 {
168 (void)position; // prevent warning
169 (void)color; // prevent warning
170
171 glUseProgram(shaderProgramId);
172 glUniformMatrix4fv(m_uniformProjectionMatrix, 1, GL_FALSE, m_projectionMatrix);
173 }
174