oculus1
diff src/main.cc @ 18:1b107de821c1
fixed the test to work with non-pow2 textures
author | John Tsiombikas <nuclear@member.fsf.org> |
---|---|
date | Thu, 26 Sep 2013 10:33:08 +0300 |
parents | f3672317e5c2 |
children | ff3bfd4da86b 0c76f70fb7e9 |
line diff
1.1 --- a/src/main.cc Sat Sep 21 07:09:48 2013 +0300 1.2 +++ b/src/main.cc Thu Sep 26 10:33:08 2013 +0300 1.3 @@ -7,6 +7,12 @@ 1.4 #include "camera.h" 1.5 #include "sdr.h" 1.6 1.7 +#ifdef __APPLE__ 1.8 +#include <OpenGL/OpenGL.h> 1.9 +#include <OpenGL/CGLCurrent.h> 1.10 +#include <ApplicationServices/ApplicationServices.h> 1.11 +#endif 1.12 + 1.13 static bool init(); 1.14 static void cleanup(); 1.15 static void disp(); 1.16 @@ -26,6 +32,8 @@ 1.17 static void passive(int x, int y); 1.18 static void sball_rotate(int rx, int ry, int rz); 1.19 static bool parse_args(int argc, char **argv); 1.20 +static void printfps(); 1.21 +static int next_pow2(int x); 1.22 1.23 static VRFpsCamera cam; 1.24 static int width, height; 1.25 @@ -33,13 +41,15 @@ 1.26 1.27 static bool keystate[256]; 1.28 1.29 -static int rtarg_width, rtarg_height; 1.30 +static int rtarg_width, rtarg_height, rtarg_tex_width, rtarg_tex_height; 1.31 +static float tex_scale_x, tex_scale_y; 1.32 static unsigned int fbo, tex[2], zbuf; 1.33 1.34 static unsigned int teapot_sdr; 1.35 1.36 static bool fullscreen_pending; 1.37 1.38 + 1.39 int main(int argc, char **argv) 1.40 { 1.41 glutInitWindowSize(1280, 800); 1.42 @@ -102,7 +112,12 @@ 1.43 rtarg_width = (xsz + xsz / 2) / 2; 1.44 rtarg_height = ysz + ysz / 2; 1.45 1.46 - printf("render target: %dx%d\n", rtarg_width, rtarg_height); 1.47 + rtarg_tex_width = next_pow2(rtarg_width); 1.48 + rtarg_tex_height = next_pow2(rtarg_height); 1.49 + tex_scale_x = (float)rtarg_width / (float)rtarg_tex_width; 1.50 + tex_scale_y = (float)rtarg_height / (float)rtarg_tex_height; 1.51 + 1.52 + printf("render target: %dx%d (%dx%d)\n", rtarg_width, rtarg_height, rtarg_tex_width, rtarg_tex_height); 1.53 1.54 // create render targets for each eye 1.55 GLenum wrap_mode = GL_CLAMP_TO_EDGE; 1.56 @@ -117,31 +132,43 @@ 1.57 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); 1.58 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, wrap_mode); 1.59 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, wrap_mode); 1.60 - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, rtarg_width, rtarg_height, 0, GL_RGB, GL_UNSIGNED_BYTE, 0); 1.61 + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, rtarg_tex_width, rtarg_tex_height, 0, GL_RGB, GL_UNSIGNED_BYTE, 0); 1.62 } 1.63 1.64 // create the depth render buffer 1.65 - glGenRenderbuffers(1, &zbuf); 1.66 - glBindRenderbuffer(GL_RENDERBUFFER, zbuf); 1.67 - glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT24, rtarg_width, rtarg_height); 1.68 + glGenRenderbuffersEXT(1, &zbuf); 1.69 + glBindRenderbufferEXT(GL_RENDERBUFFER, zbuf); 1.70 + glRenderbufferStorageEXT(GL_RENDERBUFFER, GL_DEPTH_COMPONENT24, rtarg_tex_width, rtarg_tex_height); 1.71 1.72 // create the FBO 1.73 - glGenFramebuffers(1, &fbo); 1.74 - glBindFramebuffer(GL_FRAMEBUFFER, fbo); 1.75 - glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, tex[0], 0); 1.76 - glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, zbuf); 1.77 + glGenFramebuffersEXT(1, &fbo); 1.78 + glBindFramebufferEXT(GL_FRAMEBUFFER, fbo); 1.79 + glFramebufferTextureEXT(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, tex[0], 0); 1.80 + glFramebufferRenderbufferEXT(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, zbuf); 1.81 } 1.82 1.83 teapot_sdr = create_program_load("sdr/phong.v.glsl", "sdr/phong.p.glsl"); 1.84 1.85 + // enable vsync 1.86 +#ifdef __APPLE__ 1.87 + int swapint = 1; 1.88 + CGLContextObj ctx = CGLGetCurrentContext(); 1.89 + CGLSetParameter(ctx, kCGLCPSwapInterval, &swapint); 1.90 +#endif 1.91 + 1.92 +#ifdef __APPLE__ 1.93 + // this is required for glutWarpPointer to work correctly, otherwise after every 1.94 + // warp, mac os x freezes event processing for 1/4 second. 1.95 + CGSetLocalEventsSuppressionInterval(0.0); 1.96 +#endif 1.97 return true; 1.98 } 1.99 1.100 static void cleanup() 1.101 { 1.102 glDeleteTextures(2, tex); 1.103 - glDeleteRenderbuffers(1, &zbuf); 1.104 - glDeleteFramebuffers(1, &fbo); 1.105 + glDeleteRenderbuffersEXT(1, &zbuf); 1.106 + glDeleteFramebuffersEXT(1, &fbo); 1.107 vr_shutdown(); 1.108 } 1.109 1.110 @@ -189,6 +216,8 @@ 1.111 1.112 glutSwapBuffers(); 1.113 assert(glGetError() == GL_NO_ERROR); 1.114 + 1.115 + printfps(); 1.116 } 1.117 1.118 // display function used in VR mode 1.119 @@ -211,8 +240,8 @@ 1.120 glClearColor(0.1, 0.1, 0.1, 1.0); 1.121 1.122 // draw left view 1.123 - glBindFramebuffer(GL_FRAMEBUFFER, fbo); 1.124 - glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, tex[0], 0); 1.125 + glBindFramebufferEXT(GL_FRAMEBUFFER, fbo); 1.126 + glFramebufferTextureEXT(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, tex[0], 0); 1.127 1.128 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 1.129 1.130 @@ -228,8 +257,8 @@ 1.131 1.132 1.133 // draw right view 1.134 - glBindFramebuffer(GL_FRAMEBUFFER, fbo); 1.135 - glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, tex[1], 0); 1.136 + glBindFramebufferEXT(GL_FRAMEBUFFER, fbo); 1.137 + glFramebufferTextureEXT(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, tex[1], 0); 1.138 1.139 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 1.140 1.141 @@ -250,13 +279,15 @@ 1.142 glClearColor(0, 0, 0, 0); 1.143 glClear(GL_COLOR_BUFFER_BIT); 1.144 1.145 - vr_draw_eye(tex[0], VR_EYE_LEFT); 1.146 - vr_draw_eye(tex[1], VR_EYE_RIGHT); 1.147 + vr_draw_eye(VR_EYE_LEFT, tex[0], tex_scale_x, tex_scale_y); 1.148 + vr_draw_eye(VR_EYE_RIGHT, tex[1], tex_scale_x, tex_scale_y); 1.149 1.150 glutSwapBuffers(); 1.151 assert(glGetError() == GL_NO_ERROR); 1.152 1.153 glFinish(); 1.154 + 1.155 + printfps(); 1.156 } 1.157 1.158 static void draw_scene() 1.159 @@ -473,6 +504,21 @@ 1.160 if(!use_vr) { 1.161 rtarg_width = width; 1.162 rtarg_height = height; 1.163 + 1.164 + int new_tex_width = next_pow2(width); 1.165 + int new_tex_height = next_pow2(height); 1.166 + 1.167 + if(new_tex_width != rtarg_tex_width || new_tex_height != rtarg_tex_width) { 1.168 + // TODO 1.169 + exit(1); 1.170 + } 1.171 + 1.172 + rtarg_tex_width = new_tex_width; 1.173 + rtarg_tex_height = new_tex_height; 1.174 + 1.175 + tex_scale_x = (float)rtarg_width / (float)rtarg_tex_width; 1.176 + tex_scale_y = (float)rtarg_height / (float)rtarg_tex_height; 1.177 + 1.178 } 1.179 } 1.180 1.181 @@ -526,7 +572,7 @@ 1.182 int center_y = height / 2; 1.183 1.184 int dx = x - center_x; 1.185 - int dy = y - center_y; 1.186 + int dy = use_vr ? 0 : y - center_y; 1.187 1.188 if(!dx && !dy) { 1.189 return; 1.190 @@ -537,8 +583,8 @@ 1.191 1.192 cam.input_rotate(DEG_TO_RAD(dtheta_deg), DEG_TO_RAD(dphi_deg), 0); 1.193 1.194 + glutWarpPointer(center_x, center_y); 1.195 glutPostRedisplay(); 1.196 - glutWarpPointer(center_x, center_y); 1.197 } 1.198 1.199 static void sball_rotate(int rx, int ry, int rz) 1.200 @@ -564,3 +610,33 @@ 1.201 } 1.202 return true; 1.203 } 1.204 + 1.205 +static void printfps() 1.206 +{ 1.207 + static unsigned int last_upd, frames; 1.208 + unsigned int msec = glutGet(GLUT_ELAPSED_TIME); 1.209 + unsigned int dmsec = msec - last_upd; 1.210 + 1.211 + frames++; 1.212 + 1.213 + if(dmsec > 2000) { 1.214 + float dt = (float)dmsec / 1000.0f; 1.215 + 1.216 + printf("fps: %.2f \r", (float)frames / dt); 1.217 + fflush(stdout); 1.218 + 1.219 + frames = 0; 1.220 + last_upd = msec; 1.221 + } 1.222 +} 1.223 + 1.224 +static int next_pow2(int x) 1.225 +{ 1.226 + x--; 1.227 + x = (x >> 1) | x; 1.228 + x = (x >> 2) | x; 1.229 + x = (x >> 4) | x; 1.230 + x = (x >> 8) | x; 1.231 + x = (x >> 16) | x; 1.232 + return x + 1; 1.233 +}