dungeon_crawler
diff prototype/src/renderer.cc @ 17:d98240a13793
lalala
author | John Tsiombikas <nuclear@member.fsf.org> |
---|---|
date | Mon, 20 Aug 2012 06:11:58 +0300 |
parents | 91180ee7b7d9 |
children | 5c41e6fcb300 |
line diff
1.1 --- a/prototype/src/renderer.cc Mon Aug 20 03:40:51 2012 +0300 1.2 +++ b/prototype/src/renderer.cc Mon Aug 20 06:11:58 2012 +0300 1.3 @@ -7,40 +7,119 @@ 1.4 #include "sdr.h" 1.5 #include "datapath.h" 1.6 1.7 -#define MRT_COUNT (sizeof mrt_sdr_file / sizeof *mrt_sdr_file) 1.8 +static bool create_fbo(int xsz, int ysz); 1.9 +static bool load_shaders(); 1.10 +static int round_pow2(int x); 1.11 1.12 -static const char *mrt_sdr_file[][2] = { 1.13 - {0, "mrt0.p.glsl"}/*, 1.14 - {0, "mrt1.p.glsl"}, 1.15 - {0, "mrt2.p.glsl"}, 1.16 - {0, "mrt3.p.glsl"}*/ 1.17 + 1.18 +#define MRT_COUNT 4 1.19 +static unsigned int mrt_tex[MRT_COUNT]; 1.20 + 1.21 +static unsigned int mrt_prog; 1.22 +static unsigned int deferred_omni; 1.23 + 1.24 +static unsigned int fbo, rbuf_depth; 1.25 +static const char *fbstname[] = { 1.26 + "GL_FRAMEBUFFER_COMPLETE", 1.27 + "GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT", 1.28 + "GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT", 1.29 + "no such fbo error", 1.30 + "GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS", 1.31 + "GL_FRAMEBUFFER_INCOMPLETE_FORMATS", 1.32 + "GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER", 1.33 + "GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER", 1.34 + "GL_FRAMEBUFFER_UNSUPPORTED" 1.35 }; 1.36 1.37 -static unsigned int mrt_prog[MRT_COUNT]; 1.38 -static unsigned int deferred_prog; 1.39 +static int fb_xsz, fb_ysz, tex_xsz, tex_ysz; 1.40 1.41 -bool init_renderer() 1.42 +bool init_renderer(int xsz, int ysz) 1.43 +{ 1.44 + if(!create_fbo(xsz, ysz)) { 1.45 + return false; 1.46 + } 1.47 + if(!load_shaders()) { 1.48 + return false; 1.49 + } 1.50 + return true; 1.51 +} 1.52 + 1.53 +void destroy_renderer() 1.54 +{ 1.55 + free_program(mrt_prog); 1.56 + free_program(deferred_omni); 1.57 + 1.58 + glDeleteTextures(MRT_COUNT, mrt_tex); 1.59 + glDeleteFramebuffersEXT(1, &fbo); 1.60 +} 1.61 + 1.62 +void render_deferred(void (*draw_func)()) 1.63 +{ 1.64 + bind_program(mrt_prog); 1.65 + draw_func(); 1.66 + bind_program(0); 1.67 +} 1.68 + 1.69 +static bool create_fbo(int xsz, int ysz) 1.70 +{ 1.71 + unsigned int clamp = GL_ARB_texture_border_clamp ? GL_CLAMP_TO_EDGE : GL_CLAMP; 1.72 + 1.73 + tex_xsz = round_pow2(xsz); 1.74 + tex_ysz = round_pow2(ysz); 1.75 + fb_xsz = xsz; 1.76 + fb_ysz = ysz; 1.77 + 1.78 + if(!glGenFramebuffersEXT) { 1.79 + fprintf(stderr, "FBO support missing\n"); 1.80 + return false; 1.81 + } 1.82 + glGenFramebuffersEXT(1, &fbo); 1.83 + 1.84 + glGenRenderbuffersEXT(1, &rbuf_depth); 1.85 + glBindRenderbufferEXT(GL_RENDERBUFFER, rbuf_depth); 1.86 + glRenderbufferStorageEXT(GL_RENDERBUFFER, GL_DEPTH_COMPONENT, tex_xsz, tex_ysz); 1.87 + glFramebufferRenderbufferEXT(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, rbuf_depth); 1.88 + 1.89 + glGenTextures(MRT_COUNT, mrt_tex); 1.90 + for(int i=0; i<MRT_COUNT; i++) { 1.91 + glBindTexture(GL_TEXTURE_2D, mrt_tex[i]); 1.92 + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, clamp); 1.93 + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, clamp); 1.94 + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); 1.95 + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); 1.96 + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, tex_xsz, tex_ysz, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0); 1.97 + 1.98 + // attach to fbo 1.99 + glFramebufferTexture2DEXT(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + i, GL_TEXTURE_2D, 1.100 + mrt_tex[i], 0); 1.101 + } 1.102 + 1.103 + int fbst = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER); 1.104 + if(fbst != GL_FRAMEBUFFER_COMPLETE) { 1.105 + fprintf(stderr, "incomplete fbo: %u (%s)\n", fbo, fbstname[fbst - GL_FRAMEBUFFER_COMPLETE]); 1.106 + return false; 1.107 + } 1.108 + return true; 1.109 +} 1.110 + 1.111 +static bool load_shaders() 1.112 { 1.113 char vsfile[PATH_MAX], psfile[PATH_MAX]; 1.114 const char *fname; 1.115 1.116 - for(int i=0; i<MRT_COUNT; i++) { 1.117 - if((fname = datafile_path(mrt_sdr_file[i][0]))) { 1.118 - strcpy(vsfile, mrt_sdr_file[i][0]); 1.119 - } else { 1.120 - vsfile[0] = 0; 1.121 - } 1.122 - 1.123 - if((fname = datafile_path(mrt_sdr_file[i][1]))) { 1.124 - strcpy(psfile, mrt_sdr_file[i][1]); 1.125 - } else { 1.126 - psfile[0] = 0; 1.127 - } 1.128 - 1.129 - if(!(mrt_prog[i] = create_program_load(vsfile, psfile))) { 1.130 - fprintf(stderr, "failed to load MRT program\n"); 1.131 - return false; 1.132 - } 1.133 + if((fname = datafile_path("mrt.v.glsl"))) { 1.134 + strcpy(vsfile, fname); 1.135 + } else { 1.136 + vsfile[0] = 0; 1.137 + } 1.138 + if((fname = datafile_path("mrt.p.glsl"))) { 1.139 + strcpy(psfile, fname); 1.140 + } else { 1.141 + psfile[0] = 0; 1.142 + } 1.143 + if(!(mrt_prog = create_program_load(vsfile, psfile))) { 1.144 + fprintf(stderr, "failed to load MRT program\n"); 1.145 + return false; 1.146 } 1.147 1.148 if((fname = datafile_path("deferred.v.glsl"))) { 1.149 @@ -54,24 +133,20 @@ 1.150 psfile[0] = 0; 1.151 } 1.152 1.153 - if(!(deferred_prog = create_program_load(vsfile, psfile))) { 1.154 + if(!(deferred_omni = create_program_load(vsfile, psfile))) { 1.155 fprintf(stderr, "failed to load deferred shader program\n"); 1.156 return false; 1.157 } 1.158 return true; 1.159 } 1.160 1.161 -void destroy_renderer() 1.162 +static int round_pow2(int x) 1.163 { 1.164 - for(int i=0; i<MRT_COUNT; i++) { 1.165 - free_program(mrt_prog[i]); 1.166 - } 1.167 - free_program(deferred_prog); 1.168 + x--; 1.169 + x = (x >> 1) | x; 1.170 + x = (x >> 2) | x; 1.171 + x = (x >> 4) | x; 1.172 + x = (x >> 8) | x; 1.173 + x = (x >> 16) | x; 1.174 + return x + 1; 1.175 } 1.176 - 1.177 -void render_deferred(void (*draw_func)()) 1.178 -{ 1.179 - 1.180 - 1.181 - draw_func(); 1.182 -}