OpenGL ES SDK for Android ARM Developer Center
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
shader.cpp
Go to the documentation of this file.
1 /* Copyright (c) 2014-2017, ARM Limited and Contributors
2  *
3  * SPDX-License-Identifier: MIT
4  *
5  * Permission is hereby granted, free of charge,
6  * to any person obtaining a copy of this software and associated documentation files (the "Software"),
7  * to deal in the Software without restriction, including without limitation the rights to
8  * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software,
9  * and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
10  *
11  * The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
12  *
13  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
14  * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
16  * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
17  * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
19  */
20 
21 #include "shader.h"
22 #include "glutil.h"
23 
24 Shader::Shader() : m_id(0), m_attributes(), m_uniforms(), m_shaders()
25 {
26  m_shaders.clear();
27 }
28 
29 bool compile_shader(GLuint shader, GLenum type, const char *source)
30 {
31  const char *src = source;
32  glShaderSource(shader, 1, &src, NULL);
33  glCompileShader(shader);
34  GLint status;
35  glGetShaderiv(shader, GL_COMPILE_STATUS, &status);
36  if (status == GL_FALSE) {
37  GLint length;
38  glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &length);
39  GLchar *info = new GLchar[length];
40  glGetShaderInfoLog(shader, length, NULL, info);
41  LOGE("Error compiling shader: %s\n", info);
42  delete[] info;
43  return false;
44  }
45  return true;
46 }
47 
48 bool link_program(GLuint program, std::vector<GLuint> shaders)
49 {
50  for (unsigned int i = 0; i < shaders.size(); ++i)
51  glAttachShader(program, shaders[i]);
52 
53  glLinkProgram(program);
54 
55  for (unsigned int i = 0; i < shaders.size(); ++i)
56  glDetachShader(program, shaders[i]);
57 
58  GLint status;
59  glGetProgramiv(program, GL_LINK_STATUS, &status);
60  if (status == GL_FALSE) {
61  GLint length;
62  glGetProgramiv(program, GL_INFO_LOG_LENGTH, &length);
63  GLchar *info = new GLchar[length];
64  glGetProgramInfoLog(program, length, NULL, info);
65  LOGE("Error linking program: %s\n", info);
66  delete[] info;
67  return false;
68  }
69  return true;
70 }
71 
72 bool Shader::load_from_src(const string *sources, GLenum *types, int count)
73 {
74  m_id = glCreateProgram();
75  m_shaders.clear();
76  for (int i = 0; i < count; ++i)
77  {
78  GLuint shader = glCreateShader(types[i]);
79  if (!compile_shader(shader, types[i], sources[i].c_str()))
80  return false;
81  m_shaders.push_back(shader);
82  }
83  return true;
84 }
85 
86 bool Shader::load_from_src(string vs_src, string fs_src)
87 {
88  string sources[] = { vs_src, fs_src };
89  GLenum types[] = { GL_VERTEX_SHADER, GL_FRAGMENT_SHADER };
90  return load_from_src(sources, types, 2);
91 }
92 
93 bool Shader::load_from_file(const string *paths, GLenum *types, int count)
94 {
95  m_id = glCreateProgram();
96  m_shaders.clear();
97  for (int i = 0; i < count; ++i)
98  {
99  GLuint shader = glCreateShader(types[i]);
100  string src;
101  if (!read_file(paths[i], src))
102  return false;
103  if (!compile_shader(shader, types[i], src.c_str()))
104  return false;
105  m_shaders.push_back(shader);
106  }
107  return true;
108 }
109 
110 bool Shader::load_from_file(string vs_path, string fs_path)
111 {
112  string paths[] = { vs_path, fs_path };
113  GLenum types[] = { GL_VERTEX_SHADER, GL_FRAGMENT_SHADER };
114  return load_from_file(paths, types, 2);
115 }
116 
117 bool Shader::load_compute_from_file(string cs_path)
118 {
119  string paths[] = { cs_path };
120  GLenum types[] = { GL_COMPUTE_SHADER };
121  return load_from_file(paths, types, 1);
122 }
123 
125 {
126  return link_program(m_id, m_shaders);
127 }
128 
130 {
131  m_attributes.clear();
132  m_uniforms.clear();
133  for (int i = 0; i < m_shaders.size(); ++i)
134  glDeleteShader(m_shaders[i]);
135  glDeleteProgram(m_id);
136 }
137 
139 {
140  glUseProgram(m_id);
141 }
142 
144 {
145  glUseProgram(0);
146 }
147 
149 {
150  std::unordered_map<std::string, GLint>::iterator it = m_uniforms.find(name);
151  if(it != m_uniforms.end())
152  {
153  return it->second;
154  }
155  else
156  {
157  GLint location = glGetUniformLocation(m_id, name.c_str());
158  string msg = "Invalid shader uniform [" + name + "]";
159  ASSERT(location >= 0, msg.c_str());
161  return location;
162  }
163 }
164 
166 {
167  std::unordered_map<std::string, GLint>::iterator it = m_attributes.find(name);
168  if(it != m_attributes.end())
169  {
170  return it->second;
171  }
172  else
173  {
174  GLint location = glGetAttribLocation(m_id, name.c_str());
175  string msg = "Invalid shader attribute [" + name + "]";
176  ASSERT(location >= 0, msg.c_str());
178  return location;
179  }
180 }
181 
182 void Shader::set_attribfv(string name, GLsizei num_components,
183  GLsizei stride, GLsizei offset)
184 {
185  GLint loc = get_attribute_location(name);
186  glEnableVertexAttribArray(loc);
187  glVertexAttribPointer(
188  loc,
189  num_components, // in the attribute,
190  GL_FLOAT, // each component is a float,
191  GL_FALSE, // not normalized,
192  stride * sizeof(GLfloat), // the attribs are seperated by this much,
193  (void*)(offset * sizeof(GLfloat)) // beginning at this offset in the array.
194  );
195 }
196 
198 {
199  glDisableVertexAttribArray(get_attribute_location(name));
200 }
201 
202 void Shader::set_uniform(string name, const mat4 &v) { glUniformMatrix4fv(get_uniform_location(name), 1, GL_FALSE, v.value_ptr()); }
203 void Shader::set_uniform(string name, const vec4 &v) { glUniform4f(get_uniform_location(name), v.x, v.y, v.z, v.w); }
204 void Shader::set_uniform(string name, const vec3 &v) { glUniform3f(get_uniform_location(name), v.x, v.y, v.z); }
205 void Shader::set_uniform(string name, const vec2 &v) { glUniform2f(get_uniform_location(name), v.x, v.y); }
206 void Shader::set_uniform(string name, double v) { glUniform1f(get_uniform_location(name), v); }
207 void Shader::set_uniform(string name, float v) { glUniform1f(get_uniform_location(name), v); }
208 void Shader::set_uniform(string name, int v) { glUniform1i(get_uniform_location(name), v); }
209 void Shader::set_uniform(string name, unsigned int v) { glUniform1ui(get_uniform_location(name), v); }
const GLfloat * v
Definition: gl2ext.h:2231
Shader()
Definition: shader.cpp:24
void set_attribfv(string name, GLsizei num_components, GLsizei stride, GLsizei offset)
Definition: shader.cpp:182
bool load_compute_from_file(string cs_path)
Definition: shader.cpp:117
Definition: matrix.h:51
Definition: matrix.h:28
bool load_from_file(const string *paths, GLenum *types, int count)
Definition: shader.cpp:93
GLsizei GLenum * sources
Definition: gl2ext.h:136
GLenum GLuint GLintptr offset
Definition: gl2ext.h:629
std::vector< GLuint > m_shaders
Definition: shader.h:61
float z
Definition: matrix.h:55
Definition: matrix.h:75
GLsizei const GLuint * paths
Definition: gl2ext.h:2476
GLenum GLenum GLsizei count
Definition: gl2ext.h:133
const float * value_ptr() const
Definition: matrix.h:150
bool read_file(const std::string &path, std::string &dest)
Definition: glutil.cpp:106
bool link_program(GLuint program, std::vector< GLuint > shaders)
Definition: shader.cpp:48
bool load_from_src(const string *sources, GLenum *types, int count)
Definition: shader.cpp:72
bool compile_shader(GLuint shader, GLenum type, const char *source)
Definition: shader.cpp:29
GLsizei GLsizei GLchar * source
Definition: gl2ext.h:877
void dispose()
Definition: shader.cpp:129
std::unordered_map< string, GLint > m_attributes
Definition: shader.h:58
bool link()
Definition: shader.cpp:124
GLint location
Definition: gl2ext.h:180
void set_uniform(string name, const mat4 &v)
Definition: shader.cpp:202
GLsizei GLenum GLenum * types
Definition: gl2ext.h:136
float y
Definition: matrix.h:31
GLuint m_id
Definition: shader.h:60
float w
Definition: matrix.h:80
void unuse()
Definition: shader.cpp:143
float x
Definition: matrix.h:53
float y
Definition: matrix.h:54
GLenum type
Definition: gl2ext.h:133
GLint get_attribute_location(string name)
Definition: shader.cpp:165
GLuint name
Definition: gl2ext.h:139
GLint get_uniform_location(string name)
Definition: shader.cpp:148
void use()
Definition: shader.cpp:138
GLenum GLuint GLenum GLsizei length
Definition: gl2ext.h:134
Definition: matrix.h:104
const void GLsizei GLsizei stride
Definition: gl2ext.h:1335
float z
Definition: matrix.h:79
#define LOGE(...)
Definition: AstcTextures.h:30
#define ASSERT(x, s)
Definition: common.h:45
float x
Definition: matrix.h:30
typedef GLfloat(GL_APIENTRYP PFNGLGETPATHLENGTHNVPROC)(GLuint path
typedef GLenum(GL_APIENTRYP PFNGLGETGRAPHICSRESETSTATUSKHRPROC)(void)
GLuint program
Definition: gl2ext.h:1475
std::unordered_map< string, GLint > m_uniforms
Definition: shader.h:59
float x
Definition: matrix.h:77
typedef GLuint(GL_APIENTRYP PFNGLGETDEBUGMESSAGELOGKHRPROC)(GLuint count
void unset_attrib(string name)
Definition: shader.cpp:197
float y
Definition: matrix.h:78
GLenum src
Definition: gl2ext.h:304