1 | #include "shader.h"
|
2 |
|
3 | #include "config.h"
|
4 |
|
5 | #ifdef USE_GLES
|
6 | #include <GLES2/gl2.h>
|
7 | #include <GLES2/gl2ext.h>
|
8 | #else
|
9 | #include <GL/glew.h>
|
10 | #endif
|
11 |
|
12 | #include <stdlib.h>
|
13 | #include <stdio.h>
|
14 |
|
15 | static void shaderPrintLog(GLuint program);
|
16 | static GLint shaderGetUniLoc(Shader *shader, const char *name);
|
17 |
|
18 | Shader *shaderLoad(const char *vertexCode, const char *fragmentCode)
|
19 | {
|
20 | GLuint program = 0;
|
21 | GLuint vertexShader = glCreateShader(GL_VERTEX_SHADER);
|
22 | GLuint fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
|
23 |
|
24 | GLint vertexCompiled;
|
25 | GLint fragCompiled;
|
26 | Shader *result = NULL;
|
27 |
|
28 | glShaderSource(vertexShader, 1, &vertexCode, NULL);
|
29 | glShaderSource(fragmentShader, 1, &fragmentCode, NULL);
|
30 |
|
31 | glCompileShader(vertexShader);
|
32 | glGetShaderiv(vertexShader, GL_COMPILE_STATUS, &vertexCompiled);
|
33 | if(!vertexCompiled)
|
34 | {
|
35 | fprintf(stderr, "shaderLoad() could not compile vertex shader\n" );
|
36 | shaderPrintLog(vertexShader);
|
37 | exit(1);
|
38 | }
|
39 |
|
40 | glCompileShader(fragmentShader);
|
41 | glGetShaderiv(fragmentShader, GL_COMPILE_STATUS, &fragCompiled);
|
42 | if(!fragCompiled)
|
43 | {
|
44 | fprintf(stderr, "shaderLoad() could not compile fragment shader\n" );
|
45 | shaderPrintLog(fragmentShader);
|
46 | exit(1);
|
47 | }
|
48 |
|
49 | if(vertexCompiled && fragCompiled)
|
50 | {
|
51 | program = glCreateProgram();
|
52 | glAttachShader(program, vertexShader);
|
53 | glAttachShader(program, fragmentShader);
|
54 |
|
55 | result = (Shader*)malloc(sizeof(Shader));
|
56 | result -> program = program;
|
57 | result -> vertexShader = vertexShader;
|
58 | result -> fragmentShader = fragmentShader;
|
59 | }
|
60 |
|
61 | return result;
|
62 | }
|
63 |
|
64 | void shaderLink(Shader *shader)
|
65 | {
|
66 | GLint linked = 0;
|
67 |
|
68 | glLinkProgram(shader -> program);
|
69 | glGetProgramiv(shader -> program, GL_LINK_STATUS, &linked);
|
70 |
|
71 | if(!linked)
|
72 | {
|
73 | fprintf(stderr, "shaderLink() could not link shader program\n" );
|
74 | exit(1);
|
75 | }
|
76 | }
|
77 |
|
78 | void shaderBind(Shader *shader)
|
79 | {
|
80 | glUseProgram(shader -> program);
|
81 | }
|
82 |
|
83 | void shaderUnbind()
|
84 | {
|
85 | glUseProgram(0);
|
86 | }
|
87 |
|
88 | void shaderBindAttrib(Shader *shader, const char *var, unsigned int index)
|
89 | {
|
90 | glBindAttribLocation(shader -> program, index, var);
|
91 | }
|
92 |
|
93 | void shaderFinalize(Shader *shader)
|
94 | {
|
95 | glDetachShader(shader -> program, shader -> vertexShader);
|
96 | glDetachShader(shader -> program, shader -> fragmentShader);
|
97 | glDeleteShader(shader -> vertexShader);
|
98 | glDeleteShader(shader -> fragmentShader);
|
99 | }
|
100 |
|
101 | void shaderDelete(Shader *shader)
|
102 | {
|
103 | glDeleteProgram(shader -> program);
|
104 | free(shader);
|
105 | }
|
106 |
|
107 | void shaderUniform1f(Shader *shader, const char *var, float val)
|
108 | {
|
109 | glUniform1f(shaderGetUniLoc(shader, var), val);
|
110 | }
|
111 |
|
112 | void shaderUniform1i(Shader *shader, const char *var, int val)
|
113 | {
|
114 | glUniform1i(shaderGetUniLoc(shader, var), val);
|
115 | }
|
116 |
|
117 | void shaderUniform1fv(Shader *shader, const char *var, int count, float *vals)
|
118 | {
|
119 | glUniform1fv(shaderGetUniLoc(shader, var), count, vals);
|
120 | }
|
121 |
|
122 | void shaderUniform2f(Shader *shader, const char *var, float v1, float v2)
|
123 | {
|
124 | glUniform2f(shaderGetUniLoc(shader, var), v1, v2);
|
125 | }
|
126 |
|
127 | void shaderUniform2fv(Shader *shader, const char *var, int count, float *vals)
|
128 | {
|
129 | glUniform2fv(shaderGetUniLoc(shader, var), count, vals);
|
130 | }
|
131 |
|
132 | void shaderUniform3iv(Shader *shader, const char *var, int count, int *vals)
|
133 | {
|
134 | glUniform3iv(shaderGetUniLoc(shader, var), count, vals);
|
135 | }
|
136 |
|
137 | void shaderUniform3fv(Shader *shader, const char *var, int count, float *vals)
|
138 | {
|
139 | glUniform3fv(shaderGetUniLoc(shader, var), count, vals);
|
140 | }
|
141 |
|
142 | void shaderUniform3f(Shader *shader, const char *var, const float v1, const float v2, const float v3)
|
143 | {
|
144 | glUniform3f(shaderGetUniLoc(shader, var), v1, v2, v3);
|
145 | }
|
146 |
|
147 | void shaderUniformMatrix3fv(Shader *shader, const char *var, GLsizei count, GLfloat *vals)
|
148 | {
|
149 | glUniformMatrix3fv(shaderGetUniLoc(shader, var), count, GL_FALSE, vals);
|
150 | }
|
151 |
|
152 | void shaderUniform4iv(Shader *shader, const char *var, int count, int *vals)
|
153 | {
|
154 | glUniform4iv(shaderGetUniLoc(shader, var), count, vals);
|
155 | }
|
156 |
|
157 | void shaderUniform4fv(Shader *shader, const char *var, int count, float *vals)
|
158 | {
|
159 | glUniform4fv(shaderGetUniLoc(shader, var), count, vals);
|
160 | }
|
161 |
|
162 | void shaderUniform4f(Shader *shader, const char *var, float v1, float v2, float v3, float v4)
|
163 | {
|
164 | glUniform4f(shaderGetUniLoc(shader, var), v1, v2, v3, v4);
|
165 | }
|
166 |
|
167 | void shaderUniformMatrix4fv(Shader *shader, const char *var, GLsizei count, GLfloat *vals)
|
168 | {
|
169 | glUniformMatrix4fv(shaderGetUniLoc(shader, var), count, GL_FALSE, vals);
|
170 | }
|
171 |
|
172 | GLint shaderGetUniLoc(Shader *shader, const char *name)
|
173 | {
|
174 | GLint result;
|
175 | result = glGetUniformLocation(shader -> program, name);
|
176 |
|
177 | if(result == -1)
|
178 | {
|
179 | fprintf(stderr, "shaderGetUniLoc(): uniform '%s' has not been defined\n" , name);
|
180 | exit(1);
|
181 | }
|
182 |
|
183 | return result;
|
184 | }
|
185 |
|
186 | void shaderPrintLog(GLuint program)
|
187 | {
|
188 | int infologLength = 0;
|
189 | int charsWritten = 0;
|
190 | char *infoLog;
|
191 |
|
192 | glGetShaderiv(program, GL_INFO_LOG_LENGTH,&infologLength);
|
193 |
|
194 | if (infologLength > 1)
|
195 | {
|
196 | infoLog = (char*)malloc(infologLength);
|
197 | glGetShaderInfoLog(program, infologLength, &charsWritten, infoLog);
|
198 | fprintf(stderr, "%s\n" , infoLog);
|
199 | free(infoLog);
|
200 | }
|
201 | }
|
202 | |