Beam rendering, max entity distance and other stuff
This commit is contained in:
parent
4b04a77e7e
commit
0cc61ec358
@ -82,9 +82,12 @@ void App::Frame()
|
|||||||
{
|
{
|
||||||
// glm::mat4 view = glm::lookAt(glm::vec3(15.0f, 0.0f, 1.0f), glm::vec3(0.0f, 0.0f, -13.0f), glm::vec3(0.0f, 0.0f, 1.0f));
|
// glm::mat4 view = glm::lookAt(glm::vec3(15.0f, 0.0f, 1.0f), glm::vec3(0.0f, 0.0f, -13.0f), glm::vec3(0.0f, 0.0f, 1.0f));
|
||||||
glm::mat4 proj = glm::perspective(glm::radians(45.0f), aspect, 0.1f, 3000.0f);
|
glm::mat4 proj = glm::perspective(glm::radians(45.0f), aspect, 0.1f, 3000.0f);
|
||||||
glm::mat4 view = session_->GetViewMatrix();
|
glm::vec3 eye;
|
||||||
|
glm::mat4 view;
|
||||||
|
session_->GetViewInfo(eye, view);
|
||||||
|
|
||||||
params.view_proj = proj * view;
|
params.view_proj = proj * view;
|
||||||
|
params.cam_pos = eye;
|
||||||
|
|
||||||
game::view::DrawArgs draw_args(dlist_, params.view_proj, viewport_size_);
|
game::view::DrawArgs draw_args(dlist_, params.view_proj, viewport_size_);
|
||||||
world->Draw(draw_args);
|
world->Draw(draw_args);
|
||||||
|
|||||||
@ -30,6 +30,9 @@ public:
|
|||||||
void Remove() { removed_ = true; }
|
void Remove() { removed_ = true; }
|
||||||
bool IsRemoved() const { return removed_; }
|
bool IsRemoved() const { return removed_; }
|
||||||
|
|
||||||
|
const Transform& GetRootTransform() const { return root_.local; }
|
||||||
|
float GetMaxDistance() const { return max_distance_; }
|
||||||
|
|
||||||
virtual ~Entity() = default;
|
virtual ~Entity() = default;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@ -46,8 +49,11 @@ protected:
|
|||||||
const net::EntType viewtype_;
|
const net::EntType viewtype_;
|
||||||
|
|
||||||
TransformNode root_;
|
TransformNode root_;
|
||||||
|
|
||||||
|
float max_distance_ = 700.0f;
|
||||||
std::string nametag_;
|
std::string nametag_;
|
||||||
|
|
||||||
|
|
||||||
bool removed_ = false;
|
bool removed_ = false;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|||||||
@ -94,7 +94,7 @@ game::OpenWorld::OpenWorld() : World("openworld")
|
|||||||
// }
|
// }
|
||||||
|
|
||||||
// spawn bots
|
// spawn bots
|
||||||
for (size_t i = 0; i < 30; ++i)
|
for (size_t i = 0; i < 70; ++i)
|
||||||
{
|
{
|
||||||
SpawnBot();
|
SpawnBot();
|
||||||
}
|
}
|
||||||
@ -262,7 +262,16 @@ static float GetTurnAngle(const glm::vec3& pos, const glm::quat& rot, const glm:
|
|||||||
static void SelectNextNode(BotThinkState& s)
|
static void SelectNextNode(BotThinkState& s)
|
||||||
{
|
{
|
||||||
size_t node = s.path.back();
|
size_t node = s.path.back();
|
||||||
s.path.push_back(s.roads.nbs[s.roads.nodes[node].nbs + (rand() % s.roads.nodes[node].num_nbs)]);
|
size_t num_nbs = s.roads.nodes[node].num_nbs;
|
||||||
|
|
||||||
|
if (num_nbs < 1)
|
||||||
|
{
|
||||||
|
const auto& pos = s.roads.nodes[node].position;
|
||||||
|
std::cout << "node " << node << " has no neighbors!!!1 position: " << pos.x << " " << pos.y << " " << pos.z << std::endl;
|
||||||
|
throw std::runtime_error("no neighbors");
|
||||||
|
}
|
||||||
|
|
||||||
|
s.path.push_back(s.roads.nbs[s.roads.nodes[node].nbs + (rand() % num_nbs)]);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void BotThink(std::shared_ptr<BotThinkState> s)
|
static void BotThink(std::shared_ptr<BotThinkState> s)
|
||||||
@ -480,13 +489,13 @@ void game::OpenWorld::SpawnBot()
|
|||||||
// auto color = glm::vec3{0.3f, 0.3f, 0.3f};
|
// auto color = glm::vec3{0.3f, 0.3f, 0.3f};
|
||||||
auto color = GetRandomColor();
|
auto color = GetRandomColor();
|
||||||
auto& vehicle = Spawn<Vehicle>(GetRandomCarModel(), color);
|
auto& vehicle = Spawn<Vehicle>(GetRandomCarModel(), color);
|
||||||
vehicle.SetNametag("bot (" + std::to_string(vehicle.GetEntNum()) + ")");
|
//vehicle.SetNametag("bot (" + std::to_string(vehicle.GetEntNum()) + ")");
|
||||||
vehicle.SetPosition(roads->nodes[start_node].position + glm::vec3{0.0f, 0.0f, 5.0f});
|
vehicle.SetPosition(roads->nodes[start_node].position + glm::vec3{0.0f, 0.0f, 5.0f});
|
||||||
|
|
||||||
auto think_state = std::make_shared<BotThinkState>(vehicle, *roads, start_node);
|
auto think_state = std::make_shared<BotThinkState>(vehicle, *roads, start_node);
|
||||||
BotThink(think_state);
|
BotThink(think_state);
|
||||||
vehicle.Schedule(rand() % 500, [think_state]() {
|
vehicle.Schedule(rand() % 500, [think_state]() {
|
||||||
BotNametagThink(think_state);
|
//BotNametagThink(think_state);
|
||||||
} );
|
} );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -1,9 +1,12 @@
|
|||||||
#include "player.hpp"
|
#include "player.hpp"
|
||||||
|
|
||||||
#include "world.hpp"
|
|
||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
||||||
|
#define GLM_ENABLE_EXPERIMENTAL
|
||||||
|
#include <glm/gtx/norm.hpp>
|
||||||
|
|
||||||
|
#include "world.hpp"
|
||||||
|
|
||||||
game::Player::Player(Game& game, std::string name) : game_(game), name_(std::move(name))
|
game::Player::Player(Game& game, std::string name) : game_(game), name_(std::move(name))
|
||||||
{
|
{
|
||||||
game_.PlayerJoined(*this);
|
game_.PlayerJoined(*this);
|
||||||
@ -30,8 +33,19 @@ void game::Player::Update()
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (world_)
|
if (world_)
|
||||||
|
{
|
||||||
|
if (cam_ent_)
|
||||||
|
{
|
||||||
|
auto cam_ent = world_->GetEntity(cam_ent_);
|
||||||
|
if (cam_ent)
|
||||||
|
{
|
||||||
|
cull_pos_ = cam_ent->GetRootTransform().position;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
SyncEntities();
|
SyncEntities();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void game::Player::SetWorld(std::shared_ptr<World> world)
|
void game::Player::SetWorld(std::shared_ptr<World> world)
|
||||||
{
|
{
|
||||||
@ -49,6 +63,8 @@ void game::Player::SetWorld(std::shared_ptr<World> world)
|
|||||||
|
|
||||||
void game::Player::SetCamera(net::EntNum entnum)
|
void game::Player::SetCamera(net::EntNum entnum)
|
||||||
{
|
{
|
||||||
|
cam_ent_ = entnum;
|
||||||
|
|
||||||
auto msg = BeginMsg(net::MSG_CAM);
|
auto msg = BeginMsg(net::MSG_CAM);
|
||||||
msg.Write(entnum);
|
msg.Write(entnum);
|
||||||
}
|
}
|
||||||
@ -121,7 +137,14 @@ void game::Player::SyncEntities()
|
|||||||
|
|
||||||
bool game::Player::ShouldSeeEntity(const Entity& entity) const
|
bool game::Player::ShouldSeeEntity(const Entity& entity) const
|
||||||
{
|
{
|
||||||
return true; // TODO: check distance?
|
// max distance check
|
||||||
|
float max_dist = entity.GetMaxDistance();
|
||||||
|
if (glm::distance2(entity.GetRootTransform().position, cull_pos_) > (max_dist * max_dist))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// TODO: custom callback
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void game::Player::SendInitEntity(const Entity& entity)
|
void game::Player::SendInitEntity(const Entity& entity)
|
||||||
|
|||||||
@ -59,6 +59,9 @@ private:
|
|||||||
std::set<net::EntNum> known_ents_;
|
std::set<net::EntNum> known_ents_;
|
||||||
|
|
||||||
PlayerInputFlags in_ = 0;
|
PlayerInputFlags in_ = 0;
|
||||||
|
|
||||||
|
net::EntNum cam_ent_ = 0;
|
||||||
|
glm::vec3 cull_pos_ = glm::vec3(0.0f);
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -57,7 +57,7 @@ game::Vehicle::Vehicle(World& world, std::string model_name, const glm::vec3& co
|
|||||||
{
|
{
|
||||||
float wheelRadius = wheeldef.radius;
|
float wheelRadius = wheeldef.radius;
|
||||||
|
|
||||||
float friction = 2.0f; // 5.0f;
|
float friction = 3.0f; // 5.0f;
|
||||||
float suspensionStiffness = 50.0f;
|
float suspensionStiffness = 50.0f;
|
||||||
// float suspensionDamping = 2.3f;
|
// float suspensionDamping = 2.3f;
|
||||||
// float suspensionCompression = 4.4f;
|
// float suspensionCompression = 4.4f;
|
||||||
|
|||||||
@ -65,7 +65,7 @@ void game::view::ClientSession::Update(const UpdateInfo& info)
|
|||||||
world_->Update(info);
|
world_->Update(info);
|
||||||
}
|
}
|
||||||
|
|
||||||
glm::mat4 game::view::ClientSession::GetViewMatrix() const
|
void game::view::ClientSession::GetViewInfo(glm::vec3& eye, glm::mat4& view) const
|
||||||
{
|
{
|
||||||
glm::vec3 center(0.0f, 0.0f, 2.5f);
|
glm::vec3 center(0.0f, 0.0f, 2.5f);
|
||||||
|
|
||||||
@ -84,9 +84,8 @@ glm::mat4 game::view::ClientSession::GetViewMatrix() const
|
|||||||
|
|
||||||
float distance = 8.0f;
|
float distance = 8.0f;
|
||||||
|
|
||||||
auto eye = center - dir * distance;
|
eye = center - dir * distance;
|
||||||
|
view = glm::lookAt(eye, center, glm::vec3(0, 0, 1));
|
||||||
return glm::lookAt(eye, center, glm::vec3(0, 0, 1));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
audio::Master& game::view::ClientSession::GetAudioMaster() const
|
audio::Master& game::view::ClientSession::GetAudioMaster() const
|
||||||
|
|||||||
@ -27,7 +27,7 @@ public:
|
|||||||
|
|
||||||
const WorldView* GetWorld() const { return world_.get(); }
|
const WorldView* GetWorld() const { return world_.get(); }
|
||||||
|
|
||||||
glm::mat4 GetViewMatrix() const;
|
void GetViewInfo(glm::vec3& eye, glm::mat4& view) const;
|
||||||
|
|
||||||
audio::Master& GetAudioMaster() const;
|
audio::Master& GetAudioMaster() const;
|
||||||
|
|
||||||
|
|||||||
@ -33,7 +33,23 @@ void game::view::EntityView::Update(const UpdateInfo& info)
|
|||||||
void game::view::EntityView::Draw(const DrawArgs& args)
|
void game::view::EntityView::Draw(const DrawArgs& args)
|
||||||
{
|
{
|
||||||
// std::cout << "TODO draw entity nametag: " << nametag_ << std::endl;
|
// std::cout << "TODO draw entity nametag: " << nametag_ << std::endl;
|
||||||
|
DrawNametag(args);
|
||||||
|
//DrawAxes(args);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool game::view::EntityView::ReadNametag(net::InMessage& msg)
|
||||||
|
{
|
||||||
|
// read nametag
|
||||||
|
net::NameTag nametag;
|
||||||
|
if (!msg.Read(nametag))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
nametag_ = nametag;
|
||||||
|
nametag_text_.SetText(nametag);
|
||||||
|
}
|
||||||
|
|
||||||
|
void game::view::EntityView::DrawNametag(const DrawArgs& args)
|
||||||
|
{
|
||||||
if (nametag_.empty())
|
if (nametag_.empty())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@ -68,13 +84,23 @@ void game::view::EntityView::Draw(const DrawArgs& args)
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool game::view::EntityView::ReadNametag(net::InMessage& msg)
|
void game::view::EntityView::DrawAxes(const DrawArgs& args)
|
||||||
{
|
{
|
||||||
// read nametag
|
const float len = 5.0f;
|
||||||
net::NameTag nametag;
|
static const uint32_t colors[] = {0xFF0000FF, 0xFF00FF00, 0xFFFF0000};
|
||||||
if (!msg.Read(nametag))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
nametag_ = nametag;
|
for (size_t i = 0; i < 3; i++)
|
||||||
nametag_text_.SetText(nametag);
|
{
|
||||||
|
glm::vec3 end(0.0f);
|
||||||
|
end[i] = len;
|
||||||
|
|
||||||
|
gfx::DrawBeamCmd cmd;
|
||||||
|
cmd.start = glm::vec3(root_.matrix * glm::vec4(0.0f, 0.0f, 0.0f, 1.0f));
|
||||||
|
cmd.end = glm::vec3(root_.matrix * glm::vec4(end, 1.0f));
|
||||||
|
cmd.color = colors[i];
|
||||||
|
cmd.radius = 0.05f;
|
||||||
|
//cmd.num_segments = 10;
|
||||||
|
//cmd.max_offset = 0.1f;
|
||||||
|
args.dlist.AddBeam(cmd);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -48,6 +48,9 @@ public:
|
|||||||
private:
|
private:
|
||||||
bool ReadNametag(net::InMessage& msg);
|
bool ReadNametag(net::InMessage& msg);
|
||||||
|
|
||||||
|
void DrawNametag(const DrawArgs& args);
|
||||||
|
void DrawAxes(const DrawArgs& args);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
WorldView& world_;
|
WorldView& world_;
|
||||||
|
|
||||||
|
|||||||
@ -16,8 +16,6 @@ game::view::VehicleView::VehicleView(WorldView& world, net::InMessage& msg)
|
|||||||
|
|
||||||
model_ = assets::CacheManager::GetVehicleModel("data/" + std::string(modelname) + ".veh");
|
model_ = assets::CacheManager::GetVehicleModel("data/" + std::string(modelname) + ".veh");
|
||||||
|
|
||||||
// init the other transform to identical
|
|
||||||
root_trans_[0] = root_trans_[1];
|
|
||||||
|
|
||||||
auto& modelwheels = model_->GetWheels();
|
auto& modelwheels = model_->GetWheels();
|
||||||
wheels_.resize(modelwheels.size());
|
wheels_.resize(modelwheels.size());
|
||||||
@ -32,6 +30,9 @@ game::view::VehicleView::VehicleView(WorldView& world, net::InMessage& msg)
|
|||||||
if (!ReadState(msg))
|
if (!ReadState(msg))
|
||||||
throw EntityInitError();
|
throw EntityInitError();
|
||||||
|
|
||||||
|
// init the other transform to identical
|
||||||
|
root_trans_[0] = root_trans_[1];
|
||||||
|
|
||||||
snd_accel_ = assets::CacheManager::GetSound("data/auto.snd");
|
snd_accel_ = assets::CacheManager::GetSound("data/auto.snd");
|
||||||
|
|
||||||
// sync state
|
// sync state
|
||||||
|
|||||||
@ -19,6 +19,16 @@ struct DrawSurfaceCmd
|
|||||||
float dist = 0.0f; // distance to camera - for transparnt sorting
|
float dist = 0.0f; // distance to camera - for transparnt sorting
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct DrawBeamCmd
|
||||||
|
{
|
||||||
|
glm::vec3 start;
|
||||||
|
glm::vec3 end;
|
||||||
|
uint32_t color = 0xFFFFFFFF;
|
||||||
|
float radius = 0.1f;
|
||||||
|
size_t num_segments = 1;
|
||||||
|
float max_offset = 0.0f;
|
||||||
|
};
|
||||||
|
|
||||||
struct DrawHudCmd
|
struct DrawHudCmd
|
||||||
{
|
{
|
||||||
const VertexArray* va = nullptr;
|
const VertexArray* va = nullptr;
|
||||||
@ -30,14 +40,17 @@ struct DrawHudCmd
|
|||||||
struct DrawList
|
struct DrawList
|
||||||
{
|
{
|
||||||
std::vector<DrawSurfaceCmd> surfaces;
|
std::vector<DrawSurfaceCmd> surfaces;
|
||||||
|
std::vector<DrawBeamCmd> beams;
|
||||||
std::vector<DrawHudCmd> huds;
|
std::vector<DrawHudCmd> huds;
|
||||||
|
|
||||||
void AddSurface(const DrawSurfaceCmd& cmd) { surfaces.emplace_back(cmd); }
|
void AddSurface(const DrawSurfaceCmd& cmd) { surfaces.emplace_back(cmd); }
|
||||||
|
void AddBeam(const DrawBeamCmd& cmd) { beams.emplace_back(cmd); }
|
||||||
void AddHUD(const DrawHudCmd& cmd) { huds.emplace_back(cmd); }
|
void AddHUD(const DrawHudCmd& cmd) { huds.emplace_back(cmd); }
|
||||||
|
|
||||||
void Clear()
|
void Clear()
|
||||||
{
|
{
|
||||||
surfaces.clear();
|
surfaces.clear();
|
||||||
|
beams.clear();
|
||||||
huds.clear();
|
huds.clear();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
@ -18,6 +18,9 @@ gfx::Renderer::Renderer()
|
|||||||
ShaderSources::MakeShader(skel_mesh_shader_.shader, SS_SKEL_MESH_VERT, SS_SKEL_MESH_FRAG);
|
ShaderSources::MakeShader(skel_mesh_shader_.shader, SS_SKEL_MESH_VERT, SS_SKEL_MESH_FRAG);
|
||||||
ShaderSources::MakeShader(solid_shader_, SS_SOLID_VERT, SS_SOLID_FRAG);
|
ShaderSources::MakeShader(solid_shader_, SS_SOLID_VERT, SS_SOLID_FRAG);
|
||||||
ShaderSources::MakeShader(hud_shader_, SS_HUD_VERT, SS_HUD_FRAG);
|
ShaderSources::MakeShader(hud_shader_, SS_HUD_VERT, SS_HUD_FRAG);
|
||||||
|
ShaderSources::MakeShader(beam_shader_, SS_BEAM_VERT, SS_BEAM_FRAG);
|
||||||
|
|
||||||
|
SetupBeamVA();
|
||||||
}
|
}
|
||||||
|
|
||||||
void gfx::Renderer::Begin(size_t width, size_t height)
|
void gfx::Renderer::Begin(size_t width, size_t height)
|
||||||
@ -40,9 +43,61 @@ void gfx::Renderer::ClearDepth()
|
|||||||
void gfx::Renderer::DrawList(gfx::DrawList& list, const DrawListParams& params)
|
void gfx::Renderer::DrawList(gfx::DrawList& list, const DrawListParams& params)
|
||||||
{
|
{
|
||||||
DrawSurfaceList(list.surfaces, params);
|
DrawSurfaceList(list.surfaces, params);
|
||||||
|
DrawBeamList(list.beams, params);
|
||||||
DrawHudList(list.huds, params);
|
DrawHudList(list.huds, params);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct BeamSegment
|
||||||
|
{
|
||||||
|
glm::vec3 p0;
|
||||||
|
uint32_t color;
|
||||||
|
glm::vec3 p1;
|
||||||
|
float radius;
|
||||||
|
};
|
||||||
|
|
||||||
|
void gfx::Renderer::SetupBeamVA()
|
||||||
|
{
|
||||||
|
beam_va_ = std::make_unique<VertexArray>(VA_POSITION, 0);
|
||||||
|
|
||||||
|
static const float quad_points[] = {
|
||||||
|
0.0f, 0.0f, 0.0f,
|
||||||
|
1.0f, 0.0f, 0.0f,
|
||||||
|
0.0f, 1.0f, 0.0f,
|
||||||
|
1.0f, 1.0f, 0.0f,
|
||||||
|
};
|
||||||
|
|
||||||
|
beam_va_->SetVBOData(quad_points, sizeof(quad_points));
|
||||||
|
|
||||||
|
// create points buffer
|
||||||
|
glBindVertexArray(beam_va_->GetVAOId());
|
||||||
|
beam_segments_vbo_ = std::make_unique<BufferObject>(GL_ARRAY_BUFFER, GL_STREAM_DRAW);
|
||||||
|
beam_segments_vbo_->Bind();
|
||||||
|
|
||||||
|
constexpr size_t STRIDE = sizeof(BeamSegment);
|
||||||
|
|
||||||
|
// p0
|
||||||
|
glEnableVertexAttribArray(10);
|
||||||
|
glVertexAttribPointer(10, 3, GL_FLOAT, GL_FALSE, STRIDE, (const void*)offsetof(BeamSegment, p0));
|
||||||
|
glVertexAttribDivisor(10, 1);
|
||||||
|
|
||||||
|
// color
|
||||||
|
glEnableVertexAttribArray(2);
|
||||||
|
glVertexAttribPointer(2, 4, GL_UNSIGNED_BYTE, GL_TRUE, STRIDE, (const void*)offsetof(BeamSegment, color));
|
||||||
|
glVertexAttribDivisor(2, 1);
|
||||||
|
|
||||||
|
// p1
|
||||||
|
glEnableVertexAttribArray(11);
|
||||||
|
glVertexAttribPointer(11, 3, GL_FLOAT, GL_FALSE, STRIDE, (const void*)offsetof(BeamSegment, p1));
|
||||||
|
glVertexAttribDivisor(11, 1);
|
||||||
|
|
||||||
|
// radius
|
||||||
|
glEnableVertexAttribArray(12);
|
||||||
|
glVertexAttribPointer(12, 1, GL_FLOAT, GL_FALSE, STRIDE, (const void*)offsetof(BeamSegment, radius));
|
||||||
|
glVertexAttribDivisor(12, 1);
|
||||||
|
|
||||||
|
glBindVertexArray(0);
|
||||||
|
}
|
||||||
|
|
||||||
void gfx::Renderer::InvalidateShaders()
|
void gfx::Renderer::InvalidateShaders()
|
||||||
{
|
{
|
||||||
InvalidateMeshShader(mesh_shader_);
|
InvalidateMeshShader(mesh_shader_);
|
||||||
@ -253,6 +308,82 @@ void gfx::Renderer::DrawSurfaceList(std::span<DrawSurfaceCmd> list, const DrawLi
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static float GetRandomOffset(float max_offset)
|
||||||
|
{
|
||||||
|
return (static_cast<float>(rand()) / static_cast<float>(RAND_MAX) - 0.5f) * 2.0f * max_offset;
|
||||||
|
}
|
||||||
|
|
||||||
|
void gfx::Renderer::DrawBeamList(std::span<DrawBeamCmd> queue, const DrawListParams& params)
|
||||||
|
{
|
||||||
|
static std::vector<BeamSegment> segments;
|
||||||
|
static std::vector<glm::vec3> points;
|
||||||
|
segments.clear();
|
||||||
|
|
||||||
|
for (const auto& cmd : queue)
|
||||||
|
{
|
||||||
|
if (cmd.num_segments < 1)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
points.resize(cmd.num_segments + 1);
|
||||||
|
|
||||||
|
const glm::vec3 seg_step = (cmd.end - cmd.start) / static_cast<float>(cmd.num_segments);
|
||||||
|
glm::vec3 pos = cmd.start;
|
||||||
|
for (size_t i = 0; i <= cmd.num_segments; ++i)
|
||||||
|
{
|
||||||
|
points[i] = pos;
|
||||||
|
pos += seg_step;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cmd.max_offset > 0.0f)
|
||||||
|
{
|
||||||
|
for (auto& p : points)
|
||||||
|
{
|
||||||
|
p.x += GetRandomOffset(cmd.max_offset);
|
||||||
|
p.y += GetRandomOffset(cmd.max_offset);
|
||||||
|
p.z += GetRandomOffset(cmd.max_offset);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (size_t i = 1; i < points.size(); ++i)
|
||||||
|
{
|
||||||
|
auto& segment = segments.emplace_back();
|
||||||
|
segment.p0 = points[i - 1];
|
||||||
|
segment.p1 = points[i];
|
||||||
|
segment.color = cmd.color;
|
||||||
|
segment.radius = cmd.radius;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
if (segments.empty())
|
||||||
|
return;
|
||||||
|
|
||||||
|
glBindVertexArray(beam_va_->GetVAOId());
|
||||||
|
beam_segments_vbo_->SetData(segments.data(), segments.size() * sizeof(segments[0]));
|
||||||
|
|
||||||
|
Shader* shader = beam_shader_.get();
|
||||||
|
glUseProgram(shader->GetId());
|
||||||
|
current_shader_ = shader;
|
||||||
|
|
||||||
|
glDisable(GL_CULL_FACE);
|
||||||
|
|
||||||
|
glEnable(GL_DEPTH_TEST);
|
||||||
|
glDepthMask(GL_FALSE);
|
||||||
|
|
||||||
|
glEnable(GL_BLEND);
|
||||||
|
glBlendFunc(GL_SRC_ALPHA, GL_ONE); // ADDITIVE blend
|
||||||
|
|
||||||
|
glUniformMatrix4fv(shader->U(gfx::SU_VIEW_PROJ), 1, GL_FALSE, ¶ms.view_proj[0][0]);
|
||||||
|
glUniform3fv(shader->U(gfx::SU_CAMERA), 1, ¶ms.cam_pos[0]);
|
||||||
|
|
||||||
|
glDrawArraysInstanced(GL_TRIANGLE_STRIP, 0, 4, segments.size());
|
||||||
|
|
||||||
|
glBindVertexArray(0);
|
||||||
|
|
||||||
|
glDepthMask(GL_TRUE);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
void gfx::Renderer::DrawHudList(std::span<DrawHudCmd> queue, const DrawListParams& params)
|
void gfx::Renderer::DrawHudList(std::span<DrawHudCmd> queue, const DrawListParams& params)
|
||||||
{
|
{
|
||||||
// cannot sort anything here, must be drawn in FIFO order for correct overlay
|
// cannot sort anything here, must be drawn in FIFO order for correct overlay
|
||||||
|
|||||||
@ -10,6 +10,7 @@ namespace gfx
|
|||||||
{
|
{
|
||||||
struct DrawListParams
|
struct DrawListParams
|
||||||
{
|
{
|
||||||
|
glm::vec3 cam_pos;
|
||||||
glm::mat4 view_proj;
|
glm::mat4 view_proj;
|
||||||
size_t screen_width = 0;
|
size_t screen_width = 0;
|
||||||
size_t screen_height = 0;
|
size_t screen_height = 0;
|
||||||
@ -38,20 +39,30 @@ namespace gfx
|
|||||||
void DrawList(gfx::DrawList& list, const DrawListParams& params);
|
void DrawList(gfx::DrawList& list, const DrawListParams& params);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
MeshShader mesh_shader_;
|
void SetupBeamVA();
|
||||||
MeshShader skel_mesh_shader_;
|
|
||||||
std::unique_ptr<Shader> solid_shader_;
|
|
||||||
std::unique_ptr<Shader> hud_shader_;
|
|
||||||
|
|
||||||
const Shader* current_shader_ = nullptr;
|
|
||||||
|
|
||||||
void InvalidateShaders();
|
void InvalidateShaders();
|
||||||
void InvalidateMeshShader(MeshShader& mshader);
|
void InvalidateMeshShader(MeshShader& mshader);
|
||||||
void SetupMeshShader(MeshShader& mshader, const DrawListParams& params);
|
void SetupMeshShader(MeshShader& mshader, const DrawListParams& params);
|
||||||
|
|
||||||
void DrawSurfaceList(std::span<DrawSurfaceCmd> 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);
|
void DrawHudList(std::span<DrawHudCmd> queue, const DrawListParams& params);
|
||||||
|
|
||||||
|
private:
|
||||||
|
MeshShader mesh_shader_;
|
||||||
|
MeshShader skel_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<Shader> hud_shader_;
|
||||||
|
|
||||||
|
const Shader* current_shader_ = nullptr;
|
||||||
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -10,6 +10,7 @@ static const char* const s_uni_names[] = {
|
|||||||
"u_tex", // SU_TEX
|
"u_tex", // SU_TEX
|
||||||
"u_color", // SU_COLOR
|
"u_color", // SU_COLOR
|
||||||
"u_flags", // SU_FLAGS
|
"u_flags", // SU_FLAGS
|
||||||
|
"u_camera", // SU_CAMERA
|
||||||
};
|
};
|
||||||
|
|
||||||
// Vytvori shader z daneho zdroje
|
// Vytvori shader z daneho zdroje
|
||||||
|
|||||||
@ -15,6 +15,7 @@ namespace gfx
|
|||||||
SU_TEX,
|
SU_TEX,
|
||||||
SU_COLOR,
|
SU_COLOR,
|
||||||
SU_FLAGS,
|
SU_FLAGS,
|
||||||
|
SU_CAMERA,
|
||||||
|
|
||||||
SU_COUNT
|
SU_COUNT
|
||||||
};
|
};
|
||||||
|
|||||||
@ -265,6 +265,50 @@ void main() {
|
|||||||
|
|
||||||
)GLSL",
|
)GLSL",
|
||||||
|
|
||||||
|
|
||||||
|
// SS_BEAM_VERT
|
||||||
|
SHADER_HEADER
|
||||||
|
R"GLSL(
|
||||||
|
layout (location = 0) in vec3 a_pos;
|
||||||
|
|
||||||
|
// instance
|
||||||
|
layout (location = 2) in vec4 a_color;
|
||||||
|
layout (location = 10) in vec3 a_p0;
|
||||||
|
layout (location = 11) in vec3 a_p1;
|
||||||
|
layout (location = 12) in float a_radius;
|
||||||
|
|
||||||
|
uniform mat4 u_view_proj;
|
||||||
|
uniform vec3 u_camera;
|
||||||
|
|
||||||
|
out vec4 v_color;
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
vec3 p = mix(a_p0, a_p1, a_pos.y);
|
||||||
|
|
||||||
|
vec3 seg_dir = a_p1 - a_p0;
|
||||||
|
vec3 cam_dir = u_camera - p;
|
||||||
|
vec3 cross_dir = normalize(cross(seg_dir, cam_dir));
|
||||||
|
|
||||||
|
p += cross_dir * a_radius * (a_pos.x - 0.5) * 2.0;
|
||||||
|
gl_Position = u_view_proj * vec4(p, 1.0);
|
||||||
|
v_color = a_color;
|
||||||
|
}
|
||||||
|
)GLSL",
|
||||||
|
|
||||||
|
// SS_BEAM_FRAG
|
||||||
|
SHADER_HEADER
|
||||||
|
R"GLSL(
|
||||||
|
|
||||||
|
in vec4 v_color;
|
||||||
|
|
||||||
|
layout (location = 0) out vec4 o_color;
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
o_color = v_color;
|
||||||
|
}
|
||||||
|
|
||||||
|
)GLSL",
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// Vrati zdrojovy kod shaderu
|
// Vrati zdrojovy kod shaderu
|
||||||
|
|||||||
@ -19,6 +19,8 @@ namespace gfx
|
|||||||
SS_HUD_VERT,
|
SS_HUD_VERT,
|
||||||
SS_HUD_FRAG,
|
SS_HUD_FRAG,
|
||||||
|
|
||||||
|
SS_BEAM_VERT,
|
||||||
|
SS_BEAM_FRAG,
|
||||||
};
|
};
|
||||||
|
|
||||||
class ShaderSources
|
class ShaderSources
|
||||||
|
|||||||
@ -50,6 +50,9 @@ gfx::Texture::Texture(GLuint width, GLuint height, const void* data, GLint inter
|
|||||||
|
|
||||||
if (mipmaps)
|
if (mipmaps)
|
||||||
{
|
{
|
||||||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0);
|
||||||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 3);
|
||||||
|
|
||||||
glGenerateMipmap(GL_TEXTURE_2D);
|
glGenerateMipmap(GL_TEXTURE_2D);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user