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  *shaderObjectIdPtr = GL_CHECK(glCreateShader(shaderType));
75  strings[0] = loadShader(filename);
76 
77  GL_CHECK(glShaderSource(*shaderObjectIdPtr, 1, strings, NULL));
78 
79  /* Clean up shader source. */
80  free((void *)(strings[0]));
81  strings[0] = NULL;
82 
83  /* Try compiling the shader. */
84  GL_CHECK(glCompileShader(*shaderObjectIdPtr));
85 
86  GL_CHECK(glGetShaderiv(*shaderObjectIdPtr, GL_COMPILE_STATUS, &compileStatus));
87 
88  /* Dump debug info (source and log) if compilation failed. */
89  if (compileStatus != GL_TRUE)
90  {
91  char *debugSource = NULL;
92  char *errorLog = NULL;
93  GLint length;
94 
95  /* Get shader source. */
96  GL_CHECK(glGetShaderiv(*shaderObjectIdPtr, GL_SHADER_SOURCE_LENGTH, &length));
97 
98  debugSource = (char*) malloc(length);
99 
100  if (debugSource != NULL)
101  {
102  GL_CHECK(glGetShaderSource(*shaderObjectIdPtr, length, NULL, debugSource));
103 
104  LOGE("Debug source START:\n%s\nDebug source END\n\n", debugSource);
105 
106  free(debugSource);
107 
108  debugSource = NULL;
109  }
110 
111  /* Now get the info log. */
112  GL_CHECK(glGetShaderiv(*shaderObjectIdPtr, GL_INFO_LOG_LENGTH, &length));
113 
114  errorLog = (char*) malloc(length);
115 
116  if (errorLog != NULL)
117  {
118  GL_CHECK(glGetShaderInfoLog(*shaderObjectIdPtr, length, NULL, errorLog));
119 
120  LOGE("Log START:\n%s\nLog END\n\n", errorLog);
121 
122  free(errorLog);
123 
124  errorLog = NULL;
125  }
126  }
127 
128  ASSERT(compileStatus == GL_TRUE, "Shader compilation FAILED!");
129  }
130 }
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