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 +}