git.haldean.org ana / 430c158
remove SDL dependency in shaders.cpp Haldean Brown 1 year, 9 months ago
2 changed file(s) with 39 addition(s) and 203 deletion(s). Raw diff Collapse all Expand all
88
99 #include <SDL2/SDL.h>
1010 #include <GL/glew.h>
11
12 /**
13 * Store all the file's contents in memory, useful to pass shaders
14 * source code to OpenGL. Using SDL_RWops for Android asset support.
15 */
16 char* file_read(const char* filename, int* size) {
17 SDL_RWops *rw = SDL_RWFromFile(filename, "rb");
18 if (rw == NULL) return NULL;
19
20 Sint64 res_size = SDL_RWsize(rw);
21 char* res = (char*)malloc(res_size + 1);
22
23 Sint64 nb_read_total = 0, nb_read = 1;
24 char* buf = res;
25 while (nb_read_total < res_size && nb_read != 0) {
26 nb_read = SDL_RWread(rw, buf, 1, (res_size - nb_read_total));
27 nb_read_total += nb_read;
28 buf += nb_read;
29 }
30 SDL_RWclose(rw);
31 if (nb_read_total != res_size) {
32 free(res);
33 return NULL;
34 }
35
36 res[nb_read_total] = '\0';
37 if (size != NULL)
38 *size = nb_read_total;
39 return res;
40 }
4111
4212 /**
4313 * Display compilation errors from the OpenGL shader compiler
6535 free(log);
6636 }
6737
68 /**
69 * Compile the shader from file 'filename', with error handling
70 */
71 GLuint create_shader(const char* filename, GLenum type) {
72 const GLchar* source = file_read(filename, NULL);
73 if (source == NULL) {
74 SDL_LogMessage(SDL_LOG_CATEGORY_APPLICATION, SDL_LOG_PRIORITY_ERROR,
75 "Error opening %s: %s", filename, SDL_GetError());
76 return 0;
77 }
78 GLuint res = glCreateShader(type);
79
80 // GLSL version
81 const char* version;
82 int profile;
83 SDL_GL_GetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, &profile);
84 if (profile == SDL_GL_CONTEXT_PROFILE_ES)
85 version = "#version 100\n"; // OpenGL ES 2.0
86 else
87 version = "#version 120\n"; // OpenGL 2.1
88
89 // GLES2 precision specifiers
90 const char* precision;
91 precision =
92 "#ifdef GL_ES \n"
93 "# ifdef GL_FRAGMENT_PRECISION_HIGH \n"
94 " precision highp float; \n"
95 "# else \n"
96 " precision mediump float; \n"
97 "# endif \n"
98 "#else \n"
99 // Ignore unsupported precision specifiers
100 "# define lowp \n"
101 "# define mediump \n"
102 "# define highp \n"
103 "#endif \n";
104
105 const GLchar* sources[] = {
106 version,
107 precision,
108 source
109 };
110 glShaderSource(res, 3, sources, NULL);
111 free((void*)source);
112
113 glCompileShader(res);
114 GLint compile_ok = GL_FALSE;
115 glGetShaderiv(res, GL_COMPILE_STATUS, &compile_ok);
116 if (compile_ok == GL_FALSE) {
117 SDL_LogMessage(SDL_LOG_CATEGORY_APPLICATION, SDL_LOG_PRIORITY_ERROR, "%s:\n", filename);
118 print_log(res);
119 glDeleteShader(res);
120 return 0;
121 }
122
123 return res;
124 }
125
126 GLuint create_program(const char *vertexfile, const char *fragmentfile) {
127 GLuint program = glCreateProgram();
128 GLuint shader;
129
130 if(vertexfile) {
131 shader = create_shader(vertexfile, GL_VERTEX_SHADER);
132 if(!shader)
133 return 0;
134 glAttachShader(program, shader);
135 }
136
137 if(fragmentfile) {
138 shader = create_shader(fragmentfile, GL_FRAGMENT_SHADER);
139 if(!shader)
140 return 0;
141 glAttachShader(program, shader);
142 }
143
144 glLinkProgram(program);
145 GLint link_ok = GL_FALSE;
146 glGetProgramiv(program, GL_LINK_STATUS, &link_ok);
147 if (!link_ok) {
148 SDL_LogMessage(SDL_LOG_CATEGORY_APPLICATION, SDL_LOG_PRIORITY_INFO, "glLinkProgram:");
149 print_log(program);
150 glDeleteProgram(program);
151 return 0;
152 }
153
154 return program;
155 }
156
157 #ifdef GL_GEOMETRY_SHADER
158 GLuint create_gs_program(const char *vertexfile, const char *geometryfile, const char *fragmentfile, GLint input, GLint output, GLint vertices) {
159 GLuint program = glCreateProgram();
160 GLuint shader;
161
162 if(vertexfile) {
163 shader = create_shader(vertexfile, GL_VERTEX_SHADER);
164 if(!shader)
165 return 0;
166 glAttachShader(program, shader);
167 }
168
169 if(geometryfile) {
170 shader = create_shader(geometryfile, GL_GEOMETRY_SHADER);
171 if(!shader)
172 return 0;
173 glAttachShader(program, shader);
174
175 glProgramParameteriEXT(program, GL_GEOMETRY_INPUT_TYPE_EXT, input);
176 glProgramParameteriEXT(program, GL_GEOMETRY_OUTPUT_TYPE_EXT, output);
177 glProgramParameteriEXT(program, GL_GEOMETRY_VERTICES_OUT_EXT, vertices);
178 }
179
180 if(fragmentfile) {
181 shader = create_shader(fragmentfile, GL_FRAGMENT_SHADER);
182 if(!shader)
183 return 0;
184 glAttachShader(program, shader);
185 }
186
187 glLinkProgram(program);
188 GLint link_ok = GL_FALSE;
189 glGetProgramiv(program, GL_LINK_STATUS, &link_ok);
190 if (!link_ok) {
191 SDL_LogMessage(SDL_LOG_CATEGORY_APPLICATION, SDL_LOG_PRIORITY_ERROR, "glLinkProgram:");
192 print_log(program);
193 glDeleteProgram(program);
194 return 0;
195 }
196
197 return program;
198 }
199 #else
200 GLuint create_gs_program(const char *vertexfile, const char *geometryfile, const char *fragmentfile, GLint input, GLint output, GLint vertices) {
201 SDL_LogMessage(SDL_LOG_CATEGORY_APPLICATION, SDL_LOG_PRIORITY_ERROR,
202 "Missing support for geometry shaders.");
203 return 0;
204 }
205 #endif
206
207 GLint get_attrib(GLuint program, const char *name) {
208 GLint attribute = glGetAttribLocation(program, name);
209 if(attribute == -1)
210 SDL_LogMessage(SDL_LOG_CATEGORY_APPLICATION, SDL_LOG_PRIORITY_ERROR,
211 "Could not bind attribute %s", name);
212 return attribute;
213 }
214
215 GLint get_uniform(GLuint program, const char *name) {
216 GLint uniform = glGetUniformLocation(program, name);
217 if(uniform == -1)
218 SDL_LogMessage(SDL_LOG_CATEGORY_APPLICATION, SDL_LOG_PRIORITY_ERROR,
219 "Could not bind uniform %s", name);
220 return uniform;
221 }
222
223 void print_opengl_info() {
224 int major, minor, profile;
225 SDL_GL_GetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, &major);
226 SDL_GL_GetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, &minor);
227 SDL_GL_GetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, &profile);
228 const char* profile_str = "";
229 if (profile & SDL_GL_CONTEXT_PROFILE_CORE)
230 profile_str = "CORE";
231 if (profile & SDL_GL_CONTEXT_PROFILE_COMPATIBILITY)
232 profile_str = "COMPATIBILITY";
233 if (profile & SDL_GL_CONTEXT_PROFILE_ES)
234 profile_str = "ES";
235
236 SDL_LogMessage(SDL_LOG_CATEGORY_APPLICATION, SDL_LOG_PRIORITY_INFO,
237 "OpenGL %d.%d %s", major, minor, profile_str);
238 }
239
24038 GLuint create_shader_from_string(const std::string &src, GLenum type) {
24139 GLuint res = glCreateShader(type);
24240 const GLchar *csrc = src.c_str();
00 #include "shaders.hpp"
11 #include "glerr.hpp"
22 #include "node.hpp"
3 #include "wbogl/shader_utils.hpp"
43
54 #include <glm/glm.hpp>
65 #include <glm/gtc/matrix_transform.hpp>
6867 static GLint node_viewport_attr;
6968
7069 static GLuint node_data_buf;
70
71 void print_log(GLuint object) {
72 GLint log_length = 0;
73 if (glIsShader(object)) {
74 glGetShaderiv(object, GL_INFO_LOG_LENGTH, &log_length);
75 } else if (glIsProgram(object)) {
76 glGetProgramiv(object, GL_INFO_LOG_LENGTH, &log_length);
77 } else {
78 std::cerr << "print_log called with invalid object" << std::endl;
79 return;
80 }
81
82 char* log = (char*)malloc(log_length);
83 if (glIsShader(object))
84 glGetShaderInfoLog(object, log_length, NULL, log);
85 else if (glIsProgram(object))
86 glGetProgramInfoLog(object, log_length, NULL, log);
87 std::cerr << log << std::endl;
88 free(log);
89 }
90
91 GLuint create_shader_from_string(const std::string &src, GLenum type) {
92 GLuint res = glCreateShader(type);
93 const GLchar *csrc = src.c_str();
94 GLint len = src.length();
95 glShaderSource(res, 1, &csrc, &len);
96 glCompileShader(res);
97
98 GLint compile_ok = GL_FALSE;
99 glGetShaderiv(res, GL_COMPILE_STATUS, &compile_ok);
100 if (compile_ok == GL_FALSE) {
101 std::cerr << "[E] error loading shader: " << std::endl;
102 print_log(res);
103 glDeleteShader(res);
104 return 0;
105 }
106 return res;
107 }
71108
72109 bool init(void) {
73110 GLuint vs, fs, gs;
126163 void draw(const ana::ui &ui, const ana::nodeset &nodes) {
127164 static GLfloat *node_data = nullptr;
128165 static size_t node_data_size = 0;
166 std::cout << "new center: " << ui.center.x << ", " << ui.center.y << std::endl;
129167
130168 size_t elems = nodes.size() * 4;
131169 if (elems != node_data_size) {