nuclear@0: #include nuclear@0: #include nuclear@0: #include nuclear@0: #include nuclear@1: #include nuclear@1: nuclear@1: using namespace goatgfx; nuclear@0: nuclear@0: static bool init(); nuclear@0: static void cleanup(); nuclear@1: static void disp(); nuclear@1: static void draw_scene(int which); nuclear@0: static void handle_input(float dt); nuclear@0: static void idle(); nuclear@0: static void reshape(int x, int y); nuclear@0: static void keypress(unsigned char key, int x, int y); nuclear@0: static void keyrelease(unsigned char key, int x, int y); nuclear@0: static void mouse(int bn, int st, int x, int y); nuclear@0: static void motion(int x, int y); nuclear@0: nuclear@1: static int win_width, win_height; nuclear@1: static float split_pos = 0.5; nuclear@1: static VRFpsCamera cam; nuclear@0: static std::vector keystate(256); nuclear@0: nuclear@0: int main(int argc, char **argv) nuclear@0: { nuclear@1: glutInitWindowSize(1024, 768); nuclear@0: glutInit(&argc, argv); nuclear@0: glutInitDisplayMode(GLUT_RGB | GLUT_DEPTH | GLUT_DOUBLE); nuclear@0: glutCreateWindow("symmetry"); nuclear@0: nuclear@0: glutDisplayFunc(disp); nuclear@0: glutIdleFunc(idle); nuclear@0: glutReshapeFunc(reshape); nuclear@0: glutKeyboardFunc(keypress); nuclear@0: glutKeyboardUpFunc(keyrelease); nuclear@0: glutMouseFunc(mouse); nuclear@0: glutMotionFunc(motion); nuclear@0: nuclear@0: if(!init()) { nuclear@0: return 1; nuclear@0: } nuclear@0: atexit(cleanup); nuclear@0: nuclear@0: glutMainLoop(); nuclear@0: return 0; nuclear@0: } nuclear@0: nuclear@0: nuclear@0: static bool init() nuclear@0: { nuclear@0: glewInit(); nuclear@0: nuclear@0: glEnable(GL_DEPTH_TEST); nuclear@0: glEnable(GL_CULL_FACE); nuclear@0: nuclear@0: glEnable(GL_LIGHTING); nuclear@0: glEnable(GL_LIGHT0); nuclear@0: nuclear@0: cam.input_move(0, 1.65, 0); nuclear@0: nuclear@0: return true; nuclear@0: } nuclear@0: nuclear@0: static void cleanup() nuclear@0: { nuclear@0: } nuclear@0: nuclear@0: static void disp() nuclear@0: { nuclear@0: unsigned int msec = glutGet(GLUT_ELAPSED_TIME); nuclear@0: static unsigned int prev_msec; nuclear@0: float dt = (float)(msec - prev_msec) / 1000.0f; nuclear@1: prev_msec = msec; nuclear@0: nuclear@0: handle_input(dt); nuclear@0: nuclear@0: glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); nuclear@0: nuclear@0: cam.use_inverse(); nuclear@1: setup_gl_matrices(); nuclear@0: nuclear@1: float left_pixels = split_pos * win_width; nuclear@0: nuclear@1: glEnable(GL_SCISSOR_TEST); nuclear@1: nuclear@1: // draw left viewport nuclear@1: if(left_pixels > 0) { nuclear@1: glScissor(0, 0, left_pixels, win_height); nuclear@1: draw_scene(0); nuclear@1: } nuclear@1: nuclear@1: // draw right viewport nuclear@1: if(left_pixels < win_width) { nuclear@1: glScissor(left_pixels, 0, win_width - left_pixels, win_height); nuclear@1: draw_scene(1); nuclear@1: } nuclear@1: nuclear@1: glDisable(GL_SCISSOR_TEST); nuclear@0: nuclear@0: glutSwapBuffers(); nuclear@0: assert(glGetError() == GL_NO_ERROR); nuclear@0: } nuclear@0: nuclear@1: static void draw_scene(int which) nuclear@1: { nuclear@1: glMatrixMode(GL_MODELVIEW); nuclear@1: nuclear@1: float lpos[] = {-5, 20, 5, 1}; nuclear@1: glLightfv(GL_LIGHT0, GL_POSITION, lpos); nuclear@1: nuclear@1: float color[][4] = { nuclear@1: {1.0, 0.3, 0.2, 1.0}, nuclear@1: {0.2, 0.3, 1.0, 1.0} nuclear@1: }; nuclear@1: nuclear@1: glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, color[which]); nuclear@1: nuclear@1: glBegin(GL_QUADS); nuclear@1: glNormal3f(0, 1, 0); nuclear@1: glVertex3f(-20, 0, 20); nuclear@1: glVertex3f(20, 0, 20); nuclear@1: glVertex3f(20, 0, -20); nuclear@1: glVertex3f(-20, 0, -20); nuclear@1: glEnd(); nuclear@1: nuclear@1: for(int i=0; i<8; i++) { nuclear@1: float theta = 360.0 * (float)i / 8.0; nuclear@1: glPushMatrix(); nuclear@1: glRotatef(theta, 0, 1, 0); nuclear@1: glTranslatef(0, 0, 10); nuclear@1: nuclear@1: glTranslatef(0, 1, 0); nuclear@1: nuclear@1: glFrontFace(GL_CW); nuclear@1: glutSolidTeapot(1.0); nuclear@1: glFrontFace(GL_CCW); nuclear@1: glPopMatrix(); nuclear@1: } nuclear@1: } nuclear@0: nuclear@0: static void handle_input(float dt) nuclear@0: { nuclear@0: Vector3 inpv; nuclear@0: float offs = dt * 2.0; nuclear@0: nuclear@0: if(keystate['w'] || keystate['W']) { nuclear@0: inpv.z -= offs; nuclear@0: } nuclear@0: if(keystate['s'] || keystate['S']) { nuclear@0: inpv.z += offs; nuclear@0: } nuclear@0: if(keystate['d'] || keystate['D']) { nuclear@0: inpv.x += offs; nuclear@0: } nuclear@0: if(keystate['a'] || keystate['A']) { nuclear@0: inpv.x -= offs; nuclear@0: } nuclear@0: nuclear@0: cam.input_move(inpv.x, inpv.y, inpv.z); nuclear@0: } nuclear@0: nuclear@0: static void idle() nuclear@0: { nuclear@0: glutPostRedisplay(); nuclear@0: } nuclear@0: nuclear@0: static void reshape(int x, int y) nuclear@0: { nuclear@0: glViewport(0, 0, x, y); nuclear@0: nuclear@1: Matrix4x4 proj; nuclear@1: proj.set_perspective(DEG_TO_RAD(50), (float)x / (float)y, 0.5, 500.0); nuclear@1: set_projection_matrix(proj); nuclear@1: nuclear@1: win_width = x; nuclear@1: win_height = y; nuclear@0: } nuclear@0: nuclear@0: static void keypress(unsigned char key, int x, int y) nuclear@0: { nuclear@0: keystate[key] = true; nuclear@0: nuclear@0: switch(key) { nuclear@0: case 27: nuclear@0: exit(0); nuclear@1: nuclear@1: case ' ': nuclear@1: split_pos = 0.5; nuclear@1: break; nuclear@0: } nuclear@0: } nuclear@0: nuclear@0: static void keyrelease(unsigned char key, int x, int y) nuclear@0: { nuclear@0: keystate[key] = false; nuclear@0: } nuclear@0: nuclear@0: static int prev_x, prev_y; nuclear@0: static bool bnstate[32]; nuclear@0: nuclear@0: static void mouse(int bn, int st, int x, int y) nuclear@0: { nuclear@0: prev_x = x; nuclear@0: prev_y = y; nuclear@0: bnstate[bn - GLUT_LEFT_BUTTON] = st == GLUT_DOWN; nuclear@0: } nuclear@0: nuclear@0: static void motion(int x, int y) nuclear@0: { nuclear@0: int dx = x - prev_x; nuclear@0: int dy = y - prev_y; nuclear@0: prev_x = x; nuclear@0: prev_y = y; nuclear@0: nuclear@0: if(!dx && !dy) { nuclear@0: return; nuclear@0: } nuclear@0: nuclear@1: if(keystate[(int)'\b']) { nuclear@1: split_pos = (float)x / win_width; nuclear@1: return; nuclear@1: } nuclear@1: nuclear@0: if(bnstate[0]) { nuclear@0: float dtheta_deg = dy * 0.5; nuclear@0: float dphi_deg = dx * 0.5; nuclear@0: nuclear@0: cam.input_rotate(DEG_TO_RAD(dtheta_deg), DEG_TO_RAD(dphi_deg), 0); nuclear@0: } nuclear@0: }