istereo2
diff src/sdr.c @ 2:81d35769f546
added the tunnel effect source
author | John Tsiombikas <nuclear@member.fsf.org> |
---|---|
date | Sat, 19 Sep 2015 05:51:51 +0300 |
parents | |
children | 9d53a4938ce8 |
line diff
1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/src/sdr.c Sat Sep 19 05:51:51 2015 +0300 1.3 @@ -0,0 +1,341 @@ 1.4 +/* 1.5 +Stereoscopic tunnel for iOS. 1.6 +Copyright (C) 2011 John Tsiombikas <nuclear@member.fsf.org> 1.7 + 1.8 +This program is free software: you can redistribute it and/or modify 1.9 +it under the terms of the GNU General Public License as published by 1.10 +the Free Software Foundation, either version 3 of the License, or 1.11 +(at your option) any later version. 1.12 + 1.13 +This program is distributed in the hope that it will be useful, 1.14 +but WITHOUT ANY WARRANTY; without even the implied warranty of 1.15 +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 1.16 +GNU General Public License for more details. 1.17 + 1.18 +You should have received a copy of the GNU General Public License 1.19 +along with this program. If not, see <http://www.gnu.org/licenses/>. 1.20 +*/ 1.21 + 1.22 +#include <stdio.h> 1.23 +#include <stdlib.h> 1.24 +#include <string.h> 1.25 +#include <errno.h> 1.26 +#include <assert.h> 1.27 +#include "opengl.h" 1.28 + 1.29 +#if defined(unix) || defined(__unix__) 1.30 +#include <unistd.h> 1.31 +#include <sys/stat.h> 1.32 +#endif /* unix */ 1.33 + 1.34 +#include "sdr.h" 1.35 + 1.36 + 1.37 +unsigned int create_vertex_shader(const char *src) 1.38 +{ 1.39 + return create_shader(src, GL_VERTEX_SHADER); 1.40 +} 1.41 + 1.42 +unsigned int create_pixel_shader(const char *src) 1.43 +{ 1.44 + return create_shader(src, GL_FRAGMENT_SHADER); 1.45 +} 1.46 + 1.47 +unsigned int create_shader(const char *src, unsigned int sdr_type) 1.48 +{ 1.49 + unsigned int sdr; 1.50 + int success, info_len; 1.51 + char *info_str = 0; 1.52 + GLenum err; 1.53 + 1.54 + sdr = glCreateShader(sdr_type); 1.55 + assert(glGetError() == GL_NO_ERROR); 1.56 + glShaderSource(sdr, 1, &src, 0); 1.57 + err = glGetError(); 1.58 + assert(err == GL_NO_ERROR); 1.59 + glCompileShader(sdr); 1.60 + assert(glGetError() == GL_NO_ERROR); 1.61 + 1.62 + glGetShaderiv(sdr, GL_COMPILE_STATUS, &success); 1.63 + assert(glGetError() == GL_NO_ERROR); 1.64 + glGetShaderiv(sdr, GL_INFO_LOG_LENGTH, &info_len); 1.65 + assert(glGetError() == GL_NO_ERROR); 1.66 + 1.67 + if(info_len) { 1.68 + if((info_str = malloc(info_len + 1))) { 1.69 + glGetShaderInfoLog(sdr, info_len, 0, info_str); 1.70 + assert(glGetError() == GL_NO_ERROR); 1.71 + } 1.72 + } 1.73 + 1.74 + if(success) { 1.75 + fprintf(stderr, info_str ? "done: %s\n" : "done\n", info_str); 1.76 + } else { 1.77 + fprintf(stderr, info_str ? "failed: %s\n" : "failed\n", info_str); 1.78 + glDeleteShader(sdr); 1.79 + sdr = 0; 1.80 + } 1.81 + 1.82 + free(info_str); 1.83 + return sdr; 1.84 +} 1.85 + 1.86 +void free_shader(unsigned int sdr) 1.87 +{ 1.88 + glDeleteShader(sdr); 1.89 +} 1.90 + 1.91 +unsigned int load_vertex_shader(const char *fname) 1.92 +{ 1.93 + return load_shader(fname, GL_VERTEX_SHADER); 1.94 +} 1.95 + 1.96 +unsigned int load_pixel_shader(const char *fname) 1.97 +{ 1.98 + return load_shader(fname, GL_FRAGMENT_SHADER); 1.99 +} 1.100 + 1.101 +unsigned int load_shader(const char *fname, unsigned int sdr_type) 1.102 +{ 1.103 +#if defined(unix) || defined(__unix__) 1.104 + struct stat st; 1.105 +#endif 1.106 + unsigned int sdr; 1.107 + size_t filesize; 1.108 + FILE *fp; 1.109 + char *src; 1.110 + 1.111 + if(!(fp = fopen(fname, "r"))) { 1.112 + fprintf(stderr, "failed to open shader %s: %s\n", fname, strerror(errno)); 1.113 + return 0; 1.114 + } 1.115 + 1.116 +#if defined(unix) || defined(__unix__) 1.117 + fstat(fileno(fp), &st); 1.118 + filesize = st.st_size; 1.119 +#else 1.120 + fseek(fp, 0, SEEK_END); 1.121 + filesize = ftell(fp); 1.122 + fseek(fp, 0, SEEK_SET); 1.123 +#endif /* unix */ 1.124 + 1.125 + if(!(src = malloc(filesize + 1))) { 1.126 + fclose(fp); 1.127 + return 0; 1.128 + } 1.129 + fread(src, 1, filesize, fp); 1.130 + src[filesize] = 0; 1.131 + fclose(fp); 1.132 + 1.133 + fprintf(stderr, "compiling %s shader: %s... ", (sdr_type == GL_VERTEX_SHADER ? "vertex" : "pixel"), fname); 1.134 + sdr = create_shader(src, sdr_type); 1.135 + 1.136 + free(src); 1.137 + return sdr; 1.138 +} 1.139 + 1.140 + 1.141 +unsigned int get_vertex_shader(const char *fname) 1.142 +{ 1.143 + return get_shader(fname, GL_VERTEX_SHADER); 1.144 +} 1.145 + 1.146 +unsigned int get_pixel_shader(const char *fname) 1.147 +{ 1.148 + return get_shader(fname, GL_FRAGMENT_SHADER); 1.149 +} 1.150 + 1.151 +unsigned int get_shader(const char *fname, unsigned int sdr_type) 1.152 +{ 1.153 + unsigned int sdr; 1.154 + 1.155 + if(!fname || !(sdr = load_shader(fname, sdr_type))) { 1.156 + return 0; 1.157 + } 1.158 + return sdr; 1.159 +} 1.160 + 1.161 + 1.162 +/* ---- gpu programs ---- */ 1.163 + 1.164 +unsigned int create_program(void) 1.165 +{ 1.166 + unsigned int prog = glCreateProgram(); 1.167 + assert(glGetError() == GL_NO_ERROR); 1.168 + return prog; 1.169 +} 1.170 + 1.171 +unsigned int create_program_link(unsigned int vs, unsigned int ps) 1.172 +{ 1.173 + unsigned int prog; 1.174 + 1.175 + if(!(prog = create_program())) { 1.176 + return 0; 1.177 + } 1.178 + 1.179 + attach_shader(prog, vs); 1.180 + assert(glGetError() == GL_NO_ERROR); 1.181 + attach_shader(prog, ps); 1.182 + assert(glGetError() == GL_NO_ERROR); 1.183 + 1.184 + if(link_program(prog) == -1) { 1.185 + free_program(prog); 1.186 + return 0; 1.187 + } 1.188 + return prog; 1.189 +} 1.190 + 1.191 +unsigned int create_program_load(const char *vfile, const char *pfile) 1.192 +{ 1.193 + unsigned int vs, ps; 1.194 + 1.195 + if(!(vs = get_vertex_shader(vfile)) || !(ps = get_pixel_shader(pfile))) { 1.196 + return 0; 1.197 + } 1.198 + return create_program_link(vs, ps); 1.199 +} 1.200 + 1.201 +void free_program(unsigned int sdr) 1.202 +{ 1.203 + glDeleteProgram(sdr); 1.204 +} 1.205 + 1.206 +void attach_shader(unsigned int prog, unsigned int sdr) 1.207 +{ 1.208 + glAttachShader(prog, sdr); 1.209 + assert(glGetError() == GL_NO_ERROR); 1.210 +} 1.211 + 1.212 +int link_program(unsigned int prog) 1.213 +{ 1.214 + int linked, info_len, retval = 0; 1.215 + char *info_str = 0; 1.216 + 1.217 + glLinkProgram(prog); 1.218 + assert(glGetError() == GL_NO_ERROR); 1.219 + glGetProgramiv(prog, GL_LINK_STATUS, &linked); 1.220 + assert(glGetError() == GL_NO_ERROR); 1.221 + glGetProgramiv(prog, GL_INFO_LOG_LENGTH, &info_len); 1.222 + assert(glGetError() == GL_NO_ERROR); 1.223 + 1.224 + if(info_len) { 1.225 + if((info_str = malloc(info_len + 1))) { 1.226 + glGetProgramInfoLog(prog, info_len, 0, info_str); 1.227 + assert(glGetError() == GL_NO_ERROR); 1.228 + } 1.229 + } 1.230 + 1.231 + if(linked) { 1.232 + fprintf(stderr, info_str ? "linking done: %s\n" : "linking done\n", info_str); 1.233 + } else { 1.234 + fprintf(stderr, info_str ? "linking failed: %s\n" : "linking failed\n", info_str); 1.235 + retval = -1; 1.236 + } 1.237 + 1.238 + free(info_str); 1.239 + return retval; 1.240 +} 1.241 + 1.242 +int bind_program(unsigned int prog) 1.243 +{ 1.244 + GLenum err; 1.245 + 1.246 + glUseProgram(prog); 1.247 + if(prog && (err = glGetError()) != GL_NO_ERROR) { 1.248 + /* maybe the program is not linked, try linking first */ 1.249 + if(err == GL_INVALID_OPERATION) { 1.250 + if(link_program(prog) == -1) { 1.251 + return -1; 1.252 + } 1.253 + glUseProgram(prog); 1.254 + return glGetError() == GL_NO_ERROR ? 0 : -1; 1.255 + } 1.256 + return -1; 1.257 + } 1.258 + return 0; 1.259 +} 1.260 + 1.261 +/* ugly but I'm not going to write the same bloody code over and over */ 1.262 +#define BEGIN_UNIFORM_CODE \ 1.263 + int loc, curr_prog; \ 1.264 + glGetIntegerv(GL_CURRENT_PROGRAM, &curr_prog); \ 1.265 + if(curr_prog != prog && bind_program(prog) == -1) { \ 1.266 + return -1; \ 1.267 + } \ 1.268 + if((loc = glGetUniformLocation(prog, name)) != -1) 1.269 + 1.270 +#define END_UNIFORM_CODE \ 1.271 + if(curr_prog != prog) { \ 1.272 + bind_program(curr_prog); \ 1.273 + } \ 1.274 + return loc == -1 ? -1 : 0 1.275 + 1.276 +int set_uniform_int(unsigned int prog, const char *name, int val) 1.277 +{ 1.278 + BEGIN_UNIFORM_CODE { 1.279 + glUniform1i(loc, val); 1.280 + } 1.281 + END_UNIFORM_CODE; 1.282 +} 1.283 + 1.284 +int set_uniform_float(unsigned int prog, const char *name, float val) 1.285 +{ 1.286 + BEGIN_UNIFORM_CODE { 1.287 + glUniform1f(loc, val); 1.288 + } 1.289 + END_UNIFORM_CODE; 1.290 +} 1.291 + 1.292 +int set_uniform_float3(unsigned int prog, const char *name, float x, float y, float z) 1.293 +{ 1.294 + BEGIN_UNIFORM_CODE { 1.295 + glUniform3f(loc, x, y, z); 1.296 + } 1.297 + END_UNIFORM_CODE; 1.298 +} 1.299 + 1.300 +int set_uniform_float4(unsigned int prog, const char *name, float x, float y, float z, float w) 1.301 +{ 1.302 + BEGIN_UNIFORM_CODE { 1.303 + glUniform4f(loc, x, y, z, w); 1.304 + } 1.305 + END_UNIFORM_CODE; 1.306 +} 1.307 + 1.308 +int set_uniform_matrix4(unsigned int prog, const char *name, float *mat) 1.309 +{ 1.310 + BEGIN_UNIFORM_CODE { 1.311 + glUniformMatrix4fv(loc, 1, GL_FALSE, mat); 1.312 + } 1.313 + END_UNIFORM_CODE; 1.314 +} 1.315 + 1.316 +int set_uniform_matrix4_transposed(unsigned int prog, const char *name, float *mat) 1.317 +{ 1.318 + BEGIN_UNIFORM_CODE { 1.319 + glUniformMatrix4fv(loc, 1, GL_TRUE, mat); 1.320 + } 1.321 + END_UNIFORM_CODE; 1.322 +} 1.323 + 1.324 +int get_attrib_loc(unsigned int prog, const char *name) 1.325 +{ 1.326 + int loc, curr_prog; 1.327 + 1.328 + glGetIntegerv(GL_CURRENT_PROGRAM, &curr_prog); 1.329 + if(curr_prog != prog && bind_program(prog) == -1) { 1.330 + return -1; 1.331 + } 1.332 + 1.333 + loc = glGetAttribLocation(prog, (char*)name); 1.334 + 1.335 + if(curr_prog != prog) { 1.336 + bind_program(curr_prog); 1.337 + } 1.338 + return loc; 1.339 +} 1.340 + 1.341 +void set_attrib_float3(int attr_loc, float x, float y, float z) 1.342 +{ 1.343 + glVertexAttrib3f(attr_loc, x, y, z); 1.344 +}