1
0
mirror of https://github.com/rwengine/openrw.git synced 2024-09-15 15:02:34 +02:00

Move GameState out of GameWorld ownership

This commit is contained in:
Daniel Evans 2015-04-27 03:55:18 +01:00
parent 1daa5a6fb2
commit 85b1ab120f
21 changed files with 175 additions and 142 deletions

View File

@ -74,12 +74,10 @@ class WorkContext
std::mutex _inMutex; std::mutex _inMutex;
std::mutex _outMutex; std::mutex _outMutex;
GameWorld* _world;
public: public:
WorkContext(GameWorld* world = nullptr) WorkContext()
: _worker(this), _world(world) { } : _worker(this) { }
void queueJob( WorkJob* job ) void queueJob( WorkJob* job )
{ {
@ -100,8 +98,6 @@ public:
return (getWorkQueue().size() + getCompleteQueue().size()) == 0; return (getWorkQueue().size() + getCompleteQueue().size()) == 0;
} }
GameWorld* getWorld() const { return _world; }
void update(); void update();
}; };

View File

@ -44,14 +44,14 @@ private:
std::string splash; std::string splash;
Logger* logger; Logger* logger;
WorkContext* workContext;
public: public:
/** /**
* ctor * ctor
* @param path Path to the root of the game data. * @param path Path to the root of the game data.
*/ */
GameData(Logger* log, const std::string& path = ""); GameData(Logger* log, WorkContext* work, const std::string& path = "");
~GameData(); ~GameData();
GameWorld* engine; GameWorld* engine;

View File

@ -94,6 +94,9 @@ struct BlipData
{ } { }
}; };
/**
* Global Gameplay data, that mostly persists across game saves.
*/
struct GameState struct GameState
{ {
unsigned int currentProgress; unsigned int currentProgress;
@ -166,34 +169,8 @@ struct GameState
std::map<int, BlipData> radarBlips; std::map<int, BlipData> radarBlips;
GameState() : GameState();
currentProgress(0),
maxProgress(1),
numMissions(0),
numHiddenPackages(0),
numHiddenPackagesDiscovered(0),
numUniqueJumps(0),
numRampages(0),
maxWantedLevel(0),
player(nullptr),
currentWeather(0),
scriptOnMissionFlag(nullptr),
fadeOut(true),
fadeStart(0.f),
fadeTime(0.f),
fadeSound(false),
skipCutscene(false),
isIntroPlaying(false),
currentCutscene(nullptr),
cutsceneStartTime(-1.f),
isCinematic(false),
hour(0),
minute(0),
cameraNear(0.1f),
cameraFixed(false),
cameraTarget(nullptr)
{}
/** /**
* Adds a blip to the state, returning it's ID. * Adds a blip to the state, returning it's ID.
*/ */

View File

@ -61,7 +61,7 @@ class GameWorld
{ {
public: public:
GameWorld(Logger* log, GameData* dat); GameWorld(Logger* log, WorkContext* work, GameData* dat);
~GameWorld(); ~GameWorld();

View File

@ -43,9 +43,9 @@ class Renderer;
*/ */
class GameRenderer class GameRenderer
{ {
/** Pointer to the world instance */ /** Game data to use for rendering */
GameWorld* engine; GameData* data;
/** Logger to output messages */ /** Logger to output messages */
Logger* logger; Logger* logger;
@ -76,7 +76,9 @@ class GameRenderer
/** Transparent objects are queued into this list */ /** Transparent objects are queued into this list */
std::vector<RQueueEntry> transparentDrawQueue; std::vector<RQueueEntry> transparentDrawQueue;
// Temporary variables used during rendering
float _renderAlpha; float _renderAlpha;
GameWorld* _renderWorld;
/** Internal non-descript VAOs */ /** Internal non-descript VAOs */
GLuint vao, debugVAO; GLuint vao, debugVAO;
@ -91,7 +93,7 @@ class GameRenderer
public: public:
GameRenderer(Logger* log, GameWorld*); GameRenderer(Logger* log, GameData* data);
~GameRenderer(); ~GameRenderer();
/** Number of culling events */ /** Number of culling events */
@ -113,7 +115,9 @@ public:
DrawBuffer cylinderBuffer; DrawBuffer cylinderBuffer;
GeometryBuffer cylinderGeometry; GeometryBuffer cylinderGeometry;
GameData* getData() const { return data; }
/** /**
* Renders the world using the parameters of the passed Camera. * Renders the world using the parameters of the passed Camera.
* Note: The camera's near and far planes are overriden by weather effects. * Note: The camera's near and far planes are overriden by weather effects.
@ -123,7 +127,7 @@ public:
* - draws water surfaces * - draws water surfaces
* - draws the skybox * - draws the skybox
*/ */
void renderWorld(const ViewCamera &camera, float alpha); void renderWorld(GameWorld* world, const ViewCamera &camera, float alpha);
/** /**
* @brief draws a CharacterObject and any item they are holding. * @brief draws a CharacterObject and any item they are holding.
@ -160,7 +164,7 @@ public:
/** /**
* Renders the effects (Particles, Lighttrails etc) * Renders the effects (Particles, Lighttrails etc)
*/ */
void renderEffects(); void renderEffects(GameWorld* world);
/** /**
* @brief Draws the current on screen text. * @brief Draws the current on screen text.

View File

@ -1,6 +1,7 @@
#pragma once #pragma once
#include <render/OpenGLRenderer.hpp> #include <render/OpenGLRenderer.hpp>
class GameData;
class GameWorld; class GameWorld;
#define MAP_BLOCK_SIZE 63 #define MAP_BLOCK_SIZE 63
@ -26,15 +27,15 @@ public:
glm::vec2 mapScreenTop; glm::vec2 mapScreenTop;
}; };
MapRenderer(GameWorld* world, Renderer* renderer); MapRenderer(Renderer* renderer, GameData* data);
glm::vec2 worldToMap(const glm::vec2& coord); glm::vec2 worldToMap(const glm::vec2& coord);
glm::vec2 mapToScreen(const glm::vec2& map, const MapInfo& mi); glm::vec2 mapToScreen(const glm::vec2& map, const MapInfo& mi);
void draw(const MapInfo& mi); void draw(GameWorld* world, const MapInfo& mi);
private: private:
GameWorld* world; GameData* data;
Renderer* renderer; Renderer* renderer;
GeometryBuffer rectGeom; GeometryBuffer rectGeom;

View File

@ -5,7 +5,6 @@
#define GAME_FONTS 3 #define GAME_FONTS 3
#define GAME_GLYPHS 192 #define GAME_GLYPHS 192
class GameWorld;
class GameRenderer; class GameRenderer;
/** /**
* @brief Handles rendering of bitmap font textures. * @brief Handles rendering of bitmap font textures.
@ -53,7 +52,7 @@ public:
float widthFrac; float widthFrac;
}; };
TextRenderer(GameWorld* engine, GameRenderer* renderer); TextRenderer(GameRenderer* renderer);
~TextRenderer(); ~TextRenderer();
void setFontTexture( int index, const std::string& font ); void setFontTexture( int index, const std::string& font );
@ -63,8 +62,7 @@ public:
private: private:
std::string fonts[GAME_FONTS]; std::string fonts[GAME_FONTS];
GlyphInfo glyphData[GAME_GLYPHS]; GlyphInfo glyphData[GAME_GLYPHS];
GameWorld* engine;
GameRenderer* renderer; GameRenderer* renderer;
Renderer::ShaderProgram* textShader; Renderer::ShaderProgram* textShader;

View File

@ -80,8 +80,8 @@ std::string fixPath(std::string path) {
} }
GameData::GameData(Logger* log, const std::string& path) GameData::GameData(Logger* log, WorkContext* work, const std::string& path)
: datpath(path), logger(log), engine(nullptr) : datpath(path), logger(log), workContext(work), engine(nullptr)
{ {
} }
@ -421,10 +421,10 @@ void GameData::loadTXD(const std::string& name, bool async)
loadedFiles[name] = true; loadedFiles[name] = true;
auto j = new LoadTextureArchiveJob(this->engine->_work, this, name); auto j = new LoadTextureArchiveJob(workContext, this, name);
if( async ) { if( async ) {
this->engine->_work->queueJob( j ); workContext->queueJob( j );
} }
else { else {
j->work(); j->work();
@ -446,10 +446,10 @@ void GameData::loadDFF(const std::string& name, bool async)
models[realname] = ModelRef( new ResourceHandle<Model>(realname) ); models[realname] = ModelRef( new ResourceHandle<Model>(realname) );
auto job = new BackgroundLoaderJob<Model, LoaderDFF> auto job = new BackgroundLoaderJob<Model, LoaderDFF>
{ this->engine->_work, &this->index, name, models[realname] }; { workContext, &this->index, name, models[realname] };
if( async ) { if( async ) {
this->engine->_work->queueJob( job ); workContext->queueJob( job );
} }
else { else {
job->work(); job->work();

View File

@ -1,5 +1,35 @@
#include <engine/GameState.hpp> #include <engine/GameState.hpp>
GameState::GameState() :
currentProgress(0),
maxProgress(1),
numMissions(0),
numHiddenPackages(0),
numHiddenPackagesDiscovered(0),
numUniqueJumps(0),
numRampages(0),
maxWantedLevel(0),
player(nullptr),
currentWeather(0),
scriptOnMissionFlag(nullptr),
fadeOut(true),
fadeStart(0.f),
fadeTime(0.f),
fadeSound(false),
skipCutscene(false),
isIntroPlaying(false),
currentCutscene(nullptr),
cutsceneStartTime(-1.f),
isCinematic(false),
hour(0),
minute(0),
cameraNear(0.1f),
cameraFixed(false),
cameraTarget(nullptr)
{
}
int GameState::addRadarBlip(BlipData& blip) int GameState::addRadarBlip(BlipData& blip)
{ {
int l = 0; int l = 0;

View File

@ -74,9 +74,9 @@ public:
} }
}; };
GameWorld::GameWorld(Logger* log, GameData* dat) GameWorld::GameWorld(Logger* log, WorkContext* work, GameData* dat)
: logger(log), gameTime(0.f), data(dat), randomEngine(rand()), : logger(log), gameTime(0.f), data(dat), randomEngine(rand()),
_work( new WorkContext( this ) ), cutsceneAudio(nullptr), missionAudio(nullptr), _work( work ), cutsceneAudio(nullptr), missionAudio(nullptr),
paused(false) paused(false)
{ {
data->engine = this; data->engine = this;
@ -94,8 +94,6 @@ GameWorld::GameWorld(Logger* log, GameData* dat)
GameWorld::~GameWorld() GameWorld::~GameWorld()
{ {
delete _work;
for(auto o : objects) { for(auto o : objects) {
delete o; delete o;
} }

View File

@ -66,9 +66,9 @@ std::vector<VertexP2> sspaceRect = {
GeometryBuffer ssRectGeom; GeometryBuffer ssRectGeom;
DrawBuffer ssRectDraw; DrawBuffer ssRectDraw;
GameRenderer::GameRenderer(Logger* log, GameWorld* engine) GameRenderer::GameRenderer(Logger* log, GameData* _data)
: engine(engine), logger(log), renderer(new OpenGLRenderer), _renderAlpha(0.f), : data(_data), logger(log), renderer(new OpenGLRenderer), _renderAlpha(0.f),
map(engine, renderer), water(this), text(engine, this) _renderWorld(nullptr), map(renderer, _data), water(this), text(this)
{ {
logger->info("Renderer", renderer->getIDString()); logger->info("Renderer", renderer->getIDString());
@ -235,9 +235,10 @@ void GameRenderer::setupRender()
glClear(GL_DEPTH_BUFFER_BIT|GL_COLOR_BUFFER_BIT); glClear(GL_DEPTH_BUFFER_BIT|GL_COLOR_BUFFER_BIT);
} }
void GameRenderer::renderWorld(const ViewCamera &camera, float alpha) void GameRenderer::renderWorld(GameWorld* world, const ViewCamera &camera, float alpha)
{ {
_renderAlpha = alpha; _renderAlpha = alpha;
_renderWorld = world;
// Store the input camera, // Store the input camera,
_camera = camera; _camera = camera;
@ -246,11 +247,11 @@ void GameRenderer::renderWorld(const ViewCamera &camera, float alpha)
glBindVertexArray( vao ); glBindVertexArray( vao );
float tod = engine->state.hour + engine->state.minute/60.f; float tod = world->state.hour + world->state.minute/60.f;
// Requires a float 0-24 // Requires a float 0-24
auto weatherID = static_cast<WeatherLoader::WeatherCondition>(engine->state.currentWeather * 24); auto weatherID = static_cast<WeatherLoader::WeatherCondition>(world->state.currentWeather * 24);
auto weather = engine->data->weatherLoader.getWeatherData(weatherID, tod); auto weather = world->data->weatherLoader.getWeatherData(weatherID, tod);
glm::vec3 skyTop = weather.skyTopColor; glm::vec3 skyTop = weather.skyTopColor;
glm::vec3 skyBottom = weather.skyBottomColor; glm::vec3 skyBottom = weather.skyBottomColor;
@ -265,7 +266,7 @@ void GameRenderer::renderWorld(const ViewCamera &camera, float alpha)
}; };
sunDirection = glm::normalize(sunDirection); sunDirection = glm::normalize(sunDirection);
_camera.frustum.near = engine->state.cameraNear; _camera.frustum.near = world->state.cameraNear;
_camera.frustum.far = weather.farClipping; _camera.frustum.far = weather.farClipping;
auto view = _camera.getView(); auto view = _camera.getView();
@ -295,7 +296,7 @@ void GameRenderer::renderWorld(const ViewCamera &camera, float alpha)
renderer->pushDebugGroup("Objects"); renderer->pushDebugGroup("Objects");
renderer->pushDebugGroup("Dynamic"); renderer->pushDebugGroup("Dynamic");
for( GameObject* object : engine->objects ) { for( GameObject* object : world->objects ) {
if(! object->visible ) if(! object->visible )
{ {
continue; continue;
@ -314,7 +315,7 @@ void GameRenderer::renderWorld(const ViewCamera &camera, float alpha)
renderVehicle(static_cast<VehicleObject*>(object)); renderVehicle(static_cast<VehicleObject*>(object));
break; break;
case GameObject::Instance: case GameObject::Instance:
if(! engine->shouldBeOnGrid(object) ) if(! world->shouldBeOnGrid(object) )
{ {
renderInstance(static_cast<InstanceObject*>(object)); renderInstance(static_cast<InstanceObject*>(object));
} }
@ -337,15 +338,15 @@ void GameRenderer::renderWorld(const ViewCamera &camera, float alpha)
// Draw the static instance objects. k = % culled // Draw the static instance objects. k = % culled
int c = 0, k = 0; int c = 0, k = 0;
for(auto& cell : engine->worldGrid ) for(auto& cell : world->worldGrid )
{ {
c++; c++;
int y = c % WORLD_GRID_WIDTH; int y = c % WORLD_GRID_WIDTH;
int x = c / WORLD_GRID_WIDTH; int x = c / WORLD_GRID_WIDTH;
float cellhalf = WORLD_CELL_SIZE/2.f; float cellhalf = WORLD_CELL_SIZE/2.f;
float radius = cell.boundingRadius; float radius = cell.boundingRadius;
auto world = glm::vec3(glm::vec2(x,y) * glm::vec2(WORLD_CELL_SIZE) - glm::vec2(WORLD_GRID_SIZE/2.f) + glm::vec2(cellhalf), 0.f); auto worldp = glm::vec3(glm::vec2(x,y) * glm::vec2(WORLD_CELL_SIZE) - glm::vec2(WORLD_GRID_SIZE/2.f) + glm::vec2(cellhalf), 0.f);
if( _camera.frustum.intersects(world, radius) ) if( _camera.frustum.intersects(worldp, radius) )
{ {
for( auto& inst : cell.instances ) for( auto& inst : cell.instances )
{ {
@ -374,12 +375,12 @@ void GameRenderer::renderWorld(const ViewCamera &camera, float alpha)
profObjects = renderer->popDebugGroup(); profObjects = renderer->popDebugGroup();
// Render arrows above anything that isn't radar only (or hidden) // Render arrows above anything that isn't radar only (or hidden)
ModelRef& arrowModel = engine->data->models["arrow"]; ModelRef& arrowModel = world->data->models["arrow"];
if( arrowModel && arrowModel->resource ) if( arrowModel && arrowModel->resource )
{ {
auto arrowTex = engine->data->textures[{"copblue",""}]; auto arrowTex = world->data->textures[{"copblue",""}];
auto arrowFrame = arrowModel->resource->findFrame( "arrow" ); auto arrowFrame = arrowModel->resource->findFrame( "arrow" );
for( auto& blip : engine->state.radarBlips ) for( auto& blip : world->state.radarBlips )
{ {
if( blip.second.display == BlipData::Show ) if( blip.second.display == BlipData::Show )
{ {
@ -394,7 +395,7 @@ void GameRenderer::renderWorld(const ViewCamera &camera, float alpha)
model = glm::translate( model, blip.second.coord ); model = glm::translate( model, blip.second.coord );
} }
float a = engine->gameTime * glm::pi<float>(); float a = world->gameTime * glm::pi<float>();
model = glm::translate( model, glm::vec3(0.f, 0.f, 2.5f + glm::sin( a ) * 0.5f) ); model = glm::translate( model, glm::vec3(0.f, 0.f, 2.5f + glm::sin( a ) * 0.5f) );
model = glm::rotate( model, a, glm::vec3(0.f, 0.f, 1.f) ); model = glm::rotate( model, a, glm::vec3(0.f, 0.f, 1.f) );
model = glm::scale( model, glm::vec3(1.5f, 1.5f, 1.5f) ); model = glm::scale( model, glm::vec3(1.5f, 1.5f, 1.5f) );
@ -419,7 +420,7 @@ void GameRenderer::renderWorld(const ViewCamera &camera, float alpha)
// Draw goal indicators // Draw goal indicators
glDepthMask(GL_FALSE); glDepthMask(GL_FALSE);
renderer->useProgram( particleProg ); renderer->useProgram( particleProg );
for(auto& i : engine->getAreaIndicators()) for(auto& i : world->getAreaIndicators())
{ {
renderAreaIndicator( &i ); renderAreaIndicator( &i );
} }
@ -427,7 +428,7 @@ void GameRenderer::renderWorld(const ViewCamera &camera, float alpha)
renderer->pushDebugGroup("Water"); renderer->pushDebugGroup("Water");
water.render(this, engine); water.render(this, world);
profWater = renderer->popDebugGroup(); profWater = renderer->popDebugGroup();
@ -448,27 +449,27 @@ void GameRenderer::renderWorld(const ViewCamera &camera, float alpha)
profSky = renderer->popDebugGroup(); profSky = renderer->popDebugGroup();
renderer->pushDebugGroup("Effects"); renderer->pushDebugGroup("Effects");
renderEffects(); renderEffects(world);
profEffects = renderer->popDebugGroup(); profEffects = renderer->popDebugGroup();
glDisable(GL_DEPTH_TEST); glDisable(GL_DEPTH_TEST);
GLuint splashTexName = 0; GLuint splashTexName = 0;
auto fc = engine->state.fadeColour; auto fc = world->state.fadeColour;
if((fc.r + fc.g + fc.b) == 0 && engine->state.currentSplash.size() > 0) { if((fc.r + fc.g + fc.b) == 0 && world->state.currentSplash.size() > 0) {
auto splash = engine->data->findTexture(engine->state.currentSplash); auto splash = world->data->findTexture(world->state.currentSplash);
if ( splash ) if ( splash )
{ {
splashTexName = splash->getName(); splashTexName = splash->getName();
} }
} }
if( (engine->state.isCinematic || engine->state.currentCutscene ) && splashTexName != 0 ) { if( (world->state.isCinematic || world->state.currentCutscene ) && splashTexName != 0 ) {
renderLetterbox(); renderLetterbox();
} }
float fadeTimer = engine->gameTime - engine->state.fadeStart; float fadeTimer = world->gameTime - world->state.fadeStart;
if( fadeTimer < engine->state.fadeTime || !engine->state.fadeOut ) { if( fadeTimer < world->state.fadeTime || !world->state.fadeOut ) {
glUseProgram(ssRectProgram); glUseProgram(ssRectProgram);
glUniform2f(ssRectOffset, 0.f, 0.f); glUniform2f(ssRectOffset, 0.f, 0.f);
glUniform2f(ssRectSize, 1.f, 1.f); glUniform2f(ssRectSize, 1.f, 1.f);
@ -484,11 +485,11 @@ void GameRenderer::renderWorld(const ViewCamera &camera, float alpha)
} }
float fadeFrac = 0.f; float fadeFrac = 0.f;
if( engine->state.fadeTime > 0.f ) { if( world->state.fadeTime > 0.f ) {
fadeFrac = std::min(fadeTimer / engine->state.fadeTime, 1.f); fadeFrac = std::min(fadeTimer / world->state.fadeTime, 1.f);
} }
float a = engine->state.fadeOut ? 1.f - fadeFrac : fadeFrac; float a = world->state.fadeOut ? 1.f - fadeFrac : fadeFrac;
glm::vec4 fadeNormed(fc.r / 255.f, fc.g/ 255.f, fc.b/ 255.f, a); glm::vec4 fadeNormed(fc.r / 255.f, fc.g/ 255.f, fc.b/ 255.f, a);
@ -498,7 +499,7 @@ void GameRenderer::renderWorld(const ViewCamera &camera, float alpha)
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
} }
if( (engine->state.isCinematic || engine->state.currentCutscene ) && splashTexName == 0 ) { if( (world->state.isCinematic || world->state.currentCutscene ) && splashTexName == 0 ) {
renderLetterbox(); renderLetterbox();
} }
@ -561,9 +562,9 @@ void GameRenderer::renderVehicle(VehicleObject *vehicle)
// Draw wheels n' stuff // Draw wheels n' stuff
for( size_t w = 0; w < vehicle->info->wheels.size(); ++w) { for( size_t w = 0; w < vehicle->info->wheels.size(); ++w) {
auto woi = engine->data->findObjectType<ObjectData>(vehicle->vehicle->wheelModelID); auto woi = data->findObjectType<ObjectData>(vehicle->vehicle->wheelModelID);
if( woi ) { if( woi ) {
Model* wheelModel = engine->data->models["wheels"]->resource; Model* wheelModel = data->models["wheels"]->resource;
auto& wi = vehicle->physVehicle->getWheelInfo(w); auto& wi = vehicle->physVehicle->getWheelInfo(w);
if( wheelModel ) { if( wheelModel ) {
// Construct our own matrix so we can use the local transform // Construct our own matrix so we can use the local transform
@ -607,8 +608,8 @@ void GameRenderer::renderInstance(InstanceObject *instance)
{ {
if(instance->object && instance->object->timeOn != instance->object->timeOff) { if(instance->object && instance->object->timeOn != instance->object->timeOff) {
// Update rendering flags. // Update rendering flags.
if(engine->getHour() < instance->object->timeOn if(_renderWorld->getHour() < instance->object->timeOn
&& engine->getHour() > instance->object->timeOff) { && _renderWorld->getHour() > instance->object->timeOff) {
return; return;
} }
} }
@ -703,9 +704,9 @@ void GameRenderer::renderPickup(PickupObject *pickup)
if( ! pickup->isEnabled() ) return; if( ! pickup->isEnabled() ) return;
glm::mat4 modelMatrix = glm::translate(glm::mat4(), pickup->getPosition()); glm::mat4 modelMatrix = glm::translate(glm::mat4(), pickup->getPosition());
modelMatrix = glm::rotate(modelMatrix, engine->gameTime, glm::vec3(0.f, 0.f, 1.f)); modelMatrix = glm::rotate(modelMatrix, _renderWorld->gameTime, glm::vec3(0.f, 0.f, 1.f));
auto odata = engine->data->findObjectType<ObjectData>(pickup->getModelID()); auto odata = data->findObjectType<ObjectData>(pickup->getModelID());
Model* model = nullptr; Model* model = nullptr;
ModelFrame* itemModel = nullptr; ModelFrame* itemModel = nullptr;
@ -713,7 +714,7 @@ void GameRenderer::renderPickup(PickupObject *pickup)
/// @todo Better determination of is this object a weapon. /// @todo Better determination of is this object a weapon.
if( odata->ID >= 170 && odata->ID <= 184 ) if( odata->ID >= 170 && odata->ID <= 184 )
{ {
auto weapons = engine->data->models["weapons"]; auto weapons = data->models["weapons"];
if( weapons && weapons->resource && odata ) { if( weapons && weapons->resource && odata ) {
model = weapons->resource; model = weapons->resource;
itemModel = weapons->resource->findFrame(odata->modelName + "_l0"); itemModel = weapons->resource->findFrame(odata->modelName + "_l0");
@ -725,7 +726,7 @@ void GameRenderer::renderPickup(PickupObject *pickup)
} }
else else
{ {
auto handle = engine->data->models[odata->modelName]; auto handle = data->models[odata->modelName];
if ( handle && handle->resource ) if ( handle && handle->resource )
{ {
model = handle->resource; model = handle->resource;
@ -746,7 +747,7 @@ void GameRenderer::renderPickup(PickupObject *pickup)
void GameRenderer::renderCutsceneObject(CutsceneObject *cutscene) void GameRenderer::renderCutsceneObject(CutsceneObject *cutscene)
{ {
if(!engine->state.currentCutscene) return; if(!_renderWorld->state.currentCutscene) return;
if(!cutscene->model->resource) if(!cutscene->model->resource)
{ {
@ -756,7 +757,7 @@ void GameRenderer::renderCutsceneObject(CutsceneObject *cutscene)
glm::mat4 matrixModel; glm::mat4 matrixModel;
if( cutscene->getParentActor() ) { if( cutscene->getParentActor() ) {
matrixModel = glm::translate(matrixModel, engine->state.currentCutscene->meta.sceneOffset + glm::vec3(0.f, 0.f, 1.f)); matrixModel = glm::translate(matrixModel, _renderWorld->state.currentCutscene->meta.sceneOffset + glm::vec3(0.f, 0.f, 1.f));
//matrixModel = cutscene->getParentActor()->getTimeAdjustedTransform(_renderAlpha); //matrixModel = cutscene->getParentActor()->getTimeAdjustedTransform(_renderAlpha);
//matrixModel = glm::translate(matrixModel, glm::vec3(0.f, 0.f, 1.f)); //matrixModel = glm::translate(matrixModel, glm::vec3(0.f, 0.f, 1.f));
glm::mat4 localMatrix; glm::mat4 localMatrix;
@ -768,7 +769,7 @@ void GameRenderer::renderCutsceneObject(CutsceneObject *cutscene)
matrixModel = matrixModel * localMatrix; matrixModel = matrixModel * localMatrix;
} }
else { else {
matrixModel = glm::translate(matrixModel, engine->state.currentCutscene->meta.sceneOffset + glm::vec3(0.f, 0.f, 1.f)); matrixModel = glm::translate(matrixModel, _renderWorld->state.currentCutscene->meta.sceneOffset + glm::vec3(0.f, 0.f, 1.f));
} }
float mindist = 100000.f; float mindist = 100000.f;
@ -793,8 +794,8 @@ void GameRenderer::renderProjectile(ProjectileObject *projectile)
{ {
glm::mat4 modelMatrix = projectile->getTimeAdjustedTransform(_renderAlpha); glm::mat4 modelMatrix = projectile->getTimeAdjustedTransform(_renderAlpha);
auto odata = engine->data->findObjectType<ObjectData>(projectile->getProjectileInfo().weapon->modelID); auto odata = data->findObjectType<ObjectData>(projectile->getProjectileInfo().weapon->modelID);
auto weapons = engine->data->models["weapons"]; auto weapons = data->models["weapons"];
if( weapons && weapons->resource ) { if( weapons && weapons->resource ) {
auto itemModel = weapons->resource->findFrame(odata->modelName + "_l0"); auto itemModel = weapons->resource->findFrame(odata->modelName + "_l0");
auto matrix = glm::inverse(itemModel->getTransform()); auto matrix = glm::inverse(itemModel->getTransform());
@ -837,8 +838,8 @@ void GameRenderer::renderWheel(Model* model, const glm::mat4 &matrix, const std:
void GameRenderer::renderItem(InventoryItem *item, const glm::mat4 &modelMatrix) void GameRenderer::renderItem(InventoryItem *item, const glm::mat4 &modelMatrix)
{ {
// srhand // srhand
std::shared_ptr<ObjectData> odata = engine->data->findObjectType<ObjectData>(item->getModelID()); std::shared_ptr<ObjectData> odata = data->findObjectType<ObjectData>(item->getModelID());
auto weapons = engine->data->models["weapons"]; auto weapons = data->models["weapons"];
if( weapons && weapons->resource ) { if( weapons && weapons->resource ) {
auto itemModel = weapons->resource->findFrame(odata->modelName + "_l0"); auto itemModel = weapons->resource->findFrame(odata->modelName + "_l0");
auto matrix = glm::inverse(itemModel->getTransform()); auto matrix = glm::inverse(itemModel->getTransform());
@ -878,7 +879,7 @@ void GameRenderer::renderGeometry(Model* model, size_t g, const glm::mat4& model
{ {
auto& tC = mat.textures[0].name; auto& tC = mat.textures[0].name;
auto& tA = mat.textures[0].alphaName; auto& tA = mat.textures[0].alphaName;
tex = engine->data->findTexture(tC, tA); tex = data->findTexture(tC, tA);
if( ! tex ) if( ! tex )
{ {
//logger->warning("Renderer", "Missing texture: " + tC + " " + tA); //logger->warning("Renderer", "Missing texture: " + tC + " " + tA);
@ -935,10 +936,10 @@ void GameRenderer::renderAreaIndicator(const AreaIndicatorInfo* info)
{ {
glm::mat4 m(1.f); glm::mat4 m(1.f);
m = glm::translate(m, info->position); m = glm::translate(m, info->position);
glm::vec3 scale = info->radius + 0.15f * glm::sin(engine->gameTime * 5.f); glm::vec3 scale = info->radius + 0.15f * glm::sin(_renderWorld->gameTime * 5.f);
Renderer::DrawParameters dp; Renderer::DrawParameters dp;
dp.textures = {engine->data->findTexture("cloud1")->getName()}; dp.textures = {data->findTexture("cloud1")->getName()};
dp.ambient = 1.f; dp.ambient = 1.f;
dp.colour = glm::u8vec4(50, 100, 255, 1); dp.colour = glm::u8vec4(50, 100, 255, 1);
dp.start = 0; dp.start = 0;
@ -951,20 +952,20 @@ void GameRenderer::renderAreaIndicator(const AreaIndicatorInfo* info)
glm::vec3 final = scale * glm::pow(0.9f, i + 1.0f); glm::vec3 final = scale * glm::pow(0.9f, i + 1.0f);
mt = glm::scale(mt, glm::vec3(final.x, final.y, 1.0f + i * 0.1f)); mt = glm::scale(mt, glm::vec3(final.x, final.y, 1.0f + i * 0.1f));
int reverse = (i % 2 ? 1 : -1); int reverse = (i % 2 ? 1 : -1);
mt = glm::rotate(mt, reverse * engine->gameTime * 0.5f, glm::vec3(0.f, 0.f, 1.f) ); mt = glm::rotate(mt, reverse * _renderWorld->gameTime * 0.5f, glm::vec3(0.f, 0.f, 1.f) );
renderer->drawArrays(mt, &cylinderBuffer, dp); renderer->drawArrays(mt, &cylinderBuffer, dp);
} }
} }
void GameRenderer::renderEffects() void GameRenderer::renderEffects(GameWorld* world)
{ {
renderer->useProgram( particleProg ); renderer->useProgram( particleProg );
auto cpos = _camera.position; auto cpos = _camera.position;
auto cfwd = glm::normalize(glm::inverse(_camera.rotation) * glm::vec3(0.f, 1.f, 0.f)); auto cfwd = glm::normalize(glm::inverse(_camera.rotation) * glm::vec3(0.f, 1.f, 0.f));
auto& effects = engine->effects; auto& effects = world->effects;
std::sort( effects.begin(), effects.end(), std::sort( effects.begin(), effects.end(),
[&](const VisualFX* a, const VisualFX* b) { [&](const VisualFX* a, const VisualFX* b) {

View File

@ -38,8 +38,8 @@ void main()
})"; })";
MapRenderer::MapRenderer(GameWorld* world, Renderer* renderer) MapRenderer::MapRenderer(Renderer* renderer, GameData* _data)
: world( world ), renderer(renderer) : data(_data), renderer(renderer)
{ {
rectGeom.uploadVertices<VertexP2>({ rectGeom.uploadVertices<VertexP2>({
{-.5f, .5f}, {-.5f, .5f},
@ -72,7 +72,7 @@ glm::vec2 MapRenderer::mapToScreen(const glm::vec2& map, const MapInfo& mi)
return screenSize + screenCenter; return screenSize + screenCenter;
} }
void MapRenderer::draw(const MapInfo& mi) void MapRenderer::draw(GameWorld* world, const MapInfo& mi)
{ {
renderer->pushDebugGroup("Map"); renderer->pushDebugGroup("Map");
renderer->useProgram(rectProg); renderer->useProgram(rectProg);
@ -198,7 +198,7 @@ void MapRenderer::drawBlip(const glm::vec2& coord, const glm::mat4& model, const
GLuint tex = 0; GLuint tex = 0;
if ( !texture.empty() ) if ( !texture.empty() )
{ {
auto sprite= world->data->findTexture(texture); auto sprite= data->findTexture(texture);
tex = sprite->getName(); tex = sprite->getName();
renderer->setUniform(rectProg, "colour", glm::vec4(0.f)); renderer->setUniform(rectProg, "colour", glm::vec4(0.f));
} }

View File

@ -105,8 +105,8 @@ TextRenderer::TextInfo::TextInfo()
} }
TextRenderer::TextRenderer(GameWorld* engine, GameRenderer* renderer) TextRenderer::TextRenderer(GameRenderer* renderer)
: fonts({}), engine(engine), renderer(renderer) : fonts({}), renderer(renderer)
{ {
textShader = renderer->getRenderer()->createShader( textShader = renderer->getRenderer()->createShader(
TextVertexShader, TextFragmentShader ); TextVertexShader, TextFragmentShader );
@ -235,7 +235,7 @@ void TextRenderer::renderText(const TextRenderer::TextInfo& ti)
Renderer::DrawParameters dp; Renderer::DrawParameters dp;
dp.start = 0; dp.start = 0;
dp.count = gb.getCount(); dp.count = gb.getCount();
auto ftexture = engine->data->findTexture(fonts[ti.font]); auto ftexture = renderer->getData()->findTexture(fonts[ti.font]);
dp.textures = {ftexture->getName()}; dp.textures = {ftexture->getName()};
renderer->getRenderer()->drawArrays(glm::mat4(), &db, dp); renderer->getRenderer()->drawArrays(glm::mat4(), &db, dp);

View File

@ -6,8 +6,8 @@ BOOST_AUTO_TEST_SUITE(GameDataTests)
BOOST_AUTO_TEST_CASE(test_object_data) BOOST_AUTO_TEST_CASE(test_object_data)
{ {
GameData gd(&Global::get().log, Global::getGamePath()); GameData gd(&Global::get().log, &Global::get().work, Global::getGamePath());
GameWorld gw(&Global::get().log, &gd); GameWorld gw(&Global::get().log, &Global::get().work, &gd);
gd.load(); gd.load();

View File

@ -29,7 +29,7 @@ void drawMap(PlayerController* player, GameWorld* world, GameRenderer* render)
map.center = glm::vec2(player->getCharacter()->getPosition()); map.center = glm::vec2(player->getCharacter()->getPosition());
} }
render->map.draw(map); render->map.draw(world, map);
} }
void drawHUD(PlayerController* player, GameWorld* world, GameRenderer* render) void drawHUD(PlayerController* player, GameWorld* world, GameRenderer* render)

View File

@ -26,7 +26,7 @@ DebugDraw* debug;
StdOutReciever logPrinter; StdOutReciever logPrinter;
RWGame::RWGame(const std::string& gamepath, int argc, char* argv[]) RWGame::RWGame(const std::string& gamepath, int argc, char* argv[])
: engine(nullptr), renderer(nullptr), script(nullptr), inFocus(true), : state(nullptr), engine(nullptr), renderer(nullptr), script(nullptr), inFocus(true),
showDebugStats(false), showDebugPaths(false), showDebugStats(false), showDebugPaths(false),
accum(0.f), timescale(1.f) accum(0.f), timescale(1.f)
{ {
@ -89,19 +89,17 @@ RWGame::RWGame(const std::string& gamepath, int argc, char* argv[])
throw std::runtime_error("Invalid game directory path, is " +envname+ " set?"); throw std::runtime_error("Invalid game directory path, is " +envname+ " set?");
} }
data = new GameData(&log, gamepath); data = new GameData(&log, &work, gamepath);
engine = new GameWorld(&log, data);
// Initalize all the archives. // Initalize all the archives.
engine->data->loadIMG("/models/gta3"); data->loadIMG("/models/gta3");
//engine->data.loadIMG("/models/txd"); //engine->data.loadIMG("/models/txd");
engine->data->loadIMG("/anim/cuts"); data->loadIMG("/anim/cuts");
engine->data->load(); data->load();
// Initialize renderer // Initialize renderer
renderer = new GameRenderer(&log, engine); renderer = new GameRenderer(&log, data);
// Set up text renderer // Set up text renderer
renderer->text.setFontTexture(0, "pager"); renderer->text.setFontTexture(0, "pager");
@ -111,22 +109,23 @@ RWGame::RWGame(const std::string& gamepath, int argc, char* argv[])
debug = new DebugDraw; debug = new DebugDraw;
debug->setDebugMode(btIDebugDraw::DBG_DrawWireframe | btIDebugDraw::DBG_DrawConstraints | btIDebugDraw::DBG_DrawConstraintLimits); debug->setDebugMode(btIDebugDraw::DBG_DrawWireframe | btIDebugDraw::DBG_DrawConstraints | btIDebugDraw::DBG_DrawConstraintLimits);
debug->setShaderProgram(renderer->worldProg); debug->setShaderProgram(renderer->worldProg);
engine->dynamicsWorld->setDebugDrawer(debug);
engine->data->loadDynamicObjects(gamepath + "/data/object.dat"); data->loadDynamicObjects(gamepath + "/data/object.dat");
/// @TODO language choices. /// @TODO language choices.
engine->data->loadGXT("english.gxt"); data->loadGXT("english.gxt");
getRenderer()->water.setWaterTable(data->waterHeights, 48, engine->data->realWater, 128*128); getRenderer()->water.setWaterTable(data->waterHeights, 48, data->realWater, 128*128);
for(int m = 0; m < MAP_BLOCK_SIZE; ++m) for(int m = 0; m < MAP_BLOCK_SIZE; ++m)
{ {
std::string num = (m < 10 ? "0" : ""); std::string num = (m < 10 ? "0" : "");
std::string name = "radar" + num + std::to_string(m); std::string name = "radar" + num + std::to_string(m);
engine->data->loadTXD(name + ".txd"); data->loadTXD(name + ".txd");
} }
newGame();
auto loading = new LoadingState(this); auto loading = new LoadingState(this);
if( newgame ) if( newgame )
{ {
@ -147,6 +146,20 @@ RWGame::~RWGame()
delete script; delete script;
delete renderer; delete renderer;
delete engine; delete engine;
delete state;
}
void RWGame::newGame()
{
if( state != nullptr )
{
log.error("Game", "Cannot start a new game: game is already running.");
return;
}
state = new GameState;
engine = new GameWorld(&log, &work, data);
engine->dynamicsWorld->setDebugDrawer(debug);
} }
void RWGame::startScript(const std::string& name) void RWGame::startScript(const std::string& name)
@ -417,7 +430,7 @@ void RWGame::render(float alpha, float time)
renderer->getRenderer()->pushDebugGroup("World"); renderer->getRenderer()->pushDebugGroup("World");
renderer->renderWorld(viewCam, alpha); renderer->renderWorld(engine, viewCam, alpha);
auto rendertime = renderer->getRenderer()->popDebugGroup(); auto rendertime = renderer->getRenderer()->popDebugGroup();

View File

@ -13,11 +13,14 @@
class RWGame class RWGame
{ {
Logger log; Logger log;
GameState* state;
GameData* data; GameData* data;
GameWorld* engine; GameWorld* engine;
// must be allocated after Logger setup. // must be allocated after Logger setup.
GameRenderer* renderer; GameRenderer* renderer;
ScriptMachine* script; ScriptMachine* script;
// Background worker
WorkContext work;
sf::RenderWindow window; sf::RenderWindow window;
sf::Clock clock; sf::Clock clock;
bool inFocus; bool inFocus;
@ -35,6 +38,16 @@ public:
int run(); int run();
/**
* Initalizes a new game
*/
void newGame();
GameState* getState() const
{
return state;
}
GameWorld* getWorld() const GameWorld* getWorld() const
{ {
return engine; return engine;

View File

@ -39,7 +39,7 @@ void PauseState::draw(GameRenderer* r)
map.mapScreenTop = glm::vec2(vp.x, vp.y); map.mapScreenTop = glm::vec2(vp.x, vp.y);
map.mapScreenBottom = glm::vec2(0.f, 0.f); map.mapScreenBottom = glm::vec2(0.f, 0.f);
game->getRenderer()->map.draw(map); game->getRenderer()->map.draw(getWorld(), map);
State::draw(r); State::draw(r);
} }

View File

@ -149,9 +149,9 @@ void ViewerWindow::loadGame(const QString &path)
QDir gameDir( path ); QDir gameDir( path );
if( gameDir.exists() && path.size() > 0 ) { if( gameDir.exists() && path.size() > 0 ) {
gameData = new GameData( &engineLog, gameDir.absolutePath().toStdString() ); gameData = new GameData( &engineLog, &work, gameDir.absolutePath().toStdString() );
gameWorld = new GameWorld( &engineLog, gameData ); gameWorld = new GameWorld( &engineLog, &work, gameData );
renderer = new GameRenderer(&engineLog, gameWorld); renderer = new GameRenderer(&engineLog, gameData );
viewerWidget->setRenderer(renderer); viewerWidget->setRenderer(renderer);
gameWorld->data->load(); gameWorld->data->load();

View File

@ -19,6 +19,7 @@ class ViewerWindow : public QMainWindow
Q_OBJECT Q_OBJECT
Logger engineLog; Logger engineLog;
WorkContext work;
GameData* gameData; GameData* gameData;
GameWorld* gameWorld; GameWorld* gameWorld;

View File

@ -38,13 +38,14 @@ public:
GameData* d; GameData* d;
GameWorld* e; GameWorld* e;
Logger log; Logger log;
WorkContext work;
Global() { Global() {
wnd.create(sf::VideoMode(640, 360), "Testing"); wnd.create(sf::VideoMode(640, 360), "Testing");
glewExperimental = GL_TRUE; glewExperimental = GL_TRUE;
glewInit(); glewInit();
d = new GameData(&log, getGamePath()); d = new GameData(&log, &work, getGamePath());
e = new GameWorld(&log, d); e = new GameWorld(&log, &work, d);
e->data->loadIMG("/models/gta3"); e->data->loadIMG("/models/gta3");
e->data->loadIMG("/anim/cuts"); e->data->loadIMG("/anim/cuts");