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
15static void shaderPrintLog(GLuint program);
16static GLint shaderGetUniLoc(Shader *shader, const char *name);
17
18Shader *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
64void 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
78void shaderBind(Shader *shader)
79{
80 glUseProgram(shader -> program);
81}
82
83void shaderUnbind()
84{
85 glUseProgram(0);
86}
87
88void shaderBindAttrib(Shader *shader, const char *var, unsigned int index)
89{
90 glBindAttribLocation(shader -> program, index, var);
91}
92
93void 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
101void shaderDelete(Shader *shader)
102{
103 glDeleteProgram(shader -> program);
104 free(shader);
105}
106
107void shaderUniform1f(Shader *shader, const char *var, float val)
108{
109 glUniform1f(shaderGetUniLoc(shader, var), val);
110}
111
112void shaderUniform1i(Shader *shader, const char *var, int val)
113{
114 glUniform1i(shaderGetUniLoc(shader, var), val);
115}
116
117void shaderUniform1fv(Shader *shader, const char *var, int count, float *vals)
118{
119 glUniform1fv(shaderGetUniLoc(shader, var), count, vals);
120}
121
122void shaderUniform2f(Shader *shader, const char *var, float v1, float v2)
123{
124 glUniform2f(shaderGetUniLoc(shader, var), v1, v2);
125}
126
127void shaderUniform2fv(Shader *shader, const char *var, int count, float *vals)
128{
129 glUniform2fv(shaderGetUniLoc(shader, var), count, vals);
130}
131
132void shaderUniform3iv(Shader *shader, const char *var, int count, int *vals)
133{
134 glUniform3iv(shaderGetUniLoc(shader, var), count, vals);
135}
136
137void shaderUniform3fv(Shader *shader, const char *var, int count, float *vals)
138{
139 glUniform3fv(shaderGetUniLoc(shader, var), count, vals);
140}
141
142void 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
147void shaderUniformMatrix3fv(Shader *shader, const char *var, GLsizei count, GLfloat *vals)
148{
149 glUniformMatrix3fv(shaderGetUniLoc(shader, var), count, GL_FALSE, vals);
150}
151
152void shaderUniform4iv(Shader *shader, const char *var, int count, int *vals)
153{
154 glUniform4iv(shaderGetUniLoc(shader, var), count, vals);
155}
156
157void shaderUniform4fv(Shader *shader, const char *var, int count, float *vals)
158{
159 glUniform4fv(shaderGetUniLoc(shader, var), count, vals);
160}
161
162void 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
167void shaderUniformMatrix4fv(Shader *shader, const char *var, GLsizei count, GLfloat *vals)
168{
169 glUniformMatrix4fv(shaderGetUniLoc(shader, var), count, GL_FALSE, vals);
170}
171
172GLint 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
186void 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