dungeon_crawler
changeset 15:3a3236a4833c
adding shaders and renderer abstraction
author | John Tsiombikas <nuclear@member.fsf.org> |
---|---|
date | Sun, 19 Aug 2012 23:09:30 +0300 |
parents | 67ae9fcb802c |
children | 91180ee7b7d9 |
files | prototype/src/main.cc prototype/src/renderer.cc prototype/src/renderer.h prototype/src/sdr.c prototype/src/sdr.h |
diffstat | 5 files changed, 483 insertions(+), 1 deletions(-) [+] |
line diff
1.1 --- a/prototype/src/main.cc Sun Aug 19 06:30:18 2012 +0300 1.2 +++ b/prototype/src/main.cc Sun Aug 19 23:09:30 2012 +0300 1.3 @@ -7,11 +7,13 @@ 1.4 #include "camera.h" 1.5 #include "datapath.h" 1.6 #include "tileset.h" 1.7 +#include "renderer.h" 1.8 1.9 bool init(); 1.10 void cleanup(); 1.11 void idle(); 1.12 void disp(); 1.13 +void draw(); 1.14 void update(unsigned long msec); 1.15 void reshape(int x, int y); 1.16 void keyb(unsigned char key, int x, int y); 1.17 @@ -70,6 +72,10 @@ 1.18 1.19 add_data_path("data"); 1.20 1.21 + if(!init_renderer()) { 1.22 + return false; 1.23 + } 1.24 + 1.25 // load a tileset 1.26 tileset = new TileSet; 1.27 if(!tileset->load(datafile_path("default.tileset"))) { 1.28 @@ -88,6 +94,14 @@ 1.29 return true; 1.30 } 1.31 1.32 +void cleanup() 1.33 +{ 1.34 + delete level; 1.35 + delete tileset; 1.36 + 1.37 + destroy_renderer(); 1.38 +} 1.39 + 1.40 void idle() 1.41 { 1.42 glutPostRedisplay(); 1.43 @@ -103,7 +117,7 @@ 1.44 glLoadIdentity(); 1.45 cam.use_inverse(); 1.46 1.47 - level->draw(); 1.48 + render_deferred(draw); 1.49 1.50 glutSwapBuffers(); 1.51 assert(glGetError() == GL_NO_ERROR); 1.52 @@ -111,6 +125,11 @@ 1.53 usleep(10000); 1.54 } 1.55 1.56 +void draw() 1.57 +{ 1.58 + level->draw(); 1.59 +} 1.60 + 1.61 void update(unsigned long msec) 1.62 { 1.63 static unsigned long last_upd;
2.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 2.2 +++ b/prototype/src/renderer.cc Sun Aug 19 23:09:30 2012 +0300 2.3 @@ -0,0 +1,77 @@ 2.4 +#include <stdio.h> 2.5 +#include <stdlib.h> 2.6 +#include <string.h> 2.7 +#include <limits.h> 2.8 +#include "opengl.h" 2.9 +#include "renderer.h" 2.10 +#include "sdr.h" 2.11 +#include "datapath.h" 2.12 + 2.13 +#define MRT_COUNT 4 2.14 + 2.15 +static const char *mrt_sdr_file[][2] = { 2.16 + {0, "mrt0.p.glsl"}, 2.17 + {0, "mrt1.p.glsl"}, 2.18 + {0, "mrt2.p.glsl"}, 2.19 + {0, "mrt3.p.glsl"} 2.20 +}; 2.21 + 2.22 +static unsigned int mrt_prog[MRT_COUNT]; 2.23 +static unsigned int deferred_prog; 2.24 + 2.25 +bool init_renderer() 2.26 +{ 2.27 + char vsfile[PATH_MAX], psfile[PATH_MAX]; 2.28 + const char *fname; 2.29 + 2.30 + for(int i=0; i<MRT_COUNT; i++) { 2.31 + if((fname = datafile_path(mrt_sdr_file[i][0]))) { 2.32 + strcpy(vsfile, mrt_sdr_file[i][0]); 2.33 + } else { 2.34 + vsfile[0] = 0; 2.35 + } 2.36 + 2.37 + if((fname = datafile_path(mrt_sdr_file[i][1]))) { 2.38 + strcpy(psfile, mrt_sdr_file[i][1]); 2.39 + } else { 2.40 + psfile[0] = 0; 2.41 + } 2.42 + 2.43 + if(!(mrt_prog[i] = create_program_load(vsfile, psfile))) { 2.44 + fprintf(stderr, "failed to load MRT program\n"); 2.45 + return false; 2.46 + } 2.47 + } 2.48 + 2.49 + if((fname = datafile_path("deferred.v.glsl"))) { 2.50 + strcpy(vsfile, fname); 2.51 + } else { 2.52 + vsfile[0] = 0; 2.53 + } 2.54 + if((fname = datafile_path("deferred.p.glsl"))) { 2.55 + strcpy(psfile, fname); 2.56 + } else { 2.57 + psfile[0] = 0; 2.58 + } 2.59 + 2.60 + if(!(deferred_prog = create_program_load(vsfile, psfile))) { 2.61 + fprintf(stderr, "failed to load deferred shader program\n"); 2.62 + return false; 2.63 + } 2.64 + return true; 2.65 +} 2.66 + 2.67 +void destroy_renderer() 2.68 +{ 2.69 + for(int i=0; i<MRT_COUNT; i++) { 2.70 + free_program(mrt_prog[i]); 2.71 + } 2.72 + free_program(deferred_prog); 2.73 +} 2.74 + 2.75 +void render_deferred(void (*draw_func)()) 2.76 +{ 2.77 + 2.78 + 2.79 + draw_func(); 2.80 +}
3.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 3.2 +++ b/prototype/src/renderer.h Sun Aug 19 23:09:30 2012 +0300 3.3 @@ -0,0 +1,9 @@ 3.4 +#ifndef RENDERER_H_ 3.5 +#define RENDERER_H_ 3.6 + 3.7 +bool init_renderer(); 3.8 +void destroy_renderer(); 3.9 + 3.10 +void render_deferred(void (*draw_func)()); 3.11 + 3.12 +#endif // RENDERER_H_
4.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 4.2 +++ b/prototype/src/sdr.c Sun Aug 19 23:09:30 2012 +0300 4.3 @@ -0,0 +1,328 @@ 4.4 +#include <stdio.h> 4.5 +#include <stdlib.h> 4.6 +#include <string.h> 4.7 +#include <errno.h> 4.8 +#include <assert.h> 4.9 +#include <GL/glew.h> 4.10 + 4.11 +#if defined(unix) || defined(__unix__) 4.12 +#include <unistd.h> 4.13 +#include <sys/stat.h> 4.14 +#endif /* unix */ 4.15 + 4.16 +#include "sdr.h" 4.17 + 4.18 +unsigned int create_vertex_shader(const char *src) 4.19 +{ 4.20 + return create_shader(src, GL_VERTEX_SHADER); 4.21 +} 4.22 + 4.23 +unsigned int create_pixel_shader(const char *src) 4.24 +{ 4.25 + return create_shader(src, GL_FRAGMENT_SHADER); 4.26 +} 4.27 + 4.28 +unsigned int create_shader(const char *src, unsigned int sdr_type) 4.29 +{ 4.30 + unsigned int sdr; 4.31 + int success, info_len; 4.32 + char *info_str = 0; 4.33 + GLenum err; 4.34 + 4.35 + sdr = glCreateShader(sdr_type); 4.36 + assert(glGetError() == GL_NO_ERROR); 4.37 + glShaderSource(sdr, 1, &src, 0); 4.38 + err = glGetError(); 4.39 + assert(err == GL_NO_ERROR); 4.40 + glCompileShader(sdr); 4.41 + assert(glGetError() == GL_NO_ERROR); 4.42 + 4.43 + glGetShaderiv(sdr, GL_COMPILE_STATUS, &success); 4.44 + assert(glGetError() == GL_NO_ERROR); 4.45 + glGetShaderiv(sdr, GL_INFO_LOG_LENGTH, &info_len); 4.46 + assert(glGetError() == GL_NO_ERROR); 4.47 + 4.48 + if(info_len) { 4.49 + if((info_str = malloc(info_len + 1))) { 4.50 + glGetShaderInfoLog(sdr, info_len, 0, info_str); 4.51 + assert(glGetError() == GL_NO_ERROR); 4.52 + } 4.53 + } 4.54 + 4.55 + if(success) { 4.56 + fprintf(stderr, info_str ? "done: %s\n" : "done\n", info_str); 4.57 + } else { 4.58 + fprintf(stderr, info_str ? "failed: %s\n" : "failed\n", info_str); 4.59 + glDeleteShader(sdr); 4.60 + sdr = 0; 4.61 + } 4.62 + 4.63 + free(info_str); 4.64 + return sdr; 4.65 +} 4.66 + 4.67 +void free_shader(unsigned int sdr) 4.68 +{ 4.69 + glDeleteShader(sdr); 4.70 +} 4.71 + 4.72 +unsigned int load_vertex_shader(const char *fname) 4.73 +{ 4.74 + return load_shader(fname, GL_VERTEX_SHADER); 4.75 +} 4.76 + 4.77 +unsigned int load_pixel_shader(const char *fname) 4.78 +{ 4.79 + return load_shader(fname, GL_FRAGMENT_SHADER); 4.80 +} 4.81 + 4.82 +unsigned int load_shader(const char *fname, unsigned int sdr_type) 4.83 +{ 4.84 +#if defined(unix) || defined(__unix__) 4.85 + struct stat st; 4.86 +#endif 4.87 + unsigned int sdr; 4.88 + size_t filesize; 4.89 + FILE *fp; 4.90 + char *src; 4.91 + 4.92 + if(!(fp = fopen(fname, "r"))) { 4.93 + fprintf(stderr, "failed to open shader %s: %s\n", fname, strerror(errno)); 4.94 + return 0; 4.95 + } 4.96 + 4.97 +#if defined(unix) || defined(__unix__) 4.98 + fstat(fileno(fp), &st); 4.99 + filesize = st.st_size; 4.100 +#else 4.101 + fseek(fp, 0, SEEK_END); 4.102 + filesize = ftell(fp); 4.103 + fseek(fp, 0, SEEK_SET); 4.104 +#endif /* unix */ 4.105 + 4.106 + if(!(src = malloc(filesize + 1))) { 4.107 + fclose(fp); 4.108 + return 0; 4.109 + } 4.110 + fread(src, 1, filesize, fp); 4.111 + src[filesize] = 0; 4.112 + fclose(fp); 4.113 + 4.114 + fprintf(stderr, "compiling %s shader: %s... ", (sdr_type == GL_VERTEX_SHADER ? "vertex" : "pixel"), fname); 4.115 + sdr = create_shader(src, sdr_type); 4.116 + 4.117 + free(src); 4.118 + return sdr; 4.119 +} 4.120 + 4.121 + 4.122 +unsigned int get_vertex_shader(const char *fname) 4.123 +{ 4.124 + return get_shader(fname, GL_VERTEX_SHADER); 4.125 +} 4.126 + 4.127 +unsigned int get_pixel_shader(const char *fname) 4.128 +{ 4.129 + return get_shader(fname, GL_FRAGMENT_SHADER); 4.130 +} 4.131 + 4.132 +unsigned int get_shader(const char *fname, unsigned int sdr_type) 4.133 +{ 4.134 + unsigned int sdr; 4.135 + if(!(sdr = load_shader(fname, sdr_type))) { 4.136 + return 0; 4.137 + } 4.138 + return sdr; 4.139 +} 4.140 + 4.141 + 4.142 +/* ---- gpu programs ---- */ 4.143 + 4.144 +unsigned int create_program(void) 4.145 +{ 4.146 + unsigned int prog = glCreateProgram(); 4.147 + assert(glGetError() == GL_NO_ERROR); 4.148 + return prog; 4.149 +} 4.150 + 4.151 +unsigned int create_program_link(unsigned int vs, unsigned int ps) 4.152 +{ 4.153 + unsigned int prog; 4.154 + 4.155 + if(!(prog = create_program())) { 4.156 + return 0; 4.157 + } 4.158 + 4.159 + if(vs) { 4.160 + attach_shader(prog, vs); 4.161 + assert(glGetError() == GL_NO_ERROR); 4.162 + } 4.163 + if(ps) { 4.164 + attach_shader(prog, ps); 4.165 + assert(glGetError() == GL_NO_ERROR); 4.166 + } 4.167 + 4.168 + if(link_program(prog) == -1) { 4.169 + free_program(prog); 4.170 + return 0; 4.171 + } 4.172 + return prog; 4.173 +} 4.174 + 4.175 +unsigned int create_program_load(const char *vfile, const char *pfile) 4.176 +{ 4.177 + unsigned int vs = 0, ps = 0; 4.178 + 4.179 + if(vfile && !(vs = get_vertex_shader(vfile))) { 4.180 + return 0; 4.181 + } 4.182 + if(pfile && !(ps = get_pixel_shader(pfile))) { 4.183 + return 0; 4.184 + } 4.185 + return create_program_link(vs, ps); 4.186 +} 4.187 + 4.188 +void free_program(unsigned int sdr) 4.189 +{ 4.190 + glDeleteProgram(sdr); 4.191 +} 4.192 + 4.193 +void attach_shader(unsigned int prog, unsigned int sdr) 4.194 +{ 4.195 + glAttachShader(prog, sdr); 4.196 + assert(glGetError() == GL_NO_ERROR); 4.197 +} 4.198 + 4.199 +int link_program(unsigned int prog) 4.200 +{ 4.201 + int linked, info_len, retval = 0; 4.202 + char *info_str = 0; 4.203 + 4.204 + glLinkProgram(prog); 4.205 + assert(glGetError() == GL_NO_ERROR); 4.206 + glGetProgramiv(prog, GL_LINK_STATUS, &linked); 4.207 + assert(glGetError() == GL_NO_ERROR); 4.208 + glGetProgramiv(prog, GL_INFO_LOG_LENGTH, &info_len); 4.209 + assert(glGetError() == GL_NO_ERROR); 4.210 + 4.211 + if(info_len) { 4.212 + if((info_str = malloc(info_len + 1))) { 4.213 + glGetProgramInfoLog(prog, info_len, 0, info_str); 4.214 + assert(glGetError() == GL_NO_ERROR); 4.215 + } 4.216 + } 4.217 + 4.218 + if(linked) { 4.219 + fprintf(stderr, info_str ? "linking done: %s\n" : "linking done\n", info_str); 4.220 + } else { 4.221 + fprintf(stderr, info_str ? "linking failed: %s\n" : "linking failed\n", info_str); 4.222 + retval = -1; 4.223 + } 4.224 + 4.225 + free(info_str); 4.226 + return retval; 4.227 +} 4.228 + 4.229 +int bind_program(unsigned int prog) 4.230 +{ 4.231 + GLenum err; 4.232 + 4.233 + glUseProgram(prog); 4.234 + if(prog && (err = glGetError()) != GL_NO_ERROR) { 4.235 + /* maybe the program is not linked, try linking first */ 4.236 + if(err == GL_INVALID_OPERATION) { 4.237 + if(link_program(prog) == -1) { 4.238 + return -1; 4.239 + } 4.240 + glUseProgram(prog); 4.241 + return glGetError() == GL_NO_ERROR ? 0 : -1; 4.242 + } 4.243 + return -1; 4.244 + } 4.245 + return 0; 4.246 +} 4.247 + 4.248 +/* ugly but I'm not going to write the same bloody code over and over */ 4.249 +#define BEGIN_UNIFORM_CODE \ 4.250 + int loc, curr_prog; \ 4.251 + glGetIntegerv(GL_CURRENT_PROGRAM, &curr_prog); \ 4.252 + if((unsigned int)curr_prog != prog && bind_program(prog) == -1) { \ 4.253 + return -1; \ 4.254 + } \ 4.255 + if((loc = glGetUniformLocation(prog, name)) != -1) 4.256 + 4.257 +#define END_UNIFORM_CODE \ 4.258 + if((unsigned int)curr_prog != prog) { \ 4.259 + bind_program(curr_prog); \ 4.260 + } \ 4.261 + return loc == -1 ? -1 : 0 4.262 + 4.263 +int set_uniform_int(unsigned int prog, const char *name, int val) 4.264 +{ 4.265 + BEGIN_UNIFORM_CODE { 4.266 + glUniform1i(loc, val); 4.267 + } 4.268 + END_UNIFORM_CODE; 4.269 +} 4.270 + 4.271 +int set_uniform_float(unsigned int prog, const char *name, float val) 4.272 +{ 4.273 + BEGIN_UNIFORM_CODE { 4.274 + glUniform1f(loc, val); 4.275 + } 4.276 + END_UNIFORM_CODE; 4.277 +} 4.278 + 4.279 +int set_uniform_float3(unsigned int prog, const char *name, float x, float y, float z) 4.280 +{ 4.281 + BEGIN_UNIFORM_CODE { 4.282 + glUniform3f(loc, x, y, z); 4.283 + } 4.284 + END_UNIFORM_CODE; 4.285 +} 4.286 + 4.287 +int set_uniform_float4(unsigned int prog, const char *name, float x, float y, float z, float w) 4.288 +{ 4.289 + BEGIN_UNIFORM_CODE { 4.290 + glUniform4f(loc, x, y, z, w); 4.291 + } 4.292 + END_UNIFORM_CODE; 4.293 +} 4.294 + 4.295 +int set_uniform_matrix4(unsigned int prog, const char *name, float *mat) 4.296 +{ 4.297 + BEGIN_UNIFORM_CODE { 4.298 + glUniformMatrix4fv(loc, 1, GL_FALSE, mat); 4.299 + } 4.300 + END_UNIFORM_CODE; 4.301 +} 4.302 + 4.303 +int set_uniform_matrix4_transposed(unsigned int prog, const char *name, float *mat) 4.304 +{ 4.305 + BEGIN_UNIFORM_CODE { 4.306 + glUniformMatrix4fv(loc, 1, GL_TRUE, mat); 4.307 + } 4.308 + END_UNIFORM_CODE; 4.309 +} 4.310 + 4.311 +int get_attrib_loc(unsigned int prog, const char *name) 4.312 +{ 4.313 + int loc, curr_prog; 4.314 + 4.315 + glGetIntegerv(GL_CURRENT_PROGRAM, &curr_prog); 4.316 + if((unsigned int)curr_prog != prog && bind_program(prog) == -1) { 4.317 + return -1; 4.318 + } 4.319 + 4.320 + loc = glGetAttribLocation(prog, (char*)name); 4.321 + 4.322 + if((unsigned int)curr_prog != prog) { 4.323 + bind_program(curr_prog); 4.324 + } 4.325 + return loc; 4.326 +} 4.327 + 4.328 +void set_attrib_float3(int attr_loc, float x, float y, float z) 4.329 +{ 4.330 + glVertexAttrib3f(attr_loc, x, y, z); 4.331 +}
5.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 5.2 +++ b/prototype/src/sdr.h Sun Aug 19 23:09:30 2012 +0300 5.3 @@ -0,0 +1,49 @@ 5.4 +#ifndef SDR_H_ 5.5 +#define SDR_H_ 5.6 + 5.7 +#ifdef __cplusplus 5.8 +extern "C" { 5.9 +#endif /* __cplusplus */ 5.10 + 5.11 +/* ---- shaders ---- */ 5.12 +unsigned int create_vertex_shader(const char *src); 5.13 +unsigned int create_pixel_shader(const char *src); 5.14 +unsigned int create_shader(const char *src, unsigned int sdr_type); 5.15 +void free_shader(unsigned int sdr); 5.16 + 5.17 +unsigned int load_vertex_shader(const char *fname); 5.18 +unsigned int load_pixel_shader(const char *fname); 5.19 +unsigned int load_shader(const char *src, unsigned int sdr_type); 5.20 + 5.21 +unsigned int get_vertex_shader(const char *fname); 5.22 +unsigned int get_pixel_shader(const char *fname); 5.23 +unsigned int get_shader(const char *fname, unsigned int sdr_type); 5.24 + 5.25 +int add_shader(const char *fname, unsigned int sdr); 5.26 +int remove_shader(const char *fname); 5.27 + 5.28 +/* ---- gpu programs ---- */ 5.29 +unsigned int create_program(void); 5.30 +unsigned int create_program_link(unsigned int vs, unsigned int ps); 5.31 +unsigned int create_program_load(const char *vfile, const char *pfile); 5.32 +void free_program(unsigned int sdr); 5.33 + 5.34 +void attach_shader(unsigned int prog, unsigned int sdr); 5.35 +int link_program(unsigned int prog); 5.36 +int bind_program(unsigned int prog); 5.37 + 5.38 +int set_uniform_int(unsigned int prog, const char *name, int val); 5.39 +int set_uniform_float(unsigned int prog, const char *name, float val); 5.40 +int set_uniform_float3(unsigned int prog, const char *name, float x, float y, float z); 5.41 +int set_uniform_float4(unsigned int prog, const char *name, float x, float y, float z, float w); 5.42 +int set_uniform_matrix4(unsigned int prog, const char *name, float *mat); 5.43 +int set_uniform_matrix4_transposed(unsigned int prog, const char *name, float *mat); 5.44 + 5.45 +int get_attrib_loc(unsigned int prog, const char *name); 5.46 +void set_attrib_float3(int attr_loc, float x, float y, float z); 5.47 + 5.48 +#ifdef __cplusplus 5.49 +} 5.50 +#endif /* __cplusplus */ 5.51 + 5.52 +#endif /* SDR_H_ */