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 "Common.h"
22 #include "Shader.h"
23 
24 #include <cstdio>
25 #include <cstdlib>
26 
27 namespace MaliSDK
28 {
29  /* Please see header for specification. */
30  char* Shader::loadShader(const char *filename)
31  {
32  FILE *file = fopen(filename, "rb");
33 
34  ASSERT(file != NULL, "Cannot read shader file.");
35 
36  /* Seek end of file. */
37  fseek(file, 0, SEEK_END);
38 
39  /* Record the size of the file for memory allocation. */
40  long length = ftell(file);
41 
42  /* Seek start of file again. */
43  fseek(file, 0, SEEK_SET);
44 
45  char *shader = (char *)calloc(length + 1, sizeof(char));
46 
47  ASSERT(shader != NULL, "Cannot allocate memory for shader source.");
48 
49  /* Read in the file */
50  size_t numberOfBytesRead = fread(shader, sizeof(char), length, file);
51 
52  ASSERT(numberOfBytesRead == length, "An error ocurred while reading shader source.");
53 
54  shader[length] = '\0';
55 
56  fclose(file);
57 
58  return shader;
59  }
60 
61  /* Please see header for specification. */
62  void Shader::processShader(GLuint *shaderObjectIdPtr, const char *filename, GLint shaderType)
63  {
64  ASSERT(shaderObjectIdPtr != NULL,
65  "NULL pointer used to store generated shader object ID.");
66 
67  ASSERT(shaderType == GL_FRAGMENT_SHADER || shaderType == GL_VERTEX_SHADER,
68  "Invalid shader object type.");
69 
70  GLint compileStatus = GL_FALSE;
71  const char *strings[1] = { NULL };
72 
73  /* Create shader and load into GL. */
74  /* [Create shader object] */
75  *shaderObjectIdPtr = GL_CHECK(glCreateShader(shaderType));
76  /* [Create shader object] */
77  /* [Load shader source] */
78  strings[0] = loadShader(filename);
79  /* [Load shader source] */
80 
81  /* [Attach shader source] */
82  GL_CHECK(glShaderSource(*shaderObjectIdPtr, 1, strings, NULL));
83  /* [Attach shader source] */
84 
85  /* Clean up shader source. */
86  free((void *)(strings[0]));
87  strings[0] = NULL;
88 
89  /* Try compiling the shader. */
90 
91  /* [Compile a shader] */
92  GL_CHECK(glCompileShader(*shaderObjectIdPtr));
93  /* [Compile a shader] */
94 
95  /* [Get compilation status] */
96  GL_CHECK(glGetShaderiv(*shaderObjectIdPtr, GL_COMPILE_STATUS, &compileStatus));
97  /* [Get compilation status] */
98 
99  /* Dump debug info (source and log) if compilation failed. */
100  if (compileStatus != GL_TRUE)
101  {
102  char *debugSource = NULL;
103  char *errorLog = NULL;
104  GLint length;
105 
106  /* Get shader source. */
107  GL_CHECK(glGetShaderiv(*shaderObjectIdPtr, GL_SHADER_SOURCE_LENGTH, &length));
108 
109  debugSource = (char*) malloc(length);
110 
111  if (debugSource != NULL)
112  {
113  GL_CHECK(glGetShaderSource(*shaderObjectIdPtr, length, NULL, debugSource));
114 
115  LOGE("Debug source START:\n%s\nDebug source END\n\n", debugSource);
116 
117  free(debugSource);
118 
119  debugSource = NULL;
120  }
121 
122  /* Now get the info log. */
123  GL_CHECK(glGetShaderiv(*shaderObjectIdPtr, GL_INFO_LOG_LENGTH, &length));
124 
125  errorLog = (char*) malloc(length);
126 
127  if (errorLog != NULL)
128  {
129  GL_CHECK(glGetShaderInfoLog(*shaderObjectIdPtr, length, NULL, errorLog));
130 
131  LOGE("Log START:\n%s\nLog END\n\n", errorLog);
132 
133  free(errorLog);
134 
135  errorLog = NULL;
136  }
137  }
138 
139  ASSERT(compileStatus == GL_TRUE, "Shader compilation FAILED!");
140  }
141 }
static char * loadShader(const char *filename)
Load shader source from a file into memory.
Definition: Shader.cpp:73
GLsizei const GLchar ** strings
Definition: gl2ext.h:1477
#define GL_CHECK(x)
Definition: AstcTextures.h:59
GLenum GLuint GLenum GLsizei length
Definition: gl2ext.h:134
#define ASSERT(x, s)
Definition: common.h:45
#define LOGE(...)
Definition: Shader.cpp:24
static void processShader(GLuint *shader, const char *filename, GLint shaderType)
Create shader, load in source, compile, and dump debug as necessary.
Definition: Shader.cpp:29
typedef GLuint(GL_APIENTRYP PFNGLGETDEBUGMESSAGELOGKHRPROC)(GLuint count