Commit 46a4362e authored by Julius Nehring-Wirxel's avatar Julius Nehring-Wirxel
Browse files

Merge develop into jn/develop

parents 96ef34d1 a8440bd6
......@@ -89,7 +89,7 @@ public:
auto ii = 0u;
VertexT vertices[4 * 3 * 2];
uint8_t indices[6 * 3 * 2];
uint16_t indices[6 * 3 * 2];
for (int i = 0; i < 3; ++i)
{
......@@ -130,9 +130,6 @@ public: // Predefined attributes
static std::vector<ArrayBufferAttribute> attributesOf(void*) { return VertexT::attributes(); }
};
inline SharedVertexArray make_cube()
{
return Cube<>().generate();
}
inline SharedVertexArray make_cube() { return Cube<>().generate(); }
}
}
......@@ -57,6 +57,12 @@ struct SceneConfig
/// exposure setting for tonemapping
float tonemapExposure = 1.f;
/// a screen-space distance (in px) that is used to fadeout shadows
float shadowScreenFadeoutDistance = 0.f;
/// maximum number of samples for the soft shadow
int maxShadowSamples = 1024;
//
// Camera settings
......@@ -76,6 +82,9 @@ struct SceneConfig
/// custom camera distance (requries customCameraOrientation == true)
float cameraDistance = -1.f;
/// custom camera fov
tg::optional<tg::angle> cameraHorizontalFov;
/// if true, overwrites the starting camera position
bool customCameraPosition = false;
/// custom camera position (requires customCameraPosition == true)
......@@ -106,6 +115,7 @@ struct SceneConfig
/// if set, this is the size of a ground grid cell (the major ones)
tg::optional<float> customGridSize;
//
// Interaction settings
//
......
......@@ -369,6 +369,8 @@ void ViewerApp::resetCameraToScene(bool clipCam)
camera.setTransform(node.scene.config.cameraPosition, node.scene.config.cameraTarget);
if (node.scene.config.enableOrthogonalProjection)
camera.enableOrthographicMode(node.scene.config.orthogonalProjectionBounds);
if (node.scene.config.cameraHorizontalFov.has_value())
camera.s.HorizontalFov = node.scene.config.cameraHorizontalFov.value();
}
detail::set_2d_controls(mSettings.controls2d_enabled || !has_3d_geometry);
......
......@@ -263,7 +263,7 @@ void glow::viewer::ViewerRenderer::renderSubview(tg::isize2 const& res, tg::ipos
if (r->name().empty())
continue;
if (!name.empty())
if (!name.empty() && name != r->name())
has_unique_name = false;
name = r->name();
}
......@@ -339,7 +339,7 @@ void glow::viewer::ViewerRenderer::renderSubview(tg::isize2 const& res, tg::ipos
auto const groundShadowAabb = tg::aabb3(tg::pos3(boundingInfo.center.x, groundY, boundingInfo.center.z) - tg::vec3(1, 0, 1) * boundingInfo.diagonal * 1,
tg::pos3(boundingInfo.center.x, groundY, boundingInfo.center.z) + tg::vec3(1, 0, 1) * boundingInfo.diagonal * 1);
for (auto _ = 0; _ < mShadowSamplesPerFrame && subViewData.shadowSampleCount < mMinShadowCnt; ++_)
for (auto _ = 0; _ < mShadowSamplesPerFrame && subViewData.shadowSampleCount < scene.config.maxShadowSamples; ++_)
{
auto sunPosJitter = sunPos;
if (subViewData.shadowSampleCount > 0)
......@@ -489,6 +489,7 @@ void glow::viewer::ViewerRenderer::renderSubview(tg::isize2 const& res, tg::ipos
shader["uGroundShadowMax"] = groundShadowAabb.max;
shader["uShadowSamples"] = float(subViewData.shadowSampleCount);
shader["uShadowMapSoft"] = subViewData.shadowMapSoft;
shader["uShadowFadeoutDistance"] = scene.config.shadowScreenFadeoutDistance;
shader["uShowGrid"] = scene.config.enableGrid;
shader["uTexDepth"] = subViewData.targetDepth;
mMeshQuad->bind().draw();
......
......@@ -56,7 +56,6 @@ private:
// == Config ==
int const mMinAccumCnt = 128;
int const mMinSSAOCnt = 8196;
int const mMinShadowCnt = 1024;
int const mAccumPerFrame = 1;
float const mDepthThresholdFactor = 1.0f;
float const mNormalThreshold = 0.9f;
......@@ -132,6 +131,7 @@ public:
targetSsao = renderer->texturePoolRect.alloc({GL_R32F, size});
shadowMapSoft = renderer->texturePool2D.alloc({GL_R32F, shadowMapSize, 0});
shadowMapSoft->bind().setAnisotropicFiltering(16);
}
~SubViewData()
......
......@@ -4,24 +4,61 @@
#include <glow-extras/colors/color.hh>
void glow::viewer::canvas_t::set_color(std::string_view hex)
// TODO: more performant from_hex
void glow::viewer::canvas_data::set_color(std::string_view hex)
{
auto c = glow::colors::color::from_hex(std::string(hex));
set_color(c.r, c.g, c.b, c.a);
}
void glow::viewer::canvas_t::add_label(const glow::viewer::label& label) { _labels.push_back(label); }
glow::viewer::material::material(std::string_view color_str) : type(material_type::diffuse)
{
auto c = glow::colors::color::from_hex(std::string(color_str));
color = {c.r, c.g, c.b, c.a};
}
glow::viewer::material::material(const char* color_str) : type(material_type::diffuse)
{
auto c = glow::colors::color::from_hex(color_str);
color = {c.r, c.g, c.b, c.a};
}
glow::viewer::canvas_t::point_ref& glow::viewer::canvas_t::point_ref::color(std::string_view color_str)
{
auto c = glow::colors::color::from_hex(std::string(color_str));
return color(tg::color4(c.r, c.g, c.b, c.a));
}
void glow::viewer::canvas_t::add_labels(glow::array_view<const glow::viewer::label> labels)
glow::viewer::canvas_t::splat_ref& glow::viewer::canvas_t::splat_ref::color(std::string_view color_str)
{
auto c = glow::colors::color::from_hex(std::string(color_str));
return color(tg::color4(c.r, c.g, c.b, c.a));
}
glow::viewer::canvas_t::line_ref& glow::viewer::canvas_t::line_ref::color(std::string_view color_str)
{
auto c = glow::colors::color::from_hex(std::string(color_str));
return color(tg::color4(c.r, c.g, c.b, c.a));
}
glow::viewer::canvas_t::triangle_ref& glow::viewer::canvas_t::triangle_ref::color(std::string_view color_str)
{
auto c = glow::colors::color::from_hex(std::string(color_str));
return color(tg::color4(c.r, c.g, c.b, c.a));
}
void glow::viewer::canvas_data::add_label(const glow::viewer::label& label) { _labels.push_back(label); }
void glow::viewer::canvas_data::add_labels(glow::array_view<const glow::viewer::label> labels)
{
for (auto l : labels)
_labels.push_back(l);
}
void glow::viewer::canvas_t::add_arrow(tg::pos3 from, tg::pos3 to, float world_size, tg::color3 color, const glow::viewer::arrow_style& style)
void glow::viewer::canvas_data::add_arrow(tg::pos3 from, tg::pos3 to, float world_size, tg::color3 color, const glow::viewer::arrow_style& style)
{
auto prev_color = _color;
_color = tg::color4(color, 1);
auto mat = material(color);
auto const length = distance(to, from);
auto const dir = normalize_safe(to - from);
......@@ -75,36 +112,34 @@ void glow::viewer::canvas_t::add_arrow(tg::pos3 from, tg::pos3 to, float world_s
auto const center_arrow_1 = center + n1 * r_arrow;
// shaft end
_add_triangle(from, from_shaft_0, from_shaft_1, -dir, -dir, -dir);
_add_triangle(from, from_shaft_0, from_shaft_1, -dir, -dir, -dir, mat);
// shaft mantle
_add_triangle(from_shaft_0, center_shaft_0, center_shaft_1, n0, n0, n1);
_add_triangle(from_shaft_0, center_shaft_1, from_shaft_1, n0, n1, n1);
_add_triangle(from_shaft_0, center_shaft_0, center_shaft_1, n0, n0, n1, mat);
_add_triangle(from_shaft_0, center_shaft_1, from_shaft_1, n0, n1, n1, mat);
// arrow end
_add_triangle(center, center_arrow_0, center_arrow_1, -dir, -dir, -dir);
_add_triangle(center, center_arrow_0, center_arrow_1, -dir, -dir, -dir, mat);
// arrow mantle
// TODO: normal?
_add_triangle(center_arrow_0, to, center_arrow_1, n0, n0, n1);
_add_triangle(center_arrow_0, to, center_arrow_1, n0, n0, n1, mat);
}
_color = prev_color;
}
void glow::viewer::canvas_t::add_arrow(tg::pos3 from_pos, tg::vec3 extent, float world_size, tg::color3 color, const glow::viewer::arrow_style& style)
void glow::viewer::canvas_data::add_arrow(tg::pos3 from_pos, tg::vec3 extent, float world_size, tg::color3 color, const glow::viewer::arrow_style& style)
{
add_arrow(from_pos, from_pos + extent, world_size, color, style);
}
void glow::viewer::canvas_t::add_arrow(tg::vec3 extent, tg::pos3 to_pos, float world_size, tg::color3 color, const glow::viewer::arrow_style& style)
void glow::viewer::canvas_data::add_arrow(tg::vec3 extent, tg::pos3 to_pos, float world_size, tg::color3 color, const glow::viewer::arrow_style& style)
{
add_arrow(to_pos - extent, to_pos, world_size, color, style);
}
glow::viewer::canvas_t::~canvas_t()
std::vector<glow::viewer::SharedRenderable> glow::viewer::canvas_data::create_renderables() const
{
auto v = gv::view();
std::vector<glow::viewer::SharedRenderable> res;
pm::Mesh m;
auto pos = m.vertices().make_attribute<tg::pos3>();
......@@ -112,6 +147,7 @@ glow::viewer::canvas_t::~canvas_t()
auto size = m.vertices().make_attribute<float>();
auto color3 = m.vertices().make_attribute<tg::color3>();
auto color4 = m.vertices().make_attribute<tg::color4>();
auto dash_size = m.edges().make_attribute<float>();
//
// points
......@@ -139,7 +175,7 @@ glow::viewer::canvas_t::~canvas_t()
}
if (!m.vertices().empty())
gv::view(gv::points(pos).point_size_px(size), color3);
res.push_back(gv::make_and_configure_renderable(gv::points(pos).point_size_px(size), color3));
if (has_transparent)
{
......@@ -155,7 +191,7 @@ glow::viewer::canvas_t::~canvas_t()
size[v] = p.size;
}
gv::view(gv::points(pos).point_size_px(size), color4, gv::transparent);
res.push_back(gv::make_and_configure_renderable(gv::points(pos).point_size_px(size), color4, gv::transparent));
}
}
if (!_points_world.empty())
......@@ -181,7 +217,7 @@ glow::viewer::canvas_t::~canvas_t()
}
if (!m.vertices().empty())
gv::view(gv::points(pos).point_size_world(size), color3);
res.push_back(gv::make_and_configure_renderable(gv::points(pos).point_size_world(size), color3));
if (has_transparent)
{
......@@ -197,7 +233,7 @@ glow::viewer::canvas_t::~canvas_t()
size[v] = p.size;
}
gv::view(gv::points(pos).point_size_world(size), color4, gv::transparent);
res.push_back(gv::make_and_configure_renderable(gv::points(pos).point_size_world(size), color4, gv::transparent));
}
}
......@@ -211,6 +247,8 @@ glow::viewer::canvas_t::~canvas_t()
m.vertices().reserve(_splats.size());
for (auto const& p : _splats)
{
TG_ASSERT(p.size >= 0 && "no splat size set (forgot to call .set_splat_size() or .add_splats(...).size(...)?)");
if (p.color.a <= 0)
continue;
......@@ -228,7 +266,7 @@ glow::viewer::canvas_t::~canvas_t()
}
if (!m.vertices().empty())
gv::view(gv::points(pos).round().normals(normals).point_size_world(size), color3);
res.push_back(gv::make_and_configure_renderable(gv::points(pos).round().normals(normals).point_size_world(size), color3));
if (has_transparent)
{
......@@ -245,7 +283,7 @@ glow::viewer::canvas_t::~canvas_t()
normals[v] = p.normal;
}
gv::view(gv::points(pos).round().normals(normals).point_size_world(size), color4, gv::transparent);
res.push_back(gv::make_and_configure_renderable(gv::points(pos).round().normals(normals).point_size_world(size), color4, gv::transparent));
}
}
......@@ -276,11 +314,13 @@ glow::viewer::canvas_t::~canvas_t()
color3[v1] = tg::color3(l.p1.color);
size[v0] = l.p0.size;
size[v1] = l.p1.size;
m.edges().add_or_get(v0, v1);
auto e = m.edges().add_or_get(v0, v1);
dash_size[e] = l.dash_size;
}
// TODO: screen space dash size
if (!m.vertices().empty())
gv::view(gv::lines(pos).line_width_px(size), color3);
res.push_back(gv::make_and_configure_renderable(gv::lines(pos).line_width_px(size), color3));
if (has_transparent)
{
......@@ -301,10 +341,12 @@ glow::viewer::canvas_t::~canvas_t()
color4[v1] = tg::color4(l.p1.color);
size[v0] = l.p0.size;
size[v1] = l.p1.size;
m.edges().add_or_get(v0, v1);
auto e = m.edges().add_or_get(v0, v1);
dash_size[e] = l.dash_size;
}
gv::view(gv::lines(pos).line_width_px(size), color4, gv::transparent);
// TODO: screen space dash size
res.push_back(gv::make_and_configure_renderable(gv::lines(pos).line_width_px(size), color4, gv::transparent));
}
}
if (!_lines_world.empty())
......@@ -331,11 +373,12 @@ glow::viewer::canvas_t::~canvas_t()
color3[v1] = tg::color3(l.p1.color);
size[v0] = l.p0.size;
size[v1] = l.p1.size;
m.edges().add_or_get(v0, v1);
auto e = m.edges().add_or_get(v0, v1);
dash_size[e] = l.dash_size;
}
if (!m.vertices().empty())
gv::view(gv::lines(pos).line_width_world(size), color3);
res.push_back(gv::make_and_configure_renderable(gv::lines(pos).line_width_world(size).dash_size_world(dash_size), color3));
if (has_transparent)
{
......@@ -356,10 +399,11 @@ glow::viewer::canvas_t::~canvas_t()
color4[v1] = tg::color4(l.p1.color);
size[v0] = l.p0.size;
size[v1] = l.p1.size;
m.edges().add_or_get(v0, v1);
auto e = m.edges().add_or_get(v0, v1);
dash_size[e] = l.dash_size;
}
gv::view(gv::lines(pos).line_width_world(size), color4, gv::transparent);
res.push_back(gv::make_and_configure_renderable(gv::lines(pos).line_width_world(size).dash_size_world(dash_size), color4, gv::transparent));
}
}
......@@ -398,7 +442,7 @@ glow::viewer::canvas_t::~canvas_t()
}
if (!m.vertices().empty())
gv::view(gv::polygons(pos).normals(normals), color3);
res.push_back(gv::make_and_configure_renderable(gv::polygons(pos).normals(normals), color3));
if (has_transparent)
{
......@@ -426,7 +470,7 @@ glow::viewer::canvas_t::~canvas_t()
m.faces().add(v0, v1, v2);
}
gv::view(gv::lines(pos).line_width_px(size), color4, gv::transparent);
res.push_back(gv::make_and_configure_renderable(gv::polygons(pos).normals(normals), color4, gv::transparent));
}
}
......@@ -434,5 +478,24 @@ glow::viewer::canvas_t::~canvas_t()
// labels
//
if (!_labels.empty())
gv::view(_labels);
res.push_back(gv::make_and_configure_renderable(_labels));
//
// quadrics
//
if (!_quadrics.empty())
res.push_back(gv::make_renderable(_quadrics));
// extras
for (auto& r : res)
r->name(_name);
return res;
}
glow::viewer::canvas_t::~canvas_t()
{
auto v = gv::view();
for (auto const& r : create_renderables())
gv::view(r);
}
This diff is collapsed.
......@@ -194,6 +194,15 @@ void configure(Renderable&, const grid_center& v)
detail::submit_command(detail::command::sceneCustomConfig([c = v.center](SceneConfig& cfg) { cfg.customGridCenter = c; }));
}
void configure(Renderable&, const shadow_screen_fadeout_distance& v)
{
detail::submit_command(detail::command::sceneCustomConfig([r = v.radius](SceneConfig& cfg) { cfg.shadowScreenFadeoutDistance = r; }));
}
void configure(Renderable&, const total_shadow_samples& v)
{
detail::submit_command(detail::command::sceneCustomConfig([s = v.samples](SceneConfig& cfg) { cfg.maxShadowSamples = s; }));
}
void configure(GeometricRenderable& r, const clip_plane& p) { r.setClipPlane(tg::vec4(p.normal, dot(p.normal, p.pos))); }
void configure(GeometricRenderable& r, const EnvMap& em)
......
......@@ -34,6 +34,16 @@ struct ssao_radius
float radius;
constexpr explicit ssao_radius(float r) : radius(r) {}
};
struct shadow_screen_fadeout_distance
{
float radius;
constexpr explicit shadow_screen_fadeout_distance(float r) : radius(r) {}
};
struct total_shadow_samples
{
int samples;
constexpr explicit total_shadow_samples(int s) : samples(s) {}
};
struct grid_size
{
float size;
......@@ -151,6 +161,8 @@ void configure(Renderable&, tonemap_exposure_t const& b);
void configure(Renderable&, background_color const& b);
void configure(Renderable&, ssao_power const& b);
void configure(Renderable&, ssao_radius const& b);
void configure(Renderable&, shadow_screen_fadeout_distance const& b);
void configure(Renderable&, total_shadow_samples const& v);
void configure(Renderable&, grid_size const& v);
void configure(Renderable&, grid_center const& v);
void configure(Renderable&, camera_orientation const& b);
......
......@@ -25,6 +25,7 @@ GLOW_SHARED(class, LineRenderable);
GLOW_SHARED(class, Vector2DRenderable);
GLOW_SHARED(class, TextureRenderable);
GLOW_SHARED(class, LabelRenderable);
GLOW_SHARED(class, QuadricRenderable);
class ColorMapping;
class Texturing;
......
......@@ -46,4 +46,8 @@ SharedLabelRenderable make_renderable(const label& label) { return LabelRenderab
SharedLabelRenderable make_renderable(glow::array_view<const label> labels) { return LabelRenderable::create(labels); }
SharedQuadricRenderable make_renderable(const boxed_quadric& q) { return QuadricRenderable::create(array_view<boxed_quadric const>{&q, 1}); }
SharedQuadricRenderable make_renderable(array_view<const boxed_quadric> qs) { return QuadricRenderable::create(qs); }
} // namespace viewer
......@@ -6,6 +6,7 @@
#include "renderables/LineRenderable.hh"
#include "renderables/MeshRenderable.hh"
#include "renderables/PointRenderable.hh"
#include "renderables/QuadricRenderable.hh"
#include "renderables/Renderable.hh"
#include "renderables/TextureRenderable.hh"
#include "renderables/Vector2DRenderable.hh"
......@@ -70,6 +71,11 @@ SharedMeshRenderable make_renderable(std::vector<std::vector<Pos3>> const& pos);
template <class Pos3, class = std::enable_if_t<detail::is_pos3_like<Pos3>>>
SharedPointRenderable make_renderable(Pos3 const& pos);
// quadrics
SharedQuadricRenderable make_renderable(boxed_quadric const& q);
SharedQuadricRenderable make_renderable(array_view<boxed_quadric const> qs);
// labels
SharedLabelRenderable make_renderable(label const& label);
SharedLabelRenderable make_renderable(glow::array_view<label const> labels);
......
......@@ -127,6 +127,17 @@ public:
return *this;
}
template <class T>
LineBuilder& dash_size_world(T const& val)
{
addAttribute(detail::make_mesh_attribute("aDashSize", val));
mDashSizeWorld = true;
if (!mWorldSpaceSize)
glow::warning() << "lines with dash size currently need world space sizes";
return *this;
}
private:
bool mSquareCaps = false;
bool mRoundCaps = false;
......@@ -138,6 +149,7 @@ private:
bool mForce3D = false;
bool mWorldSpaceSize = false;
bool mScreenSpaceSize = false;
bool mDashSizeWorld = false;
std::shared_ptr<detail::PolyMeshDefinition> mMeshDef;
......
......@@ -12,6 +12,9 @@ struct label_style
int padding_x = 8;
int padding_y = 4;
// if non-zero, this overrides the label dir
tg::vec2 override_dir;
float line_width = 1.f;
tg::color3 line_color = tg::color3::black;
......
......@@ -29,6 +29,8 @@ void glow::viewer::LabelRenderable::renderOverlay(RenderInfo const& info, vector
continue; // out of frustum
auto dir = normalize(tg::vec2(x > res.width / 2 ? 1 : -1, y > res.height / 2 ? 1 : -1));
if (l.style.override_dir != tg::vec2::zero)
dir = normalize(l.style.override_dir);
auto ox = x;
auto oy = y;
......@@ -56,7 +58,6 @@ void glow::viewer::LabelRenderable::renderOverlay(RenderInfo const& info, vector
auto tx = x + l.style.padding_x - tbb.min.x;
auto ty = y + l.style.padding_y - tbb.min.y;
auto pv = tg::vec2(l.style.padding_x, l.style.padding_y);
auto bb = tg::aabb2(tg::pos2(x, y), tg::size2(w, h));
g.draw(tg::segment2({ox, oy}, {lx, ly}), {l.style.line_color, l.style.line_width});
......
......@@ -77,6 +77,8 @@ void LineRenderable::renderForward(RenderInfo const& info)
shader["uProj"] = info.proj;
shader["uCamPos"] = info.camPos;
shader["uClipPlane"] = getClipPlane();
shader["uSeed"] = tg::u32(info.accumulationCount);
shader["uIsTransparent"] = getRenderMode() == GeometricRenderable::RenderMode::Transparent;
if (m3D)
{
auto const tanHalfFovY = 1.f / tg::abs(info.proj[1][1]);
......@@ -164,6 +166,8 @@ void LineRenderable::initFromBuilder(const builder::LineBuilder& builder)
else
mWorldSpaceSize = false; // default
mDashSizeWorld = builder.mDashSizeWorld;
if (builder.mOwnNormals && !m3D && !builder.mWorldSpaceSize && !builder.mScreenSpaceSize)
glow::warning() << "Normal aligned lines need some size information, since the default screen space size does not work in this case.";
}
......@@ -237,6 +241,9 @@ void LineRenderable::init()
sb.addPassthrough("float", "LineWidth");
sb.addPassthrough("vec3", "fragPosWS");
if (mDashSizeWorld)
sb.addPassthrough("float", "DashSize");
sb.addVertexShaderCode("vOut.fragPosWS = vec3(0);");
for (auto const& attr : getAttributes())
......@@ -486,7 +493,23 @@ float distance2(vec3 a, vec3 b)
// Project onto line segment
float lineLength = length(gLineEnd - gLineOrigin);
float lambda = dot(cylIntersection - gLineOrigin, gLineDir); // TODO: QUESTION: Is there a better way?
vec3 closestOnSegment = gLineOrigin + clamp(lambda, 0, lineLength) * gLineDir;
lambda = clamp(lambda, 0, lineLength);
)");
if (mDashSizeWorld)
sb.addFragmentShaderCode(R"(
// dash
float dash_size = vDashSize;
if (dash_size > 0)
{
float dashes = float(int(ceil(lineLength / dash_size)) / 2 * 2);
if (int(round(lambda / lineLength * dashes)) % 2 == 1)
discard;
}
)");
sb.addFragmentShaderCode(R"(
vec3 closestOnSegment = gLineOrigin + lambda * gLineDir;
// Ray-Sphere intersection same as in PointRenderable
vec3 sphereCenter = closestOnSegment;
......@@ -541,6 +564,8 @@ float distance2(vec3 a, vec3 b)
sbForward.addUniform("bool", "uExtrapolate");
sbForward.addUniform("bool", "uIsShadingEnabled");
sbForward.addUniform("uint", "uSeed");
sbForward.addUniform("bool", "uIsTransparent");
sbForward.addFragmentLocation("vec4", "fColor");
sbForward.addFragmentLocation("vec3", "fNormal");
......@@ -640,6 +665,21 @@ float distance2(vec3 a, vec3 b)