#include "Client.h" #include "Network.h" #include "Explosion.h" #include "Time.h" #include "btBulletDynamicsCommon.h" #include "Horde3D.h" #include #include #include #include #include #include namespace gln { Explosion explosion; void setup_explosion() { // Loads particle texture GLuint textures[5]; glGenTextures(5, textures); glBindTexture(GL_TEXTURE_2D, textures[0]); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glfwLoadTexture2D("data/explosion/explosion.tga", GLFW_ALPHA_MAP_BIT); glBindTexture(GL_TEXTURE_2D, textures[1]); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glfwLoadTexture2D("data/explosion/flash.tga", 0); glBindTexture(GL_TEXTURE_2D, textures[2]); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glfwLoadTexture2D("data/explosion/spark.tga", 0); glBindTexture(GL_TEXTURE_2D, textures[3]); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glfwLoadTexture2D("data/explosion/point.tga", GLFW_ALPHA_MAP_BIT); glBindTexture(GL_TEXTURE_2D, textures[4]); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glfwLoadTexture2D("data/explosion/wave.tga", 0); explosion.initialize(textures[0], textures[1], textures[2], textures[3], textures[4]); } void Client::accelerate(double x, double y, double z) { if (game.local_player == 0) return; player_accelerate_message_t msg; msg.player_id = game.local_player->id; msg.x = x; msg.y = y; msg.z = z; YAML::Emitter m; m << msg; network.send(m); } void Client::drop_bomb(double rx, double ry, double rz, double ttl) { bomb_drop_meesage_t msg; btVector3 p = game.local_player->body->getWorldTransform().getOrigin(); btVector3 v = game.local_player->body->getLinearVelocity(); msg.x = p.x() + rx * 1; msg.y = p.y() + ry * 1; msg.z = p.z() + rz * 1; msg.vx = v.x() + rx * 500; msg.vy = v.y() + ry * 500; msg.vz = v.z() + rz * 500; msg.ttl = ttl; YAML::Emitter m; m << msg; network.send(m); } void Client::loadConsoleFont() { GLuint font_id = 0; glGenTextures(1, &font_id); glBindTexture(GL_TEXTURE_2D, font_id); // Set texture parameters glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); // Upload texture from file to texture memory glfwLoadTexture2D("data/fonts/console.tga", 0); oglf_load(&font, "data/fonts/console.fnt", font_id); } void Client::initialize(Config &config) { Application::initialize(config); window.initialize(config); renderer.initialize(&window, config); loadConsoleFont(); //setup_explosion(); if (isMaster()) { Team *team = game.getTeam(0); game.local_player = game.spawnPlayer(team); std::cout << "[Game] local player " << game.local_player->id << std::endl; } size_t i; last_bomb = time - 5.; glfwGetMousePos(&last_x, &last_y); accelerate_schudule.setExact(true); accelerate_schudule.setInterval(0.05); theta = 0.0; phi = 0.0; loadConsoleFont(); // setup signals game.ExplosionSignal.connect(this, &Client::onExplosion); renderer.create("level"); } void Client::processInput(double step) { if (!game.local_player) return; btRigidBody *body = game.local_player->body.get(); if (!body) return; btMatrix3x3 &basis = body->getWorldTransform().getBasis(); btVector3 front = basis * btVector3(0, 0, -10) * step; btVector3 right = basis * btVector3(10, 0, 0) * step; btVector3 up = basis * btVector3(0, 10, 0) * step; float accelSpeed = 200 / body->getInvMass(); btVector3 accel(0, 0, 0); if (glfwGetKey('W') == GLFW_PRESS) { accel += accelSpeed * front; } if (glfwGetKey('A') == GLFW_PRESS) { accel += -accelSpeed * right; } if (glfwGetKey('S') == GLFW_PRESS) { accel += -accelSpeed * front; } if (glfwGetKey('D') == GLFW_PRESS) { accel += accelSpeed * right; } if (glfwGetKey('R') == GLFW_PRESS) { accel += accelSpeed * up; } if (glfwGetKey('F') == GLFW_PRESS) { accel += -accelSpeed * up; } accel *= step; accelerate(accel.x(), accel.y(), accel.z()); #if 0 float rotationSpeed = 1000 / body->getInvMass(); float lx = (mouseX - 0.5) * 2; float ly = (mouseY - 0.5) * 2; btVector3 desiredLocalAngualarVelocity = btVector3(0, -2 * lx, 0) + btVector3(-2 * ly, 0, 0); btVector3 desiredAngualarVelocity = body->getWorldTransform().getBasis() * desiredLocalAngualarVelocity; btVector3 angularVelocity = body->getAngularVelocity(); btVector3 a = desiredAngualarVelocity - angularVelocity; float turningAngle = a.length(); a *= fabs(turningAngle); Steering *s = 0; if (entity->getComponent(s)) s->setAngularForce(a); //} if (turningAngle > 0.001) { activate = true; jetStrength += std::min(0.2f, turningAngle * turningAngle * 10); } if (glfwGetKey(GLFW_KEY_LEFT) == GLFW_PRESS) { body->applyForce(-rotationSpeed * right, front); body->applyForce(rotationSpeed * right, -front); activate = true; } if (glfwGetKey(GLFW_KEY_RIGHT) == GLFW_PRESS) { body->applyForce(rotationSpeed * right, front); body->applyForce(-rotationSpeed * right, -front); activate = true; } if (glfwGetKey(GLFW_KEY_UP) == GLFW_PRESS) { body->applyForce(-rotationSpeed * up, front); body->applyForce(rotationSpeed * up, -front); activate = true; } if (glfwGetKey(GLFW_KEY_DOWN) == GLFW_PRESS) { body->applyForce(rotationSpeed * up, front); body->applyForce(-rotationSpeed * up, -front); activate = true; } // roll if (glfwGetKey('Q') == GLFW_PRESS) { body->applyForce(rotationSpeed * up, right); body->applyForce(-rotationSpeed * up, -right); jetStrength += 0.1; activate = true; } if (glfwGetKey('E') == GLFW_PRESS) { body->applyForce(-rotationSpeed * up, right); body->applyForce(rotationSpeed * up, -right); jetStrength += 0.1; activate = true; } if (activate) { body->activate(); } if (jetStrength > 0) { jet->setVolume(jetStrength); if (!jet->isPlaying()) { jet->play2d(true); } } else { jet->stop(); } #endif } void Client::update() { Application::update(); window.update(); int x, y; glfwGetMousePos(&x, &y); if (glfwGetMouseButton(GLFW_MOUSE_BUTTON_2) == GLFW_PRESS) { phi += (x - last_x) * 0.01; theta += (y - last_y) * -0.01; if (theta > 1.5) theta = 1.5; if (theta < -1.5) theta = -1.5; } last_x = x; last_y = y; double rx = cos(phi) * cos(theta); double ry = sin(theta); double rz = sin(phi) * cos(theta); if (accelerate_schudule.next(time)) { double t = accelerate_schudule.getInterval(); processInput(t); } if (glfwGetKey(GLFW_KEY_LCTRL)) { if (time - last_bomb > 1.0) { last_bomb = time; drop_bomb(rx, ry, rz, 5.0); } } btScalar bullet_trafo[16]; if (game.local_player) { game.local_player->body->getWorldTransform().getOpenGLMatrix( bullet_trafo); // bullet_trafo[12] -= origin.x(); // bullet_trafo[13] -= origin.y(); // bullet_trafo[14] -= origin.z(); } else { bullet_trafo[12] = 1000.0; bullet_trafo[13] = 1000.0; bullet_trafo[14] = 1000.0; } float trafo[16]; for (size_t i = 0; i < 16; i++) trafo[i] = bullet_trafo[i]; h3dSetNodeTransMat(renderer.getCameraNode(), trafo); // h3dSetNodeTransform(renderer.getCameraNode(), camX, camY, camZ, // -theta * 180 / M_PI - 90, phi * 180 / M_PI, 0, 1, 1, 1); // H3DNode cam = renderer.getCameraNode(); renderer.draw(); #if 0 prepareFrame(rx, ry, rz); setup_light(); glEnable(GL_LIGHT0); glEnable(GL_LIGHTING); glEnable(GL_CULL_FACE); glDisable(GL_TEXTURE_2D); // for (size_t i = 0; i < game.teams.size(); i++) // draw_team(&game.teams[i]); for (size_t i = 0; i < GAME_PLAYER_COUNT; i++) drawPlayer(&game.player[i]); for (size_t i = 0; i < GAME_BOMB_COUNT; i++) draw_bomb(&game.bomb[i]); // // for (size_t i = 0; i < GAME_POINT_COUNT; i++) // draw_point(&game.point[i]); drawLevel(); explosion.update(dt * 1000.0, camX, camY, camZ); explosion.render(); #endif glDisable(GL_LIGHT0); glDisable(GL_LIGHTING); glDisable(GL_CULL_FACE); oglf_begin(&font, width, height); size_t fy = 1; if (game.local_player) { std::stringstream sstr; sstr << "Points: " << game.local_player->points; oglf_print(&font, 10, 25 * fy++, sstr.str().c_str()); } for (size_t i = 0; i < game.teams.size(); i++) { std::stringstream sstr; if (game.local_player && &game.teams[i] == game.local_player->team) { sstr << "Team " << i << " (yours) : " << game.teams[i].points; } else { sstr << "Team " << i << " (other) : " << game.teams[i].points; } oglf_print(&font, 10, 25 * fy++, sstr.str().c_str()); } { std::stringstream sstr; sstr << "FPS: " << (int) (1 / dt) << " Time: " << floor(dt * 10000.0 + 0.5) / 10.0; oglf_print(&font, 10, 25 * fy++, sstr.str().c_str()); } oglf_end(); // Swap buffers glfwSwapBuffers(); // Check if the ESC key was pressed or the window was closed if (glfwGetKey(GLFW_KEY_ESC)) stop(); if (glfwGetWindowParam(GLFW_OPENED) != GL_TRUE) stop(); } void Client::shutdown() { Application::shutdown(); oglf_destroy(&font); glfwTerminate(); } void Client::onExplosion(double x, double y, double z) { explosion.add(x, y, z); } } // namespace grln