oculus1
changeset 16:f3672317e5c2
made teapots many sizes and more colorful, added phong shader
author | John Tsiombikas <nuclear@member.fsf.org> |
---|---|
date | Sat, 21 Sep 2013 05:22:48 +0300 |
parents | 402cbb6d9ce3 |
children | cfe4979ab3eb |
files | Makefile sdr.glsl sdr/phong.p.glsl sdr/phong.v.glsl sdr/sdr.glsl src/main.cc src/sdr.c src/sdr.h src/vr.cc src/vr.h src/vr_impl.h |
diffstat | 11 files changed, 769 insertions(+), 114 deletions(-) [+] |
line diff
1.1 --- a/Makefile Sat Sep 21 04:15:20 2013 +0300 1.2 +++ b/Makefile Sat Sep 21 05:22:48 2013 +0300 1.3 @@ -1,12 +1,13 @@ 1.4 -src = $(wildcard src/*.cc) 1.5 +ccsrc = $(wildcard src/*.cc) 1.6 +csrc = $(wildcard src/*.c) 1.7 ovr_src = $(wildcard libovr/Src/*.cpp) \ 1.8 $(wildcard libovr/Src/Kernel/*.cpp) \ 1.9 $(wildcard libovr/Src/Util/*.cpp) 1.10 1.11 -obj = $(src:.cc=.o) $(ovr_src:.cpp=.o) $(ovr_sys_src:.cpp=.o) 1.12 +obj = $(csrc:.c=.o) $(ccsrc:.cc=.o) $(ovr_src:.cpp=.o) $(ovr_sys_src:.cpp=.o) 1.13 bin = oculus1 1.14 1.15 - 1.16 +CFLAGS = -pedantic -Wall -g 1.17 CXXFLAGS = -Wall -g -I/usr/local/include $(ovr_include) -DUSE_OVR 1.18 LDFLAGS = -L/usr/local/lib $(libgl) $(ovrlibs) -lvmath -lm 1.19
2.1 --- a/sdr.glsl Sat Sep 21 04:15:20 2013 +0300 2.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 2.3 @@ -1,43 +0,0 @@ 2.4 -uniform sampler2D tex; 2.5 -uniform float aspect, scale; 2.6 -uniform float lens_center_offset; 2.7 -uniform vec4 dist_factors; 2.8 - 2.9 -vec2 distort_texcoords(in vec2 tc); 2.10 -float barrel_scale(float x, in vec4 k); 2.11 - 2.12 -void main() 2.13 -{ 2.14 - vec2 tc = distort_texcoords(gl_TexCoord[0].xy); 2.15 - 2.16 - float vis = any(greaterThan(tc, vec2(1.0)) || lessThan(tc, vec2(0.0))) ? 0.0 : 1.0; 2.17 - 2.18 - gl_FragColor.rgb = texture2D(tex, tc).rgb * vis; 2.19 - gl_FragColor.a = 1.0; 2.20 -} 2.21 - 2.22 -vec2 distort_texcoords(in vec2 tc) 2.23 -{ 2.24 - // map tc [0, 1] -> [-1, 1] 2.25 - vec2 pt = tc * 2.0 - 1.0; 2.26 - 2.27 - pt.x += lens_center_offset * 2.0; 2.28 - pt.y /= aspect; // correct for aspect ratio 2.29 - 2.30 - float rad = barrel_scale(dot(pt, pt), dist_factors); 2.31 - pt *= rad; // scale the point by the computer distortion radius 2.32 - 2.33 - pt /= scale; 2.34 - pt.y *= aspect; 2.35 - pt.x -= lens_center_offset * 2.0; 2.36 - 2.37 - // map back to range [0, 1] 2.38 - return pt * 0.5 + 0.5; 2.39 -} 2.40 - 2.41 -float barrel_scale(float rad, in vec4 k) 2.42 -{ 2.43 - float radsq = rad * rad; 2.44 - float radquad = radsq * radsq; 2.45 - return k.x + k.y * radsq + k.z * radquad + k.w * radquad * radsq; 2.46 -}
3.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 3.2 +++ b/sdr/phong.p.glsl Sat Sep 21 05:22:48 2013 +0300 3.3 @@ -0,0 +1,19 @@ 3.4 +varying vec3 vpos, norm, ldir; 3.5 + 3.6 +void main() 3.7 +{ 3.8 + vec3 v = -normalize(vpos); 3.9 + vec3 n = normalize(norm); 3.10 + vec3 l = normalize(ldir); 3.11 + vec3 h = normalize(v + l); 3.12 + 3.13 + float ndotl = max(dot(n, l), 0.0); 3.14 + float ndoth = max(dot(n, h), 0.0); 3.15 + 3.16 + vec3 diff = gl_FrontMaterial.diffuse.rgb * gl_LightSource[0].diffuse.rgb * ndotl; 3.17 + vec3 spec = gl_FrontMaterial.specular.rgb * gl_LightSource[0].specular.rgb * 3.18 + pow(ndoth, gl_FrontMaterial.shininess); 3.19 + 3.20 + gl_FragColor.rgb = diff + spec; 3.21 + gl_FragColor.a = 1.0; 3.22 +}
4.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 4.2 +++ b/sdr/phong.v.glsl Sat Sep 21 05:22:48 2013 +0300 4.3 @@ -0,0 +1,11 @@ 4.4 +varying vec3 vpos, norm, ldir; 4.5 + 4.6 +void main() 4.7 +{ 4.8 + gl_Position = ftransform(); 4.9 + 4.10 + vpos = (gl_ModelViewMatrix * gl_Vertex).xyz; 4.11 + norm = gl_NormalMatrix * gl_Normal; 4.12 + 4.13 + ldir = gl_LightSource[0].position.xyz - vpos; 4.14 +}
5.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 5.2 +++ b/sdr/sdr.glsl Sat Sep 21 05:22:48 2013 +0300 5.3 @@ -0,0 +1,43 @@ 5.4 +uniform sampler2D tex; 5.5 +uniform float aspect, scale; 5.6 +uniform float lens_center_offset; 5.7 +uniform vec4 dist_factors; 5.8 + 5.9 +vec2 distort_texcoords(in vec2 tc); 5.10 +float barrel_scale(float x, in vec4 k); 5.11 + 5.12 +void main() 5.13 +{ 5.14 + vec2 tc = distort_texcoords(gl_TexCoord[0].xy); 5.15 + 5.16 + float vis = any(greaterThan(tc, vec2(1.0)) || lessThan(tc, vec2(0.0))) ? 0.0 : 1.0; 5.17 + 5.18 + gl_FragColor.rgb = texture2D(tex, tc).rgb * vis; 5.19 + gl_FragColor.a = 1.0; 5.20 +} 5.21 + 5.22 +vec2 distort_texcoords(in vec2 tc) 5.23 +{ 5.24 + // map tc [0, 1] -> [-1, 1] 5.25 + vec2 pt = tc * 2.0 - 1.0; 5.26 + 5.27 + pt.x += lens_center_offset * 2.0; 5.28 + pt.y /= aspect; // correct for aspect ratio 5.29 + 5.30 + float rad = barrel_scale(dot(pt, pt), dist_factors); 5.31 + pt *= rad; // scale the point by the computer distortion radius 5.32 + 5.33 + pt /= scale; 5.34 + pt.y *= aspect; 5.35 + pt.x -= lens_center_offset * 2.0; 5.36 + 5.37 + // map back to range [0, 1] 5.38 + return pt * 0.5 + 0.5; 5.39 +} 5.40 + 5.41 +float barrel_scale(float rad, in vec4 k) 5.42 +{ 5.43 + float radsq = rad * rad; 5.44 + float radquad = radsq * radsq; 5.45 + return k.x + k.y * radsq + k.z * radquad + k.w * radquad * radsq; 5.46 +}
6.1 --- a/src/main.cc Sat Sep 21 04:15:20 2013 +0300 6.2 +++ b/src/main.cc Sat Sep 21 05:22:48 2013 +0300 6.3 @@ -5,14 +5,18 @@ 6.4 #include "opengl.h" 6.5 #include "vr.h" 6.6 #include "camera.h" 6.7 +#include "sdr.h" 6.8 6.9 static bool init(); 6.10 static void cleanup(); 6.11 static void disp(); 6.12 +static void disp_vr(); 6.13 static void draw_scene(); 6.14 -static void draw_teapot(); 6.15 +static void draw_teapot(float size); 6.16 static void draw_squares(); 6.17 static void draw_grid(float size, float spacing); 6.18 +static void toggle_mouselook(); 6.19 +static void toggle_fullscreen(); 6.20 static void idle(); 6.21 static void reshape(int x, int y); 6.22 static void keyb(unsigned char key, int x, int y); 6.23 @@ -26,13 +30,16 @@ 6.24 static VRFpsCamera cam; 6.25 static int width, height; 6.26 static bool use_vr = false; 6.27 -static bool mouselook = false; 6.28 6.29 static bool keystate[256]; 6.30 6.31 static int rtarg_width, rtarg_height; 6.32 static unsigned int fbo, tex[2], zbuf; 6.33 6.34 +static unsigned int teapot_sdr; 6.35 + 6.36 +static bool fullscreen_pending; 6.37 + 6.38 int main(int argc, char **argv) 6.39 { 6.40 glutInitWindowSize(1280, 800); 6.41 @@ -48,7 +55,7 @@ 6.42 width = glutGet(GLUT_WINDOW_WIDTH); 6.43 height = glutGet(GLUT_WINDOW_HEIGHT); 6.44 6.45 - glutDisplayFunc(disp); 6.46 + glutDisplayFunc(use_vr ? disp_vr : disp); 6.47 glutIdleFunc(idle); 6.48 glutReshapeFunc(reshape); 6.49 glutKeyboardFunc(keyb); 6.50 @@ -76,6 +83,7 @@ 6.51 6.52 glEnable(GL_LIGHT0); 6.53 glEnable(GL_LIGHTING); 6.54 + glEnable(GL_NORMALIZE); 6.55 6.56 // y = height of neck 6.57 cam.input_move(0, 1.65, 0); 6.58 @@ -93,39 +101,38 @@ 6.59 6.60 rtarg_width = (xsz + xsz / 2) / 2; 6.61 rtarg_height = ysz + ysz / 2; 6.62 - } else { 6.63 - rtarg_width = width; 6.64 - rtarg_height = height; 6.65 + 6.66 + printf("render target: %dx%d\n", rtarg_width, rtarg_height); 6.67 + 6.68 + // create render targets for each eye 6.69 + GLenum wrap_mode = GL_CLAMP_TO_EDGE; 6.70 + if(!GLEW_SGIS_texture_edge_clamp) { 6.71 + wrap_mode = GL_CLAMP; 6.72 + } 6.73 + 6.74 + glGenTextures(2, tex); 6.75 + for(int i=0; i<2; i++) { 6.76 + glBindTexture(GL_TEXTURE_2D, tex[i]); 6.77 + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); 6.78 + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); 6.79 + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, wrap_mode); 6.80 + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, wrap_mode); 6.81 + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, rtarg_width, rtarg_height, 0, GL_RGB, GL_UNSIGNED_BYTE, 0); 6.82 + } 6.83 + 6.84 + // create the depth render buffer 6.85 + glGenRenderbuffers(1, &zbuf); 6.86 + glBindRenderbuffer(GL_RENDERBUFFER, zbuf); 6.87 + glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT24, rtarg_width, rtarg_height); 6.88 + 6.89 + // create the FBO 6.90 + glGenFramebuffers(1, &fbo); 6.91 + glBindFramebuffer(GL_FRAMEBUFFER, fbo); 6.92 + glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, tex[0], 0); 6.93 + glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, zbuf); 6.94 } 6.95 6.96 - printf("render target: %dx%d\n", rtarg_width, rtarg_height); 6.97 - 6.98 - // create render targets for each eye 6.99 - GLenum wrap_mode = GL_CLAMP_TO_EDGE; 6.100 - if(!GLEW_SGIS_texture_edge_clamp) { 6.101 - wrap_mode = GL_CLAMP; 6.102 - } 6.103 - 6.104 - glGenTextures(2, tex); 6.105 - for(int i=0; i<2; i++) { 6.106 - glBindTexture(GL_TEXTURE_2D, tex[i]); 6.107 - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); 6.108 - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); 6.109 - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, wrap_mode); 6.110 - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, wrap_mode); 6.111 - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, rtarg_width, rtarg_height, 0, GL_RGB, GL_UNSIGNED_BYTE, 0); 6.112 - } 6.113 - 6.114 - // create the depth render buffer 6.115 - glGenRenderbuffers(1, &zbuf); 6.116 - glBindRenderbuffer(GL_RENDERBUFFER, zbuf); 6.117 - glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT24, rtarg_width, rtarg_height); 6.118 - 6.119 - // create the FBO 6.120 - glGenFramebuffers(1, &fbo); 6.121 - glBindFramebuffer(GL_FRAMEBUFFER, fbo); 6.122 - glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, tex[0], 0); 6.123 - glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, zbuf); 6.124 + teapot_sdr = create_program_load("sdr/phong.v.glsl", "sdr/phong.p.glsl"); 6.125 6.126 return true; 6.127 } 6.128 @@ -159,6 +166,7 @@ 6.129 cam.input_move(inpv.x, inpv.y, inpv.z); 6.130 } 6.131 6.132 +// display function used in regular mode 6.133 static void disp() 6.134 { 6.135 static long prev_msec; 6.136 @@ -167,12 +175,33 @@ 6.137 prev_msec = msec; 6.138 6.139 handle_input(dt); 6.140 + 6.141 + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 6.142 + 6.143 + glMatrixMode(GL_PROJECTION); 6.144 + glLoadIdentity(); 6.145 + gluPerspective(45, (float)width / (float)height, 0.25, 500.0); 6.146 + 6.147 + glMatrixMode(GL_MODELVIEW); 6.148 + glLoadIdentity(); 6.149 + cam.use_inverse(); 6.150 + draw_scene(); 6.151 + 6.152 + glutSwapBuffers(); 6.153 + assert(glGetError() == GL_NO_ERROR); 6.154 +} 6.155 + 6.156 +// display function used in VR mode 6.157 +static void disp_vr() 6.158 +{ 6.159 + static long prev_msec; 6.160 + long msec = glutGet(GLUT_ELAPSED_TIME); 6.161 + float dt = (msec - prev_msec) / 1000.0; 6.162 + prev_msec = msec; 6.163 + 6.164 + handle_input(dt); 6.165 cam.track_vr(); 6.166 6.167 - /*glMatrixMode(GL_PROJECTION); 6.168 - glLoadIdentity(); 6.169 - float fov = RAD_TO_DEG(vr_get_fov()); 6.170 - gluPerspective(fov, (float)rtarg_width / (float)rtarg_height, 0.25, 500.0);*/ 6.171 float proj_matrix[16]; 6.172 6.173 float eye_dist = vr_get_eyedist(); 6.174 @@ -230,7 +259,6 @@ 6.175 glFinish(); 6.176 } 6.177 6.178 - 6.179 static void draw_scene() 6.180 { 6.181 float lpos[] = {0, 60, 0, 1}; 6.182 @@ -238,21 +266,33 @@ 6.183 6.184 draw_grid(50.0, 2.5); 6.185 6.186 - static Vector2 teapos[] = { 6.187 - Vector2(-8, 8), Vector2(8, 8), Vector2(8, -8), Vector2(-8, -8) 6.188 + static const Vector2 teapos[] = { 6.189 + Vector2(-8, -8), Vector2(8, -8), Vector2(8, 8), Vector2(-8, 8) 6.190 }; 6.191 + static const float teasize[] = { 1.0, 2.0, 1.7, 1.4 }; 6.192 + static const float teacolor[][4] = { 6.193 + {1.0, 0.4, 0.2, 1.0}, {0.2, 0.35, 1.0, 1.0}, {1.0, 0.9, 0.3, 1.0}, {0.3, 1.0, 0.4, 1.0} 6.194 + }; 6.195 + static const float spec[] = {0.8, 0.8, 0.8, 1.0}; 6.196 + 6.197 + glUseProgram(teapot_sdr); 6.198 6.199 for(int i=0; i<4; i++) { 6.200 + glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, teacolor[i]); 6.201 + glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, spec); 6.202 + glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, 70.0); 6.203 + 6.204 glPushMatrix(); 6.205 glTranslatef(teapos[i].x, 0, teapos[i].y); 6.206 - draw_teapot(); 6.207 + draw_teapot(teasize[i]); 6.208 glPopMatrix(); 6.209 } 6.210 + glUseProgram(0); 6.211 6.212 draw_squares(); 6.213 } 6.214 6.215 -static void draw_teapot() 6.216 +static void draw_teapot(float size) 6.217 { 6.218 static int tealist; 6.219 6.220 @@ -263,9 +303,16 @@ 6.221 glEndList(); 6.222 } 6.223 6.224 + glMatrixMode(GL_MODELVIEW); 6.225 + glPushMatrix(); 6.226 + glScalef(size, size, size); 6.227 + glTranslatef(0, 0.73, 0); 6.228 + 6.229 glFrontFace(GL_CW); 6.230 glCallList(tealist); 6.231 glFrontFace(GL_CCW); 6.232 + 6.233 + glPopMatrix(); 6.234 } 6.235 6.236 static void draw_squares() 6.237 @@ -338,8 +385,82 @@ 6.238 glPopAttrib(); 6.239 } 6.240 6.241 +static bool mouselook; 6.242 + 6.243 +static void toggle_mouselook() 6.244 +{ 6.245 + mouselook = !mouselook; 6.246 + if(mouselook) { 6.247 + glutPassiveMotionFunc(passive); 6.248 + glutSetCursor(GLUT_CURSOR_NONE); 6.249 + glutWarpPointer(width / 2, height / 2); 6.250 + } else { 6.251 + glutPassiveMotionFunc(0); 6.252 + glutSetCursor(GLUT_CURSOR_INHERIT); 6.253 + } 6.254 +} 6.255 + 6.256 +static void toggle_fullscreen() 6.257 +{ 6.258 + static bool fullscreen; 6.259 + static int prev_x, prev_y; 6.260 + static int prev_xsz, prev_ysz; 6.261 + 6.262 + fullscreen = !fullscreen; 6.263 + 6.264 + if(fullscreen) { 6.265 + prev_x = glutGet(GLUT_WINDOW_X); 6.266 + prev_y = glutGet(GLUT_WINDOW_Y); 6.267 + prev_xsz = width; 6.268 + prev_ysz = height; 6.269 + 6.270 + if(use_vr) { 6.271 + // go fullscreen to the correct monitor 6.272 + int x, y; 6.273 + vr_get_display_pos(&x, &y); 6.274 + glutPositionWindow(x, y); 6.275 + 6.276 + // also warp the mouse and enable mouselook 6.277 + glutWarpPointer(x + width / 2, y + height / 2); 6.278 + 6.279 + /* Ok this next line needs some explanation: 6.280 + * glutPositionWindow, doesn't necessarilly get executed directly. 6.281 + * GLUT might defer it for the next round of event processing, just 6.282 + * so that it may coalesce multiple positioning requests. 6.283 + * However that means that if we just called glutFullScreen right 6.284 + * here, the window manager would have no idea that the window will 6.285 + * move to another monitor, thus making it the size of the monitor 6.286 + * it occupied before the move. 6.287 + * So I'm setting a flag here, and execute the glutFullScreen call 6.288 + * at the next idle invocation. (would display be a safer place?). 6.289 + */ 6.290 + fullscreen_pending = true; 6.291 + } else { 6.292 + glutFullScreen(); 6.293 + toggle_mouselook(); 6.294 + } 6.295 + } else { 6.296 + glutReshapeWindow(prev_xsz, prev_ysz); 6.297 + glutPositionWindow(prev_x, prev_y); 6.298 + 6.299 + if(mouselook) { 6.300 + toggle_mouselook(); 6.301 + } 6.302 + } 6.303 + glutPostRedisplay(); 6.304 +} 6.305 + 6.306 + 6.307 static void idle() 6.308 { 6.309 + if(fullscreen_pending) { 6.310 + glutFullScreen(); 6.311 + 6.312 + if(!mouselook) { 6.313 + toggle_mouselook(); 6.314 + } 6.315 + fullscreen_pending = false; 6.316 + } 6.317 glutPostRedisplay(); 6.318 } 6.319 6.320 @@ -362,33 +483,11 @@ 6.321 exit(0); 6.322 6.323 case 'm': 6.324 - mouselook = !mouselook; 6.325 - if(mouselook) { 6.326 - glutPassiveMotionFunc(passive); 6.327 - glutSetCursor(GLUT_CURSOR_NONE); 6.328 - glutWarpPointer(width / 2, height / 2); 6.329 - } else { 6.330 - glutPassiveMotionFunc(0); 6.331 - glutSetCursor(GLUT_CURSOR_INHERIT); 6.332 - } 6.333 + toggle_mouselook(); 6.334 break; 6.335 6.336 case 'f': 6.337 - { 6.338 - static bool fullscreen; 6.339 - static int prev_xsz, prev_ysz; 6.340 - 6.341 - fullscreen = !fullscreen; 6.342 - 6.343 - if(fullscreen) { 6.344 - prev_xsz = width; 6.345 - prev_ysz = height; 6.346 - glutFullScreen(); 6.347 - } else { 6.348 - glutReshapeWindow(prev_xsz, prev_ysz); 6.349 - } 6.350 - glutPostRedisplay(); 6.351 - } 6.352 + toggle_fullscreen(); 6.353 break; 6.354 } 6.355
7.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 7.2 +++ b/src/sdr.c Sat Sep 21 05:22:48 2013 +0300 7.3 @@ -0,0 +1,427 @@ 7.4 +/* 7.5 +Printblobs - halftoning display hack 7.6 +Copyright (C) 2013 John Tsiombikas <nuclear@member.fsf.org> 7.7 + 7.8 +This program is free software: you can redistribute it and/or modify 7.9 +it under the terms of the GNU General Public License as published by 7.10 +the Free Software Foundation, either version 3 of the License, or 7.11 +(at your option) any later version. 7.12 + 7.13 +This program is distributed in the hope that it will be useful, 7.14 +but WITHOUT ANY WARRANTY; without even the implied warranty of 7.15 +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 7.16 +GNU General Public License for more details. 7.17 + 7.18 +You should have received a copy of the GNU General Public License 7.19 +along with this program. If not, see <http://www.gnu.org/licenses/>. 7.20 +*/ 7.21 +#include <stdio.h> 7.22 +#include <stdlib.h> 7.23 +#include <string.h> 7.24 +#include <errno.h> 7.25 +#include <stdarg.h> 7.26 +#include <assert.h> 7.27 +#include <GL/glew.h> 7.28 + 7.29 +#if defined(unix) || defined(__unix__) 7.30 +#include <unistd.h> 7.31 +#include <sys/stat.h> 7.32 +#endif /* unix */ 7.33 + 7.34 +#include "sdr.h" 7.35 + 7.36 +static const char *sdrtypestr(unsigned int sdrtype); 7.37 + 7.38 +unsigned int create_vertex_shader(const char *src) 7.39 +{ 7.40 + return create_shader(src, GL_VERTEX_SHADER); 7.41 +} 7.42 + 7.43 +unsigned int create_pixel_shader(const char *src) 7.44 +{ 7.45 + return create_shader(src, GL_FRAGMENT_SHADER); 7.46 +} 7.47 + 7.48 +unsigned int create_tessctl_shader(const char *src) 7.49 +{ 7.50 + return create_shader(src, GL_TESS_CONTROL_SHADER); 7.51 +} 7.52 + 7.53 +unsigned int create_tesseval_shader(const char *src) 7.54 +{ 7.55 + return create_shader(src, GL_TESS_EVALUATION_SHADER); 7.56 +} 7.57 + 7.58 +unsigned int create_geometry_shader(const char *src) 7.59 +{ 7.60 + return create_shader(src, GL_GEOMETRY_SHADER); 7.61 +} 7.62 + 7.63 +unsigned int create_shader(const char *src, unsigned int sdr_type) 7.64 +{ 7.65 + unsigned int sdr; 7.66 + int success, info_len; 7.67 + char *info_str = 0; 7.68 + GLenum err; 7.69 + 7.70 + sdr = glCreateShader(sdr_type); 7.71 + assert(glGetError() == GL_NO_ERROR); 7.72 + glShaderSource(sdr, 1, &src, 0); 7.73 + err = glGetError(); 7.74 + assert(err == GL_NO_ERROR); 7.75 + glCompileShader(sdr); 7.76 + assert(glGetError() == GL_NO_ERROR); 7.77 + 7.78 + glGetShaderiv(sdr, GL_COMPILE_STATUS, &success); 7.79 + assert(glGetError() == GL_NO_ERROR); 7.80 + glGetShaderiv(sdr, GL_INFO_LOG_LENGTH, &info_len); 7.81 + assert(glGetError() == GL_NO_ERROR); 7.82 + 7.83 + if(info_len) { 7.84 + if((info_str = malloc(info_len + 1))) { 7.85 + glGetShaderInfoLog(sdr, info_len, 0, info_str); 7.86 + assert(glGetError() == GL_NO_ERROR); 7.87 + } 7.88 + } 7.89 + 7.90 + if(success) { 7.91 + fprintf(stderr, info_str ? "done: %s\n" : "done\n", info_str); 7.92 + } else { 7.93 + fprintf(stderr, info_str ? "failed: %s\n" : "failed\n", info_str); 7.94 + glDeleteShader(sdr); 7.95 + sdr = 0; 7.96 + } 7.97 + 7.98 + free(info_str); 7.99 + return sdr; 7.100 +} 7.101 + 7.102 +void free_shader(unsigned int sdr) 7.103 +{ 7.104 + glDeleteShader(sdr); 7.105 +} 7.106 + 7.107 +unsigned int load_vertex_shader(const char *fname) 7.108 +{ 7.109 + return load_shader(fname, GL_VERTEX_SHADER); 7.110 +} 7.111 + 7.112 +unsigned int load_pixel_shader(const char *fname) 7.113 +{ 7.114 + return load_shader(fname, GL_FRAGMENT_SHADER); 7.115 +} 7.116 + 7.117 +unsigned int load_tessctl_shader(const char *fname) 7.118 +{ 7.119 + return load_shader(fname, GL_TESS_CONTROL_SHADER); 7.120 +} 7.121 + 7.122 +unsigned int load_tesseval_shader(const char *fname) 7.123 +{ 7.124 + return load_shader(fname, GL_TESS_EVALUATION_SHADER); 7.125 +} 7.126 + 7.127 +unsigned int load_geometry_shader(const char *fname) 7.128 +{ 7.129 + return load_shader(fname, GL_GEOMETRY_SHADER); 7.130 +} 7.131 + 7.132 +unsigned int load_shader(const char *fname, unsigned int sdr_type) 7.133 +{ 7.134 +#if defined(unix) || defined(__unix__) 7.135 + struct stat st; 7.136 +#endif 7.137 + unsigned int sdr; 7.138 + size_t filesize; 7.139 + FILE *fp; 7.140 + char *src; 7.141 + 7.142 + if(!(fp = fopen(fname, "r"))) { 7.143 + fprintf(stderr, "failed to open shader %s: %s\n", fname, strerror(errno)); 7.144 + return 0; 7.145 + } 7.146 + 7.147 +#if defined(unix) || defined(__unix__) 7.148 + fstat(fileno(fp), &st); 7.149 + filesize = st.st_size; 7.150 +#else 7.151 + fseek(fp, 0, SEEK_END); 7.152 + filesize = ftell(fp); 7.153 + fseek(fp, 0, SEEK_SET); 7.154 +#endif /* unix */ 7.155 + 7.156 + if(!(src = malloc(filesize + 1))) { 7.157 + fclose(fp); 7.158 + return 0; 7.159 + } 7.160 + fread(src, 1, filesize, fp); 7.161 + src[filesize] = 0; 7.162 + fclose(fp); 7.163 + 7.164 + fprintf(stderr, "compiling %s shader: %s... ", sdrtypestr(sdr_type), fname); 7.165 + sdr = create_shader(src, sdr_type); 7.166 + 7.167 + free(src); 7.168 + return sdr; 7.169 +} 7.170 + 7.171 + 7.172 +unsigned int get_vertex_shader(const char *fname) 7.173 +{ 7.174 + return get_shader(fname, GL_VERTEX_SHADER); 7.175 +} 7.176 + 7.177 +unsigned int get_pixel_shader(const char *fname) 7.178 +{ 7.179 + return get_shader(fname, GL_FRAGMENT_SHADER); 7.180 +} 7.181 + 7.182 +unsigned int get_tessctl_shader(const char *fname) 7.183 +{ 7.184 + return get_shader(fname, GL_TESS_CONTROL_SHADER); 7.185 +} 7.186 + 7.187 +unsigned int get_tesseval_shader(const char *fname) 7.188 +{ 7.189 + return get_shader(fname, GL_TESS_EVALUATION_SHADER); 7.190 +} 7.191 + 7.192 +unsigned int get_geometry_shader(const char *fname) 7.193 +{ 7.194 + return get_shader(fname, GL_GEOMETRY_SHADER); 7.195 +} 7.196 + 7.197 +unsigned int get_shader(const char *fname, unsigned int sdr_type) 7.198 +{ 7.199 + unsigned int sdr; 7.200 + if(!(sdr = load_shader(fname, sdr_type))) { 7.201 + return 0; 7.202 + } 7.203 + return sdr; 7.204 +} 7.205 + 7.206 + 7.207 +/* ---- gpu programs ---- */ 7.208 + 7.209 +unsigned int create_program(void) 7.210 +{ 7.211 + unsigned int prog = glCreateProgram(); 7.212 + assert(glGetError() == GL_NO_ERROR); 7.213 + return prog; 7.214 +} 7.215 + 7.216 +unsigned int create_program_link(unsigned int sdr0, ...) 7.217 +{ 7.218 + unsigned int prog, sdr; 7.219 + va_list ap; 7.220 + 7.221 + if(!(prog = create_program())) { 7.222 + return 0; 7.223 + } 7.224 + 7.225 + attach_shader(prog, sdr0); 7.226 + if(glGetError()) { 7.227 + return 0; 7.228 + } 7.229 + 7.230 + va_start(ap, sdr0); 7.231 + while((sdr = va_arg(ap, unsigned int))) { 7.232 + attach_shader(prog, sdr); 7.233 + if(glGetError()) { 7.234 + return 0; 7.235 + } 7.236 + } 7.237 + va_end(ap); 7.238 + 7.239 + if(link_program(prog) == -1) { 7.240 + free_program(prog); 7.241 + return 0; 7.242 + } 7.243 + return prog; 7.244 +} 7.245 + 7.246 +unsigned int create_program_load(const char *vfile, const char *pfile) 7.247 +{ 7.248 + unsigned int vs = 0, ps = 0; 7.249 + 7.250 + if(vfile && *vfile && !(vs = get_vertex_shader(vfile))) { 7.251 + return 0; 7.252 + } 7.253 + if(pfile && *pfile && !(ps = get_pixel_shader(pfile))) { 7.254 + return 0; 7.255 + } 7.256 + return create_program_link(vs, ps, 0); 7.257 +} 7.258 + 7.259 +void free_program(unsigned int sdr) 7.260 +{ 7.261 + glDeleteProgram(sdr); 7.262 +} 7.263 + 7.264 +void attach_shader(unsigned int prog, unsigned int sdr) 7.265 +{ 7.266 + glAttachShader(prog, sdr); 7.267 + assert(glGetError() == GL_NO_ERROR); 7.268 +} 7.269 + 7.270 +int link_program(unsigned int prog) 7.271 +{ 7.272 + int linked, info_len, retval = 0; 7.273 + char *info_str = 0; 7.274 + 7.275 + glLinkProgram(prog); 7.276 + assert(glGetError() == GL_NO_ERROR); 7.277 + glGetProgramiv(prog, GL_LINK_STATUS, &linked); 7.278 + assert(glGetError() == GL_NO_ERROR); 7.279 + glGetProgramiv(prog, GL_INFO_LOG_LENGTH, &info_len); 7.280 + assert(glGetError() == GL_NO_ERROR); 7.281 + 7.282 + if(info_len) { 7.283 + if((info_str = malloc(info_len + 1))) { 7.284 + glGetProgramInfoLog(prog, info_len, 0, info_str); 7.285 + assert(glGetError() == GL_NO_ERROR); 7.286 + } 7.287 + } 7.288 + 7.289 + if(linked) { 7.290 + fprintf(stderr, info_str ? "linking done: %s\n" : "linking done\n", info_str); 7.291 + } else { 7.292 + fprintf(stderr, info_str ? "linking failed: %s\n" : "linking failed\n", info_str); 7.293 + retval = -1; 7.294 + } 7.295 + 7.296 + free(info_str); 7.297 + return retval; 7.298 +} 7.299 + 7.300 +int bind_program(unsigned int prog) 7.301 +{ 7.302 + GLenum err; 7.303 + 7.304 + glUseProgram(prog); 7.305 + if(prog && (err = glGetError()) != GL_NO_ERROR) { 7.306 + /* maybe the program is not linked, try linking first */ 7.307 + if(err == GL_INVALID_OPERATION) { 7.308 + if(link_program(prog) == -1) { 7.309 + return -1; 7.310 + } 7.311 + glUseProgram(prog); 7.312 + return glGetError() == GL_NO_ERROR ? 0 : -1; 7.313 + } 7.314 + return -1; 7.315 + } 7.316 + return 0; 7.317 +} 7.318 + 7.319 +/* ugly but I'm not going to write the same bloody code over and over */ 7.320 +#define BEGIN_UNIFORM_CODE \ 7.321 + int loc, curr_prog; \ 7.322 + glGetIntegerv(GL_CURRENT_PROGRAM, &curr_prog); \ 7.323 + if((unsigned int)curr_prog != prog && bind_program(prog) == -1) { \ 7.324 + return -1; \ 7.325 + } \ 7.326 + if((loc = glGetUniformLocation(prog, name)) != -1) 7.327 + 7.328 +#define END_UNIFORM_CODE \ 7.329 + if((unsigned int)curr_prog != prog) { \ 7.330 + bind_program(curr_prog); \ 7.331 + } \ 7.332 + return loc == -1 ? -1 : 0 7.333 + 7.334 +int set_uniform_int(unsigned int prog, const char *name, int val) 7.335 +{ 7.336 + BEGIN_UNIFORM_CODE { 7.337 + glUniform1i(loc, val); 7.338 + } 7.339 + END_UNIFORM_CODE; 7.340 +} 7.341 + 7.342 +int set_uniform_float(unsigned int prog, const char *name, float val) 7.343 +{ 7.344 + BEGIN_UNIFORM_CODE { 7.345 + glUniform1f(loc, val); 7.346 + } 7.347 + END_UNIFORM_CODE; 7.348 +} 7.349 + 7.350 +int set_uniform_float2(unsigned int prog, const char *name, float x, float y) 7.351 +{ 7.352 + BEGIN_UNIFORM_CODE { 7.353 + glUniform2f(loc, x, y); 7.354 + } 7.355 + END_UNIFORM_CODE; 7.356 +} 7.357 + 7.358 +int set_uniform_float3(unsigned int prog, const char *name, float x, float y, float z) 7.359 +{ 7.360 + BEGIN_UNIFORM_CODE { 7.361 + glUniform3f(loc, x, y, z); 7.362 + } 7.363 + END_UNIFORM_CODE; 7.364 +} 7.365 + 7.366 +int set_uniform_float4(unsigned int prog, const char *name, float x, float y, float z, float w) 7.367 +{ 7.368 + BEGIN_UNIFORM_CODE { 7.369 + glUniform4f(loc, x, y, z, w); 7.370 + } 7.371 + END_UNIFORM_CODE; 7.372 +} 7.373 + 7.374 +int set_uniform_matrix4(unsigned int prog, const char *name, float *mat) 7.375 +{ 7.376 + BEGIN_UNIFORM_CODE { 7.377 + glUniformMatrix4fv(loc, 1, GL_FALSE, mat); 7.378 + } 7.379 + END_UNIFORM_CODE; 7.380 +} 7.381 + 7.382 +int set_uniform_matrix4_transposed(unsigned int prog, const char *name, float *mat) 7.383 +{ 7.384 + BEGIN_UNIFORM_CODE { 7.385 + glUniformMatrix4fv(loc, 1, GL_TRUE, mat); 7.386 + } 7.387 + END_UNIFORM_CODE; 7.388 +} 7.389 + 7.390 +int get_attrib_loc(unsigned int prog, const char *name) 7.391 +{ 7.392 + int loc, curr_prog; 7.393 + 7.394 + glGetIntegerv(GL_CURRENT_PROGRAM, &curr_prog); 7.395 + if((unsigned int)curr_prog != prog && bind_program(prog) == -1) { 7.396 + return -1; 7.397 + } 7.398 + 7.399 + loc = glGetAttribLocation(prog, (char*)name); 7.400 + 7.401 + if((unsigned int)curr_prog != prog) { 7.402 + bind_program(curr_prog); 7.403 + } 7.404 + return loc; 7.405 +} 7.406 + 7.407 +void set_attrib_float3(int attr_loc, float x, float y, float z) 7.408 +{ 7.409 + glVertexAttrib3f(attr_loc, x, y, z); 7.410 +} 7.411 + 7.412 +static const char *sdrtypestr(unsigned int sdrtype) 7.413 +{ 7.414 + switch(sdrtype) { 7.415 + case GL_VERTEX_SHADER: 7.416 + return "vertex"; 7.417 + case GL_FRAGMENT_SHADER: 7.418 + return "pixel"; 7.419 + case GL_TESS_CONTROL_SHADER: 7.420 + return "tessellation control"; 7.421 + case GL_TESS_EVALUATION_SHADER: 7.422 + return "tessellation evaluation"; 7.423 + case GL_GEOMETRY_SHADER: 7.424 + return "geometry"; 7.425 + 7.426 + default: 7.427 + break; 7.428 + } 7.429 + return "<unknown>"; 7.430 +}
8.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 8.2 +++ b/src/sdr.h Sat Sep 21 05:22:48 2013 +0300 8.3 @@ -0,0 +1,76 @@ 8.4 +/* 8.5 +Printblobs - halftoning display hack 8.6 +Copyright (C) 2013 John Tsiombikas <nuclear@member.fsf.org> 8.7 + 8.8 +This program is free software: you can redistribute it and/or modify 8.9 +it under the terms of the GNU General Public License as published by 8.10 +the Free Software Foundation, either version 3 of the License, or 8.11 +(at your option) any later version. 8.12 + 8.13 +This program is distributed in the hope that it will be useful, 8.14 +but WITHOUT ANY WARRANTY; without even the implied warranty of 8.15 +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 8.16 +GNU General Public License for more details. 8.17 + 8.18 +You should have received a copy of the GNU General Public License 8.19 +along with this program. If not, see <http://www.gnu.org/licenses/>. 8.20 +*/ 8.21 +#ifndef SDR_H_ 8.22 +#define SDR_H_ 8.23 + 8.24 +#ifdef __cplusplus 8.25 +extern "C" { 8.26 +#endif /* __cplusplus */ 8.27 + 8.28 +/* ---- shaders ---- */ 8.29 +unsigned int create_vertex_shader(const char *src); 8.30 +unsigned int create_pixel_shader(const char *src); 8.31 +unsigned int create_tessctl_shader(const char *src); 8.32 +unsigned int create_tesseval_shader(const char *src); 8.33 +unsigned int create_geometry_shader(const char *src); 8.34 +unsigned int create_shader(const char *src, unsigned int sdr_type); 8.35 +void free_shader(unsigned int sdr); 8.36 + 8.37 +unsigned int load_vertex_shader(const char *fname); 8.38 +unsigned int load_pixel_shader(const char *fname); 8.39 +unsigned int load_tessctl_shader(const char *fname); 8.40 +unsigned int load_tesseval_shader(const char *fname); 8.41 +unsigned int load_geometry_shader(const char *fname); 8.42 +unsigned int load_shader(const char *src, unsigned int sdr_type); 8.43 + 8.44 +unsigned int get_vertex_shader(const char *fname); 8.45 +unsigned int get_pixel_shader(const char *fname); 8.46 +unsigned int get_tessctl_shader(const char *fname); 8.47 +unsigned int get_tesseval_shader(const char *fname); 8.48 +unsigned int get_geometry_shader(const char *fname); 8.49 +unsigned int get_shader(const char *fname, unsigned int sdr_type); 8.50 + 8.51 +int add_shader(const char *fname, unsigned int sdr); 8.52 +int remove_shader(const char *fname); 8.53 + 8.54 +/* ---- gpu programs ---- */ 8.55 +unsigned int create_program(void); 8.56 +unsigned int create_program_link(unsigned int sdr0, ...); 8.57 +unsigned int create_program_load(const char *vfile, const char *pfile); 8.58 +void free_program(unsigned int sdr); 8.59 + 8.60 +void attach_shader(unsigned int prog, unsigned int sdr); 8.61 +int link_program(unsigned int prog); 8.62 +int bind_program(unsigned int prog); 8.63 + 8.64 +int set_uniform_int(unsigned int prog, const char *name, int val); 8.65 +int set_uniform_float(unsigned int prog, const char *name, float val); 8.66 +int set_uniform_float2(unsigned int prog, const char *name, float x, float y); 8.67 +int set_uniform_float3(unsigned int prog, const char *name, float x, float y, float z); 8.68 +int set_uniform_float4(unsigned int prog, const char *name, float x, float y, float z, float w); 8.69 +int set_uniform_matrix4(unsigned int prog, const char *name, float *mat); 8.70 +int set_uniform_matrix4_transposed(unsigned int prog, const char *name, float *mat); 8.71 + 8.72 +int get_attrib_loc(unsigned int prog, const char *name); 8.73 +void set_attrib_float3(int attr_loc, float x, float y, float z); 8.74 + 8.75 +#ifdef __cplusplus 8.76 +} 8.77 +#endif /* __cplusplus */ 8.78 + 8.79 +#endif /* SDR_H_ */
9.1 --- a/src/vr.cc Sat Sep 21 04:15:20 2013 +0300 9.2 +++ b/src/vr.cc Sat Sep 21 05:22:48 2013 +0300 9.3 @@ -98,9 +98,15 @@ 9.4 float proj_shift = center_dist_meters - info.LensSeparationDistance * 0.5; 9.5 vr_ctx.info.proj_center_offset = 4.0 * proj_shift / info.HScreenSize; 9.6 9.7 - // grab the display name 9.8 + // grab the display info 9.9 vr_ctx.info.display = new char[strlen(info.DisplayDeviceName) + 1]; 9.10 strcpy(vr_ctx.info.display, info.DisplayDeviceName); 9.11 + 9.12 + vr_ctx.info.display_xoffs = info.DesktopX; 9.13 + vr_ctx.info.display_yoffs = info.DesktopY; 9.14 + 9.15 + printf("display: \"%s\" offset: %+d %+d\n", vr_ctx.info.display, 9.16 + vr_ctx.info.display_xoffs, vr_ctx.info.display_yoffs); 9.17 } 9.18 9.19 // get the sensor device 9.20 @@ -209,6 +215,17 @@ 9.21 return true; 9.22 } 9.23 9.24 +extern "C" const char *vr_get_display_name(void) 9.25 +{ 9.26 + return vr_ctx.info.display; 9.27 +} 9.28 + 9.29 +extern "C" void vr_get_display_pos(int *xptr, int *yptr) 9.30 +{ 9.31 + *xptr = vr_ctx.info.display_xoffs; 9.32 + *yptr = vr_ctx.info.display_yoffs; 9.33 +} 9.34 + 9.35 extern "C" int vr_get_width(void) 9.36 { 9.37 return vr_ctx.info.width;
10.1 --- a/src/vr.h Sat Sep 21 04:15:20 2013 +0300 10.2 +++ b/src/vr.h Sat Sep 21 05:22:48 2013 +0300 10.3 @@ -22,6 +22,9 @@ 10.4 int vr_init(enum vr_init_mode mode); 10.5 void vr_shutdown(void); 10.6 10.7 +const char *vr_get_display_name(void); 10.8 +void vr_get_display_pos(int *xptr, int *yptr); 10.9 + 10.10 int vr_get_width(void); 10.11 int vr_get_height(void); 10.12
11.1 --- a/src/vr_impl.h Sat Sep 21 04:15:20 2013 +0300 11.2 +++ b/src/vr_impl.h Sat Sep 21 05:22:48 2013 +0300 11.3 @@ -13,6 +13,8 @@ 11.4 11.5 struct { 11.6 char *display; 11.7 + int display_xoffs, display_yoffs; 11.8 + 11.9 // the full width and height of the display (both eyes) 11.10 int width, height; 11.11 float fov;