dungeon_crawler
changeset 18:5c41e6fcb300
- commandline arguments
- stereoscopic rendering
- FBO fixed
author | John Tsiombikas <nuclear@member.fsf.org> |
---|---|
date | Tue, 21 Aug 2012 03:17:48 +0300 |
parents | d98240a13793 |
children | 8a0ae6b4aa9b |
files | prototype/sdr/deferred.p.glsl prototype/sdr/deferred.v.glsl prototype/sdr/mrt.v.glsl prototype/src/camera.cc prototype/src/cfg.cc prototype/src/cfg.h prototype/src/main.cc prototype/src/opengl.cc prototype/src/opengl.h prototype/src/renderer.cc |
diffstat | 10 files changed, 291 insertions(+), 78 deletions(-) [+] |
line diff
1.1 --- a/prototype/sdr/deferred.p.glsl Mon Aug 20 06:11:58 2012 +0300 1.2 +++ b/prototype/sdr/deferred.p.glsl Tue Aug 21 03:17:48 2012 +0300 1.3 @@ -1,4 +1,8 @@ 1.4 +uniform sampler2D mrt0; 1.5 +uniform vec2 tex_scale; 1.6 + 1.7 void main() 1.8 { 1.9 - gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0); 1.10 + vec4 texel0 = texture2D(mrt0, gl_TexCoord[0].st * tex_scale); 1.11 + gl_FragColor = texel0; 1.12 }
2.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 2.2 +++ b/prototype/sdr/deferred.v.glsl Tue Aug 21 03:17:48 2012 +0300 2.3 @@ -0,0 +1,5 @@ 2.4 +void main() 2.5 +{ 2.6 + gl_Position = gl_Vertex; 2.7 + gl_TexCoord[0] = gl_MultiTexCoord0; 2.8 +}
3.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 3.2 +++ b/prototype/sdr/mrt.v.glsl Tue Aug 21 03:17:48 2012 +0300 3.3 @@ -0,0 +1,5 @@ 3.4 +void main() 3.5 +{ 3.6 + gl_Position = ftransform(); 3.7 + gl_TexCoord[0] = gl_MultiTexCoord0; 3.8 +}
4.1 --- a/prototype/src/camera.cc Mon Aug 20 06:11:58 2012 +0300 4.2 +++ b/prototype/src/camera.cc Tue Aug 21 03:17:48 2012 +0300 4.3 @@ -15,25 +15,6 @@ 4.4 *mat = matrix().inverse(); 4.5 } 4.6 4.7 -void Camera::set_glmat(const Matrix4x4 &mat) const 4.8 -{ 4.9 -#ifdef SINGLE_PRECISION_MATH 4.10 - if(glLoadTransposeMatrixfARB) { 4.11 - glLoadTransposeMatrixfARB((float*)&mat); 4.12 - } else { 4.13 - Matrix4x4 tmat = mat.transposed(); 4.14 - glLoadMatrixf((float*)&tmat); 4.15 - } 4.16 -#else 4.17 - if(glLoadTransposeMatrixdARB) { 4.18 - glLoadTransposeMatrixdARB((double*)&mat); 4.19 - } else { 4.20 - Matrix4x4 tmat = mat.transposed(); 4.21 - glLoadMatrixd((double*)&tmat); 4.22 - } 4.23 -#endif 4.24 -} 4.25 - 4.26 const Matrix4x4 &Camera::matrix() const 4.27 { 4.28 if(!mcache.valid) { 4.29 @@ -54,12 +35,12 @@ 4.30 4.31 void Camera::use() const 4.32 { 4.33 - set_glmat(matrix()); 4.34 + mult_matrix(matrix()); 4.35 } 4.36 4.37 void Camera::use_inverse() const 4.38 { 4.39 - set_glmat(inv_matrix()); 4.40 + mult_matrix(inv_matrix()); 4.41 } 4.42 4.43 void Camera::input_move(float x, float y, float z)
5.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 5.2 +++ b/prototype/src/cfg.cc Tue Aug 21 03:17:48 2012 +0300 5.3 @@ -0,0 +1,46 @@ 5.4 +#include <stdio.h> 5.5 +#include <stdlib.h> 5.6 +#include <string.h> 5.7 +#include "cfg.h" 5.8 + 5.9 +Config cfg; 5.10 + 5.11 +Config::Config() 5.12 +{ 5.13 + width = 800; 5.14 + height = 600; 5.15 + stereo = false; 5.16 + level_file = "0.level"; 5.17 + tileset_file = "default.tileset"; 5.18 +} 5.19 + 5.20 +bool Config::parse_args(int argc, char **argv) 5.21 +{ 5.22 + for(int i=1; i<argc; i++) { 5.23 + if(strcmp(argv[i], "-s") == 0) { 5.24 + if(sscanf(argv[++i], "%dx%d", &width, &height) != 2) { 5.25 + fprintf(stderr, "-s must be followed by <width>x<height>\n"); 5.26 + return false; 5.27 + } 5.28 + } else if(strcmp(argv[i], "-stereo") == 0) { 5.29 + stereo = true; 5.30 + } else if(strcmp(argv[i], "-level") == 0) { 5.31 + level_file = argv[++i]; 5.32 + } else if(strcmp(argv[i], "-tileset") == 0) { 5.33 + tileset_file = argv[++i]; 5.34 + } else if(strcmp(argv[i], "-h") == 0 || strcmp(argv[i], "-help") == 0) { 5.35 + printf("Usage: %s [options]\n", argv[0]); 5.36 + printf(" -s WxH window size (resolution)\n"); 5.37 + printf(" -level <filename> specify which level file to load\n"); 5.38 + printf(" -tileset <filename> specify which tileset to use\n"); 5.39 + printf(" -stereo enable stereoscopic rendering\n"); 5.40 + printf(" -h/-help print usage information and exit\n"); 5.41 + exit(0); 5.42 + 5.43 + } else { 5.44 + fprintf(stderr, "unrecognized argument: %s\n", argv[i]); 5.45 + return false; 5.46 + } 5.47 + } 5.48 + return true; 5.49 +}
6.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 6.2 +++ b/prototype/src/cfg.h Tue Aug 21 03:17:48 2012 +0300 6.3 @@ -0,0 +1,15 @@ 6.4 +#ifndef CFG_H_ 6.5 +#define CFG_H_ 6.6 + 6.7 +extern class Config { 6.8 +public: 6.9 + int width, height; 6.10 + bool stereo; 6.11 + const char *level_file, *tileset_file; 6.12 + 6.13 + Config(); 6.14 + 6.15 + bool parse_args(int argc, char **argv); 6.16 +} cfg; 6.17 + 6.18 +#endif // CFG_H_
7.1 --- a/prototype/src/main.cc Mon Aug 20 06:11:58 2012 +0300 7.2 +++ b/prototype/src/main.cc Tue Aug 21 03:17:48 2012 +0300 7.3 @@ -8,12 +8,15 @@ 7.4 #include "datapath.h" 7.5 #include "tileset.h" 7.6 #include "renderer.h" 7.7 +#include "cfg.h" 7.8 7.9 bool init(int xsz, int ysz); 7.10 void cleanup(); 7.11 void idle(); 7.12 void disp(); 7.13 void draw(); 7.14 +void view_matrix(int eye); 7.15 +void proj_matrix(int eye); 7.16 void update(unsigned long msec); 7.17 void reshape(int x, int y); 7.18 void keyb(unsigned char key, int x, int y); 7.19 @@ -27,23 +30,21 @@ 7.20 static FpsCamera cam; 7.21 static bool keystate[256]; 7.22 7.23 -static const char *level_file = "0.level"; 7.24 +static float stereo_focus_dist = 0.25; 7.25 +static float stereo_eye_sep = stereo_focus_dist / 30.0; 7.26 + 7.27 7.28 int main(int argc, char **argv) 7.29 { 7.30 - int xsz, ysz; 7.31 - 7.32 glutInit(&argc, argv); 7.33 7.34 - if(argc > 1) { 7.35 - level_file = argv[1]; 7.36 + if(!cfg.parse_args(argc, argv)) { 7.37 + return 1; 7.38 } 7.39 7.40 - glutInitWindowSize(800, 600); 7.41 - glutInitDisplayMode(GLUT_RGB | GLUT_DEPTH | GLUT_DOUBLE | GLUT_MULTISAMPLE); 7.42 - glutCreateWindow("prototype"); 7.43 - xsz = glutGet(GLUT_WINDOW_WIDTH); 7.44 - ysz = glutGet(GLUT_WINDOW_HEIGHT); 7.45 + glutInitWindowSize(cfg.width, cfg.height); 7.46 + glutInitDisplayMode(GLUT_RGB | GLUT_DEPTH | GLUT_DOUBLE | (cfg.stereo ? GLUT_STEREO : 0)); 7.47 + glutCreateWindow("dungeon crawler prototype"); 7.48 7.49 glutIdleFunc(idle); 7.50 glutDisplayFunc(disp); 7.51 @@ -55,7 +56,7 @@ 7.52 7.53 glewInit(); 7.54 7.55 - if(!init(xsz, ysz)) { 7.56 + if(!init(cfg.width, cfg.height)) { 7.57 return 1; 7.58 } 7.59 7.60 @@ -83,14 +84,15 @@ 7.61 7.62 // load a tileset 7.63 tileset = new TileSet; 7.64 - if(!tileset->load(datafile_path("default.tileset"))) { 7.65 + printf("loading tileset: %s\n", cfg.tileset_file); 7.66 + if(!tileset->load(datafile_path(cfg.tileset_file))) { 7.67 return false; 7.68 } 7.69 set_active_tileset(tileset); 7.70 7.71 level = new Level; 7.72 - printf("loading level: %s\n", level_file); 7.73 - if(!level->load(datafile_path(level_file))) { 7.74 + printf("loading level: %s\n", cfg.level_file); 7.75 + if(!level->load(datafile_path(cfg.level_file))) { 7.76 return false; 7.77 } 7.78 7.79 @@ -116,13 +118,39 @@ 7.80 { 7.81 update(glutGet(GLUT_ELAPSED_TIME)); 7.82 7.83 - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 7.84 + if(cfg.stereo) { 7.85 + glDrawBuffer(GL_BACK_LEFT); 7.86 7.87 - glMatrixMode(GL_MODELVIEW); 7.88 - glLoadIdentity(); 7.89 - cam.use_inverse(); 7.90 + glMatrixMode(GL_PROJECTION); 7.91 + glLoadIdentity(); 7.92 + proj_matrix(-1); 7.93 + glMatrixMode(GL_MODELVIEW); 7.94 + glLoadIdentity(); 7.95 + view_matrix(-1); 7.96 7.97 - render_deferred(draw); 7.98 + render_deferred(draw); 7.99 + 7.100 + glDrawBuffer(GL_BACK_RIGHT); 7.101 + 7.102 + glMatrixMode(GL_PROJECTION); 7.103 + glLoadIdentity(); 7.104 + proj_matrix(1); 7.105 + glMatrixMode(GL_MODELVIEW); 7.106 + glLoadIdentity(); 7.107 + view_matrix(1); 7.108 + 7.109 + render_deferred(draw); 7.110 + 7.111 + } else { 7.112 + glMatrixMode(GL_PROJECTION); 7.113 + glLoadIdentity(); 7.114 + proj_matrix(0); 7.115 + glMatrixMode(GL_MODELVIEW); 7.116 + glLoadIdentity(); 7.117 + view_matrix(0); 7.118 + 7.119 + render_deferred(draw); 7.120 + } 7.121 7.122 glutSwapBuffers(); 7.123 assert(glGetError() == GL_NO_ERROR); 7.124 @@ -132,9 +160,31 @@ 7.125 7.126 void draw() 7.127 { 7.128 + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 7.129 level->draw(); 7.130 } 7.131 7.132 +void view_matrix(int eye) 7.133 +{ 7.134 + float offs = stereo_eye_sep * eye * 0.5; 7.135 + glTranslatef(-offs, 0, 0); 7.136 + cam.use_inverse(); 7.137 +} 7.138 + 7.139 +void proj_matrix(int eye) 7.140 +{ 7.141 + static const float fov = M_PI / 4.0; 7.142 + static const float near_clip = 0.1; 7.143 + static const float far_clip = 100.0; 7.144 + 7.145 + float top = near_clip * tan(fov * 0.5); 7.146 + float right = top * (float)cfg.width / (float)cfg.height; 7.147 + 7.148 + float frust_shift = -(float)eye * (stereo_eye_sep * 0.5 * near_clip / stereo_focus_dist); 7.149 + glFrustum(-right + frust_shift, right + frust_shift, -top, top, near_clip, far_clip); 7.150 +} 7.151 + 7.152 + 7.153 void update(unsigned long msec) 7.154 { 7.155 static unsigned long last_upd; 7.156 @@ -169,16 +219,39 @@ 7.157 void reshape(int x, int y) 7.158 { 7.159 glViewport(0, 0, x, y); 7.160 - glMatrixMode(GL_PROJECTION); 7.161 - glLoadIdentity(); 7.162 - gluPerspective(45.0, (float)x / (float)y, 0.25, 100.0); 7.163 + cfg.width = x; 7.164 + cfg.height = y; 7.165 } 7.166 7.167 +static bool stereo_shift_pressed; 7.168 + 7.169 void keyb(unsigned char key, int x, int y) 7.170 { 7.171 switch(key) { 7.172 case 27: 7.173 exit(0); 7.174 + 7.175 + case 'z': 7.176 + stereo_shift_pressed = true; 7.177 + break; 7.178 + 7.179 + case '\n': 7.180 + case '\r': 7.181 + { 7.182 + static bool fullscr; 7.183 + if(glutGetModifiers() & GLUT_ACTIVE_ALT) { 7.184 + fullscr = !fullscr; 7.185 + if(fullscr) { 7.186 + glutFullScreen(); 7.187 + } else { 7.188 + glutPositionWindow(20, 20); 7.189 + } 7.190 + } 7.191 + } 7.192 + break; 7.193 + 7.194 + default: 7.195 + break; 7.196 } 7.197 7.198 keystate[key] = true; 7.199 @@ -186,6 +259,15 @@ 7.200 7.201 void key_release(unsigned char key, int x, int y) 7.202 { 7.203 + switch(key) { 7.204 + case 'z': 7.205 + stereo_shift_pressed = false; 7.206 + break; 7.207 + 7.208 + default: 7.209 + break; 7.210 + } 7.211 + 7.212 keystate[key] = false; 7.213 } 7.214 7.215 @@ -206,6 +288,16 @@ 7.216 prev_x = x; 7.217 prev_y = y; 7.218 7.219 + if(stereo_shift_pressed) { 7.220 + if(dy != 0) { 7.221 + stereo_focus_dist += dy * 0.01; 7.222 + stereo_eye_sep = stereo_focus_dist / 30.0; 7.223 + printf("foc: %f, sep: %f\n", stereo_focus_dist, stereo_eye_sep); 7.224 + glutPostRedisplay(); 7.225 + } 7.226 + return; 7.227 + } 7.228 + 7.229 if(bnstate[0]) { 7.230 cam.input_rotate(dy * 0.01, dx * 0.01, 0); 7.231 glutPostRedisplay();
8.1 --- a/prototype/src/opengl.cc Mon Aug 20 06:11:58 2012 +0300 8.2 +++ b/prototype/src/opengl.cc Tue Aug 21 03:17:48 2012 +0300 8.3 @@ -38,3 +38,24 @@ 8.4 } 8.5 #endif 8.6 } 8.7 + 8.8 +const char *strglerr(int err) 8.9 +{ 8.10 + static const char *errnames[] = { 8.11 + "GL_INVALID_ENUM", 8.12 + "GL_INVALID_VALUE", 8.13 + "GL_INVALID_OPERATION", 8.14 + "GL_STACK_OVERFLOW", 8.15 + "GL_STACK_UNDERFLOW", 8.16 + "GL_OUT_OF_MEMORY", 8.17 + "GL_INVALID_FRAMEBUFFER_OPERATION" 8.18 + }; 8.19 + 8.20 + if(!err) { 8.21 + return "GL_NO_ERROR"; 8.22 + } 8.23 + if(err < GL_INVALID_ENUM || err > GL_OUT_OF_MEMORY) { 8.24 + return "<invalid gl error>"; 8.25 + } 8.26 + return errnames[err - GL_INVALID_ENUM]; 8.27 +}
9.1 --- a/prototype/src/opengl.h Mon Aug 20 06:11:58 2012 +0300 9.2 +++ b/prototype/src/opengl.h Tue Aug 21 03:17:48 2012 +0300 9.3 @@ -9,9 +9,21 @@ 9.4 #include <GLUT/glut.h> 9.5 #endif 9.6 9.7 +#define CHECKGLERR \ 9.8 + do { \ 9.9 + int err = glGetError(); \ 9.10 + if(err) { \ 9.11 + fprintf(stderr, "%s:%d: OpenGL error 0x%x: %s\n", __FILE__, __LINE__, err, strglerr(err)); \ 9.12 + abort(); \ 9.13 + } \ 9.14 + } while(0) 9.15 + 9.16 + 9.17 class Matrix4x4; 9.18 9.19 void load_matrix(const Matrix4x4 &m); 9.20 void mult_matrix(const Matrix4x4 &m); 9.21 9.22 +const char *strglerr(int err); 9.23 + 9.24 #endif /* OPENGL_H_ */
10.1 --- a/prototype/src/renderer.cc Mon Aug 20 06:11:58 2012 +0300 10.2 +++ b/prototype/src/renderer.cc Tue Aug 21 03:17:48 2012 +0300 10.3 @@ -2,21 +2,23 @@ 10.4 #include <stdlib.h> 10.5 #include <string.h> 10.6 #include <limits.h> 10.7 +#include <assert.h> 10.8 #include "opengl.h" 10.9 #include "renderer.h" 10.10 #include "sdr.h" 10.11 #include "datapath.h" 10.12 10.13 + 10.14 static bool create_fbo(int xsz, int ysz); 10.15 -static bool load_shaders(); 10.16 +static unsigned int load_sdr(const char *vfname, const char *pfname); 10.17 static int round_pow2(int x); 10.18 10.19 10.20 -#define MRT_COUNT 4 10.21 +#define MRT_COUNT 1 10.22 static unsigned int mrt_tex[MRT_COUNT]; 10.23 10.24 static unsigned int mrt_prog; 10.25 -static unsigned int deferred_omni; 10.26 +static unsigned int deferred_omni, deferred_debug; 10.27 10.28 static unsigned int fbo, rbuf_depth; 10.29 static const char *fbstname[] = { 10.30 @@ -38,7 +40,11 @@ 10.31 if(!create_fbo(xsz, ysz)) { 10.32 return false; 10.33 } 10.34 - if(!load_shaders()) { 10.35 + 10.36 + if(!(mrt_prog = load_sdr("mrt.v.glsl", "mrt.p.glsl"))) { 10.37 + return false; 10.38 + } 10.39 + if(!(deferred_debug = load_sdr("deferred.v.glsl", "deferred.p.glsl"))) { 10.40 return false; 10.41 } 10.42 return true; 10.43 @@ -55,9 +61,45 @@ 10.44 10.45 void render_deferred(void (*draw_func)()) 10.46 { 10.47 - bind_program(mrt_prog); 10.48 + int loc; 10.49 + 10.50 + // render into the MRT buffers 10.51 + glBindFramebufferEXT(GL_FRAMEBUFFER, fbo); 10.52 + glUseProgram(mrt_prog); 10.53 draw_func(); 10.54 - bind_program(0); 10.55 + glUseProgram(0); 10.56 + glBindFramebufferEXT(GL_FRAMEBUFFER, 0); 10.57 + 10.58 + 10.59 + // post-process lighting 10.60 + glPushAttrib(GL_ENABLE_BIT); 10.61 + 10.62 + glDisable(GL_LIGHTING); 10.63 + glDisable(GL_DEPTH_TEST); 10.64 + glBindTexture(GL_TEXTURE_2D, mrt_tex[0]); 10.65 + glEnable(GL_TEXTURE_2D); 10.66 + 10.67 + glUseProgram(deferred_debug); 10.68 + if((loc = glGetUniformLocation(deferred_debug, "tex0")) != -1) { 10.69 + glUniform1i(loc, 0); 10.70 + } 10.71 + if((loc = glGetUniformLocation(deferred_debug, "tex_scale")) != -1) { 10.72 + glUniform2f(loc, (float)fb_xsz / tex_xsz, (float)fb_ysz / tex_ysz); 10.73 + } 10.74 + 10.75 + glBegin(GL_QUADS); 10.76 + glTexCoord2f(0, 0); 10.77 + glVertex2f(-1, -1); 10.78 + glTexCoord2f(1, 0); 10.79 + glVertex2f(1, -1); 10.80 + glTexCoord2f(1, 1); 10.81 + glVertex2f(1, 1); 10.82 + glTexCoord2f(0, 1); 10.83 + glVertex2f(-1, 1); 10.84 + glEnd(); 10.85 + 10.86 + glUseProgram(0); 10.87 + glPopAttrib(); 10.88 } 10.89 10.90 static bool create_fbo(int xsz, int ysz) 10.91 @@ -74,11 +116,7 @@ 10.92 return false; 10.93 } 10.94 glGenFramebuffersEXT(1, &fbo); 10.95 - 10.96 - glGenRenderbuffersEXT(1, &rbuf_depth); 10.97 - glBindRenderbufferEXT(GL_RENDERBUFFER, rbuf_depth); 10.98 - glRenderbufferStorageEXT(GL_RENDERBUFFER, GL_DEPTH_COMPONENT, tex_xsz, tex_ysz); 10.99 - glFramebufferRenderbufferEXT(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, rbuf_depth); 10.100 + glBindFramebufferEXT(GL_FRAMEBUFFER, fbo); 10.101 10.102 glGenTextures(MRT_COUNT, mrt_tex); 10.103 for(int i=0; i<MRT_COUNT; i++) { 10.104 @@ -92,52 +130,46 @@ 10.105 // attach to fbo 10.106 glFramebufferTexture2DEXT(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + i, GL_TEXTURE_2D, 10.107 mrt_tex[i], 0); 10.108 + CHECKGLERR; 10.109 } 10.110 10.111 + glGenRenderbuffersEXT(1, &rbuf_depth); 10.112 + glBindRenderbufferEXT(GL_RENDERBUFFER, rbuf_depth); 10.113 + glRenderbufferStorageEXT(GL_RENDERBUFFER, GL_DEPTH_COMPONENT, tex_xsz, tex_ysz); 10.114 + glFramebufferRenderbufferEXT(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, rbuf_depth); 10.115 + 10.116 int fbst = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER); 10.117 if(fbst != GL_FRAMEBUFFER_COMPLETE) { 10.118 fprintf(stderr, "incomplete fbo: %u (%s)\n", fbo, fbstname[fbst - GL_FRAMEBUFFER_COMPLETE]); 10.119 return false; 10.120 } 10.121 + CHECKGLERR; 10.122 + 10.123 + glBindFramebufferEXT(GL_FRAMEBUFFER, 0); 10.124 return true; 10.125 } 10.126 10.127 -static bool load_shaders() 10.128 +static unsigned int load_sdr(const char *vfname, const char *pfname) 10.129 { 10.130 char vsfile[PATH_MAX], psfile[PATH_MAX]; 10.131 const char *fname; 10.132 + unsigned int prog; 10.133 10.134 - if((fname = datafile_path("mrt.v.glsl"))) { 10.135 + if((fname = datafile_path(vfname))) { 10.136 strcpy(vsfile, fname); 10.137 } else { 10.138 vsfile[0] = 0; 10.139 } 10.140 - if((fname = datafile_path("mrt.p.glsl"))) { 10.141 + if((fname = datafile_path(pfname))) { 10.142 strcpy(psfile, fname); 10.143 } else { 10.144 psfile[0] = 0; 10.145 } 10.146 - if(!(mrt_prog = create_program_load(vsfile, psfile))) { 10.147 - fprintf(stderr, "failed to load MRT program\n"); 10.148 - return false; 10.149 + if(!(prog = create_program_load(vsfile, psfile))) { 10.150 + fprintf(stderr, "failed to load shader program (%s, %s)\n", vsfile, psfile); 10.151 + return 0; 10.152 } 10.153 - 10.154 - if((fname = datafile_path("deferred.v.glsl"))) { 10.155 - strcpy(vsfile, fname); 10.156 - } else { 10.157 - vsfile[0] = 0; 10.158 - } 10.159 - if((fname = datafile_path("deferred.p.glsl"))) { 10.160 - strcpy(psfile, fname); 10.161 - } else { 10.162 - psfile[0] = 0; 10.163 - } 10.164 - 10.165 - if(!(deferred_omni = create_program_load(vsfile, psfile))) { 10.166 - fprintf(stderr, "failed to load deferred shader program\n"); 10.167 - return false; 10.168 - } 10.169 - return true; 10.170 + return prog; 10.171 } 10.172 10.173 static int round_pow2(int x)