2013-07-01 02:22:29 +02:00
|
|
|
#define GLEW_STATIC
|
|
|
|
#include <GL/glew.h>
|
|
|
|
|
2013-12-20 17:02:46 +01:00
|
|
|
#include <engine/GameWorld.hpp>
|
2013-12-20 15:03:32 +01:00
|
|
|
#include <loaders/LoaderDFF.hpp>
|
|
|
|
#include <render/DebugDraw.hpp>
|
2013-12-20 16:45:41 +01:00
|
|
|
#include <render/Model.hpp>
|
2013-12-20 15:03:32 +01:00
|
|
|
#include <objects/GTACharacter.hpp>
|
|
|
|
#include <objects/GTAVehicle.hpp>
|
2013-07-01 02:22:29 +02:00
|
|
|
|
|
|
|
#include <glm/glm.hpp>
|
|
|
|
#include <glm/gtc/matrix_transform.hpp>
|
|
|
|
#include <glm/gtc/type_ptr.hpp>
|
|
|
|
|
2014-05-26 06:34:49 +02:00
|
|
|
#include "menustate.hpp"
|
2013-07-01 02:22:29 +02:00
|
|
|
#include <SFML/Graphics.hpp>
|
|
|
|
|
2013-07-01 05:40:11 +02:00
|
|
|
#include <memory>
|
2013-07-02 12:48:01 +02:00
|
|
|
#include <sstream>
|
2013-12-27 23:57:11 +01:00
|
|
|
#include <iomanip>
|
2013-07-04 01:35:03 +02:00
|
|
|
#include <getopt.h>
|
2014-05-26 06:34:49 +02:00
|
|
|
#include "game.hpp"
|
2013-07-01 05:40:11 +02:00
|
|
|
|
2014-05-25 23:47:10 +02:00
|
|
|
#define ENV_GAME_PATH_NAME ("OPENRW_GAME_PATH")
|
|
|
|
|
2013-07-01 02:22:29 +02:00
|
|
|
constexpr int WIDTH = 800,
|
|
|
|
HEIGHT = 600;
|
|
|
|
|
2013-07-05 20:50:04 +02:00
|
|
|
sf::RenderWindow window;
|
2013-07-01 02:22:29 +02:00
|
|
|
|
2013-12-20 17:02:46 +01:00
|
|
|
GameWorld* gta = nullptr;
|
2014-05-31 09:18:50 +02:00
|
|
|
GTACharacter* player = nullptr;
|
2013-07-01 05:40:11 +02:00
|
|
|
|
2013-07-22 03:38:43 +02:00
|
|
|
DebugDraw* debugDrawer = nullptr;
|
|
|
|
|
2013-07-04 11:56:23 +02:00
|
|
|
bool inFocus = false;
|
2013-07-30 17:59:44 +02:00
|
|
|
int debugMode = 0;
|
2013-07-02 00:16:02 +02:00
|
|
|
|
2013-07-05 20:50:04 +02:00
|
|
|
sf::Font font;
|
|
|
|
|
2013-12-27 00:18:55 +01:00
|
|
|
bool showControls = false;
|
2013-09-27 17:49:10 +02:00
|
|
|
|
2014-05-26 06:34:49 +02:00
|
|
|
glm::vec3 viewPosition;
|
|
|
|
glm::vec2 viewAngles;
|
|
|
|
|
|
|
|
void setViewParameters(const glm::vec3 ¢er, const glm::vec2 &angles)
|
|
|
|
{
|
|
|
|
viewPosition = center;
|
|
|
|
viewAngles = angles;
|
|
|
|
}
|
|
|
|
|
|
|
|
sf::Window& getWindow()
|
|
|
|
{
|
|
|
|
return window;
|
|
|
|
}
|
|
|
|
|
|
|
|
GameWorld* getWorld()
|
|
|
|
{
|
|
|
|
return gta;
|
|
|
|
}
|
|
|
|
|
|
|
|
sf::Font& getFont()
|
|
|
|
{
|
|
|
|
return font;
|
|
|
|
}
|
|
|
|
|
2014-05-31 09:18:50 +02:00
|
|
|
void setPlayerCharacter(GTACharacter *playerCharacter)
|
|
|
|
{
|
|
|
|
player = playerCharacter;
|
|
|
|
}
|
|
|
|
|
|
|
|
GTACharacter* getPlayerCharacter()
|
|
|
|
{
|
|
|
|
return player;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool hitWorldRay(glm::vec3 &hit, glm::vec3 &normal, GameObject** object)
|
2013-12-05 13:45:20 +01:00
|
|
|
{
|
|
|
|
glm::mat4 view;
|
|
|
|
view = glm::rotate(view, -90.f, glm::vec3(1, 0, 0));
|
2014-05-26 06:34:49 +02:00
|
|
|
view = glm::rotate(view, viewAngles.y, glm::vec3(1, 0, 0));
|
|
|
|
view = glm::rotate(view, viewAngles.x, glm::vec3(0, 0, 1));
|
2013-12-05 13:45:20 +01:00
|
|
|
glm::vec3 dir = glm::inverse(glm::mat3(view)) * glm::vec3(0.f, 0.f, 1.f) * -50.f;
|
2014-05-26 06:34:49 +02:00
|
|
|
auto from = btVector3(viewPosition.x, viewPosition.y, viewPosition.z);
|
|
|
|
auto to = btVector3(viewPosition.x+dir.x, viewPosition.y+dir.y, viewPosition.z+dir.z);
|
2013-12-05 13:45:20 +01:00
|
|
|
btCollisionWorld::ClosestRayResultCallback ray(from, to);
|
|
|
|
gta->dynamicsWorld->rayTest(from, to, ray);
|
|
|
|
if( ray.hasHit() )
|
|
|
|
{
|
|
|
|
hit = glm::vec3(ray.m_hitPointWorld.x(), ray.m_hitPointWorld.y(),
|
|
|
|
ray.m_hitPointWorld.z());
|
|
|
|
normal = glm::vec3(ray.m_hitNormalWorld.x(), ray.m_hitNormalWorld.y(),
|
|
|
|
ray.m_hitNormalWorld.z());
|
2013-12-07 00:19:17 +01:00
|
|
|
if(object) {
|
2014-02-28 12:23:51 +01:00
|
|
|
*object = static_cast<GameObject*>(ray.m_collisionObject->getUserPointer());
|
2013-12-07 00:19:17 +01:00
|
|
|
}
|
2013-12-05 13:45:20 +01:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
2013-09-27 17:49:10 +02:00
|
|
|
|
2014-05-31 09:18:50 +02:00
|
|
|
bool hitWorldRay(const glm::vec3 &start, const glm::vec3 &direction, glm::vec3 &hit, glm::vec3 &normal, GameObject **object)
|
|
|
|
{
|
|
|
|
auto from = btVector3(start.x, start.y, start.z);
|
|
|
|
auto to = btVector3(start.x+direction.x, start.y+direction.y, start.z+direction.z);
|
|
|
|
btCollisionWorld::ClosestRayResultCallback ray(from, to);
|
|
|
|
gta->dynamicsWorld->rayTest(from, to, ray);
|
|
|
|
if( ray.hasHit() )
|
|
|
|
{
|
|
|
|
hit = glm::vec3(ray.m_hitPointWorld.x(), ray.m_hitPointWorld.y(),
|
|
|
|
ray.m_hitPointWorld.z());
|
|
|
|
normal = glm::vec3(ray.m_hitNormalWorld.x(), ray.m_hitNormalWorld.y(),
|
|
|
|
ray.m_hitNormalWorld.z());
|
|
|
|
if(object) {
|
|
|
|
*object = static_cast<GameObject*>(ray.m_collisionObject->getUserPointer());
|
|
|
|
}
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2013-12-13 15:30:45 +01:00
|
|
|
// Commands.
|
|
|
|
std::map<std::string, std::function<void (std::string)>> Commands = {
|
|
|
|
{"pedestrian-vehicle",
|
|
|
|
[&](std::string) {
|
|
|
|
glm::vec3 hit, normal;
|
|
|
|
if(hitWorldRay(hit, normal)) {
|
2014-05-26 06:34:49 +02:00
|
|
|
auto ped = gta->createPedestrian(2, hit+glm::vec3(0.f,10.f,0.f));
|
2013-12-13 15:30:45 +01:00
|
|
|
// Pick random vehicle.
|
|
|
|
auto it = gta->vehicleTypes.begin();
|
|
|
|
std::uniform_int_distribution<int> uniform(0, 9);
|
|
|
|
for(size_t i = 0, n = uniform(gta->randomEngine); i != n; i++) {
|
|
|
|
it++;
|
|
|
|
}
|
|
|
|
auto spawnpos = hit + normal;
|
2014-05-26 06:34:49 +02:00
|
|
|
auto vehicle = gta->createVehicle(it->first, spawnpos, glm::quat(glm::vec3(0.f, 0.f, -viewAngles.x * PiOver180)));
|
2013-12-13 15:30:45 +01:00
|
|
|
ped->enterVehicle(vehicle, 0);
|
2013-12-05 13:45:20 +01:00
|
|
|
}
|
2013-09-27 17:49:10 +02:00
|
|
|
}
|
2013-12-13 15:30:45 +01:00
|
|
|
},
|
|
|
|
{"vehicle-test",
|
|
|
|
[&](std::string) {
|
|
|
|
glm::vec3 hit, normal;
|
|
|
|
if(hitWorldRay(hit, normal)) {
|
|
|
|
glm::vec3 spawnPos = hit + glm::vec3(-5, 0.f, 0.0) + normal;
|
|
|
|
size_t k = 1;
|
2014-02-28 12:23:51 +01:00
|
|
|
for(std::map<uint16_t, std::shared_ptr<VehicleData>>::iterator it = gta->vehicleTypes.begin();
|
2013-12-13 15:30:45 +01:00
|
|
|
it != gta->vehicleTypes.end(); ++it) {
|
|
|
|
if(it->first == 140) continue; // get this plane out of here.
|
|
|
|
gta->createVehicle(it->first, spawnPos);
|
|
|
|
spawnPos += glm::vec3(5, 0, 0);
|
|
|
|
if((k++ % 4) == 0) { spawnPos += glm::vec3(-20, -15, 0); }
|
|
|
|
}
|
2013-12-05 14:46:40 +01:00
|
|
|
}
|
|
|
|
}
|
2013-12-13 15:30:45 +01:00
|
|
|
},
|
|
|
|
{"pedestrian-test",
|
|
|
|
[&](std::string) {
|
|
|
|
glm::vec3 hit, normal;
|
|
|
|
if(hitWorldRay(hit, normal)) {
|
|
|
|
glm::vec3 spawnPos = hit + glm::vec3(-5, 0.f, 0.0) + normal;
|
|
|
|
size_t k = 1;
|
|
|
|
// Spawn every pedestrian.
|
|
|
|
for(auto it = gta->pedestrianTypes.begin();
|
|
|
|
it != gta->pedestrianTypes.end(); ++it) {
|
|
|
|
gta->createPedestrian(it->first, spawnPos);
|
|
|
|
spawnPos += glm::vec3(2.5, 0, 0);
|
|
|
|
if((k++ % 6) == 0) { spawnPos += glm::vec3(-15, -2.5, 0); }
|
|
|
|
}
|
|
|
|
}
|
2013-09-30 00:12:03 +02:00
|
|
|
}
|
2013-12-13 15:30:45 +01:00
|
|
|
},
|
|
|
|
{"list-ipl",
|
|
|
|
[&](std::string) {
|
|
|
|
for(std::map<std::string, std::string>::iterator it = gta->gameData.iplLocations.begin();
|
|
|
|
it != gta->gameData.iplLocations.end();
|
|
|
|
++it) {
|
|
|
|
gta->logInfo(it->second);
|
2013-09-30 00:12:03 +02:00
|
|
|
}
|
2013-12-13 15:30:45 +01:00
|
|
|
}
|
|
|
|
},
|
|
|
|
{"load-ipl",
|
|
|
|
[&](std::string line) {
|
|
|
|
if(line.find(' ') != line.npos) {
|
|
|
|
std::string ipl = line.substr(line.find(' ')+1);
|
|
|
|
auto iplit = gta->gameData.iplLocations.find(ipl);
|
|
|
|
if(iplit != gta->gameData.iplLocations.end()) {
|
|
|
|
gta->logInfo("Loading: " + iplit->second);
|
|
|
|
gta->loadZone(iplit->second);
|
|
|
|
gta->placeItems(iplit->second);
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
gta->logInfo("Not found: " + ipl);
|
|
|
|
}
|
2013-09-30 00:12:03 +02:00
|
|
|
}
|
|
|
|
}
|
2013-12-13 15:30:45 +01:00
|
|
|
},
|
|
|
|
/*{"",
|
|
|
|
[&](std::string) {
|
|
|
|
|
2013-12-12 16:36:50 +01:00
|
|
|
}
|
2013-12-13 15:30:45 +01:00
|
|
|
}*/
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void command(const std::string& line)
|
|
|
|
{
|
|
|
|
std::string cmd;
|
|
|
|
if(line.find(' ') != line.npos) {
|
|
|
|
cmd = line.substr(0, line.find(' '));
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
cmd = line;
|
|
|
|
}
|
|
|
|
|
|
|
|
auto it = Commands.find(cmd);
|
|
|
|
if(it != Commands.end()) {
|
|
|
|
it->second(line);
|
2013-12-12 16:36:50 +01:00
|
|
|
}
|
2013-09-27 17:49:10 +02:00
|
|
|
else {
|
|
|
|
gta->logInfo("Unkown command: " + cmd);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void handleGlobalEvent(sf::Event &event)
|
2013-07-01 02:22:29 +02:00
|
|
|
{
|
|
|
|
switch (event.type) {
|
|
|
|
case sf::Event::KeyPressed:
|
2013-09-27 17:49:10 +02:00
|
|
|
break;
|
|
|
|
case sf::Event::GainedFocus:
|
|
|
|
inFocus = true;
|
|
|
|
break;
|
|
|
|
case sf::Event::LostFocus:
|
|
|
|
inFocus = false;
|
|
|
|
break;
|
|
|
|
default: break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void handleInputEvent(sf::Event &event)
|
|
|
|
{
|
|
|
|
switch(event.type) {
|
|
|
|
case sf::Event::KeyPressed:
|
|
|
|
switch (event.key.code) {
|
2013-07-21 06:12:27 +02:00
|
|
|
case sf::Keyboard::P:
|
2013-10-02 14:49:45 +02:00
|
|
|
debugMode+=1;
|
2013-07-30 17:59:44 +02:00
|
|
|
while(debugMode > 2) debugMode -= 3;
|
2013-07-21 06:12:27 +02:00
|
|
|
break;
|
2013-10-02 14:49:45 +02:00
|
|
|
default: break;
|
2013-07-01 02:22:29 +02:00
|
|
|
}
|
|
|
|
break;
|
2013-07-02 18:29:20 +02:00
|
|
|
case sf::Event::KeyReleased:
|
|
|
|
switch(event.key.code) {
|
2013-10-02 14:49:45 +02:00
|
|
|
default: break;
|
2013-07-02 18:29:20 +02:00
|
|
|
}
|
|
|
|
break;
|
2013-10-02 14:49:45 +02:00
|
|
|
default: break;
|
2013-09-27 17:49:10 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void handleCommandEvent(sf::Event &event)
|
|
|
|
{
|
|
|
|
switch(event.type) {
|
|
|
|
case sf::Event::KeyPressed:
|
2013-12-05 13:45:20 +01:00
|
|
|
switch (event.key.code) {
|
|
|
|
case sf::Keyboard::F1:
|
|
|
|
showControls = !showControls;
|
2013-09-27 17:49:10 +02:00
|
|
|
break;
|
2013-12-05 13:45:20 +01:00
|
|
|
case sf::Keyboard::F2:
|
|
|
|
command("pedestrian-vehicle");
|
2013-09-27 17:49:10 +02:00
|
|
|
break;
|
2013-12-05 13:45:20 +01:00
|
|
|
case sf::Keyboard::F3:
|
|
|
|
command("player-vehicle");
|
|
|
|
break;
|
2013-12-13 19:19:03 +01:00
|
|
|
case sf::Keyboard::F4:
|
|
|
|
command("empty-vehicle");
|
|
|
|
break;
|
2013-12-05 14:46:40 +01:00
|
|
|
case sf::Keyboard::F6:
|
|
|
|
command("vehicle-test");
|
|
|
|
break;
|
|
|
|
case sf::Keyboard::F7:
|
|
|
|
command("pedestrian-test");
|
|
|
|
break;
|
2013-12-12 16:36:50 +01:00
|
|
|
case sf::Keyboard::F8:
|
|
|
|
command("damage-object");
|
|
|
|
break;
|
2013-12-07 00:19:17 +01:00
|
|
|
case sf::Keyboard::F9:
|
|
|
|
command("object-info");
|
|
|
|
break;
|
2013-12-28 01:51:15 +01:00
|
|
|
case sf::Keyboard::LBracket:
|
|
|
|
gta->gameTime -= 60.f;
|
|
|
|
break;
|
|
|
|
case sf::Keyboard::RBracket:
|
|
|
|
gta->gameTime += 60.f;
|
|
|
|
break;
|
2013-12-05 13:45:20 +01:00
|
|
|
break;
|
2013-12-27 00:18:55 +01:00
|
|
|
default: break;
|
2013-12-05 14:46:40 +01:00
|
|
|
}
|
2013-12-27 00:18:55 +01:00
|
|
|
default: break;
|
2013-07-01 02:22:29 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-09-30 00:12:03 +02:00
|
|
|
void init(std::string gtapath, bool loadWorld)
|
2013-07-01 02:22:29 +02:00
|
|
|
{
|
2013-07-02 08:06:03 +02:00
|
|
|
// GTA GET
|
2013-12-20 17:02:46 +01:00
|
|
|
gta = new GameWorld(gtapath);
|
2013-07-02 08:06:03 +02:00
|
|
|
|
|
|
|
// This is harcoded in GTA III for some reason
|
|
|
|
gta->gameData.loadIMG("/models/gta3");
|
|
|
|
|
|
|
|
gta->load();
|
|
|
|
|
2014-01-03 21:37:21 +01:00
|
|
|
// Load dynamic object data
|
|
|
|
gta->gameData.loadDynamicObjects(gtapath + "/data/object.dat");
|
|
|
|
|
2013-12-27 23:57:11 +01:00
|
|
|
// Set time to noon.
|
|
|
|
gta->gameTime = 12.f * 60.f;
|
|
|
|
|
2013-09-30 00:12:03 +02:00
|
|
|
// Loade all of the IDEs.
|
|
|
|
for(std::map<std::string, std::string>::iterator it = gta->gameData.ideLocations.begin();
|
|
|
|
it != gta->gameData.ideLocations.end();
|
|
|
|
++it) {
|
|
|
|
gta->defineItems(it->second);
|
|
|
|
}
|
2013-07-02 08:06:03 +02:00
|
|
|
|
2013-09-30 00:12:03 +02:00
|
|
|
if(loadWorld) {
|
|
|
|
// Load IPLs
|
|
|
|
for(std::map<std::string, std::string>::iterator it = gta->gameData.iplLocations.begin();
|
|
|
|
it != gta->gameData.iplLocations.end();
|
|
|
|
++it) {
|
|
|
|
gta->loadZone(it->second);
|
|
|
|
gta->placeItems(it->second);
|
|
|
|
}
|
|
|
|
}
|
2013-07-02 19:37:19 +02:00
|
|
|
|
2013-07-22 03:38:43 +02:00
|
|
|
debugDrawer = new DebugDraw;
|
|
|
|
debugDrawer->setShaderProgram(gta->renderer.worldProgram);
|
|
|
|
debugDrawer->setDebugMode(btIDebugDraw::DBG_DrawWireframe);
|
|
|
|
gta->dynamicsWorld->setDebugDrawer(debugDrawer);
|
2013-09-11 13:10:42 +02:00
|
|
|
|
|
|
|
std::cout << "Loaded "
|
|
|
|
<< gta->gameData.models.size() << " models, "
|
2013-09-11 20:23:31 +02:00
|
|
|
<< gta->gameData.textures.size() << " textures" << std::endl;
|
2013-07-01 02:22:29 +02:00
|
|
|
}
|
|
|
|
|
2013-07-02 11:39:52 +02:00
|
|
|
void update(float dt)
|
2013-07-01 02:22:29 +02:00
|
|
|
{
|
2013-07-04 11:56:23 +02:00
|
|
|
if (inFocus) {
|
2014-05-25 23:47:10 +02:00
|
|
|
float qpi = glm::half_pi<float>();
|
|
|
|
|
2013-07-04 11:56:23 +02:00
|
|
|
glm::mat4 view;
|
2014-05-26 06:34:49 +02:00
|
|
|
view = glm::translate(view, viewPosition);
|
|
|
|
view = glm::rotate(view, viewAngles.x, glm::vec3(0, 0, 1));
|
|
|
|
view = glm::rotate(view, viewAngles.y - qpi, glm::vec3(1, 0, 0));
|
|
|
|
view = glm::inverse(view);
|
2013-07-05 03:15:29 +02:00
|
|
|
|
|
|
|
gta->gameTime += dt;
|
2013-07-02 00:16:02 +02:00
|
|
|
|
2014-05-26 06:34:49 +02:00
|
|
|
gta->renderer.camera.worldPos = viewPosition;
|
2013-07-04 11:56:23 +02:00
|
|
|
gta->renderer.camera.frustum.view = view;
|
2013-12-12 03:55:31 +01:00
|
|
|
|
|
|
|
// Update all objects.
|
2014-05-26 06:34:49 +02:00
|
|
|
for( size_t p = 0; p < gta->pedestrians.size(); ++p) {
|
2013-09-11 01:26:13 +02:00
|
|
|
gta->pedestrians[p]->tick(dt);
|
2014-05-26 06:34:49 +02:00
|
|
|
|
2013-12-12 16:36:50 +01:00
|
|
|
if(gta->pedestrians[p]->mHealth <= 0.f) {
|
2014-05-26 06:34:49 +02:00
|
|
|
gta->destroyObject(gta->pedestrians[p]);
|
|
|
|
p--;
|
2013-12-12 16:36:50 +01:00
|
|
|
}
|
2014-05-26 06:34:49 +02:00
|
|
|
}
|
2013-09-15 03:42:35 +02:00
|
|
|
for( size_t v = 0; v < gta->vehicleInstances.size(); ++v ) {
|
|
|
|
gta->vehicleInstances[v]->tick(dt);
|
2013-12-12 16:36:50 +01:00
|
|
|
if(gta->vehicleInstances[v]->mHealth <= 0.f) {
|
|
|
|
gta->destroyObject(gta->vehicleInstances[v]);
|
|
|
|
v--;
|
|
|
|
}
|
2013-09-15 03:42:35 +02:00
|
|
|
}
|
2013-12-12 03:55:31 +01:00
|
|
|
|
|
|
|
|
2013-09-15 03:42:35 +02:00
|
|
|
|
2013-10-02 02:27:48 +02:00
|
|
|
gta->dynamicsWorld->stepSimulation(dt, 2, dt);
|
2013-07-02 00:16:02 +02:00
|
|
|
}
|
2013-07-01 02:22:29 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
void render()
|
|
|
|
{
|
2013-07-02 10:09:40 +02:00
|
|
|
// Update aspect ratio..
|
|
|
|
gta->renderer.camera.frustum.aspectRatio = window.getSize().x / (float) window.getSize().y;
|
2013-07-02 10:58:01 +02:00
|
|
|
|
2013-07-06 02:39:54 +02:00
|
|
|
glEnable(GL_DEPTH_TEST);
|
2013-08-18 21:31:37 +02:00
|
|
|
glClear(GL_DEPTH_BUFFER_BIT|GL_COLOR_BUFFER_BIT);
|
2013-07-06 02:39:54 +02:00
|
|
|
//glEnable(GL_CULL_FACE);
|
2013-07-01 02:22:29 +02:00
|
|
|
|
2013-07-30 17:59:44 +02:00
|
|
|
switch( debugMode ) {
|
|
|
|
case 0:
|
2013-07-24 01:42:50 +02:00
|
|
|
gta->renderer.renderWorld();
|
2013-07-30 17:59:44 +02:00
|
|
|
break;
|
|
|
|
|
|
|
|
case 1: {
|
2013-09-19 00:16:26 +02:00
|
|
|
gta->renderer.renderWorld();
|
2013-07-30 17:59:44 +02:00
|
|
|
glUseProgram(gta->renderer.worldProgram);
|
|
|
|
glm::mat4 proj = gta->renderer.camera.frustum.projection();
|
|
|
|
glm::mat4 view = gta->renderer.camera.frustum.view;
|
|
|
|
glUniformMatrix4fv(gta->renderer.uniView, 1, GL_FALSE, glm::value_ptr(view));
|
|
|
|
glUniformMatrix4fv(gta->renderer.uniProj, 1, GL_FALSE, glm::value_ptr(proj));
|
|
|
|
gta->renderer.renderPaths();
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case 2: {
|
|
|
|
glUseProgram(gta->renderer.worldProgram);
|
|
|
|
glm::mat4 proj = gta->renderer.camera.frustum.projection();
|
|
|
|
glm::mat4 view = gta->renderer.camera.frustum.view;
|
|
|
|
glUniformMatrix4fv(gta->renderer.uniView, 1, GL_FALSE, glm::value_ptr(view));
|
|
|
|
glUniformMatrix4fv(gta->renderer.uniProj, 1, GL_FALSE, glm::value_ptr(proj));
|
|
|
|
gta->dynamicsWorld->debugDrawWorld();
|
|
|
|
debugDrawer->drawAllLines();
|
|
|
|
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-07-05 20:50:04 +02:00
|
|
|
window.resetGLStates();
|
2013-07-06 02:39:54 +02:00
|
|
|
|
2013-07-05 20:50:04 +02:00
|
|
|
std::stringstream ss;
|
2013-12-27 23:57:11 +01:00
|
|
|
ss << std::setfill('0') << "Time: " << std::setw(2) << gta->getHour()
|
|
|
|
<< ":" << std::setw(2) << gta->getMinute() << std::endl;
|
2013-12-05 13:45:20 +01:00
|
|
|
ss << "Game Time: " << gta->gameTime << std::endl;
|
2014-05-26 06:34:49 +02:00
|
|
|
ss << "Camera: " << viewPosition.x << " " << viewPosition.y << " " << viewPosition.z << std::endl;
|
2013-12-07 00:19:17 +01:00
|
|
|
|
2014-05-31 09:18:50 +02:00
|
|
|
|
2013-12-05 13:45:20 +01:00
|
|
|
if(showControls) {
|
|
|
|
ss << "F1 - Toggle Help" << std::endl;
|
|
|
|
ss << "F2 - Create Vehicle (with driver)" << std::endl;
|
|
|
|
ss << "F3 - Create Vehicle (with player)" << std::endl;
|
2013-12-13 19:19:03 +01:00
|
|
|
ss << "F4 - Create Vehicle (empty)" << std::endl;
|
2013-12-05 14:46:40 +01:00
|
|
|
ss << "F6 - Create all Vehicles" << std::endl;
|
|
|
|
ss << "F7 - Create all Pedestrians" << std::endl;
|
2013-12-07 00:19:17 +01:00
|
|
|
ss << "F9 - Display Object Information" << std::endl;
|
2013-09-27 17:49:10 +02:00
|
|
|
}
|
|
|
|
|
2013-12-07 00:19:17 +01:00
|
|
|
sf::Text text(ss.str(), font, 15);
|
|
|
|
text.setPosition(10, 10);
|
|
|
|
window.draw(text);
|
|
|
|
|
2013-07-06 02:39:54 +02:00
|
|
|
while( gta->log.size() > 0 && gta->log.front().time + 10.f < gta->gameTime ) {
|
|
|
|
gta->log.pop_front();
|
|
|
|
}
|
|
|
|
|
2013-12-27 00:26:45 +01:00
|
|
|
sf::Vector2f tpos(10.f, window.getSize().y - 30.f);
|
2013-07-06 02:39:54 +02:00
|
|
|
text.setCharacterSize(15);
|
|
|
|
for(auto it = gta->log.begin(); it != gta->log.end(); ++it) {
|
|
|
|
text.setString(it->message);
|
|
|
|
switch(it->type) {
|
2013-12-20 17:02:46 +01:00
|
|
|
case GameWorld::LogEntry::Error:
|
2013-07-06 02:39:54 +02:00
|
|
|
text.setColor(sf::Color::Red);
|
|
|
|
break;
|
2013-12-20 17:02:46 +01:00
|
|
|
case GameWorld::LogEntry::Warning:
|
2013-07-06 02:39:54 +02:00
|
|
|
text.setColor(sf::Color::Yellow);
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
text.setColor(sf::Color::White);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Interpolate the color
|
|
|
|
auto c = text.getColor();
|
|
|
|
c.a = (gta->gameTime - it->time > 5.f) ? 255 - (((gta->gameTime - it->time) - 5.f)/5.f) * 255 : 255;
|
|
|
|
text.setColor(c);
|
|
|
|
|
|
|
|
text.setPosition(tpos);
|
|
|
|
window.draw(text);
|
2013-12-27 00:26:45 +01:00
|
|
|
tpos.y -= text.getLocalBounds().height;
|
2013-07-06 02:39:54 +02:00
|
|
|
}
|
2013-07-05 20:50:04 +02:00
|
|
|
|
2013-07-02 10:58:01 +02:00
|
|
|
static size_t fc = 0;
|
|
|
|
if(fc++ == 60)
|
|
|
|
{
|
|
|
|
std::cout << "Rendered: " << gta->renderer.rendered << " / Culled: " << gta->renderer.culled << std::endl;
|
|
|
|
fc = 0;
|
|
|
|
}
|
2013-07-01 02:22:29 +02:00
|
|
|
}
|
|
|
|
|
2014-05-25 23:47:10 +02:00
|
|
|
std::string getGamePath()
|
|
|
|
{
|
|
|
|
auto v = getenv(ENV_GAME_PATH_NAME);
|
|
|
|
return v ? v : "";
|
|
|
|
}
|
|
|
|
|
2013-07-01 02:22:29 +02:00
|
|
|
int main(int argc, char *argv[])
|
|
|
|
{
|
2014-05-31 09:18:50 +02:00
|
|
|
if(! font.loadFromFile(getGamePath() + "/DejaVuSansMono.ttf")) {
|
2013-07-06 02:39:54 +02:00
|
|
|
std::cerr << "Failed to load font" << std::endl;
|
2013-07-05 20:50:04 +02:00
|
|
|
}
|
2013-07-01 05:40:11 +02:00
|
|
|
|
2013-07-01 02:22:29 +02:00
|
|
|
glewExperimental = GL_TRUE;
|
|
|
|
glewInit();
|
2013-09-30 00:12:03 +02:00
|
|
|
|
2014-05-25 23:47:10 +02:00
|
|
|
bool loadWorld = true;
|
2013-07-04 01:35:03 +02:00
|
|
|
size_t w = WIDTH, h = HEIGHT;
|
|
|
|
int c;
|
2013-09-30 00:12:03 +02:00
|
|
|
while( (c = getopt(argc, argv, "w:h:l")) != -1) {
|
2013-07-04 01:35:03 +02:00
|
|
|
switch(c) {
|
|
|
|
case 'w':
|
|
|
|
w = atoi(optarg);
|
|
|
|
break;
|
|
|
|
case 'h':
|
|
|
|
h = atoi(optarg);
|
|
|
|
break;
|
2013-09-30 00:12:03 +02:00
|
|
|
case 'l':
|
2014-05-25 23:47:10 +02:00
|
|
|
loadWorld = false;
|
2013-09-30 00:12:03 +02:00
|
|
|
break;
|
2013-07-04 01:35:03 +02:00
|
|
|
}
|
|
|
|
}
|
2013-07-01 02:22:29 +02:00
|
|
|
|
2013-08-18 21:31:37 +02:00
|
|
|
sf::ContextSettings cs;
|
|
|
|
cs.depthBits = 32;
|
2013-12-27 00:18:55 +01:00
|
|
|
window.create(sf::VideoMode(w, h), "", sf::Style::Default, cs);
|
2013-07-01 02:22:29 +02:00
|
|
|
window.setVerticalSyncEnabled(true);
|
2013-12-24 20:47:04 +01:00
|
|
|
window.setMouseCursorVisible(false);
|
2013-07-01 02:22:29 +02:00
|
|
|
|
2014-05-25 23:47:10 +02:00
|
|
|
init(getGamePath(), loadWorld);
|
2013-07-02 11:39:52 +02:00
|
|
|
|
|
|
|
sf::Clock clock;
|
2014-05-26 06:34:49 +02:00
|
|
|
|
|
|
|
MenuState* menuState = new MenuState();
|
2013-12-25 20:54:22 +01:00
|
|
|
|
2014-05-26 06:34:49 +02:00
|
|
|
StateManager::get().enter(menuState);
|
2013-12-25 20:54:22 +01:00
|
|
|
|
2013-08-15 18:53:11 +02:00
|
|
|
float accum = 0.f;
|
2013-10-02 02:27:48 +02:00
|
|
|
float ts = 1.f / 60.f;
|
2013-08-15 18:53:11 +02:00
|
|
|
|
2013-12-27 00:18:55 +01:00
|
|
|
// Loop until the window is closed or we run out of state.
|
|
|
|
while (window.isOpen() && StateManager::get().states.size()) {
|
2013-07-01 02:22:29 +02:00
|
|
|
sf::Event event;
|
|
|
|
while (window.pollEvent(event)) {
|
2013-09-27 17:49:10 +02:00
|
|
|
handleGlobalEvent(event);
|
2013-12-05 13:45:20 +01:00
|
|
|
handleCommandEvent(event);
|
|
|
|
handleInputEvent(event);
|
2013-12-25 20:54:22 +01:00
|
|
|
|
2013-12-27 00:18:55 +01:00
|
|
|
StateManager::get().states.back()->handleEvent(event);
|
2013-07-01 02:22:29 +02:00
|
|
|
}
|
2013-09-15 03:42:35 +02:00
|
|
|
|
2013-08-15 18:53:11 +02:00
|
|
|
accum += clock.restart().asSeconds();
|
|
|
|
|
|
|
|
while ( accum >= ts ) {
|
2014-05-26 06:34:49 +02:00
|
|
|
|
|
|
|
StateManager::get().tick(ts);
|
|
|
|
|
2013-08-15 18:53:11 +02:00
|
|
|
update(ts);
|
|
|
|
accum -= ts;
|
|
|
|
}
|
2013-07-02 11:39:52 +02:00
|
|
|
|
2013-07-01 02:22:29 +02:00
|
|
|
render();
|
2013-12-27 00:18:55 +01:00
|
|
|
|
|
|
|
StateManager::get().draw(window);
|
|
|
|
|
2013-07-01 02:22:29 +02:00
|
|
|
window.display();
|
2013-08-15 18:53:11 +02:00
|
|
|
|
2013-07-01 02:22:29 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|