📄 glpuzzle.cxx
字号:
** Ok, no problem. ** Now we solve for x and y. We know that w = c + d z, so we compute it. */ w = c + d * z; /* ** Now for x and y: */ *selx = (in[0] * finalMatrix[0 * 4 + 0] + in[1] * finalMatrix[1 * 4 + 0] + z * finalMatrix[2 * 4 + 0] + finalMatrix[3 * 4 + 0]) / w - OFFSETX; *sely = (in[0] * finalMatrix[0 * 4 + 1] + in[1] * finalMatrix[1 * 4 + 1] + z * finalMatrix[2 * 4 + 1] + finalMatrix[3 * 4 + 1]) / w - OFFSETY; return 1;}static int selected;static int selectx, selecty;static float selstartx, selstarty;voidgrabPiece(int piece, float selx, float sely){ int hit; selectx = int(selx); selecty = int(sely); if (selectx < 0 || selecty < 0 || selectx >= WIDTH || selecty >= HEIGHT) { return; } hit = thePuzzle[selecty][selectx]; if (hit != piece) return; if (hit) { movingPiece = hit; while (selectx > 0 && thePuzzle[selecty][selectx - 1] == movingPiece) { selectx--; } while (selecty > 0 && thePuzzle[selecty - 1][selectx] == movingPiece) { selecty--; } move_x = selectx; move_y = selecty; selected = 1; selstartx = selx; selstarty = sely; } else { selected = 0; } changeState();}voidmoveSelection(float selx, float sely){ float deltax, deltay; int dir; Config newpieces; if (!selected) return; deltax = selx - selstartx; deltay = sely - selstarty; if (fabs(deltax) > fabs(deltay)) { deltay = 0; if (deltax > 0) { if (deltax > 1) deltax = 1; dir = 2; } else { if (deltax < -1) deltax = -1; dir = 0; } } else { deltax = 0; if (deltay > 0) { if (deltay > 1) deltay = 1; dir = 3; } else { if (deltay < -1) deltay = -1; dir = 1; } } if (canmove(thePuzzle, selectx, selecty, dir, newpieces)) { move_x = deltax + selectx; move_y = deltay + selecty; if (deltax > 0.5) { memcpy(thePuzzle, newpieces, HEIGHT * WIDTH); selectx++; selstartx++; } else if (deltax < -0.5) { memcpy(thePuzzle, newpieces, HEIGHT * WIDTH); selectx--; selstartx--; } else if (deltay > 0.5) { memcpy(thePuzzle, newpieces, HEIGHT * WIDTH); selecty++; selstarty++; } else if (deltay < -0.5) { memcpy(thePuzzle, newpieces, HEIGHT * WIDTH); selecty--; selstarty--; } } else { if (deltay > 0 && thePuzzle[selecty][selectx] == 10 && selectx == 1 && selecty == 3) { /* Allow visual movement of solution piece outside of the box */ move_x = selectx; move_y = sely - selstarty + selecty; } else { move_x = selectx; move_y = selecty; } }}voiddropSelection(void){ if (!selected) return; movingPiece = 0; selected = 0; changeState();}static int left_mouse, middle_mouse;static int mousex, mousey;static int solving;static int spinning;static float lastquat[4];static int sel_piece;static voidReshape(int width, int height){ W = width; H = height; glViewport(0, 0, W, H); glGetIntegerv(GL_VIEWPORT, viewport);}voidtoggleSolve(void){ if (solving) { freeSolutions(); solving = 0; glutChangeToMenuEntry(1, "Solving", 1); glutSetWindowTitle("glpuzzle"); movingPiece = 0; } else { glutChangeToMenuEntry(1, "Stop solving", 1); glutSetWindowTitle("Solving..."); if (solvePuzzle()) { solving = 1; } } changeState(); glutPostRedisplay();}void reset(void){ if (solving) { freeSolutions(); solving = 0; glutChangeToMenuEntry(1, "Solving", 1); glutSetWindowTitle("glpuzzle"); movingPiece = 0; changeState(); } memcpy(thePuzzle, startConfig, HEIGHT * WIDTH); glutPostRedisplay();}voidkeyboard(unsigned char c, int x, int y){ int piece; switch (c) { case 27: exit(0); break; case 'D': case 'd': if (solving) { freeSolutions(); solving = 0; glutChangeToMenuEntry(1, "Solving", 1); glutSetWindowTitle("glpuzzle"); movingPiece = 0; changeState(); } piece = selectPiece(x, y); if (piece) { nukePiece(piece); } glutPostRedisplay(); break; case 'R': case 'r': reset(); break; case 'S': case 's': toggleSolve(); break; case 'b': case 'B': depth = 1 - depth; if (depth) { glEnable(GL_DEPTH_TEST); } else { glDisable(GL_DEPTH_TEST); } glutPostRedisplay(); break; default: break; }}voidmotion(int x, int y){ float selx, sely; if (middle_mouse && !left_mouse) { if (mousex != x || mousey != y) { trackball(lastquat, (2.0*mousex - W) / W, (H - 2.0*mousey) / H, (2.0*x - W) / W, (H - 2.0*y) / H); spinning = 1; } else { spinning = 0; } changeState(); } else { computeCoords(sel_piece, x, y, &selx, &sely); moveSelection(selx, sely); } mousex = x; mousey = y; glutPostRedisplay();}voidmouse(int b, int s, int x, int y){ float selx, sely; mousex = x; mousey = y; curX = x; curY = y; if (s == GLUT_DOWN) { switch (b) { case GLUT_LEFT_BUTTON: if (solving) { freeSolutions(); solving = 0; glutChangeToMenuEntry(1, "Solving", 1); glutSetWindowTitle("glpuzzle"); movingPiece = 0; } left_mouse = GL_TRUE; sel_piece = selectPiece(mousex, mousey); if (!sel_piece) { left_mouse = GL_FALSE; middle_mouse = GL_TRUE; // let it rotate object } else if (computeCoords(sel_piece, mousex, mousey, &selx, &sely)) { grabPiece(sel_piece, selx, sely); } glutPostRedisplay(); break; case GLUT_MIDDLE_BUTTON: middle_mouse = GL_TRUE; glutPostRedisplay(); break; } } else { if (left_mouse) { left_mouse = GL_FALSE; dropSelection(); glutPostRedisplay(); } else if (middle_mouse) { middle_mouse = GL_FALSE; glutPostRedisplay(); } } motion(x, y);}voidanimate(void){ if (spinning) { add_quats(lastquat, curquat, curquat); } glutPostRedisplay(); if (solving) { if (!continueSolving()) { solving = 0; glutChangeToMenuEntry(1, "Solving", 1); glutSetWindowTitle("glpuzzle"); } } if (!solving && !spinning && !visible) { glutIdleFunc(NULL); }}voidchangeState(void){ if (visible) { if (!solving && !spinning) { glutIdleFunc(NULL); } else { glutIdleFunc(animate); } } else { glutIdleFunc(NULL); }}voidinit(void){ static float lmodel_ambient[] = {0.0, 0.0, 0.0, 0.0}; static float lmodel_twoside[] = {GL_FALSE}; static float lmodel_local[] = {GL_FALSE}; static float light0_ambient[] = {0.1, 0.1, 0.1, 1.0}; static float light0_diffuse[] = {1.0, 1.0, 1.0, 0.0}; static float light0_position[] = {0.8660254, 0.5, 1, 0}; static float light0_specular[] = {0.0, 0.0, 0.0, 0.0}; static float bevel_mat_ambient[] = {0.0, 0.0, 0.0, 1.0}; static float bevel_mat_shininess[] = {40.0}; static float bevel_mat_specular[] = {0.0, 0.0, 0.0, 0.0}; static float bevel_mat_diffuse[] = {1.0, 0.0, 0.0, 0.0}; glEnable(GL_CULL_FACE); glCullFace(GL_BACK); glEnable(GL_DEPTH_TEST); glClearDepth(1.0); glClearColor(0.5, 0.5, 0.5, 0.0); glLightfv(GL_LIGHT0, GL_AMBIENT, light0_ambient); glLightfv(GL_LIGHT0, GL_DIFFUSE, light0_diffuse); glLightfv(GL_LIGHT0, GL_SPECULAR, light0_specular); glLightfv(GL_LIGHT0, GL_POSITION, light0_position); glEnable(GL_LIGHT0); glLightModelfv(GL_LIGHT_MODEL_LOCAL_VIEWER, lmodel_local); glLightModelfv(GL_LIGHT_MODEL_TWO_SIDE, lmodel_twoside); glLightModelfv(GL_LIGHT_MODEL_AMBIENT, lmodel_ambient); glEnable(GL_LIGHTING); glMaterialfv(GL_FRONT, GL_AMBIENT, bevel_mat_ambient); glMaterialfv(GL_FRONT, GL_SHININESS, bevel_mat_shininess); glMaterialfv(GL_FRONT, GL_SPECULAR, bevel_mat_specular); glMaterialfv(GL_FRONT, GL_DIFFUSE, bevel_mat_diffuse); glColorMaterial(GL_FRONT_AND_BACK, GL_DIFFUSE); glEnable(GL_COLOR_MATERIAL); glShadeModel(GL_FLAT); trackball(curquat, 0.0, 0.0, 0.0, 0.0); srandom(time(NULL));}static voidUsage(void){ printf("Usage: puzzle [-s]\n"); printf(" -s: Run in single buffered mode\n"); exit(-1);}voidvisibility(int v){ if (v == GLUT_VISIBLE) { visible = 1; } else { visible = 0; } changeState();}voidmenu(int choice){ switch(choice) { case 1: toggleSolve(); break; case 2: reset(); break; case 3: exit(0); break; }}intmain(int argc, char **argv){ long i; glutInit(&argc, argv); for (i = 1; i < argc; i++) { if (argv[i][0] == '-') { switch (argv[i][1]) { case 's': doubleBuffer = 0; break; default: Usage(); } } else { Usage(); } } glutInitWindowSize(W, H); if (doubleBuffer) { glutInitDisplayMode(GLUT_DEPTH | GLUT_RGB | GLUT_DOUBLE | GLUT_MULTISAMPLE); } else { glutInitDisplayMode(GLUT_DEPTH | GLUT_RGB | GLUT_SINGLE | GLUT_MULTISAMPLE); } glutCreateWindow("glpuzzle"); visible = 1; // added for fltk, bug in original program? init(); glGetIntegerv(GL_VIEWPORT, viewport); printf("\n"); printf("r Reset puzzle\n"); printf("s Solve puzzle (may take a few seconds to compute)\n"); printf("d Destroy a piece - makes the puzzle easier\n"); printf("b Toggles the depth buffer on and off\n"); printf("\n"); printf("Left mouse moves pieces\n"); printf("Middle mouse spins the puzzle\n"); printf("Right mouse has menu\n"); glutReshapeFunc(Reshape); glutDisplayFunc(redraw); glutKeyboardFunc(keyboard); glutMotionFunc(motion); glutMouseFunc(mouse); glutVisibilityFunc(visibility); glutCreateMenu(menu); glutAddMenuEntry("Solve", 1); glutAddMenuEntry("Reset", 2); glutAddMenuEntry("Quit", 3); glutAttachMenu(GLUT_RIGHT_BUTTON); glutMainLoop(); return 0; /* ANSI C requires main to return int. */}#endif // added for fltk's distribution//// End of "$Id: glpuzzle.cxx,v 1.1.1.1 2003/08/07 21:18:42 jasonk Exp $".//
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -