Non-blocking map loading
This commit is contained in:
parent
773d80109a
commit
d0b30ed56b
@ -1,12 +1,13 @@
|
||||
#include "cmdfile.hpp"
|
||||
|
||||
void assets::LoadCMDFile(const std::string& filename,
|
||||
const std::function<void(const std::string& command, std::istringstream& iss)>& handler)
|
||||
void assets::LoadCMDStream(std::istream& is, CmdCallback handler)
|
||||
{
|
||||
std::istringstream file = fs::ReadFileAsStream(filename);
|
||||
std::string line, command;
|
||||
|
||||
std::string line;
|
||||
while (std::getline(file, line))
|
||||
if (is.eof())
|
||||
return;
|
||||
|
||||
while (std::getline(is, line))
|
||||
{
|
||||
if (line.empty() || line[0] == '#') // Skip empty lines and comments
|
||||
continue;
|
||||
@ -15,13 +16,20 @@ void assets::LoadCMDFile(const std::string& filename,
|
||||
line.erase(0, line.find_first_not_of(" \t"));
|
||||
|
||||
std::istringstream iss(line);
|
||||
|
||||
std::string command;
|
||||
iss >> command;
|
||||
|
||||
handler(command, iss);
|
||||
if (!handler(command, iss))
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void assets::LoadCMDFile(const std::string& filename, CmdCallbackVoid handler)
|
||||
{
|
||||
std::istringstream file = fs::ReadFileAsStream(filename);
|
||||
LoadCMDStream(file, [handler](const std::string& command, std::istringstream& iss) {
|
||||
handler(command, iss);
|
||||
return true;
|
||||
});
|
||||
}
|
||||
|
||||
std::string assets::ParseString(std::istringstream& iss)
|
||||
|
||||
@ -10,9 +10,11 @@
|
||||
namespace assets
|
||||
{
|
||||
|
||||
void LoadCMDFile(const std::string& filename,
|
||||
const std::function<void(const std::string& command, std::istringstream& iss)>& handler);
|
||||
using CmdCallback = std::function<bool(const std::string& command, std::istringstream& iss)>;
|
||||
using CmdCallbackVoid = std::function<void(const std::string& command, std::istringstream& iss)>;
|
||||
|
||||
void LoadCMDStream(std::istream& is, CmdCallback handler);
|
||||
void LoadCMDFile(const std::string& filename, CmdCallbackVoid handler);
|
||||
|
||||
inline void ParseTransform(std::istringstream& iss, Transform& trans)
|
||||
{
|
||||
|
||||
@ -28,8 +28,131 @@ static AABB3 TransformAABB(const AABB3& aabb, const glm::mat4& mat)
|
||||
|
||||
std::shared_ptr<const assets::Map> assets::Map::LoadFromFile(const std::string& filename)
|
||||
{
|
||||
auto map = std::make_shared<Map>();
|
||||
MapLoader loader(filename);
|
||||
while (loader.Next()) {}
|
||||
return loader.GetMap();
|
||||
}
|
||||
|
||||
const assets::MapGraph* assets::Map::GetGraph(const std::string& name) const
|
||||
{
|
||||
auto it = graphs_.find(name);
|
||||
if (it != graphs_.end())
|
||||
return &it->second;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// MapLoader
|
||||
|
||||
assets::MapLoader::MapLoader(const std::string& filename)
|
||||
: map_iss_(fs::ReadFileAsStream(filename)), map_(std::make_shared<Map>())
|
||||
{
|
||||
}
|
||||
|
||||
bool assets::MapLoader::Next()
|
||||
{
|
||||
switch (state_)
|
||||
{
|
||||
case ML_INIT:
|
||||
state_ = ML_READ_MODELS;
|
||||
return true;
|
||||
|
||||
case ML_READ_MODELS:
|
||||
ReadModels();
|
||||
state_ = ML_LOAD_BASEMODEL;
|
||||
return true;
|
||||
|
||||
case ML_LOAD_BASEMODEL:
|
||||
LoadBaseModel();
|
||||
state_ = ML_LOAD_MODELS;
|
||||
return true;
|
||||
|
||||
case ML_LOAD_MODELS:
|
||||
if (LoadNextModel())
|
||||
return true;
|
||||
|
||||
state_ = ML_STRUCTS;
|
||||
return true;
|
||||
|
||||
case ML_STRUCTS:
|
||||
LoadStructs();
|
||||
state_ = ML_FINISHED;
|
||||
return true;
|
||||
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
int assets::MapLoader::GetPercent() const
|
||||
{
|
||||
switch (state_)
|
||||
{
|
||||
case ML_INIT:
|
||||
case ML_READ_MODELS:
|
||||
return 0;
|
||||
|
||||
case ML_LOAD_BASEMODEL:
|
||||
return 10;
|
||||
|
||||
case ML_LOAD_MODELS:
|
||||
return 60 + models_.size() * 30 / model_names_.size();
|
||||
|
||||
case ML_STRUCTS:
|
||||
return 90;
|
||||
|
||||
default:
|
||||
return 100;
|
||||
}
|
||||
}
|
||||
|
||||
std::shared_ptr<const assets::Map> assets::MapLoader::GetMap() const
|
||||
{
|
||||
if (state_ != ML_FINISHED)
|
||||
return nullptr;
|
||||
|
||||
return map_;
|
||||
}
|
||||
|
||||
void assets::MapLoader::ReadModels()
|
||||
{
|
||||
LoadCMDStream(map_iss_, [&](const std::string& command, std::istringstream& iss) {
|
||||
if (command == "basemodel")
|
||||
{
|
||||
iss >> basemodel_name_;
|
||||
}
|
||||
else if (command == "model")
|
||||
{
|
||||
std::string model_name;
|
||||
iss >> model_name;
|
||||
model_names_.emplace_back(std::move(model_name));
|
||||
}
|
||||
else if (command == "endmodels")
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
});
|
||||
}
|
||||
|
||||
void assets::MapLoader::LoadBaseModel()
|
||||
{
|
||||
map_->basemodel_ = CacheManager::GetModel("data/" + basemodel_name_ + ".mdl");
|
||||
}
|
||||
|
||||
bool assets::MapLoader::LoadNextModel()
|
||||
{
|
||||
if (models_.size() >= model_names_.size())
|
||||
return false;
|
||||
|
||||
const auto& model_name = model_names_[models_.size()];
|
||||
models_.push_back(assets::CacheManager::GetModel("data/" + model_name + ".mdl"));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void assets::MapLoader::LoadStructs()
|
||||
{
|
||||
MapGraph* graph = nullptr;
|
||||
std::vector<std::tuple<size_t, size_t>> graph_edges;
|
||||
|
||||
@ -49,24 +172,20 @@ std::shared_ptr<const assets::Map> assets::Map::LoadFromFile(const std::string&
|
||||
|
||||
Chunk* chunk = nullptr;
|
||||
|
||||
LoadCMDFile(filename, [&](const std::string& command, std::istringstream& iss) {
|
||||
if (command == "basemodel")
|
||||
{
|
||||
std::string model_name;
|
||||
iss >> model_name;
|
||||
|
||||
map->basemodel_ = CacheManager::GetModel("data/" + model_name + ".mdl");
|
||||
}
|
||||
else if (command == "static")
|
||||
LoadCMDStream(map_iss_, [&](const std::string& command, std::istringstream& iss) {
|
||||
if (command == "static")
|
||||
{
|
||||
if (!chunk)
|
||||
throw std::runtime_error("static in map without chunk");
|
||||
|
||||
MapStaticObject obj;
|
||||
std::string model_name;
|
||||
iss >> model_name;
|
||||
size_t model_idx;
|
||||
iss >> model_idx;
|
||||
|
||||
obj.model = assets::CacheManager::GetModel("data/" + model_name + ".mdl");
|
||||
if (model_idx >= models_.size())
|
||||
throw std::runtime_error("static in map with out of range model idx");
|
||||
|
||||
obj.model = models_[model_idx];
|
||||
|
||||
glm::vec3 angles;
|
||||
|
||||
@ -87,18 +206,18 @@ std::shared_ptr<const assets::Map> assets::Map::LoadFromFile(const std::string&
|
||||
}
|
||||
}
|
||||
|
||||
map->objs_.push_back(std::move(obj));
|
||||
map_->objs_.push_back(std::move(obj));
|
||||
chunk->num_objs++;
|
||||
}
|
||||
else if (command == "chunk")
|
||||
{
|
||||
glm::ivec2 coord;
|
||||
chunk = &map->chunks_.emplace_back();
|
||||
chunk = &map_->chunks_.emplace_back();
|
||||
iss >> coord.x >> coord.y;
|
||||
iss >> chunk->aabb.min.x >> chunk->aabb.min.y >> chunk->aabb.min.z;
|
||||
iss >> chunk->aabb.max.x >> chunk->aabb.max.y >> chunk->aabb.max.z;
|
||||
|
||||
chunk->first_obj = map->objs_.size();
|
||||
chunk->first_obj = map_->objs_.size();
|
||||
}
|
||||
else if (command == "surface")
|
||||
{
|
||||
@ -110,10 +229,10 @@ std::shared_ptr<const assets::Map> assets::Map::LoadFromFile(const std::string&
|
||||
throw std::runtime_error("surface in map without chunk");
|
||||
|
||||
#ifdef CLIENT
|
||||
if (!map->basemodel_)
|
||||
if (!map_->basemodel_)
|
||||
throw std::runtime_error("surface in map with no basemodel");
|
||||
|
||||
auto mesh = map->basemodel_->GetMesh();
|
||||
auto mesh = map_->basemodel_->GetMesh();
|
||||
|
||||
if (!mesh)
|
||||
throw std::runtime_error("surface in map with no basemodel mesh");
|
||||
@ -138,7 +257,7 @@ std::shared_ptr<const assets::Map> assets::Map::LoadFromFile(const std::string&
|
||||
std::string graph_name;
|
||||
iss >> graph_name;
|
||||
|
||||
graph = &map->graphs_[graph_name];
|
||||
graph = &map_->graphs_[graph_name];
|
||||
graph_edges.clear();
|
||||
}
|
||||
else if (command == "n")
|
||||
@ -162,18 +281,11 @@ std::shared_ptr<const assets::Map> assets::Map::LoadFromFile(const std::string&
|
||||
|
||||
graph_edges.emplace_back(from_idx, to_idx);
|
||||
}
|
||||
|
||||
return true;
|
||||
});
|
||||
|
||||
if (graph)
|
||||
ProcessGraph();
|
||||
|
||||
return map;
|
||||
}
|
||||
|
||||
const assets::MapGraph* assets::Map::GetGraph(const std::string& name) const
|
||||
{
|
||||
auto it = graphs_.find(name);
|
||||
if (it != graphs_.end())
|
||||
return &it->second;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
@ -4,6 +4,7 @@
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <sstream>
|
||||
|
||||
#include "game/transform_node.hpp"
|
||||
#include "model.hpp"
|
||||
@ -66,6 +67,46 @@ private:
|
||||
std::vector<Chunk> chunks_;
|
||||
std::vector<MapStaticObject> objs_;
|
||||
std::map<std::string, MapGraph> graphs_;
|
||||
|
||||
friend class MapLoader;
|
||||
};
|
||||
|
||||
enum MapLoadingState
|
||||
{
|
||||
ML_INIT,
|
||||
ML_READ_MODELS,
|
||||
ML_LOAD_BASEMODEL,
|
||||
ML_LOAD_MODELS,
|
||||
ML_STRUCTS,
|
||||
ML_FINISHED,
|
||||
};
|
||||
|
||||
class MapLoader
|
||||
{
|
||||
public:
|
||||
MapLoader(const std::string& filename);
|
||||
|
||||
bool Next();
|
||||
int GetPercent() const;
|
||||
|
||||
std::shared_ptr<const Map> GetMap() const;
|
||||
|
||||
private:
|
||||
void ReadModels();
|
||||
void LoadBaseModel();
|
||||
bool LoadNextModel();
|
||||
void LoadStructs();
|
||||
|
||||
private:
|
||||
std::istringstream map_iss_;
|
||||
|
||||
MapLoadingState state_ = ML_INIT;
|
||||
|
||||
std::string basemodel_name_;
|
||||
std::vector<std::string> model_names_;
|
||||
std::vector<std::shared_ptr<const Model>> models_;
|
||||
|
||||
std::shared_ptr<Map> map_;
|
||||
};
|
||||
|
||||
} // namespace assets
|
||||
@ -38,16 +38,12 @@ void App::Frame()
|
||||
session_->Update(updinfo);
|
||||
}
|
||||
|
||||
|
||||
renderer_.Begin(viewport_size_.x, viewport_size_.y);
|
||||
renderer_.ClearColor(glm::vec3(0.5f, 0.7f, 1.0f));
|
||||
renderer_.ClearDepth();
|
||||
|
||||
dlist_.Clear();
|
||||
gfx::DrawListParams params;
|
||||
gfx::DrawListParams params{};
|
||||
params.screen_width = viewport_size_.x;
|
||||
params.screen_height = viewport_size_.y;
|
||||
params.env.clear_color = glm::vec3(0.1f);
|
||||
|
||||
dlist_.Clear();
|
||||
gui_.Begin();
|
||||
|
||||
// draw session
|
||||
|
||||
@ -182,7 +182,7 @@ void game::view::ClientSession::DrawWorld(gfx::DrawList& dlist, gfx::DrawListPar
|
||||
|
||||
// glm::mat4 fake_view_proj = glm::perspective(glm::radians(30.0f), aspect, 0.1f, 3000.0f) * view;
|
||||
|
||||
game::view::DrawArgs draw_args(dlist, gui, params.view_proj, eye, glm::ivec2(params.screen_width, params.screen_height), 500.0f);
|
||||
game::view::DrawArgs draw_args(dlist, params.env, gui, params.view_proj, eye, glm::ivec2(params.screen_width, params.screen_height), 500.0f);
|
||||
world_->Draw(draw_args);
|
||||
|
||||
glm::mat4 camera_world = glm::inverse(view);
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include "gfx/draw_list.hpp"
|
||||
#include "gfx/renderer.hpp"
|
||||
#include "gfx/frustum.hpp"
|
||||
#include "gui/context.hpp"
|
||||
|
||||
@ -10,16 +11,19 @@ namespace game::view
|
||||
struct DrawArgs
|
||||
{
|
||||
gfx::DrawList& dlist;
|
||||
gfx::DrawListEnvironmentParams& env;
|
||||
gui::Context& gui;
|
||||
|
||||
|
||||
const glm::mat4 view_proj;
|
||||
const glm::vec3 eye;
|
||||
const gfx::Frustum frustum;
|
||||
const glm::ivec2 screen_size;
|
||||
const float render_distance;
|
||||
|
||||
DrawArgs(gfx::DrawList& dlist, gui::Context& gui, const glm::mat4& view_proj, const glm::vec3& eye, const glm::ivec2& screen_size, float render_distance)
|
||||
: dlist(dlist), gui(gui), view_proj(view_proj), eye(eye), frustum(view_proj), screen_size(screen_size), render_distance(render_distance)
|
||||
DrawArgs(gfx::DrawList& dlist, gfx::DrawListEnvironmentParams& env, gui::Context& gui, const glm::mat4& view_proj,
|
||||
const glm::vec3& eye, const glm::ivec2& screen_size, float render_distance)
|
||||
: dlist(dlist), env(env), gui(gui), view_proj(view_proj), eye(eye), frustum(view_proj),
|
||||
screen_size(screen_size), render_distance(render_distance)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
@ -6,13 +6,36 @@
|
||||
|
||||
game::view::MapInstanceView::MapInstanceView(const std::string& map_name)
|
||||
{
|
||||
map_ = assets::CacheManager::GetMap("data/" + map_name + ".map");
|
||||
loader_ = std::make_unique<assets::MapLoader>("data/" + map_name + ".map");
|
||||
}
|
||||
|
||||
void game::view::MapInstanceView::LoadNext()
|
||||
{
|
||||
if (IsLoaded())
|
||||
return;
|
||||
|
||||
if (loader_->Next())
|
||||
return;
|
||||
|
||||
// just loaded
|
||||
map_ = loader_->GetMap();
|
||||
objs_visible_.resize(map_->GetStaticObjects().size(), true);
|
||||
loader_.reset();
|
||||
}
|
||||
|
||||
int game::view::MapInstanceView::GetLoadingPercent() const
|
||||
{
|
||||
if (!loader_)
|
||||
return 100;
|
||||
|
||||
return loader_->GetPercent();
|
||||
}
|
||||
|
||||
void game::view::MapInstanceView::Draw(const game::view::DrawArgs& args) const
|
||||
{
|
||||
if (!map_)
|
||||
return;
|
||||
|
||||
const auto& basemodel = map_->GetBaseModel();
|
||||
|
||||
if (!basemodel || !basemodel->GetMesh())
|
||||
@ -40,8 +63,10 @@ void game::view::MapInstanceView::Draw(const game::view::DrawArgs& args) const
|
||||
void game::view::MapInstanceView::EnableObj(net::ObjNum num, bool enable)
|
||||
{
|
||||
size_t i = static_cast<size_t>(num);
|
||||
|
||||
// map may be not loaded yet, in that case make the visible flag fit
|
||||
if (i >= objs_visible_.size())
|
||||
return;
|
||||
objs_visible_.resize(i + 1, true);
|
||||
|
||||
objs_visible_[i] = enable;
|
||||
}
|
||||
|
||||
@ -12,6 +12,10 @@ class MapInstanceView
|
||||
public:
|
||||
MapInstanceView(const std::string& map_name);
|
||||
|
||||
void LoadNext();
|
||||
bool IsLoaded() const { return loader_.get() == nullptr; }
|
||||
int GetLoadingPercent() const;
|
||||
|
||||
void Draw(const game::view::DrawArgs& args) const;
|
||||
|
||||
void EnableObj(net::ObjNum num, bool enable);
|
||||
@ -20,6 +24,7 @@ private:
|
||||
void DrawChunk(const game::view::DrawArgs& args, const assets::Mesh& basemesh, const assets::Chunk& chunk) const;
|
||||
|
||||
private:
|
||||
std::unique_ptr<assets::MapLoader> loader_;
|
||||
std::shared_ptr<const assets::Map> map_;
|
||||
std::vector<bool> objs_visible_;
|
||||
|
||||
|
||||
@ -6,6 +6,7 @@
|
||||
#include "characterview.hpp"
|
||||
#include "vehicleview.hpp"
|
||||
#include "client_session.hpp"
|
||||
#include "draw_args.hpp"
|
||||
|
||||
game::view::WorldView::WorldView(ClientSession& session, net::InMessage& msg) :
|
||||
session_(session), audiomaster_(session_.GetAudioMaster()), map_("openworld")
|
||||
@ -68,6 +69,9 @@ void game::view::WorldView::Update(const UpdateInfo& info)
|
||||
{
|
||||
time_ = info.time;
|
||||
|
||||
if (!map_.IsLoaded())
|
||||
map_.LoadNext();
|
||||
|
||||
for (const auto& [entnum, ent] : ents_)
|
||||
{
|
||||
ent->TryUpdate(info);
|
||||
@ -76,6 +80,14 @@ void game::view::WorldView::Update(const UpdateInfo& info)
|
||||
|
||||
void game::view::WorldView::Draw(const DrawArgs& args) const
|
||||
{
|
||||
if (!map_.IsLoaded())
|
||||
{
|
||||
DrawLoadingScreen(args);
|
||||
return;
|
||||
}
|
||||
|
||||
args.env.clear_color = glm::vec3(0.5f, 0.7f, 1.0f);
|
||||
|
||||
map_.Draw(args);
|
||||
|
||||
for (const auto& [entnum, ent] : ents_)
|
||||
@ -119,6 +131,22 @@ game::view::EntityView* game::view::WorldView::GetEntity(net::EntNum entnum)
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void game::view::WorldView::DrawLoadingScreen(const DrawArgs& args) const
|
||||
{
|
||||
float margin = 50.0f;
|
||||
glm::vec2 size(400.0f, 15.0f);
|
||||
glm::vec2 pos(margin, args.screen_size.y - margin - size.y);
|
||||
|
||||
int loaded_percent = map_.GetLoadingPercent();
|
||||
float loaded = static_cast<float>(loaded_percent) * 0.01f;
|
||||
|
||||
args.gui.DrawRect(pos, pos + size, 0x77FFFFFF);
|
||||
args.gui.DrawRect(pos, pos + glm::vec2(size.x * loaded, size.y), 0xFF00FFFF);
|
||||
|
||||
std::string load_text = std::to_string(loaded_percent) + "%";
|
||||
args.gui.DrawTextAligned(load_text, pos + glm::vec2(size.x + 50.0f, size.y * 0.5f), glm::vec2(-0.5f, -0.5f));
|
||||
}
|
||||
|
||||
bool game::view::WorldView::ProcessEntSpawnMsg(net::InMessage& msg)
|
||||
{
|
||||
net::EntNum entnum;
|
||||
|
||||
@ -33,6 +33,8 @@ public:
|
||||
audio::Master& GetAudioMaster() const { return audiomaster_; }
|
||||
|
||||
private:
|
||||
void DrawLoadingScreen(const DrawArgs& args) const;
|
||||
|
||||
// msg handlers
|
||||
bool ProcessEntSpawnMsg(net::InMessage& msg);
|
||||
bool ProcessEntMsgMsg(net::InMessage& msg);
|
||||
|
||||
@ -24,27 +24,13 @@ gfx::Renderer::Renderer()
|
||||
SetupBeamVA();
|
||||
}
|
||||
|
||||
void gfx::Renderer::Begin(size_t width, size_t height)
|
||||
{
|
||||
current_shader_ = nullptr;
|
||||
glViewport(0, 0, width, height);
|
||||
|
||||
//glEnable(GL_MULTISAMPLE);
|
||||
}
|
||||
|
||||
void gfx::Renderer::ClearColor(const glm::vec3& color)
|
||||
{
|
||||
glClearColor(color.r, color.g, color.b, 1.0f);
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
}
|
||||
|
||||
void gfx::Renderer::ClearDepth()
|
||||
{
|
||||
glClear(GL_DEPTH_BUFFER_BIT);
|
||||
}
|
||||
|
||||
void gfx::Renderer::DrawList(gfx::DrawList& list, const DrawListParams& params)
|
||||
{
|
||||
current_shader_ = nullptr;
|
||||
glViewport(0, 0, params.screen_width, params.screen_height);
|
||||
glClearColor(params.env.clear_color.r, params.env.clear_color.g, params.env.clear_color.b, 1.0f);
|
||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||
|
||||
DrawSurfaceList(list.surfaces, params);
|
||||
DrawBeamList(list.beams, params);
|
||||
DrawHudList(list.huds, params);
|
||||
|
||||
@ -3,67 +3,66 @@
|
||||
#include <memory>
|
||||
#include <span>
|
||||
|
||||
#include "shader.hpp"
|
||||
#include "draw_list.hpp"
|
||||
#include "shader.hpp"
|
||||
|
||||
namespace gfx
|
||||
{
|
||||
struct DrawListParams
|
||||
{
|
||||
glm::vec3 cam_pos;
|
||||
glm::mat4 view_proj;
|
||||
size_t screen_width = 0;
|
||||
size_t screen_height = 0;
|
||||
};
|
||||
|
||||
struct MeshShader
|
||||
{
|
||||
std::unique_ptr<Shader> shader;
|
||||
struct DrawListEnvironmentParams
|
||||
{
|
||||
glm::vec3 clear_color;
|
||||
};
|
||||
|
||||
// cached state to avoid redundant uniform updates which are expensive especially on WebGL
|
||||
bool global_setup = false;
|
||||
glm::vec4 color = glm::vec4(-1.0f); // invalid to force initial setup
|
||||
int flags = 0;
|
||||
};
|
||||
struct DrawListParams
|
||||
{
|
||||
DrawListEnvironmentParams env;
|
||||
glm::vec3 cam_pos;
|
||||
glm::mat4 view_proj;
|
||||
size_t screen_width = 0;
|
||||
size_t screen_height = 0;
|
||||
};
|
||||
|
||||
class Renderer
|
||||
{
|
||||
public:
|
||||
Renderer();
|
||||
struct MeshShader
|
||||
{
|
||||
std::unique_ptr<Shader> shader;
|
||||
|
||||
void Begin(size_t width, size_t height);
|
||||
// cached state to avoid redundant uniform updates which are expensive especially on WebGL
|
||||
bool global_setup = false;
|
||||
glm::vec4 color = glm::vec4(-1.0f); // invalid to force initial setup
|
||||
int flags = 0;
|
||||
};
|
||||
|
||||
void ClearColor(const glm::vec3& color);
|
||||
void ClearDepth();
|
||||
class Renderer
|
||||
{
|
||||
public:
|
||||
Renderer();
|
||||
void DrawList(gfx::DrawList& list, const DrawListParams& params);
|
||||
|
||||
void DrawList(gfx::DrawList& list, const DrawListParams& params);
|
||||
private:
|
||||
void SetupBeamVA();
|
||||
|
||||
private:
|
||||
void SetupBeamVA();
|
||||
void InvalidateShaders();
|
||||
void InvalidateMeshShader(MeshShader& mshader);
|
||||
void SetupMeshShader(MeshShader& mshader, const DrawListParams& params);
|
||||
|
||||
void InvalidateShaders();
|
||||
void InvalidateMeshShader(MeshShader& mshader);
|
||||
void SetupMeshShader(MeshShader& mshader, const DrawListParams& params);
|
||||
void DrawSurfaceList(std::span<DrawSurfaceCmd> queue, const DrawListParams& params);
|
||||
void DrawBeamList(std::span<DrawBeamCmd> queue, const DrawListParams& params);
|
||||
void DrawHudList(std::span<DrawHudCmd> queue, const DrawListParams& params);
|
||||
|
||||
void DrawSurfaceList(std::span<DrawSurfaceCmd> queue, const DrawListParams& params);
|
||||
void DrawBeamList(std::span<DrawBeamCmd> queue, const DrawListParams& params);
|
||||
void DrawHudList(std::span<DrawHudCmd> queue, const DrawListParams& params);
|
||||
private:
|
||||
MeshShader mesh_shader_;
|
||||
MeshShader skel_mesh_shader_;
|
||||
MeshShader deform_mesh_shader_;
|
||||
std::unique_ptr<Shader> solid_shader_;
|
||||
|
||||
private:
|
||||
MeshShader mesh_shader_;
|
||||
MeshShader skel_mesh_shader_;
|
||||
MeshShader deform_mesh_shader_;
|
||||
std::unique_ptr<Shader> solid_shader_;
|
||||
std::unique_ptr<BufferObject> beam_segments_vbo_;
|
||||
std::unique_ptr<VertexArray> beam_va_;
|
||||
std::unique_ptr<Shader> beam_shader_;
|
||||
|
||||
std::unique_ptr<BufferObject> beam_segments_vbo_;
|
||||
std::unique_ptr<VertexArray> beam_va_;
|
||||
std::unique_ptr<Shader> beam_shader_;
|
||||
std::unique_ptr<Shader> hud_shader_;
|
||||
|
||||
std::unique_ptr<Shader> hud_shader_;
|
||||
const Shader* current_shader_ = nullptr;
|
||||
};
|
||||
|
||||
const Shader* current_shader_ = nullptr;
|
||||
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
} // namespace gfx
|
||||
Loading…
x
Reference in New Issue
Block a user