📄 main.cpp
字号:
objects->lights = (light *) malloc_align(sizeof(light)*objects->num_lights, 7); // Commented out, but gives an alternate implementation using a point light source... // Later in the code, we update the position of the light to follow the paddle. // This has no effect for the directional light source, but will show with the point light /* objects->lights[0].type = LIGHT_POINT; objects->lights[0].position_x = 0.5f; objects->lights[0].position_y = 1.0f; objects->lights[0].position_z = 0.1f; objects->lights[0].color_x = 1.0f; objects->lights[0].color_y = 0.0f; objects->lights[0].color_z = 0.0f; objects->lights[0].attn_x = 1.0f; objects->lights[0].attn_y = 1.0f; objects->lights[0].attn_z = 1.0f; */ objects->lights[0].type = LIGHT_DIRECTIONAL; objects->lights[0].direction_x = 0.0f; objects->lights[0].direction_y = 1.0f; objects->lights[0].direction_z = -1.0f; objects->lights[0].color_x = 1.0f; objects->lights[0].color_y = 1.0f; objects->lights[0].color_z = 1.0f; objects->lights[0].attn_x = 1.0f; objects->lights[0].attn_y = 1.0f; objects->lights[0].attn_z = 1.0f; bsInit(objects); //INITIALIZE FRAME BUFFER bool fb_good = false; if(fb_good = fb_init()) fb_set_all_pixels(RGB32(0, 0, 0)); // INITIALIZE JOYSTICK int fd = open("/dev/js0", O_RDONLY | O_NONBLOCK); float cam_x = 1.0f; float cam_y = -0.5; float cam_z = 1.5f; int direction = 1; float lightDir = 0.1f; float bx, by, bz; bx = 0.3f; by = 0.8f; bz = 0.041f; float dx,dy,dz; dx = 0.006f; dy = 0.014f; dz = 0.0f; // Paddle will move in the x direction float paddleSpeed[2] = {0.02f, -0.02f}; float paddleX = 0.4f; int inum = 1; float totalTime = 0; bool paused = false; // 4 view modes: top of board looking at ball, paddle looking at ball, ball looking at paddle, above board int viewMode = 3; // Set the initial position of the sphere, as well as the initial camera position and direction // and the ambient lighting term objects->spheres[0].setPosition((vector float) {bx, by, bz, 0.0f}); bsSetCenter(0.5f, 1.2f, 0.2f); bsLookAt(bx, by, bz, 0.0f, 0.0f, 1.0f); bsAmbient(0.1f, 0.1f, 0.1f); while(1) { // If we're paused, we still want to receive input to unpause, but nothing else... // So we check for input, but simply continue with the next iteration of the game loop // if we haven't been unpaused. This check it done within a frame rendering, but // the latency from the rendering process is not a problem in practice, where the user // will receive almost immediate unpausing, despite waiting on the scene to finish rendering if (paused) { bsRenderScene(image); if (getch() == 'p') paused = false; struct js_event pEvent; int s = read(fd, &pEvent, sizeof(struct js_event)); if (s > 0) { int type = pEvent.type; type &= ~JS_EVENT_INIT; if (type == JS_EVENT_BUTTON && pEvent.number == 3 && pEvent.value) paused = false; } bsWait(); // Still want to update the frame buffer when paused, this assures that if(fb_good) { fb_memcpy_frame((unsigned int*)&image[0], IMG_WIDTH, IMG_HEIGHT); fb_flip_buffer(); } continue; } uint32_t curr_i = 0; // Let's get things started... // Start the scene rendering process on the SPUs bsRenderScene(image); // Perform the updates to the ball velocities if we have hit the extremities bx += dx; by += dy; bz += dz; if ((bx > paddleX) && (bx < paddleX + 0.15f) && (by < 0.09f)) { dy = -dy; by = 0.09f; } if ((bx > 0.96f) || (bx < 0.04f)){ dx = -dx; } if ((by > 0.96f)) { dy = -dy; } if (by < 0.04f) { paused= true; dy = -dy; bx = 0.3f; by = 0.8f; } char input = '0'; struct js_event jsEvent; static bool lDown = false; static bool rDown = false; // While the scene is still being rendered... Accept keyboard and joystick input while (!bsDone()) { if (kbhit()) { input = getch(); } int s = read(fd, &jsEvent, sizeof(struct js_event)); if (s > 0) { int type = jsEvent.type; type &= ~JS_EVENT_INIT; if (type == JS_EVENT_BUTTON) { printf("Button pressed: %i\n", jsEvent.number); if (jsEvent.number == 5) { rDown = (bool) jsEvent.value; } if (jsEvent.number == 7) { lDown = (bool) jsEvent.value; } if (jsEvent.number == 10 && jsEvent.value) { viewMode = (viewMode > 0)? (viewMode - 1):0; } if (jsEvent.number == 11 && jsEvent.value) { viewMode = (viewMode < 3)? (viewMode + 1):3; } if (jsEvent.number == 16 && jsEvent.value) { DEINITKEYBOARD; exit(0); } if (jsEvent.number == 3 && jsEvent.value) { paused = true; } } } } // Wait on the rendering to finish bsWait(); // After the rendering has completed, let's update the objects based on the input received int whichSpeed = viewMode%2; bool checkBounds[2] = {(paddleX > 0.0f), (paddleX < 1.0f - 0.2f)}; if (rDown && checkBounds[whichSpeed]) { paddleX -= paddleSpeed[whichSpeed]; objects->triangles[2].translate((vector float) {-paddleSpeed[whichSpeed], 0.0f, 0.0f, 0.0f}); objects->triangles[3].translate((vector float) {-paddleSpeed[whichSpeed], 0.0f, 0.0f, 0.0f}); } if (lDown && checkBounds[1 - whichSpeed]) { paddleX += paddleSpeed[whichSpeed]; objects->triangles[2].translate((vector float) {paddleSpeed[whichSpeed], 0.0f, 0.0f, 0.0f}); objects->triangles[3].translate((vector float) {paddleSpeed[whichSpeed], 0.0f, 0.0f, 0.0f}); } switch (input) { case '/': if (checkBounds[whichSpeed]) { paddleX -= -paddleSpeed[whichSpeed]; objects->triangles[2].translate((vector float) {-paddleSpeed[whichSpeed], 0.0f, 0.0f, 0.0f}); objects->triangles[3].translate((vector float) {-paddleSpeed[whichSpeed], 0.0f, 0.0f, 0.0f}); } break; case 'z': if (checkBounds[whichSpeed]) { paddleX += paddleSpeed[whichSpeed]; objects->triangles[2].translate((vector float) {paddleSpeed[whichSpeed], 0.0f, 0.0f, 0.0f}); objects->triangles[3].translate((vector float) {paddleSpeed[whichSpeed], 0.0f, 0.0f, 0.0f}); } break; case 'p': paused = true; break; case '1': viewMode = 0; break; case '2': viewMode = 1; break; case '3': viewMode = 2; break; default: break; } objects->spheres[0].setPosition((vector float) {bx, by, bz, 0.0f}); objects->lights[0].position_x = paddleX + 0.1f; if (viewMode == 0) { bsSetCenter(0.5f, 1.2f, 0.2f); bsLookAt(bx, by, bz, 0.0f, 0.0f, 1.0f); } if (viewMode == 1) { bsSetCenter(paddleX + 0.05f, 0.0f, 0.15f); bsLookAt(bx, by, bz, 0.0f, 0.0f, 1.0f); } if (viewMode == 2) { bsSetCenter(bx, by+0.15f, bz + 0.1f); bsLookAt(bx, 0.05f, 0.0f, 0.0f, 0.0f, 1.0f); } if (viewMode == 3) { bsSetCenter(0.5f, 0.5f, 1.0f); bsLookAt(0.5f, 0.5f, 0.0f, 0.0f, 1.0f, 0.0f); } // If the frame buffer is not being used, we can write each frame to an image file... // This code is commented out in the release, but is left in to demonstrate the process // an image would undergo for writing the pixels. /*#if(!FRAME_BUFFER) int index = 0; for (int i = IMG_HEIGHT - 1; i >= 0 ; i--) { for (int j = 0; j < IMG_WIDTH; j+=4) { //union { //vector float c; //float v[4]; //} rv, gv, bv; //rv.c = image[index].r; gv.c = image[index].g; bv.c = image[index].b; //dprintf("(i,j) (r,g,b):\t(%i, %i)\t (%f, %f, %f)", i, j, rv.v[0], gv.v[0], bv.v[0]); uint32_t x = j; uint32_t y = i; vector unsigned int xx = (vector unsigned int) {x, x + 1, x + 2, x + 3}; vector unsigned int yy = (vector unsigned int) {y, y, y, y}; RGBPacket color; color.r = _unpack_rgba8_v(image[index], 0); color.g = _unpack_rgba8_v(image[index], 1); color.b = _unpack_rgba8_v(image[index], 2); img->SetPixelPacket(xx, yy, color); index++; } } sprintf(filename, "demo%i.tga", inum); img->SaveTGA(filename); #endif */ inum++; if(fb_good) { fb_memcpy_frame((unsigned int*)&image[0], IMG_WIDTH, IMG_HEIGHT); fb_flip_buffer(); } } //render loop DEINITKEYBOARD; if(fb_good) { fb_shutdown(); fb_good = false; } return 0;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -